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
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits