aprantl created this revision.

LLVM now interprets DIExpressions correctly and no longer determines the 
location description kind by looking at whether the first operator is a 
DW_OP_deref.

      

The code that emitted debug info for block captures used to rely on this and 
used the presence of an alloca (which was only emitted when optimizations were 
enabled) as a proxy for tweaking the expression in a way the resulted in the 
backend doing the right thing. This is now unnecessary and this patch 
unconditionally emits an alloca for block descriptors, which is then elided by 
mem2reg.

      

https://bugs.llvm.org/show_bug.cgi?id=32382
rdar://problem/31205000


https://reviews.llvm.org/D31440

Files:
  lib/CodeGen/CGBlocks.cpp
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CGDebugInfo.h
  test/CodeGenObjC/debug-info-block-captured-self.m
  test/CodeGenObjC/debug-info-blocks.m

Index: test/CodeGenObjC/debug-info-blocks.m
===================================================================
--- test/CodeGenObjC/debug-info-blocks.m
+++ test/CodeGenObjC/debug-info-blocks.m
@@ -4,11 +4,18 @@
 // Test that we generate the proper debug location for a captured self.
 // The second half of this test is in llvm/tests/DebugInfo/debug-info-blocks.ll
 
-// CHECK: define {{.*}}_block_invoke
-// CHECK: %[[BLOCK:.*]] = bitcast i8* %.block_descriptor to <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0* }>*, !dbg
-// CHECK-NEXT: store <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0* }>* %[[BLOCK]], <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0* }>** %[[ALLOCA:.*]], align
-// CHECK-NEXT: call void @llvm.dbg.declare(metadata <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0* }>** %[[ALLOCA]], metadata ![[SELF:[0-9]+]], metadata !{{.*}})
-// CHECK-NEXT: call void @llvm.dbg.declare(metadata %1** %d, metadata ![[D:[0-9]+]], metadata !{{.*}})
+// CHECK: define {{.*}}[A init]_block_invoke
+// CHECK-NEXT: entry
+// CHECK-NEXT: %[[DESC_ALLOCA:.*]] = alloca i8*, align 8
+// CHECK-NEXT: %[[BLOCK_ALLOCA:.*]] = alloca <{{.*}}>*, align 8
+// CHECK: store i8* %.block_descriptor, i8** %[[ALLOCA:.*]], align 8
+// CHECK: call void @llvm.dbg.declare(metadata i8** %[[DESC_ALLOCA]],
+// CHECK-SAME:                        metadata ![[BLOCK_VAR:[0-9]+]],
+// CHECK: call void @llvm.dbg.declare(
+// CHECK-SAME: metadata <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0* }>**
+// CHECK-SAME:          %[[BLOCK_ALLOCA]], metadata ![[SELF_VAR:[0-9]+]],
+// CHECK-SAME:          metadata ![[SELF_EXPR:[0-9]+]])
+// CHECK: call void @llvm.dbg.declare(metadata %1** %d, metadata ![[D_VAR:[0-9]+]],
 
 // rdar://problem/14386148
 // Test that we don't emit bogus line numbers for the helper functions.
@@ -22,11 +29,13 @@
 // CHECK-NOT: ret
 // CHECK: load {{.*}}, !dbg ![[DESTROY_LINE:[0-9]+]]
 
-// CHECK-DAG: [[DBG_LINE]] = !DILocation(line: 0, scope: ![[COPY_SP:[0-9]+]])
-// CHECK-DAG: [[COPY_LINE]] = !DILocation(line: 0, scope: ![[COPY_SP:[0-9]+]])
-// CHECK-DAG: [[COPY_SP]] = distinct !DISubprogram(name: "__copy_helper_block_"
-// CHECK-DAG: [[DESTROY_LINE]] = !DILocation(line: 0, scope: ![[DESTROY_SP:[0-9]+]])
-// CHECK-DAG: [[DESTROY_SP]] = distinct !DISubprogram(name: "__destroy_helper_block_"
+// CHECK-DAG: ![[DBG_LINE]] = !DILocation(line: 0, scope: ![[COPY_SP:[0-9]+]])
+// CHECK-DAG: ![[COPY_LINE]] = !DILocation(line: 0, scope: ![[COPY_SP:[0-9]+]])
+// CHECK-DAG: ![[COPY_SP]] = distinct !DISubprogram(name: "__copy_helper_block_"
+// CHECK-DAG: ![[DESTROY_LINE]] = !DILocation(line: 0, scope: ![[DESTROY_SP:[0-9]+]])
+// CHECK-DAG: ![[DESTROY_SP]] = distinct !DISubprogram(name: "__destroy_helper_block_"
+// CHECK-DAG: ![[BLOCK_VAR]] = !DILocalVariable(name: ".block_descriptor"
+// CHECK-DAG: ![[SELF_EXPR]] = !DIExpression(DW_OP_plus, 32, DW_OP_deref)
 typedef unsigned int NSUInteger;
 
 @protocol NSObject
