1 #include "llvm/ADT/StringRef.h"
2 #include "llvm/Support/CommandLine.h"
3 #include "llvm/Support/Error.h"
4 #include "llvm/Support/InitLLVM.h"
5 #include "llvm/Support/TargetSelect.h"
6 
7 #include "ThinLtoJIT.h"
8 
9 #include <string>
10 #include <vector>
11 
12 using namespace llvm;
13 
14 static cl::list<std::string>
15     InputFiles(cl::Positional, cl::OneOrMore,
16                cl::desc("<bitcode files or global index>"));
17 
18 static cl::list<std::string> InputArgs("args", cl::Positional,
19                                        cl::desc("<program arguments>..."),
20                                        cl::ZeroOrMore, cl::PositionalEatsArgs);
21 
22 static cl::opt<unsigned> CompileThreads("compile-threads", cl::Optional,
23                                         cl::desc("Number of compile threads"),
24                                         cl::init(4));
25 
26 static cl::opt<unsigned> LoadThreads("load-threads", cl::Optional,
27                                      cl::desc("Number of module load threads"),
28                                      cl::init(8));
29 
30 static cl::opt<unsigned>
31     LookaheadLevels("lookahead", cl::Optional,
32                     cl::desc("Calls to look ahead of execution"), cl::init(4));
33 
34 static cl::opt<unsigned> DiscoveryFlagsBucketSize(
35     "discovery-flag-bucket-size", cl::Optional,
36     cl::desc("Flags per bucket (rounds up to memory pages)"), cl::init(4096));
37 
38 static cl::opt<orc::ThinLtoJIT::ExplicitMemoryBarrier>
39     MemFence("mem-fence",
40              cl::desc("Control memory fences for cache synchronization"),
41              cl::init(orc::ThinLtoJIT::NeverFence),
42              cl::values(clEnumValN(orc::ThinLtoJIT::NeverFence, "never",
43                                    "No use of memory fences"),
44                         clEnumValN(orc::ThinLtoJIT::FenceStaticCode, "static",
45                                    "Use of memory fences in static code only"),
46                         clEnumValN(orc::ThinLtoJIT::FenceJITedCode, "jited",
47                                    "Install memory fences in JITed code only"),
48                         clEnumValN(orc::ThinLtoJIT::AlwaysFence, "always",
49                                    "Always use of memory fences")));
50 
51 static cl::opt<bool>
52     AllowNudge("allow-nudge",
53                cl::desc("Allow the symbol generator to nudge symbols into "
54                         "discovery even though they haven't been reached"),
55                cl::init(false));
56 
57 static cl::opt<bool> PrintStats("print-stats",
58                                 cl::desc("Print module stats on shutdown"),
59                                 cl::init(false));
60 
main(int argc,char * argv[])61 int main(int argc, char *argv[]) {
62   InitLLVM X(argc, argv);
63   InitializeNativeTarget();
64   InitializeNativeTargetAsmPrinter();
65   cl::ParseCommandLineOptions(argc, argv, "ThinLtoJIT");
66 
67   Error Err = Error::success();
68   auto atLeastOne = [](unsigned N) { return std::max(1u, N); };
69 
70   orc::ThinLtoJIT Jit(InputFiles, "main", atLeastOne(LookaheadLevels),
71                       atLeastOne(CompileThreads), atLeastOne(LoadThreads),
72                       DiscoveryFlagsBucketSize, MemFence, AllowNudge,
73                       PrintStats, Err);
74   if (Err) {
75     logAllUnhandledErrors(std::move(Err), errs(), "[ThinLtoJIT] ");
76     exit(1);
77   }
78 
79   ExitOnError ExitOnErr;
80   ExitOnErr.setBanner("[ThinLtoJIT] ");
81 
82   return ExitOnErr(Jit.main(InputArgs));
83 }
84