xref: /aosp_15_r20/external/llvm/tools/lli/OrcLazyJIT.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===------ OrcLazyJIT.cpp - Basic Orc-based JIT for lazy execution -------===//
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 #include "OrcLazyJIT.h"
11*9880d681SAndroid Build Coastguard Worker #include "llvm/ExecutionEngine/Orc/OrcABISupport.h"
12*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
13*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/DynamicLibrary.h"
14*9880d681SAndroid Build Coastguard Worker #include <cstdio>
15*9880d681SAndroid Build Coastguard Worker #include <system_error>
16*9880d681SAndroid Build Coastguard Worker 
17*9880d681SAndroid Build Coastguard Worker using namespace llvm;
18*9880d681SAndroid Build Coastguard Worker 
19*9880d681SAndroid Build Coastguard Worker namespace {
20*9880d681SAndroid Build Coastguard Worker 
21*9880d681SAndroid Build Coastguard Worker   enum class DumpKind { NoDump, DumpFuncsToStdOut, DumpModsToStdErr,
22*9880d681SAndroid Build Coastguard Worker                         DumpModsToDisk };
23*9880d681SAndroid Build Coastguard Worker 
24*9880d681SAndroid Build Coastguard Worker   cl::opt<DumpKind> OrcDumpKind("orc-lazy-debug",
25*9880d681SAndroid Build Coastguard Worker                                 cl::desc("Debug dumping for the orc-lazy JIT."),
26*9880d681SAndroid Build Coastguard Worker                                 cl::init(DumpKind::NoDump),
27*9880d681SAndroid Build Coastguard Worker                                 cl::values(
28*9880d681SAndroid Build Coastguard Worker                                   clEnumValN(DumpKind::NoDump, "no-dump",
29*9880d681SAndroid Build Coastguard Worker                                              "Don't dump anything."),
30*9880d681SAndroid Build Coastguard Worker                                   clEnumValN(DumpKind::DumpFuncsToStdOut,
31*9880d681SAndroid Build Coastguard Worker                                              "funcs-to-stdout",
32*9880d681SAndroid Build Coastguard Worker                                              "Dump function names to stdout."),
33*9880d681SAndroid Build Coastguard Worker                                   clEnumValN(DumpKind::DumpModsToStdErr,
34*9880d681SAndroid Build Coastguard Worker                                              "mods-to-stderr",
35*9880d681SAndroid Build Coastguard Worker                                              "Dump modules to stderr."),
36*9880d681SAndroid Build Coastguard Worker                                   clEnumValN(DumpKind::DumpModsToDisk,
37*9880d681SAndroid Build Coastguard Worker                                              "mods-to-disk",
38*9880d681SAndroid Build Coastguard Worker                                              "Dump modules to the current "
39*9880d681SAndroid Build Coastguard Worker                                              "working directory. (WARNING: "
40*9880d681SAndroid Build Coastguard Worker                                              "will overwrite existing files)."),
41*9880d681SAndroid Build Coastguard Worker                                   clEnumValEnd),
42*9880d681SAndroid Build Coastguard Worker                                 cl::Hidden);
43*9880d681SAndroid Build Coastguard Worker 
44*9880d681SAndroid Build Coastguard Worker   cl::opt<bool> OrcInlineStubs("orc-lazy-inline-stubs",
45*9880d681SAndroid Build Coastguard Worker                                cl::desc("Try to inline stubs"),
46*9880d681SAndroid Build Coastguard Worker                                cl::init(true), cl::Hidden);
47*9880d681SAndroid Build Coastguard Worker }
48*9880d681SAndroid Build Coastguard Worker 
createDebugDumper()49*9880d681SAndroid Build Coastguard Worker OrcLazyJIT::TransformFtor OrcLazyJIT::createDebugDumper() {
50*9880d681SAndroid Build Coastguard Worker 
51*9880d681SAndroid Build Coastguard Worker   switch (OrcDumpKind) {
52*9880d681SAndroid Build Coastguard Worker   case DumpKind::NoDump:
53*9880d681SAndroid Build Coastguard Worker     return [](std::unique_ptr<Module> M) { return M; };
54*9880d681SAndroid Build Coastguard Worker 
55*9880d681SAndroid Build Coastguard Worker   case DumpKind::DumpFuncsToStdOut:
56*9880d681SAndroid Build Coastguard Worker     return [](std::unique_ptr<Module> M) {
57*9880d681SAndroid Build Coastguard Worker       printf("[ ");
58*9880d681SAndroid Build Coastguard Worker 
59*9880d681SAndroid Build Coastguard Worker       for (const auto &F : *M) {
60*9880d681SAndroid Build Coastguard Worker         if (F.isDeclaration())
61*9880d681SAndroid Build Coastguard Worker           continue;
62*9880d681SAndroid Build Coastguard Worker 
63*9880d681SAndroid Build Coastguard Worker         if (F.hasName()) {
64*9880d681SAndroid Build Coastguard Worker           std::string Name(F.getName());
65*9880d681SAndroid Build Coastguard Worker           printf("%s ", Name.c_str());
66*9880d681SAndroid Build Coastguard Worker         } else
67*9880d681SAndroid Build Coastguard Worker           printf("<anon> ");
68*9880d681SAndroid Build Coastguard Worker       }
69*9880d681SAndroid Build Coastguard Worker 
70*9880d681SAndroid Build Coastguard Worker       printf("]\n");
71*9880d681SAndroid Build Coastguard Worker       return M;
72*9880d681SAndroid Build Coastguard Worker     };
73*9880d681SAndroid Build Coastguard Worker 
74*9880d681SAndroid Build Coastguard Worker   case DumpKind::DumpModsToStdErr:
75*9880d681SAndroid Build Coastguard Worker     return [](std::unique_ptr<Module> M) {
76*9880d681SAndroid Build Coastguard Worker              dbgs() << "----- Module Start -----\n" << *M
77*9880d681SAndroid Build Coastguard Worker                     << "----- Module End -----\n";
78*9880d681SAndroid Build Coastguard Worker 
79*9880d681SAndroid Build Coastguard Worker              return M;
80*9880d681SAndroid Build Coastguard Worker            };
81*9880d681SAndroid Build Coastguard Worker 
82*9880d681SAndroid Build Coastguard Worker   case DumpKind::DumpModsToDisk:
83*9880d681SAndroid Build Coastguard Worker     return [](std::unique_ptr<Module> M) {
84*9880d681SAndroid Build Coastguard Worker              std::error_code EC;
85*9880d681SAndroid Build Coastguard Worker              raw_fd_ostream Out(M->getModuleIdentifier() + ".ll", EC,
86*9880d681SAndroid Build Coastguard Worker                                 sys::fs::F_Text);
87*9880d681SAndroid Build Coastguard Worker              if (EC) {
88*9880d681SAndroid Build Coastguard Worker                errs() << "Couldn't open " << M->getModuleIdentifier()
89*9880d681SAndroid Build Coastguard Worker                       << " for dumping.\nError:" << EC.message() << "\n";
90*9880d681SAndroid Build Coastguard Worker                exit(1);
91*9880d681SAndroid Build Coastguard Worker              }
92*9880d681SAndroid Build Coastguard Worker              Out << *M;
93*9880d681SAndroid Build Coastguard Worker              return M;
94*9880d681SAndroid Build Coastguard Worker            };
95*9880d681SAndroid Build Coastguard Worker   }
96*9880d681SAndroid Build Coastguard Worker   llvm_unreachable("Unknown DumpKind");
97*9880d681SAndroid Build Coastguard Worker }
98*9880d681SAndroid Build Coastguard Worker 
99*9880d681SAndroid Build Coastguard Worker // Defined in lli.cpp.
100*9880d681SAndroid Build Coastguard Worker CodeGenOpt::Level getOptLevel();
101*9880d681SAndroid Build Coastguard Worker 
102*9880d681SAndroid Build Coastguard Worker 
103*9880d681SAndroid Build Coastguard Worker template <typename PtrTy>
fromTargetAddress(orc::TargetAddress Addr)104*9880d681SAndroid Build Coastguard Worker static PtrTy fromTargetAddress(orc::TargetAddress Addr) {
105*9880d681SAndroid Build Coastguard Worker   return reinterpret_cast<PtrTy>(static_cast<uintptr_t>(Addr));
106*9880d681SAndroid Build Coastguard Worker }
107*9880d681SAndroid Build Coastguard Worker 
runOrcLazyJIT(std::unique_ptr<Module> M,int ArgC,char * ArgV[])108*9880d681SAndroid Build Coastguard Worker int llvm::runOrcLazyJIT(std::unique_ptr<Module> M, int ArgC, char* ArgV[]) {
109*9880d681SAndroid Build Coastguard Worker   // Add the program's symbols into the JIT's search space.
110*9880d681SAndroid Build Coastguard Worker   if (sys::DynamicLibrary::LoadLibraryPermanently(nullptr)) {
111*9880d681SAndroid Build Coastguard Worker     errs() << "Error loading program symbols.\n";
112*9880d681SAndroid Build Coastguard Worker     return 1;
113*9880d681SAndroid Build Coastguard Worker   }
114*9880d681SAndroid Build Coastguard Worker 
115*9880d681SAndroid Build Coastguard Worker   // Grab a target machine and try to build a factory function for the
116*9880d681SAndroid Build Coastguard Worker   // target-specific Orc callback manager.
117*9880d681SAndroid Build Coastguard Worker   EngineBuilder EB;
118*9880d681SAndroid Build Coastguard Worker   EB.setOptLevel(getOptLevel());
119*9880d681SAndroid Build Coastguard Worker   auto TM = std::unique_ptr<TargetMachine>(EB.selectTarget());
120*9880d681SAndroid Build Coastguard Worker   Triple T(TM->getTargetTriple());
121*9880d681SAndroid Build Coastguard Worker   auto CompileCallbackMgr = orc::createLocalCompileCallbackManager(T, 0);
122*9880d681SAndroid Build Coastguard Worker 
123*9880d681SAndroid Build Coastguard Worker   // If we couldn't build the factory function then there must not be a callback
124*9880d681SAndroid Build Coastguard Worker   // manager for this target. Bail out.
125*9880d681SAndroid Build Coastguard Worker   if (!CompileCallbackMgr) {
126*9880d681SAndroid Build Coastguard Worker     errs() << "No callback manager available for target '"
127*9880d681SAndroid Build Coastguard Worker            << TM->getTargetTriple().str() << "'.\n";
128*9880d681SAndroid Build Coastguard Worker     return 1;
129*9880d681SAndroid Build Coastguard Worker   }
130*9880d681SAndroid Build Coastguard Worker 
131*9880d681SAndroid Build Coastguard Worker   auto IndirectStubsMgrBuilder = orc::createLocalIndirectStubsManagerBuilder(T);
132*9880d681SAndroid Build Coastguard Worker 
133*9880d681SAndroid Build Coastguard Worker   // If we couldn't build a stubs-manager-builder for this target then bail out.
134*9880d681SAndroid Build Coastguard Worker   if (!IndirectStubsMgrBuilder) {
135*9880d681SAndroid Build Coastguard Worker     errs() << "No indirect stubs manager available for target '"
136*9880d681SAndroid Build Coastguard Worker            << TM->getTargetTriple().str() << "'.\n";
137*9880d681SAndroid Build Coastguard Worker     return 1;
138*9880d681SAndroid Build Coastguard Worker   }
139*9880d681SAndroid Build Coastguard Worker 
140*9880d681SAndroid Build Coastguard Worker   // Everything looks good. Build the JIT.
141*9880d681SAndroid Build Coastguard Worker   OrcLazyJIT J(std::move(TM), std::move(CompileCallbackMgr),
142*9880d681SAndroid Build Coastguard Worker                std::move(IndirectStubsMgrBuilder),
143*9880d681SAndroid Build Coastguard Worker                OrcInlineStubs);
144*9880d681SAndroid Build Coastguard Worker 
145*9880d681SAndroid Build Coastguard Worker   // Add the module, look up main and run it.
146*9880d681SAndroid Build Coastguard Worker   auto MainHandle = J.addModule(std::move(M));
147*9880d681SAndroid Build Coastguard Worker   auto MainSym = J.findSymbolIn(MainHandle, "main");
148*9880d681SAndroid Build Coastguard Worker 
149*9880d681SAndroid Build Coastguard Worker   if (!MainSym) {
150*9880d681SAndroid Build Coastguard Worker     errs() << "Could not find main function.\n";
151*9880d681SAndroid Build Coastguard Worker     return 1;
152*9880d681SAndroid Build Coastguard Worker   }
153*9880d681SAndroid Build Coastguard Worker 
154*9880d681SAndroid Build Coastguard Worker   typedef int (*MainFnPtr)(int, char*[]);
155*9880d681SAndroid Build Coastguard Worker   auto Main = fromTargetAddress<MainFnPtr>(MainSym.getAddress());
156*9880d681SAndroid Build Coastguard Worker   return Main(ArgC, ArgV);
157*9880d681SAndroid Build Coastguard Worker }
158*9880d681SAndroid Build Coastguard Worker 
159