[MIPS GlobalISel] Select MSA vector generic and builtin add
[llvm-complete.git] / lib / ExecutionEngine / Orc / OrcCBindingsStack.h
blobe0af3df9d010f0f87caeb5462fb0993f4d05f273
1 //===- OrcCBindingsStack.h - Orc JIT stack for C bindings -----*- C++ -*---===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_LIB_EXECUTIONENGINE_ORC_ORCCBINDINGSSTACK_H
10 #define LLVM_LIB_EXECUTIONENGINE_ORC_ORCCBINDINGSSTACK_H
12 #include "llvm-c/OrcBindings.h"
13 #include "llvm-c/TargetMachine.h"
14 #include "llvm/ADT/STLExtras.h"
15 #include "llvm/ADT/StringRef.h"
16 #include "llvm/ExecutionEngine/JITSymbol.h"
17 #include "llvm/ExecutionEngine/JITEventListener.h"
18 #include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h"
19 #include "llvm/ExecutionEngine/Orc/CompileUtils.h"
20 #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
21 #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
22 #include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
23 #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
24 #include "llvm/ExecutionEngine/RuntimeDyld.h"
25 #include "llvm/ExecutionEngine/SectionMemoryManager.h"
26 #include "llvm/IR/DataLayout.h"
27 #include "llvm/IR/Mangler.h"
28 #include "llvm/IR/Module.h"
29 #include "llvm/Support/CBindingWrapping.h"
30 #include "llvm/Support/Error.h"
31 #include "llvm/Support/raw_ostream.h"
32 #include "llvm/Target/TargetMachine.h"
33 #include <algorithm>
34 #include <cstdint>
35 #include <functional>
36 #include <map>
37 #include <memory>
38 #include <set>
39 #include <string>
40 #include <vector>
42 namespace llvm {
44 class OrcCBindingsStack;
46 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(OrcCBindingsStack, LLVMOrcJITStackRef)
47 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)
49 namespace detail {
51 // FIXME: Kill this off once the Layer concept becomes an interface.
52 class GenericLayer {
53 public:
54 virtual ~GenericLayer() = default;
56 virtual JITSymbol findSymbolIn(orc::VModuleKey K, const std::string &Name,
57 bool ExportedSymbolsOnly) = 0;
58 virtual Error removeModule(orc::VModuleKey K) = 0;
61 template <typename LayerT> class GenericLayerImpl : public GenericLayer {
62 public:
63 GenericLayerImpl(LayerT &Layer) : Layer(Layer) {}
65 JITSymbol findSymbolIn(orc::VModuleKey K, const std::string &Name,
66 bool ExportedSymbolsOnly) override {
67 return Layer.findSymbolIn(K, Name, ExportedSymbolsOnly);
70 Error removeModule(orc::VModuleKey K) override {
71 return Layer.removeModule(K);
74 private:
75 LayerT &Layer;
78 template <>
79 class GenericLayerImpl<orc::LegacyRTDyldObjectLinkingLayer> : public GenericLayer {
80 private:
81 using LayerT = orc::LegacyRTDyldObjectLinkingLayer;
82 public:
83 GenericLayerImpl(LayerT &Layer) : Layer(Layer) {}
85 JITSymbol findSymbolIn(orc::VModuleKey K, const std::string &Name,
86 bool ExportedSymbolsOnly) override {
87 return Layer.findSymbolIn(K, Name, ExportedSymbolsOnly);
90 Error removeModule(orc::VModuleKey K) override {
91 return Layer.removeObject(K);
94 private:
95 LayerT &Layer;
98 template <typename LayerT>
99 std::unique_ptr<GenericLayerImpl<LayerT>> createGenericLayer(LayerT &Layer) {
100 return std::make_unique<GenericLayerImpl<LayerT>>(Layer);
103 } // end namespace detail
105 class OrcCBindingsStack {
106 public:
108 using CompileCallbackMgr = orc::JITCompileCallbackManager;
109 using ObjLayerT = orc::LegacyRTDyldObjectLinkingLayer;
110 using CompileLayerT = orc::LegacyIRCompileLayer<ObjLayerT, orc::SimpleCompiler>;
111 using CODLayerT =
112 orc::LegacyCompileOnDemandLayer<CompileLayerT, CompileCallbackMgr>;
114 using CallbackManagerBuilder =
115 std::function<std::unique_ptr<CompileCallbackMgr>()>;
117 using IndirectStubsManagerBuilder = CODLayerT::IndirectStubsManagerBuilderT;
119 private:
121 using OwningObject = object::OwningBinary<object::ObjectFile>;
123 class CBindingsResolver : public orc::SymbolResolver {
124 public:
125 CBindingsResolver(OrcCBindingsStack &Stack,
126 LLVMOrcSymbolResolverFn ExternalResolver,
127 void *ExternalResolverCtx)
128 : Stack(Stack), ExternalResolver(std::move(ExternalResolver)),
129 ExternalResolverCtx(std::move(ExternalResolverCtx)) {}
131 orc::SymbolNameSet
132 getResponsibilitySet(const orc::SymbolNameSet &Symbols) override {
133 orc::SymbolNameSet Result;
135 for (auto &S : Symbols) {
136 if (auto Sym = findSymbol(*S)) {
137 if (!Sym.getFlags().isStrong())
138 Result.insert(S);
139 } else if (auto Err = Sym.takeError()) {
140 Stack.reportError(std::move(Err));
141 return orc::SymbolNameSet();
145 return Result;
148 orc::SymbolNameSet
149 lookup(std::shared_ptr<orc::AsynchronousSymbolQuery> Query,
150 orc::SymbolNameSet Symbols) override {
151 orc::SymbolNameSet UnresolvedSymbols;
153 for (auto &S : Symbols) {
154 if (auto Sym = findSymbol(*S)) {
155 if (auto Addr = Sym.getAddress()) {
156 Query->notifySymbolMetRequiredState(
157 S, JITEvaluatedSymbol(*Addr, Sym.getFlags()));
158 } else {
159 Stack.ES.legacyFailQuery(*Query, Addr.takeError());
160 return orc::SymbolNameSet();
162 } else if (auto Err = Sym.takeError()) {
163 Stack.ES.legacyFailQuery(*Query, std::move(Err));
164 return orc::SymbolNameSet();
165 } else
166 UnresolvedSymbols.insert(S);
169 if (Query->isComplete())
170 Query->handleComplete();
172 return UnresolvedSymbols;
175 private:
176 JITSymbol findSymbol(const std::string &Name) {
177 // Search order:
178 // 1. JIT'd symbols.
179 // 2. Runtime overrides.
180 // 3. External resolver (if present).
182 if (Stack.CODLayer) {
183 if (auto Sym = Stack.CODLayer->findSymbol(Name, true))
184 return Sym;
185 else if (auto Err = Sym.takeError())
186 return Sym.takeError();
187 } else {
188 if (auto Sym = Stack.CompileLayer.findSymbol(Name, true))
189 return Sym;
190 else if (auto Err = Sym.takeError())
191 return Sym.takeError();
194 if (auto Sym = Stack.CXXRuntimeOverrides.searchOverrides(Name))
195 return Sym;
197 if (ExternalResolver)
198 return JITSymbol(ExternalResolver(Name.c_str(), ExternalResolverCtx),
199 JITSymbolFlags::Exported);
201 return JITSymbol(nullptr);
204 OrcCBindingsStack &Stack;
205 LLVMOrcSymbolResolverFn ExternalResolver;
206 void *ExternalResolverCtx = nullptr;
209 public:
210 OrcCBindingsStack(TargetMachine &TM,
211 IndirectStubsManagerBuilder IndirectStubsMgrBuilder)
212 : CCMgr(createCompileCallbackManager(TM, ES)), DL(TM.createDataLayout()),
213 IndirectStubsMgr(IndirectStubsMgrBuilder()),
214 ObjectLayer(
215 AcknowledgeORCv1Deprecation, ES,
216 [this](orc::VModuleKey K) {
217 auto ResolverI = Resolvers.find(K);
218 assert(ResolverI != Resolvers.end() &&
219 "No resolver for module K");
220 auto Resolver = std::move(ResolverI->second);
221 Resolvers.erase(ResolverI);
222 return ObjLayerT::Resources{
223 std::make_shared<SectionMemoryManager>(), Resolver};
225 nullptr,
226 [this](orc::VModuleKey K, const object::ObjectFile &Obj,
227 const RuntimeDyld::LoadedObjectInfo &LoadedObjInfo) {
228 this->notifyFinalized(K, Obj, LoadedObjInfo);
230 [this](orc::VModuleKey K, const object::ObjectFile &Obj) {
231 this->notifyFreed(K, Obj);
233 CompileLayer(AcknowledgeORCv1Deprecation, ObjectLayer,
234 orc::SimpleCompiler(TM)),
235 CODLayer(createCODLayer(ES, CompileLayer, CCMgr.get(),
236 std::move(IndirectStubsMgrBuilder), Resolvers)),
237 CXXRuntimeOverrides(
238 AcknowledgeORCv1Deprecation,
239 [this](const std::string &S) { return mangle(S); }) {}
241 Error shutdown() {
242 // Run any destructors registered with __cxa_atexit.
243 CXXRuntimeOverrides.runDestructors();
244 // Run any IR destructors.
245 for (auto &DtorRunner : IRStaticDestructorRunners)
246 if (auto Err = DtorRunner.runViaLayer(*this))
247 return Err;
248 return Error::success();
251 std::string mangle(StringRef Name) {
252 std::string MangledName;
254 raw_string_ostream MangledNameStream(MangledName);
255 Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
257 return MangledName;
260 template <typename PtrTy>
261 static PtrTy fromTargetAddress(JITTargetAddress Addr) {
262 return reinterpret_cast<PtrTy>(static_cast<uintptr_t>(Addr));
265 Expected<JITTargetAddress>
266 createLazyCompileCallback(LLVMOrcLazyCompileCallbackFn Callback,
267 void *CallbackCtx) {
268 auto WrappedCallback = [=]() -> JITTargetAddress {
269 return Callback(wrap(this), CallbackCtx);
272 return CCMgr->getCompileCallback(std::move(WrappedCallback));
275 Error createIndirectStub(StringRef StubName, JITTargetAddress Addr) {
276 return IndirectStubsMgr->createStub(StubName, Addr,
277 JITSymbolFlags::Exported);
280 Error setIndirectStubPointer(StringRef Name, JITTargetAddress Addr) {
281 return IndirectStubsMgr->updatePointer(Name, Addr);
284 template <typename LayerT>
285 Expected<orc::VModuleKey>
286 addIRModule(LayerT &Layer, std::unique_ptr<Module> M,
287 std::unique_ptr<RuntimeDyld::MemoryManager> MemMgr,
288 LLVMOrcSymbolResolverFn ExternalResolver,
289 void *ExternalResolverCtx) {
291 // Attach a data-layout if one isn't already present.
292 if (M->getDataLayout().isDefault())
293 M->setDataLayout(DL);
295 // Record the static constructors and destructors. We have to do this before
296 // we hand over ownership of the module to the JIT.
297 std::vector<std::string> CtorNames, DtorNames;
298 for (auto Ctor : orc::getConstructors(*M))
299 CtorNames.push_back(mangle(Ctor.Func->getName()));
300 for (auto Dtor : orc::getDestructors(*M))
301 DtorNames.push_back(mangle(Dtor.Func->getName()));
303 // Add the module to the JIT.
304 auto K = ES.allocateVModule();
305 Resolvers[K] = std::make_shared<CBindingsResolver>(*this, ExternalResolver,
306 ExternalResolverCtx);
307 if (auto Err = Layer.addModule(K, std::move(M)))
308 return std::move(Err);
310 KeyLayers[K] = detail::createGenericLayer(Layer);
312 // Run the static constructors, and save the static destructor runner for
313 // execution when the JIT is torn down.
314 orc::LegacyCtorDtorRunner<OrcCBindingsStack> CtorRunner(
315 AcknowledgeORCv1Deprecation, std::move(CtorNames), K);
316 if (auto Err = CtorRunner.runViaLayer(*this))
317 return std::move(Err);
319 IRStaticDestructorRunners.emplace_back(AcknowledgeORCv1Deprecation,
320 std::move(DtorNames), K);
322 return K;
325 Expected<orc::VModuleKey>
326 addIRModuleEager(std::unique_ptr<Module> M,
327 LLVMOrcSymbolResolverFn ExternalResolver,
328 void *ExternalResolverCtx) {
329 return addIRModule(CompileLayer, std::move(M),
330 std::make_unique<SectionMemoryManager>(),
331 std::move(ExternalResolver), ExternalResolverCtx);
334 Expected<orc::VModuleKey>
335 addIRModuleLazy(std::unique_ptr<Module> M,
336 LLVMOrcSymbolResolverFn ExternalResolver,
337 void *ExternalResolverCtx) {
338 if (!CODLayer)
339 return make_error<StringError>("Can not add lazy module: No compile "
340 "callback manager available",
341 inconvertibleErrorCode());
343 return addIRModule(*CODLayer, std::move(M),
344 std::make_unique<SectionMemoryManager>(),
345 std::move(ExternalResolver), ExternalResolverCtx);
348 Error removeModule(orc::VModuleKey K) {
349 // FIXME: Should error release the module key?
350 if (auto Err = KeyLayers[K]->removeModule(K))
351 return Err;
352 ES.releaseVModule(K);
353 KeyLayers.erase(K);
354 return Error::success();
357 Expected<orc::VModuleKey> addObject(std::unique_ptr<MemoryBuffer> ObjBuffer,
358 LLVMOrcSymbolResolverFn ExternalResolver,
359 void *ExternalResolverCtx) {
360 if (auto Obj = object::ObjectFile::createObjectFile(
361 ObjBuffer->getMemBufferRef())) {
363 auto K = ES.allocateVModule();
364 Resolvers[K] = std::make_shared<CBindingsResolver>(
365 *this, ExternalResolver, ExternalResolverCtx);
367 if (auto Err = ObjectLayer.addObject(K, std::move(ObjBuffer)))
368 return std::move(Err);
370 KeyLayers[K] = detail::createGenericLayer(ObjectLayer);
372 return K;
373 } else
374 return Obj.takeError();
377 JITSymbol findSymbol(const std::string &Name,
378 bool ExportedSymbolsOnly) {
379 if (auto Sym = IndirectStubsMgr->findStub(Name, ExportedSymbolsOnly))
380 return Sym;
381 if (CODLayer)
382 return CODLayer->findSymbol(mangle(Name), ExportedSymbolsOnly);
383 return CompileLayer.findSymbol(mangle(Name), ExportedSymbolsOnly);
386 JITSymbol findSymbolIn(orc::VModuleKey K, const std::string &Name,
387 bool ExportedSymbolsOnly) {
388 assert(KeyLayers.count(K) && "looking up symbol in unknown module");
389 return KeyLayers[K]->findSymbolIn(K, mangle(Name), ExportedSymbolsOnly);
392 Expected<JITTargetAddress> findSymbolAddress(const std::string &Name,
393 bool ExportedSymbolsOnly) {
394 if (auto Sym = findSymbol(Name, ExportedSymbolsOnly)) {
395 // Successful lookup, non-null symbol:
396 if (auto AddrOrErr = Sym.getAddress())
397 return *AddrOrErr;
398 else
399 return AddrOrErr.takeError();
400 } else if (auto Err = Sym.takeError()) {
401 // Lookup failure - report error.
402 return std::move(Err);
405 // No symbol not found. Return 0.
406 return 0;
409 Expected<JITTargetAddress> findSymbolAddressIn(orc::VModuleKey K,
410 const std::string &Name,
411 bool ExportedSymbolsOnly) {
412 if (auto Sym = findSymbolIn(K, Name, ExportedSymbolsOnly)) {
413 // Successful lookup, non-null symbol:
414 if (auto AddrOrErr = Sym.getAddress())
415 return *AddrOrErr;
416 else
417 return AddrOrErr.takeError();
418 } else if (auto Err = Sym.takeError()) {
419 // Lookup failure - report error.
420 return std::move(Err);
423 // Symbol not found. Return 0.
424 return 0;
427 const std::string &getErrorMessage() const { return ErrMsg; }
429 void RegisterJITEventListener(JITEventListener *L) {
430 if (!L)
431 return;
432 EventListeners.push_back(L);
435 void UnregisterJITEventListener(JITEventListener *L) {
436 if (!L)
437 return;
439 auto I = find(reverse(EventListeners), L);
440 if (I != EventListeners.rend()) {
441 std::swap(*I, EventListeners.back());
442 EventListeners.pop_back();
446 private:
447 using ResolverMap =
448 std::map<orc::VModuleKey, std::shared_ptr<orc::SymbolResolver>>;
450 static std::unique_ptr<CompileCallbackMgr>
451 createCompileCallbackManager(TargetMachine &TM, orc::ExecutionSession &ES) {
452 auto CCMgr = createLocalCompileCallbackManager(TM.getTargetTriple(), ES, 0);
453 if (!CCMgr) {
454 // FIXME: It would be good if we could report this somewhere, but we do
455 // have an instance yet.
456 logAllUnhandledErrors(CCMgr.takeError(), errs(), "ORC error: ");
457 return nullptr;
459 return std::move(*CCMgr);
462 static std::unique_ptr<CODLayerT>
463 createCODLayer(orc::ExecutionSession &ES, CompileLayerT &CompileLayer,
464 CompileCallbackMgr *CCMgr,
465 IndirectStubsManagerBuilder IndirectStubsMgrBuilder,
466 ResolverMap &Resolvers) {
467 // If there is no compile callback manager available we can not create a
468 // compile on demand layer.
469 if (!CCMgr)
470 return nullptr;
472 return std::make_unique<CODLayerT>(
473 AcknowledgeORCv1Deprecation, ES, CompileLayer,
474 [&Resolvers](orc::VModuleKey K) {
475 auto ResolverI = Resolvers.find(K);
476 assert(ResolverI != Resolvers.end() && "No resolver for module K");
477 return ResolverI->second;
479 [&Resolvers](orc::VModuleKey K,
480 std::shared_ptr<orc::SymbolResolver> Resolver) {
481 assert(!Resolvers.count(K) && "Resolver already present");
482 Resolvers[K] = std::move(Resolver);
484 [](Function &F) { return std::set<Function *>({&F}); }, *CCMgr,
485 std::move(IndirectStubsMgrBuilder), false);
488 void reportError(Error Err) {
489 // FIXME: Report errors on the execution session.
490 logAllUnhandledErrors(std::move(Err), errs(), "ORC error: ");
493 void notifyFinalized(orc::VModuleKey K,
494 const object::ObjectFile &Obj,
495 const RuntimeDyld::LoadedObjectInfo &LoadedObjInfo) {
496 uint64_t Key = static_cast<uint64_t>(
497 reinterpret_cast<uintptr_t>(Obj.getData().data()));
498 for (auto &Listener : EventListeners)
499 Listener->notifyObjectLoaded(Key, Obj, LoadedObjInfo);
502 void notifyFreed(orc::VModuleKey K, const object::ObjectFile &Obj) {
503 uint64_t Key = static_cast<uint64_t>(
504 reinterpret_cast<uintptr_t>(Obj.getData().data()));
505 for (auto &Listener : EventListeners)
506 Listener->notifyFreeingObject(Key);
509 orc::ExecutionSession ES;
510 std::unique_ptr<CompileCallbackMgr> CCMgr;
512 std::vector<JITEventListener *> EventListeners;
514 DataLayout DL;
515 SectionMemoryManager CCMgrMemMgr;
517 std::unique_ptr<orc::IndirectStubsManager> IndirectStubsMgr;
519 ObjLayerT ObjectLayer;
520 CompileLayerT CompileLayer;
521 std::unique_ptr<CODLayerT> CODLayer;
523 std::map<orc::VModuleKey, std::unique_ptr<detail::GenericLayer>> KeyLayers;
525 orc::LegacyLocalCXXRuntimeOverrides CXXRuntimeOverrides;
526 std::vector<orc::LegacyCtorDtorRunner<OrcCBindingsStack>> IRStaticDestructorRunners;
527 std::string ErrMsg;
529 ResolverMap Resolvers;
532 } // end namespace llvm
534 #endif // LLVM_LIB_EXECUTIONENGINE_ORC_ORCCBINDINGSSTACK_H