From 4c5e43da7792f75567b693105cc53e3f1992ad98 Mon Sep 17 00:00:00 2001 From: Pirama Arumuga Nainar Date: Wed, 8 Apr 2015 08:55:49 -0700 Subject: Update aosp/master llvm for rebase to r233350 Change-Id: I07d935f8793ee8ec6b7da003f6483046594bca49 --- .../ExecutionEngine/Orc/CompileOnDemandLayer.h | 17 ++- .../llvm/ExecutionEngine/Orc/IndirectionUtils.h | 109 +++++++++---------- include/llvm/ExecutionEngine/Orc/JITSymbol.h | 19 ++-- .../llvm/ExecutionEngine/Orc/LazyEmittingLayer.h | 116 +++++++++++---------- .../llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h | 50 ++++----- .../llvm/ExecutionEngine/Orc/OrcTargetSupport.h | 7 +- 6 files changed, 164 insertions(+), 154 deletions(-) (limited to 'include/llvm/ExecutionEngine/Orc') diff --git a/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h b/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h index 0e218e2..77b0c48 100644 --- a/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h +++ b/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h @@ -142,9 +142,8 @@ public: typedef std::function LookupFtor; /// @brief Construct a compile-on-demand layer instance. - CompileOnDemandLayer(BaseLayerT &BaseLayer, LLVMContext &Context) - : BaseLayer(BaseLayer), - CompileCallbackMgr(BaseLayer, Context, 0, 64) {} + CompileOnDemandLayer(BaseLayerT &BaseLayer, CompileCallbackMgrT &CallbackMgr) + : BaseLayer(BaseLayer), CompileCallbackMgr(CallbackMgr) {} /// @brief Add a module to the compile-on-demand layer. template @@ -194,8 +193,8 @@ public: /// below this one. JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name, bool ExportedSymbolsOnly) { - BaseLayerModuleSetHandleListT &BaseLayerHandles = H->second; - for (auto &BH : BaseLayerHandles) { + + for (auto &BH : H->BaseLayerModuleSetHandles) { if (auto Symbol = BaseLayer.findSymbolIn(BH, Name, ExportedSymbolsOnly)) return Symbol; } @@ -274,7 +273,7 @@ private: // Set the compile actions for this module: for (auto &KVPair : NewStubInfos) { std::string BodyName = Mangle(KVPair->first + BodySuffix, - *M.getDataLayout()); + M.getDataLayout()); auto &CCInfo = KVPair->second; CCInfo.setCompileAction( [=](){ @@ -291,10 +290,10 @@ private: for (auto &KVPair : StubInfos) { std::string AddrName = Mangle(KVPair.first + AddrSuffix, - *M.getDataLayout()); + M.getDataLayout()); auto &CCInfo = KVPair.second; CCInfo.setUpdateAction( - CompileCallbackMgr.getLocalFPUpdater(StubsH, AddrName)); + getLocalFPUpdater(BaseLayer, StubsH, AddrName)); } } @@ -345,7 +344,7 @@ private: } BaseLayerT &BaseLayer; - CompileCallbackMgrT CompileCallbackMgr; + CompileCallbackMgrT &CompileCallbackMgr; ModuleSetInfoListT ModuleSetInfos; }; diff --git a/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h b/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h index e9d3d34..8ce1d4d 100644 --- a/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h +++ b/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h @@ -26,10 +26,34 @@ namespace orc { /// @brief Base class for JITLayer independent aspects of /// JITCompileCallbackManager. -template class JITCompileCallbackManagerBase { public: + typedef std::function CompileFtor; + typedef std::function UpdateFtor; + + /// @brief Handle to a newly created compile callback. Can be used to get an + /// IR constant representing the address of the trampoline, and to set + /// the compile and update actions for the callback. + class CompileCallbackInfo { + public: + CompileCallbackInfo(Constant *Addr, CompileFtor &Compile, + UpdateFtor &Update) + : Addr(Addr), Compile(Compile), Update(Update) {} + + Constant* getAddress() const { return Addr; } + void setCompileAction(CompileFtor Compile) { + this->Compile = std::move(Compile); + } + void setUpdateAction(UpdateFtor Update) { + this->Update = std::move(Update); + } + private: + Constant *Addr; + CompileFtor &Compile; + UpdateFtor &Update; + }; + /// @brief Construct a JITCompileCallbackManagerBase. /// @param ErrorHandlerAddress The address of an error handler in the target /// process to be used if a compile callback fails. @@ -41,10 +65,12 @@ public: : ErrorHandlerAddress(ErrorHandlerAddress), NumTrampolinesPerBlock(NumTrampolinesPerBlock) {} + virtual ~JITCompileCallbackManagerBase() {} + /// @brief Execute the callback for the given trampoline id. Called by the JIT /// to compile functions on demand. TargetAddress executeCompileCallback(TargetAddress TrampolineID) { - typename TrampolineMapT::iterator I = ActiveTrampolines.find(TrampolineID); + TrampolineMapT::iterator I = ActiveTrampolines.find(TrampolineID); // FIXME: Also raise an error in the Orc error-handler when we finally have // one. if (I == ActiveTrampolines.end()) @@ -56,7 +82,7 @@ public: // Moving the trampoline ID back to the available list first means there's at // least one available trampoline if the compile action triggers a request for // a new one. - AvailableTrampolines.push_back(I->first - TargetT::CallSize); + AvailableTrampolines.push_back(I->first); auto CallbackHandler = std::move(I->second); ActiveTrampolines.erase(I); @@ -67,14 +93,14 @@ public: return ErrorHandlerAddress; } -protected: + /// @brief Get/create a compile callback with the given signature. + virtual CompileCallbackInfo getCompileCallback(FunctionType &FT) = 0; - typedef std::function CompileFtorT; - typedef std::function UpdateFtorT; +protected: struct CallbackHandler { - CompileFtorT Compile; - UpdateFtorT Update; + CompileFtor Compile; + UpdateFtor Update; }; TargetAddress ErrorHandlerAddress; @@ -87,15 +113,9 @@ protected: /// @brief Manage compile callbacks. template -class JITCompileCallbackManager : - public JITCompileCallbackManagerBase { +class JITCompileCallbackManager : public JITCompileCallbackManagerBase { public: - typedef typename JITCompileCallbackManagerBase::CompileFtorT - CompileFtorT; - typedef typename JITCompileCallbackManagerBase::UpdateFtorT - UpdateFtorT; - /// @brief Construct a JITCompileCallbackManager. /// @param JIT JIT layer to emit callback trampolines, etc. into. /// @param Context LLVMContext to use for trampoline & resolve block modules. @@ -108,39 +128,17 @@ public: JITCompileCallbackManager(JITLayerT &JIT, LLVMContext &Context, TargetAddress ErrorHandlerAddress, unsigned NumTrampolinesPerBlock) - : JITCompileCallbackManagerBase(ErrorHandlerAddress, - NumTrampolinesPerBlock), + : JITCompileCallbackManagerBase(ErrorHandlerAddress, + NumTrampolinesPerBlock), JIT(JIT) { emitResolverBlock(Context); } - /// @brief Handle to a newly created compile callback. Can be used to get an - /// IR constant representing the address of the trampoline, and to set - /// the compile and update actions for the callback. - class CompileCallbackInfo { - public: - CompileCallbackInfo(Constant *Addr, CompileFtorT &Compile, - UpdateFtorT &Update) - : Addr(Addr), Compile(Compile), Update(Update) {} - - Constant* getAddress() const { return Addr; } - void setCompileAction(CompileFtorT Compile) { - this->Compile = std::move(Compile); - } - void setUpdateAction(UpdateFtorT Update) { - this->Update = std::move(Update); - } - private: - Constant *Addr; - CompileFtorT &Compile; - UpdateFtorT &Update; - }; - /// @brief Get/create a compile callback with the given signature. - CompileCallbackInfo getCompileCallback(FunctionType &FT) { + CompileCallbackInfo getCompileCallback(FunctionType &FT) final { TargetAddress TrampolineAddr = getAvailableTrampolineAddr(FT.getContext()); auto &CallbackHandler = - this->ActiveTrampolines[TrampolineAddr + TargetT::CallSize]; + this->ActiveTrampolines[TrampolineAddr]; Constant *AddrIntVal = ConstantInt::get(Type::getInt64Ty(FT.getContext()), TrampolineAddr); Constant *AddrPtrVal = @@ -151,19 +149,6 @@ public: CallbackHandler.Update); } - /// @brief Get a functor for updating the value of a named function pointer. - UpdateFtorT getLocalFPUpdater(typename JITLayerT::ModuleSetHandleT H, - std::string Name) { - // FIXME: Move-capture Name once we can use C++14. - return [=](TargetAddress Addr) { - auto FPSym = JIT.findSymbolIn(H, Name, true); - assert(FPSym && "Cannot find function pointer to update."); - void *FPAddr = reinterpret_cast( - static_cast(FPSym.getAddress())); - memcpy(FPAddr, &Addr, sizeof(uintptr_t)); - }; - } - private: std::vector> @@ -216,6 +201,22 @@ private: TargetAddress ResolverBlockAddr; }; +/// @brief Get an update functor for updating the value of a named function +/// pointer. +template +JITCompileCallbackManagerBase::UpdateFtor +getLocalFPUpdater(JITLayerT &JIT, typename JITLayerT::ModuleSetHandleT H, + std::string Name) { + // FIXME: Move-capture Name once we can use C++14. + return [=,&JIT](TargetAddress Addr) { + auto FPSym = JIT.findSymbolIn(H, Name, true); + assert(FPSym && "Cannot find function pointer to update."); + void *FPAddr = reinterpret_cast( + static_cast(FPSym.getAddress())); + memcpy(FPAddr, &Addr, sizeof(uintptr_t)); + }; + } + GlobalVariable* createImplPointer(Function &F, const Twine &Name, Constant *Initializer); diff --git a/include/llvm/ExecutionEngine/Orc/JITSymbol.h b/include/llvm/ExecutionEngine/Orc/JITSymbol.h index a670222..7c3ad56 100644 --- a/include/llvm/ExecutionEngine/Orc/JITSymbol.h +++ b/include/llvm/ExecutionEngine/Orc/JITSymbol.h @@ -14,6 +14,7 @@ #ifndef LLVM_EXECUTIONENGINE_ORC_JITSYMBOL_H #define LLVM_EXECUTIONENGINE_ORC_JITSYMBOL_H +#include "llvm/ExecutionEngine/JITSymbolFlags.h" #include "llvm/Support/DataTypes.h" #include #include @@ -25,17 +26,19 @@ namespace orc { typedef uint64_t TargetAddress; /// @brief Represents a symbol in the JIT. -class JITSymbol { -public: +class JITSymbol : public JITSymbolBase { +public: + typedef std::function GetAddressFtor; /// @brief Create a 'null' symbol that represents failure to find a symbol /// definition. - JITSymbol(std::nullptr_t) : CachedAddr(0) {} + JITSymbol(std::nullptr_t) + : JITSymbolBase(JITSymbolFlags::None), CachedAddr(0) {} /// @brief Create a symbol for a definition with a known address. - JITSymbol(TargetAddress Addr) - : CachedAddr(Addr) {} + JITSymbol(TargetAddress Addr, JITSymbolFlags Flags) + : JITSymbolBase(Flags), CachedAddr(Addr) {} /// @brief Create a symbol for a definition that doesn't have a known address /// yet. @@ -46,8 +49,8 @@ public: /// definition without actually materializing the definition up front. The /// user can materialize the definition at any time by calling the getAddress /// method. - JITSymbol(GetAddressFtor GetAddress) - : CachedAddr(0), GetAddress(std::move(GetAddress)) {} + JITSymbol(GetAddressFtor GetAddress, JITSymbolFlags Flags) + : JITSymbolBase(Flags), GetAddress(std::move(GetAddress)), CachedAddr(0) {} /// @brief Returns true if the symbol exists, false otherwise. explicit operator bool() const { return CachedAddr || GetAddress; } @@ -64,8 +67,8 @@ public: } private: - TargetAddress CachedAddr; GetAddressFtor GetAddress; + TargetAddress CachedAddr; }; } // End namespace orc. diff --git a/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h b/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h index 2a94abe..ac5fccf 100644 --- a/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h +++ b/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h @@ -45,23 +45,25 @@ private: JITSymbol find(StringRef Name, bool ExportedSymbolsOnly, BaseLayerT &B) { switch (EmitState) { case NotEmitted: - if (provides(Name, ExportedSymbolsOnly)) { + if (auto GV = searchGVs(Name, ExportedSymbolsOnly)) { // Create a std::string version of Name to capture here - the argument // (a StringRef) may go away before the lambda is executed. - // FIXME: Use capture-init when we move to C++14. + // FIXME: Use capture-init when we move to C++14. std::string PName = Name; - return JITSymbol( - [this, ExportedSymbolsOnly, PName, &B]() -> TargetAddress { - if (this->EmitState == Emitting) - return 0; - else if (this->EmitState == NotEmitted) { - this->EmitState = Emitting; - Handle = this->emitToBaseLayer(B); - this->EmitState = Emitted; - } - return B.findSymbolIn(Handle, PName, ExportedSymbolsOnly) - .getAddress(); - }); + JITSymbolFlags Flags = JITSymbolBase::flagsFromGlobalValue(*GV); + auto GetAddress = + [this, ExportedSymbolsOnly, PName, &B]() -> TargetAddress { + if (this->EmitState == Emitting) + return 0; + else if (this->EmitState == NotEmitted) { + this->EmitState = Emitting; + Handle = this->emitToBaseLayer(B); + this->EmitState = Emitted; + } + auto Sym = B.findSymbolIn(Handle, PName, ExportedSymbolsOnly); + return Sym.getAddress(); + }; + return JITSymbol(std::move(GetAddress), Flags); } else return nullptr; case Emitting: @@ -98,7 +100,8 @@ private: std::unique_ptr MM); protected: - virtual bool provides(StringRef Name, bool ExportedSymbolsOnly) const = 0; + virtual const GlobalValue* searchGVs(StringRef Name, + bool ExportedSymbolsOnly) const = 0; virtual BaseLayerHandleT emitToBaseLayer(BaseLayerT &BaseLayer) = 0; private: @@ -115,46 +118,48 @@ private: protected: - BaseLayerHandleT emitToBaseLayer(BaseLayerT &BaseLayer) override { - // We don't need the mangled names set any more: Once we've emitted this - // to the base layer we'll just look for symbols there. - MangledNames.reset(); - return BaseLayer.addModuleSet(std::move(Ms), std::move(MM)); - } - - bool provides(StringRef Name, bool ExportedSymbolsOnly) const override { + const GlobalValue* searchGVs(StringRef Name, + bool ExportedSymbolsOnly) const override { // FIXME: We could clean all this up if we had a way to reliably demangle // names: We could just demangle name and search, rather than // mangling everything else. // If we have already built the mangled name set then just search it. - if (MangledNames) { - auto VI = MangledNames->find(Name); - if (VI == MangledNames->end()) - return false; - return !ExportedSymbolsOnly || VI->second; + if (MangledSymbols) { + auto VI = MangledSymbols->find(Name); + if (VI == MangledSymbols->end()) + return nullptr; + auto GV = VI->second; + if (!ExportedSymbolsOnly || GV->hasDefaultVisibility()) + return GV; + return nullptr; } // If we haven't built the mangled name set yet, try to build it. As an // optimization this will leave MangledNames set to nullptr if we find // Name in the process of building the set. - buildMangledNames(Name, ExportedSymbolsOnly); - if (!MangledNames) - return true; - return false; + return buildMangledSymbols(Name, ExportedSymbolsOnly); + } + + BaseLayerHandleT emitToBaseLayer(BaseLayerT &BaseLayer) override { + // We don't need the mangled names set any more: Once we've emitted this + // to the base layer we'll just look for symbols there. + MangledSymbols.reset(); + return BaseLayer.addModuleSet(std::move(Ms), std::move(MM)); } private: // If the mangled name of the given GlobalValue matches the given search // name (and its visibility conforms to the ExportedSymbolsOnly flag) then - // just return 'true'. Otherwise, add the mangled name to the Names map and - // return 'false'. - bool addGlobalValue(StringMap &Names, const GlobalValue &GV, - const Mangler &Mang, StringRef SearchName, - bool ExportedSymbolsOnly) const { + // return the symbol. Otherwise, add the mangled name to the Names map and + // return nullptr. + const GlobalValue* addGlobalValue(StringMap &Names, + const GlobalValue &GV, + const Mangler &Mang, StringRef SearchName, + bool ExportedSymbolsOnly) const { // Modules don't "provide" decls or common symbols. if (GV.isDeclaration() || GV.hasCommonLinkage()) - return false; + return nullptr; // Mangle the GV name. std::string MangledName; @@ -167,39 +172,42 @@ private: // bail out early. if (MangledName == SearchName) if (!ExportedSymbolsOnly || GV.hasDefaultVisibility()) - return true; + return &GV; // Otherwise add this to the map for later. - Names[MangledName] = GV.hasDefaultVisibility(); - return false; + Names[MangledName] = &GV; + return nullptr; } - // Build the MangledNames map. Bails out early (with MangledNames left set + // Build the MangledSymbols map. Bails out early (with MangledSymbols left set // to nullptr) if the given SearchName is found while building the map. - void buildMangledNames(StringRef SearchName, - bool ExportedSymbolsOnly) const { - assert(!MangledNames && "Mangled names map already exists?"); + const GlobalValue* buildMangledSymbols(StringRef SearchName, + bool ExportedSymbolsOnly) const { + assert(!MangledSymbols && "Mangled symbols map already exists?"); - auto Names = llvm::make_unique>(); + auto Symbols = llvm::make_unique>(); for (const auto &M : Ms) { - Mangler Mang(M->getDataLayout()); + Mangler Mang(&M->getDataLayout()); - for (const auto &GV : M->globals()) - if (addGlobalValue(*Names, GV, Mang, SearchName, ExportedSymbolsOnly)) - return; + for (const auto &V : M->globals()) + if (auto GV = addGlobalValue(*Symbols, V, Mang, SearchName, + ExportedSymbolsOnly)) + return GV; for (const auto &F : *M) - if (addGlobalValue(*Names, F, Mang, SearchName, ExportedSymbolsOnly)) - return; + if (auto GV = addGlobalValue(*Symbols, F, Mang, SearchName, + ExportedSymbolsOnly)) + return GV; } - MangledNames = std::move(Names); + MangledSymbols = std::move(Symbols); + return nullptr; } ModuleSetT Ms; std::unique_ptr MM; - mutable std::unique_ptr> MangledNames; + mutable std::unique_ptr> MangledSymbols; }; typedef std::list> ModuleSetListT; diff --git a/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h b/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h index 36af0fe..9838991 100644 --- a/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h +++ b/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h @@ -51,10 +51,8 @@ protected: return RTDyld->loadObject(Obj); } - TargetAddress getSymbolAddress(StringRef Name, bool ExportedSymbolsOnly) { - if (ExportedSymbolsOnly) - return RTDyld->getExportedSymbolLoadAddress(Name); - return RTDyld->getSymbolLoadAddress(Name); + RuntimeDyld::SymbolInfo getSymbol(StringRef Name) const { + return RTDyld->getSymbol(Name); } bool NeedsFinalization() const { return (State == Raw); } @@ -214,28 +212,32 @@ public: /// given object set. JITSymbol findSymbolIn(ObjSetHandleT H, StringRef Name, bool ExportedSymbolsOnly) { - if (auto Addr = H->getSymbolAddress(Name, ExportedSymbolsOnly)) { - if (!H->NeedsFinalization()) { - // If this instance has already been finalized then we can just return - // the address. - return JITSymbol(Addr); - } else { - // If this instance needs finalization return a functor that will do it. - // The functor still needs to double-check whether finalization is - // required, in case someone else finalizes this set before the functor - // is called. - return JITSymbol( - [this, Addr, H]() { - if (H->NeedsFinalization()) { - H->Finalize(); - if (NotifyFinalized) - NotifyFinalized(H); - } - return Addr; - }); + if (auto Sym = H->getSymbol(Name)) { + if (Sym.isExported() || !ExportedSymbolsOnly) { + auto Addr = Sym.getAddress(); + auto Flags = Sym.getFlags(); + if (!H->NeedsFinalization()) { + // If this instance has already been finalized then we can just return + // the address. + return JITSymbol(Addr, Flags); + } else { + // If this instance needs finalization return a functor that will do + // it. The functor still needs to double-check whether finalization is + // required, in case someone else finalizes this set before the + // functor is called. + auto GetAddress = + [this, Addr, H]() { + if (H->NeedsFinalization()) { + H->Finalize(); + if (NotifyFinalized) + NotifyFinalized(H); + } + return Addr; + }; + return JITSymbol(std::move(GetAddress), Flags); + } } } - return nullptr; } diff --git a/include/llvm/ExecutionEngine/Orc/OrcTargetSupport.h b/include/llvm/ExecutionEngine/Orc/OrcTargetSupport.h index c6f866a..309f5a9 100644 --- a/include/llvm/ExecutionEngine/Orc/OrcTargetSupport.h +++ b/include/llvm/ExecutionEngine/Orc/OrcTargetSupport.h @@ -25,15 +25,12 @@ public: /// @brief Insert module-level inline callback asm into module M for the /// symbols managed by JITResolveCallbackHandler J. - static void insertResolverBlock( - Module &M, - JITCompileCallbackManagerBase &JCBM); + static void insertResolverBlock(Module &M, + JITCompileCallbackManagerBase &JCBM); /// @brief Get a label name from the given index. typedef std::function LabelNameFtor; - static const unsigned CallSize = 6; - /// @brief Insert the requested number of trampolines into the given module. /// @param M Module to insert the call block into. /// @param NumCalls Number of calls to create in the call block. -- cgit v1.1