[Alignment][NFC] Use Align with TargetLowering::setMinFunctionAlignment
[llvm-core.git] / include / llvm / ExecutionEngine / Orc / LLJIT.h
blobb1e47d77557c5117455b4518e5fd6f642e7f1af0
1 //===----- LLJIT.h -- An ORC-based JIT for compiling LLVM IR ----*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // An ORC-based JIT for compiling LLVM IR.
11 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_EXECUTIONENGINE_ORC_LLJIT_H
14 #define LLVM_EXECUTIONENGINE_ORC_LLJIT_H
16 #include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h"
17 #include "llvm/ExecutionEngine/Orc/CompileUtils.h"
18 #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
19 #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
20 #include "llvm/ExecutionEngine/Orc/IRTransformLayer.h"
21 #include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
22 #include "llvm/ExecutionEngine/Orc/ObjectTransformLayer.h"
23 #include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h"
24 #include "llvm/Support/ThreadPool.h"
26 namespace llvm {
27 namespace orc {
29 class LLJITBuilderState;
30 class LLLazyJITBuilderState;
32 /// A pre-fabricated ORC JIT stack that can serve as an alternative to MCJIT.
33 ///
34 /// Create instances using LLJITBuilder.
35 class LLJIT {
36 template <typename, typename, typename> friend class LLJITBuilderSetters;
38 public:
39 static Expected<std::unique_ptr<LLJIT>> Create(LLJITBuilderState &S);
41 /// Destruct this instance. If a multi-threaded instance, waits for all
42 /// compile threads to complete.
43 ~LLJIT();
45 /// Returns the ExecutionSession for this instance.
46 ExecutionSession &getExecutionSession() { return *ES; }
48 /// Returns a reference to the DataLayout for this instance.
49 const DataLayout &getDataLayout() const { return DL; }
51 /// Returns a reference to the JITDylib representing the JIT'd main program.
52 JITDylib &getMainJITDylib() { return Main; }
54 /// Returns the JITDylib with the given name, or nullptr if no JITDylib with
55 /// that name exists.
56 JITDylib *getJITDylibByName(StringRef Name) {
57 return ES->getJITDylibByName(Name);
60 /// Create a new JITDylib with the given name and return a reference to it.
61 ///
62 /// JITDylib names must be unique. If the given name is derived from user
63 /// input or elsewhere in the environment then the client should check
64 /// (e.g. by calling getJITDylibByName) that the given name is not already in
65 /// use.
66 JITDylib &createJITDylib(std::string Name) {
67 return ES->createJITDylib(std::move(Name));
70 /// Convenience method for defining an absolute symbol.
71 Error defineAbsolute(StringRef Name, JITEvaluatedSymbol Address);
73 /// Adds an IR module to the given JITDylib.
74 Error addIRModule(JITDylib &JD, ThreadSafeModule TSM);
76 /// Adds an IR module to the Main JITDylib.
77 Error addIRModule(ThreadSafeModule TSM) {
78 return addIRModule(Main, std::move(TSM));
81 /// Adds an object file to the given JITDylib.
82 Error addObjectFile(JITDylib &JD, std::unique_ptr<MemoryBuffer> Obj);
84 /// Adds an object file to the given JITDylib.
85 Error addObjectFile(std::unique_ptr<MemoryBuffer> Obj) {
86 return addObjectFile(Main, std::move(Obj));
89 /// Look up a symbol in JITDylib JD by the symbol's linker-mangled name (to
90 /// look up symbols based on their IR name use the lookup function instead).
91 Expected<JITEvaluatedSymbol> lookupLinkerMangled(JITDylib &JD,
92 StringRef Name);
94 /// Look up a symbol in the main JITDylib by the symbol's linker-mangled name
95 /// (to look up symbols based on their IR name use the lookup function
96 /// instead).
97 Expected<JITEvaluatedSymbol> lookupLinkerMangled(StringRef Name) {
98 return lookupLinkerMangled(Main, Name);
101 /// Look up a symbol in JITDylib JD based on its IR symbol name.
102 Expected<JITEvaluatedSymbol> lookup(JITDylib &JD, StringRef UnmangledName) {
103 return lookupLinkerMangled(JD, mangle(UnmangledName));
106 /// Look up a symbol in the main JITDylib based on its IR symbol name.
107 Expected<JITEvaluatedSymbol> lookup(StringRef UnmangledName) {
108 return lookup(Main, UnmangledName);
111 /// Runs all not-yet-run static constructors.
112 Error runConstructors() { return CtorRunner.run(); }
114 /// Runs all not-yet-run static destructors.
115 Error runDestructors() { return DtorRunner.run(); }
117 /// Returns a reference to the ObjLinkingLayer
118 ObjectLayer &getObjLinkingLayer() { return *ObjLinkingLayer; }
120 protected:
121 static std::unique_ptr<ObjectLayer>
122 createObjectLinkingLayer(LLJITBuilderState &S, ExecutionSession &ES);
124 static Expected<IRCompileLayer::CompileFunction>
125 createCompileFunction(LLJITBuilderState &S, JITTargetMachineBuilder JTMB);
127 /// Create an LLJIT instance with a single compile thread.
128 LLJIT(LLJITBuilderState &S, Error &Err);
130 std::string mangle(StringRef UnmangledName);
132 Error applyDataLayout(Module &M);
134 void recordCtorDtors(Module &M);
136 std::unique_ptr<ExecutionSession> ES;
137 JITDylib &Main;
139 DataLayout DL;
140 std::unique_ptr<ThreadPool> CompileThreads;
142 std::unique_ptr<ObjectLayer> ObjLinkingLayer;
143 std::unique_ptr<IRCompileLayer> CompileLayer;
145 CtorDtorRunner CtorRunner, DtorRunner;
148 /// An extended version of LLJIT that supports lazy function-at-a-time
149 /// compilation of LLVM IR.
150 class LLLazyJIT : public LLJIT {
151 template <typename, typename, typename> friend class LLJITBuilderSetters;
153 public:
155 /// Set an IR transform (e.g. pass manager pipeline) to run on each function
156 /// when it is compiled.
157 void setLazyCompileTransform(IRTransformLayer::TransformFunction Transform) {
158 TransformLayer->setTransform(std::move(Transform));
161 /// Sets the partition function.
162 void
163 setPartitionFunction(CompileOnDemandLayer::PartitionFunction Partition) {
164 CODLayer->setPartitionFunction(std::move(Partition));
167 /// Add a module to be lazily compiled to JITDylib JD.
168 Error addLazyIRModule(JITDylib &JD, ThreadSafeModule M);
170 /// Add a module to be lazily compiled to the main JITDylib.
171 Error addLazyIRModule(ThreadSafeModule M) {
172 return addLazyIRModule(Main, std::move(M));
175 private:
177 // Create a single-threaded LLLazyJIT instance.
178 LLLazyJIT(LLLazyJITBuilderState &S, Error &Err);
180 std::unique_ptr<LazyCallThroughManager> LCTMgr;
181 std::unique_ptr<IRTransformLayer> TransformLayer;
182 std::unique_ptr<CompileOnDemandLayer> CODLayer;
185 class LLJITBuilderState {
186 public:
187 using ObjectLinkingLayerCreator = std::function<std::unique_ptr<ObjectLayer>(
188 ExecutionSession &, const Triple &TT)>;
190 using CompileFunctionCreator =
191 std::function<Expected<IRCompileLayer::CompileFunction>(
192 JITTargetMachineBuilder JTMB)>;
194 std::unique_ptr<ExecutionSession> ES;
195 Optional<JITTargetMachineBuilder> JTMB;
196 ObjectLinkingLayerCreator CreateObjectLinkingLayer;
197 CompileFunctionCreator CreateCompileFunction;
198 unsigned NumCompileThreads = 0;
200 /// Called prior to JIT class construcion to fix up defaults.
201 Error prepareForConstruction();
204 template <typename JITType, typename SetterImpl, typename State>
205 class LLJITBuilderSetters {
206 public:
207 /// Set the JITTargetMachineBuilder for this instance.
209 /// If this method is not called, JITTargetMachineBuilder::detectHost will be
210 /// used to construct a default target machine builder for the host platform.
211 SetterImpl &setJITTargetMachineBuilder(JITTargetMachineBuilder JTMB) {
212 impl().JTMB = std::move(JTMB);
213 return impl();
216 /// Return a reference to the JITTargetMachineBuilder.
218 Optional<JITTargetMachineBuilder> &getJITTargetMachineBuilder() {
219 return impl().JTMB;
222 /// Set an ObjectLinkingLayer creation function.
224 /// If this method is not called, a default creation function will be used
225 /// that will construct an RTDyldObjectLinkingLayer.
226 SetterImpl &setObjectLinkingLayerCreator(
227 LLJITBuilderState::ObjectLinkingLayerCreator CreateObjectLinkingLayer) {
228 impl().CreateObjectLinkingLayer = std::move(CreateObjectLinkingLayer);
229 return impl();
232 /// Set a CompileFunctionCreator.
234 /// If this method is not called, a default creation function wil be used
235 /// that will construct a basic IR compile function that is compatible with
236 /// the selected number of threads (SimpleCompiler for '0' compile threads,
237 /// ConcurrentIRCompiler otherwise).
238 SetterImpl &setCompileFunctionCreator(
239 LLJITBuilderState::CompileFunctionCreator CreateCompileFunction) {
240 impl().CreateCompileFunction = std::move(CreateCompileFunction);
241 return impl();
244 /// Set the number of compile threads to use.
246 /// If set to zero, compilation will be performed on the execution thread when
247 /// JITing in-process. If set to any other number N, a thread pool of N
248 /// threads will be created for compilation.
250 /// If this method is not called, behavior will be as if it were called with
251 /// a zero argument.
252 SetterImpl &setNumCompileThreads(unsigned NumCompileThreads) {
253 impl().NumCompileThreads = NumCompileThreads;
254 return impl();
257 /// Create an instance of the JIT.
258 Expected<std::unique_ptr<JITType>> create() {
259 if (auto Err = impl().prepareForConstruction())
260 return std::move(Err);
262 Error Err = Error::success();
263 std::unique_ptr<JITType> J(new JITType(impl(), Err));
264 if (Err)
265 return std::move(Err);
266 return std::move(J);
269 protected:
270 SetterImpl &impl() { return static_cast<SetterImpl &>(*this); }
273 /// Constructs LLJIT instances.
274 class LLJITBuilder
275 : public LLJITBuilderState,
276 public LLJITBuilderSetters<LLJIT, LLJITBuilder, LLJITBuilderState> {};
278 class LLLazyJITBuilderState : public LLJITBuilderState {
279 friend class LLLazyJIT;
281 public:
282 using IndirectStubsManagerBuilderFunction =
283 std::function<std::unique_ptr<IndirectStubsManager>()>;
285 Triple TT;
286 JITTargetAddress LazyCompileFailureAddr = 0;
287 std::unique_ptr<LazyCallThroughManager> LCTMgr;
288 IndirectStubsManagerBuilderFunction ISMBuilder;
290 Error prepareForConstruction();
293 template <typename JITType, typename SetterImpl, typename State>
294 class LLLazyJITBuilderSetters
295 : public LLJITBuilderSetters<JITType, SetterImpl, State> {
296 public:
297 /// Set the address in the target address to call if a lazy compile fails.
299 /// If this method is not called then the value will default to 0.
300 SetterImpl &setLazyCompileFailureAddr(JITTargetAddress Addr) {
301 this->impl().LazyCompileFailureAddr = Addr;
302 return this->impl();
305 /// Set the lazy-callthrough manager.
307 /// If this method is not called then a default, in-process lazy callthrough
308 /// manager for the host platform will be used.
309 SetterImpl &
310 setLazyCallthroughManager(std::unique_ptr<LazyCallThroughManager> LCTMgr) {
311 this->impl().LCTMgr = std::move(LCTMgr);
312 return this->impl();
315 /// Set the IndirectStubsManager builder function.
317 /// If this method is not called then a default, in-process
318 /// IndirectStubsManager builder for the host platform will be used.
319 SetterImpl &setIndirectStubsManagerBuilder(
320 LLLazyJITBuilderState::IndirectStubsManagerBuilderFunction ISMBuilder) {
321 this->impl().ISMBuilder = std::move(ISMBuilder);
322 return this->impl();
326 /// Constructs LLLazyJIT instances.
327 class LLLazyJITBuilder
328 : public LLLazyJITBuilderState,
329 public LLLazyJITBuilderSetters<LLLazyJIT, LLLazyJITBuilder,
330 LLLazyJITBuilderState> {};
332 } // End namespace orc
333 } // End namespace llvm
335 #endif // LLVM_EXECUTIONENGINE_ORC_LLJIT_H