[lld] r289409 - COFF: Load inputs immediately instead of adding them to a queue.

Peter Collingbourne via llvm-commits llvm-commits at lists.llvm.org
Sun Dec 11 14:15:26 PST 2016


Author: pcc
Date: Sun Dec 11 16:15:25 2016
New Revision: 289409

URL: http://llvm.org/viewvc/llvm-project?rev=289409&view=rev
Log:
COFF: Load inputs immediately instead of adding them to a queue.

This patch replaces the symbol table's object and archive queues, as well as
the convergent loop in the linker driver, with a design more similar to the
ELF linker where symbol resolution directly causes input files to be added to
the link, including input files arising from linker directives. Effectively
this removes the last vestiges of the old parallel input file loader.

Differential Revision: https://reviews.llvm.org/D27660

Modified:
    lld/trunk/COFF/Driver.cpp
    lld/trunk/COFF/SymbolTable.cpp
    lld/trunk/COFF/SymbolTable.h
    lld/trunk/test/COFF/order.test

Modified: lld/trunk/COFF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.cpp?rev=289409&r1=289408&r2=289409&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.cpp (original)
+++ lld/trunk/COFF/Driver.cpp Sun Dec 11 16:15:25 2016
@@ -575,27 +575,12 @@ void LinkerDriver::link(ArrayRef<const c
     MBs.erase(It, MBs.end());
   }
 
-  // Read all input files given via the command line. Note that step()
-  // doesn't read files that are specified by directive sections.
+  // Read all input files given via the command line.
   for (MemoryBufferRef MB : MBs)
     Symtab.addFile(createFile(MB));
-  Symtab.step();
 
