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
32namespace llvm {
33namespace 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.
41template <typename BaseLayerT> class LazyEmittingLayer {
42public:
43  typedef typename BaseLayerT::ModuleSetHandleT BaseLayerHandleT;
44
45private:
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
224public:
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
287template <typename BaseLayerT>
288template <typename ModuleSetT, typename MemoryManagerPtrT,
289          typename SymbolResolverPtrT>
290std::unique_ptr<typename LazyEmittingLayer<BaseLayerT>::EmissionDeferredSet>
291LazyEmittingLayer<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