Author: Fangrui Song Date: 2021-02-26T10:42:07-08:00 New Revision: 28cb620321f5461255423f84c85e6891b5174c13
URL: https://github.com/llvm/llvm-project/commit/28cb620321f5461255423f84c85e6891b5174c13 DIFF: https://github.com/llvm/llvm-project/commit/28cb620321f5461255423f84c85e6891b5174c13.diff LOG: Change some addUsedGlobal to addUsedOrCompilerUsedGlobal An global value in the `llvm.used` list does not have GC root semantics on ELF targets. This will be changed in a subsequent backend patch. Change some `llvm.used` in the ELF code path to use `llvm.compiler.used` to prevent undesired GC root semantics. Change one extern "C" alias (due to `__attribute__((used))` in extern "C") to use `llvm.compiler.used` on all targets. GNU ld has a rule "`__start_/__stop_` references from a live input section retain the associated C identifier name sections", which LLD may drop entirely (currently refined to exclude SHF_LINK_ORDER/SHF_GROUP) in a future release (the rule makes it clumsy to GC metadata sections; D96914 added a way to try the potential future behavior). For `llvm.used` global values defined in a C identifier name section, keep using `llvm.used` so that the future LLD change will not affect them. rnk kindly categorized the changes: ``` ObjC/blocks: this wants GC root semantics, since ObjC mainly runs on Mac. MS C++ ABI stuff: wants GC root semantics, no change OpenMP: unsure, but GC root semantics probably don't hurt CodeGenModule: affected in this patch to *not* use GC root semantics so that __attribute__((used)) behavior remains the same on ELF, plus two other minor use cases that don't want GC semantics Coverage: Probably want GC root semantics CGExpr.cpp: refers to LTO, wants GC root CGDeclCXX.cpp: one is MS ABI specific, so yes GC root, one is some other C++ init functionality, which should form GC roots (C++ initializers can have side effects and must run) CGDecl.cpp: Changed in this patch for __attribute__((used)) ``` Differential Revision: https://reviews.llvm.org/D97446 Added: Modified: clang/lib/CodeGen/CGDecl.cpp clang/lib/CodeGen/CodeGenModule.cpp clang/lib/CodeGen/CodeGenModule.h clang/test/CodeGen/2005-12-04-AttributeUsed.c clang/test/CodeGen/attr-msp430.c clang/test/CodeGen/attr-target-mv.c clang/test/CodeGen/attr-used.c clang/test/CodeGen/attr-x86-interrupt.c clang/test/CodeGen/keep-static-consts.cpp clang/test/CodeGenCUDA/llvm-used.cu clang/test/CodeGenCXX/attr-x86-interrupt.cpp clang/test/CodeGenCXX/extern-c.cpp Removed: ################################################################################ diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index a01638f0b67b..ecf79dbbaffc 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -442,7 +442,7 @@ void CodeGenFunction::EmitStaticVarDecl(const VarDecl &D, var->setSection(SA->getName()); if (D.hasAttr<UsedAttr>()) - CGM.addUsedGlobal(var); + CGM.addUsedOrCompilerUsedGlobal(var); // We may have to cast the constant because of the initializer // mismatch above. diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 9dcdc8da4d92..564b07582376 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1820,13 +1820,13 @@ void CodeGenModule::SetCommonAttributes(GlobalDecl GD, llvm::GlobalValue *GV) { GV->setVisibility(llvm::GlobalValue::DefaultVisibility); if (D && D->hasAttr<UsedAttr>()) - addUsedGlobal(GV); + addUsedOrCompilerUsedGlobal(GV); if (CodeGenOpts.KeepStaticConsts && D && isa<VarDecl>(D)) { const auto *VD = cast<VarDecl>(D); if (VD->getType().isConstQualified() && VD->getStorageDuration() == SD_Static) - addUsedGlobal(GV); + addUsedOrCompilerUsedGlobal(GV); } } @@ -2087,6 +2087,15 @@ void CodeGenModule::addCompilerUsedGlobal(llvm::GlobalValue *GV) { LLVMCompilerUsed.emplace_back(GV); } +void CodeGenModule::addUsedOrCompilerUsedGlobal(llvm::GlobalValue *GV) { + assert((isa<llvm::Function>(GV) || !GV->isDeclaration()) && + "Only globals with definition can force usage."); + if (getTriple().isOSBinFormatELF()) + LLVMCompilerUsed.emplace_back(GV); + else + LLVMUsed.emplace_back(GV); +} + static void emitUsed(CodeGenModule &CGM, StringRef Name, std::vector<llvm::WeakTrackingVH> &List) { // Don't create llvm.used if there is no need. @@ -5912,7 +5921,7 @@ void CodeGenModule::EmitStaticExternCAliases() { IdentifierInfo *Name = I.first; llvm::GlobalValue *Val = I.second; if (Val && !getModule().getNamedValue(Name->getName())) - addUsedGlobal(llvm::GlobalAlias::create(Name->getName(), Val)); + addCompilerUsedGlobal(llvm::GlobalAlias::create(Name->getName(), Val)); } } diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index 49f94042a787..d495a169b609 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -1054,6 +1054,9 @@ class CodeGenModule : public CodeGenTypeCache { /// Add a global to a list to be added to the llvm.compiler.used metadata. void addCompilerUsedGlobal(llvm::GlobalValue *GV); + /// Add a global to a list to be added to the llvm.compiler.used metadata. + void addUsedOrCompilerUsedGlobal(llvm::GlobalValue *GV); + /// Add a destructor and object to add to the C++ global destructor function. void AddCXXDtorEntry(llvm::FunctionCallee DtorFn, llvm::Constant *Object) { CXXGlobalDtorsOrStermFinalizers.emplace_back(DtorFn.getFunctionType(), diff --git a/clang/test/CodeGen/2005-12-04-AttributeUsed.c b/clang/test/CodeGen/2005-12-04-AttributeUsed.c index 4be6b798fd43..b2146ccb8295 100644 --- a/clang/test/CodeGen/2005-12-04-AttributeUsed.c +++ b/clang/test/CodeGen/2005-12-04-AttributeUsed.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -triple x86_64-apple-darwin -emit-llvm -o - | FileCheck %s // CHECK: @llvm.used = appending global [2 x i8*] [i8* bitcast (void ()* @foo to i8*), i8* bitcast (i32* @X to i8*)], section "llvm.metadata" int X __attribute__((used)); diff --git a/clang/test/CodeGen/attr-msp430.c b/clang/test/CodeGen/attr-msp430.c index c6d6e54df79b..cbc7599b96bf 100644 --- a/clang/test/CodeGen/attr-msp430.c +++ b/clang/test/CodeGen/attr-msp430.c @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -triple msp430-unknown-unknown -emit-llvm < %s| FileCheck %s __attribute__((interrupt(1))) void foo(void) {} -// CHECK: @llvm.used +// CHECK: @llvm.compiler.used = // CHECK-SAME: @foo // CHECK: define{{.*}} msp430_intrcc void @foo() #0 diff --git a/clang/test/CodeGen/attr-target-mv.c b/clang/test/CodeGen/attr-target-mv.c index e106b635e08b..ef966cf2efec 100644 --- a/clang/test/CodeGen/attr-target-mv.c +++ b/clang/test/CodeGen/attr-target-mv.c @@ -65,7 +65,7 @@ __attribute__((target("avx,sse4.2"))) inline void foo_used(int i, double d) {} __attribute__((target("default"))) inline void foo_used2(int i, double d) {} __attribute__((target("avx,sse4.2"), used)) inline void foo_used2(int i, double d) {} -// LINUX: @llvm.used = appending global [2 x i8*] [i8* bitcast (void (i32, double)* @foo_used to i8*), i8* bitcast (void (i32, double)* @foo_used2.avx_sse4.2 to i8*)], section "llvm.metadata" +// LINUX: @llvm.compiler.used = appending global [2 x i8*] [i8* bitcast (void (i32, double)* @foo_used to i8*), i8* bitcast (void (i32, double)* @foo_used2.avx_sse4.2 to i8*)], section "llvm.metadata" // WINDOWS: @llvm.used = appending global [2 x i8*] [i8* bitcast (void (i32, double)* @foo_used to i8*), i8* bitcast (void (i32, double)* @foo_used2.avx_sse4.2 to i8*)], section "llvm.metadata" // LINUX: @foo.ifunc = weak_odr ifunc i32 (), i32 ()* ()* @foo.resolver diff --git a/clang/test/CodeGen/attr-used.c b/clang/test/CodeGen/attr-used.c index de38b51523a0..dee0cf6a9fd3 100644 --- a/clang/test/CodeGen/attr-used.c +++ b/clang/test/CodeGen/attr-used.c @@ -1,9 +1,12 @@ -// RUN: %clang_cc1 -emit-llvm -o %t %s -// RUN: grep '@llvm.used = .*@a0' %t -// RUN: grep '@llvm.used = .*@g0' %t -// RUN: grep '@llvm.used = .*@f0' %t -// RUN: grep '@llvm.used = .*@f1.l0' %t +// RUN: %clang_cc1 -emit-llvm -triple x86_64 %s -o - | FileCheck %s --check-prefixes=CHECK,CUSED +// RUN: %clang_cc1 -emit-llvm -triple x86_64-apple-darwin %s -o - | FileCheck %s --check-prefixes=CHECK,USED +// USED: @llvm.used = +// CUSED: @llvm.compiler.used = +// CHECK-SAME: @f0 +// CHECK-SAME: @f1.l0 +// CHECK-SAME: @g0 +// CHECK-SAME: @a0 int g0 __attribute__((used)); diff --git a/clang/test/CodeGen/attr-x86-interrupt.c b/clang/test/CodeGen/attr-x86-interrupt.c index c9f7245bab06..3453784dcc3a 100644 --- a/clang/test/CodeGen/attr-x86-interrupt.c +++ b/clang/test/CodeGen/attr-x86-interrupt.c @@ -12,12 +12,12 @@ typedef __UINT32_TYPE__ uword; __attribute__((interrupt)) void foo7(int *a, uword b) {} __attribute__((interrupt)) void foo8(int *a) {} -// X86_64_LINUX: @llvm.used = appending global [2 x i8*] [i8* bitcast (void (i32*, i64)* @foo7 to i8*), i8* bitcast (void (i32*)* @foo8 to i8*)], section "llvm.metadata" +// X86_64_LINUX: @llvm.compiler.used = appending global [2 x i8*] [i8* bitcast (void (i32*, i64)* @foo7 to i8*), i8* bitcast (void (i32*)* @foo8 to i8*)], section "llvm.metadata" // X86_64_LINUX: define{{.*}} x86_intrcc void @foo7(i32* byval(i32) %{{.+}}, i64 %{{.+}}) // X86_64_LINUX: define{{.*}} x86_intrcc void @foo8(i32* byval(i32) %{{.+}}) // X86_64_LINUX: "disable-tail-calls"="true" // X86_64_LINUX-NOT: "disable-tail-calls"="false" -// X86_LINUX: @llvm.used = appending global [2 x i8*] [i8* bitcast (void (i32*, i32)* @foo7 to i8*), i8* bitcast (void (i32*)* @foo8 to i8*)], section "llvm.metadata" +// X86_LINUX: @llvm.compiler.used = appending global [2 x i8*] [i8* bitcast (void (i32*, i32)* @foo7 to i8*), i8* bitcast (void (i32*)* @foo8 to i8*)], section "llvm.metadata" // X86_LINUX: define{{.*}} x86_intrcc void @foo7(i32* byval(i32) %{{.+}}, i32 %{{.+}}) // X86_LINUX: define{{.*}} x86_intrcc void @foo8(i32* byval(i32) %{{.+}}) // X86_LINUX: "disable-tail-calls"="true" diff --git a/clang/test/CodeGen/keep-static-consts.cpp b/clang/test/CodeGen/keep-static-consts.cpp index d89f21cf65aa..c92bb3ece812 100644 --- a/clang/test/CodeGen/keep-static-consts.cpp +++ b/clang/test/CodeGen/keep-static-consts.cpp @@ -3,7 +3,7 @@ // CHECK: @_ZL7srcvers = internal constant [4 x i8] c"xyz\00", align 1 // CHECK: @_ZL8srcvers2 = internal constant [4 x i8] c"abc\00", align 1 // CHECK: @_ZL1N = internal constant i32 2, align 4 -// CHECK: @llvm.used = appending global [4 x i8*] [i8* getelementptr inbounds ([4 x i8], [4 x i8]* @_ZL7srcvers, i32 0, i32 0), i8* bitcast (i32* @b to i8*), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @_ZL8srcvers2, i32 0, i32 0), i8* bitcast (i32* @_ZL1N to i8*)], section "llvm.metadata" +// CHECK: @llvm.compiler.used = appending global [4 x i8*] [i8* getelementptr inbounds ([4 x i8], [4 x i8]* @_ZL7srcvers, i32 0, i32 0), i8* bitcast (i32* @b to i8*), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @_ZL8srcvers2, i32 0, i32 0), i8* bitcast (i32* @_ZL1N to i8*)], section "llvm.metadata" static const char srcvers[] = "xyz"; extern const int b = 1; diff --git a/clang/test/CodeGenCUDA/llvm-used.cu b/clang/test/CodeGenCUDA/llvm-used.cu index 44666a91c3bb..37358a61d0e3 100644 --- a/clang/test/CodeGenCUDA/llvm-used.cu +++ b/clang/test/CodeGenCUDA/llvm-used.cu @@ -4,5 +4,5 @@ // Make sure we emit the proper addrspacecast for llvm.used. PR22383 exposed an // issue where we were generating a bitcast instead of an addrspacecast. -// CHECK: @llvm.used = appending global [1 x i8*] [i8* addrspacecast (i8 addrspace(1)* bitcast ([0 x i32] addrspace(1)* @a to i8 addrspace(1)*) to i8*)], section "llvm.metadata" +// CHECK: @llvm.compiler.used = appending global [1 x i8*] [i8* addrspacecast (i8 addrspace(1)* bitcast ([0 x i32] addrspace(1)* @a to i8 addrspace(1)*) to i8*)], section "llvm.metadata" __attribute__((device)) __attribute__((__used__)) int a[] = {}; diff --git a/clang/test/CodeGenCXX/attr-x86-interrupt.cpp b/clang/test/CodeGenCXX/attr-x86-interrupt.cpp index e5a855f8852a..446d4d79a5a9 100644 --- a/clang/test/CodeGenCXX/attr-x86-interrupt.cpp +++ b/clang/test/CodeGenCXX/attr-x86-interrupt.cpp @@ -17,11 +17,11 @@ __attribute__((interrupt)) void foo8(int *a) {} struct St { static void foo9(int *a) __attribute__((interrupt)) {} }; -// X86_64_LINUX: @llvm.used = appending global [3 x i8*] [i8* bitcast (void (i32*, i64)* @{{.*}}foo7{{.*}} to i8*), i8* bitcast (void (i32*)* @{{.*}}foo8{{.*}} to i8*), i8* bitcast (void (i32*)* @{{.*}}foo9{{.*}} to i8*)], section "llvm.metadata" +// X86_64_LINUX: @llvm.compiler.used = appending global [3 x i8*] [i8* bitcast (void (i32*, i64)* @{{.*}}foo7{{.*}} to i8*), i8* bitcast (void (i32*)* @{{.*}}foo8{{.*}} to i8*), i8* bitcast (void (i32*)* @{{.*}}foo9{{.*}} to i8*)], section "llvm.metadata" // X86_64_LINUX: define{{.*}} x86_intrcc void @{{.*}}foo7{{.*}}(i32* byval(i32) %{{.+}}, i64 %{{.+}}) // X86_64_LINUX: define{{.*}} x86_intrcc void @{{.*}}foo8{{.*}}(i32* byval(i32) %{{.+}}) // X86_64_LINUX: define linkonce_odr x86_intrcc void @{{.*}}foo9{{.*}}(i32* byval(i32) %{{.+}}) -// X86_LINUX: @llvm.used = appending global [3 x i8*] [i8* bitcast (void (i32*, i32)* @{{.*}}foo7{{.*}} to i8*), i8* bitcast (void (i32*)* @{{.*}}foo8{{.*}} to i8*), i8* bitcast (void (i32*)* @{{.*}}foo9{{.*}} to i8*)], section "llvm.metadata" +// X86_LINUX: @llvm.compiler.used = appending global [3 x i8*] [i8* bitcast (void (i32*, i32)* @{{.*}}foo7{{.*}} to i8*), i8* bitcast (void (i32*)* @{{.*}}foo8{{.*}} to i8*), i8* bitcast (void (i32*)* @{{.*}}foo9{{.*}} to i8*)], section "llvm.metadata" // X86_LINUX: define{{.*}} x86_intrcc void @{{.*}}foo7{{.*}}(i32* byval(i32) %{{.+}}, i32 %{{.+}}) // X86_LINUX: define{{.*}} x86_intrcc void @{{.*}}foo8{{.*}}(i32* byval(i32) %{{.+}}) // X86_LINUX: define linkonce_odr x86_intrcc void @{{.*}}foo9{{.*}}(i32* byval(i32) %{{.+}}) diff --git a/clang/test/CodeGenCXX/extern-c.cpp b/clang/test/CodeGenCXX/extern-c.cpp index b80d3257e5de..d5498b8d2686 100644 --- a/clang/test/CodeGenCXX/extern-c.cpp +++ b/clang/test/CodeGenCXX/extern-c.cpp @@ -70,7 +70,7 @@ extern "C" { __attribute__((used)) static int duplicate_internal_fn() { return 0; } } - // CHECK: @llvm.used = appending global {{.*}} @internal_var {{.*}} @internal_fn + // CHECK: @llvm.compiler.used = appending global {{.*}} @internal_var {{.*}} @internal_fn // CHECK-NOT: @unused // CHECK-NOT: @duplicate_internal _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits