[clang] 28cb620 - Change some addUsedGlobal to addUsedOrCompilerUsedGlobal

Fangrui Song via cfe-commits cfe-commits at lists.llvm.org
Fri Feb 26 10:42:14 PST 2021


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


        


More information about the cfe-commits mailing list