[llvm-commits] CVS: llvm/lib/Linker/LinkArchives.cpp

Reid Spencer reid at x10sys.com
Thu Nov 18 19:13:36 PST 2004



Changes in directory llvm/lib/Linker:

LinkArchives.cpp updated: 1.36 -> 1.37
---
Log message:

Reduce the amount of work in LinkInArchive by not searching the archive for
symbols it has already identified as not defining.


---
Diffs of the changes:  (+36 -10)

Index: llvm/lib/Linker/LinkArchives.cpp
diff -u llvm/lib/Linker/LinkArchives.cpp:1.36 llvm/lib/Linker/LinkArchives.cpp:1.37
--- llvm/lib/Linker/LinkArchives.cpp:1.36	Tue Nov 16 00:47:41 2004
+++ llvm/lib/Linker/LinkArchives.cpp	Thu Nov 18 21:13:25 2004
@@ -16,6 +16,7 @@
 #include "llvm/Module.h"
 #include "llvm/ModuleProvider.h"
 #include "llvm/PassManager.h"
+#include "llvm/ADT/SetOperations.h"
 #include "llvm/Bytecode/Reader.h"
 #include "llvm/Bytecode/Archive.h"
 #include "llvm/Bytecode/WriteBytecodePass.h"
@@ -25,6 +26,7 @@
 #include "llvm/Config/config.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/FileUtilities.h"
+#include "llvm/Support/Timer.h"
 #include "llvm/System/Signals.h"
 #include "llvm/Support/SystemUtils.h"
 #include <algorithm>
@@ -106,7 +108,7 @@
 llvm::GetAllUndefinedSymbols(Module *M,
                              std::set<std::string> &UndefinedSymbols) {
   std::set<std::string> DefinedSymbols;
-  UndefinedSymbols.clear();   // Start out empty
+  UndefinedSymbols.clear();
   
   for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
     if (I->hasName()) {
@@ -172,6 +174,7 @@
   // no reason to link in any archive files.
   std::set<std::string> UndefinedSymbols;
   GetAllUndefinedSymbols(M, UndefinedSymbols);
+  
   if (UndefinedSymbols.empty()) {
     if (Verbose) std::cerr << "  No symbols undefined, don't link library!\n";
     return false;  // No need to link anything in!
@@ -184,35 +187,58 @@
 
   Archive* arch = AutoArch.get();
 
+  // Save a set of symbols that are not defined by the archive. Since we're
+  // entering a loop, there's no point searching for these multiple times. This
+  // variable is used to "set_subtract" from the set of undefined symbols.
+  std::set<std::string> NotDefinedByArchive;
+
   // While we are linking in object files, loop.
   while (true) {     
+
+    // Find the modules we need to link into the target module
     std::set<ModuleProvider*> Modules;
-    // Find the modules we need to link
     arch->findModulesDefiningSymbols(UndefinedSymbols, Modules);
 
-    // If we didn't find any more modules to link this time, we are done.
+    // If we didn't find any more modules to link this time, we are done 
+    // searching this archive.
     if (Modules.empty())
       break;
 
+    // Any symbols remaining in UndefinedSymbols after
+    // findModulesDefiningSymbols are ones that the archive does not define. So
+    // we add them to the NotDefinedByArchive variable now.
+    NotDefinedByArchive.insert(UndefinedSymbols.begin(),
+        UndefinedSymbols.end());;
+
     // Loop over all the ModuleProviders that we got back from the archive
     for (std::set<ModuleProvider*>::iterator I=Modules.begin(), E=Modules.end();
          I != E; ++I) {
+
       // Get the module we must link in.
       std::auto_ptr<Module> AutoModule( (*I)->releaseModule() );
-
       Module* aModule = AutoModule.get();
 
       // Link it in
       if (LinkModules(M, aModule, ErrorMessage))
-        return true;   // Couldn't link in the right object file...        
+        return true;   // Couldn't link in the module
     }
 
-    // We have linked in a set of modules determined by the archive to satisfy
-    // our missing symbols. Linking in the new modules will have satisfied some
-    // symbols but may introduce additional missing symbols. We need to update
-    // the list of undefined symbols and try again until the archive doesn't
-    // have any modules that satisfy our symbols. 
+    // Get the undefined symbols from the aggregate module. This recomputes the
+    // symbols we still need after the new modules have been linked in.
     GetAllUndefinedSymbols(M, UndefinedSymbols);
+
+    // At this point we have two sets of undefined symbols: UndefinedSymbols
+    // which holds the undefined symbols from all the modules, and 
+    // NotDefinedByArchive which holds symbols we know the archive doesn't
+    // define. There's no point searching for symbols that we won't find in the
+    // archive so we subtract these sets.
+    set_subtract<std::set<std::string>,std::set<std::string> >(
+        UndefinedSymbols,NotDefinedByArchive);
+    
+    // If there's no symbols left, no point in continuing to search the
+    // archive.
+    if (UndefinedSymbols.empty())
+      break;
   }
   
   return false;






More information about the llvm-commits mailing list