Skip to content

[KeyInstrs] Disable key-instructions for coroutine scopes #147551

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
6 changes: 5 additions & 1 deletion clang/lib/CodeGen/CGDebugInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4629,6 +4629,7 @@ void CGDebugInfo::emitFunctionStart(GlobalDecl GD, SourceLocation Loc,
llvm::DIFile *Unit = getOrCreateFile(Loc);
llvm::DIScope *FDContext = Unit;
llvm::DINodeArray TParamsArray;
bool KeyInstructions = CGM.getCodeGenOpts().DebugKeyInstructions;
if (!HasDecl) {
// Use llvm function name.
LinkageName = Fn->getName();
Expand All @@ -4645,6 +4646,9 @@ void CGDebugInfo::emitFunctionStart(GlobalDecl GD, SourceLocation Loc,
}
collectFunctionDeclProps(GD, Unit, Name, LinkageName, FDContext,
TParamsArray, Flags);
// Disable KIs if this is a coroutine.
KeyInstructions =
KeyInstructions && !isa_and_present<CoroutineBodyStmt>(FD->getBody());
} else if (const auto *OMD = dyn_cast<ObjCMethodDecl>(D)) {
Name = getObjCMethodName(OMD);
Flags |= llvm::DINode::FlagPrototyped;
Expand Down Expand Up @@ -4706,7 +4710,7 @@ void CGDebugInfo::emitFunctionStart(GlobalDecl GD, SourceLocation Loc,
llvm::DISubprogram *SP = DBuilder.createFunction(
FDContext, Name, LinkageName, Unit, LineNo, DIFnType, ScopeLine,
FlagsForDef, SPFlagsForDef, TParamsArray.get(), Decl, nullptr,
Annotations, "", CGM.getCodeGenOpts().DebugKeyInstructions);
Annotations, "", KeyInstructions);
Fn->setSubprogram(SP);

// We might get here with a VarDecl in the case we're generating
Expand Down
81 changes: 81 additions & 0 deletions clang/test/DebugInfo/KeyInstructions/coro-dwarf-key-instrs.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// RUN: %clang_cc1 -disable-llvm-optzns -std=c++20 \
// RUN: -triple=x86_64 -dwarf-version=4 -debug-info-kind=limited \
// RUN: -emit-llvm -o - %s -gkey-instructions | \
// RUN: FileCheck %s

// Check that for the coroutine below, we mark the created DISubprogram as
// not having key instructions. This will prevent AsmPrinter from trying to
// instrument the linetable with key-instructions for source-locations in
// the coroutine scope.
//
// This is a temporary workaround for key instructions: we can instrument
// coroutine code in the future, but it hasn't been done yet.
//
// File contents copied from coro-dwarf.cpp.
Copy link
Contributor

Choose a reason for hiding this comment

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

What's the reason for creating this as a new file rather than adding this as a new check in the existing file - is it just to keep the test confined to the KeyInstructions test dir?


namespace std {
template <typename... T> struct coroutine_traits;

template <class Promise = void> struct coroutine_handle {
coroutine_handle() = default;
static coroutine_handle from_address(void *) noexcept;
};
template <> struct coroutine_handle<void> {
static coroutine_handle from_address(void *) noexcept;
coroutine_handle() = default;
template <class PromiseType>
coroutine_handle(coroutine_handle<PromiseType>) noexcept;
};
} // namespace std

struct suspend_always {
bool await_ready() noexcept;
void await_suspend(std::coroutine_handle<>) noexcept;
void await_resume() noexcept;
};

template <typename... Args> struct std::coroutine_traits<void, Args...> {
struct promise_type {
void get_return_object() noexcept;
suspend_always initial_suspend() noexcept;
suspend_always final_suspend() noexcept;
void return_void() noexcept;
promise_type();
~promise_type() noexcept;
void unhandled_exception() noexcept;
};
};

// TODO: Not supported yet
struct CopyOnly {
int val;
CopyOnly(const CopyOnly &) noexcept;
CopyOnly(CopyOnly &&) = delete;
~CopyOnly();
};

struct MoveOnly {
int val;
MoveOnly(const MoveOnly &) = delete;
MoveOnly(MoveOnly &&) noexcept;
~MoveOnly();
};

struct MoveAndCopy {
int val;
MoveAndCopy(const MoveAndCopy &) noexcept;
MoveAndCopy(MoveAndCopy &&) noexcept;
~MoveAndCopy();
};

void consume(int, int, int) noexcept;

void f_coro(int val, MoveOnly moParam, MoveAndCopy mcParam) {
consume(val, moParam.val, mcParam.val);
co_return;
}

// CHECK: ![[SP:[0-9]+]] = distinct !DISubprogram(name: "f_coro", linkageName: "_Z6f_coroi8MoveOnly11MoveAndCopy"
// CHECK-NOT: keyInstructions:
// CHECK: !DIFil

Loading