1 //===- LazyEmittingLayer.h - Lazily emit IR to lower JIT layers -*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // Contains the definition for a lazy-emitting layer for the JIT.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_EXECUTIONENGINE_ORC_LAZYEMITTINGLAYER_H
15 #define LLVM_EXECUTIONENGINE_ORC_LAZYEMITTINGLAYER_H
17 #include "JITSymbol.h"
18 #include "LookasideRTDyldMM.h"
19 #include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
20 #include "llvm/IR/GlobalValue.h"
21 #include "llvm/IR/Mangler.h"
22 #include "llvm/ADT/StringMap.h"
28 /// @brief Lazy-emitting IR layer.
30 /// This layer accepts sets of LLVM IR Modules (via addModuleSet), but does
31 /// not immediately emit them the layer below. Instead, emissing to the base
32 /// layer is deferred until the first time the client requests the address
33 /// (via JITSymbol::getAddress) for a symbol contained in this layer.
34 template <typename BaseLayerT> class LazyEmittingLayer {
36 typedef typename BaseLayerT::ModuleSetHandleT BaseLayerHandleT;
39 class EmissionDeferredSet {
41 EmissionDeferredSet() : EmitState(NotEmitted) {}
42 virtual ~EmissionDeferredSet() {}
44 JITSymbol find(StringRef Name, bool ExportedSymbolsOnly, BaseLayerT &B) {
47 if (provides(Name, ExportedSymbolsOnly)) {
48 // Create a std::string version of Name to capture here - the argument
49 // (a StringRef) may go away before the lambda is executed.
50 // FIXME: Use capture-init when we move to C++14.
51 std::string PName = Name;
53 [this, ExportedSymbolsOnly, PName, &B]() -> TargetAddress {
54 if (this->EmitState == Emitting)
56 else if (this->EmitState == NotEmitted) {
57 this->EmitState = Emitting;
58 Handle = this->emitToBaseLayer(B);
59 this->EmitState = Emitted;
61 return B.findSymbolIn(Handle, PName, ExportedSymbolsOnly)
67 // Calling "emit" can trigger external symbol lookup (e.g. to check for
68 // pre-existing definitions of common-symbol), but it will never find in
69 // this module that it would not have found already, so return null from
73 return B.findSymbolIn(Handle, Name, ExportedSymbolsOnly);
75 llvm_unreachable("Invalid emit-state.");
78 void removeModulesFromBaseLayer(BaseLayerT &BaseLayer) {
79 if (EmitState != NotEmitted)
80 BaseLayer.removeModuleSet(Handle);
83 void emitAndFinalize(BaseLayerT &BaseLayer) {
84 assert(EmitState != Emitting &&
85 "Cannot emitAndFinalize while already emitting");
86 if (EmitState == NotEmitted) {
88 Handle = emitToBaseLayer(BaseLayer);
91 BaseLayer.emitAndFinalize(Handle);
94 template <typename ModuleSetT>
95 static std::unique_ptr<EmissionDeferredSet>
96 create(BaseLayerT &B, ModuleSetT Ms,
97 std::unique_ptr<RTDyldMemoryManager> MM);
100 virtual bool provides(StringRef Name, bool ExportedSymbolsOnly) const = 0;
101 virtual BaseLayerHandleT emitToBaseLayer(BaseLayerT &BaseLayer) = 0;
104 enum { NotEmitted, Emitting, Emitted } EmitState;
105 BaseLayerHandleT Handle;
108 template <typename ModuleSetT>
109 class EmissionDeferredSetImpl : public EmissionDeferredSet {
111 EmissionDeferredSetImpl(ModuleSetT Ms,
112 std::unique_ptr<RTDyldMemoryManager> MM)
113 : Ms(std::move(Ms)), MM(std::move(MM)) {}
117 BaseLayerHandleT emitToBaseLayer(BaseLayerT &BaseLayer) override {
118 // We don't need the mangled names set any more: Once we've emitted this
119 // to the base layer we'll just look for symbols there.
120 MangledNames.reset();
121 return BaseLayer.addModuleSet(std::move(Ms), std::move(MM));
124 bool provides(StringRef Name, bool ExportedSymbolsOnly) const override {
125 // FIXME: We could clean all this up if we had a way to reliably demangle
126 // names: We could just demangle name and search, rather than
127 // mangling everything else.
129 // If we have already built the mangled name set then just search it.
131 auto VI = MangledNames->find(Name);
132 if (VI == MangledNames->end())
134 return !ExportedSymbolsOnly || VI->second;
137 // If we haven't built the mangled name set yet, try to build it. As an
138 // optimization this will leave MangledNames set to nullptr if we find
139 // Name in the process of building the set.
140 buildMangledNames(Name, ExportedSymbolsOnly);
147 // If the mangled name of the given GlobalValue matches the given search
148 // name (and its visibility conforms to the ExportedSymbolsOnly flag) then
149 // just return 'true'. Otherwise, add the mangled name to the Names map and
151 bool addGlobalValue(StringMap<bool> &Names, const GlobalValue &GV,
152 const Mangler &Mang, StringRef SearchName,
153 bool ExportedSymbolsOnly) const {
154 // Modules don't "provide" decls or common symbols.
155 if (GV.isDeclaration() || GV.hasCommonLinkage())
158 // Mangle the GV name.
159 std::string MangledName;
161 raw_string_ostream MangledNameStream(MangledName);
162 Mang.getNameWithPrefix(MangledNameStream, &GV, false);
165 // Check whether this is the name we were searching for, and if it is then
167 if (MangledName == SearchName)
168 if (!ExportedSymbolsOnly || GV.hasDefaultVisibility())
171 // Otherwise add this to the map for later.
172 Names[MangledName] = GV.hasDefaultVisibility();
176 // Build the MangledNames map. Bails out early (with MangledNames left set
177 // to nullptr) if the given SearchName is found while building the map.
178 void buildMangledNames(StringRef SearchName,
179 bool ExportedSymbolsOnly) const {
180 assert(!MangledNames && "Mangled names map already exists?");
182 auto Names = llvm::make_unique<StringMap<bool>>();
184 for (const auto &M : Ms) {
185 Mangler Mang(M->getDataLayout());
187 for (const auto &GV : M->globals())
188 if (addGlobalValue(*Names, GV, Mang, SearchName, ExportedSymbolsOnly))
191 for (const auto &F : *M)
192 if (addGlobalValue(*Names, F, Mang, SearchName, ExportedSymbolsOnly))
196 MangledNames = std::move(Names);
200 std::unique_ptr<RTDyldMemoryManager> MM;
201 mutable std::unique_ptr<StringMap<bool>> MangledNames;
204 typedef std::list<std::unique_ptr<EmissionDeferredSet>> ModuleSetListT;
206 BaseLayerT &BaseLayer;
207 ModuleSetListT ModuleSetList;
210 /// @brief Handle to a set of loaded modules.
211 typedef typename ModuleSetListT::iterator ModuleSetHandleT;
213 /// @brief Construct a lazy emitting layer.
214 LazyEmittingLayer(BaseLayerT &BaseLayer) : BaseLayer(BaseLayer) {}
216 /// @brief Add the given set of modules to the lazy emitting layer.
217 template <typename ModuleSetT>
218 ModuleSetHandleT addModuleSet(ModuleSetT Ms,
219 std::unique_ptr<RTDyldMemoryManager> MM) {
220 return ModuleSetList.insert(
222 EmissionDeferredSet::create(BaseLayer, std::move(Ms), std::move(MM)));
225 /// @brief Remove the module set represented by the given handle.
227 /// This method will free the memory associated with the given module set,
228 /// both in this layer, and the base layer.
229 void removeModuleSet(ModuleSetHandleT H) {
230 (*H)->removeModulesFromBaseLayer(BaseLayer);
231 ModuleSetList.erase(H);
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))
243 // If not found then search the deferred sets. 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 &DeferredSet : ModuleSetList)
247 if (auto Symbol = DeferredSet->find(Name, ExportedSymbolsOnly, BaseLayer))
250 // If no definition found anywhere return a null symbol.
254 /// @brief Get the address of the given symbol in the context of the set of
255 /// compiled modules represented by the handle H.
256 JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name,
257 bool ExportedSymbolsOnly) {
258 return (*H)->find(Name, ExportedSymbolsOnly, BaseLayer);
261 /// @brief Immediately emit and finalize the moduleOB set represented by the
263 /// @param H Handle for module set to emit/finalize.
264 void emitAndFinalize(ModuleSetHandleT H) {
265 (*H)->emitAndFinalize(BaseLayer);
270 template <typename BaseLayerT>
271 template <typename ModuleSetT>
272 std::unique_ptr<typename LazyEmittingLayer<BaseLayerT>::EmissionDeferredSet>
273 LazyEmittingLayer<BaseLayerT>::EmissionDeferredSet::create(
274 BaseLayerT &B, ModuleSetT Ms, std::unique_ptr<RTDyldMemoryManager> MM) {
275 return llvm::make_unique<EmissionDeferredSetImpl<ModuleSetT>>(std::move(Ms),
279 } // End namespace orc.
280 } // End namespace llvm.
282 #endif // LLVM_EXECUTIONENGINE_ORC_LAZYEMITTINGLAYER_H