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