blob: b0ef20dec4d576dd5fe62d66ae0b172893715a73 [file] [log] [blame]
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001//===----- LLJIT.h -- An ORC-based JIT for compiling LLVM IR ----*- C++ -*-===//
2//
Andrew Walbran16937d02019-10-22 13:54:20 +01003// 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
Andrew Scullcdfcccc2018-10-05 20:58:37 +01006//
7//===----------------------------------------------------------------------===//
8//
9// An ORC-based JIT for compiling LLVM IR.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_EXECUTIONENGINE_ORC_LLJIT_H
14#define LLVM_EXECUTIONENGINE_ORC_LLJIT_H
15
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"
Andrew Scull0372a572018-11-16 15:47:06 +000021#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
Andrew Scullcdfcccc2018-10-05 20:58:37 +010022#include "llvm/ExecutionEngine/Orc/ObjectTransformLayer.h"
23#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
Andrew Scull0372a572018-11-16 15:47:06 +000024#include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h"
25#include "llvm/Support/ThreadPool.h"
Andrew Scullcdfcccc2018-10-05 20:58:37 +010026
27namespace llvm {
28namespace orc {
29
30/// A pre-fabricated ORC JIT stack that can serve as an alternative to MCJIT.
31class LLJIT {
32public:
Andrew Scullcdfcccc2018-10-05 20:58:37 +010033
Andrew Scull0372a572018-11-16 15:47:06 +000034 /// Destruct this instance. If a multi-threaded instance, waits for all
35 /// compile threads to complete.
36 ~LLJIT();
37
38 /// Create an LLJIT instance.
39 /// If NumCompileThreads is not equal to zero, creates a multi-threaded
40 /// LLJIT with the given number of compile threads.
41 static Expected<std::unique_ptr<LLJIT>>
42 Create(JITTargetMachineBuilder JTMB, DataLayout DL,
43 unsigned NumCompileThreads = 0);
44
45 /// Returns the ExecutionSession for this instance.
Andrew Scullcdfcccc2018-10-05 20:58:37 +010046 ExecutionSession &getExecutionSession() { return *ES; }
47
Andrew Scull0372a572018-11-16 15:47:06 +000048 /// Returns a reference to the JITDylib representing the JIT'd main program.
49 JITDylib &getMainJITDylib() { return Main; }
Andrew Scullcdfcccc2018-10-05 20:58:37 +010050
Andrew Walbran16937d02019-10-22 13:54:20 +010051 /// Create a new JITDylib with the given name and return a reference to it.
52 JITDylib &createJITDylib(std::string Name) {
53 return ES->createJITDylib(std::move(Name));
54 }
55
Andrew Scullcdfcccc2018-10-05 20:58:37 +010056 /// Convenience method for defining an absolute symbol.
57 Error defineAbsolute(StringRef Name, JITEvaluatedSymbol Address);
58
Andrew Scull0372a572018-11-16 15:47:06 +000059 /// Convenience method for defining an
Andrew Scullcdfcccc2018-10-05 20:58:37 +010060
Andrew Scull0372a572018-11-16 15:47:06 +000061 /// Adds an IR module to the given JITDylib.
62 Error addIRModule(JITDylib &JD, ThreadSafeModule TSM);
63
64 /// Adds an IR module to the Main JITDylib.
65 Error addIRModule(ThreadSafeModule TSM) {
66 return addIRModule(Main, std::move(TSM));
Andrew Scullcdfcccc2018-10-05 20:58:37 +010067 }
68
Andrew Scull0372a572018-11-16 15:47:06 +000069 /// Adds an object file to the given JITDylib.
70 Error addObjectFile(JITDylib &JD, std::unique_ptr<MemoryBuffer> Obj);
Andrew Scullcdfcccc2018-10-05 20:58:37 +010071
Andrew Scull0372a572018-11-16 15:47:06 +000072 /// Adds an object file to the given JITDylib.
73 Error addObjectFile(std::unique_ptr<MemoryBuffer> Obj) {
74 return addObjectFile(Main, std::move(Obj));
75 }
76
77 /// Look up a symbol in JITDylib JD by the symbol's linker-mangled name (to
Andrew Scullcdfcccc2018-10-05 20:58:37 +010078 /// look up symbols based on their IR name use the lookup function instead).
Andrew Scull0372a572018-11-16 15:47:06 +000079 Expected<JITEvaluatedSymbol> lookupLinkerMangled(JITDylib &JD,
80 StringRef Name);
81
82 /// Look up a symbol in the main JITDylib by the symbol's linker-mangled name
83 /// (to look up symbols based on their IR name use the lookup function
84 /// instead).
Andrew Scullcdfcccc2018-10-05 20:58:37 +010085 Expected<JITEvaluatedSymbol> lookupLinkerMangled(StringRef Name) {
86 return lookupLinkerMangled(Main, Name);
87 }
88
Andrew Scull0372a572018-11-16 15:47:06 +000089 /// Look up a symbol in JITDylib JD based on its IR symbol name.
90 Expected<JITEvaluatedSymbol> lookup(JITDylib &JD, StringRef UnmangledName) {
91 return lookupLinkerMangled(JD, mangle(UnmangledName));
Andrew Scullcdfcccc2018-10-05 20:58:37 +010092 }
93
Andrew Scull0372a572018-11-16 15:47:06 +000094 /// Look up a symbol in the main JITDylib based on its IR symbol name.
Andrew Scullcdfcccc2018-10-05 20:58:37 +010095 Expected<JITEvaluatedSymbol> lookup(StringRef UnmangledName) {
96 return lookup(Main, UnmangledName);
97 }
98
99 /// Runs all not-yet-run static constructors.
100 Error runConstructors() { return CtorRunner.run(); }
101
102 /// Runs all not-yet-run static destructors.
103 Error runDestructors() { return DtorRunner.run(); }
104
Andrew Scull0372a572018-11-16 15:47:06 +0000105 /// Returns a reference to the ObjLinkingLayer
Andrew Walbran16937d02019-10-22 13:54:20 +0100106 RTDyldObjectLinkingLayer &getObjLinkingLayer() { return ObjLinkingLayer; }
Andrew Scull0372a572018-11-16 15:47:06 +0000107
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100108protected:
Andrew Scull0372a572018-11-16 15:47:06 +0000109
110 /// Create an LLJIT instance with a single compile thread.
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100111 LLJIT(std::unique_ptr<ExecutionSession> ES, std::unique_ptr<TargetMachine> TM,
112 DataLayout DL);
113
Andrew Scull0372a572018-11-16 15:47:06 +0000114 /// Create an LLJIT instance with multiple compile threads.
115 LLJIT(std::unique_ptr<ExecutionSession> ES, JITTargetMachineBuilder JTMB,
116 DataLayout DL, unsigned NumCompileThreads);
117
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100118 std::string mangle(StringRef UnmangledName);
119
120 Error applyDataLayout(Module &M);
121
122 void recordCtorDtors(Module &M);
123
124 std::unique_ptr<ExecutionSession> ES;
Andrew Scull0372a572018-11-16 15:47:06 +0000125 JITDylib &Main;
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100126
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100127 DataLayout DL;
Andrew Scull0372a572018-11-16 15:47:06 +0000128 std::unique_ptr<ThreadPool> CompileThreads;
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100129
Andrew Walbran16937d02019-10-22 13:54:20 +0100130 RTDyldObjectLinkingLayer ObjLinkingLayer;
131 IRCompileLayer CompileLayer;
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100132
Andrew Walbran16937d02019-10-22 13:54:20 +0100133 CtorDtorRunner CtorRunner, DtorRunner;
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100134};
135
136/// An extended version of LLJIT that supports lazy function-at-a-time
137/// compilation of LLVM IR.
138class LLLazyJIT : public LLJIT {
139public:
Andrew Scull0372a572018-11-16 15:47:06 +0000140
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100141 /// Create an LLLazyJIT instance.
Andrew Scull0372a572018-11-16 15:47:06 +0000142 /// If NumCompileThreads is not equal to zero, creates a multi-threaded
143 /// LLLazyJIT with the given number of compile threads.
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100144 static Expected<std::unique_ptr<LLLazyJIT>>
Andrew Scull0372a572018-11-16 15:47:06 +0000145 Create(JITTargetMachineBuilder JTMB, DataLayout DL,
Andrew Walbran16937d02019-10-22 13:54:20 +0100146 JITTargetAddress ErrorAddr, unsigned NumCompileThreads = 0);
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100147
148 /// Set an IR transform (e.g. pass manager pipeline) to run on each function
149 /// when it is compiled.
Andrew Walbran16937d02019-10-22 13:54:20 +0100150 void setLazyCompileTransform(IRTransformLayer::TransformFunction Transform) {
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100151 TransformLayer.setTransform(std::move(Transform));
152 }
153
Andrew Scull0372a572018-11-16 15:47:06 +0000154 /// Sets the partition function.
155 void
Andrew Walbran16937d02019-10-22 13:54:20 +0100156 setPartitionFunction(CompileOnDemandLayer::PartitionFunction Partition) {
Andrew Scull0372a572018-11-16 15:47:06 +0000157 CODLayer.setPartitionFunction(std::move(Partition));
158 }
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100159
Andrew Scull0372a572018-11-16 15:47:06 +0000160 /// Add a module to be lazily compiled to JITDylib JD.
161 Error addLazyIRModule(JITDylib &JD, ThreadSafeModule M);
162
163 /// Add a module to be lazily compiled to the main JITDylib.
164 Error addLazyIRModule(ThreadSafeModule M) {
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100165 return addLazyIRModule(Main, std::move(M));
166 }
167
168private:
Andrew Scull0372a572018-11-16 15:47:06 +0000169
170 // Create a single-threaded LLLazyJIT instance.
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100171 LLLazyJIT(std::unique_ptr<ExecutionSession> ES,
Andrew Scull0372a572018-11-16 15:47:06 +0000172 std::unique_ptr<TargetMachine> TM, DataLayout DL,
173 std::unique_ptr<LazyCallThroughManager> LCTMgr,
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100174 std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder);
175
Andrew Scull0372a572018-11-16 15:47:06 +0000176 // Create a multi-threaded LLLazyJIT instance.
177 LLLazyJIT(std::unique_ptr<ExecutionSession> ES, JITTargetMachineBuilder JTMB,
178 DataLayout DL, unsigned NumCompileThreads,
179 std::unique_ptr<LazyCallThroughManager> LCTMgr,
180 std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder);
181
182 std::unique_ptr<LazyCallThroughManager> LCTMgr;
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100183 std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder;
184
Andrew Walbran16937d02019-10-22 13:54:20 +0100185 IRTransformLayer TransformLayer;
186 CompileOnDemandLayer CODLayer;
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100187};
188
189} // End namespace orc
190} // End namespace llvm
191
192#endif // LLVM_EXECUTIONENGINE_ORC_LLJIT_H