00e39bb73c13d435fd1c43613c5dee60ca8a9c4f
[oota-llvm.git] / lib / ExecutionEngine / Orc / OrcMCJITReplacement.h
1 //===---- OrcMCJITReplacement.h - Orc based MCJIT replacement ---*- 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 // Orc based MCJIT replacement.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_LIB_EXECUTIONENGINE_ORC_ORCMCJITREPLACEMENT_H
15 #define LLVM_LIB_EXECUTIONENGINE_ORC_ORCMCJITREPLACEMENT_H
16
17 #include "llvm/ExecutionEngine/ExecutionEngine.h"
18 #include "llvm/ExecutionEngine/Orc/CompileUtils.h"
19 #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
20 #include "llvm/ExecutionEngine/Orc/LazyEmittingLayer.h"
21 #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
22 #include "llvm/Object/Archive.h"
23
24 namespace llvm {
25 namespace orc {
26
27 class OrcMCJITReplacement : public ExecutionEngine {
28
29   class ForwardingRTDyldMM : public RTDyldMemoryManager {
30   public:
31     ForwardingRTDyldMM(OrcMCJITReplacement &M) : M(M) {}
32
33     uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
34                                  unsigned SectionID,
35                                  StringRef SectionName) override {
36       uint8_t *Addr =
37           M.MM->allocateCodeSection(Size, Alignment, SectionID, SectionName);
38       M.SectionsAllocatedSinceLastLoad.insert(Addr);
39       return Addr;
40     }
41
42     uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
43                                  unsigned SectionID, StringRef SectionName,
44                                  bool IsReadOnly) override {
45       uint8_t *Addr = M.MM->allocateDataSection(Size, Alignment, SectionID,
46                                                 SectionName, IsReadOnly);
47       M.SectionsAllocatedSinceLastLoad.insert(Addr);
48       return Addr;
49     }
50
51     void reserveAllocationSpace(uintptr_t CodeSize, uintptr_t DataSizeRO,
52                                 uintptr_t DataSizeRW) override {
53       return M.MM->reserveAllocationSpace(CodeSize, DataSizeRO, DataSizeRW);
54     }
55
56     bool needsToReserveAllocationSpace() override {
57       return M.MM->needsToReserveAllocationSpace();
58     }
59
60     void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr,
61                           size_t Size) override {
62       return M.MM->registerEHFrames(Addr, LoadAddr, Size);
63     }
64
65     void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr,
66                             size_t Size) override {
67       return M.MM->deregisterEHFrames(Addr, LoadAddr, Size);
68     }
69
70     uint64_t getSymbolAddress(const std::string &Name) override {
71       return M.getSymbolAddressWithoutMangling(Name);
72     }
73
74     void *getPointerToNamedFunction(const std::string &Name,
75                                     bool AbortOnFailure = true) override {
76       return M.MM->getPointerToNamedFunction(Name, AbortOnFailure);
77     }
78
79     void notifyObjectLoaded(ExecutionEngine *EE,
80                             const object::ObjectFile &O) override {
81       return M.MM->notifyObjectLoaded(EE, O);
82     }
83
84     bool finalizeMemory(std::string *ErrMsg = nullptr) override {
85       // Each set of objects loaded will be finalized exactly once, but since
86       // symbol lookup during relocation may recursively trigger the
87       // loading/relocation of other modules, and since we're forwarding all
88       // finalizeMemory calls to a single underlying memory manager, we need to
89       // defer forwarding the call on until all necessary objects have been
90       // loaded. Otherwise, during the relocation of a leaf object, we will end
91       // up finalizing memory, causing a crash further up the stack when we
92       // attempt to apply relocations to finalized memory.
93       // To avoid finalizing too early, look at how many objects have been
94       // loaded but not yet finalized. This is a bit of a hack that relies on
95       // the fact that we're lazily emitting object files: The only way you can
96       // get more than one set of objects loaded but not yet finalized is if
97       // they were loaded during relocation of another set.
98       if (M.UnfinalizedSections.size() == 1)
99         return M.MM->finalizeMemory(ErrMsg);
100       return false;
101     }
102
103   private:
104     OrcMCJITReplacement &M;
105   };
106
107 private:
108
109   static ExecutionEngine *
110   createOrcMCJITReplacement(std::string *ErrorMsg,
111                             std::unique_ptr<RTDyldMemoryManager> OrcJMM,
112                             std::unique_ptr<TargetMachine> TM) {
113     return new OrcMCJITReplacement(std::move(OrcJMM), std::move(TM));
114   }
115
116 public:
117   static void Register() {
118     OrcMCJITReplacementCtor = createOrcMCJITReplacement;
119   }
120
121   OrcMCJITReplacement(std::unique_ptr<RTDyldMemoryManager> MM,
122                       std::unique_ptr<TargetMachine> TM)
123       : TM(std::move(TM)), MM(std::move(MM)), Mang(this->TM->getDataLayout()),
124         NotifyObjectLoaded(*this), NotifyFinalized(*this),
125         ObjectLayer(ObjectLayerT::CreateRTDyldMMFtor(), NotifyObjectLoaded,
126                     NotifyFinalized),
127         CompileLayer(ObjectLayer, SimpleCompiler(*this->TM)),
128         LazyEmitLayer(CompileLayer) {
129     setDataLayout(this->TM->getDataLayout());
130   }
131
132   void addModule(std::unique_ptr<Module> M) override {
133
134     // If this module doesn't have a DataLayout attached then attach the
135     // default.
136     if (M->getDataLayout().isDefault())
137       M->setDataLayout(*getDataLayout());
138
139     Modules.push_back(std::move(M));
140     std::vector<Module *> Ms;
141     Ms.push_back(&*Modules.back());
142     LazyEmitLayer.addModuleSet(std::move(Ms),
143                                llvm::make_unique<ForwardingRTDyldMM>(*this));
144   }
145
146   void addObjectFile(std::unique_ptr<object::ObjectFile> O) override {
147     std::vector<std::unique_ptr<object::ObjectFile>> Objs;
148     Objs.push_back(std::move(O));
149     ObjectLayer.addObjectSet(std::move(Objs),
150                              llvm::make_unique<ForwardingRTDyldMM>(*this));
151   }
152
153   void addObjectFile(object::OwningBinary<object::ObjectFile> O) override {
154     std::unique_ptr<object::ObjectFile> Obj;
155     std::unique_ptr<MemoryBuffer> Buf;
156     std::tie(Obj, Buf) = O.takeBinary();
157     std::vector<std::unique_ptr<object::ObjectFile>> Objs;
158     Objs.push_back(std::move(Obj));
159     auto H =
160       ObjectLayer.addObjectSet(std::move(Objs),
161                                llvm::make_unique<ForwardingRTDyldMM>(*this));
162
163     std::vector<std::unique_ptr<MemoryBuffer>> Bufs;
164     Bufs.push_back(std::move(Buf));
165     ObjectLayer.takeOwnershipOfBuffers(H, std::move(Bufs));
166   }
167
168   void addArchive(object::OwningBinary<object::Archive> A) override {
169     Archives.push_back(std::move(A));
170   }
171
172   uint64_t getSymbolAddress(StringRef Name) {
173     return getSymbolAddressWithoutMangling(Mangle(Name));
174   }
175
176   void finalizeObject() override {
177     // This is deprecated - Aim to remove in ExecutionEngine.
178     // REMOVE IF POSSIBLE - Doesn't make sense for New JIT.
179   }
180
181   void mapSectionAddress(const void *LocalAddress,
182                          uint64_t TargetAddress) override {
183     for (auto &P : UnfinalizedSections)
184       if (P.second.count(LocalAddress))
185         ObjectLayer.mapSectionAddress(P.first, LocalAddress, TargetAddress);
186   }
187
188   uint64_t getGlobalValueAddress(const std::string &Name) override {
189     return getSymbolAddress(Name);
190   }
191
192   uint64_t getFunctionAddress(const std::string &Name) override {
193     return getSymbolAddress(Name);
194   }
195
196   void *getPointerToFunction(Function *F) override {
197     uint64_t FAddr = getSymbolAddress(F->getName());
198     return reinterpret_cast<void *>(static_cast<uintptr_t>(FAddr));
199   }
200
201   void *getPointerToNamedFunction(StringRef Name,
202                                   bool AbortOnFailure = true) override {
203     uint64_t Addr = getSymbolAddress(Name);
204     if (!Addr && AbortOnFailure)
205       llvm_unreachable("Missing symbol!");
206     return reinterpret_cast<void *>(static_cast<uintptr_t>(Addr));
207   }
208
209   GenericValue runFunction(Function *F,
210                            const std::vector<GenericValue> &ArgValues) override;
211
212   void setObjectCache(ObjectCache *NewCache) override {
213     CompileLayer.setObjectCache(NewCache);
214   }
215
216 private:
217   uint64_t getSymbolAddressWithoutMangling(StringRef Name) {
218     if (uint64_t Addr = LazyEmitLayer.findSymbol(Name, false).getAddress())
219       return Addr;
220     if (uint64_t Addr = MM->getSymbolAddress(Name))
221       return Addr;
222     if (uint64_t Addr = scanArchives(Name))
223       return Addr;
224
225     return 0;
226   }
227
228   uint64_t scanArchives(StringRef Name) {
229     for (object::OwningBinary<object::Archive> &OB : Archives) {
230       object::Archive *A = OB.getBinary();
231       // Look for our symbols in each Archive
232       object::Archive::child_iterator ChildIt = A->findSym(Name);
233       if (ChildIt != A->child_end()) {
234         // FIXME: Support nested archives?
235         ErrorOr<std::unique_ptr<object::Binary>> ChildBinOrErr =
236             ChildIt->getAsBinary();
237         if (ChildBinOrErr.getError())
238           continue;
239         std::unique_ptr<object::Binary> &ChildBin = ChildBinOrErr.get();
240         if (ChildBin->isObject()) {
241           std::vector<std::unique_ptr<object::ObjectFile>> ObjSet;
242           ObjSet.push_back(std::unique_ptr<object::ObjectFile>(
243               static_cast<object::ObjectFile *>(ChildBin.release())));
244           ObjectLayer.addObjectSet(
245               std::move(ObjSet), llvm::make_unique<ForwardingRTDyldMM>(*this));
246           if (uint64_t Addr = ObjectLayer.findSymbol(Name, true).getAddress())
247             return Addr;
248         }
249       }
250     }
251     return 0;
252   }
253
254   class NotifyObjectLoadedT {
255   public:
256     typedef std::vector<std::unique_ptr<object::ObjectFile>> ObjListT;
257     typedef std::vector<std::unique_ptr<RuntimeDyld::LoadedObjectInfo>>
258         LoadedObjInfoListT;
259
260     NotifyObjectLoadedT(OrcMCJITReplacement &M) : M(M) {}
261
262     void operator()(ObjectLinkingLayerBase::ObjSetHandleT H,
263                     const ObjListT &Objects,
264                     const LoadedObjInfoListT &Infos) const {
265       M.UnfinalizedSections[H] = std::move(M.SectionsAllocatedSinceLastLoad);
266       M.SectionsAllocatedSinceLastLoad = SectionAddrSet();
267       assert(Objects.size() == Infos.size() &&
268              "Incorrect number of Infos for Objects.");
269       for (unsigned I = 0; I < Objects.size(); ++I)
270         M.MM->notifyObjectLoaded(&M, *Objects[I]);
271     };
272
273   private:
274     OrcMCJITReplacement &M;
275   };
276
277   class NotifyFinalizedT {
278   public:
279     NotifyFinalizedT(OrcMCJITReplacement &M) : M(M) {}
280     void operator()(ObjectLinkingLayerBase::ObjSetHandleT H) {
281       M.UnfinalizedSections.erase(H);
282     }
283
284   private:
285     OrcMCJITReplacement &M;
286   };
287
288   std::string Mangle(StringRef Name) {
289     std::string MangledName;
290     {
291       raw_string_ostream MangledNameStream(MangledName);
292       Mang.getNameWithPrefix(MangledNameStream, Name);
293     }
294     return MangledName;
295   }
296
297   typedef ObjectLinkingLayer<NotifyObjectLoadedT> ObjectLayerT;
298   typedef IRCompileLayer<ObjectLayerT> CompileLayerT;
299   typedef LazyEmittingLayer<CompileLayerT> LazyEmitLayerT;
300
301   std::unique_ptr<TargetMachine> TM;
302   std::unique_ptr<RTDyldMemoryManager> MM;
303   Mangler Mang;
304
305   NotifyObjectLoadedT NotifyObjectLoaded;
306   NotifyFinalizedT NotifyFinalized;
307
308   ObjectLayerT ObjectLayer;
309   CompileLayerT CompileLayer;
310   LazyEmitLayerT LazyEmitLayer;
311
312   // We need to store ObjLayerT::ObjSetHandles for each of the object sets
313   // that have been emitted but not yet finalized so that we can forward the
314   // mapSectionAddress calls appropriately.
315   typedef std::set<const void *> SectionAddrSet;
316   struct ObjSetHandleCompare {
317     bool operator()(ObjectLayerT::ObjSetHandleT H1,
318                     ObjectLayerT::ObjSetHandleT H2) const {
319       return &*H1 < &*H2;
320     }
321   };
322   SectionAddrSet SectionsAllocatedSinceLastLoad;
323   std::map<ObjectLayerT::ObjSetHandleT, SectionAddrSet, ObjSetHandleCompare>
324       UnfinalizedSections;
325
326   std::vector<object::OwningBinary<object::Archive>> Archives;
327 };
328
329 } // End namespace orc.
330 } // End namespace llvm.
331
332 #endif // LLVM_LIB_EXECUTIONENGINE_ORC_MCJITREPLACEMENT_H