From 5af06ba7dc26f614989a9a9e16e69f6ecc811519 Mon Sep 17 00:00:00 2001 From: Adrian Vogelsgesang Date: Wed, 24 Aug 2022 10:27:23 -0700 Subject: [PATCH] [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 --- llvm/lib/Transforms/Coroutines/CoroEarly.cpp | 23 ++++++++++++++- llvm/test/Transforms/Coroutines/coro-noop.ll | 33 ++++++++++++++++++++++ .../{coro-early.ll => coro-resume-destroy.ll} | 19 ------------- 3 files changed, 55 insertions(+), 20 deletions(-) create mode 100644 llvm/test/Transforms/Coroutines/coro-noop.ll rename llvm/test/Transforms/Coroutines/{coro-early.ll => coro-resume-destroy.ll} (63%) diff --git a/llvm/lib/Transforms/Coroutines/CoroEarly.cpp b/llvm/lib/Transforms/Coroutines/CoroEarly.cpp index dd7cb23..d510b90 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 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 0000000..23533c8 --- /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: "", 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 0489372..86e4a81 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() -- 2.7.4