Line data Source code
1 : //===----- LLJIT.h -- An ORC-based JIT for compiling LLVM IR ----*- C++ -*-===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for 3Bdetails.
7 : //
8 : //===----------------------------------------------------------------------===//
9 : //
10 : // An ORC-based JIT for compiling LLVM IR.
11 : //
12 : //===----------------------------------------------------------------------===//
13 :
14 : #ifndef LLVM_EXECUTIONENGINE_ORC_LLJIT_H
15 : #define LLVM_EXECUTIONENGINE_ORC_LLJIT_H
16 :
17 : #include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h"
18 : #include "llvm/ExecutionEngine/Orc/CompileUtils.h"
19 : #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
20 : #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
21 : #include "llvm/ExecutionEngine/Orc/IRTransformLayer.h"
22 : #include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
23 : #include "llvm/ExecutionEngine/Orc/ObjectTransformLayer.h"
24 : #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
25 : #include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h"
26 : #include "llvm/Support/ThreadPool.h"
27 :
28 : namespace llvm {
29 : namespace orc {
30 :
31 : /// A pre-fabricated ORC JIT stack that can serve as an alternative to MCJIT.
32 : class LLJIT {
33 : public:
34 :
35 : /// Destruct this instance. If a multi-threaded instance, waits for all
36 : /// compile threads to complete.
37 : ~LLJIT();
38 :
39 : /// Create an LLJIT instance.
40 : /// If NumCompileThreads is not equal to zero, creates a multi-threaded
41 : /// LLJIT with the given number of compile threads.
42 : static Expected<std::unique_ptr<LLJIT>>
43 : Create(JITTargetMachineBuilder JTMB, DataLayout DL,
44 : unsigned NumCompileThreads = 0);
45 :
46 : /// Returns the ExecutionSession for this instance.
47 : ExecutionSession &getExecutionSession() { return *ES; }
48 :
49 : /// Returns a reference to the JITDylib representing the JIT'd main program.
50 0 : JITDylib &getMainJITDylib() { return Main; }
51 :
52 : /// Convenience method for defining an absolute symbol.
53 : Error defineAbsolute(StringRef Name, JITEvaluatedSymbol Address);
54 :
55 : /// Convenience method for defining an
56 :
57 : /// Adds an IR module to the given JITDylib.
58 : Error addIRModule(JITDylib &JD, ThreadSafeModule TSM);
59 :
60 : /// Adds an IR module to the Main JITDylib.
61 : Error addIRModule(ThreadSafeModule TSM) {
62 : return addIRModule(Main, std::move(TSM));
63 : }
64 :
65 : /// Adds an object file to the given JITDylib.
66 : Error addObjectFile(JITDylib &JD, std::unique_ptr<MemoryBuffer> Obj);
67 :
68 : /// Adds an object file to the given JITDylib.
69 4 : Error addObjectFile(std::unique_ptr<MemoryBuffer> Obj) {
70 4 : return addObjectFile(Main, std::move(Obj));
71 : }
72 :
73 : /// Look up a symbol in JITDylib JD by the symbol's linker-mangled name (to
74 : /// look up symbols based on their IR name use the lookup function instead).
75 : Expected<JITEvaluatedSymbol> lookupLinkerMangled(JITDylib &JD,
76 : StringRef Name);
77 :
78 : /// Look up a symbol in the main JITDylib by the symbol's linker-mangled name
79 : /// (to look up symbols based on their IR name use the lookup function
80 : /// instead).
81 : Expected<JITEvaluatedSymbol> lookupLinkerMangled(StringRef Name) {
82 : return lookupLinkerMangled(Main, Name);
83 : }
84 :
85 : /// Look up a symbol in JITDylib JD based on its IR symbol name.
86 13 : Expected<JITEvaluatedSymbol> lookup(JITDylib &JD, StringRef UnmangledName) {
87 13 : return lookupLinkerMangled(JD, mangle(UnmangledName));
88 : }
89 :
90 : /// Look up a symbol in the main JITDylib based on its IR symbol name.
91 : Expected<JITEvaluatedSymbol> lookup(StringRef UnmangledName) {
92 13 : return lookup(Main, UnmangledName);
93 : }
94 :
95 : /// Runs all not-yet-run static constructors.
96 12 : Error runConstructors() { return CtorRunner.run(); }
97 :
98 : /// Runs all not-yet-run static destructors.
99 12 : Error runDestructors() { return DtorRunner.run(); }
100 :
101 : /// Returns a reference to the ObjLinkingLayer
102 : RTDyldObjectLinkingLayer &getObjLinkingLayer() { return ObjLinkingLayer; }
103 :
104 : protected:
105 :
106 : /// Create an LLJIT instance with a single compile thread.
107 : LLJIT(std::unique_ptr<ExecutionSession> ES, std::unique_ptr<TargetMachine> TM,
108 : DataLayout DL);
109 :
110 : /// Create an LLJIT instance with multiple compile threads.
111 : LLJIT(std::unique_ptr<ExecutionSession> ES, JITTargetMachineBuilder JTMB,
112 : DataLayout DL, unsigned NumCompileThreads);
113 :
114 : std::string mangle(StringRef UnmangledName);
115 :
116 : Error applyDataLayout(Module &M);
117 :
118 : void recordCtorDtors(Module &M);
119 :
120 : std::unique_ptr<ExecutionSession> ES;
121 : JITDylib &Main;
122 :
123 : DataLayout DL;
124 : std::unique_ptr<ThreadPool> CompileThreads;
125 :
126 : RTDyldObjectLinkingLayer ObjLinkingLayer;
127 : IRCompileLayer CompileLayer;
128 :
129 : CtorDtorRunner CtorRunner, DtorRunner;
130 : };
131 :
132 : /// An extended version of LLJIT that supports lazy function-at-a-time
133 : /// compilation of LLVM IR.
134 : class LLLazyJIT : public LLJIT {
135 : public:
136 :
137 : /// Create an LLLazyJIT instance.
138 : /// If NumCompileThreads is not equal to zero, creates a multi-threaded
139 : /// LLLazyJIT with the given number of compile threads.
140 : static Expected<std::unique_ptr<LLLazyJIT>>
141 : Create(JITTargetMachineBuilder JTMB, DataLayout DL,
142 : unsigned NumCompileThreads = 0);
143 :
144 : /// Set an IR transform (e.g. pass manager pipeline) to run on each function
145 : /// when it is compiled.
146 13 : void setLazyCompileTransform(IRTransformLayer::TransformFunction Transform) {
147 13 : TransformLayer.setTransform(std::move(Transform));
148 13 : }
149 :
150 : /// Sets the partition function.
151 : void
152 1 : setPartitionFunction(CompileOnDemandLayer::PartitionFunction Partition) {
153 2 : CODLayer.setPartitionFunction(std::move(Partition));
154 1 : }
155 :
156 : /// Add a module to be lazily compiled to JITDylib JD.
157 : Error addLazyIRModule(JITDylib &JD, ThreadSafeModule M);
158 :
159 : /// Add a module to be lazily compiled to the main JITDylib.
160 14 : Error addLazyIRModule(ThreadSafeModule M) {
161 14 : return addLazyIRModule(Main, std::move(M));
162 : }
163 :
164 : private:
165 :
166 : // Create a single-threaded LLLazyJIT instance.
167 : LLLazyJIT(std::unique_ptr<ExecutionSession> ES,
168 : std::unique_ptr<TargetMachine> TM, DataLayout DL,
169 : std::unique_ptr<LazyCallThroughManager> LCTMgr,
170 : std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder);
171 :
172 : // Create a multi-threaded LLLazyJIT instance.
173 : LLLazyJIT(std::unique_ptr<ExecutionSession> ES, JITTargetMachineBuilder JTMB,
174 : DataLayout DL, unsigned NumCompileThreads,
175 : std::unique_ptr<LazyCallThroughManager> LCTMgr,
176 : std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder);
177 :
178 : std::unique_ptr<LazyCallThroughManager> LCTMgr;
179 : std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder;
180 :
181 : IRTransformLayer TransformLayer;
182 : CompileOnDemandLayer CODLayer;
183 : };
184 :
185 : } // End namespace orc
186 : } // End namespace llvm
187 :
188 : #endif // LLVM_EXECUTIONENGINE_ORC_LLJIT_H
|