summaryrefslogtreecommitdiff
path: root/lib/CodeGen/CodeGenModule.cpp
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2013-12-09 14:59:08 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2013-12-09 14:59:08 +0000
commit9c8da1b492c33dce3367c7edd3d3bcf1560535e9 (patch)
treeaa01cc0402c33ba88402f9ca30b0849930def09f /lib/CodeGen/CodeGenModule.cpp
parentd6c0a824b6fdaffd12cf64ee136973278ae20c08 (diff)
downloadclang-9c8da1b492c33dce3367c7edd3d3bcf1560535e9.tar.gz
clang-9c8da1b492c33dce3367c7edd3d3bcf1560535e9.tar.bz2
clang-9c8da1b492c33dce3367c7edd3d3bcf1560535e9.tar.xz
When we decide to output a deferred decl, remember the llvm GlobalValue.
We can reuse it to avoid a DenseMap+StringMap lookup to find if it was already emitted or not. This fixes a 2010 TODO. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@196785 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CodeGenModule.cpp')
-rw-r--r--lib/CodeGen/CodeGenModule.cpp47
1 files changed, 24 insertions, 23 deletions
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index 4f7886b34d..583ee88bd6 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -233,6 +233,10 @@ void CodeGenModule::checkAliases() {
}
}
+void CodeGenModule::clear() {
+ DeferredDeclsToEmit.clear();
+}
+
void CodeGenModule::Release() {
EmitDeferred();
applyReplacements();
@@ -1002,22 +1006,19 @@ void CodeGenModule::EmitDeferred() {
// Stop if we're out of both deferred v-tables and deferred declarations.
if (DeferredDeclsToEmit.empty()) break;
- GlobalDecl D = DeferredDeclsToEmit.back();
+ DeferredGlobal &G = DeferredDeclsToEmit.back();
+ GlobalDecl D = G.GD;
+ llvm::GlobalValue *GV = G.GV;
DeferredDeclsToEmit.pop_back();
+ assert(GV == GetGlobalValue(getMangledName(D)));
// Check to see if we've already emitted this. This is necessary
// for a couple of reasons: first, decls can end up in the
// deferred-decls queue multiple times, and second, decls can end
// up with definitions in unusual ways (e.g. by an extern inline
// function acquiring a strong function redefinition). Just
// ignore these cases.
- //
- // TODO: That said, looking this up multiple times is very wasteful.
- StringRef Name = getMangledName(D);
- llvm::GlobalValue *CGRef = GetGlobalValue(Name);
- assert(CGRef && "Deferred decl wasn't referenced?");
-
- if (!CGRef->isDeclaration())
+ if(!GV->isDeclaration())
continue;
// Otherwise, emit the definition and move on to the next one.
@@ -1226,8 +1227,8 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) {
// If the value has already been used, add it directly to the
// DeferredDeclsToEmit list.
StringRef MangledName = getMangledName(GD);
- if (GetGlobalValue(MangledName))
- DeferredDeclsToEmit.push_back(GD);
+ if (llvm::GlobalValue *GV = GetGlobalValue(MangledName))
+ addDeferredDeclToEmit(GV, GD);
else {
// Otherwise, remember that we saw a deferred decl with this name. The
// first use of the mangled name will cause it to move into
@@ -1428,7 +1429,7 @@ CodeGenModule::GetOrCreateLLVMFunction(StringRef MangledName,
if (D && isa<CXXDestructorDecl>(D) &&
getCXXABI().useThunkForDtorVariant(cast<CXXDestructorDecl>(D),
GD.getDtorType()))
- DeferredDeclsToEmit.push_back(GD);
+ addDeferredDeclToEmit(F, GD);
// This is the first use or definition of a mangled name. If there is a
// deferred decl with this name, remember that we need to emit it at the end
@@ -1438,7 +1439,7 @@ CodeGenModule::GetOrCreateLLVMFunction(StringRef MangledName,
// Move the potentially referenced deferred decl to the
// DeferredDeclsToEmit list, and remove it from DeferredDecls (since we
// don't need it anymore).
- DeferredDeclsToEmit.push_back(DDI->second);
+ addDeferredDeclToEmit(F, DDI->second);
DeferredDecls.erase(DDI);
// Otherwise, if this is a sized deallocation function, emit a weak
@@ -1446,7 +1447,7 @@ CodeGenModule::GetOrCreateLLVMFunction(StringRef MangledName,
// for it at the end of the translation unit.
} else if (D && cast<FunctionDecl>(D)
->getCorrespondingUnsizedGlobalDeallocationFunction()) {
- DeferredDeclsToEmit.push_back(GD);
+ addDeferredDeclToEmit(F, GD);
// Otherwise, there are cases we have to worry about where we're
// using a declaration for which we must emit a definition but where
@@ -1469,10 +1470,10 @@ CodeGenModule::GetOrCreateLLVMFunction(StringRef MangledName,
if (FD->isImplicit() && !ForVTable) {
assert(FD->isUsed() &&
"Sema didn't mark implicit function as used!");
- DeferredDeclsToEmit.push_back(GD.getWithDecl(FD));
+ addDeferredDeclToEmit(F, GD.getWithDecl(FD));
break;
} else if (FD->doesThisDeclarationHaveABody()) {
- DeferredDeclsToEmit.push_back(GD.getWithDecl(FD));
+ addDeferredDeclToEmit(F, GD.getWithDecl(FD));
break;
}
}
@@ -1574,6 +1575,13 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName,
return llvm::ConstantExpr::getBitCast(Entry, Ty);
}
+ unsigned AddrSpace = GetGlobalVarAddressSpace(D, Ty->getAddressSpace());
+ llvm::GlobalVariable *GV =
+ new llvm::GlobalVariable(getModule(), Ty->getElementType(), false,
+ llvm::GlobalValue::ExternalLinkage,
+ 0, MangledName, 0,
+ llvm::GlobalVariable::NotThreadLocal, AddrSpace);
+
// This is the first use or definition of a mangled name. If there is a
// deferred decl with this name, remember that we need to emit it at the end
// of the file.
@@ -1581,17 +1589,10 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName,
if (DDI != DeferredDecls.end()) {
// Move the potentially referenced deferred decl to the DeferredDeclsToEmit
// list, and remove it from DeferredDecls (since we don't need it anymore).
- DeferredDeclsToEmit.push_back(DDI->second);
+ addDeferredDeclToEmit(GV, DDI->second);
DeferredDecls.erase(DDI);
}
- unsigned AddrSpace = GetGlobalVarAddressSpace(D, Ty->getAddressSpace());
- llvm::GlobalVariable *GV =
- new llvm::GlobalVariable(getModule(), Ty->getElementType(), false,
- llvm::GlobalValue::ExternalLinkage,
- 0, MangledName, 0,
- llvm::GlobalVariable::NotThreadLocal, AddrSpace);
-
// Handle things which are present even on external declarations.
if (D) {
// FIXME: This code is overly simple and should be merged with other global