@@ -451,7 +451,7 @@ void CIRGenModule::emitGlobalFunctionDefinition(clang::GlobalDecl gd,
451451 curCGF = nullptr ;
452452
453453 setNonAliasAttributes (gd, funcOp);
454- assert (! cir::MissingFeatures::opFuncAttributesForDefinition () );
454+ setCIRFunctionAttributesForDefinition (funcDecl, funcOp );
455455
456456 auto getPriority = [this ](const auto *attr) -> int {
457457 Expr *e = attr->getPriority ();
@@ -1919,6 +1919,91 @@ void CIRGenModule::setFunctionAttributes(GlobalDecl globalDecl,
19191919 }
19201920}
19211921
1922+ void CIRGenModule::setCIRFunctionAttributesForDefinition (
1923+ const clang::FunctionDecl *decl, cir::FuncOp f) {
1924+ assert (!cir::MissingFeatures::opFuncUnwindTablesAttr ());
1925+ assert (!cir::MissingFeatures::stackProtector ());
1926+
1927+ std::optional<cir::InlineKind> existingInlineKind = f.getInlineKind ();
1928+ bool isNoInline =
1929+ existingInlineKind && *existingInlineKind == cir::InlineKind::NoInline;
1930+ bool isAlwaysInline = existingInlineKind &&
1931+ *existingInlineKind == cir::InlineKind::AlwaysInline;
1932+
1933+ if (!decl) {
1934+ assert (!cir::MissingFeatures::hlsl ());
1935+
1936+ if (!isAlwaysInline &&
1937+ codeGenOpts.getInlining () == CodeGenOptions::OnlyAlwaysInlining) {
1938+ // If inlining is disabled and we don't have a declaration to control
1939+ // inlining, mark the function as 'noinline' unless it is explicitly
1940+ // marked as 'alwaysinline'.
1941+ f.setInlineKindAttr (
1942+ cir::InlineAttr::get (&getMLIRContext (), cir::InlineKind::NoInline));
1943+ }
1944+
1945+ return ;
1946+ }
1947+
1948+ assert (!cir::MissingFeatures::opFuncArmStreamingAttr ());
1949+ assert (!cir::MissingFeatures::opFuncArmNewAttr ());
1950+ assert (!cir::MissingFeatures::opFuncOptNoneAttr ());
1951+ assert (!cir::MissingFeatures::opFuncMinSizeAttr ());
1952+ assert (!cir::MissingFeatures::opFuncNakedAttr ());
1953+ assert (!cir::MissingFeatures::opFuncNoDuplicateAttr ());
1954+ assert (!cir::MissingFeatures::hlsl ());
1955+
1956+ // Handle inline attributes
1957+ if (decl->hasAttr <NoInlineAttr>() && !isAlwaysInline) {
1958+ // Add noinline if the function isn't always_inline.
1959+ f.setInlineKindAttr (
1960+ cir::InlineAttr::get (&getMLIRContext (), cir::InlineKind::NoInline));
1961+ } else if (decl->hasAttr <AlwaysInlineAttr>() && !isNoInline) {
1962+ // Don't override AlwaysInline with NoInline, or vice versa, since we can't
1963+ // specify both in IR.
1964+ f.setInlineKindAttr (
1965+ cir::InlineAttr::get (&getMLIRContext (), cir::InlineKind::AlwaysInline));
1966+ } else if (codeGenOpts.getInlining () == CodeGenOptions::OnlyAlwaysInlining) {
1967+ // If inlining is disabled, force everything that isn't always_inline
1968+ // to carry an explicit noinline attribute.
1969+ if (!isAlwaysInline) {
1970+ f.setInlineKindAttr (
1971+ cir::InlineAttr::get (&getMLIRContext (), cir::InlineKind::NoInline));
1972+ }
1973+ } else {
1974+ // Otherwise, propagate the inline hint attribute and potentially use its
1975+ // absence to mark things as noinline.
1976+ // Search function and template pattern redeclarations for inline.
1977+ if (auto *fd = dyn_cast<FunctionDecl>(decl)) {
1978+ // TODO: Share this checkForInline implementation with classic codegen.
1979+ // This logic is likely to change over time, so sharing would help ensure
1980+ // consistency.
1981+ auto checkForInline = [](const FunctionDecl *decl) {
1982+ auto checkRedeclForInline = [](const FunctionDecl *redecl) {
1983+ return redecl->isInlineSpecified ();
1984+ };
1985+ if (any_of (decl->redecls (), checkRedeclForInline))
1986+ return true ;
1987+ const FunctionDecl *pattern = decl->getTemplateInstantiationPattern ();
1988+ if (!pattern)
1989+ return false ;
1990+ return any_of (pattern->redecls (), checkRedeclForInline);
1991+ };
1992+ if (checkForInline (fd)) {
1993+ f.setInlineKindAttr (cir::InlineAttr::get (&getMLIRContext (),
1994+ cir::InlineKind::InlineHint));
1995+ } else if (codeGenOpts.getInlining () ==
1996+ CodeGenOptions::OnlyHintInlining &&
1997+ !fd->isInlined () && !isAlwaysInline) {
1998+ f.setInlineKindAttr (
1999+ cir::InlineAttr::get (&getMLIRContext (), cir::InlineKind::NoInline));
2000+ }
2001+ }
2002+ }
2003+
2004+ assert (!cir::MissingFeatures::opFuncColdHotAttr ());
2005+ }
2006+
19222007cir::FuncOp CIRGenModule::getOrCreateCIRFunction (
19232008 StringRef mangledName, mlir::Type funcType, GlobalDecl gd, bool forVTable,
19242009 bool dontDefer, bool isThunk, ForDefinition_t isForDefinition,
0 commit comments