summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
authorReid Kleckner <reid@kleckner.net>2015-04-15 01:08:06 +0000
committerReid Kleckner <reid@kleckner.net>2015-04-15 01:08:06 +0000
commite07140eb3fb5b2d3df2f57cccc633a0d1e21c6f2 (patch)
tree7ae34ebf92346ca97b9df63beff0cac6f606dd98 /clang/lib/CodeGen
parent58927f1aa2e37854b5ff728eedda8ec8aff779be (diff)
downloadbcm5719-llvm-e07140eb3fb5b2d3df2f57cccc633a0d1e21c6f2.tar.gz
bcm5719-llvm-e07140eb3fb5b2d3df2f57cccc633a0d1e21c6f2.zip
Move the logic to avoid double global emission from Sema to CodeGen
Reverts the code changes from r234675 but keeps the test case. We were already maintaining a DenseMap of globals with dynamic initializers anyway. Fixes the test case from PR23234. llvm-svn: 234961
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CGDeclCXX.cpp21
-rw-r--r--clang/lib/CodeGen/CodeGenModule.h3
2 files changed, 14 insertions, 10 deletions
diff --git a/clang/lib/CodeGen/CGDeclCXX.cpp b/clang/lib/CodeGen/CGDeclCXX.cpp
index 236337b4034..eb4ddc704d1 100644
--- a/clang/lib/CodeGen/CGDeclCXX.cpp
+++ b/clang/lib/CodeGen/CGDeclCXX.cpp
@@ -298,6 +298,11 @@ void
CodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D,
llvm::GlobalVariable *Addr,
bool PerformInit) {
+ // Check if we've already initialized this decl.
+ auto I = DelayedCXXInitPosition.find(D);
+ if (I != DelayedCXXInitPosition.end() && I->second == ~0U)
+ return;
+
llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);
SmallString<256> FnName;
{
@@ -327,11 +332,9 @@ CodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D,
CXXThreadLocalInitVars.push_back(Addr);
} else if (PerformInit && ISA) {
EmitPointerToInitFunc(D, Addr, Fn, ISA);
- DelayedCXXInitPosition.erase(D);
} else if (auto *IPA = D->getAttr<InitPriorityAttr>()) {
OrderGlobalInits Key(IPA->getPriority(), PrioritizedCXXGlobalInits.size());
PrioritizedCXXGlobalInits.push_back(std::make_pair(Key, Fn));
- DelayedCXXInitPosition.erase(D);
} else if (isTemplateInstantiation(D->getTemplateSpecializationKind())) {
// C++ [basic.start.init]p2:
// Definitions of explicitly specialized class template static data
@@ -346,24 +349,24 @@ CodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D,
// 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, COMDATKey);
- 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, COMDATKey);
- DelayedCXXInitPosition.erase(D);
} else {
- llvm::DenseMap<const Decl *, unsigned>::iterator I =
- DelayedCXXInitPosition.find(D);
+ I = DelayedCXXInitPosition.find(D); // Re-do lookup in case of re-hash.
if (I == DelayedCXXInitPosition.end()) {
CXXGlobalInits.push_back(Fn);
- } else {
- assert(CXXGlobalInits[I->second] == nullptr);
+ } else if (I->second != ~0U) {
+ assert(I->second < CXXGlobalInits.size() &&
+ CXXGlobalInits[I->second] == nullptr);
CXXGlobalInits[I->second] = Fn;
- DelayedCXXInitPosition.erase(I);
}
}
+
+ // Remember that we already emitted the initializer for this global.
+ DelayedCXXInitPosition[D] = ~0U;
}
void CodeGenModule::EmitCXXThreadLocalInitFunc() {
diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index e5e52b5e7ba..feef6c2583e 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -400,7 +400,8 @@ private:
/// When a C++ decl with an initializer is deferred, null is
/// appended to CXXGlobalInits, and the index of that null is placed
/// here so that the initializer will be performed in the correct
- /// order.
+ /// order. Once the decl is emitted, the index is replaced with ~0U to ensure
+ /// that we don't re-emit the initializer.
llvm::DenseMap<const Decl*, unsigned> DelayedCXXInitPosition;
typedef std::pair<OrderGlobalInits, llvm::Function*> GlobalInitData;
OpenPOWER on IntegriCloud