2
0

LazyEmittingLayer.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. //===- LazyEmittingLayer.h - Lazily emit IR to lower JIT layers -*- C++ -*-===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // Contains the definition for a lazy-emitting layer for the JIT.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #ifndef LLVM_EXECUTIONENGINE_ORC_LAZYEMITTINGLAYER_H
  14. #define LLVM_EXECUTIONENGINE_ORC_LAZYEMITTINGLAYER_H
  15. #include "JITSymbol.h"
  16. #include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
  17. #include "llvm/IR/GlobalValue.h"
  18. #include "llvm/IR/Mangler.h"
  19. #include "llvm/IR/Module.h"
  20. #include "llvm/ADT/STLExtras.h"
  21. #include "llvm/ADT/StringMap.h"
  22. #include <list>
  23. namespace llvm {
  24. namespace orc {
  25. /// @brief Lazy-emitting IR layer.
  26. ///
  27. /// This layer accepts sets of LLVM IR Modules (via addModuleSet), but does
  28. /// not immediately emit them the layer below. Instead, emissing to the base
  29. /// layer is deferred until the first time the client requests the address
  30. /// (via JITSymbol::getAddress) for a symbol contained in this layer.
  31. template <typename BaseLayerT> class LazyEmittingLayer {
  32. public:
  33. typedef typename BaseLayerT::ModuleSetHandleT BaseLayerHandleT;
  34. private:
  35. class EmissionDeferredSet {
  36. public:
  37. EmissionDeferredSet() : EmitState(NotEmitted) {}
  38. virtual ~EmissionDeferredSet() {}
  39. JITSymbol find(StringRef Name, bool ExportedSymbolsOnly, BaseLayerT &B) {
  40. switch (EmitState) {
  41. case NotEmitted:
  42. if (auto GV = searchGVs(Name, ExportedSymbolsOnly)) {
  43. // Create a std::string version of Name to capture here - the argument
  44. // (a StringRef) may go away before the lambda is executed.
  45. // FIXME: Use capture-init when we move to C++14.
  46. std::string PName = Name;
  47. JITSymbolFlags Flags = JITSymbolBase::flagsFromGlobalValue(*GV);
  48. auto GetAddress =
  49. [this, ExportedSymbolsOnly, PName, &B]() -> TargetAddress {
  50. if (this->EmitState == Emitting)
  51. return 0;
  52. else if (this->EmitState == NotEmitted) {
  53. this->EmitState = Emitting;
  54. Handle = this->emitToBaseLayer(B);
  55. this->EmitState = Emitted;
  56. }
  57. auto Sym = B.findSymbolIn(Handle, PName, ExportedSymbolsOnly);
  58. return Sym.getAddress();
  59. };
  60. return JITSymbol(std::move(GetAddress), Flags);
  61. } else
  62. return nullptr;
  63. case Emitting:
  64. // Calling "emit" can trigger external symbol lookup (e.g. to check for
  65. // pre-existing definitions of common-symbol), but it will never find in
  66. // this module that it would not have found already, so return null from
  67. // here.
  68. return nullptr;
  69. case Emitted:
  70. return B.findSymbolIn(Handle, Name, ExportedSymbolsOnly);
  71. }
  72. llvm_unreachable("Invalid emit-state.");
  73. }
  74. void removeModulesFromBaseLayer(BaseLayerT &BaseLayer) {
  75. if (EmitState != NotEmitted)
  76. BaseLayer.removeModuleSet(Handle);
  77. }
  78. void emitAndFinalize(BaseLayerT &BaseLayer) {
  79. assert(EmitState != Emitting &&
  80. "Cannot emitAndFinalize while already emitting");
  81. if (EmitState == NotEmitted) {
  82. EmitState = Emitting;
  83. Handle = emitToBaseLayer(BaseLayer);
  84. EmitState = Emitted;
  85. }
  86. BaseLayer.emitAndFinalize(Handle);
  87. }
  88. template <typename ModuleSetT, typename MemoryManagerPtrT,
  89. typename SymbolResolverPtrT>
  90. static std::unique_ptr<EmissionDeferredSet>
  91. create(BaseLayerT &B, ModuleSetT Ms, MemoryManagerPtrT MemMgr,
  92. SymbolResolverPtrT Resolver);
  93. protected:
  94. virtual const GlobalValue* searchGVs(StringRef Name,
  95. bool ExportedSymbolsOnly) const = 0;
  96. virtual BaseLayerHandleT emitToBaseLayer(BaseLayerT &BaseLayer) = 0;
  97. private:
  98. enum { NotEmitted, Emitting, Emitted } EmitState;
  99. BaseLayerHandleT Handle;
  100. };
  101. template <typename ModuleSetT, typename MemoryManagerPtrT,
  102. typename SymbolResolverPtrT>
  103. class EmissionDeferredSetImpl : public EmissionDeferredSet {
  104. public:
  105. EmissionDeferredSetImpl(ModuleSetT Ms,
  106. MemoryManagerPtrT MemMgr,
  107. SymbolResolverPtrT Resolver)
  108. : Ms(std::move(Ms)), MemMgr(std::move(MemMgr)),
  109. Resolver(std::move(Resolver)) {}
  110. protected:
  111. const GlobalValue* searchGVs(StringRef Name,
  112. bool ExportedSymbolsOnly) const override {
  113. // FIXME: We could clean all this up if we had a way to reliably demangle
  114. // names: We could just demangle name and search, rather than
  115. // mangling everything else.
  116. // If we have already built the mangled name set then just search it.
  117. if (MangledSymbols) {
  118. auto VI = MangledSymbols->find(Name);
  119. if (VI == MangledSymbols->end())
  120. return nullptr;
  121. auto GV = VI->second;
  122. if (!ExportedSymbolsOnly || GV->hasDefaultVisibility())
  123. return GV;
  124. return nullptr;
  125. }
  126. // If we haven't built the mangled name set yet, try to build it. As an
  127. // optimization this will leave MangledNames set to nullptr if we find
  128. // Name in the process of building the set.
  129. return buildMangledSymbols(Name, ExportedSymbolsOnly);
  130. }
  131. BaseLayerHandleT emitToBaseLayer(BaseLayerT &BaseLayer) override {
  132. // We don't need the mangled names set any more: Once we've emitted this
  133. // to the base layer we'll just look for symbols there.
  134. MangledSymbols.reset();
  135. return BaseLayer.addModuleSet(std::move(Ms), std::move(MemMgr),
  136. std::move(Resolver));
  137. }
  138. private:
  139. // If the mangled name of the given GlobalValue matches the given search
  140. // name (and its visibility conforms to the ExportedSymbolsOnly flag) then
  141. // return the symbol. Otherwise, add the mangled name to the Names map and
  142. // return nullptr.
  143. const GlobalValue* addGlobalValue(StringMap<const GlobalValue*> &Names,
  144. const GlobalValue &GV,
  145. const Mangler &Mang, StringRef SearchName,
  146. bool ExportedSymbolsOnly) const {
  147. // Modules don't "provide" decls or common symbols.
  148. if (GV.isDeclaration() || GV.hasCommonLinkage())
  149. return nullptr;
  150. // Mangle the GV name.
  151. std::string MangledName;
  152. {
  153. raw_string_ostream MangledNameStream(MangledName);
  154. Mang.getNameWithPrefix(MangledNameStream, &GV, false);
  155. }
  156. // Check whether this is the name we were searching for, and if it is then
  157. // bail out early.
  158. if (MangledName == SearchName)
  159. if (!ExportedSymbolsOnly || GV.hasDefaultVisibility())
  160. return &GV;
  161. // Otherwise add this to the map for later.
  162. Names[MangledName] = &GV;
  163. return nullptr;
  164. }
  165. // Build the MangledSymbols map. Bails out early (with MangledSymbols left set
  166. // to nullptr) if the given SearchName is found while building the map.
  167. const GlobalValue* buildMangledSymbols(StringRef SearchName,
  168. bool ExportedSymbolsOnly) const {
  169. assert(!MangledSymbols && "Mangled symbols map already exists?");
  170. auto Symbols = llvm::make_unique<StringMap<const GlobalValue*>>();
  171. for (const auto &M : Ms) {
  172. Mangler Mang;
  173. for (const auto &V : M->globals())
  174. if (auto GV = addGlobalValue(*Symbols, V, Mang, SearchName,
  175. ExportedSymbolsOnly))
  176. return GV;
  177. for (const auto &F : *M)
  178. if (auto GV = addGlobalValue(*Symbols, F, Mang, SearchName,
  179. ExportedSymbolsOnly))
  180. return GV;
  181. }
  182. MangledSymbols = std::move(Symbols);
  183. return nullptr;
  184. }
  185. ModuleSetT Ms;
  186. MemoryManagerPtrT MemMgr;
  187. SymbolResolverPtrT Resolver;
  188. mutable std::unique_ptr<StringMap<const GlobalValue*>> MangledSymbols;
  189. };
  190. typedef std::list<std::unique_ptr<EmissionDeferredSet>> ModuleSetListT;
  191. BaseLayerT &BaseLayer;
  192. ModuleSetListT ModuleSetList;
  193. public:
  194. /// @brief Handle to a set of loaded modules.
  195. typedef typename ModuleSetListT::iterator ModuleSetHandleT;
  196. /// @brief Construct a lazy emitting layer.
  197. LazyEmittingLayer(BaseLayerT &BaseLayer) : BaseLayer(BaseLayer) {}
  198. /// @brief Add the given set of modules to the lazy emitting layer.
  199. template <typename ModuleSetT, typename MemoryManagerPtrT,
  200. typename SymbolResolverPtrT>
  201. ModuleSetHandleT addModuleSet(ModuleSetT Ms,
  202. MemoryManagerPtrT MemMgr,
  203. SymbolResolverPtrT Resolver) {
  204. return ModuleSetList.insert(
  205. ModuleSetList.end(),
  206. EmissionDeferredSet::create(BaseLayer, std::move(Ms), std::move(MemMgr),
  207. std::move(Resolver)));
  208. }
  209. /// @brief Remove the module set represented by the given handle.
  210. ///
  211. /// This method will free the memory associated with the given module set,
  212. /// both in this layer, and the base layer.
  213. void removeModuleSet(ModuleSetHandleT H) {
  214. (*H)->removeModulesFromBaseLayer(BaseLayer);
  215. ModuleSetList.erase(H);
  216. }
  217. /// @brief Search for the given named symbol.
  218. /// @param Name The name of the symbol to search for.
  219. /// @param ExportedSymbolsOnly If true, search only for exported symbols.
  220. /// @return A handle for the given named symbol, if it exists.
  221. JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
  222. // Look for the symbol among existing definitions.
  223. if (auto Symbol = BaseLayer.findSymbol(Name, ExportedSymbolsOnly))
  224. return Symbol;
  225. // If not found then search the deferred sets. If any of these contain a
  226. // definition of 'Name' then they will return a JITSymbol that will emit
  227. // the corresponding module when the symbol address is requested.
  228. for (auto &DeferredSet : ModuleSetList)
  229. if (auto Symbol = DeferredSet->find(Name, ExportedSymbolsOnly, BaseLayer))
  230. return Symbol;
  231. // If no definition found anywhere return a null symbol.
  232. return nullptr;
  233. }
  234. /// @brief Get the address of the given symbol in the context of the set of
  235. /// compiled modules represented by the handle H.
  236. JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name,
  237. bool ExportedSymbolsOnly) {
  238. return (*H)->find(Name, ExportedSymbolsOnly, BaseLayer);
  239. }
  240. /// @brief Immediately emit and finalize the moduleOB set represented by the
  241. /// given handle.
  242. /// @param H Handle for module set to emit/finalize.
  243. void emitAndFinalize(ModuleSetHandleT H) {
  244. (*H)->emitAndFinalize(BaseLayer);
  245. }
  246. };
  247. template <typename BaseLayerT>
  248. template <typename ModuleSetT, typename MemoryManagerPtrT,
  249. typename SymbolResolverPtrT>
  250. std::unique_ptr<typename LazyEmittingLayer<BaseLayerT>::EmissionDeferredSet>
  251. LazyEmittingLayer<BaseLayerT>::EmissionDeferredSet::create(
  252. BaseLayerT &B, ModuleSetT Ms, MemoryManagerPtrT MemMgr,
  253. SymbolResolverPtrT Resolver) {
  254. typedef EmissionDeferredSetImpl<ModuleSetT, MemoryManagerPtrT, SymbolResolverPtrT>
  255. EDS;
  256. return llvm::make_unique<EDS>(std::move(Ms), std::move(MemMgr),
  257. std::move(Resolver));
  258. }
  259. } // End namespace orc.
  260. } // End namespace llvm.
  261. #endif // LLVM_EXECUTIONENGINE_ORC_LAZYEMITTINGLAYER_H