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