-  // Determine machine type and check if all object files are
-  // for the same CPU type. Note that this needs to be done before
-  // any call to mangle().
-  for (InputFile *File : Symtab.getFiles()) {
-    MachineTypes MT = File->getMachineType();
-    if (MT == IMAGE_FILE_MACHINE_UNKNOWN)
-      continue;
-    if (Config->Machine == IMAGE_FILE_MACHINE_UNKNOWN) {
-      Config->Machine = MT;
-      continue;
-    }
-    if (Config->Machine != MT)
-      fatal(toString(File) + ": machine type " + machineToStr(MT) +
-            " conflicts with " + machineToStr(Config->Machine));
-  }
+  // We should have inferred a machine type by now from the input files, but if
+  // not we assume x64.
   if (Config->Machine == IMAGE_FILE_MACHINE_UNKNOWN) {
     errs() << "warning: /machine is not specified. x64 is assumed.\n";
     Config->Machine = AMD64;
@@ -686,50 +671,37 @@ void LinkerDriver::link(ArrayRef<const c
   Symtab.addAbsolute(mangle("__guard_fids_count"), 0);
   Symtab.addAbsolute(mangle("__guard_flags"), 0x100);
 
-  // Read as much files as we can from directives sections.
-  Symtab.run();
-
-  // Resolve auxiliary symbols until we get a convergence.
-  // (Trying to resolve a symbol may trigger a Lazy symbol to load a new file.
-  // A new file may contain a directive section to add new command line options.
-  // That's why we have to repeat until converge.)
-  for (;;) {
-    // Windows specific -- if entry point is not found,
-    // search for its mangled names.
-    if (Config->Entry)
-      Symtab.mangleMaybe(Config->Entry);
-
-    // Windows specific -- Make sure we resolve all dllexported symbols.
-    for (Export &E : Config->Exports) {
-      if (!E.ForwardTo.empty())
-        continue;
-      E.Sym = addUndefined(E.Name);
-      if (!E.Directives)
-        Symtab.mangleMaybe(E.Sym);
-    }
-
-    // Add weak aliases. Weak aliases is a mechanism to give remaining
-    // undefined symbols final chance to be resolved successfully.
-    for (auto Pair : Config->AlternateNames) {
-      StringRef From = Pair.first;
-      StringRef To = Pair.second;
-      Symbol *Sym = Symtab.find(From);
-      if (!Sym)
-        continue;
-      if (auto *U = dyn_cast<Undefined>(Sym->body()))
-        if (!U->WeakAlias)
-          U->WeakAlias = Symtab.addUndefined(To);
-    }
+  // Windows specific -- if entry point is not found,
+  // search for its mangled names.
+  if (Config->Entry)
+    Symtab.mangleMaybe(Config->Entry);
+
+  // Windows specific -- Make sure we resolve all dllexported symbols.
+  for (Export &E : Config->Exports) {
+    if (!E.ForwardTo.empty())
+      continue;
+    E.Sym = addUndefined(E.Name);
+    if (!E.Directives)
+      Symtab.mangleMaybe(E.Sym);
+  }
 
-    // Windows specific -- if __load_config_used can be resolved, resolve it.
-    if (Symtab.findUnderscore("_load_config_used"))
-      addUndefined(mangle("_load_config_used"));
-
-    if (Symtab.queueEmpty())
-      break;
-    Symtab.run();
+  // Add weak aliases. Weak aliases is a mechanism to give remaining
+  // undefined symbols final chance to be resolved successfully.
+  for (auto Pair : Config->AlternateNames) {
+    StringRef From = Pair.first;
+    StringRef To = Pair.second;
+    Symbol *Sym = Symtab.find(From);
+    if (!Sym)
+      continue;
+    if (auto *U = dyn_cast<Undefined>(Sym->body()))
+      if (!U->WeakAlias)
+        U->WeakAlias = Symtab.addUndefined(To);
   }
 
+  // Windows specific -- if __load_config_used can be resolved, resolve it.
+  if (Symtab.findUnderscore("_load_config_used"))
+    addUndefined(mangle("_load_config_used"));
+
   // Do LTO by compiling bitcode input files to a set of native COFF files then
   // link those files.
   Symtab.addCombinedLTOObjects();

Modified: lld/trunk/COFF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/SymbolTable.cpp?rev=289409&r1=289408&r2=289409&view=diff
==============================================================================
--- lld/trunk/COFF/SymbolTable.cpp (original)
+++ lld/trunk/COFF/SymbolTable.cpp Sun Dec 11 16:15:25 2016
@@ -27,76 +27,33 @@ namespace coff {
 SymbolTable *Symtab;
 
 void SymbolTable::addFile(InputFile *File) {
-  Files.push_back(File);
-  if (auto *F = dyn_cast<ArchiveFile>(File)) {
-    ArchiveQueue.push_back(F);
-    return;
+  if (Config->Verbose)
+    outs() << "Reading " << toString(File) << "\n";
+  File->parse();
+
+  MachineTypes MT = File->getMachineType();
+  if (Config->Machine == IMAGE_FILE_MACHINE_UNKNOWN) {
+    Config->Machine = MT;
+  } else if (MT != IMAGE_FILE_MACHINE_UNKNOWN && Config->Machine != MT) {
+    fatal(toString(File) + ": machine type " + machineToStr(MT) +
+          " conflicts with " + machineToStr(Config->Machine));
   }
-  ObjectQueue.push_back(File);
+
   if (auto *F = dyn_cast<ObjectFile>(File)) {
     ObjectFiles.push_back(F);
   } else if (auto *F = dyn_cast<BitcodeFile>(File)) {
     BitcodeFiles.push_back(F);
-  } else {
-    ImportFiles.push_back(cast<ImportFile>(File));
+  } else if (auto *F = dyn_cast<ImportFile>(File)) {
+    ImportFiles.push_back(F);
   }
-}
-
-void SymbolTable::step() {
-  if (queueEmpty())
-    return;
-  readObjects();
-  readArchive();
-}
-
-void SymbolTable::run() {
-  while (!queueEmpty())
-    step();
-}
 
-void SymbolTable::readArchive() {
-  if (ArchiveQueue.empty())
+  StringRef S = File->getDirectives();
+  if (S.empty())
     return;
 
-  // Add lazy symbols to the symbol table. Lazy symbols that conflict
-  // with existing undefined symbols are accumulated in LazySyms.
-  ArchiveFile *File = ArchiveQueue.front();
-  ArchiveQueue.pop_front();
   if (Config->Verbose)
-    outs() << "Reading " << toString(File) << "\n";
-  File->parse();
-}
-
-void SymbolTable::readObjects() {
-  if (ObjectQueue.empty())
-    return;
-
-  // Add defined and undefined symbols to the symbol table.
-  std::vector<StringRef> Directives;
-  for (size_t I = 0; I < ObjectQueue.size(); ++I) {
-    InputFile *File = ObjectQueue[I];
-    if (Config->Verbose)
-      outs() << "Reading " << toString(File) << "\n";
-    File->parse();
-    // Adding symbols may add more files to ObjectQueue
-    // (but not to ArchiveQueue).
-    StringRef S = File->getDirectives();
-    if (!S.empty()) {
-      Directives.push_back(S);
-      if (Config->Verbose)
-        outs() << "Directives: " << toString(File) << ": " << S << "\n";
-    }
-  }
-  ObjectQueue.clear();
-
-  // Parse directive sections. This may add files to
-  // ArchiveQueue and ObjectQueue.
-  for (StringRef S : Directives)
-    Driver->parseDirectives(S);
-}
-
-bool SymbolTable::queueEmpty() {
-  return ArchiveQueue.empty() && ObjectQueue.empty();
+    outs() << "Directives: " << toString(File) << ": " << S << "\n";
+  Driver->parseDirectives(S);
 }
 
 void SymbolTable::reportRemainingUndefines() {
@@ -419,7 +376,6 @@ void SymbolTable::addCombinedLTOObjects(
   size_t NumBitcodeFiles = BitcodeFiles.size();
   for (ObjectFile *Obj : Objs)
     Obj->parse();
-  run();
   if (BitcodeFiles.size() != NumBitcodeFiles)
     fatal("LTO: late loaded symbol created new bitcode reference");
 }
@@ -465,7 +421,6 @@ std::vector<ObjectFile *> SymbolTable::c
   std::vector<ObjectFile *> ObjFiles;
   for (SmallString<0> &Obj : Objs) {
     auto *ObjFile = new ObjectFile(MemoryBufferRef(Obj, "<LTO object>"));
-    Files.emplace_back(ObjFile);
     ObjectFiles.push_back(ObjFile);
     ObjFiles.push_back(ObjFile);
   }

Modified: lld/trunk/COFF/SymbolTable.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/SymbolTable.h?rev=289409&r1=289408&r2=289409&view=diff
==============================================================================
--- lld/trunk/COFF/SymbolTable.h (original)
+++ lld/trunk/COFF/SymbolTable.h Sun Dec 11 16:15:25 2016
@@ -21,9 +21,6 @@
 #include <eh.h>
 #endif
 
-#include <future>
-#include <list>
-
 namespace llvm {
 struct LTOCodeGenerator;
 }
@@ -56,10 +53,6 @@ struct Symbol;
 class SymbolTable {
 public:
   void addFile(InputFile *File);
-  std::vector<InputFile *> &getFiles() { return Files; }
-  void step();
-  void run();
-  bool queueEmpty();
 
   // Try to resolve any undefined symbols and update the symbol table
   // accordingly, then print an error message for any remaining undefined
@@ -129,10 +122,6 @@ private:
 
   llvm::DenseMap<StringRef, Symbol *> Symtab;
 
-  std::vector<InputFile *> Files;
-  std::list<ArchiveFile *> ArchiveQueue;
-  std::vector<InputFile *> ObjectQueue;
-
   std::vector<BitcodeFile *> BitcodeFiles;
   std::vector<SmallString<0>> Objs;
 };

Modified: lld/trunk/test/COFF/order.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/order.test?rev=289409&r1=289408&r2=289409&view=diff
==============================================================================
--- lld/trunk/test/COFF/order.test (original)
+++ lld/trunk/test/COFF/order.test Sun Dec 11 16:15:25 2016
@@ -9,7 +9,7 @@
 # RUN: FileCheck %s < %t.log
 
 CHECK: order.test.tmp1.obj
-CHECK: order.test.tmp3.obj
 CHECK: order.test.tmp2.lib
 CHECK: order.test.tmp2.lib(order.test.tmp2.obj) for foo
+CHECK: order.test.tmp3.obj
 CHECK: order.test.tmp3.lib




More information about the llvm-commits mailing list