Index: llvm/include/llvm/IR/DebugInfoMetadata.h =================================================================== --- llvm/include/llvm/IR/DebugInfoMetadata.h +++ llvm/include/llvm/IR/DebugInfoMetadata.h @@ -1951,6 +1951,7 @@ unsigned getVirtualIndex() const { return VirtualIndex; } int getThisAdjustment() const { return ThisAdjustment; } unsigned getScopeLine() const { return ScopeLine; } + void setScopeLine(unsigned L) { assert(isDistinct()); ScopeLine = L; } DIFlags getFlags() const { return Flags; } DISPFlags getSPFlags() const { return SPFlags; } bool isLocalToUnit() const { return getSPFlags() & SPFlagLocalToUnit; } @@ -2010,6 +2011,7 @@ StringRef getName() const { return getStringOperand(2); } StringRef getLinkageName() const { return getStringOperand(3); } + void replaceLinkageName(MDString *LN) { replaceOperandWith(3, LN); } DISubroutineType *getType() const { return cast_or_null(getRawType()); Index: llvm/include/llvm/Transforms/Utils/Cloning.h =================================================================== --- llvm/include/llvm/Transforms/Utils/Cloning.h +++ llvm/include/llvm/Transforms/Utils/Cloning.h @@ -35,6 +35,7 @@ class BlockFrequencyInfo; class CallInst; class CallGraph; +class DISubprogram; class DebugInfoFinder; class DominatorTree; class Function; Index: llvm/lib/Transforms/Coroutines/CoroSplit.cpp =================================================================== --- llvm/lib/Transforms/Coroutines/CoroSplit.cpp +++ llvm/lib/Transforms/Coroutines/CoroSplit.cpp @@ -841,17 +841,24 @@ // so protect against that. auto savedLinkage = NewF->getLinkage(); NewF->setLinkage(llvm::GlobalValue::ExternalLinkage); + auto &Context = NewF->getContext(); CloneFunctionInto(NewF, &OrigF, VMap, CloneFunctionChangeType::LocalChangesOnly, Returns); + // Adjust the scope line of the clone to the line number of the suspend point. + if (DISubprogram *SP = NewF->getSubprogram()) { + assert(SP != OrigF.getSubprogram() && SP->isDistinct()); + if (ActiveSuspend) + if (auto DL = ActiveSuspend->getDebugLoc()) + SP->setScopeLine(DL->getLine()); + SP->replaceLinkageName(MDString::get(Context, NewF->getName())); + } NewF->setLinkage(savedLinkage); NewF->setVisibility(savedVisibility); NewF->setUnnamedAddr(savedUnnamedAddr); NewF->setDLLStorageClass(savedDLLStorageClass); - auto &Context = NewF->getContext(); - // Replace the attributes of the new function: auto OrigAttrs = NewF->getAttributes(); auto NewAttrs = AttributeList(); Index: llvm/test/Transforms/Coroutines/coro-async.ll =================================================================== --- llvm/test/Transforms/Coroutines/coro-async.ll +++ llvm/test/Transforms/Coroutines/coro-async.ll @@ -46,7 +46,7 @@ } -define swiftcc void @my_async_function(i8* %async.ctxt, %async.task* %task, %async.actor* %actor) { +define swiftcc void @my_async_function(i8* %async.ctxt, %async.task* %task, %async.actor* %actor) !dbg !1 { entry: %tmp = alloca { i64, i64 }, align 8 %proj.1 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %tmp, i64 0, i32 0 @@ -84,7 +84,7 @@ i8* %resume.func_ptr, i8* %resume_proj_fun, void (i8*, i8*, %async.task*, %async.actor*)* @my_async_function.my_other_async_function_fp.apply, - i8* %callee, i8* %callee_context, %async.task* %task, %async.actor *%actor) + i8* %callee, i8* %callee_context, %async.task* %task, %async.actor *%actor), !dbg !5 call void @llvm.coro.async.context.dealloc(i8* %callee_context) %continuation_task_arg = extractvalue {i8*, i8*, i8*} %res, 1 @@ -103,7 +103,8 @@ ; CHECK: @my_async_function_fp = constant <{ i32, i32 }> <{ {{.*}}, i32 176 } ; CHECK: @my_async_function2_fp = constant <{ i32, i32 }> <{ {{.*}}, i32 176 } -; CHECK-LABEL: define swiftcc void @my_async_function(i8* %async.ctxt, %async.task* %task, %async.actor* %actor) { +; CHECK-LABEL: define swiftcc void @my_async_function(i8* %async.ctxt, %async.task* %task, %async.actor* %actor) +; CHECK-SAME: !dbg ![[SP1:[0-9]+]] { ; CHECK: entry: ; CHECK: [[FRAMEPTR:%.*]] = getelementptr inbounds i8, i8* %async.ctxt, i64 128 ; CHECK: [[ACTOR_SPILL_ADDR:%.*]] = getelementptr inbounds i8, i8* %async.ctxt, i64 152 @@ -132,7 +133,8 @@ ; CHECK: ret void ; CHECK: } -; CHECK-LABEL: define internal swiftcc void @my_async_function.resume.0(i8* nocapture readonly %0, i8* %1, i8* nocapture readnone %2) { +; CHECK-LABEL: define internal swiftcc void @my_async_function.resume.0(i8* nocapture readonly %0, i8* %1, i8* nocapture readnone %2) +; CHECK-SAME: !dbg ![[SP2:[0-9]+]] { ; CHECK: entryresume.0: ; CHECK: [[CALLER_CONTEXT_ADDR:%.*]] = bitcast i8* %0 to i8** ; CHECK: [[CALLER_CONTEXT:%.*]] = load i8*, i8** [[CALLER_CONTEXT_ADDR]] @@ -511,3 +513,20 @@ declare swiftcc void @asyncReturn(i8*, %async.task*, %async.actor*) declare swiftcc void @asyncSuspend(i8*, %async.task*, %async.actor*) declare i8* @llvm.coro.async.resume() + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!0} + +!0 = !{i32 2, !"Debug Info Version", i32 3} + +; CHECK: ![[SP1]] = distinct !DISubprogram(name: "my_async_function", +; CHECK-SAME: linkageName: "my_async_function", +; CHECK-SAME: scopeLine: 1 +!1 = distinct !DISubprogram(name: "my_async_function", linkageName: "my_async_function", scope:; CHECK: ![[SP2]] = distinct !DISubprogram(name: "my_async_function", +; CHECK-SAME: linkageName: "my_async_function.resume.0", +; CHECK-SAME: scopeLine: 2 + !2, file: !3, line: 1, type: !4, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !2) +!2 = distinct !DICompileUnit(language: DW_LANG_Swift, file: !3, emissionKind: FullDebug) +!3 = !DIFile(filename: "/tmp/1.swift", directory: "/") +!4 = !DISubroutineType(types: !{}) +!5 = !DILocation(line: 2, column: 0, scope: !1) Index: llvm/test/Transforms/Coroutines/coro-debug.ll =================================================================== --- llvm/test/Transforms/Coroutines/coro-debug.ll +++ llvm/test/Transforms/Coroutines/coro-debug.ll @@ -153,12 +153,12 @@ ; CHECK: ![[ORIG]] = distinct !DISubprogram(name: "f", linkageName: "flink" -; CHECK: ![[RESUME]] = distinct !DISubprogram(name: "f", linkageName: "flink" +; CHECK: ![[RESUME]] = distinct !DISubprogram(name: "f", linkageName: "f.resume" ; CHECK: ![[RESUME_COROHDL]] = !DILocalVariable(name: "coro_hdl", scope: ![[RESUME]] ; CHECK: ![[RESUME_X]] = !DILocalVariable(name: "x", arg: 1, scope: ![[RESUME]] ; CHECK: ![[RESUME_DIRECT]] = !DILocalVariable(name: "direct_mem", scope: ![[RESUME]] ; CHECK: ![[RESUME_CONST]] = !DILocalVariable(name: "direct_const", scope: ![[RESUME]] -; CHECK: ![[DESTROY]] = distinct !DISubprogram(name: "f", linkageName: "flink" +; CHECK: ![[DESTROY]] = distinct !DISubprogram(name: "f", linkageName: "f.destroy" -; CHECK: ![[CLEANUP]] = distinct !DISubprogram(name: "f", linkageName: "flink" +; CHECK: ![[CLEANUP]] = distinct !DISubprogram(name: "f", linkageName: "f.cleanup"