https://github.com/HighW4y2H3ll updated https://github.com/llvm/llvm-project/pull/145652
>From 9a29dd6fa3f28bf507f047a22597f8510bd096b3 Mon Sep 17 00:00:00 2001 From: h2h <h...@meta.com> Date: Tue, 24 Jun 2025 23:24:32 -0700 Subject: [PATCH 1/7] [Clang] Allow vanilla C function symbol name to be used in __attribute__((alias)) when -funique-internal-linkage-names is specified --- clang/lib/CodeGen/CodeGenModule.cpp | 48 +++++++++++++++++-- .../unique-internal-linkage-names-alias.c | 10 ++++ 2 files changed, 54 insertions(+), 4 deletions(-) create mode 100644 clang/test/CodeGen/unique-internal-linkage-names-alias.c diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 16688810d0685..90f02220ec306 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -588,8 +588,9 @@ static const llvm::GlobalValue *getAliasedGlobal(const llvm::GlobalValue *GV) { } static bool checkAliasedGlobal( - const ASTContext &Context, DiagnosticsEngine &Diags, SourceLocation Location, - bool IsIFunc, const llvm::GlobalValue *Alias, const llvm::GlobalValue *&GV, + const CodeGenModule *CGM, const ASTContext &Context, + DiagnosticsEngine &Diags, SourceLocation Location, bool IsIFunc, + const llvm::GlobalValue *Alias, const llvm::GlobalValue *&GV, const llvm::MapVector<GlobalDecl, StringRef> &MangledDeclNames, SourceRange AliasRange) { GV = getAliasedGlobal(Alias); @@ -598,6 +599,23 @@ static bool checkAliasedGlobal( return false; } + // Only resolve unique internal linkage symbols for C code + if (!CGM->getLangOpts().CPlusPlus) { + for (const auto &[Decl, Name] : MangledDeclNames) { + if (const auto *ND = dyn_cast<NamedDecl>(Decl.getDecl())) { + IdentifierInfo *II = ND->getIdentifier(); + if (II && II->getName() == GV->getName() && + Name.contains(llvm::FunctionSamples::UniqSuffix)) { + GlobalDecl GD; + if (CGM->lookupRepresentativeDecl(Name, GD)) { + GV = CGM->getModule().getNamedValue(Name); + break; + } + } + } + } + } + if (GV->hasCommonLinkage()) { const llvm::Triple &Triple = Context.getTargetInfo().getTriple(); if (Triple.getObjectFormat() == llvm::Triple::XCOFF) { @@ -687,8 +705,8 @@ void CodeGenModule::checkAliases() { StringRef MangledName = getMangledName(GD); llvm::GlobalValue *Alias = GetGlobalValue(MangledName); const llvm::GlobalValue *GV = nullptr; - if (!checkAliasedGlobal(getContext(), Diags, Location, IsIFunc, Alias, GV, - MangledDeclNames, Range)) { + if (!checkAliasedGlobal(this, getContext(), Diags, Location, IsIFunc, Alias, + GV, MangledDeclNames, Range)) { Error = true; continue; } @@ -4038,6 +4056,7 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) { CXXGlobalInits.push_back(nullptr); } + const auto *ND = dyn_cast<NamedDecl>(GD.getDecl()); StringRef MangledName = getMangledName(GD); if (GetGlobalValue(MangledName) != nullptr) { // The value has already been used and should therefore be emitted. @@ -4046,6 +4065,12 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) { // The value must be emitted, but cannot be emitted eagerly. assert(!MayBeEmittedEagerly(Global)); addDeferredDeclToEmit(GD); + } else if (!getLangOpts().CPlusPlus && ND && + GetGlobalValue(ND->getName()) != nullptr && + MangledName.contains(llvm::FunctionSamples::UniqSuffix)) { + // Emit static C function that is mangled with + // -funique-internal-linkage-names. + addDeferredDeclToEmit(GD); } else { // Otherwise, remember that we saw a deferred decl with this name. The // first use of the mangled name will cause it to move into @@ -6189,6 +6214,21 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD, /*DontDefer=*/true, ForDefinition)); + if (!getLangOpts().CPlusPlus && + getCXXABI().getMangleContext().shouldMangleDeclName(D)) { + // -funique-internal-linkage-names may change the symbol name of C function. + // Replace all uses of old symbol with the emitted global value. + if (IdentifierInfo *II = D->getIdentifier()) { + if (II->getName() != GV->getName() && + GV->getName().contains(llvm::FunctionSamples::UniqSuffix)) { + if (llvm::GlobalValue *GVDef = + getModule().getNamedValue(D->getName())) { + GVDef->replaceAllUsesWith(GV); + } + } + } + } + // Already emitted. if (!GV->isDeclaration()) return; diff --git a/clang/test/CodeGen/unique-internal-linkage-names-alias.c b/clang/test/CodeGen/unique-internal-linkage-names-alias.c new file mode 100644 index 0000000000000..14bfea08367d3 --- /dev/null +++ b/clang/test/CodeGen/unique-internal-linkage-names-alias.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 %s -emit-llvm -funique-internal-linkage-names -o - | FileCheck %s + +struct A; +static long foo(const struct A*p); + +long bar(const struct A*p); +long bar(const struct A*p) __attribute__((__alias__("foo"))); + +// CHECK: define internal i64 @_ZL3fooPK1A.__uniq.[[ATTR:[0-9]+]](ptr noundef %p) #1 { +static long foo(const struct A*p) {return 1;} >From aedff8d00362405ad73880eccf4bd7006f6facb2 Mon Sep 17 00:00:00 2001 From: h2h <h...@meta.com> Date: Wed, 25 Jun 2025 16:22:49 -0700 Subject: [PATCH 2/7] Check Itanium mangling only --- clang/test/CodeGen/unique-internal-linkage-names-alias.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/test/CodeGen/unique-internal-linkage-names-alias.c b/clang/test/CodeGen/unique-internal-linkage-names-alias.c index 14bfea08367d3..85345233ad507 100644 --- a/clang/test/CodeGen/unique-internal-linkage-names-alias.c +++ b/clang/test/CodeGen/unique-internal-linkage-names-alias.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -emit-llvm -funique-internal-linkage-names -o - | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux %s -emit-llvm -funique-internal-linkage-names -o - | FileCheck %s struct A; static long foo(const struct A*p); >From 80e7bda91ae783ce02e8c3491a88e65779a1e01c Mon Sep 17 00:00:00 2001 From: h2h <h...@meta.com> Date: Thu, 3 Jul 2025 13:33:44 -0700 Subject: [PATCH 3/7] Fix frontend crash with extern_weak when using __attribute__((weak, alias())) --- clang/lib/CodeGen/CodeGenModule.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 90f02220ec306..83515a4488256 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -4066,7 +4066,6 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) { assert(!MayBeEmittedEagerly(Global)); addDeferredDeclToEmit(GD); } else if (!getLangOpts().CPlusPlus && ND && - GetGlobalValue(ND->getName()) != nullptr && MangledName.contains(llvm::FunctionSamples::UniqSuffix)) { // Emit static C function that is mangled with // -funique-internal-linkage-names. >From 1e116a9b6a7964a78ae1b795bc2ac80ec9f46be1 Mon Sep 17 00:00:00 2001 From: h2h <h...@meta.com> Date: Sun, 6 Jul 2025 13:17:35 -0700 Subject: [PATCH 4/7] Fix missed aliasee function emit when function alias is used after the definitation of the aliasee function --- clang/lib/CodeGen/CodeGenModule.cpp | 33 +++++++++++++++++-- clang/lib/CodeGen/CodeGenModule.h | 1 + .../unique-internal-linkage-names-alias.c | 2 +- 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 83515a4488256..1c9c9c04b6d4a 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -3902,6 +3902,22 @@ bool CodeGenModule::shouldEmitCUDAGlobalVar(const VarDecl *Global) const { Global->getType()->isCUDADeviceBuiltinTextureType(); } +bool CodeGenModule::shouldEmitUniqLinkageName(GlobalDecl GD) { + const auto *ND = dyn_cast<FunctionDecl>(GD.getDecl()); + if (!ND || !getCXXABI().getMangleContext().shouldMangleDeclName(ND)) + return false; + StringRef MangledName = getMangledName(GD); + if (!MangledName.contains(llvm::FunctionSamples::UniqSuffix)) + return false; + for (const GlobalDecl &AD : Aliases) { + const auto *D = cast<ValueDecl>(AD.getDecl()); + const AliasAttr *AA = D->getAttr<AliasAttr>(); + if (AA && AA->getAliasee() == ND->getName()) + return true; + } + return false; +} + void CodeGenModule::EmitGlobal(GlobalDecl GD) { const auto *Global = cast<ValueDecl>(GD.getDecl()); @@ -4056,7 +4072,6 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) { CXXGlobalInits.push_back(nullptr); } - const auto *ND = dyn_cast<NamedDecl>(GD.getDecl()); StringRef MangledName = getMangledName(GD); if (GetGlobalValue(MangledName) != nullptr) { // The value has already been used and should therefore be emitted. @@ -4065,8 +4080,7 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) { // The value must be emitted, but cannot be emitted eagerly. assert(!MayBeEmittedEagerly(Global)); addDeferredDeclToEmit(GD); - } else if (!getLangOpts().CPlusPlus && ND && - MangledName.contains(llvm::FunctionSamples::UniqSuffix)) { + } else if (!getLangOpts().CPlusPlus && shouldEmitUniqLinkageName(GD)) { // Emit static C function that is mangled with // -funique-internal-linkage-names. addDeferredDeclToEmit(GD); @@ -6223,6 +6237,7 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD, if (llvm::GlobalValue *GVDef = getModule().getNamedValue(D->getName())) { GVDef->replaceAllUsesWith(GV); + GVDef->removeFromParent(); } } } @@ -6287,6 +6302,18 @@ void CodeGenModule::EmitAliasDefinition(GlobalDecl GD) { return; } + // Deferred emit for aliased C function when __attribute__((alias)) might be + // used after the definition of aliasee function + if (!getLangOpts().CPlusPlus) { + for (const auto &[Name, Decl] : DeferredDecls) { + const auto *FD = dyn_cast<FunctionDecl>(Decl.getDecl()); + if (FD && FD->getName() == AA->getAliasee() && + Name.contains(llvm::FunctionSamples::UniqSuffix)) { + addDeferredDeclToEmit(Decl); + } + } + } + // If there is a definition in the module, then it wins over the alias. // This is dubious, but allow it to be safe. Just ignore the alias. llvm::GlobalValue *Entry = GetGlobalValue(MangledName); diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index 1b67d4354efc0..e7d3f0276566c 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -613,6 +613,7 @@ class CodeGenModule : public CodeGenTypeCache { // related attributes. bool shouldEmitCUDAGlobalVar(const VarDecl *VD) const; bool shouldOpportunisticallyEmitVTables(); + bool shouldEmitUniqLinkageName(GlobalDecl GD); /// Map used to be sure we don't emit the same CompoundLiteral twice. llvm::DenseMap<const CompoundLiteralExpr *, llvm::GlobalVariable *> EmittedCompoundLiterals; diff --git a/clang/test/CodeGen/unique-internal-linkage-names-alias.c b/clang/test/CodeGen/unique-internal-linkage-names-alias.c index 85345233ad507..e9cedc9dd8957 100644 --- a/clang/test/CodeGen/unique-internal-linkage-names-alias.c +++ b/clang/test/CodeGen/unique-internal-linkage-names-alias.c @@ -6,5 +6,5 @@ static long foo(const struct A*p); long bar(const struct A*p); long bar(const struct A*p) __attribute__((__alias__("foo"))); -// CHECK: define internal i64 @_ZL3fooPK1A.__uniq.[[ATTR:[0-9]+]](ptr noundef %p) #1 { +// CHECK: define internal i64 @_ZL3fooPK1A.__uniq.[[ATTR:[0-9]+]](ptr noundef %p) #0 { static long foo(const struct A*p) {return 1;} >From 3beeb6a17ba5e3e1cc8be455505633aec89e9d94 Mon Sep 17 00:00:00 2001 From: h2h <h...@meta.com> Date: Mon, 7 Jul 2025 13:50:33 -0700 Subject: [PATCH 5/7] Make the original function GlobalAlias to avoid broken references in the inline assembly --- clang/lib/CodeGen/CGCall.cpp | 18 +++++++++++++++ clang/lib/CodeGen/CodeGenModule.cpp | 35 +++++++++++++++++++++++++++-- 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index fd75de42515da..e44d9d3c6691c 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -5741,6 +5741,24 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, IRFuncTy = OrigFn->getFunctionType(); } + // Propogate Error Attribute if Callee is declared within the function body + // e.g. + // void foo() { + // __extern__ void nocall(void) __attribute__((__error__(msg))); + // if (nobranch) + // nocall(); + // } + if (CalleePtr && CalleeDecl) { + if (const auto *EA = CalleeDecl->getAttr<ErrorAttr>()) { + if (EA->isError()) + dyn_cast<llvm::Function>(CalleePtr)->addFnAttr("dontcall-error", + EA->getUserDiagnostic()); + else if (EA->isWarning()) + dyn_cast<llvm::Function>(CalleePtr)->addFnAttr("dontcall-warn", + EA->getUserDiagnostic()); + } + } + // 3. Perform the actual call. // Deactivate any cleanups that we're supposed to do immediately before diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 1c9c9c04b6d4a..ae4273efcb4da 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -6227,6 +6227,7 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD, /*DontDefer=*/true, ForDefinition)); + llvm::GlobalAlias *GA = nullptr; if (!getLangOpts().CPlusPlus && getCXXABI().getMangleContext().shouldMangleDeclName(D)) { // -funique-internal-linkage-names may change the symbol name of C function. @@ -6235,9 +6236,17 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD, if (II->getName() != GV->getName() && GV->getName().contains(llvm::FunctionSamples::UniqSuffix)) { if (llvm::GlobalValue *GVDef = - getModule().getNamedValue(D->getName())) { + getModule().getNamedValue(II->getName())) { GVDef->replaceAllUsesWith(GV); - GVDef->removeFromParent(); + GVDef->eraseFromParent(); + } else if (!D->hasAttr<AlwaysInlineAttr>() && + !D->hasAttr<GNUInlineAttr>()) { + // Create a GlobalAlias to the original symbol in case it was + // referenced in the inline assembly + unsigned AS = GV->getType()->getPointerAddressSpace(); + GA = llvm::GlobalAlias::create(GV->getValueType(), AS, + llvm::GlobalValue::InternalLinkage, + II->getName(), GV, &getModule()); } } } @@ -6282,6 +6291,28 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD, SetLLVMFunctionAttributesForDefinition(D, Fn); + // Avoid extra uses of the internal GlobalAlias if Callee has + // __attribute__((error)). + for (auto BB = Fn->begin(); GA && BB != Fn->end(); BB++) { + for (auto &I : *BB) { + if (auto *CI = dyn_cast<llvm::CallInst>(&I)) { + if (auto *Callee = CI->getCalledFunction()) { + if (Callee->hasFnAttribute("dontcall-error")) { + GA->eraseFromParent(); + GA = nullptr; + break; + } + } + } + } + } + + // Set Attributes to perserve the internal GlobalAlias + if (GA) { + SetCommonAttributes(GD, GA); + addUsedOrCompilerUsedGlobal(GA); + } + if (const ConstructorAttr *CA = D->getAttr<ConstructorAttr>()) AddGlobalCtor(Fn, CA->getPriority()); if (const DestructorAttr *DA = D->getAttr<DestructorAttr>()) >From 0003a3f53bbaad91b1222f3549bf020ff0087772 Mon Sep 17 00:00:00 2001 From: h2h <h...@meta.com> Date: Tue, 8 Jul 2025 02:39:13 -0700 Subject: [PATCH 6/7] Create GlobalAlias for AlwaysInline internal functions --- clang/lib/CodeGen/CodeGenModule.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index ae4273efcb4da..e7258197936ed 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -6239,8 +6239,7 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD, getModule().getNamedValue(II->getName())) { GVDef->replaceAllUsesWith(GV); GVDef->eraseFromParent(); - } else if (!D->hasAttr<AlwaysInlineAttr>() && - !D->hasAttr<GNUInlineAttr>()) { + } else if (!D->hasAttr<GNUInlineAttr>()) { // Create a GlobalAlias to the original symbol in case it was // referenced in the inline assembly unsigned AS = GV->getType()->getPointerAddressSpace(); >From cab9bf6dde61ee8f337f33aac47fbd14ae33ce8f Mon Sep 17 00:00:00 2001 From: h2h <h...@meta.com> Date: Tue, 8 Jul 2025 21:43:17 -0700 Subject: [PATCH 7/7] Check static __always_inline/inline functions to avoid inline assembly breakages --- clang/lib/CodeGen/CodeGenModule.cpp | 68 ++++++++++++++++++++++++++--- clang/lib/CodeGen/CodeGenModule.h | 12 +++++ 2 files changed, 75 insertions(+), 5 deletions(-) diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index e7258197936ed..47d4603bcc6d7 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -775,6 +775,7 @@ void CodeGenModule::clear() { DeferredAnnotations.clear(); if (OpenMPRuntime) OpenMPRuntime->clear(); + DeferredMaybeInlineFunctions.clear(); } void InstrProfStats::reportDiagnostics(DiagnosticsEngine &Diags, @@ -940,6 +941,7 @@ void CodeGenModule::Release() { emitAtAvailableLinkGuard(); if (Context.getTargetInfo().getTriple().isWasm()) EmitMainVoidAlias(); + FixupMaybeInlineFunctions(); if (getTriple().isAMDGPU() || (getTriple().isSPIRV() && getTriple().getVendor() == llvm::Triple::AMD)) { @@ -6213,6 +6215,10 @@ void CodeGenModule::HandleCXXStaticMemberVarInstantiation(VarDecl *VD) { EmitTopLevelDecl(VD); } +static bool hasInlineAttr(const FunctionDecl *Decl) { + return Decl->hasAttr<AlwaysInlineAttr>() || Decl->hasAttr<GNUInlineAttr>(); +} + void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD, llvm::GlobalValue *GV) { const auto *D = cast<FunctionDecl>(GD.getDecl()); @@ -6239,7 +6245,7 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD, getModule().getNamedValue(II->getName())) { GVDef->replaceAllUsesWith(GV); GVDef->eraseFromParent(); - } else if (!D->hasAttr<GNUInlineAttr>()) { + } else { // Create a GlobalAlias to the original symbol in case it was // referenced in the inline assembly unsigned AS = GV->getType()->getPointerAddressSpace(); @@ -6294,22 +6300,43 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD, // __attribute__((error)). for (auto BB = Fn->begin(); GA && BB != Fn->end(); BB++) { for (auto &I : *BB) { - if (auto *CI = dyn_cast<llvm::CallInst>(&I)) { + bool shouldEraseAlias = false; + if (auto *CI = dyn_cast<llvm::CallBase>(&I)) { if (auto *Callee = CI->getCalledFunction()) { - if (Callee->hasFnAttribute("dontcall-error")) { - GA->eraseFromParent(); + if (MustInlinedFunctions.contains(Callee->getName())) { + // Callee is a known always inline, inline assembly + if (hasInlineAttr(D)) + MustInlinedFunctions.insert(Fn->getName()); + shouldEraseAlias = true; + } else if (Callee->hasFnAttribute("dontcall-error")) { + // Callee has Error Attribute + shouldEraseAlias = true; + } else if (Callee->isDeclaration() && !Callee->isIntrinsic() && + hasInlineAttr(D)) { + // Callee has not emitted. Defer this check to a later stage + DeferredMaybeInlineFunctions[GD] = Callee; GA = nullptr; break; } + } else if (CI->isInlineAsm() && hasInlineAttr(D)) { + // Avoid alias towards always inline assembly to allow inlining + MustInlinedFunctions.insert(Fn->getName()); + shouldEraseAlias = true; } } + if (shouldEraseAlias) { + GA->eraseFromParent(); + GA = nullptr; + break; + } } } - // Set Attributes to perserve the internal GlobalAlias + // Set Attributes to perserve the internal GlobalValues if (GA) { SetCommonAttributes(GD, GA); addUsedOrCompilerUsedGlobal(GA); + addUsedOrCompilerUsedGlobal(GV); } if (const ConstructorAttr *CA = D->getAttr<ConstructorAttr>()) @@ -7592,6 +7619,37 @@ void CodeGenModule::EmitMainVoidAlias() { } } +void CodeGenModule::FixupMaybeInlineFunctions() { + // Check if GlobalAlias need to be removed + unsigned long sz = 0; + while (sz != DeferredMaybeInlineFunctions.size()) { + sz = DeferredMaybeInlineFunctions.size(); + for (auto I = DeferredMaybeInlineFunctions.begin(); I != DeferredMaybeInlineFunctions.end();) { + const auto *D = cast<FunctionDecl>(I->first.getDecl()); + auto *GA = GetGlobalValue(D->getName()); + StringRef MangledName = getMangledName(I->first); + if (GA && MustInlinedFunctions.contains(I->second->getName())) { + MustInlinedFunctions.insert(MangledName); + GA->eraseFromParent(); + I = DeferredMaybeInlineFunctions.erase(I); + } else + I++; + } + } + // Fixup attributes + for (auto &[Decl, Callee] : DeferredMaybeInlineFunctions) { + const auto *D = cast<FunctionDecl>(Decl.getDecl()); + auto *GA = GetGlobalValue(D->getName()); + StringRef MangledName = getMangledName(Decl); + auto *GV = GetGlobalValue(MangledName); + if (!GA || !GV) + continue; + SetCommonAttributes(Decl, GA); + addUsedOrCompilerUsedGlobal(GA); + addUsedOrCompilerUsedGlobal(GV); + } +} + /// Turns the given pointer into a constant. static llvm::Constant *GetPointerConstant(llvm::LLVMContext &Context, const void *Ptr) { diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index e7d3f0276566c..bb05bdb8ca538 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -464,6 +464,14 @@ class CodeGenModule : public CodeGenTypeCache { std::vector<llvm::WeakTrackingVH> LLVMUsed; std::vector<llvm::WeakTrackingVH> LLVMCompilerUsed; + /// Set of function names that must be inlined. e.g. + /// __always_inline void foo() { asm (...); } + llvm::DenseSet<StringRef> MustInlinedFunctions; + + /// Deferred always inline functions that has a generated GlobalAlias due to + /// -funique-internal-linkage-names + llvm::MapVector<GlobalDecl, llvm::Function *> DeferredMaybeInlineFunctions; + /// Store the list of global constructors and their respective priorities to /// be emitted when the translation unit is complete. CtorList GlobalCtors; @@ -1257,6 +1265,10 @@ class CodeGenModule : public CodeGenTypeCache { /// Emit an alias for "main" if it has no arguments (needed for wasm). void EmitMainVoidAlias(); + /// Fixup attributes or remove GlobalAlias for always inline functions due to + /// -funique-internal-linkage-names + void FixupMaybeInlineFunctions(); + /// Tell the consumer that this variable has been instantiated. void HandleCXXStaticMemberVarInstantiation(VarDecl *VD); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits