[lld] r241416 - COFF: Use atomic pointers in preparation for parallelizing.

Rui Ueyama ruiu at google.com
Sun Jul 5 14:54:42 PDT 2015


Author: ruiu
Date: Sun Jul  5 16:54:42 2015
New Revision: 241416

URL: http://llvm.org/viewvc/llvm-project?rev=241416&view=rev
Log:
COFF: Use atomic pointers in preparation for parallelizing.

In the new design, mutation of Symbol pointers is the name resolution
operation. This patch makes them atomic pointers so that they can
be mutated by multiple threads safely. I'm going to use atomic
compare-exchange on these pointers.

dyn_cast<> doesn't recognize atomic pointers as pointers,
so we need to call load(). This is unfortunate, but in other places
automatic type conversion works fine.

Modified:
    lld/trunk/COFF/Driver.cpp
    lld/trunk/COFF/SymbolTable.cpp
    lld/trunk/COFF/Symbols.h
    lld/trunk/COFF/Writer.cpp

Modified: lld/trunk/COFF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.cpp?rev=241416&r1=241415&r2=241416&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.cpp (original)
+++ lld/trunk/COFF/Driver.cpp Sun Jul  5 16:54:42 2015
@@ -220,7 +220,7 @@ StringRef LinkerDriver::findDefaultEntry
   };
   for (auto E : Entries) {
     Symbol *Sym = Symtab.find(E[0]);
-    if (Sym && !isa<Undefined>(Sym->Body))
+    if (Sym && !isa<Undefined>(Sym->Body.load()))
       return E[1];
   }
   return "";
@@ -591,7 +591,7 @@ bool LinkerDriver::link(llvm::ArrayRef<c
       Symbol *Sym = Symtab.find(From);
       if (!Sym)
         continue;
-      if (auto *U = dyn_cast<Undefined>(Sym->Body))
+      if (auto *U = dyn_cast<Undefined>(Sym->Body.load()))
         if (!U->WeakAlias)
           U->WeakAlias = Symtab.addUndefined(To);
     }

Modified: lld/trunk/COFF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/SymbolTable.cpp?rev=241416&r1=241415&r2=241416&view=diff
==============================================================================
--- lld/trunk/COFF/SymbolTable.cpp (original)
+++ lld/trunk/COFF/SymbolTable.cpp Sun Jul  5 16:54:42 2015
@@ -77,7 +77,7 @@ std::error_code SymbolTable::readArchive
   // Add archive member files to ObjectQueue that should resolve
   // existing undefined symbols.
   for (Symbol *Sym : LazySyms)
-    if (auto EC = addMemberFile(cast<Lazy>(Sym->Body)))
+    if (auto EC = addMemberFile(cast<Lazy>(Sym->Body.load())))
       return EC;
   return std::error_code();
 }
@@ -126,7 +126,7 @@ bool SymbolTable::reportRemainingUndefin
   bool Ret = false;
   for (auto &I : Symtab) {
     Symbol *Sym = I.second;
-    auto *Undef = dyn_cast<Undefined>(Sym->Body);
+    auto *Undef = dyn_cast<Undefined>(Sym->Body.load());
     if (!Undef)
       continue;
     StringRef Name = Undef->getName();
@@ -140,10 +140,10 @@ bool SymbolTable::reportRemainingUndefin
     // This odd rule is for compatibility with MSVC linker.
     if (Name.startswith("__imp_")) {
       Symbol *Imp = find(Name.substr(strlen("__imp_")));
-      if (Imp && isa<Defined>(Imp->Body)) {
+      if (Imp && isa<Defined>(Imp->Body.load())) {
         if (!Resolve)
           continue;
-        auto *D = cast<Defined>(Imp->Body);
+        auto *D = cast<Defined>(Imp->Body.load());
         auto *S = new (Alloc) DefinedLocalImport(Name, D);
         LocalImportChunks.push_back(S->getChunk());
         Sym->Body = S;
@@ -320,11 +320,11 @@ std::error_code SymbolTable::addCombined
     StringRef Name = Body->getName();
     Symbol *Sym = insert(Body);
 
-    if (isa<DefinedBitcode>(Sym->Body)) {
+    if (isa<DefinedBitcode>(Sym->Body.load())) {
       Sym->Body = Body;
       continue;
     }
-    if (auto *L = dyn_cast<Lazy>(Sym->Body)) {
+    if (auto *L = dyn_cast<Lazy>(Sym->Body.load())) {
       // We may see new references to runtime library symbols such as __chkstk
       // here. These symbols must be wholly defined in non-bitcode files.
       if (auto EC = addMemberFile(L))

Modified: lld/trunk/COFF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Symbols.h?rev=241416&r1=241415&r2=241416&view=diff
==============================================================================
--- lld/trunk/COFF/Symbols.h (original)
+++ lld/trunk/COFF/Symbols.h Sun Jul  5 16:54:42 2015
@@ -16,6 +16,7 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/Object/Archive.h"
 #include "llvm/Object/COFF.h"
+#include <atomic>
 #include <memory>
 #include <vector>
 
@@ -38,7 +39,7 @@ class SymbolBody;
 // The resolver updates SymbolBody pointers as it resolves symbols.
 struct Symbol {
   explicit Symbol(SymbolBody *P) : Body(P) {}
-  SymbolBody *Body;
+  std::atomic<SymbolBody *> Body;
 };
 
 // The base class for real symbol classes.
@@ -80,7 +81,7 @@ public:
   // has chosen the object among other objects having the same name,
   // you can access P->Backref->Body to get the resolver's result.
   void setBackref(Symbol *P) { Backref = P; }
-  SymbolBody *repl() { return Backref ? Backref->Body : this; }
+  SymbolBody *repl() { return Backref ? Backref->Body.load() : this; }
 
   // Decides which symbol should "win" in the symbol table, this or
   // the Other. Returns 1 if this wins, -1 if the Other wins, or 0 if

Modified: lld/trunk/COFF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Writer.cpp?rev=241416&r1=241415&r2=241416&view=diff
==============================================================================
--- lld/trunk/COFF/Writer.cpp (original)
+++ lld/trunk/COFF/Writer.cpp Sun Jul  5 16:54:42 2015
@@ -243,7 +243,8 @@ void Writer::createImportTables() {
       Sec->addChunk(C);
   }
   if (!DelayIdata.empty()) {
-    Defined *Helper = cast<Defined>(Symtab->find("__delayLoadHelper2")->Body);
+    Symbol *Sym = Symtab->find("__delayLoadHelper2");
+    Defined *Helper = cast<Defined>(Sym->Body.load());
     DelayIdata.create(Helper);
     OutputSection *Sec = createSection(".didat");
     for (Chunk *C : DelayIdata.getChunks())
@@ -535,7 +536,7 @@ OutputSection *Writer::createSection(Str
 // Dest is .reloc section. Add contents to that section.
 void Writer::addBaserels(OutputSection *Dest) {
   std::vector<uint32_t> V;
-  Defined *ImageBase = cast<Defined>(Symtab->find("__ImageBase")->Body);
+  Defined *ImageBase = cast<Defined>(Symtab->find("__ImageBase")->Body.load());
   for (OutputSection *Sec : OutputSections) {
     if (Sec == Dest)
       continue;





More information about the llvm-commits mailing list