[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