diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2013-12-09 14:59:08 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2013-12-09 14:59:08 +0000 |
commit | 9c8da1b492c33dce3367c7edd3d3bcf1560535e9 (patch) | |
tree | aa01cc0402c33ba88402f9ca30b0849930def09f /lib/CodeGen/CodeGenModule.cpp | |
parent | d6c0a824b6fdaffd12cf64ee136973278ae20c08 (diff) | |
download | clang-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.cpp | 47 |
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 |