[llvm] 5af06ba - [Coro][Debuginfo] Add debug info to `__NoopCoro_ResumeDestroy` function

Adrian Vogelsgesang via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 26 05:50:23 PDT 2022


Author: Adrian Vogelsgesang
Date: 2022-08-26T05:49:52-07:00
New Revision: 5af06ba7dc26f614989a9a9e16e69f6ecc811519

URL: https://github.com/llvm/llvm-project/commit/5af06ba7dc26f614989a9a9e16e69f6ecc811519
DIFF: https://github.com/llvm/llvm-project/commit/5af06ba7dc26f614989a9a9e16e69f6ecc811519.diff

LOG: [Coro][Debuginfo] Add debug info to `__NoopCoro_ResumeDestroy` function

With this commit, we now attach an `DISubprogram` to the LLVM-generated
`_NoopCoro_ResumeDestroy` function. Thereby, lldb can show a
`std::coroutine_handle` to a `std::noop_coroutine` as

```
continuation = coro frame = 0x555555560d98 {
  resume = 0x0000555555555c50 (a.out`__NoopCoro_ResumeDestroy)
  destroy = 0x0000555555555c50 (a.out`__NoopCoro_ResumeDestroy)
}
```

instead of

```
continuation = coro frame = 0x555555560d98 {
  resume = 0x0000555555555c50 (a.out`___lldb_unnamed_symbol211)
  destroy = 0x0000555555555c50 (a.out`___lldb_unnamed_symbol211)
}
```

I renamed the function from `NoopCoro.ResumeDestroy` to
`_NoopCoro_ResumeDestroy` because:
* the leading `_` makes sure this is a reserved name and should not
  clash with any user-provided names
* the `.` was replaced by a `_`, so the name is now a valid identifier
  in C, making it allows me to type its name in the debugger

Differential Revision: https://reviews.llvm.org/D132580

Added: 
    llvm/test/Transforms/Coroutines/coro-noop.ll
    llvm/test/Transforms/Coroutines/coro-resume-destroy.ll

Modified: 
    llvm/lib/Transforms/Coroutines/CoroEarly.cpp

Removed: 
    llvm/test/Transforms/Coroutines/coro-early.ll


################################################################################
diff  --git a/llvm/lib/Transforms/Coroutines/CoroEarly.cpp b/llvm/lib/Transforms/Coroutines/CoroEarly.cpp
index dd7cb23f3f3d..d510b90d9dec 100644
--- a/llvm/lib/Transforms/Coroutines/CoroEarly.cpp
+++ b/llvm/lib/Transforms/Coroutines/CoroEarly.cpp
@@ -8,6 +8,7 @@
 
 #include "llvm/Transforms/Coroutines/CoroEarly.h"
 #include "CoroInternal.h"
+#include "llvm/IR/DIBuilder.h"
 #include "llvm/IR/Function.h"
 #include "llvm/IR/IRBuilder.h"
 #include "llvm/IR/InstIterator.h"
@@ -100,6 +101,25 @@ void Lowerer::lowerCoroDone(IntrinsicInst *II) {
   II->eraseFromParent();
 }
 
+static void buildDebugInfoForNoopResumeDestroyFunc(Function *NoopFn) {
+  Module &M = *NoopFn->getParent();
+  if (M.debug_compile_units().empty())
+     return;
+
+  DICompileUnit *CU = *M.debug_compile_units_begin();
+  DIBuilder DB(M, /*AllowUnresolved*/ false, CU);
+  std::array<Metadata *, 2> Params{nullptr, nullptr};
+  auto *SubroutineType =
+      DB.createSubroutineType(DB.getOrCreateTypeArray(Params));
+  StringRef Name = NoopFn->getName();
+  auto *SP = DB.createFunction(
+      CU, /*Name=*/Name, /*LinkageName=*/Name, /*File=*/ CU->getFile(),
+      /*LineNo=*/0, SubroutineType, /*ScopeLine=*/0, DINode::FlagArtificial,
+      DISubprogram::SPFlagDefinition);
+  NoopFn->setSubprogram(SP);
+  DB.finalize();
+}
+
 void Lowerer::lowerCoroNoop(IntrinsicInst *II) {
   if (!NoopCoro) {
     LLVMContext &C = Builder.getContext();
@@ -116,8 +136,9 @@ void Lowerer::lowerCoroNoop(IntrinsicInst *II) {
     // Create a Noop function that does nothing.
     Function *NoopFn =
         Function::Create(FnTy, GlobalValue::LinkageTypes::PrivateLinkage,
-                         "NoopCoro.ResumeDestroy", &M);
+                         "__NoopCoro_ResumeDestroy", &M);
     NoopFn->setCallingConv(CallingConv::Fast);
+    buildDebugInfoForNoopResumeDestroyFunc(NoopFn);
     auto *Entry = BasicBlock::Create(C, "entry", NoopFn);
     ReturnInst::Create(C, Entry);
 

diff  --git a/llvm/test/Transforms/Coroutines/coro-noop.ll b/llvm/test/Transforms/Coroutines/coro-noop.ll
new file mode 100644
index 000000000000..23533c87a18f
--- /dev/null
+++ b/llvm/test/Transforms/Coroutines/coro-noop.ll
@@ -0,0 +1,33 @@
+; Tests that CoroEarly pass correctly lowers coro.noop
+; RUN: opt < %s -S -passes=coro-early | FileCheck %s
+
+; CHECK: %NoopCoro.Frame = type { void (%NoopCoro.Frame*)*, void (%NoopCoro.Frame*)* }
+; CHECK: @NoopCoro.Frame.Const = private constant %NoopCoro.Frame { void (%NoopCoro.Frame*)* @__NoopCoro_ResumeDestroy, void (%NoopCoro.Frame*)* @__NoopCoro_ResumeDestroy }
+
+
+; CHECK-LABEL: @noop(
+define i8* @noop() {
+; CHECK-NEXT: entry
+entry:
+; CHECK-NEXT: ret i8* bitcast (%NoopCoro.Frame* @NoopCoro.Frame.Const to i8*)
+  %n = call i8* @llvm.coro.noop()
+  ret i8* %n
+}
+
+declare i8* @llvm.coro.noop()
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "hand-written", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
+!1 = !DIFile(filename: "<stdin>", directory: "")
+!2 = !{}
+!3 = !{i32 2, !"Dwarf Version", i32 4}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+
+
+; CHECK: define private fastcc void @__NoopCoro_ResumeDestroy(%NoopCoro.Frame* %0) !dbg ![[RESUME:[0-9]+]] {
+; CHECK-NEXT: entry
+; CHECK-NEXT:    ret void
+
+; CHECK: ![[RESUME]] = distinct !DISubprogram(name: "__NoopCoro_ResumeDestroy", linkageName: "__NoopCoro_ResumeDestroy", {{.*}} flags: DIFlagArtificial,

diff  --git a/llvm/test/Transforms/Coroutines/coro-early.ll b/llvm/test/Transforms/Coroutines/coro-resume-destroy.ll
similarity index 63%
rename from llvm/test/Transforms/Coroutines/coro-early.ll
rename to llvm/test/Transforms/Coroutines/coro-resume-destroy.ll
index 048937223279..86e4a814f58c 100644
--- a/llvm/test/Transforms/Coroutines/coro-early.ll
+++ b/llvm/test/Transforms/Coroutines/coro-resume-destroy.ll
@@ -1,10 +1,6 @@
 ; Tests that CoroEarly pass correctly lowers coro.resume, coro.destroy
-; and other intrinsics managed by this pass.
 ; RUN: opt < %s -S -passes=coro-early | FileCheck %s
 
-; CHECK: %NoopCoro.Frame = type { void (%NoopCoro.Frame*)*, void (%NoopCoro.Frame*)* }
-; CHECK: @NoopCoro.Frame.Const = private constant %NoopCoro.Frame { void (%NoopCoro.Frame*)* @NoopCoro.ResumeDestroy, void (%NoopCoro.Frame*)* @NoopCoro.ResumeDestroy }
-
 ; CHECK-LABEL: @callResume(
 define void @callResume(i8* %hdl) {
 ; CHECK-NEXT: entry
@@ -41,20 +37,5 @@ ehcleanup:
 }
 
 
-; CHECK-LABEL: @noop(
-define i8* @noop() {
-; CHECK-NEXT: entry
-entry:
-; CHECK-NEXT: ret i8* bitcast (%NoopCoro.Frame* @NoopCoro.Frame.Const to i8*)
-  %n = call i8* @llvm.coro.noop()
-  ret i8* %n
-}
-
-; CHECK-LABEL: define private fastcc void @NoopCoro.ResumeDestroy(%NoopCoro.Frame* %0) {
-; CHECK-NEXT: entry
-; CHECK-NEXT:    ret void
-
-
 declare void @llvm.coro.resume(i8*)
 declare void @llvm.coro.destroy(i8*)
-declare i8* @llvm.coro.noop()


        


More information about the llvm-commits mailing list