blob: 400d4cbe7f09bcfd73f0a86491eff48cc68404f8 [file] [log] [blame]
Andrew Scullcdfcccc2018-10-05 20:58:37 +01001//===----- 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"
Andrew Scull0372a572018-11-16 15:47:06 +000022#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
Andrew Scullcdfcccc2018-10-05 20:58:37 +010023#include "llvm/ExecutionEngine/Orc/ObjectTransformLayer.h"
24#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
Andrew Scull0372a572018-11-16 15:47:06 +000025#include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h"
26#include "llvm/Support/ThreadPool.h"
Andrew Scullcdfcccc2018-10-05 20:58:37 +010027
28namespace llvm {
29namespace orc {
30
31/// A pre-fabricated ORC JIT stack that can serve as an alternative to MCJIT.
32class LLJIT {
33public:
Andrew Scullcdfcccc2018-10-05 20:58:37 +010034
Andrew Scull0372a572018-11-16 15:47:06 +000035 /// 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.
Andrew Scullcdfcccc2018-10-05 20:58:37 +010047 ExecutionSession &getExecutionSession() { return *ES; }
48
Andrew Scull0372a572018-11-16 15:47:06 +000049 /// Returns a reference to the JITDylib representing the JIT'd main program.
50 JITDylib &getMainJITDylib() { return Main; }
Andrew Scullcdfcccc2018-10-05 20:58:37 +010051
52 /// Convenience method for defining an absolute symbol.
53 Error defineAbsolute(StringRef Name, JITEvaluatedSymbol Address);
54
Andrew Scull0372a572018-11-16 15:47:06 +000055 /// Convenience method for defining an
Andrew Scullcdfcccc2018-10-05 20:58:37 +010056
Andrew Scull0372a572018-11-16 15:47:06 +000057 /// 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));
Andrew Scullcdfcccc2018-10-05 20:58:37 +010063 }
64
Andrew Scull0372a572018-11-16 15:47:06 +000065 /// Adds an object file to the given JITDylib.
66 Error addObjectFile(JITDylib &JD, std::unique_ptr<MemoryBuffer> Obj);
Andrew Scullcdfcccc2018-10-05 20:58:37 +010067
Andrew Scull0372a572018-11-16 15:47:06 +000068 /// Adds an object file to the given JITDylib.
69 Error addObjectFile(std::unique_ptr<MemoryBuffer> Obj) {
70 return addObjectFile(Main, std::move(Obj));
71 }
72
73 /// Look up a symbol in JITDylib JD by the symbol's linker-mangled name (to
Andrew Scullcdfcccc2018-10-05 20:58:37 +010074 /// look up symbols based on their IR name use the lookup function instead).
Andrew Scull0372a572018-11-16 15:47:06 +000075 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).
Andrew Scullcdfcccc2018-10-05 20:58:37 +010081 Expected<JITEvaluatedSymbol> lookupLinkerMangled(StringRef Name) {
82 return lookupLinkerMangled(Main, Name);
83 }
84
Andrew Scull0372a572018-11-16 15:47:06 +000085 /// Look up a symbol in JITDylib JD based on its IR symbol name.
86 Expected<JITEvaluatedSymbol> lookup(JITDylib &JD, StringRef UnmangledName) {
87 return lookupLinkerMangled(JD, mangle(UnmangledName));
Andrew Scullcdfcccc2018-10-05 20:58:37 +010088 }
89
Andrew Scull0372a572018-11-16 15:47:06 +000090 /// Look up a symbol in the main JITDylib based on its IR symbol name.
Andrew Scullcdfcccc2018-10-05 20:58:37 +010091 Expected<JITEvaluatedSymbol> lookup(StringRef UnmangledName) {
92 return lookup(Main, UnmangledName);
93 }
94
95 /// Runs all not-yet-run static constructors.
96 Error runConstructors() { return CtorRunner.run(); }
97
98 /// Runs all not-yet-run static destructors.
99 Error runDestructors() { return DtorRunner.run(); }
100
Andrew Scull0372a572018-11-16 15:47:06 +0000101 /// Returns a reference to the ObjLinkingLayer
102 RTDyldObjectLinkingLayer2 &getObjLinkingLayer() { return ObjLinkingLayer; }
103
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100104protected:
Andrew Scull0372a572018-11-16 15:47:06 +0000105
106 /// Create an LLJIT instance with a single compile thread.
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100107 LLJIT(std::unique_ptr<ExecutionSession> ES, std::unique_ptr<TargetMachine> TM,
108 DataLayout DL);
109
Andrew Scull0372a572018-11-16 15:47:06 +0000110 /// 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::unique_ptr<RuntimeDyld::MemoryManager> getMemoryManager(VModuleKey K);
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100115
116 std::string mangle(StringRef UnmangledName);
117
118 Error applyDataLayout(Module &M);
119
120 void recordCtorDtors(Module &M);
121
122 std::unique_ptr<ExecutionSession> ES;
Andrew Scull0372a572018-11-16 15:47:06 +0000123 JITDylib &Main;
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100124
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100125 DataLayout DL;
Andrew Scull0372a572018-11-16 15:47:06 +0000126 std::unique_ptr<ThreadPool> CompileThreads;
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100127
128 RTDyldObjectLinkingLayer2 ObjLinkingLayer;
129 IRCompileLayer2 CompileLayer;
130
131 CtorDtorRunner2 CtorRunner, DtorRunner;
132};
133
134/// An extended version of LLJIT that supports lazy function-at-a-time
135/// compilation of LLVM IR.
136class LLLazyJIT : public LLJIT {
137public:
Andrew Scull0372a572018-11-16 15:47:06 +0000138
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100139 /// Create an LLLazyJIT instance.
Andrew Scull0372a572018-11-16 15:47:06 +0000140 /// If NumCompileThreads is not equal to zero, creates a multi-threaded
141 /// LLLazyJIT with the given number of compile threads.
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100142 static Expected<std::unique_ptr<LLLazyJIT>>
Andrew Scull0372a572018-11-16 15:47:06 +0000143 Create(JITTargetMachineBuilder JTMB, DataLayout DL,
144 unsigned NumCompileThreads = 0);
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100145
146 /// Set an IR transform (e.g. pass manager pipeline) to run on each function
147 /// when it is compiled.
148 void setLazyCompileTransform(IRTransformLayer2::TransformFunction Transform) {
149 TransformLayer.setTransform(std::move(Transform));
150 }
151
Andrew Scull0372a572018-11-16 15:47:06 +0000152 /// Sets the partition function.
153 void
154 setPartitionFunction(CompileOnDemandLayer2::PartitionFunction Partition) {
155 CODLayer.setPartitionFunction(std::move(Partition));
156 }
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100157
Andrew Scull0372a572018-11-16 15:47:06 +0000158 /// Add a module to be lazily compiled to JITDylib JD.
159 Error addLazyIRModule(JITDylib &JD, ThreadSafeModule M);
160
161 /// Add a module to be lazily compiled to the main JITDylib.
162 Error addLazyIRModule(ThreadSafeModule M) {
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100163 return addLazyIRModule(Main, std::move(M));
164 }
165
166private:
Andrew Scull0372a572018-11-16 15:47:06 +0000167
168 // Create a single-threaded LLLazyJIT instance.
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100169 LLLazyJIT(std::unique_ptr<ExecutionSession> ES,
Andrew Scull0372a572018-11-16 15:47:06 +0000170 std::unique_ptr<TargetMachine> TM, DataLayout DL,
171 std::unique_ptr<LazyCallThroughManager> LCTMgr,
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100172 std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder);
173
Andrew Scull0372a572018-11-16 15:47:06 +0000174 // Create a multi-threaded LLLazyJIT instance.
175 LLLazyJIT(std::unique_ptr<ExecutionSession> ES, JITTargetMachineBuilder JTMB,
176 DataLayout DL, unsigned NumCompileThreads,
177 std::unique_ptr<LazyCallThroughManager> LCTMgr,
178 std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder);
179
180 std::unique_ptr<LazyCallThroughManager> LCTMgr;
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100181 std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder;
182
183 IRTransformLayer2 TransformLayer;
184 CompileOnDemandLayer2 CODLayer;
185};
186
187} // End namespace orc
188} // End namespace llvm
189
190#endif // LLVM_EXECUTIONENGINE_ORC_LLJIT_H