r218097 - Don't use the third field of llvm.global_ctors for MachO.
Rafael Espindola
rafael.espindola at gmail.com
Thu Sep 18 18:54:23 PDT 2014
Author: rafael
Date: Thu Sep 18 20:54:22 2014
New Revision: 218097
URL: http://llvm.org/viewvc/llvm-project?rev=218097&view=rev
Log:
Don't use the third field of llvm.global_ctors for MachO.
The field is defined as:
If the third field is present, non-null, and points to a global variable or function, the initializer function will only run if the associated data from the current module is not discarded.
And without COMDATs we can't implement that.
Modified:
cfe/trunk/lib/CodeGen/CGDeclCXX.cpp
cfe/trunk/lib/CodeGen/CodeGenModule.h
cfe/trunk/lib/CodeGen/TargetInfo.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=218097&r1=218096&r2=218097&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDeclCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDeclCXX.cpp Thu Sep 18 20:54:22 2014
@@ -301,6 +301,9 @@ CodeGenModule::EmitCXXGlobalVarDeclInitF
auto *ISA = D->getAttr<InitSegAttr>();
CodeGenFunction(*this).GenerateCXXGlobalVarDeclInitFunc(Fn, D, Addr,
PerformInit);
+
+ llvm::GlobalVariable *Key = supportsCOMDAT() ? Addr : nullptr;
+
if (D->getTLSKind()) {
// FIXME: Should we support init_priority for thread_local?
// FIXME: Ideally, initialization of instantiated thread_local static data
@@ -330,12 +333,12 @@ CodeGenModule::EmitCXXGlobalVarDeclInitF
// being initialized. On most platforms, this is a minor startup time
// optimization. In the MS C++ ABI, there are no guard variables, so this
// COMDAT key is required for correctness.
- AddGlobalCtor(Fn, 65535, Addr);
+ AddGlobalCtor(Fn, 65535, Key);
DelayedCXXInitPosition.erase(D);
} else if (D->hasAttr<SelectAnyAttr>()) {
// SelectAny globals will be comdat-folded. Put the initializer into a COMDAT
// group associated with the global, so the initializers get folded too.
- AddGlobalCtor(Fn, 65535, Addr);
+ AddGlobalCtor(Fn, 65535, Key);
DelayedCXXInitPosition.erase(D);
} else {
llvm::DenseMap<const Decl *, unsigned>::iterator I =
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=218097&r1=218096&r2=218097&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Thu Sep 18 20:54:22 2014
@@ -599,6 +599,9 @@ public:
DiagnosticsEngine &getDiags() const { return Diags; }
const llvm::DataLayout &getDataLayout() const { return TheDataLayout; }
const TargetInfo &getTarget() const { return Target; }
+ const llvm::Triple &getTriple() const;
+ bool supportsCOMDAT() const;
+
CGCXXABI &getCXXABI() const { return *ABI; }
llvm::LLVMContext &getLLVMContext() { return VMContext; }
Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=218097&r1=218096&r2=218097&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Thu Sep 18 20:54:22 2014
@@ -6868,6 +6868,14 @@ static bool getTypeString(SmallStringEnc
// Driver code
//===----------------------------------------------------------------------===//
+const llvm::Triple &CodeGenModule::getTriple() const {
+ return getTarget().getTriple();
+}
+
+bool CodeGenModule::supportsCOMDAT() const {
+ return !getTriple().isOSBinFormatMachO();
+}
+
const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() {
if (TheTargetCodeGenInfo)
return *TheTargetCodeGenInfo;
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=218097&r1=218096&r2=218097&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/static-member-variable-explicit-specialization.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/static-member-variable-explicit-specialization.cpp Thu Sep 18 20:54:22 2014
@@ -1,25 +1,40 @@
-// RUN: %clang_cc1 %s -std=c++1y -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
-// CHECK: ; ModuleID
+// RUN: %clang_cc1 %s -std=c++1y -triple=x86_64-pc-linux -emit-llvm -o - | FileCheck --check-prefix=ELF --check-prefix=ALL %s
+// RUN: %clang_cc1 %s -std=c++1y -triple=x86_64-apple-darwin -emit-llvm -o - | FileCheck --check-prefix=MACHO --check-prefix=ALL %s
+
+// ALL: ; ModuleID
extern "C" int foo();
template<typename T> struct A { static int a; };
template<typename T> int A<T>::a = foo();
-// CHECK-NOT: @_ZN1AIcE1aE
+// ALLK-NOT: @_ZN1AIcE1aE
template<> int A<char>::a;
-// CHECK: @_ZN1AIbE1aE = global i32 10
+// ALL: @_ZN1AIbE1aE = global i32 10
template<> int A<bool>::a = 10;
-// CHECK: @llvm.global_ctors = appending global [7 x { i32, void ()*, i8* }]
-// CHECK: [{ i32, void ()*, i8* } { i32 65535, void ()* @[[unordered1:[^,]*]], i8* bitcast (i32* @_ZN1AIsE1aE to i8*) },
-// CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered2:[^,]*]], i8* bitcast (i16* @_Z1xIsE to i8*) },
-// CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered3:[^,]*]], i8* bitcast (i32* @_ZN2ns1aIiE1iE to i8*) },
-// CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered4:[^,]*]], i8* bitcast (i32* @_ZN2ns1b1iIiEE to i8*) },
-// CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered5:[^,]*]], i8* bitcast (i32* @_ZN1AIvE1aE to i8*) },
-// CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered6:[^,]*]], i8* @_Z1xIcE },
-// CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_static_member_variable_explicit_specialization.cpp, i8* null }]
+// ALL: @llvm.global_ctors = appending global [7 x { i32, void ()*, i8* }]
+
+// ELF: [{ i32, void ()*, i8* } { i32 65535, void ()* @[[unordered1:[^,]*]], i8* bitcast (i32* @_ZN1AIsE1aE to i8*) },
+// MACHO: [{ i32, void ()*, i8* } { i32 65535, void ()* @[[unordered1:[^,]*]], i8* null },
+
+// ELF: { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered2:[^,]*]], i8* bitcast (i16* @_Z1xIsE to i8*) },
+// MACHO: { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered2:[^,]*]], i8* null },
+
+// ELF: { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered3:[^,]*]], i8* bitcast (i32* @_ZN2ns1aIiE1iE to i8*) },
+// MACHO: { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered3:[^,]*]], i8* null },
+
+// ELF: { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered4:[^,]*]], i8* bitcast (i32* @_ZN2ns1b1iIiEE to i8*) },
+// MACHO: { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered4:[^,]*]], i8* null },
+
+// ELF: { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered5:[^,]*]], i8* bitcast (i32* @_ZN1AIvE1aE to i8*) },
+// MACHO: { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered5:[^,]*]], i8* null },
+
+// ELF: { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered6:[^,]*]], i8* @_Z1xIcE },
+// MACHO: { i32, void ()*, i8* } { i32 65535, void ()* @[[unordered6:[^,]*]], i8* null },
+
+// ALL: { i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_static_member_variable_explicit_specialization.cpp, i8* null }]
template int A<short>::a; // Unordered
int b = foo();
@@ -52,45 +67,45 @@ struct b {
template<typename T> T b::i = foo();
template int b::i<int>;
}
-// CHECK: define internal void @[[unordered1]]
-// CHECK: call i32 @foo()
-// CHECK: store {{.*}} @_ZN1AIsE1aE
-// CHECK: ret
-
-// CHECK: define internal void @[[unordered2]]
-// CHECK: call i32 @foo()
-// CHECK: store {{.*}} @_Z1xIsE
-// CHECK: ret
-
-// CHECK: define internal void @[[unordered3]]
-// CHECK: call i32 @foo()
-// CHECK: store {{.*}} @_ZN2ns1aIiE1iE
-// CHECK: ret
-
-// CHECK: define internal void @[[unordered4]]
-// CHECK: call i32 @foo()
-// CHECK: store {{.*}} @_ZN2ns1b1iIiEE
-// CHECK: ret
-
-// CHECK: define internal void @[[unordered5]]
-// CHECK: call i32 @foo()
-// CHECK: store {{.*}} @_ZN1AIvE1aE
-// CHECK: ret
-
-// CHECK: define internal void @[[unordered6]]
-// CHECK: call i32 @foo()
-// CHECK: store {{.*}} @_Z1xIcE
-// CHECK: ret
+// ALL: define internal void @[[unordered1]]
+// ALL: call i32 @foo()
+// ALL: store {{.*}} @_ZN1AIsE1aE
+// ALL: ret
+
+// ALL: define internal void @[[unordered2]]
+// ALL: call i32 @foo()
+// ALL: store {{.*}} @_Z1xIsE
+// ALL: ret
+
+// ALL: define internal void @[[unordered3]]
+// ALL: call i32 @foo()
+// ALL: store {{.*}} @_ZN2ns1aIiE1iE
+// ALL: ret
+
+// ALL: define internal void @[[unordered4]]
+// ALL: call i32 @foo()
+// ALL: store {{.*}} @_ZN2ns1b1iIiEE
+// ALL: ret
+
+// ALL: define internal void @[[unordered5]]
+// ALL: call i32 @foo()
+// ALL: store {{.*}} @_ZN1AIvE1aE
+// ALL: ret
+
+// ALL: define internal void @[[unordered6]]
+// ALL: call i32 @foo()
+// ALL: store {{.*}} @_Z1xIcE
+// ALL: ret
-// CHECK: define internal void @_GLOBAL__sub_I_static_member_variable_explicit_specialization.cpp()
+// ALL: define internal void @_GLOBAL__sub_I_static_member_variable_explicit_specialization.cpp()
// We call unique stubs for every ordered dynamic initializer in the TU.
-// CHECK: call
-// CHECK: call
-// CHECK: call
-// CHECK: call
-// CHECK: call
-// CHECK: call
-// CHECK: call
-// CHECK: call
-// CHECK-NOT: call
-// CHECK: ret
+// ALL: call
+// ALL: call
+// ALL: call
+// ALL: call
+// ALL: call
+// ALL: call
+// ALL: call
+// ALL: call
+// ALL-NOT: call
+// ALL: ret
More information about the cfe-commits
mailing list