r189051 - Add a separate llvm.global_ctors entry for linkonce_odr data initializers
Reid Kleckner
rnk at google.com
Tue Sep 3 17:57:30 PDT 2013
Thanks for the help, it should be fixed with r189898.
On Tue, Sep 3, 2013 at 3:14 PM, Richard Smith <richard at metafoo.co.uk> wrote:
> On Thu, Aug 22, 2013 at 1:07 PM, Reid Kleckner <reid at kleckner.net> wrote:
>
>> Author: rnk
>> Date: Thu Aug 22 15:07:45 2013
>> New Revision: 189051
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=189051&view=rev
>> Log:
>> Add a separate llvm.global_ctors entry for linkonce_odr data initializers
>>
>> Summary:
>> 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.
>>
>> CC: cfe-commits
>>
>> Differential Revision: http://llvm-reviews.chandlerc.com/D1475
>>
>> Modified:
>> cfe/trunk/lib/CodeGen/CGDeclCXX.cpp
>> cfe/trunk/test/CodeGenCXX/microsoft-abi-static-initializers.cpp
>>
>> cfe/trunk/test/CodeGenCXX/static-member-variable-explicit-specialization.cpp
>>
>> Modified: cfe/trunk/lib/CodeGen/CGDeclCXX.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDeclCXX.cpp?rev=189051&r1=189050&r2=189051&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/CodeGen/CGDeclCXX.cpp (original)
>> +++ cfe/trunk/lib/CodeGen/CGDeclCXX.cpp Thu Aug 22 15:07:45 2013
>> @@ -278,6 +278,19 @@ CodeGenModule::EmitCXXGlobalVarDeclInitF
>> OrderGlobalInits Key(order, PrioritizedCXXGlobalInits.size());
>> PrioritizedCXXGlobalInits.push_back(std::make_pair(Key, Fn));
>> DelayedCXXInitPosition.erase(D);
>> + } else if (D->getInstantiatedFromStaticDataMember()) {
>> + // C++ [basic.start.init]p2:
>> + // Defnitions of explicitly specialized class template static data
>> members
>> + // have ordered initialization. Other class template static data
>> members
>> + // (i.e., implicitly or explicitly instantiated specializations)
>> have
>> + // unordered initialization.
>> + //
>> + // As a consequence, we can put them into their own
>> llvm.global_ctors entry.
>> + // This should allow GlobalOpt to fire more often, and allow us to
>> implement
>> + // the Microsoft C++ ABI, which uses COMDAT elimination to avoid
>> double
>> + // initializaiton.
>> + AddGlobalCtor(Fn);
>> + DelayedCXXInitPosition.erase(D);
>>
>
> This is incorrect: explicit specializations of static data members of
> class templates have ordered initialization. This is causing a regression
> on code such as:
>
> int f();
> template<typename T> struct S { static T x; static T y; };
> template<> int S<int>::x = f();
> template<> int S<int>::y = S<int>::x;
>
> Here, 'x' is guaranteed to be initialized before 'y', but with your patch,
> this property is not maintained, and globalopt will remove 'y's initializer.
>
>
>> } else {
>> llvm::DenseMap<const Decl *, unsigned>::iterator I =
>> DelayedCXXInitPosition.find(D);
>>
>> Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-static-initializers.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-static-initializers.cpp?rev=189051&r1=189050&r2=189051&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/test/CodeGenCXX/microsoft-abi-static-initializers.cpp
>> (original)
>> +++ cfe/trunk/test/CodeGenCXX/microsoft-abi-static-initializers.cpp Thu
>> Aug 22 15:07:45 2013
>> @@ -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() {}
>> @@ -33,7 +37,7 @@ void force_usage() {
>> (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 ()* [[FOO_DTOR:@"__dtor_.*foo at .*]])
>> // CHECK: ret void
>> @@ -48,7 +52,6 @@ void force_usage() {
>>
>> // 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 }
>>
>> Modified:
>> cfe/trunk/test/CodeGenCXX/static-member-variable-explicit-specialization.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/static-member-variable-explicit-specialization.cpp?rev=189051&r1=189050&r2=189051&view=diff
>>
>> ==============================================================================
>> ---
>> cfe/trunk/test/CodeGenCXX/static-member-variable-explicit-specialization.cpp
>> (original)
>> +++
>> cfe/trunk/test/CodeGenCXX/static-member-variable-explicit-specialization.cpp
>> Thu Aug 22 15:07:45 2013
>> @@ -1,5 +1,6 @@
>> // 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
>> @@ -8,4 +9,28 @@ 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
>> +
>> +// An explicit specialization is ordered, and goes in __GLOBAL_I_a.
>> +template<> struct A<int> { static int a; };
>> +int A<int>::a = foo();
>> +
>> +// CHECK: define internal void @__cxx_global_var_init()
>> +// CHECK: call i32 @foo()
>> +// CHECK: store {{.*}} @_ZN1AIsE1aE
>> +// CHECK: ret
>>
>> +// CHECK: define internal void @_GLOBAL__I_a()
>> +// We call unique stubs for every ordered dynamic initializer in the
>> TU.
>> +// CHECK: call
>> +// CHECK: call
>> +// CHECK: call
>> +// CHECK-NOT: call
>> +// CHECK: ret
>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>>
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130903/2bb1adfc/attachment.html>
More information about the cfe-commits
mailing list