From a729e706de3fc6ebee49ede3c50afb47f2e29191 Mon Sep 17 00:00:00 2001 From: Greg Roth Date: Tue, 17 Sep 2024 11:09:42 -0600 Subject: [HLSL] set alwaysinline on HLSL functions (#106588) HLSL inlines all its functions by default. This uses the alwaysinline attribute to make the alwaysinliner pass inline any function not explicitly marked noinline by the user or autogeneration. The alwayslinline marking takes place in `SetLLVMFunctionAttributesForDefinitions` where all other inlining interactions are determined. The outermost entry function is marked noinline because there's no reason to inline it. Any user calls to an entry function will instead call the internal mangled version of the entry function. Adds tests for function and constructor inlining and augments some existing tests to verify correct inlining of implicitly created functions as well. Incidentally restore RUN line that I believe was mistakenly removed as part of #88918 Fixes #89282 --- clang/lib/CodeGen/CodeGenModule.cpp | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'clang/lib/CodeGen/CodeGenModule.cpp') diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index ba2d658..17b82b2 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -2473,11 +2473,14 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D, B.addAttribute(llvm::Attribute::StackProtectReq); if (!D) { + // Non-entry HLSL functions must always be inlined. + if (getLangOpts().HLSL && !F->hasFnAttribute(llvm::Attribute::NoInline)) + B.addAttribute(llvm::Attribute::AlwaysInline); // 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. - if (!F->hasFnAttribute(llvm::Attribute::AlwaysInline) && - CodeGenOpts.getInlining() == CodeGenOptions::OnlyAlwaysInlining) + else if (!F->hasFnAttribute(llvm::Attribute::AlwaysInline) && + CodeGenOpts.getInlining() == CodeGenOptions::OnlyAlwaysInlining) B.addAttribute(llvm::Attribute::NoInline); F->addFnAttrs(B); @@ -2504,9 +2507,13 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D, ShouldAddOptNone &= !D->hasAttr(); ShouldAddOptNone &= !D->hasAttr(); - // Add optnone, but do so only if the function isn't always_inline. - if ((ShouldAddOptNone || D->hasAttr()) && - !F->hasFnAttribute(llvm::Attribute::AlwaysInline)) { + // Non-entry HLSL functions must always be inlined. + if (getLangOpts().HLSL && !F->hasFnAttribute(llvm::Attribute::NoInline) && + !D->hasAttr()) { + B.addAttribute(llvm::Attribute::AlwaysInline); + } else if ((ShouldAddOptNone || D->hasAttr()) && + !F->hasFnAttribute(llvm::Attribute::AlwaysInline)) { + // Add optnone, but do so only if the function isn't always_inline. B.addAttribute(llvm::Attribute::OptimizeNone); // OptimizeNone implies noinline; we should not be inlining such functions. @@ -2526,7 +2533,8 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D, B.addAttribute(llvm::Attribute::NoInline); } else if (D->hasAttr()) { B.addAttribute(llvm::Attribute::NoDuplicate); - } else if (D->hasAttr() && !F->hasFnAttribute(llvm::Attribute::AlwaysInline)) { + } else if (D->hasAttr() && + !F->hasFnAttribute(llvm::Attribute::AlwaysInline)) { // Add noinline if the function isn't always_inline. B.addAttribute(llvm::Attribute::NoInline); } else if (D->hasAttr() && -- cgit v1.1