Skip to content
Draft
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
7 changes: 6 additions & 1 deletion clang/include/clang/CIR/Dialect/IR/CIROps.td
Original file line number Diff line number Diff line change
Expand Up @@ -2224,7 +2224,7 @@ def CIR_GlobalOp : CIR_Op<"global", [
cir::GlobalOp op, mlir::Attribute init,
mlir::ConversionPatternRewriter &rewriter) const;

void setupRegionInitializedLLVMGlobalOp(
mlir::LLVM::GlobalOp setupRegionInitializedLLVMGlobalOp(
cir::GlobalOp op, mlir::ConversionPatternRewriter &rewriter) const;

mutable mlir::LLVM::ComdatOp comdatOp = nullptr;
Expand Down Expand Up @@ -2746,6 +2746,10 @@ def CIR_FuncOp : CIR_Op<"func", [
The `always_inline` attribute marks a function that should always be inlined.
The `inline_hint` attribute suggests that the function should be inlined.

The `personality` attribute specifies the personality function to use for
exception handling. This is a symbol reference to the personality function
(e.g., `@__gxx_personality_v0` for C++ exceptions).

Example:

```mlir
Expand Down Expand Up @@ -2792,6 +2796,7 @@ def CIR_FuncOp : CIR_Op<"func", [
OptionalAttr<DictArrayAttr>:$arg_attrs,
OptionalAttr<DictArrayAttr>:$res_attrs,
OptionalAttr<FlatSymbolRefAttr>:$aliasee,
OptionalAttr<FlatSymbolRefAttr>:$personality,
CIR_OptionalPriorityAttr:$global_ctor_priority,
CIR_OptionalPriorityAttr:$global_dtor_priority,
OptionalAttr<CIR_CXXSpecialMemberAttr>:$cxx_special_member
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/CIR/MissingFeatures.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ struct MissingFeatures {
static bool opFuncNoReturn() { return false; }
static bool setFunctionAttributes() { return false; }
static bool setLLVMFunctionFEnvAttributes() { return false; }
static bool setFunctionPersonality() { return false; }

// CallOp handling
static bool opCallAggregateArgs() { return false; }
Expand Down Expand Up @@ -279,6 +278,7 @@ struct MissingFeatures {

static bool fpConstraints() { return false; }
static bool generateDebugInfo() { return false; }
static bool getRuntimeFunctionDecl() { return false; }
static bool globalViewIndices() { return false; }
static bool globalViewIntLowering() { return false; }
static bool handleBuiltinICEArguments() { return false; }
Expand Down
20 changes: 18 additions & 2 deletions clang/lib/CIR/CodeGen/CIRGenException.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,18 @@ const EHPersonality &EHPersonality::get(CIRGenFunction &cgf) {
return get(cgf.cgm, dyn_cast_or_null<FunctionDecl>(fg));
}

static llvm::StringRef getPersonalityFn(CIRGenModule &cgm,
const EHPersonality &personality) {
// Create the personality function type: i32 (...)
mlir::Type i32Ty = cgm.getBuilder().getI32Type();
auto funcTy = cir::FuncType::get({}, i32Ty, /*isVarArg=*/true);

cir::FuncOp personalityFn = cgm.createRuntimeFunction(
funcTy, personality.personalityFn, mlir::ArrayAttr(), /*isLocal=*/true);

return personalityFn.getSymName();
}

void CIRGenFunction::emitCXXThrowExpr(const CXXThrowExpr *e) {
const llvm::Triple &triple = getTarget().getTriple();
if (cgm.getLangOpts().OpenMPIsTargetDevice &&
Expand Down Expand Up @@ -641,10 +653,14 @@ void CIRGenFunction::populateCatchHandlersIfRequired(cir::TryOp tryOp) {
assert(ehStack.requiresCatchOrCleanup());
assert(!ehStack.empty());

assert(!cir::MissingFeatures::setFunctionPersonality());
const EHPersonality &personality = EHPersonality::get(*this);

// Set personality function if not already set
auto funcOp = mlir::cast<cir::FuncOp>(curFn);
if (!funcOp.getPersonality())
funcOp.setPersonality(getPersonalityFn(cgm, personality));

// CIR does not cache landing pads.
const EHPersonality &personality = EHPersonality::get(*this);
if (personality.usesFuncletPads()) {
cgm.errorNYI("getInvokeDestImpl: usesFuncletPads");
} else {
Expand Down
21 changes: 17 additions & 4 deletions clang/lib/CIR/CodeGen/CIRGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2354,14 +2354,27 @@ void CIRGenModule::setCXXSpecialMemberAttr(
}
}

static void setWindowsItaniumDLLImport(CIRGenModule &cgm, bool isLocal,
cir::FuncOp funcOp, StringRef name) {
// In Windows Itanium environments, try to mark runtime functions
// dllimport. For Mingw and MSVC, don't. We don't really know if the user
// will link their standard library statically or dynamically. Marking
// functions imported when they are not imported can cause linker errors
// and warnings.
if (!isLocal && cgm.getTarget().getTriple().isWindowsItaniumEnvironment() &&
!cgm.getCodeGenOpts().LTOVisibilityPublicStd) {
assert(!cir::MissingFeatures::getRuntimeFunctionDecl());
assert(!cir::MissingFeatures::setDLLStorageClass());
assert(!cir::MissingFeatures::opGlobalDLLImportExport());
}
}

cir::FuncOp CIRGenModule::createRuntimeFunction(cir::FuncType ty,
StringRef name, mlir::ArrayAttr,
[[maybe_unused]] bool isLocal,
bool isLocal,
bool assumeConvergent) {
if (assumeConvergent)
errorNYI("createRuntimeFunction: assumeConvergent");
if (isLocal)
errorNYI("createRuntimeFunction: local");

cir::FuncOp entry = getOrCreateCIRFunction(name, ty, GlobalDecl(),
/*forVtable=*/false);
Expand All @@ -2370,7 +2383,7 @@ cir::FuncOp CIRGenModule::createRuntimeFunction(cir::FuncType ty,
// TODO(cir): set the attributes of the function.
assert(!cir::MissingFeatures::setLLVMFunctionFEnvAttributes());
assert(!cir::MissingFeatures::opFuncCallingConv());
assert(!cir::MissingFeatures::opGlobalDLLImportExport());
setWindowsItaniumDLLImport(*this, isLocal, entry, name);
entry.setDSOLocal(true);
}

Expand Down
19 changes: 19 additions & 0 deletions clang/lib/CIR/Dialect/IR/CIRDialect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1910,6 +1910,19 @@ ParseResult cir::FuncOp::parse(OpAsmParser &parser, OperationState &state) {
hasAlias = true;
}

mlir::StringAttr personalityNameAttr = getPersonalityAttrName(state.name);
if (parser.parseOptionalKeyword("personality").succeeded()) {
if (parser.parseLParen().failed())
return failure();
mlir::StringAttr personalityAttr;
if (parser.parseOptionalSymbolName(personalityAttr).failed())
return failure();
state.addAttribute(personalityNameAttr,
FlatSymbolRefAttr::get(personalityAttr));
if (parser.parseRParen().failed())
return failure();
}

auto parseGlobalDtorCtor =
[&](StringRef keyword,
llvm::function_ref<void(std::optional<int> prio)> createAttr)
Expand Down Expand Up @@ -2111,6 +2124,12 @@ void cir::FuncOp::print(OpAsmPrinter &p) {
p << ")";
}

if (std::optional<StringRef> personalityName = getPersonality()) {
p << " personality(";
p.printSymbolName(*personalityName);
p << ")";
}

if (auto specialMemberAttr = getCxxSpecialMember()) {
p << " special_member<";
p.printAttribute(*specialMemberAttr);
Expand Down
Loading
Loading