Skip to content

[debuginfo][coro] Fix linkage name for clones of coro functions #141889

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/CGVTables.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ static void resolveTopLevelMetadata(llvm::Function *Fn,
auto *DIS = Fn->getSubprogram();
if (!DIS)
return;
auto *NewDIS = DIS->replaceWithDistinct(DIS->clone());
auto *NewDIS = llvm::MDNode::replaceWithDistinct(DIS->clone());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

drive-by?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, drive-by. I was looking up how others used the clone method, and was initially confused by this place here, because it called a static method via an object pointer.

Will update the commit message to mention that this is a drive by NFC

VMap.MD()[DIS].reset(NewDIS);

// Find all llvm.dbg.declare intrinsics and resolve the DILocalVariable nodes
Expand Down
31 changes: 8 additions & 23 deletions llvm/lib/Transforms/Coroutines/CoroSplit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -912,29 +912,14 @@ void coro::BaseCloner::create() {
assert(SP != OrigF.getSubprogram() && SP->isDistinct());
updateScopeLine(ActiveSuspend, *SP);

// Update the linkage name to reflect the modified symbol name. It
// is necessary to update the linkage name in Swift, since the
// mangling changes for resume functions. It might also be the
// right thing to do in C++, but due to a limitation in LLVM's
// AsmPrinter we can only do this if the function doesn't have an
// abstract specification, since the DWARF backend expects the
// abstract specification to contain the linkage name and asserts
// that they are identical.
if (SP->getUnit() &&
SP->getUnit()->getSourceLanguage() == dwarf::DW_LANG_Swift) {
SP->replaceLinkageName(MDString::get(Context, NewF->getName()));
if (auto *Decl = SP->getDeclaration()) {
auto *NewDecl = DISubprogram::get(
Decl->getContext(), Decl->getScope(), Decl->getName(),
NewF->getName(), Decl->getFile(), Decl->getLine(), Decl->getType(),
Decl->getScopeLine(), Decl->getContainingType(),
Decl->getVirtualIndex(), Decl->getThisAdjustment(),
Decl->getFlags(), Decl->getSPFlags(), Decl->getUnit(),
Decl->getTemplateParams(), nullptr, Decl->getRetainedNodes(),
Decl->getThrownTypes(), Decl->getAnnotations(),
Decl->getTargetFuncName());
SP->replaceDeclaration(NewDecl);
}
// Update the linkage name and the functaion name to reflect the modified
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Update the linkage name and the functaion name to reflect the modified
// Update the linkage name and the function name to reflect the modified

// name.
MDString *NewLinkageName = MDString::get(Context, NewF->getName());
SP->replaceLinkageName(NewLinkageName);
if (DISubprogram *Decl = SP->getDeclaration()) {
TempDISubprogram NewDecl = Decl->clone();
NewDecl->replaceLinkageName(NewLinkageName);
SP->replaceDeclaration(MDNode::replaceWithUniqued(std::move(NewDecl)));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@
; RUN: opt < %s -passes='module(coro-early),cgscc(coro-split,coro-split)' -S | FileCheck %s
;
; This file is based on coro-debug-frame-variable.ll.
; CHECK: define internal fastcc void @f.resume(ptr noundef nonnull align 16 dereferenceable(80) %begin) !dbg ![[RESUME_FN_DBG_NUM:[0-9]+]]
; CHECK: define internal fastcc void @_Z3foov.resume(ptr noundef nonnull align 16 dereferenceable(80) %begin) !dbg ![[RESUME_FN_DBG_NUM:[0-9]+]]
; CHECK: await.ready:
; CHECK: #dbg_value(i32 poison, ![[IVAR_RESUME:[0-9]+]], !DIExpression(
; CHECK: #dbg_value(i32 poison, ![[JVAR_RESUME:[0-9]+]], !DIExpression(
;
; CHECK: ![[RESUME_FN_DBG_NUM]] = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov"
; CHECK: ![[RESUME_FN_DBG_NUM]] = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov.resume"
; CHECK: ![[IVAR_RESUME]] = !DILocalVariable(name: "i"
; CHECK: ![[JVAR_RESUME]] = !DILocalVariable(name: "j"

source_filename = "../llvm/test/Transforms/Coroutines/coro-debug-dbg.values-O2.ll"

define void @f(i32 %i, i32 %j) presplitcoroutine !dbg !8 {
define void @_Z3foov(i32 %i, i32 %j) presplitcoroutine !dbg !8 {
entry:
%__promise = alloca i8, align 8
%x = alloca [10 x i32], align 16
Expand Down
10 changes: 5 additions & 5 deletions llvm/test/Transforms/Coroutines/coro-debug-dbg.values.ll
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
; RUN: opt < %s -passes='module(coro-early),cgscc(coro-split,coro-split)' -S | FileCheck %s
;
; This file is based on coro-debug-frame-variable.ll.
; CHECK-LABEL: define void @f(
; CHECK-LABEL: define void @_Z3foov(
; CHECK: %[[frame:.*]] = call {{.*}} @llvm.coro.begin
; CHECK: #dbg_value(ptr %[[frame]]
; CHECK-SAME: !DIExpression(DW_OP_plus_uconst, [[OffsetX:[0-9]*]]),
Expand All @@ -20,7 +20,7 @@
; CHECK: #dbg_value(ptr %[[frame]]
; CHECK-SAME: !DIExpression(DW_OP_plus_uconst, [[OffsetJ:[0-9]*]], DW_OP_deref),

; CHECK-LABEL: void @f.resume(
; CHECK-LABEL: void @_Z3foov.resume(
; CHECK-SAME: ptr {{.*}} %[[frame:.*]])
; CHECK-SAME: !dbg ![[RESUME_FN_DBG_NUM:[0-9]+]]
; CHECK: %[[frame_alloca:.*]] = alloca ptr
Expand All @@ -37,7 +37,7 @@
; CHECK: #dbg_value(ptr %[[frame_alloca]], ![[JVAR_RESUME:[0-9]+]],
; CHECK-SAME: !DIExpression(DW_OP_deref, DW_OP_plus_uconst, [[OffsetJ]], DW_OP_deref)
;
; CHECK: ![[RESUME_FN_DBG_NUM]] = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov"
; CHECK: ![[RESUME_FN_DBG_NUM]] = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov.resume"
; CHECK: ![[FRAME_DI_NUM]] = !DILocalVariable(name: "__coro_frame"
; CHECK: ![[IVAR_RESUME]] = !DILocalVariable(name: "i"
; CHECK: ![[XVAR_RESUME]] = !DILocalVariable(name: "x"
Expand All @@ -46,7 +46,7 @@

declare void @consume(i32)

define void @f(i32 %i, i32 %j) presplitcoroutine !dbg !8 {
define void @_Z3foov(i32 %i, i32 %j) presplitcoroutine !dbg !8 {
entry:
%__promise = alloca i8, align 8
%x = alloca [10 x i32], align 16
Expand Down Expand Up @@ -257,4 +257,4 @@ attributes #4 = { argmemonly nofree nosync nounwind willreturn writeonly }
!21 = !DILocation(line: 43, column: 3, scope: !7)
!22 = !DILocation(line: 43, column: 8, scope: !7)
!23 = !DILocalVariable(name: "produced", scope: !7, file: !1, line:24, type: !10)
!30 = distinct !DIAssignID()
!30 = distinct !DIAssignID()
10 changes: 5 additions & 5 deletions llvm/test/Transforms/Coroutines/coro-debug-frame-variable.ll
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@
;
; The CHECKs verify that dbg.declare intrinsics are created for the coroutine
; funclet 'f.resume', and that they reference the address of the variables on
; the coroutine frame. The debug locations for the original function 'f' are
; the coroutine frame. The debug locations for the original function 'foo' are
; static (!11 and !13), whereas the coroutine funclet will have its own new
; ones with identical line and column numbers.
;
; CHECK-LABEL: define void @f() {{.*}} {
; CHECK-LABEL: define void @_Z3foov() {{.*}} {
; CHECK: entry:
; CHECK: %j = alloca i32, align 4
; CHECK: #dbg_declare(ptr %j, ![[JVAR:[0-9]+]], !DIExpression(), ![[JDBGLOC:[0-9]+]]
Expand All @@ -36,7 +36,7 @@
; CHECK: #dbg_declare(ptr %[[MEMORY]], ![[IVAR:[0-9]+]], !DIExpression(DW_OP_plus_uconst, 20), ![[IDBGLOC]]
; CHECK: await.ready:
;
; CHECK-LABEL: define internal fastcc void @f.resume({{.*}}) {{.*}} {
; CHECK-LABEL: define internal fastcc void @_Z3foov.resume({{.*}}) {{.*}} {
; CHECK: entry.resume:
; CHECK-NEXT: %[[DBG_PTR:.*]] = alloca ptr
; CHECK-NEXT: #dbg_declare(ptr %[[DBG_PTR]], ![[XVAR_RESUME:[0-9]+]], !DIExpression(DW_OP_deref, DW_OP_plus_uconst, 32),
Expand All @@ -58,13 +58,13 @@
; CHECK-DAG: ![[JDBGLOC]] = !DILocation(line: 32, column: 7, scope: ![[BLK_SCOPE]])

; CHECK-DAG: ![[XVAR_RESUME]] = !DILocalVariable(name: "x"
; CHECK-DAG: ![[RESUME_PROG_SCOPE:[0-9]+]] = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov"
; CHECK-DAG: ![[RESUME_PROG_SCOPE:[0-9]+]] = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov.resume"
; CHECK-DAG: ![[IDBGLOC_RESUME]] = !DILocation(line: 24, column: 7, scope: ![[RESUME_BLK_SCOPE:[0-9]+]])
; CHECK-DAG: ![[RESUME_BLK_SCOPE]] = distinct !DILexicalBlock(scope: ![[RESUME_PROG_SCOPE]], file: !1, line: 23, column: 12)
; CHECK-DAG: ![[IVAR_RESUME]] = !DILocalVariable(name: "i"
; CHECK-DAG: ![[JVAR_RESUME]] = !DILocalVariable(name: "j"
; CHECK-DAG: ![[JDBGLOC_RESUME]] = !DILocation(line: 32, column: 7, scope: ![[RESUME_BLK_SCOPE]])
define void @f() presplitcoroutine !dbg !8 {
define void @_Z3foov() presplitcoroutine !dbg !8 {
entry:
%__promise = alloca i8, align 8
%i = alloca i32, align 4
Expand Down
18 changes: 9 additions & 9 deletions llvm/test/Transforms/Coroutines/coro-debug.ll
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

; Function Attrs: noinline nounwind
define ptr @f(i32 %x) #0 personality i32 0 !dbg !6 {
define ptr @flink(i32 %x) #0 personality i32 0 !dbg !6 {
entry:
%x.addr = alloca i32, align 4
%coro_hdl = alloca ptr, align 8
store i32 %x, ptr %x.addr, align 4
%0 = call token @llvm.coro.id(i32 0, ptr null, ptr @f, ptr null), !dbg !16
%0 = call token @llvm.coro.id(i32 0, ptr null, ptr @flink, ptr null), !dbg !16
%1 = call i64 @llvm.coro.size.i64(), !dbg !16
%call = call ptr @malloc(i64 %1), !dbg !16
%2 = call ptr @llvm.coro.begin(token %0, ptr %call) #7, !dbg !16
Expand Down Expand Up @@ -170,8 +170,8 @@ attributes #7 = { noduplicate }
!31 = !DILocalVariable(name: "allocated", scope: !6, file: !7, line: 55, type: !11)
!32 = !DILocalVariable(name: "inline_asm", scope: !6, file: !7, line: 55, type: !11)

; CHECK: define ptr @f(i32 %x) #0 personality i32 0 !dbg ![[ORIG:[0-9]+]]
; CHECK: define internal fastcc void @f.resume(ptr noundef nonnull align 8 dereferenceable(40) %0) #0 personality i32 0 !dbg ![[RESUME:[0-9]+]]
; CHECK: define ptr @flink(i32 %x) #0 personality i32 0 !dbg ![[ORIG:[0-9]+]]
; CHECK: define internal fastcc void @flink.resume(ptr noundef nonnull align 8 dereferenceable(40) %0) #0 personality i32 0 !dbg ![[RESUME:[0-9]+]]
; CHECK: entry.resume:
; CHECK: %[[DBG_PTR:.*]] = alloca ptr
; CHECK: #dbg_declare(ptr %[[DBG_PTR]], ![[RESUME_COROHDL:[0-9]+]], !DIExpression(DW_OP_deref, DW_OP_plus_uconst,
Expand All @@ -194,18 +194,18 @@ attributes #7 = { noduplicate }
; CHECK: [[DEFAULT_DEST]]:
; CHECK-NOT: {{.*}}:
; CHECK: #dbg_value(i32 %[[CALLBR_RES]]
; CHECK: define internal fastcc void @f.destroy(ptr noundef nonnull align 8 dereferenceable(40) %0) #0 personality i32 0 !dbg ![[DESTROY:[0-9]+]]
; CHECK: define internal fastcc void @f.cleanup(ptr noundef nonnull align 8 dereferenceable(40) %0) #0 personality i32 0 !dbg ![[CLEANUP:[0-9]+]]
; CHECK: define internal fastcc void @flink.destroy(ptr noundef nonnull align 8 dereferenceable(40) %0) #0 personality i32 0 !dbg ![[DESTROY:[0-9]+]]
; CHECK: define internal fastcc void @flink.cleanup(ptr noundef nonnull align 8 dereferenceable(40) %0) #0 personality i32 0 !dbg ![[CLEANUP:[0-9]+]]

; CHECK: ![[ORIG]] = distinct !DISubprogram(name: "f", linkageName: "flink"

; CHECK: ![[RESUME]] = distinct !DISubprogram(name: "f", linkageName: "flink"
; CHECK: ![[RESUME]] = distinct !DISubprogram(name: "f", linkageName: "flink.resume"
; CHECK: ![[RESUME_COROHDL]] = !DILocalVariable(name: "coro_hdl", scope: ![[RESUME]]
; CHECK: ![[RESUME_X]] = !DILocalVariable(name: "x", arg: 1, scope: ![[RESUME]]
; CHECK: ![[RESUME_CONST]] = !DILocalVariable(name: "direct_const", scope: ![[RESUME]]
; CHECK: ![[RESUME_DIRECT]] = !DILocalVariable(name: "direct_mem", scope: ![[RESUME]]
; CHECK: ![[RESUME_DIRECT_VALUE]] = !DILocalVariable(name: "direct_value", scope: ![[RESUME]]

; CHECK: ![[DESTROY]] = distinct !DISubprogram(name: "f", linkageName: "flink"
; CHECK: ![[DESTROY]] = distinct !DISubprogram(name: "f", linkageName: "flink.destroy"

; CHECK: ![[CLEANUP]] = distinct !DISubprogram(name: "f", linkageName: "flink"
; CHECK: ![[CLEANUP]] = distinct !DISubprogram(name: "f", linkageName: "flink.cleanup"
Loading