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