xref: /aosp_15_r20/external/llvm/tools/lli/OrcLazyJIT.h (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===--- OrcLazyJIT.h - Basic Orc-based JIT for lazy execution --*- C++ -*-===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // Simple Orc-based JIT. Uses the compile-on-demand layer to break up and
11*9880d681SAndroid Build Coastguard Worker // lazily compile modules.
12*9880d681SAndroid Build Coastguard Worker //
13*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
14*9880d681SAndroid Build Coastguard Worker 
15*9880d681SAndroid Build Coastguard Worker #ifndef LLVM_TOOLS_LLI_ORCLAZYJIT_H
16*9880d681SAndroid Build Coastguard Worker #define LLVM_TOOLS_LLI_ORCLAZYJIT_H
17*9880d681SAndroid Build Coastguard Worker 
18*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/Triple.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/ExecutionEngine/Orc/CompileUtils.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/ExecutionEngine/Orc/IRTransformLayer.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
26*9880d681SAndroid Build Coastguard Worker 
27*9880d681SAndroid Build Coastguard Worker namespace llvm {
28*9880d681SAndroid Build Coastguard Worker 
29*9880d681SAndroid Build Coastguard Worker class OrcLazyJIT {
30*9880d681SAndroid Build Coastguard Worker public:
31*9880d681SAndroid Build Coastguard Worker 
32*9880d681SAndroid Build Coastguard Worker   typedef orc::JITCompileCallbackManager CompileCallbackMgr;
33*9880d681SAndroid Build Coastguard Worker   typedef orc::ObjectLinkingLayer<> ObjLayerT;
34*9880d681SAndroid Build Coastguard Worker   typedef orc::IRCompileLayer<ObjLayerT> CompileLayerT;
35*9880d681SAndroid Build Coastguard Worker   typedef std::function<std::unique_ptr<Module>(std::unique_ptr<Module>)>
36*9880d681SAndroid Build Coastguard Worker     TransformFtor;
37*9880d681SAndroid Build Coastguard Worker   typedef orc::IRTransformLayer<CompileLayerT, TransformFtor> IRDumpLayerT;
38*9880d681SAndroid Build Coastguard Worker   typedef orc::CompileOnDemandLayer<IRDumpLayerT, CompileCallbackMgr> CODLayerT;
39*9880d681SAndroid Build Coastguard Worker   typedef CODLayerT::IndirectStubsManagerBuilderT
40*9880d681SAndroid Build Coastguard Worker     IndirectStubsManagerBuilder;
41*9880d681SAndroid Build Coastguard Worker   typedef CODLayerT::ModuleSetHandleT ModuleHandleT;
42*9880d681SAndroid Build Coastguard Worker 
OrcLazyJIT(std::unique_ptr<TargetMachine> TM,std::unique_ptr<CompileCallbackMgr> CCMgr,IndirectStubsManagerBuilder IndirectStubsMgrBuilder,bool InlineStubs)43*9880d681SAndroid Build Coastguard Worker   OrcLazyJIT(std::unique_ptr<TargetMachine> TM,
44*9880d681SAndroid Build Coastguard Worker              std::unique_ptr<CompileCallbackMgr> CCMgr,
45*9880d681SAndroid Build Coastguard Worker              IndirectStubsManagerBuilder IndirectStubsMgrBuilder,
46*9880d681SAndroid Build Coastguard Worker              bool InlineStubs)
47*9880d681SAndroid Build Coastguard Worker       : TM(std::move(TM)), DL(this->TM->createDataLayout()),
48*9880d681SAndroid Build Coastguard Worker 	CCMgr(std::move(CCMgr)),
49*9880d681SAndroid Build Coastguard Worker 	ObjectLayer(),
50*9880d681SAndroid Build Coastguard Worker         CompileLayer(ObjectLayer, orc::SimpleCompiler(*this->TM)),
51*9880d681SAndroid Build Coastguard Worker         IRDumpLayer(CompileLayer, createDebugDumper()),
52*9880d681SAndroid Build Coastguard Worker         CODLayer(IRDumpLayer, extractSingleFunction, *this->CCMgr,
53*9880d681SAndroid Build Coastguard Worker                  std::move(IndirectStubsMgrBuilder), InlineStubs),
54*9880d681SAndroid Build Coastguard Worker         CXXRuntimeOverrides(
55*9880d681SAndroid Build Coastguard Worker             [this](const std::string &S) { return mangle(S); }) {}
56*9880d681SAndroid Build Coastguard Worker 
~OrcLazyJIT()57*9880d681SAndroid Build Coastguard Worker   ~OrcLazyJIT() {
58*9880d681SAndroid Build Coastguard Worker     // Run any destructors registered with __cxa_atexit.
59*9880d681SAndroid Build Coastguard Worker     CXXRuntimeOverrides.runDestructors();
60*9880d681SAndroid Build Coastguard Worker     // Run any IR destructors.
61*9880d681SAndroid Build Coastguard Worker     for (auto &DtorRunner : IRStaticDestructorRunners)
62*9880d681SAndroid Build Coastguard Worker       DtorRunner.runViaLayer(CODLayer);
63*9880d681SAndroid Build Coastguard Worker   }
64*9880d681SAndroid Build Coastguard Worker 
addModule(std::unique_ptr<Module> M)65*9880d681SAndroid Build Coastguard Worker   ModuleHandleT addModule(std::unique_ptr<Module> M) {
66*9880d681SAndroid Build Coastguard Worker     // Attach a data-layout if one isn't already present.
67*9880d681SAndroid Build Coastguard Worker     if (M->getDataLayout().isDefault())
68*9880d681SAndroid Build Coastguard Worker       M->setDataLayout(DL);
69*9880d681SAndroid Build Coastguard Worker 
70*9880d681SAndroid Build Coastguard Worker     // Record the static constructors and destructors. We have to do this before
71*9880d681SAndroid Build Coastguard Worker     // we hand over ownership of the module to the JIT.
72*9880d681SAndroid Build Coastguard Worker     std::vector<std::string> CtorNames, DtorNames;
73*9880d681SAndroid Build Coastguard Worker     for (auto Ctor : orc::getConstructors(*M))
74*9880d681SAndroid Build Coastguard Worker       CtorNames.push_back(mangle(Ctor.Func->getName()));
75*9880d681SAndroid Build Coastguard Worker     for (auto Dtor : orc::getDestructors(*M))
76*9880d681SAndroid Build Coastguard Worker       DtorNames.push_back(mangle(Dtor.Func->getName()));
77*9880d681SAndroid Build Coastguard Worker 
78*9880d681SAndroid Build Coastguard Worker     // Symbol resolution order:
79*9880d681SAndroid Build Coastguard Worker     //   1) Search the JIT symbols.
80*9880d681SAndroid Build Coastguard Worker     //   2) Check for C++ runtime overrides.
81*9880d681SAndroid Build Coastguard Worker     //   3) Search the host process (LLI)'s symbol table.
82*9880d681SAndroid Build Coastguard Worker     auto Resolver =
83*9880d681SAndroid Build Coastguard Worker       orc::createLambdaResolver(
84*9880d681SAndroid Build Coastguard Worker         [this](const std::string &Name) {
85*9880d681SAndroid Build Coastguard Worker           if (auto Sym = CODLayer.findSymbol(Name, true))
86*9880d681SAndroid Build Coastguard Worker             return Sym.toRuntimeDyldSymbol();
87*9880d681SAndroid Build Coastguard Worker           if (auto Sym = CXXRuntimeOverrides.searchOverrides(Name))
88*9880d681SAndroid Build Coastguard Worker             return Sym;
89*9880d681SAndroid Build Coastguard Worker 
90*9880d681SAndroid Build Coastguard Worker           if (auto Addr =
91*9880d681SAndroid Build Coastguard Worker               RTDyldMemoryManager::getSymbolAddressInProcess(Name))
92*9880d681SAndroid Build Coastguard Worker             return RuntimeDyld::SymbolInfo(Addr, JITSymbolFlags::Exported);
93*9880d681SAndroid Build Coastguard Worker 
94*9880d681SAndroid Build Coastguard Worker           return RuntimeDyld::SymbolInfo(nullptr);
95*9880d681SAndroid Build Coastguard Worker         },
96*9880d681SAndroid Build Coastguard Worker         [](const std::string &Name) {
97*9880d681SAndroid Build Coastguard Worker           return RuntimeDyld::SymbolInfo(nullptr);
98*9880d681SAndroid Build Coastguard Worker         }
99*9880d681SAndroid Build Coastguard Worker       );
100*9880d681SAndroid Build Coastguard Worker 
101*9880d681SAndroid Build Coastguard Worker     // Add the module to the JIT.
102*9880d681SAndroid Build Coastguard Worker     std::vector<std::unique_ptr<Module>> S;
103*9880d681SAndroid Build Coastguard Worker     S.push_back(std::move(M));
104*9880d681SAndroid Build Coastguard Worker     auto H = CODLayer.addModuleSet(std::move(S),
105*9880d681SAndroid Build Coastguard Worker 				   llvm::make_unique<SectionMemoryManager>(),
106*9880d681SAndroid Build Coastguard Worker 				   std::move(Resolver));
107*9880d681SAndroid Build Coastguard Worker 
108*9880d681SAndroid Build Coastguard Worker     // Run the static constructors, and save the static destructor runner for
109*9880d681SAndroid Build Coastguard Worker     // execution when the JIT is torn down.
110*9880d681SAndroid Build Coastguard Worker     orc::CtorDtorRunner<CODLayerT> CtorRunner(std::move(CtorNames), H);
111*9880d681SAndroid Build Coastguard Worker     CtorRunner.runViaLayer(CODLayer);
112*9880d681SAndroid Build Coastguard Worker 
113*9880d681SAndroid Build Coastguard Worker     IRStaticDestructorRunners.emplace_back(std::move(DtorNames), H);
114*9880d681SAndroid Build Coastguard Worker 
115*9880d681SAndroid Build Coastguard Worker     return H;
116*9880d681SAndroid Build Coastguard Worker   }
117*9880d681SAndroid Build Coastguard Worker 
findSymbol(const std::string & Name)118*9880d681SAndroid Build Coastguard Worker   orc::JITSymbol findSymbol(const std::string &Name) {
119*9880d681SAndroid Build Coastguard Worker     return CODLayer.findSymbol(mangle(Name), true);
120*9880d681SAndroid Build Coastguard Worker   }
121*9880d681SAndroid Build Coastguard Worker 
findSymbolIn(ModuleHandleT H,const std::string & Name)122*9880d681SAndroid Build Coastguard Worker   orc::JITSymbol findSymbolIn(ModuleHandleT H, const std::string &Name) {
123*9880d681SAndroid Build Coastguard Worker     return CODLayer.findSymbolIn(H, mangle(Name), true);
124*9880d681SAndroid Build Coastguard Worker   }
125*9880d681SAndroid Build Coastguard Worker 
126*9880d681SAndroid Build Coastguard Worker private:
127*9880d681SAndroid Build Coastguard Worker 
mangle(const std::string & Name)128*9880d681SAndroid Build Coastguard Worker   std::string mangle(const std::string &Name) {
129*9880d681SAndroid Build Coastguard Worker     std::string MangledName;
130*9880d681SAndroid Build Coastguard Worker     {
131*9880d681SAndroid Build Coastguard Worker       raw_string_ostream MangledNameStream(MangledName);
132*9880d681SAndroid Build Coastguard Worker       Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
133*9880d681SAndroid Build Coastguard Worker     }
134*9880d681SAndroid Build Coastguard Worker     return MangledName;
135*9880d681SAndroid Build Coastguard Worker   }
136*9880d681SAndroid Build Coastguard Worker 
extractSingleFunction(Function & F)137*9880d681SAndroid Build Coastguard Worker   static std::set<Function*> extractSingleFunction(Function &F) {
138*9880d681SAndroid Build Coastguard Worker     std::set<Function*> Partition;
139*9880d681SAndroid Build Coastguard Worker     Partition.insert(&F);
140*9880d681SAndroid Build Coastguard Worker     return Partition;
141*9880d681SAndroid Build Coastguard Worker   }
142*9880d681SAndroid Build Coastguard Worker 
143*9880d681SAndroid Build Coastguard Worker   static TransformFtor createDebugDumper();
144*9880d681SAndroid Build Coastguard Worker 
145*9880d681SAndroid Build Coastguard Worker   std::unique_ptr<TargetMachine> TM;
146*9880d681SAndroid Build Coastguard Worker   DataLayout DL;
147*9880d681SAndroid Build Coastguard Worker   SectionMemoryManager CCMgrMemMgr;
148*9880d681SAndroid Build Coastguard Worker 
149*9880d681SAndroid Build Coastguard Worker   std::unique_ptr<CompileCallbackMgr> CCMgr;
150*9880d681SAndroid Build Coastguard Worker   ObjLayerT ObjectLayer;
151*9880d681SAndroid Build Coastguard Worker   CompileLayerT CompileLayer;
152*9880d681SAndroid Build Coastguard Worker   IRDumpLayerT IRDumpLayer;
153*9880d681SAndroid Build Coastguard Worker   CODLayerT CODLayer;
154*9880d681SAndroid Build Coastguard Worker 
155*9880d681SAndroid Build Coastguard Worker   orc::LocalCXXRuntimeOverrides CXXRuntimeOverrides;
156*9880d681SAndroid Build Coastguard Worker   std::vector<orc::CtorDtorRunner<CODLayerT>> IRStaticDestructorRunners;
157*9880d681SAndroid Build Coastguard Worker };
158*9880d681SAndroid Build Coastguard Worker 
159*9880d681SAndroid Build Coastguard Worker int runOrcLazyJIT(std::unique_ptr<Module> M, int ArgC, char* ArgV[]);
160*9880d681SAndroid Build Coastguard Worker 
161*9880d681SAndroid Build Coastguard Worker } // end namespace llvm
162*9880d681SAndroid Build Coastguard Worker 
163*9880d681SAndroid Build Coastguard Worker #endif
164