From dacde24744db9f9f32a5ab13afbaa5e688ed5d86 Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Mon, 15 Oct 2018 22:27:02 +0000 Subject: [PATCH] [ORC] Switch to DenseMap/DenseSet for ORC symbol map/set types. llvm-svn: 344565 --- include/llvm/ExecutionEngine/Orc/Core.h | 19 +++---- .../ExecutionEngine/Orc/SymbolStringPool.h | 27 ++++++++++ lib/ExecutionEngine/Orc/Core.cpp | 53 +++++++++++-------- lib/ExecutionEngine/Orc/ExecutionUtils.cpp | 14 ++--- 4 files changed, 73 insertions(+), 40 deletions(-) diff --git a/include/llvm/ExecutionEngine/Orc/Core.h b/include/llvm/ExecutionEngine/Orc/Core.h index 67b16894f6c..86c5ebb6d27 100644 --- a/include/llvm/ExecutionEngine/Orc/Core.h +++ b/include/llvm/ExecutionEngine/Orc/Core.h @@ -20,10 +20,7 @@ #include "llvm/IR/Module.h" #include "llvm/Support/Debug.h" -#include -#include #include -#include #include #define DEBUG_TYPE "orc" @@ -44,18 +41,18 @@ using VModuleKey = uint64_t; /// A set of symbol names (represented by SymbolStringPtrs for // efficiency). -using SymbolNameSet = std::set; +using SymbolNameSet = DenseSet; /// A map from symbol names (as SymbolStringPtrs) to JITSymbols /// (address/flags pairs). -using SymbolMap = std::map; +using SymbolMap = DenseMap; /// A map from symbol names (as SymbolStringPtrs) to JITSymbolFlags. -using SymbolFlagsMap = std::map; +using SymbolFlagsMap = DenseMap; /// A base class for materialization failures that allows the failing /// symbols to be obtained for logging. -using SymbolDependenceMap = std::map; +using SymbolDependenceMap = DenseMap; /// A list of JITDylib pointers. using JITDylibList = std::vector; @@ -339,7 +336,7 @@ struct SymbolAliasMapEntry { }; /// A map of Symbols to (Symbol, Flags) pairs. -using SymbolAliasMap = std::map; +using SymbolAliasMap = DenseMap; /// A materialization unit for symbol aliases. Allows existing symbols to be /// aliased with alternate flags. @@ -489,7 +486,7 @@ public: JITDylib &Parent, const SymbolNameSet &Names)>; using AsynchronousSymbolQuerySet = - std::set>; + std::set>; JITDylib(const JITDylib &) = delete; JITDylib &operator=(const JITDylib &) = delete; @@ -609,7 +606,7 @@ private: }; using UnmaterializedInfosMap = - std::map>; + DenseMap>; struct MaterializingInfo { AsynchronousSymbolQueryList PendingQueries; @@ -618,7 +615,7 @@ private: bool IsEmitted = false; }; - using MaterializingInfosMap = std::map; + using MaterializingInfosMap = DenseMap; using LookupImplActionFlags = enum { None = 0, diff --git a/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h b/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h index 4c45cfd199d..717076e2560 100644 --- a/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h +++ b/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h @@ -14,6 +14,7 @@ #ifndef LLVM_EXECUTIONENGINE_ORC_SYMBOLSTRINGPOOL_H #define LLVM_EXECUTIONENGINE_ORC_SYMBOLSTRINGPOOL_H +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringMap.h" #include #include @@ -49,10 +50,13 @@ private: /// Pointer to a pooled string representing a symbol name. class SymbolStringPtr { friend class SymbolStringPool; + friend struct DenseMapInfo; friend bool operator==(const SymbolStringPtr &LHS, const SymbolStringPtr &RHS); friend bool operator<(const SymbolStringPtr &LHS, const SymbolStringPtr &RHS); + static SymbolStringPool::PoolMapEntry Tombstone; + public: SymbolStringPtr() = default; SymbolStringPtr(const SymbolStringPtr &Other) @@ -142,6 +146,29 @@ inline bool SymbolStringPool::empty() const { } } // end namespace orc + +template <> +struct DenseMapInfo { + + static orc::SymbolStringPtr getEmptyKey() { + return orc::SymbolStringPtr(); + } + + static orc::SymbolStringPtr getTombstoneKey() { + return orc::SymbolStringPtr(&orc::SymbolStringPtr::Tombstone); + } + + static unsigned getHashValue(orc::SymbolStringPtr V) { + uintptr_t IV = reinterpret_cast(V.S); + return unsigned(IV) ^ unsigned(IV >> 9); + } + + static bool isEqual(const orc::SymbolStringPtr &LHS, + const orc::SymbolStringPtr &RHS) { + return LHS.S == RHS.S; + } +}; + } // end namespace llvm #endif // LLVM_EXECUTIONENGINE_ORC_SYMBOLSTRINGPOOL_H diff --git a/lib/ExecutionEngine/Orc/Core.cpp b/lib/ExecutionEngine/Orc/Core.cpp index 3fa28a5af6f..d477ca523d8 100644 --- a/lib/ExecutionEngine/Orc/Core.cpp +++ b/lib/ExecutionEngine/Orc/Core.cpp @@ -134,6 +134,8 @@ struct PrintSymbolMapElemsMatchingCLOpts { namespace llvm { namespace orc { + SymbolStringPool::PoolMapEntry SymbolStringPtr::Tombstone(0); + char FailedToMaterialize::ID = 0; char SymbolsNotFound::ID = 0; char SymbolsCouldNotBeRemoved::ID = 0; @@ -575,20 +577,22 @@ void ReExportsMaterializationUnit::materialize( SymbolNameSet QuerySymbols; SymbolAliasMap QueryAliases; - for (auto I = RequestedAliases.begin(), E = RequestedAliases.end(); - I != E;) { - auto Tmp = I++; - + // Collect as many aliases as we can without including a chain. + for (auto &KV : RequestedAliases) { // Chain detected. Skip this symbol for this round. - if (&SrcJD == &TgtJD && (QueryAliases.count(Tmp->second.Aliasee) || - RequestedAliases.count(Tmp->second.Aliasee))) + if (&SrcJD == &TgtJD && (QueryAliases.count(KV.second.Aliasee) || + RequestedAliases.count(KV.second.Aliasee))) continue; - ResponsibilitySymbols.insert(Tmp->first); - QuerySymbols.insert(Tmp->second.Aliasee); - QueryAliases[Tmp->first] = std::move(Tmp->second); - RequestedAliases.erase(Tmp); + ResponsibilitySymbols.insert(KV.first); + QuerySymbols.insert(KV.second.Aliasee); + QueryAliases[KV.first] = std::move(KV.second); } + + // Remove the aliases collected this round from the RequestedAliases map. + for (auto &KV : QueryAliases) + RequestedAliases.erase(KV.first); + assert(!QuerySymbols.empty() && "Alias cycle detected!"); auto QueryInfo = std::make_shared( @@ -1172,10 +1176,9 @@ void JITDylib::lodgeQueryImpl( std::shared_ptr &Q, SymbolNameSet &Unresolved, JITDylib *MatchNonExportedInJD, bool MatchNonExported, std::vector> &MUs) { - for (auto I = Unresolved.begin(), E = Unresolved.end(); I != E;) { - auto TmpI = I++; - auto Name = *TmpI; + std::vector ToRemove; + for (auto Name : Unresolved) { // Search for the name in Symbols. Skip it if not found. auto SymI = Symbols.find(Name); if (SymI == Symbols.end()) @@ -1188,9 +1191,9 @@ void JITDylib::lodgeQueryImpl( if (!MatchNonExported && MatchNonExportedInJD != this) continue; - // If we matched against Name in JD, remove it frome the Unresolved set and - // add it to the added set. - Unresolved.erase(TmpI); + // If we matched against Name in JD, mark it to be removed from the Unresolved + // set. + ToRemove.push_back(Name); // If the symbol has an address then resolve it. if (SymI->second.getAddress() != 0) @@ -1235,6 +1238,10 @@ void JITDylib::lodgeQueryImpl( MI.PendingQueries.push_back(Q); Q->addQueryDependence(*this, Name); } + + // Remove any symbols that we found. + for (auto &Name : ToRemove) + Unresolved.erase(Name); } SymbolNameSet JITDylib::legacyLookup(std::shared_ptr Q, @@ -1294,19 +1301,17 @@ JITDylib::lookupImpl(std::shared_ptr &Q, std::vector> &MUs, SymbolNameSet &Unresolved) { LookupImplActionFlags ActionFlags = None; + std::vector ToRemove; - for (auto I = Unresolved.begin(), E = Unresolved.end(); I != E;) { - auto TmpI = I++; - auto Name = *TmpI; + for (auto Name : Unresolved) { // Search for the name in Symbols. Skip it if not found. auto SymI = Symbols.find(Name); if (SymI == Symbols.end()) continue; - // If we found Name, remove it frome the Unresolved set and add it - // to the dependencies set. - Unresolved.erase(TmpI); + // If we found Name, mark it to be removed from the Unresolved set. + ToRemove.push_back(Name); // If the symbol has an address then resolve it. if (SymI->second.getAddress() != 0) { @@ -1357,6 +1362,10 @@ JITDylib::lookupImpl(std::shared_ptr &Q, Q->addQueryDependence(*this, Name); } + // Remove any marked symbols from the Unresolved set. + for (auto &Name : ToRemove) + Unresolved.erase(Name); + return ActionFlags; } diff --git a/lib/ExecutionEngine/Orc/ExecutionUtils.cpp b/lib/ExecutionEngine/Orc/ExecutionUtils.cpp index 667237373ca..4c8f725df54 100644 --- a/lib/ExecutionEngine/Orc/ExecutionUtils.cpp +++ b/lib/ExecutionEngine/Orc/ExecutionUtils.cpp @@ -167,13 +167,13 @@ int LocalCXXRuntimeOverridesBase::CXAAtExitOverride(DestructorPtr Destructor, Error LocalCXXRuntimeOverrides2::enable(JITDylib &JD, MangleAndInterner &Mangle) { - SymbolMap RuntimeInterposes( - {{Mangle("__dso_handle"), - JITEvaluatedSymbol(toTargetAddress(&DSOHandleOverride), - JITSymbolFlags::Exported)}, - {Mangle("__cxa_atexit"), - JITEvaluatedSymbol(toTargetAddress(&CXAAtExitOverride), - JITSymbolFlags::Exported)}}); + SymbolMap RuntimeInterposes; + RuntimeInterposes[Mangle("__dso_handle")] = + JITEvaluatedSymbol(toTargetAddress(&DSOHandleOverride), + JITSymbolFlags::Exported); + RuntimeInterposes[Mangle("__cxa_atexit")] = + JITEvaluatedSymbol(toTargetAddress(&CXAAtExitOverride), + JITSymbolFlags::Exported); return JD.define(absoluteSymbols(std::move(RuntimeInterposes))); }