#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"
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();
// 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);
--- /dev/null
+; 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,
; 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
}
-; 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()