@@ -61,8 +70,8 @@
 {
     if ((self = [super init])) {
       run(^{
-          // CHECK-DAG: ![[SELF]] = !DILocalVariable(name: "self", scope:{{.*}}, line: [[@LINE+4]],
-          // CHECK-DAG: ![[D]] = !DILocalVariable(name: "d", scope:{{.*}}, line: [[@LINE+1]],
+          // CHECK-DAG: ![[SELF_VAR]] = !DILocalVariable(name: "self", scope:{{.*}}, line: [[@LINE+4]],
+          // CHECK-DAG: ![[D_VAR]] = !DILocalVariable(name: "d", scope:{{.*}}, line: [[@LINE+1]],
           NSMutableDictionary *d = [[NSMutableDictionary alloc] init]; 
           ivar = 42 + (int)[d count];
         });
Index: test/CodeGenObjC/debug-info-block-captured-self.m
===================================================================
--- test/CodeGenObjC/debug-info-block-captured-self.m
+++ test/CodeGenObjC/debug-info-block-captured-self.m
@@ -56,16 +56,22 @@
 // CHECK-NEXT:   [[DBGADDR:%.*]] = alloca [[BLOCK_T:<{.*}>]]*, align 8
 // CHECK:        store i8* [[BLOCK_DESC:%.*]], i8** %[[MEM1]], align 8
 // CHECK:        %[[TMP0:.*]] = load i8*, i8** %[[MEM1]]
-// CHECK:        call void @llvm.dbg.value(metadata i8* %[[TMP0]], i64 0, metadata ![[BDMD:[0-9]+]], metadata !{{.*}})
-// CHECK:        call void @llvm.dbg.declare(metadata i8* [[BLOCK_DESC]], metadata ![[BDMD:[0-9]+]], metadata !{{.*}})
+// CHECK:        call void @llvm.dbg.declare(metadata i8** %[[MEM1]],
+// CHECK-SAME:                               metadata ![[BDMD:[0-9]+]],
+// CHECK-SAME:                               metadata ![[EMPTY:[0-9]+]])
 // CHECK:        store [[BLOCK_T]]* {{%.*}}, [[BLOCK_T]]** [[DBGADDR]], align 8
-// CHECK:        call void @llvm.dbg.declare(metadata [[BLOCK_T]]** [[DBGADDR]], metadata ![[SELF:.*]], metadata !{{.*}})
+// CHECK:        call void @llvm.dbg.declare(metadata [[BLOCK_T]]** [[DBGADDR]],
+// CHECK-SAME:                               metadata ![[SELF:[0-9]+]],
+// CHECK-SAME:                               metadata ![[EXPR:[0-9]+]])
+
 // make sure we are still in the same function
 // CHECK: define {{.*}}__copy_helper_block_
 // Metadata
 // CHECK: ![[MAIN:.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Main"
 // CHECK-SAME:                            line: 23,
 // CHECK: ![[PMAIN:.*]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[MAIN]],
+// CHECK: ![[EMPTY]] = !DIExpression()
+// CHECK: ![[EXPR]] = !DIExpression(DW_OP_plus, 32, DW_OP_deref)
 // CHECK: ![[BDMD]] = !DILocalVariable(name: ".block_descriptor", arg:
 // CHECK: ![[SELF]] = !DILocalVariable(name: "self"
 // CHECK-NOT:                          arg:
Index: lib/CodeGen/CGDebugInfo.h
===================================================================
--- lib/CodeGen/CGDebugInfo.h
+++ lib/CodeGen/CGDebugInfo.h
@@ -397,8 +397,9 @@
   /// Emit call to \c llvm.dbg.declare for the block-literal argument
   /// to a block invocation function.
   void EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block,
-                                            llvm::Value *Arg, unsigned ArgNo,
-                                            llvm::Value *LocalAddr,
+                                            StringRef Name,
+                                            llvm::Value *Storage,
+                                            unsigned ArgNo,
                                             CGBuilderTy &Builder);
 
   /// Emit information about a global variable.
Index: lib/CodeGen/CGDebugInfo.cpp
===================================================================
--- lib/CodeGen/CGDebugInfo.cpp
+++ lib/CodeGen/CGDebugInfo.cpp
@@ -3473,11 +3473,11 @@
       offset = CGM.getContext().toCharUnitsFromBits(
           CGM.getTarget().getPointerWidth(0));
       Expr.push_back(offset.getQuantity());
-      Expr.push_back(llvm::dwarf::DW_OP_deref);
       Expr.push_back(llvm::dwarf::DW_OP_plus);
       // offset of x field
       offset = CGM.getContext().toCharUnitsFromBits(XOffset);
       Expr.push_back(offset.getQuantity());
+      Expr.push_back(llvm::dwarf::DW_OP_deref);
 
       // Create the descriptor for the variable.
       auto *D = ArgNo
@@ -3596,22 +3596,21 @@
           ->getElementOffset(blockInfo.getCapture(VD).getIndex()));
 
   SmallVector<int64_t, 9> addr;
