diff --git a/clang/lib/CIR/CodeGen/CIRGenCXX.cpp b/clang/lib/CIR/CodeGen/CIRGenCXX.cpp index 85013189fd7e..d73222f5b79f 100644 --- a/clang/lib/CIR/CodeGen/CIRGenCXX.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenCXX.cpp @@ -287,7 +287,7 @@ mlir::cir::FuncOp CIRGenModule::codegenCXXStructor(GlobalDecl GD) { CurCGF = nullptr; setNonAliasAttributes(GD, Fn); - // TODO: SetLLVMFunctionAttributesForDefinition + setCIRFunctionAttributesForDefinition(cast(GD.getDecl()), Fn); return Fn; } diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp index dd561021d607..4f7a61e55fb6 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp @@ -587,7 +587,7 @@ void CIRGenModule::buildGlobalFunctionDefinition(GlobalDecl GD, CurCGF = nullptr; setNonAliasAttributes(GD, Op); - // TODO: SetLLVMFunctionAttributesForDeclaration + setCIRFunctionAttributesForDefinition(D, Fn); if (const ConstructorAttr *CA = D->getAttr()) AddGlobalCtor(Fn, CA->getPriority()); @@ -2264,7 +2264,9 @@ CIRGenModule::createCIRFunction(mlir::Location loc, StringRef name, mlir::SymbolTable::setSymbolVisibility( f, mlir::SymbolTable::Visibility::Private); - setExtraAttributesForFunc(f, FD); + // Initialize with empty dict of extra attributes. + f.setExtraAttrsAttr(mlir::cir::ExtraFuncAttributesAttr::get( + builder.getContext(), builder.getDictionaryAttr({}))); if (!curCGF) theModule.push_back(f); @@ -2333,16 +2335,16 @@ static bool hasUnwindExceptions(const LangOptions &LangOpts) { return true; } -void CIRGenModule::setExtraAttributesForFunc(FuncOp f, - const clang::FunctionDecl *FD) { - mlir::NamedAttrList attrs; +void CIRGenModule::setCIRFunctionAttributesForDefinition(const Decl *decl, + FuncOp f) { + mlir::NamedAttrList attrs{f.getExtraAttrs().getElements().getValue()}; if (!hasUnwindExceptions(getLangOpts())) { auto attr = mlir::cir::NoThrowAttr::get(builder.getContext()); attrs.set(attr.getMnemonic(), attr); } - if (!FD) { + if (!decl) { // If we don't have a declaration to control inlining, the function isn't // explicitly marked as alwaysinline for semantic reasons, and inlining is // disabled, mark the function as noinline. @@ -2351,12 +2353,12 @@ void CIRGenModule::setExtraAttributesForFunc(FuncOp f, builder.getContext(), mlir::cir::InlineKind::AlwaysInline); attrs.set(attr.getMnemonic(), attr); } - } else if (FD->hasAttr()) { + } else if (decl->hasAttr()) { // Add noinline if the function isn't always_inline. auto attr = mlir::cir::InlineAttr::get(builder.getContext(), mlir::cir::InlineKind::NoInline); attrs.set(attr.getMnemonic(), attr); - } else if (FD->hasAttr()) { + } else if (decl->hasAttr()) { // (noinline wins over always_inline, and we can't specify both in IR) auto attr = mlir::cir::InlineAttr::get(builder.getContext(), mlir::cir::InlineKind::AlwaysInline); @@ -2371,18 +2373,18 @@ void CIRGenModule::setExtraAttributesForFunc(FuncOp f, // Otherwise, propagate the inline hint attribute and potentially use its // absence to mark things as noinline. // Search function and template pattern redeclarations for inline. - auto CheckForInline = [](const FunctionDecl *FD) { + auto CheckForInline = [](const FunctionDecl *decl) { auto CheckRedeclForInline = [](const FunctionDecl *Redecl) { return Redecl->isInlineSpecified(); }; - if (any_of(FD->redecls(), CheckRedeclForInline)) + if (any_of(decl->redecls(), CheckRedeclForInline)) return true; - const FunctionDecl *Pattern = FD->getTemplateInstantiationPattern(); + const FunctionDecl *Pattern = decl->getTemplateInstantiationPattern(); if (!Pattern) return false; return any_of(Pattern->redecls(), CheckRedeclForInline); }; - if (CheckForInline(FD)) { + if (CheckForInline(cast(decl))) { auto attr = mlir::cir::InlineAttr::get(builder.getContext(), mlir::cir::InlineKind::InlineHint); attrs.set(attr.getMnemonic(), attr); @@ -2397,10 +2399,10 @@ void CIRGenModule::setExtraAttributesForFunc(FuncOp f, // starting with the default for this optimization level. bool ShouldAddOptNone = !codeGenOpts.DisableO0ImplyOptNone && codeGenOpts.OptimizationLevel == 0; - if (FD) { - ShouldAddOptNone &= !FD->hasAttr(); - ShouldAddOptNone &= !FD->hasAttr(); - ShouldAddOptNone |= FD->hasAttr(); + if (decl) { + ShouldAddOptNone &= !decl->hasAttr(); + ShouldAddOptNone &= !decl->hasAttr(); + ShouldAddOptNone |= decl->hasAttr(); } if (ShouldAddOptNone) { diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.h b/clang/lib/CIR/CodeGen/CIRGenModule.h index daa74d85ccea..55d609c93299 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.h +++ b/clang/lib/CIR/CodeGen/CIRGenModule.h @@ -573,7 +573,12 @@ class CIRGenModule : public CIRGenTypeCache { /// Set the CIR function attributes (sext, zext, etc). void setCIRFunctionAttributes(GlobalDecl GD, const CIRGenFunctionInfo &info, - mlir::cir::FuncOp func, bool isThunk); + mlir::cir::FuncOp func, bool isThunk); + + /// Set the CIR function attributes which only apply to a function + /// definition. + void setCIRFunctionAttributesForDefinition(const Decl *decl, + mlir::cir::FuncOp func); void buildGlobalDefinition(clang::GlobalDecl D, mlir::Operation *Op = nullptr); @@ -666,9 +671,6 @@ class CIRGenModule : public CIRGenTypeCache { void ReplaceUsesOfNonProtoTypeWithRealFunction(mlir::Operation *Old, mlir::cir::FuncOp NewFn); - void setExtraAttributesForFunc(mlir::cir::FuncOp f, - const clang::FunctionDecl *FD); - // TODO: CodeGen also passes an AttributeList here. We'll have to match that // in CIR mlir::cir::FuncOp diff --git a/clang/test/CIR/CodeGen/attributes.c b/clang/test/CIR/CodeGen/attributes.c index 4231edf968f7..f80c479df45a 100644 --- a/clang/test/CIR/CodeGen/attributes.c +++ b/clang/test/CIR/CodeGen/attributes.c @@ -14,7 +14,7 @@ int __attribute__((section(".shared"))) glob = 42; void __attribute__((__visibility__("hidden"))) foo(); -// CIR: cir.func no_proto private hidden @foo(...) extra(#fn_attr) +// CIR: cir.func no_proto private hidden @foo(...) int bah() { foo(); diff --git a/clang/test/CIR/CodeGen/visibility-attribute.c b/clang/test/CIR/CodeGen/visibility-attribute.c index 45ea4c28e272..549f05d052b8 100644 --- a/clang/test/CIR/CodeGen/visibility-attribute.c +++ b/clang/test/CIR/CodeGen/visibility-attribute.c @@ -19,15 +19,15 @@ int call_glob() } void foo_default(); -// CIR: cir.func no_proto private @foo_default(...) extra(#fn_attr) +// CIR: cir.func no_proto private @foo_default(...) // LLVM: declare {{.*}} void @foo_default(...) void __attribute__((__visibility__("hidden"))) foo_hidden(); -// CIR: cir.func no_proto private hidden @foo_hidden(...) extra(#fn_attr) +// CIR: cir.func no_proto private hidden @foo_hidden(...) // LLVM: declare {{.*}} hidden void @foo_hidden(...) void __attribute__((__visibility__("protected"))) foo_protected(); -// CIR: cir.func no_proto private protected @foo_protected(...) extra(#fn_attr) +// CIR: cir.func no_proto private protected @foo_protected(...) // LLVM: declare {{.*}} protected void @foo_protected(...) void call_foo()