[PATCH] [Core] Update references in parallel

Davide Italiano davide at freebsd.org
Thu Mar 19 16:13:56 PDT 2015


I updated the patch to use a concurrent accumulator. It's just a prototype, and a little bit hack'ish but it worked for me (and it showed up a substantial improvement). I'm working in parallel on a concurrent hash map to see if it helps with other bottlenecks in the resolver.

In the meanwhile, Rafael, do you mind to re-run your tests with this patch applied in order to see if it shows up some improvement for you (or if it doesn't) ?


http://reviews.llvm.org/D8372

Files:
  include/lld/Core/Parallel.h
  include/lld/Core/Resolver.h
  lib/Core/Resolver.cpp

Index: include/lld/Core/Parallel.h
===================================================================
--- include/lld/Core/Parallel.h
+++ include/lld/Core/Parallel.h
@@ -304,6 +304,38 @@
   std::for_each(begin, end, func);
 }
 #endif
+
+template<typename T>
+struct node
+{
+    T data;
+    node *next;
+
+    node(const T data) : data(data), next(nullptr) {}
+    T getPayload() { return data; }
+    node<T>* getNext() { return next; };
+};
+
+template<typename T>
+class ConcurrentLIFOQueue
+{
+public:
+  ConcurrentLIFOQueue() : head(nullptr) {}
+
+  void insert(const T& data)
+  {
+    node<T>* new_node = new node<T>(data);
+    node<T>* old_head = head.load(std::memory_order_relaxed);
+    do {
+      new_node->next = old_head;
+    } while (!head.compare_exchange_weak(old_head, new_node,
+                                          std::memory_order_release,
+                                          std::memory_order_relaxed));
+  }
+  node<T>* getHead() { return head; }
+private:
+    std::atomic<node<T> *> head;
+};
 } // end namespace lld
 
 #endif
Index: include/lld/Core/Resolver.h
===================================================================
--- include/lld/Core/Resolver.h
+++ include/lld/Core/Resolver.h
@@ -91,6 +91,7 @@
   std::set<const Atom *>        _deadStripRoots;
   llvm::DenseSet<const Atom *>  _liveAtoms;
   llvm::DenseSet<const Atom *>  _deadAtoms;
+  ConcurrentLIFOQueue<const Atom *> _deadAtomsAccumulator;
   std::unique_ptr<MergedFile>   _result;
   std::unordered_multimap<const Atom *, const Atom *> _reverseRef;
 
Index: lib/Core/Resolver.cpp
===================================================================
--- lib/Core/Resolver.cpp
+++ lib/Core/Resolver.cpp
@@ -341,7 +341,8 @@
 // to the new defined atom
 void Resolver::updateReferences() {
   ScopedTask task(getDefaultDomain(), "updateReferences");
-  for (const Atom *atom : _atoms) {
+  parallel_for_each(_atoms.begin(), _atoms.end(),
+      [&](const Atom *atom) {
     if (const DefinedAtom *defAtom = dyn_cast<DefinedAtom>(atom)) {
       for (const Reference *ref : *defAtom) {
         // A reference of type kindAssociate should't be updated.
@@ -351,14 +352,14 @@
         if (ref->kindNamespace() == lld::Reference::KindNamespace::all &&
             ref->kindValue() == lld::Reference::kindAssociate) {
           if (_symbolTable.isCoalescedAway(atom))
-            _deadAtoms.insert(ref->target());
+            _deadAtomsAccumulator.insert(ref->target());
           continue;
         }
         const Atom *newTarget = _symbolTable.replacement(ref->target());
         const_cast<Reference *>(ref)->setTarget(newTarget);
       }
     }
-  }
+  });
 }
 
 // For dead code stripping, recursively mark atoms "live"
@@ -491,6 +492,12 @@
   if (!resolveUndefines())
     return false;
   updateReferences();
+  // XXX: rewrite me please to use an iterator.
+  node<const Atom *>* tmp = _deadAtomsAccumulator.getHead();
+  while (tmp != nullptr) {
+    _deadAtoms.insert(tmp->getPayload());
+    tmp = tmp->getNext();
+  }
   deadStripOptimize();
   if (checkUndefines())
     if (!_ctx.allowRemainingUndefines())

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D8372.22318.patch
Type: text/x-patch
Size: 3137 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150319/c00084e1/attachment.bin>


More information about the llvm-commits mailing list