-  if (isa<llvm::AllocaInst>(Storage))
-    addr.push_back(llvm::dwarf::DW_OP_deref);
   addr.push_back(llvm::dwarf::DW_OP_plus);
-  addr.push_back(offset.getQuantity());
+  addr.push_back(offset.getQuantity()); 
+  addr.push_back(llvm::dwarf::DW_OP_deref);
   if (isByRef) {
-    addr.push_back(llvm::dwarf::DW_OP_deref);
-    addr.push_back(llvm::dwarf::DW_OP_plus);
+    addr.push_back(llvm::dwarf::DW_OP_plus); 
     // offset of __forwarding field
     offset =
         CGM.getContext().toCharUnitsFromBits(target.getPointerSizeInBits(0));
-    addr.push_back(offset.getQuantity());
+    addr.push_back(offset.getQuantity()); 
     addr.push_back(llvm::dwarf::DW_OP_deref);
     addr.push_back(llvm::dwarf::DW_OP_plus);
     // offset of x field
     offset = CGM.getContext().toCharUnitsFromBits(XOffset);
     addr.push_back(offset.getQuantity());
+    addr.push_back(llvm::dwarf::DW_OP_deref);
   }
 
   // Create the descriptor for the variable.
@@ -3649,9 +3648,9 @@
 }
 
 void CGDebugInfo::EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block,
-                                                       llvm::Value *Arg,
+                                                       StringRef Name,
+                                                       llvm::Value *Storage,
                                                        unsigned ArgNo,
-                                                       llvm::Value *LocalAddr,
                                                        CGBuilderTy &Builder) {
   assert(DebugKind >= codegenoptions::LimitedDebugInfo);
   ASTContext &C = CGM.getContext();
@@ -3783,19 +3782,10 @@
 
   // Create the descriptor for the parameter.
   auto *debugVar = DBuilder.createParameterVariable(
-      scope, Arg->getName(), ArgNo, tunit, line, type,
-      CGM.getLangOpts().Optimize, flags);
-
-  if (LocalAddr) {
-    // Insert an llvm.dbg.value into the current block.
-    DBuilder.insertDbgValueIntrinsic(
-        LocalAddr, 0, debugVar, DBuilder.createExpression(),
-        llvm::DebugLoc::get(line, column, scope, CurInlinedAt),
-        Builder.GetInsertBlock());
-  }
+      scope, Name, ArgNo, tunit, line, type, CGM.getLangOpts().Optimize, flags);
 
   // Insert an llvm.dbg.declare into the current block.
