[PATCH] Add a separate llvm.global_ctors entry for linkonce_odr data initializers
Reid Kleckner
rnk at google.com
Thu Aug 22 09:44:25 PDT 2013
These typically come from static data members of class template
specializations. This accomplishes two things:
1. May expose GlobalOpt optimizations for Itanium C++ ABI code.
2. Works toward fixing double initialization in the Microsoft C++ ABI.
http://llvm-reviews.chandlerc.com/D1475
Files:
lib/CodeGen/CGDeclCXX.cpp
test/CodeGenCXX/microsoft-abi-static-initializers.cpp
test/CodeGenCXX/static-member-variable-explicit-specialization.cpp
Index: lib/CodeGen/CGDeclCXX.cpp
===================================================================
--- lib/CodeGen/CGDeclCXX.cpp
+++ lib/CodeGen/CGDeclCXX.cpp
@@ -284,6 +284,13 @@
OrderGlobalInits Key(order, PrioritizedCXXGlobalInits.size());
PrioritizedCXXGlobalInits.push_back(std::make_pair(Key, Fn));
DelayedCXXInitPosition.erase(D);
+ } else if (D->getInstantiatedFromStaticDataMember()) {
+ // Initializers of static data members of class template specializations are
+ // not guaranteed to run in any order with respect to the rest of the
+ // initializers in a TU. As a consequence, we can put them into their own
+ // llvm.global_ctors entry. This should allow GlobalOpt to fire more often.
+ AddGlobalCtor(Fn);
+ DelayedCXXInitPosition.erase(D);
} else {
llvm::DenseMap<const Decl *, unsigned>::iterator I =
DelayedCXXInitPosition.find(D);
Index: test/CodeGenCXX/microsoft-abi-static-initializers.cpp
===================================================================
--- test/CodeGenCXX/microsoft-abi-static-initializers.cpp
+++ test/CodeGenCXX/microsoft-abi-static-initializers.cpp
@@ -1,5 +1,9 @@
// RUN: %clang_cc1 -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s
+// CHECK: @llvm.global_ctors = appending global [2 x { i32, void ()* }]
+// CHECK: [{ i32, void ()* } { i32 65535, void ()* [[INIT_foo:@.*global_var.*]] },
+// CHECK: { i32, void ()* } { i32 65535, void ()* @_GLOBAL__I_a }]
+
struct S {
S();
~S();
@@ -130,7 +134,7 @@
(void)B<int>::foo; // (void) - force usage
}
-// CHECK: define internal void [[INIT_foo:@.*global_var.*]] [[NUW]]
+// CHECK: define internal void [[INIT_foo]]() [[NUW]]
// CHECK: %{{[.0-9A-Z_a-z]+}} = call x86_thiscallcc %class.A* @"\01??0A@@QAE at XZ"
// CHECK: call i32 @atexit(void ()* @"\01??__Ffoo@?$B at H@@YAXXZ")
// CHECK: ret void
@@ -145,7 +149,6 @@
// CHECK: define internal void @_GLOBAL__I_a() [[NUW]] {
// CHECK: call void [[INIT_s]]
-// CHECK: call void [[INIT_foo]]
// CHECK: ret void
// CHECK: attributes [[NUW]] = { nounwind }
Index: test/CodeGenCXX/static-member-variable-explicit-specialization.cpp
===================================================================
--- test/CodeGenCXX/static-member-variable-explicit-specialization.cpp
+++ test/CodeGenCXX/static-member-variable-explicit-specialization.cpp
@@ -1,11 +1,30 @@
// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
// CHECK: ; ModuleID
+
template<typename> struct A { static int a; };
// CHECK-NOT: @_ZN1AIcE1aE
template<> int A<char>::a;
// CHECK: @_ZN1AIbE1aE = global i32 10
template<> int A<bool>::a = 10;
+// CHECK: @llvm.global_ctors = appending global [2 x { i32, void ()* }]
+// CHECK: [{ i32, void ()* } { i32 65535, void ()* @__cxx_global_var_init },
+// CHECK: { i32, void ()* } { i32 65535, void ()* @_GLOBAL__I_a }]
+
+extern "C" int foo();
+template<> int A<short>::a = foo(); // Separate global_ctor entry
+int b = foo(); // Goes in _GLOBAL__I_a
+int c = foo(); // Goes in _GLOBAL__I_a
+
+// CHECK: define internal void @__cxx_global_var_init()
+// CHECK: call i32 @foo()
+// CHECK: store {{.*}} @_ZN1AIsE1aE
+// CHECK: ret
+// CHECK: define internal void @_GLOBAL__I_a()
+// CHECK: call
+// CHECK: call
+// CHECK-NOT: call
+// CHECK: ret
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D1475.1.patch
Type: text/x-patch
Size: 3338 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130822/4f1d439f/attachment.bin>
More information about the cfe-commits
mailing list