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