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