-  DBuilder.insertDeclare(Arg, debugVar, DBuilder.createExpression(),
+  DBuilder.insertDeclare(Storage, debugVar, DBuilder.createExpression(),
                          llvm::DebugLoc::get(line, column, scope, CurInlinedAt),
                          Builder.GetInsertBlock());
 }
Index: lib/CodeGen/CGBlocks.cpp
===================================================================
--- lib/CodeGen/CGBlocks.cpp
+++ lib/CodeGen/CGBlocks.cpp
@@ -1170,30 +1170,25 @@
                                                llvm::Value *arg) {
   assert(BlockInfo && "not emitting prologue of block invocation function?!");
 
-  llvm::Value *localAddr = nullptr;
-  if (CGM.getCodeGenOpts().OptimizationLevel == 0) {
-    // Allocate a stack slot to let the debug info survive the RA.
-    Address alloc = CreateMemTemp(D->getType(), D->getName() + ".addr");
-    Builder.CreateStore(arg, alloc);
-    localAddr = Builder.CreateLoad(alloc);
-  }
+  // Allocate a stack slot to let the debug info survive the RA.
+  Address LocalAddrAlloca = CreateMemTemp(D->getType(), D->getName() + ".addr");
+  Builder.CreateStore(arg, LocalAddrAlloca);
+  auto *localAddr = Builder.CreateLoad(LocalAddrAlloca);
 
   if (CGDebugInfo *DI = getDebugInfo()) {
-    if (CGM.getCodeGenOpts().getDebugInfo() >=
-        codegenoptions::LimitedDebugInfo) {
-      DI->setLocation(D->getLocation());
-      DI->EmitDeclareOfBlockLiteralArgVariable(*BlockInfo, arg, argNum,
-                                               localAddr, Builder);
-    }
+    DI->setLocation(D->getLocation());
+    DI->EmitDeclareOfBlockLiteralArgVariable(*BlockInfo, arg->getName(),
+                                             LocalAddrAlloca.getPointer(),
+                                             argNum, Builder);
   }
 
   SourceLocation StartLoc = BlockInfo->getBlockExpr()->getBody()->getLocStart();
   ApplyDebugLocation Scope(*this, StartLoc);
 
   // Instead of messing around with LocalDeclMap, just set the value
   // directly as BlockPointer.
   BlockPointer = Builder.CreatePointerCast(
-      arg,
+      localAddr,
       BlockInfo->StructureType->getPointerTo(
           getContext().getLangOpts().OpenCL
               ? getContext().getTargetAddressSpace(LangAS::opencl_generic)
@@ -1275,21 +1270,15 @@
                 blockInfo.getBlockExpr()->getBody()->getLocStart());
 
   // Okay.  Undo some of what StartFunction did.
-
-  // At -O0 we generate an explicit alloca for the BlockPointer, so the RA
-  // won't delete the dbg.declare intrinsics for captured variables.
   llvm::Value *BlockPointerDbgLoc = BlockPointer;
-  if (CGM.getCodeGenOpts().OptimizationLevel == 0) {
-    // Allocate a stack slot for it, so we can point the debugger to it
-    Address Alloca = CreateTempAlloca(BlockPointer->getType(),
-                                      getPointerAlign(),
-                                      "block.addr");
-    // Set the DebugLocation to empty, so the store is recognized as a
-    // frame setup instruction by llvm::DwarfDebug::beginFunction().
-    auto NL = ApplyDebugLocation::CreateEmpty(*this);
-    Builder.CreateStore(BlockPointer, Alloca);
-    BlockPointerDbgLoc = Alloca.getPointer();
-  }
+  // Allocate a stack slot for it, so we can point the debugger to it
+  Address Alloca = CreateTempAlloca(BlockPointer->getType(), getPointerAlign(),
+                                    "block.addr");
+  // Set the DebugLocation to empty, so the store is recognized as a
+  // frame setup instruction by llvm::DwarfDebug::beginFunction().
+  auto NL = ApplyDebugLocation::CreateEmpty(*this);
+  Builder.CreateStore(BlockPointer, Alloca);
+  BlockPointerDbgLoc = Alloca.getPointer();
 
   // If we have a C++ 'this' reference, go ahead and force it into
   // existence now.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to