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