]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h
Merge llvm, clang, compiler-rt, libc++, lld, and lldb release_80 branch
[FreeBSD/FreeBSD.git] / contrib / llvm / 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 "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/ExecutionEngine/Orc/Core.h"
22 #include "llvm/IR/GlobalValue.h"
23 #include "llvm/IR/Mangler.h"
24 #include "llvm/IR/Module.h"
25 #include "llvm/Support/ErrorHandling.h"
26 #include "llvm/Support/raw_ostream.h"
27 #include <algorithm>
28 #include <cassert>
29 #include <list>
30 #include <memory>
31 #include <string>
32
33 namespace llvm {
34 namespace orc {
35
36 /// Lazy-emitting IR layer.
37 ///
38 ///   This layer accepts LLVM IR Modules (via addModule), but does not
39 /// immediately emit them the layer below. Instead, emissing to the base layer
40 /// is deferred until the first time the client requests the address (via
41 /// JITSymbol::getAddress) for a symbol contained in this layer.
42 template <typename BaseLayerT> class LazyEmittingLayer {
43 private:
44   class EmissionDeferredModule {
45   public:
46     EmissionDeferredModule(VModuleKey K, std::unique_ptr<Module> M)
47         : K(std::move(K)), M(std::move(M)) {}
48
49     JITSymbol find(StringRef Name, bool ExportedSymbolsOnly, BaseLayerT &B) {
50       switch (EmitState) {
51       case NotEmitted:
52         if (auto GV = searchGVs(Name, ExportedSymbolsOnly)) {
53           // Create a std::string version of Name to capture here - the argument
54           // (a StringRef) may go away before the lambda is executed.
55           // FIXME: Use capture-init when we move to C++14.
56           std::string PName = Name;
57           JITSymbolFlags Flags = JITSymbolFlags::fromGlobalValue(*GV);
58           auto GetAddress =
59             [this, ExportedSymbolsOnly, PName, &B]() -> Expected<JITTargetAddress> {
60               if (this->EmitState == Emitting)
61                 return 0;
62               else if (this->EmitState == NotEmitted) {
63                 this->EmitState = Emitting;
64                 if (auto Err = this->emitToBaseLayer(B))
65                   return std::move(Err);
66                 this->EmitState = Emitted;
67               }
68               if (auto Sym = B.findSymbolIn(K, PName, ExportedSymbolsOnly))
69                 return Sym.getAddress();
70               else if (auto Err = Sym.takeError())
71                 return std::move(Err);
72               else
73                 llvm_unreachable("Successful symbol lookup should return "
74                                  "definition address here");
75           };
76           return JITSymbol(std::move(GetAddress), Flags);
77         } else
78           return nullptr;
79       case Emitting:
80         // Calling "emit" can trigger a recursive call to 'find' (e.g. to check
81         // for pre-existing definitions of common-symbol), but any symbol in
82         // this module would already have been found internally (in the
83         // RuntimeDyld that did the lookup), so just return a nullptr here.
84         return nullptr;
85       case Emitted:
86         return B.findSymbolIn(K, Name, ExportedSymbolsOnly);
87       }
88       llvm_unreachable("Invalid emit-state.");
89     }
90
91     Error removeModuleFromBaseLayer(BaseLayerT& BaseLayer) {
92       return EmitState != NotEmitted ? BaseLayer.removeModule(K)
93                                      : Error::success();
94     }
95
96     void emitAndFinalize(BaseLayerT &BaseLayer) {
97       assert(EmitState != Emitting &&
98              "Cannot emitAndFinalize while already emitting");
99       if (EmitState == NotEmitted) {
100         EmitState = Emitting;
101         emitToBaseLayer(BaseLayer);
102         EmitState = Emitted;
103       }
104       BaseLayer.emitAndFinalize(K);
105     }
106
107   private:
108
109     const GlobalValue* searchGVs(StringRef Name,
110                                  bool ExportedSymbolsOnly) const {
111       // FIXME: We could clean all this up if we had a way to reliably demangle
112       //        names: We could just demangle name and search, rather than
113       //        mangling everything else.
114
115       // If we have already built the mangled name set then just search it.
116       if (MangledSymbols) {
117         auto VI = MangledSymbols->find(Name);
118         if (VI == MangledSymbols->end())
119           return nullptr;
120         auto GV = VI->second;
121         if (!ExportedSymbolsOnly || GV->hasDefaultVisibility())
122           return GV;
123         return nullptr;
124       }
125
126       // If we haven't built the mangled name set yet, try to build it. As an
127       // optimization this will leave MangledNames set to nullptr if we find
128       // Name in the process of building the set.
129       return buildMangledSymbols(Name, ExportedSymbolsOnly);
130     }
131
132     Error emitToBaseLayer(BaseLayerT &BaseLayer) {
133       // We don't need the mangled names set any more: Once we've emitted this
134       // to the base layer we'll just look for symbols there.
135       MangledSymbols.reset();
136       return BaseLayer.addModule(std::move(K), std::move(M));
137     }
138
139     // If the mangled name of the given GlobalValue matches the given search
140     // name (and its visibility conforms to the ExportedSymbolsOnly flag) then
141     // return the symbol. Otherwise, add the mangled name to the Names map and
142     // return nullptr.
143     const GlobalValue* addGlobalValue(StringMap<const GlobalValue*> &Names,
144                                       const GlobalValue &GV,
145                                       const Mangler &Mang, StringRef SearchName,
146                                       bool ExportedSymbolsOnly) const {
147       // Modules don't "provide" decls or common symbols.
148       if (GV.isDeclaration() || GV.hasCommonLinkage())
149         return nullptr;
150
151       // Mangle the GV name.
152       std::string MangledName;
153       {
154         raw_string_ostream MangledNameStream(MangledName);
155         Mang.getNameWithPrefix(MangledNameStream, &GV, false);
156       }
157
158       // Check whether this is the name we were searching for, and if it is then
159       // bail out early.
160       if (MangledName == SearchName)
161         if (!ExportedSymbolsOnly || GV.hasDefaultVisibility())
162           return &GV;
163
164       // Otherwise add this to the map for later.
165       Names[MangledName] = &GV;
166       return nullptr;
167     }
168
169     // Build the MangledSymbols map. Bails out early (with MangledSymbols left set
170     // to nullptr) if the given SearchName is found while building the map.
171     const GlobalValue* buildMangledSymbols(StringRef SearchName,
172                                            bool ExportedSymbolsOnly) const {
173       assert(!MangledSymbols && "Mangled symbols map already exists?");
174
175       auto Symbols = llvm::make_unique<StringMap<const GlobalValue*>>();
176
177       Mangler Mang;
178
179       for (const auto &GO : M->global_objects())
180           if (auto GV = addGlobalValue(*Symbols, GO, Mang, SearchName,
181                                        ExportedSymbolsOnly))
182             return GV;
183
184       MangledSymbols = std::move(Symbols);
185       return nullptr;
186     }
187
188     enum { NotEmitted, Emitting, Emitted } EmitState = NotEmitted;
189     VModuleKey K;
190     std::unique_ptr<Module> M;
191     mutable std::unique_ptr<StringMap<const GlobalValue*>> MangledSymbols;
192   };
193
194   BaseLayerT &BaseLayer;
195   std::map<VModuleKey, std::unique_ptr<EmissionDeferredModule>> ModuleMap;
196
197 public:
198
199   /// Construct a lazy emitting layer.
200   LazyEmittingLayer(BaseLayerT &BaseLayer) : BaseLayer(BaseLayer) {}
201
202   /// Add the given module to the lazy emitting layer.
203   Error addModule(VModuleKey K, std::unique_ptr<Module> M) {
204     assert(!ModuleMap.count(K) && "VModuleKey K already in use");
205     ModuleMap[K] =
206         llvm::make_unique<EmissionDeferredModule>(std::move(K), std::move(M));
207     return Error::success();
208   }
209
210   /// Remove the module represented by the given handle.
211   ///
212   ///   This method will free the memory associated with the given module, both
213   /// in this layer, and the base layer.
214   Error removeModule(VModuleKey K) {
215     auto I = ModuleMap.find(K);
216     assert(I != ModuleMap.end() && "VModuleKey K not valid here");
217     auto EDM = std::move(I.second);
218     ModuleMap.erase(I);
219     return EDM->removeModuleFromBaseLayer(BaseLayer);
220   }
221
222   /// Search for the given named symbol.
223   /// @param Name The name of the symbol to search for.
224   /// @param ExportedSymbolsOnly If true, search only for exported symbols.
225   /// @return A handle for the given named symbol, if it exists.
226   JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
227     // Look for the symbol among existing definitions.
228     if (auto Symbol = BaseLayer.findSymbol(Name, ExportedSymbolsOnly))
229       return Symbol;
230
231     // If not found then search the deferred modules. If any of these contain a
232     // definition of 'Name' then they will return a JITSymbol that will emit
233     // the corresponding module when the symbol address is requested.
234     for (auto &KV : ModuleMap)
235       if (auto Symbol = KV.second->find(Name, ExportedSymbolsOnly, BaseLayer))
236         return Symbol;
237
238     // If no definition found anywhere return a null symbol.
239     return nullptr;
240   }
241
242   /// Get the address of the given symbol in the context of the of
243   ///        compiled modules represented by the key K.
244   JITSymbol findSymbolIn(VModuleKey K, const std::string &Name,
245                          bool ExportedSymbolsOnly) {
246     assert(ModuleMap.count(K) && "VModuleKey K not valid here");
247     return ModuleMap[K]->find(Name, ExportedSymbolsOnly, BaseLayer);
248   }
249
250   /// Immediately emit and finalize the module represented by the given
251   ///        key.
252   Error emitAndFinalize(VModuleKey K) {
253     assert(ModuleMap.count(K) && "VModuleKey K not valid here");
254     return ModuleMap[K]->emitAndFinalize(BaseLayer);
255   }
256 };
257
258 } // end namespace orc
259 } // end namespace llvm
260
261 #endif // LLVM_EXECUTIONENGINE_ORC_LAZYEMITTINGLAYER_H