Mercurial > hg > Members > tobaru > cbc > CbC_llvm
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 |