akhuang created this revision.
Herald added subscribers: llvm-commits, cfe-commits, hiraditya.
Herald added projects: clang, LLVM.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D63361

Files:
  clang/lib/CodeGen/CGDebugInfo.cpp
  clang/lib/CodeGen/CGDecl.cpp
  debuginfo-tests/nrvo-string.cpp
  llvm/include/llvm/IR/DebugInfoMetadata.h
  llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
  llvm/lib/IR/DebugInfoMetadata.cpp

Index: llvm/lib/IR/DebugInfoMetadata.cpp
===================================================================
--- llvm/lib/IR/DebugInfoMetadata.cpp
+++ llvm/lib/IR/DebugInfoMetadata.cpp
@@ -936,12 +936,20 @@
   }
 }
 
-bool DIExpression::extractIfOffset(int64_t &Offset) const {
+bool DIExpression::extractIfOffset(int64_t &Offset, bool &Deref) const {
+  Deref = false;
+
   if (getNumElements() == 0) {
     Offset = 0;
     return true;
   }
 
+  if (getNumElements() == 1 && Elements[0] == dwarf::DW_OP_deref) {
+    Offset = 0;
+    Deref = true;
+    return true;
+  }
+
   if (getNumElements() == 2 && Elements[0] == dwarf::DW_OP_plus_uconst) {
     Offset = Elements[1];
     return true;
Index: llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
===================================================================
--- llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -1142,9 +1142,11 @@
     // If the variable has an attached offset expression, extract it.
     // FIXME: Try to handle DW_OP_deref as well.
     int64_t ExprOffset = 0;
-    if (VI.Expr)
-      if (!VI.Expr->extractIfOffset(ExprOffset))
+    bool Deref = false;
+    if (VI.Expr) {
+      if (!VI.Expr->extractIfOffset(ExprOffset, Deref))
         continue;
+    }
 
     // Get the frame register used and the offset.
     unsigned FrameReg = 0;
@@ -1154,6 +1156,7 @@
     // Calculate the label ranges.
     LocalVarDefRange DefRange =
         createDefRangeMem(CVReg, FrameOffset + ExprOffset);
+
     for (const InsnRange &Range : Scope->getRanges()) {
       const MCSymbol *Begin = getLabelBeforeInsn(Range.first);
       const MCSymbol *End = getLabelAfterInsn(Range.second);
@@ -1164,6 +1167,9 @@
     LocalVariable Var;
     Var.DIVar = VI.Var;
     Var.DefRanges.emplace_back(std::move(DefRange));
+    if (Deref)
+      Var.UseReferenceType = true;
+
     recordLocalVariable(std::move(Var), Scope);
   }
 }
Index: llvm/include/llvm/IR/DebugInfoMetadata.h
===================================================================
--- llvm/include/llvm/IR/DebugInfoMetadata.h
+++ llvm/include/llvm/IR/DebugInfoMetadata.h
@@ -2468,8 +2468,9 @@
   static void appendOffset(SmallVectorImpl<uint64_t> &Ops, int64_t Offset);
 
   /// If this is a constant offset, extract it. If there is no expression,
-  /// return true with an offset of zero.
-  bool extractIfOffset(int64_t &Offset) const;
+  /// or if there is one expression of DW_OP_deref, return true with an offset
+  /// of zero. Also set Deref.
+  bool extractIfOffset(int64_t &Offset, bool &Deref) const;
 
   /// Checks if the last 4 elements of the expression are DW_OP_constu <DWARF
   /// Address Space> DW_OP_swap DW_OP_xderef and extracts the <DWARF Address
Index: debuginfo-tests/nrvo-string.cpp
===================================================================
--- debuginfo-tests/nrvo-string.cpp
+++ debuginfo-tests/nrvo-string.cpp
@@ -14,10 +14,13 @@
   ~string() {}
   int i = 0;
 };
+int some_function_call(int i) { return i; }
 string get_string() {
   string unused;
   string result = 3;
-// DEBUGGER: break 21
+  // DEBUGGER: break 21
+  result = some_function_call(47);
+  // DEBUGGER: break 23
   return result;
 }
 int main() { get_string(); }
@@ -25,3 +28,6 @@
 // DEBUGGER: r
 // DEBUGGER: print result.i
 // CHECK:  = 3
+// DEBUGGER: c
+// DEBUGGER: print result.i
+// CHECK:  = 47
Index: clang/lib/CodeGen/CGDecl.cpp
===================================================================
--- clang/lib/CodeGen/CGDecl.cpp
+++ clang/lib/CodeGen/CGDecl.cpp
@@ -1403,12 +1403,11 @@
       getLangOpts().OpenMP
           ? CGM.getOpenMPRuntime().getAddressOfLocalVariable(*this, &D)
           : Address::invalid();
+  bool NRVO = getLangOpts().ElideConstructors && D.isNRVOVariable();
+
   if (getLangOpts().OpenMP && OpenMPLocalAddr.isValid()) {
     address = OpenMPLocalAddr;
   } else if (Ty->isConstantSizeType()) {
-    bool NRVO = getLangOpts().ElideConstructors &&
-      D.isNRVOVariable();
-
     // If this value is an array or struct with a statically determinable
     // constant initializer, there are optimizations we can do.
     //
@@ -1561,8 +1560,20 @@
 
   // Emit debug info for local var declaration.
   if (EmitDebugInfo && HaveInsertPoint()) {
+    Address DebugAddr = address;
     DI->setLocation(D.getLocation());
-    (void)DI->EmitDeclareOfAutoVariable(&D, address.getPointer(), Builder);
+
+    // NRVO variables are stored in the return register and are not always
+    // readable by the debugger. Get around this by storing a reference to
+    // the variable.
+    if (NRVO) {
+      llvm::Type *RefTy =
+          ConvertTypeForMem(getContext().getLValueReferenceType(Ty));
+      DebugAddr = CreateTempAlloca(RefTy, getPointerAlign(), "nrvo_ref");
+      Builder.CreateStore(ReturnValue.getPointer(), DebugAddr);
+    }
+
+    (void)DI->EmitDeclareOfAutoVariable(&D, DebugAddr.getPointer(), Builder);
   }
 
   if (D.hasAttr<AnnotateAttr>() && HaveInsertPoint())
Index: clang/lib/CodeGen/CGDebugInfo.cpp
===================================================================
--- clang/lib/CodeGen/CGDebugInfo.cpp
+++ clang/lib/CodeGen/CGDebugInfo.cpp
@@ -3937,6 +3937,11 @@
     }
   }
 
+  // Add DW_OP_deref to NRVO variables because we set their debug values to be
+  // references.
+  if (VD->isNRVOVariable())
+    Expr.push_back(llvm::dwarf::DW_OP_deref);
+
   // Create the descriptor for the variable.
   auto *D = ArgNo ? DBuilder.createParameterVariable(
                         Scope, Name, *ArgNo, Unit, Line, Ty,
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to