diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2014-09-18 23:41:44 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2014-09-18 23:41:44 +0000 |
commit | c0ce9eca0b709b16e9c1d0f1686d4e2314af02b8 (patch) | |
tree | 71ed27a2daa450a3c47f64aac713d573e5751d7c /clang/lib/CodeGen | |
parent | 2ea8639696ce7f3f732cc2f3607a1aa794eca86f (diff) | |
download | bcm5719-llvm-c0ce9eca0b709b16e9c1d0f1686d4e2314af02b8.tar.gz bcm5719-llvm-c0ce9eca0b709b16e9c1d0f1686d4e2314af02b8.zip |
Put more stuff in the comdat used for variables with static init.
Clang can already handle
-------------------------------------------
struct S {
static const int x;
};
template<typename T> struct U {
static const int k;
};
template<typename T> const int U<T>::k = T::x;
const int S::x = 42;
extern const int *f();
const int *g() { return &U<S>::k; }
int main() {
return *f() + U<S>::k;
}
const int *f() { return &U<S>::k; }
-------------------------------------------
since r217264 which puts the .inint_array section in the same COMDAT
as the variable.
This patch allows the linker to more easily delete some dead code and data by
putting the guard variable and init function in the same COMDAT.
llvm-svn: 218089
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGDeclCXX.cpp | 5 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.h | 3 | ||||
-rw-r--r-- | clang/lib/CodeGen/ItaniumCXXABI.cpp | 7 | ||||
-rw-r--r-- | clang/lib/CodeGen/TargetInfo.cpp | 8 |
4 files changed, 23 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CGDeclCXX.cpp b/clang/lib/CodeGen/CGDeclCXX.cpp index 3e5f42e18c2..3f1e4e8d955 100644 --- a/clang/lib/CodeGen/CGDeclCXX.cpp +++ b/clang/lib/CodeGen/CGDeclCXX.cpp @@ -298,6 +298,11 @@ CodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D, llvm::Function *Fn = CreateGlobalInitOrDestructFunction(*this, FTy, FnName.str()); + if (Addr->isWeakForLinker() && supportsCOMDAT()) { + llvm::Comdat *C = TheModule.getOrInsertComdat(Addr->getName()); + Fn->setComdat(C); + } + auto *ISA = D->getAttr<InitSegAttr>(); CodeGenFunction(*this).GenerateCXXGlobalVarDeclInitFunc(Fn, D, Addr, PerformInit); diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index b36d4a66cd8..a095c9ddbb9 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -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; } diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index 4a24e77139f..865831fedac 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -1666,6 +1666,13 @@ void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF, // If the variable is thread-local, so is its guard variable. guard->setThreadLocalMode(var->getThreadLocalMode()); + // The ABI says: It is suggested that it be emitted in the same COMDAT group + // as the associated data object + if (var->isWeakForLinker() && CGM.supportsCOMDAT()) { + llvm::Comdat *C = CGM.getModule().getOrInsertComdat(var->getName()); + guard->setComdat(C); + } + CGM.setStaticLocalDeclGuardAddress(&D, guard); } diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index 9bf1dbbd0d8..cca825c1c56 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -6868,6 +6868,14 @@ static bool getTypeString(SmallStringEnc &Enc, const Decl *D, // 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; |