]> granicus.if.org Git - clang/commitdiff
Put static local variables of inline functions in the function comdat.
authorRafael Espindola <rafael.espindola@gmail.com>
Tue, 16 Dec 2014 21:00:30 +0000 (21:00 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Tue, 16 Dec 2014 21:00:30 +0000 (21:00 +0000)
The variable (and the GV) is only ever used if the function is. Putting it
in the function's comdat make it easier for the linker to discard them.

The motivating example is

struct S {
  static const int x;
};
// const int S::x = 42;
inline const int *f() {
  static const int y = S::x;
  return &y;
}
const int *g() { return f(); }

With S::x commented out, _ZZ1fvE1y is a variable with a guard variable
that is initialized by f.

With S::x present, _ZZ1fvE1y is a constant.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@224369 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/ItaniumCXXABI.cpp
test/CodeGenCXX/static-init.cpp

index fd299d14c13cffea7be8756e695229e3c99d9553..8d74faf179719e01662166203b789168d3574a27 100644 (file)
@@ -1711,8 +1711,10 @@ void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF,
 
     // The ABI says: It is suggested that it be emitted in the same COMDAT group
     // as the associated data object
-    if (!D.isLocalVarDecl() && var->isWeakForLinker() && CGM.supportsCOMDAT()) {
-      llvm::Comdat *C = CGM.getModule().getOrInsertComdat(var->getName());
+    if (var->isWeakForLinker() && CGM.supportsCOMDAT()) {
+      StringRef ComdatName =
+        D.isLocalVarDecl() ? CGF.CurFn->getName() : var->getName();
+      llvm::Comdat *C = CGM.getModule().getOrInsertComdat(ComdatName);
       guard->setComdat(C);
       var->setComdat(C);
       CGF.CurFn->setComdat(C);
index a9debe3de76506b649c2cf3f7754245189c30d8b..262d750e09fc801c102695544ad35ba3464be4e1 100644 (file)
@@ -7,10 +7,8 @@
 // CHECK: @_ZZN5test31BC1EvE1u = internal global { i8, [3 x i8] } { i8 97, [3 x i8] undef }, align 4
 // CHECK: @_ZZN5test1L6getvarEiE3var = internal constant [4 x i32] [i32 1, i32 0, i32 2, i32 4], align 16
 
-// CHECK: @_ZZ2h2vE1i = linkonce_odr global i32 0
-// CHECK-NOT: comdat
-// CHECK: @_ZGVZ2h2vE1i = linkonce_odr global i64 0
-// CHECK-NOT: comdat
+// CHECK: @_ZZ2h2vE1i = linkonce_odr global i32 0, comdat $_Z2h2v
+// CHECK: @_ZGVZ2h2vE1i = linkonce_odr global i64 0, comdat $_Z2h2v
 
 struct A {
   A();
@@ -37,8 +35,7 @@ void h() {
   static const int i = a();
 }
 
-// CHECK: define linkonce_odr void @_Z2h2v()
-// CHECK-NOT: comdat
+// CHECK: define linkonce_odr void @_Z2h2v() {{.*}} comdat $_Z2h2v
 inline void h2() {
   static int i = a();
 }