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 +struct node +{ + T data; + node *next; + + node(const T data) : data(data), next(nullptr) {} + T getPayload() { return data; } + node* getNext() { return next; }; +}; + +template +class ConcurrentLIFOQueue +{ +public: + ConcurrentLIFOQueue() : head(nullptr) {} + + void insert(const T& data) + { + node* new_node = new node(data); + node* 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* getHead() { return head; } +private: + std::atomic *> 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 _deadStripRoots; llvm::DenseSet _liveAtoms; llvm::DenseSet _deadAtoms; + ConcurrentLIFOQueue _deadAtomsAccumulator; std::unique_ptr _result; std::unordered_multimap _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(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(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* tmp = _deadAtomsAccumulator.getHead(); + while (tmp != nullptr) { + _deadAtoms.insert(tmp->getPayload()); + tmp = tmp->getNext(); + } deadStripOptimize(); if (checkUndefines()) if (!_ctx.allowRemainingUndefines())