r196785 - When we decide to output a deferred decl, remember the llvm GlobalValue.
Rafael Espindola
rafael.espindola at gmail.com
Mon Dec 9 06:59:08 PST 2013
Author: rafael
Date: Mon Dec 9 08:59:08 2013
New Revision: 196785
URL: http://llvm.org/viewvc/llvm-project?rev=196785&view=rev
Log:
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.
Modified:
cfe/trunk/lib/CodeGen/CodeGenModule.cpp
cfe/trunk/lib/CodeGen/CodeGenModule.h
cfe/trunk/lib/CodeGen/ModuleBuilder.cpp
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=196785&r1=196784&r2=196785&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Mon Dec 9 08:59:08 2013
@@ -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(GlobalDec
// 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(S
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(S
// 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(S
// 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(S
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(Str
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(Str
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
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=196785&r1=196784&r2=196785&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Mon Dec 9 08:59:08 2013
@@ -273,7 +273,15 @@ class CodeGenModule : public CodeGenType
/// DeferredDeclsToEmit - This is a list of deferred decls which we have seen
/// that *are* actually referenced. These get code generated when the module
/// is done.
- std::vector<GlobalDecl> DeferredDeclsToEmit;
+ struct DeferredGlobal {
+ DeferredGlobal(llvm::GlobalValue *GV, GlobalDecl GD) : GV(GV), GD(GD) {}
+ llvm::AssertingVH<llvm::GlobalValue> GV;
+ GlobalDecl GD;
+ };
+ std::vector<DeferredGlobal> DeferredDeclsToEmit;
+ void addDeferredDeclToEmit(llvm::GlobalValue *GV, GlobalDecl GD) {
+ DeferredDeclsToEmit.push_back(DeferredGlobal(GV, GD));
+ }
/// List of alias we have emitted. Used to make sure that what they point to
/// is defined once we get to the end of the of the translation unit.
@@ -433,6 +441,8 @@ public:
~CodeGenModule();
+ void clear();
+
/// Release - Finalize LLVM code generation.
void Release();
Modified: cfe/trunk/lib/CodeGen/ModuleBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ModuleBuilder.cpp?rev=196785&r1=196784&r2=196785&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/ModuleBuilder.cpp (original)
+++ cfe/trunk/lib/CodeGen/ModuleBuilder.cpp Mon Dec 9 08:59:08 2013
@@ -117,6 +117,8 @@ namespace {
virtual void HandleTranslationUnit(ASTContext &Ctx) {
if (Diags.hasErrorOccurred()) {
+ if (Builder)
+ Builder->clear();
M.reset();
return;
}
More information about the cfe-commits
mailing list