diff options
Diffstat (limited to 'clang/lib/CIR/CodeGen/CIRGenModule.cpp')
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenModule.cpp | 89 |
1 files changed, 88 insertions, 1 deletions
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp index 82b1051..127f763 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp @@ -88,6 +88,8 @@ CIRGenModule::CIRGenModule(mlir::MLIRContext &mlirContext, FP80Ty = cir::FP80Type::get(&getMLIRContext()); FP128Ty = cir::FP128Type::get(&getMLIRContext()); + AllocaInt8PtrTy = cir::PointerType::get(UInt8Ty, cirAllocaAddressSpace); + PointerAlignInBytes = astContext .toCharUnitsFromBits( @@ -449,7 +451,7 @@ void CIRGenModule::emitGlobalFunctionDefinition(clang::GlobalDecl gd, curCGF = nullptr; setNonAliasAttributes(gd, funcOp); - assert(!cir::MissingFeatures::opFuncAttributesForDefinition()); + setCIRFunctionAttributesForDefinition(funcDecl, funcOp); auto getPriority = [this](const auto *attr) -> int { Expr *e = attr->getPriority(); @@ -1917,6 +1919,91 @@ void CIRGenModule::setFunctionAttributes(GlobalDecl globalDecl, } } +void CIRGenModule::setCIRFunctionAttributesForDefinition( + const clang::FunctionDecl *decl, cir::FuncOp f) { + assert(!cir::MissingFeatures::opFuncUnwindTablesAttr()); + assert(!cir::MissingFeatures::stackProtector()); + + std::optional<cir::InlineKind> existingInlineKind = f.getInlineKind(); + bool isNoInline = + existingInlineKind && *existingInlineKind == cir::InlineKind::NoInline; + bool isAlwaysInline = existingInlineKind && + *existingInlineKind == cir::InlineKind::AlwaysInline; + + if (!decl) { + assert(!cir::MissingFeatures::hlsl()); + + if (!isAlwaysInline && + codeGenOpts.getInlining() == CodeGenOptions::OnlyAlwaysInlining) { + // If inlining is disabled and we don't have a declaration to control + // inlining, mark the function as 'noinline' unless it is explicitly + // marked as 'alwaysinline'. + f.setInlineKindAttr( + cir::InlineAttr::get(&getMLIRContext(), cir::InlineKind::NoInline)); + } + + return; + } + + assert(!cir::MissingFeatures::opFuncArmStreamingAttr()); + assert(!cir::MissingFeatures::opFuncArmNewAttr()); + assert(!cir::MissingFeatures::opFuncOptNoneAttr()); + assert(!cir::MissingFeatures::opFuncMinSizeAttr()); + assert(!cir::MissingFeatures::opFuncNakedAttr()); + assert(!cir::MissingFeatures::opFuncNoDuplicateAttr()); + assert(!cir::MissingFeatures::hlsl()); + + // Handle inline attributes + if (decl->hasAttr<NoInlineAttr>() && !isAlwaysInline) { + // Add noinline if the function isn't always_inline. + f.setInlineKindAttr( + cir::InlineAttr::get(&getMLIRContext(), cir::InlineKind::NoInline)); + } else if (decl->hasAttr<AlwaysInlineAttr>() && !isNoInline) { + // Don't override AlwaysInline with NoInline, or vice versa, since we can't + // specify both in IR. + f.setInlineKindAttr( + cir::InlineAttr::get(&getMLIRContext(), cir::InlineKind::AlwaysInline)); + } else if (codeGenOpts.getInlining() == CodeGenOptions::OnlyAlwaysInlining) { + // If inlining is disabled, force everything that isn't always_inline + // to carry an explicit noinline attribute. + if (!isAlwaysInline) { + f.setInlineKindAttr( + cir::InlineAttr::get(&getMLIRContext(), cir::InlineKind::NoInline)); + } + } else { + // Otherwise, propagate the inline hint attribute and potentially use its + // absence to mark things as noinline. + // Search function and template pattern redeclarations for inline. + if (auto *fd = dyn_cast<FunctionDecl>(decl)) { + // TODO: Share this checkForInline implementation with classic codegen. + // This logic is likely to change over time, so sharing would help ensure + // consistency. + auto checkForInline = [](const FunctionDecl *decl) { + auto checkRedeclForInline = [](const FunctionDecl *redecl) { + return redecl->isInlineSpecified(); + }; + if (any_of(decl->redecls(), checkRedeclForInline)) + return true; + const FunctionDecl *pattern = decl->getTemplateInstantiationPattern(); + if (!pattern) + return false; + return any_of(pattern->redecls(), checkRedeclForInline); + }; + if (checkForInline(fd)) { + f.setInlineKindAttr(cir::InlineAttr::get(&getMLIRContext(), + cir::InlineKind::InlineHint)); + } else if (codeGenOpts.getInlining() == + CodeGenOptions::OnlyHintInlining && + !fd->isInlined() && !isAlwaysInline) { + f.setInlineKindAttr( + cir::InlineAttr::get(&getMLIRContext(), cir::InlineKind::NoInline)); + } + } + } + + assert(!cir::MissingFeatures::opFuncColdHotAttr()); +} + cir::FuncOp CIRGenModule::getOrCreateCIRFunction( StringRef mangledName, mlir::Type funcType, GlobalDecl gd, bool forVTable, bool dontDefer, bool isThunk, ForDefinition_t isForDefinition, |