[clang] 888ce70 - [DebugInfo] Fix DWARF expressions for __block vars that are not on the heap
Raphael Isemann via cfe-commits
cfe-commits at lists.llvm.org
Mon May 17 05:32:27 PDT 2021
Author: Raphael Isemann
Date: 2021-05-17T14:32:07+02:00
New Revision: 888ce70af288168136cf1ca658c3cf6d6759bb3f
URL: https://github.com/llvm/llvm-project/commit/888ce70af288168136cf1ca658c3cf6d6759bb3f
DIFF: https://github.com/llvm/llvm-project/commit/888ce70af288168136cf1ca658c3cf6d6759bb3f.diff
LOG: [DebugInfo] Fix DWARF expressions for __block vars that are not on the heap
`__block` variables used to be always stored on the head instead of stack.
D51564 allowed `__block` variables to the stored on the stack like normal
variablesif they not captured by any escaping block, but the debug-info
generation code wasn't made aware of it so we still unconditionally emit DWARF
expressions pointing to the heap.
This patch makes CGDebugInfo use the `EscapingByref` introduced in D51564 that
tracks whether the `__block` variable is actually on the heap. If it's stored on
the stack instead we just use the debug info we would generate for normal
variables instead.
Reviewed By: ahatanak, aprantl
Differential Revision: https://reviews.llvm.org/D99946
Added:
Modified:
clang/lib/CodeGen/CGDebugInfo.cpp
clang/test/CodeGen/debug-info-block-expr.c
Removed:
################################################################################
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 3d96bf1964e1..fefcf7a4e973 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -4303,7 +4303,9 @@ llvm::DILocalVariable *CGDebugInfo::EmitDeclare(const VarDecl *VD,
auto *Scope = cast<llvm::DIScope>(LexicalBlockStack.back());
StringRef Name = VD->getName();
if (!Name.empty()) {
- if (VD->hasAttr<BlocksAttr>()) {
+ // __block vars are stored on the heap if they are captured by a block that
+ // can escape the local scope.
+ if (VD->isEscapingByref()) {
// Here, we need an offset *into* the alloca.
CharUnits offset = CharUnits::fromQuantity(32);
Expr.push_back(llvm::dwarf::DW_OP_plus_uconst);
diff --git a/clang/test/CodeGen/debug-info-block-expr.c b/clang/test/CodeGen/debug-info-block-expr.c
index 009e7800b6ee..5626c5c33a4f 100644
--- a/clang/test/CodeGen/debug-info-block-expr.c
+++ b/clang/test/CodeGen/debug-info-block-expr.c
@@ -1,9 +1,55 @@
// RUN: %clang_cc1 -fblocks -debug-info-kind=limited -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -DDEAD_CODE -fblocks -debug-info-kind=limited -emit-llvm -o - %s | FileCheck %s
+
+typedef void (^BlockTy)();
+void escapeFunc(BlockTy);
+typedef void (^BlockTy)();
+void noEscapeFunc(__attribute__((noescape)) BlockTy);
+
+// Verify that the desired DIExpression are generated for escaping (i.e, not
+// 'noescape') blocks.
+void test_escape_func() {
+// CHECK-LABEL: void @test_escape_func
+// CHECK: call void @llvm.dbg.declare({{.*}}metadata ![[ESCAPE_VAR:[0-9]+]], metadata !DIExpression(DW_OP_plus_uconst, {{[0-9]+}}, DW_OP_deref, DW_OP_plus_uconst, {{[0-9]+}}){{.*}})
+ __block int escape_var;
+// Blocks in dead code branches still capture __block variables.
+#ifdef DEAD_CODE
+ if (0)
+#endif
+ escapeFunc(^{ (void)escape_var; });
+}
+
+// Verify that the desired DIExpression are generated for noescape blocks.
+void test_noescape_func() {
+// CHECK-LABEL: void @test_noescape_func
+// CHECK: call void @llvm.dbg.declare({{.*}}metadata ![[NOESCAPE_VAR:[0-9]+]], metadata !DIExpression())
+ __block int noescape_var;
+ noEscapeFunc(^{ (void)noescape_var; });
+}
+
// Verify that the desired DIExpression are generated for blocks.
+void test_local_block() {
+// CHECK-LABEL: void @test_local_block
+// CHECK: call void @llvm.dbg.declare({{.*}}metadata ![[BLOCK_VAR:[0-9]+]], metadata !DIExpression(DW_OP_plus_uconst, {{[0-9]+}}, DW_OP_deref, DW_OP_plus_uconst, {{[0-9]+}}){{.*}})
+ __block int block_var;
-void test() {
-// CHECK: call void @llvm.dbg.declare({{.*}}!DIExpression(DW_OP_plus_uconst, {{[0-9]+}}, DW_OP_deref, DW_OP_plus_uconst, {{[0-9]+}}){{.*}})
- __block int i;
+// CHECK-LABEL: @__test_local_block_block_invoke
// CHECK: call void @llvm.dbg.declare({{.*}}!DIExpression(DW_OP_deref, DW_OP_plus_uconst, {{[0-9]+}}, DW_OP_deref, DW_OP_plus_uconst, {{[0-9]+}}, DW_OP_deref, DW_OP_plus_uconst, {{[0-9]+}}){{.*}})
- ^ { i = 1; }();
+ ^ { block_var = 1; }();
+}
+
+// Verify that the desired DIExpression are generated for __block vars not used
+// in any block.
+void test_unused() {
+// CHECK-LABEL: void @test_unused
+// CHECK: call void @llvm.dbg.declare({{.*}}metadata ![[UNUSED_VAR:[0-9]+]], metadata !DIExpression())
+ __block int unused_var;
+// Use i (not inside a block).
+ ++unused_var;
}
+
+// CHECK: ![[ESCAPE_VAR]] = !DILocalVariable(name: "escape_var"
+// CHECK: ![[NOESCAPE_VAR]] = !DILocalVariable(name: "noescape_var"
+// CHECK: ![[BLOCK_VAR]] = !DILocalVariable(name: "block_var"
+// CHECK: ![[UNUSED_VAR]] = !DILocalVariable(name: "unused_var"
+
More information about the cfe-commits
mailing list