1 #ifndef LLVM_EXAMPLES_THINLTOJIT_THINLTOJIT_H
2 #define LLVM_EXAMPLES_THINLTOJIT_THINLTOJIT_H
3 
4 #include "llvm/ADT/StringRef.h"
5 #include "llvm/ADT/Triple.h"
6 #include "llvm/ExecutionEngine/Orc/Core.h"
7 #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
8 #include "llvm/ExecutionEngine/Orc/SymbolStringPool.h"
9 #include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h"
10 #include "llvm/IR/DataLayout.h"
11 #include "llvm/Support/Error.h"
12 #include "llvm/Support/ThreadPool.h"
13 
14 #include <functional>
15 #include <memory>
16 #include <string>
17 #include <thread>
18 #include <vector>
19 
20 namespace llvm {
21 namespace orc {
22 
23 class ThinLtoDiscoveryThread;
24 class ThinLtoInstrumentationLayer;
25 class ThinLtoModuleIndex;
26 
27 class CompileOnDemandLayer;
28 class IRCompileLayer;
29 class RTDyldObjectLinkingLayer;
30 
31 class JITDylib;
32 class JITTargetMachineBuilder;
33 class LazyCallThroughManager;
34 class MangleAndInterner;
35 
36 class ThinLtoJIT {
37 public:
38   using AddModuleFunction = std::function<Error(ThreadSafeModule)>;
39 
40   enum ExplicitMemoryBarrier {
41     NeverFence = 0,
42     FenceStaticCode = 1,
43     FenceJITedCode = 2,
44     AlwaysFence = 3
45   };
46 
47   ThinLtoJIT(ArrayRef<std::string> InputFiles, StringRef MainFunctionName,
48              unsigned LookaheadLevels, unsigned NumCompileThreads,
49              unsigned NumLoadThreads, unsigned DiscoveryFlagsPerBucket,
50              ExplicitMemoryBarrier MemFence, bool AllowNudgeIntoDiscovery,
51              bool PrintStats, Error &Err);
52   ~ThinLtoJIT();
53 
54   ThinLtoJIT(const ThinLtoJIT &) = delete;
55   ThinLtoJIT &operator=(const ThinLtoJIT &) = delete;
56   ThinLtoJIT(ThinLtoJIT &&) = delete;
57   ThinLtoJIT &operator=(ThinLtoJIT &&) = delete;
58 
main(ArrayRef<std::string> Args)59   Expected<int> main(ArrayRef<std::string> Args) {
60     auto MainSym = ES.lookup({MainJD}, MainFunctionMangled);
61     if (!MainSym)
62       return MainSym.takeError();
63 
64     using MainFn = int(int, char *[]);
65     auto Main = jitTargetAddressToFunction<MainFn *>(MainSym->getAddress());
66 
67     return runAsMain(Main, Args, StringRef("ThinLtoJIT"));
68   }
69 
70 private:
71   ExecutionSession ES;
72   DataLayout DL{""};
73 
74   JITDylib *MainJD;
75   SymbolStringPtr MainFunctionMangled;
76   std::unique_ptr<ThreadPool> CompileThreads;
77   std::unique_ptr<ThinLtoModuleIndex> GlobalIndex;
78 
79   AddModuleFunction AddModule;
80   std::unique_ptr<RTDyldObjectLinkingLayer> ObjLinkingLayer;
81   std::unique_ptr<IRCompileLayer> CompileLayer;
82   std::unique_ptr<ThinLtoInstrumentationLayer> InstrumentationLayer;
83   std::unique_ptr<CompileOnDemandLayer> OnDemandLayer;
84 
85   std::atomic<bool> JitRunning;
86   std::thread DiscoveryThread;
87   std::unique_ptr<ThinLtoDiscoveryThread> DiscoveryThreadWorker;
88 
89   std::unique_ptr<MangleAndInterner> Mangle;
90   std::unique_ptr<LazyCallThroughManager> CallThroughManager;
91 
92   void setupLayers(JITTargetMachineBuilder JTMB, unsigned NumCompileThreads,
93                    unsigned DiscoveryFlagsPerBucket,
94                    ExplicitMemoryBarrier MemFence);
95   Error setupJITDylib(JITDylib *JD, bool AllowNudge, bool PrintStats);
96   void setupDiscovery(JITDylib *MainJD, unsigned LookaheadLevels,
97                       bool PrintStats);
98   Expected<ThreadSafeModule> setupMainModule(StringRef MainFunction);
99   Expected<JITTargetMachineBuilder> setupTargetUtils(Module *M);
100   Error applyDataLayout(Module *M);
101 
exitOnLazyCallThroughFailure()102   static void exitOnLazyCallThroughFailure() {
103     errs() << "Compilation failed. Aborting.\n";
104     exit(1);
105   }
106 };
107 
108 } // namespace orc
109 } // namespace llvm
110 
111 #endif
112