Skip to content
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

Revise unwind-table emission, enabling them for most popular targets #4888

Open
wants to merge 1 commit into
base: master
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: 0 additions & 2 deletions .github/actions/4d-test-libs/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ runs:
excludes+='|^std.internal.math.gammafunction'
# FIXME: failing unittest(s) with enabled optimizations
excludes+='|^std.math.exponential(-shared)?$'
# FIXME: subtest rt_trap_exceptions fails
excludes+='|^druntime-test-exceptions-debug$'
Copy link
Member Author

@kinke kinke Mar 21, 2025

Choose a reason for hiding this comment

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

Damn, I hoped this would fix this subtest on Linux AArch64, but it doesn't.

# FIXME: sporadically hanging
excludes+='|^core.thread-shared$'
fi
Expand Down
4 changes: 4 additions & 0 deletions gen/abi/aarch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ struct AArch64TargetABI : TargetABI {
public:
AArch64TargetABI() {}

llvm::UWTableKind defaultUnwindTableKind() override {
return isDarwin() ? llvm::UWTableKind::Sync : llvm::UWTableKind::Async;
}

bool returnInArg(TypeFunction *tf, bool) override {
Type *rt = tf->next->toBasetype();
if (rt->ty == TY::Tstruct || rt->ty == TY::Tsarray) {
Expand Down
11 changes: 11 additions & 0 deletions gen/abi/abi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,17 @@ llvm::CallingConv::ID TargetABI::callingConv(FuncDeclaration *fdecl) {
return callingConv(tf, fdecl->needThis() || fdecl->isNested());
}

void TargetABI::setUnwindTableKind(llvm::Function *fn) {
llvm::UWTableKind kind = defaultUnwindTableKind();
#if LDC_LLVM_VER >= 1600
fn->setUWTableKind(kind);
#else
if (kind != llvm::UWTableKind::None) {
fn->setUWTableKind(kind);
}
#endif
}

//////////////////////////////////////////////////////////////////////////////

bool TargetABI::returnInArg(TypeFunction *tf, bool needsThis) {
Expand Down
14 changes: 8 additions & 6 deletions gen/abi/abi.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "dmd/globals.h"
#include "gen/dvalue.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/Support/CodeGen.h" // for UWTableKind
#include <vector>

class Type;
Expand All @@ -33,6 +34,7 @@ namespace llvm {
class Type;
class Value;
class FunctionType;
class Function;
}

/// Transforms function arguments and return values.
Expand Down Expand Up @@ -110,14 +112,14 @@ struct TargetABI {
return name;
}

/// Returns true if all functions require the LLVM uwtable attribute.
virtual bool needsUnwindTables() {
// Condensed logic of Clang implementations of
// `clang::ToolChain::IsUnwindTablesDefault()` based on early Clang 5.0.
return global.params.targetTriple->getArch() == llvm::Triple::x86_64 ||
global.params.targetTriple->getOS() == llvm::Triple::NetBSD;
/// Returns the default unwind-table kind for all functions.
/// Analogous to clang's ToolChain::getDefaultUnwindTableLevel().
virtual llvm::UWTableKind defaultUnwindTableKind() {
return llvm::UWTableKind::None;
}

void setUnwindTableKind(llvm::Function *fn);

/// Returns true if the target is darwin-based.
bool isDarwin() {
return global.params.targetTriple->isOSDarwin();
Expand Down
7 changes: 7 additions & 0 deletions gen/abi/arm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ struct ArmTargetABI : TargetABI {
CompositeToArray64 compositeToArray64;
IntegerRewrite integerRewrite;

llvm::UWTableKind defaultUnwindTableKind() override {
const auto &triple = *global.params.targetTriple;
return triple.isOSLinux() || triple.isOSOpenBSD()
? llvm::UWTableKind::None
: llvm::UWTableKind::Async;
}

bool returnInArg(TypeFunction *tf, bool) override {
// AAPCS 5.4 wants composites > 4-bytes returned by arg except for
// Homogeneous Aggregates of up-to 4 float types (6.1.2.1) - an HFA.
Expand Down
4 changes: 0 additions & 4 deletions gen/abi/nvptx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,6 @@ struct NVPTXTargetABI : TargetABI {
pointerRewite.applyTo(arg);
}
}
// There are no exceptions at all, so no need for unwind tables.
bool needsUnwindTables() override {
return false;
}
};

TargetABI *createNVPTXABI() { return new NVPTXTargetABI(); }
4 changes: 4 additions & 0 deletions gen/abi/ppc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ struct PPCTargetABI : TargetABI {

explicit PPCTargetABI(const bool Is64Bit) : Is64Bit(Is64Bit) {}

llvm::UWTableKind defaultUnwindTableKind() override {
return llvm::UWTableKind::Async;
}

bool returnInArg(TypeFunction *tf, bool) override {
Type *rt = tf->next->toBasetype();

Expand Down
4 changes: 4 additions & 0 deletions gen/abi/ppc64le.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ struct PPC64LETargetABI : TargetABI {

explicit PPC64LETargetABI() : hfvaToArray(8) {}

llvm::UWTableKind defaultUnwindTableKind() override {
return llvm::UWTableKind::Async;
}

bool passByVal(TypeFunction *, Type *t) override {
t = t->toBasetype();
return isPOD(t) &&
Expand Down
5 changes: 5 additions & 0 deletions gen/abi/riscv64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,11 @@ struct RISCV64TargetABI : TargetABI {
IntegerRewrite integerRewrite;

public:
llvm::UWTableKind defaultUnwindTableKind() override {
return global.params.targetTriple->isOSLinux() ? llvm::UWTableKind::Async
: llvm::UWTableKind::None;
}

Type *vaListType() override {
// va_list is void*
return pointerTo(Type::tvoid);
Expand Down
4 changes: 0 additions & 4 deletions gen/abi/spirv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,6 @@ struct SPIRVTargetABI : TargetABI {
pointerRewite.applyTo(arg);
}
}
// There are no exceptions at all, so no need for unwind tables.
bool needsUnwindTables() override {
return false;
}
};

TargetABI *createSPIRVABI() { return new SPIRVTargetABI(); }
4 changes: 4 additions & 0 deletions gen/abi/win64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ struct Win64TargetABI : TargetABI {
return name;
}

llvm::UWTableKind defaultUnwindTableKind() override {
return llvm::UWTableKind::Async;
}

bool returnInArg(TypeFunction *tf, bool needsThis) override {
Type *rt = tf->next->toBasetype();

Expand Down
4 changes: 4 additions & 0 deletions gen/abi/x86-64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,10 @@ struct X86_64TargetABI : TargetABI {
ImplicitByvalRewrite byvalRewrite;
IndirectByvalRewrite indirectByvalRewrite;

llvm::UWTableKind defaultUnwindTableKind() override {
return llvm::UWTableKind::Async;
}

bool returnInArg(TypeFunction *tf, bool needsThis) override;

bool preferPassByRef(Type *t) override;
Expand Down
4 changes: 4 additions & 0 deletions gen/abi/x86.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ struct X86TargetABI : TargetABI {
return name;
}

llvm::UWTableKind defaultUnwindTableKind() override {
return isMSVC ? llvm::UWTableKind::None : llvm::UWTableKind::Async;
}

// Helper folding the magic __c_complex_{float,double,real} enums to the basic
// complex type.
static Type *getExtraLoweredReturnType(TypeFunction *tf) {
Expand Down
4 changes: 1 addition & 3 deletions gen/functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1148,9 +1148,7 @@ void DtoDefineFunction(FuncDeclaration *fd, bool linkageAvailableExternally) {
}

// function attributes
if (gABI->needsUnwindTables()) {
func->setUWTableKind(llvm::UWTableKind::Default);
}
gABI->setUnwindTableKind(func);
if (opts::isAnySanitizerEnabled() &&
!opts::functionIsInSanitizerBlacklist(fd)) {
// Get the @noSanitize mask
Expand Down
1 change: 1 addition & 0 deletions gen/moduleinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ llvm::Function *buildForwarderFunction(
llvm::Function *fn = llvm::Function::Create(
fnTy, llvm::GlobalValue::InternalLinkage, irMangle, &gIR->module);
fn->setCallingConv(gABI->callingConv(LINK::d));
gABI->setUnwindTableKind(fn);

// Emit the body, consisting of...
const auto bb = llvm::BasicBlock::Create(gIR->context(), "", fn);
Expand Down
5 changes: 1 addition & 4 deletions gen/modules.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -287,10 +287,7 @@ void addCoverageAnalysis(Module *m) {
LLFunction::Create(ctorTy, LLGlobalValue::InternalLinkage,
getIRMangledFuncName(ctorname, LINK::d), &gIR->module);
ctor->setCallingConv(gABI->callingConv(LINK::d));
// Set function attributes. See functions.cpp:DtoDefineFunction()
if (global.params.targetTriple->getArch() == llvm::Triple::x86_64) {
ctor->setUWTableKind(llvm::UWTableKind::Default);
}
gABI->setUnwindTableKind(ctor);

llvm::BasicBlock *bb = llvm::BasicBlock::Create(gIR->context(), "", ctor);
IRBuilder<> builder(bb);
Expand Down
8 changes: 1 addition & 7 deletions gen/runtime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -269,14 +269,8 @@ struct LazyFunctionDeclarer {

fn->setAttributes(attrs);

// On x86_64, always set 'uwtable' for System V ABI compatibility.
// FIXME: Move to better place (abi-x86-64.cpp?)
// NOTE: There are several occurances if this line.
if (global.params.targetTriple->getArch() == llvm::Triple::x86_64) {
fn->setUWTableKind(llvm::UWTableKind::Default);
}

fn->setCallingConv(gABI->callingConv(dty, false));
gABI->setUnwindTableKind(fn);
}
}
};
Expand Down
Loading