comparison lib/ExecutionEngine/Orc/OrcMCJITReplacement.h @ 97:b0dd3743370f

LLVM 3.8
author Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
date Wed, 14 Oct 2015 19:39:58 +0900
parents afa8332a0e37
children 7d135dc70f03
comparison
equal deleted inserted replaced
94:d52ff4b80465 97:b0dd3743370f
20 #include "llvm/ExecutionEngine/Orc/LazyEmittingLayer.h" 20 #include "llvm/ExecutionEngine/Orc/LazyEmittingLayer.h"
21 #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h" 21 #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
22 #include "llvm/Object/Archive.h" 22 #include "llvm/Object/Archive.h"
23 23
24 namespace llvm { 24 namespace llvm {
25 namespace orc {
25 26
26 class OrcMCJITReplacement : public ExecutionEngine { 27 class OrcMCJITReplacement : public ExecutionEngine {
27 28
28 class ForwardingRTDyldMM : public RTDyldMemoryManager { 29 // OrcMCJITReplacement needs to do a little extra book-keeping to ensure that
30 // Orc's automatic finalization doesn't kick in earlier than MCJIT clients are
31 // expecting - see finalizeMemory.
32 class MCJITReplacementMemMgr : public MCJITMemoryManager {
29 public: 33 public:
30 ForwardingRTDyldMM(OrcMCJITReplacement &M) : M(M) {} 34 MCJITReplacementMemMgr(OrcMCJITReplacement &M,
35 std::shared_ptr<MCJITMemoryManager> ClientMM)
36 : M(M), ClientMM(std::move(ClientMM)) {}
31 37
32 uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, 38 uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
33 unsigned SectionID, 39 unsigned SectionID,
34 StringRef SectionName) override { 40 StringRef SectionName) override {
35 uint8_t *Addr = 41 uint8_t *Addr =
36 M.MM->allocateCodeSection(Size, Alignment, SectionID, SectionName); 42 ClientMM->allocateCodeSection(Size, Alignment, SectionID,
43 SectionName);
37 M.SectionsAllocatedSinceLastLoad.insert(Addr); 44 M.SectionsAllocatedSinceLastLoad.insert(Addr);
38 return Addr; 45 return Addr;
39 } 46 }
40 47
41 uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, 48 uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
42 unsigned SectionID, StringRef SectionName, 49 unsigned SectionID, StringRef SectionName,
43 bool IsReadOnly) override { 50 bool IsReadOnly) override {
44 uint8_t *Addr = M.MM->allocateDataSection(Size, Alignment, SectionID, 51 uint8_t *Addr = ClientMM->allocateDataSection(Size, Alignment, SectionID,
45 SectionName, IsReadOnly); 52 SectionName, IsReadOnly);
46 M.SectionsAllocatedSinceLastLoad.insert(Addr); 53 M.SectionsAllocatedSinceLastLoad.insert(Addr);
47 return Addr; 54 return Addr;
48 } 55 }
49 56
50 void reserveAllocationSpace(uintptr_t CodeSize, uintptr_t DataSizeRO, 57 void reserveAllocationSpace(uintptr_t CodeSize, uintptr_t DataSizeRO,
51 uintptr_t DataSizeRW) override { 58 uintptr_t DataSizeRW) override {
52 return M.MM->reserveAllocationSpace(CodeSize, DataSizeRO, DataSizeRW); 59 return ClientMM->reserveAllocationSpace(CodeSize, DataSizeRO,
60 DataSizeRW);
53 } 61 }
54 62
55 bool needsToReserveAllocationSpace() override { 63 bool needsToReserveAllocationSpace() override {
56 return M.MM->needsToReserveAllocationSpace(); 64 return ClientMM->needsToReserveAllocationSpace();
57 } 65 }
58 66
59 void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, 67 void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr,
60 size_t Size) override { 68 size_t Size) override {
61 return M.MM->registerEHFrames(Addr, LoadAddr, Size); 69 return ClientMM->registerEHFrames(Addr, LoadAddr, Size);
62 } 70 }
63 71
64 void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr, 72 void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr,
65 size_t Size) override { 73 size_t Size) override {
66 return M.MM->deregisterEHFrames(Addr, LoadAddr, Size); 74 return ClientMM->deregisterEHFrames(Addr, LoadAddr, Size);
67 }
68
69 uint64_t getSymbolAddress(const std::string &Name) override {
70 return M.getSymbolAddressWithoutMangling(Name);
71 }
72
73 void *getPointerToNamedFunction(const std::string &Name,
74 bool AbortOnFailure = true) override {
75 return M.MM->getPointerToNamedFunction(Name, AbortOnFailure);
76 } 75 }
77 76
78 void notifyObjectLoaded(ExecutionEngine *EE, 77 void notifyObjectLoaded(ExecutionEngine *EE,
79 const object::ObjectFile &O) override { 78 const object::ObjectFile &O) override {
80 return M.MM->notifyObjectLoaded(EE, O); 79 return ClientMM->notifyObjectLoaded(EE, O);
81 } 80 }
82 81
83 bool finalizeMemory(std::string *ErrMsg = nullptr) override { 82 bool finalizeMemory(std::string *ErrMsg = nullptr) override {
84 // Each set of objects loaded will be finalized exactly once, but since 83 // Each set of objects loaded will be finalized exactly once, but since
85 // symbol lookup during relocation may recursively trigger the 84 // symbol lookup during relocation may recursively trigger the
93 // loaded but not yet finalized. This is a bit of a hack that relies on 92 // loaded but not yet finalized. This is a bit of a hack that relies on
94 // the fact that we're lazily emitting object files: The only way you can 93 // the fact that we're lazily emitting object files: The only way you can
95 // get more than one set of objects loaded but not yet finalized is if 94 // get more than one set of objects loaded but not yet finalized is if
96 // they were loaded during relocation of another set. 95 // they were loaded during relocation of another set.
97 if (M.UnfinalizedSections.size() == 1) 96 if (M.UnfinalizedSections.size() == 1)
98 return M.MM->finalizeMemory(ErrMsg); 97 return ClientMM->finalizeMemory(ErrMsg);
99 return false; 98 return false;
100 } 99 }
101 100
102 private: 101 private:
103 OrcMCJITReplacement &M; 102 OrcMCJITReplacement &M;
103 std::shared_ptr<MCJITMemoryManager> ClientMM;
104 };
105
106 class LinkingResolver : public RuntimeDyld::SymbolResolver {
107 public:
108 LinkingResolver(OrcMCJITReplacement &M) : M(M) {}
109
110 RuntimeDyld::SymbolInfo findSymbol(const std::string &Name) override {
111 return M.findMangledSymbol(Name);
112 }
113
114 RuntimeDyld::SymbolInfo
115 findSymbolInLogicalDylib(const std::string &Name) override {
116 return M.ClientResolver->findSymbolInLogicalDylib(Name);
117 }
118
119 private:
120 OrcMCJITReplacement &M;
104 }; 121 };
105 122
106 private: 123 private:
124
107 static ExecutionEngine * 125 static ExecutionEngine *
108 createOrcMCJITReplacement(std::string *ErrorMsg, 126 createOrcMCJITReplacement(std::string *ErrorMsg,
109 std::unique_ptr<RTDyldMemoryManager> OrcJMM, 127 std::shared_ptr<MCJITMemoryManager> MemMgr,
110 std::unique_ptr<llvm::TargetMachine> TM) { 128 std::shared_ptr<RuntimeDyld::SymbolResolver> Resolver,
111 return new llvm::OrcMCJITReplacement(std::move(OrcJMM), std::move(TM)); 129 std::unique_ptr<TargetMachine> TM) {
130 return new OrcMCJITReplacement(std::move(MemMgr), std::move(Resolver),
131 std::move(TM));
112 } 132 }
113 133
114 public: 134 public:
115 static void Register() { 135 static void Register() {
116 OrcMCJITReplacementCtor = createOrcMCJITReplacement; 136 OrcMCJITReplacementCtor = createOrcMCJITReplacement;
117 } 137 }
118 138
119 OrcMCJITReplacement(std::unique_ptr<RTDyldMemoryManager> MM, 139 OrcMCJITReplacement(
120 std::unique_ptr<TargetMachine> TM) 140 std::shared_ptr<MCJITMemoryManager> MemMgr,
121 : TM(std::move(TM)), MM(std::move(MM)), Mang(this->TM->getDataLayout()), 141 std::shared_ptr<RuntimeDyld::SymbolResolver> ClientResolver,
122 NotifyObjectLoaded(*this), NotifyFinalized(*this), 142 std::unique_ptr<TargetMachine> TM)
123 ObjectLayer(ObjectLayerT::CreateRTDyldMMFtor(), NotifyObjectLoaded, 143 : ExecutionEngine(TM->createDataLayout()), TM(std::move(TM)),
124 NotifyFinalized), 144 MemMgr(*this, std::move(MemMgr)), Resolver(*this),
145 ClientResolver(std::move(ClientResolver)), NotifyObjectLoaded(*this),
146 NotifyFinalized(*this),
147 ObjectLayer(NotifyObjectLoaded, NotifyFinalized),
125 CompileLayer(ObjectLayer, SimpleCompiler(*this->TM)), 148 CompileLayer(ObjectLayer, SimpleCompiler(*this->TM)),
126 LazyEmitLayer(CompileLayer) { 149 LazyEmitLayer(CompileLayer) {}
127 setDataLayout(this->TM->getDataLayout());
128 }
129 150
130 void addModule(std::unique_ptr<Module> M) override { 151 void addModule(std::unique_ptr<Module> M) override {
131 152
132 // If this module doesn't have a DataLayout attached then attach the 153 // If this module doesn't have a DataLayout attached then attach the
133 // default. 154 // default.
134 if (!M->getDataLayout()) 155 if (M->getDataLayout().isDefault()) {
135 M->setDataLayout(getDataLayout()); 156 M->setDataLayout(getDataLayout());
136 157 } else {
158 assert(M->getDataLayout() == getDataLayout() && "DataLayout Mismatch");
159 }
137 Modules.push_back(std::move(M)); 160 Modules.push_back(std::move(M));
138 std::vector<Module *> Ms; 161 std::vector<Module *> Ms;
139 Ms.push_back(&*Modules.back()); 162 Ms.push_back(&*Modules.back());
140 LazyEmitLayer.addModuleSet(std::move(Ms), 163 LazyEmitLayer.addModuleSet(std::move(Ms), &MemMgr, &Resolver);
141 llvm::make_unique<ForwardingRTDyldMM>(*this));
142 } 164 }
143 165
144 void addObjectFile(std::unique_ptr<object::ObjectFile> O) override { 166 void addObjectFile(std::unique_ptr<object::ObjectFile> O) override {
145 std::vector<std::unique_ptr<object::ObjectFile>> Objs; 167 std::vector<std::unique_ptr<object::ObjectFile>> Objs;
146 Objs.push_back(std::move(O)); 168 Objs.push_back(std::move(O));
147 ObjectLayer.addObjectSet(std::move(Objs), 169 ObjectLayer.addObjectSet(std::move(Objs), &MemMgr, &Resolver);
148 llvm::make_unique<ForwardingRTDyldMM>(*this));
149 } 170 }
150 171
151 void addObjectFile(object::OwningBinary<object::ObjectFile> O) override { 172 void addObjectFile(object::OwningBinary<object::ObjectFile> O) override {
152 std::unique_ptr<object::ObjectFile> Obj; 173 std::unique_ptr<object::ObjectFile> Obj;
153 std::unique_ptr<MemoryBuffer> Buf; 174 std::unique_ptr<MemoryBuffer> Buf;
154 std::tie(Obj, Buf) = O.takeBinary(); 175 std::tie(Obj, Buf) = O.takeBinary();
155 std::vector<std::unique_ptr<object::ObjectFile>> Objs; 176 std::vector<std::unique_ptr<object::ObjectFile>> Objs;
156 Objs.push_back(std::move(Obj)); 177 Objs.push_back(std::move(Obj));
157 auto H = 178 auto H =
158 ObjectLayer.addObjectSet(std::move(Objs), 179 ObjectLayer.addObjectSet(std::move(Objs), &MemMgr, &Resolver);
159 llvm::make_unique<ForwardingRTDyldMM>(*this));
160 180
161 std::vector<std::unique_ptr<MemoryBuffer>> Bufs; 181 std::vector<std::unique_ptr<MemoryBuffer>> Bufs;
162 Bufs.push_back(std::move(Buf)); 182 Bufs.push_back(std::move(Buf));
163 ObjectLayer.takeOwnershipOfBuffers(H, std::move(Bufs)); 183 ObjectLayer.takeOwnershipOfBuffers(H, std::move(Bufs));
164 } 184 }
166 void addArchive(object::OwningBinary<object::Archive> A) override { 186 void addArchive(object::OwningBinary<object::Archive> A) override {
167 Archives.push_back(std::move(A)); 187 Archives.push_back(std::move(A));
168 } 188 }
169 189
170 uint64_t getSymbolAddress(StringRef Name) { 190 uint64_t getSymbolAddress(StringRef Name) {
171 return getSymbolAddressWithoutMangling(Mangle(Name)); 191 return findSymbol(Name).getAddress();
192 }
193
194 RuntimeDyld::SymbolInfo findSymbol(StringRef Name) {
195 return findMangledSymbol(Mangle(Name));
172 } 196 }
173 197
174 void finalizeObject() override { 198 void finalizeObject() override {
175 // This is deprecated - Aim to remove in ExecutionEngine. 199 // This is deprecated - Aim to remove in ExecutionEngine.
176 // REMOVE IF POSSIBLE - Doesn't make sense for New JIT. 200 // REMOVE IF POSSIBLE - Doesn't make sense for New JIT.
203 llvm_unreachable("Missing symbol!"); 227 llvm_unreachable("Missing symbol!");
204 return reinterpret_cast<void *>(static_cast<uintptr_t>(Addr)); 228 return reinterpret_cast<void *>(static_cast<uintptr_t>(Addr));
205 } 229 }
206 230
207 GenericValue runFunction(Function *F, 231 GenericValue runFunction(Function *F,
208 const std::vector<GenericValue> &ArgValues) override; 232 ArrayRef<GenericValue> ArgValues) override;
209 233
210 void setObjectCache(ObjectCache *NewCache) override { 234 void setObjectCache(ObjectCache *NewCache) override {
211 CompileLayer.setObjectCache(NewCache); 235 CompileLayer.setObjectCache(NewCache);
212 } 236 }
213 237
214 private: 238 private:
215 uint64_t getSymbolAddressWithoutMangling(StringRef Name) { 239
216 if (uint64_t Addr = LazyEmitLayer.findSymbol(Name, false).getAddress()) 240 RuntimeDyld::SymbolInfo findMangledSymbol(StringRef Name) {
217 return Addr; 241 if (auto Sym = LazyEmitLayer.findSymbol(Name, false))
218 if (uint64_t Addr = MM->getSymbolAddress(Name)) 242 return RuntimeDyld::SymbolInfo(Sym.getAddress(), Sym.getFlags());
219 return Addr; 243 if (auto Sym = ClientResolver->findSymbol(Name))
220 if (uint64_t Addr = scanArchives(Name)) 244 return RuntimeDyld::SymbolInfo(Sym.getAddress(), Sym.getFlags());
221 return Addr; 245 if (auto Sym = scanArchives(Name))
222 246 return RuntimeDyld::SymbolInfo(Sym.getAddress(), Sym.getFlags());
223 return 0; 247
224 } 248 return nullptr;
225 249 }
226 uint64_t scanArchives(StringRef Name) { 250
251 JITSymbol scanArchives(StringRef Name) {
227 for (object::OwningBinary<object::Archive> &OB : Archives) { 252 for (object::OwningBinary<object::Archive> &OB : Archives) {
228 object::Archive *A = OB.getBinary(); 253 object::Archive *A = OB.getBinary();
229 // Look for our symbols in each Archive 254 // Look for our symbols in each Archive
230 object::Archive::child_iterator ChildIt = A->findSym(Name); 255 object::Archive::child_iterator ChildIt = A->findSym(Name);
231 if (ChildIt != A->child_end()) { 256 if (ChildIt != A->child_end()) {
237 std::unique_ptr<object::Binary> &ChildBin = ChildBinOrErr.get(); 262 std::unique_ptr<object::Binary> &ChildBin = ChildBinOrErr.get();
238 if (ChildBin->isObject()) { 263 if (ChildBin->isObject()) {
239 std::vector<std::unique_ptr<object::ObjectFile>> ObjSet; 264 std::vector<std::unique_ptr<object::ObjectFile>> ObjSet;
240 ObjSet.push_back(std::unique_ptr<object::ObjectFile>( 265 ObjSet.push_back(std::unique_ptr<object::ObjectFile>(
241 static_cast<object::ObjectFile *>(ChildBin.release()))); 266 static_cast<object::ObjectFile *>(ChildBin.release())));
242 ObjectLayer.addObjectSet( 267 ObjectLayer.addObjectSet(std::move(ObjSet), &MemMgr, &Resolver);
243 std::move(ObjSet), llvm::make_unique<ForwardingRTDyldMM>(*this)); 268 if (auto Sym = ObjectLayer.findSymbol(Name, true))
244 if (uint64_t Addr = ObjectLayer.findSymbol(Name, true).getAddress()) 269 return Sym;
245 return Addr;
246 } 270 }
247 } 271 }
248 } 272 }
249 return 0; 273 return nullptr;
250 } 274 }
251 275
252 class NotifyObjectLoadedT { 276 class NotifyObjectLoadedT {
253 public: 277 public:
254 typedef std::vector<std::unique_ptr<object::ObjectFile>> ObjListT; 278 typedef std::vector<std::unique_ptr<object::ObjectFile>> ObjListT;
263 M.UnfinalizedSections[H] = std::move(M.SectionsAllocatedSinceLastLoad); 287 M.UnfinalizedSections[H] = std::move(M.SectionsAllocatedSinceLastLoad);
264 M.SectionsAllocatedSinceLastLoad = SectionAddrSet(); 288 M.SectionsAllocatedSinceLastLoad = SectionAddrSet();
265 assert(Objects.size() == Infos.size() && 289 assert(Objects.size() == Infos.size() &&
266 "Incorrect number of Infos for Objects."); 290 "Incorrect number of Infos for Objects.");
267 for (unsigned I = 0; I < Objects.size(); ++I) 291 for (unsigned I = 0; I < Objects.size(); ++I)
268 M.MM->notifyObjectLoaded(&M, *Objects[I]); 292 M.MemMgr.notifyObjectLoaded(&M, *Objects[I]);
269 }; 293 }
270 294
271 private: 295 private:
272 OrcMCJITReplacement &M; 296 OrcMCJITReplacement &M;
273 }; 297 };
274 298
285 309
286 std::string Mangle(StringRef Name) { 310 std::string Mangle(StringRef Name) {
287 std::string MangledName; 311 std::string MangledName;
288 { 312 {
289 raw_string_ostream MangledNameStream(MangledName); 313 raw_string_ostream MangledNameStream(MangledName);
290 Mang.getNameWithPrefix(MangledNameStream, Name); 314 Mang.getNameWithPrefix(MangledNameStream, Name, getDataLayout());
291 } 315 }
292 return MangledName; 316 return MangledName;
293 } 317 }
294 318
295 typedef ObjectLinkingLayer<NotifyObjectLoadedT> ObjectLayerT; 319 typedef ObjectLinkingLayer<NotifyObjectLoadedT> ObjectLayerT;
296 typedef IRCompileLayer<ObjectLayerT> CompileLayerT; 320 typedef IRCompileLayer<ObjectLayerT> CompileLayerT;
297 typedef LazyEmittingLayer<CompileLayerT> LazyEmitLayerT; 321 typedef LazyEmittingLayer<CompileLayerT> LazyEmitLayerT;
298 322
299 std::unique_ptr<TargetMachine> TM; 323 std::unique_ptr<TargetMachine> TM;
300 std::unique_ptr<RTDyldMemoryManager> MM; 324 MCJITReplacementMemMgr MemMgr;
325 LinkingResolver Resolver;
326 std::shared_ptr<RuntimeDyld::SymbolResolver> ClientResolver;
301 Mangler Mang; 327 Mangler Mang;
302 328
303 NotifyObjectLoadedT NotifyObjectLoaded; 329 NotifyObjectLoadedT NotifyObjectLoaded;
304 NotifyFinalizedT NotifyFinalized; 330 NotifyFinalizedT NotifyFinalized;
305 331
321 std::map<ObjectLayerT::ObjSetHandleT, SectionAddrSet, ObjSetHandleCompare> 347 std::map<ObjectLayerT::ObjSetHandleT, SectionAddrSet, ObjSetHandleCompare>
322 UnfinalizedSections; 348 UnfinalizedSections;
323 349
324 std::vector<object::OwningBinary<object::Archive>> Archives; 350 std::vector<object::OwningBinary<object::Archive>> Archives;
325 }; 351 };
326 } 352
353 } // End namespace orc.
354 } // End namespace llvm.
327 355
328 #endif // LLVM_LIB_EXECUTIONENGINE_ORC_MCJITREPLACEMENT_H 356 #endif // LLVM_LIB_EXECUTIONENGINE_ORC_MCJITREPLACEMENT_H