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.
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"
21#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
22#include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h"
23#include "llvm/Support/Debug.h"
24#include "llvm/Support/ThreadPool.h"
25#include <variant>
26
27namespace llvm {
28namespace orc {
29
30class LLJITBuilderState;
31class LLLazyJITBuilderState;
32class ObjectTransformLayer;
33class ExecutorProcessControl;
34
35/// A pre-fabricated ORC JIT stack that can serve as an alternative to MCJIT.
36///
37/// Create instances using LLJITBuilder.
38class LLJIT {
39 template <typename, typename, typename> friend class LLJITBuilderSetters;
40
41 friend Expected<JITDylibSP> setUpGenericLLVMIRPlatform(LLJIT &J);
42
43public:
44 /// Initializer support for LLJIT.
45 class PlatformSupport {
46 public:
47 virtual ~PlatformSupport();
48
49 virtual Error initialize(JITDylib &JD) = 0;
50
51 virtual Error deinitialize(JITDylib &JD) = 0;
52
53 protected:
54 static void setInitTransform(LLJIT &J,
55 IRTransformLayer::TransformFunction T);
56 };
57
58 /// Destruct this instance. If a multi-threaded instance, waits for all
59 /// compile threads to complete.
60 virtual ~LLJIT();
61
62 /// Returns the ExecutionSession for this instance.
63 ExecutionSession &getExecutionSession() { return *ES; }
64
65 /// Returns a reference to the triple for this instance.
66 const Triple &getTargetTriple() const { return TT; }
67
68 /// Returns a reference to the DataLayout for this instance.
69 const DataLayout &getDataLayout() const { return DL; }
70
71 /// Returns a reference to the JITDylib representing the JIT'd main program.
72 JITDylib &getMainJITDylib() { return *Main; }
73
74 /// Returns the ProcessSymbols JITDylib, which by default reflects non-JIT'd
75 /// symbols in the host process.
76 ///
77 /// Note: JIT'd code should not be added to the ProcessSymbols JITDylib. Use
78 /// the main JITDylib or a custom JITDylib instead.
79 JITDylibSP getProcessSymbolsJITDylib();
80
81 /// Returns the Platform JITDylib, which will contain the ORC runtime (if
82 /// given) and any platform symbols.
83 ///
84 /// Note: JIT'd code should not be added to the Platform JITDylib. Use the
85 /// main JITDylib or a custom JITDylib instead.
86 JITDylibSP getPlatformJITDylib();
87
88 /// Returns the JITDylib with the given name, or nullptr if no JITDylib with
89 /// that name exists.
90 JITDylib *getJITDylibByName(StringRef Name) {
91 return ES->getJITDylibByName(Name);
92 }
93
94 /// Load a (real) dynamic library and make its symbols available through a
95 /// new JITDylib with the same name.
96 ///
97 /// If the given *executor* path contains a valid platform dynamic library
98 /// then that library will be loaded, and a new bare JITDylib whose name is
99 /// the given path will be created to make the library's symbols available to
100 /// JIT'd code.
101 Expected<JITDylib &> loadPlatformDynamicLibrary(const char *Path);
102
103 /// Link a static library into the given JITDylib.
104 ///
105 /// If the given MemoryBuffer contains a valid static archive (or a universal
106 /// binary with an archive slice that fits the LLJIT instance's platform /
107 /// architecture) then it will be added to the given JITDylib using a
108 /// StaticLibraryDefinitionGenerator.
109 Error linkStaticLibraryInto(JITDylib &JD,
110 std::unique_ptr<MemoryBuffer> LibBuffer);
111
112 /// Link a static library into the given JITDylib.
113 ///
114 /// If the given *host* path contains a valid static archive (or a universal
115 /// binary with an archive slice that fits the LLJIT instance's platform /
116 /// architecture) then it will be added to the given JITDylib using a
117 /// StaticLibraryDefinitionGenerator.
118 Error linkStaticLibraryInto(JITDylib &JD, const char *Path);
119
120 /// Create a new JITDylib with the given name and return a reference to it.
121 ///
122 /// JITDylib names must be unique. If the given name is derived from user
123 /// input or elsewhere in the environment then the client should check
124 /// (e.g. by calling getJITDylibByName) that the given name is not already in
125 /// use.
126 Expected<JITDylib &> createJITDylib(std::string Name);
127
128 /// Returns the default link order for this LLJIT instance. This link order
129 /// will be appended to the link order of JITDylibs created by LLJIT's
130 /// createJITDylib method.
131 JITDylibSearchOrder defaultLinkOrder() { return DefaultLinks; }
132
133 /// Adds an IR module with the given ResourceTracker.
134 Error addIRModule(ResourceTrackerSP RT, ThreadSafeModule TSM);
135
136 /// Adds an IR module to the given JITDylib.
137 Error addIRModule(JITDylib &JD, ThreadSafeModule TSM);
138
139 /// Adds an IR module to the Main JITDylib.
140 Error addIRModule(ThreadSafeModule TSM) {
141 return addIRModule(JD&: *Main, TSM: std::move(TSM));
142 }
143
144 /// Adds an object file to the given JITDylib.
145 Error addObjectFile(ResourceTrackerSP RT, std::unique_ptr<MemoryBuffer> Obj);
146
147 /// Adds an object file to the given JITDylib.
148 Error addObjectFile(JITDylib &JD, std::unique_ptr<MemoryBuffer> Obj);
149
150 /// Adds an object file to the given JITDylib.
151 Error addObjectFile(std::unique_ptr<MemoryBuffer> Obj) {
152 return addObjectFile(JD&: *Main, Obj: std::move(Obj));
153 }
154
155 /// Look up a symbol in JITDylib JD by the symbol's linker-mangled name (to
156 /// look up symbols based on their IR name use the lookup function instead).
157 Expected<ExecutorAddr> lookupLinkerMangled(JITDylib &JD,
158 SymbolStringPtr Name);
159
160 /// Look up a symbol in JITDylib JD by the symbol's linker-mangled name (to
161 /// look up symbols based on their IR name use the lookup function instead).
162 Expected<ExecutorAddr> lookupLinkerMangled(JITDylib &JD,
163 StringRef Name) {
164 return lookupLinkerMangled(JD, Name: ES->intern(SymName: Name));
165 }
166
167 /// Look up a symbol in the main JITDylib by the symbol's linker-mangled name
168 /// (to look up symbols based on their IR name use the lookup function
169 /// instead).
170 Expected<ExecutorAddr> lookupLinkerMangled(StringRef Name) {
171 return lookupLinkerMangled(JD&: *Main, Name);
172 }
173
174 /// Look up a symbol in JITDylib JD based on its IR symbol name.
175 Expected<ExecutorAddr> lookup(JITDylib &JD, StringRef UnmangledName) {
176 return lookupLinkerMangled(JD, Name: mangle(UnmangledName));
177 }
178
179 /// Look up a symbol in the main JITDylib based on its IR symbol name.
180 Expected<ExecutorAddr> lookup(StringRef UnmangledName) {
181 return lookup(JD&: *Main, UnmangledName);
182 }
183
184 /// Set the PlatformSupport instance.
185 void setPlatformSupport(std::unique_ptr<PlatformSupport> PS) {
186 this->PS = std::move(PS);
187 }
188
189 /// Get the PlatformSupport instance.
190 PlatformSupport *getPlatformSupport() { return PS.get(); }
191
192 /// Run the initializers for the given JITDylib.
193 Error initialize(JITDylib &JD) {
194 DEBUG_WITH_TYPE("orc", {
195 dbgs() << "LLJIT running initializers for JITDylib \"" << JD.getName()
196 << "\"\n";
197 });
198 assert(PS && "PlatformSupport must be set to run initializers.");
199 return PS->initialize(JD);
200 }
201
202 /// Run the deinitializers for the given JITDylib.
203 Error deinitialize(JITDylib &JD) {
204 DEBUG_WITH_TYPE("orc", {
205 dbgs() << "LLJIT running deinitializers for JITDylib \"" << JD.getName()
206 << "\"\n";
207 });
208 assert(PS && "PlatformSupport must be set to run initializers.");
209 return PS->deinitialize(JD);
210 }
211
212 /// Returns a reference to the ObjLinkingLayer
213 ObjectLayer &getObjLinkingLayer() { return *ObjLinkingLayer; }
214
215 /// Returns a reference to the object transform layer.
216 ObjectTransformLayer &getObjTransformLayer() { return *ObjTransformLayer; }
217
218 /// Returns a reference to the IR transform layer.
219 IRTransformLayer &getIRTransformLayer() { return *TransformLayer; }
220
221 /// Returns a reference to the IR compile layer.
222 IRCompileLayer &getIRCompileLayer() { return *CompileLayer; }
223
224 /// Returns a linker-mangled version of UnmangledName.
225 std::string mangle(StringRef UnmangledName) const;
226
227 /// Returns an interned, linker-mangled version of UnmangledName.
228 SymbolStringPtr mangleAndIntern(StringRef UnmangledName) const {
229 return ES->intern(SymName: mangle(UnmangledName));
230 }
231
232protected:
233 static Expected<std::unique_ptr<ObjectLayer>>
234 createObjectLinkingLayer(LLJITBuilderState &S, ExecutionSession &ES);
235
236 static Expected<std::unique_ptr<IRCompileLayer::IRCompiler>>
237 createCompileFunction(LLJITBuilderState &S, JITTargetMachineBuilder JTMB);
238
239 /// Create an LLJIT instance with a single compile thread.
240 LLJIT(LLJITBuilderState &S, Error &Err);
241
242 Error applyDataLayout(Module &M);
243
244 void recordCtorDtors(Module &M);
245
246 std::unique_ptr<ExecutionSession> ES;
247 std::unique_ptr<PlatformSupport> PS;
248
249 JITDylib *ProcessSymbols = nullptr;
250 JITDylib *Platform = nullptr;
251 JITDylib *Main = nullptr;
252
253 JITDylibSearchOrder DefaultLinks;
254
255 DataLayout DL;
256 Triple TT;
257 std::unique_ptr<ThreadPool> CompileThreads;
258
259 std::unique_ptr<ObjectLayer> ObjLinkingLayer;
260 std::unique_ptr<ObjectTransformLayer> ObjTransformLayer;
261 std::unique_ptr<IRCompileLayer> CompileLayer;
262 std::unique_ptr<IRTransformLayer> TransformLayer;
263 std::unique_ptr<IRTransformLayer> InitHelperTransformLayer;
264};
265
266/// An extended version of LLJIT that supports lazy function-at-a-time
267/// compilation of LLVM IR.
268class LLLazyJIT : public LLJIT {
269 template <typename, typename, typename> friend class LLJITBuilderSetters;
270
271public:
272
273 /// Sets the partition function.
274 void
275 setPartitionFunction(CompileOnDemandLayer::PartitionFunction Partition) {
276 CODLayer->setPartitionFunction(std::move(Partition));
277 }
278
279 /// Returns a reference to the on-demand layer.
280 CompileOnDemandLayer &getCompileOnDemandLayer() { return *CODLayer; }
281
282 /// Add a module to be lazily compiled to JITDylib JD.
283 Error addLazyIRModule(JITDylib &JD, ThreadSafeModule M);
284
285 /// Add a module to be lazily compiled to the main JITDylib.
286 Error addLazyIRModule(ThreadSafeModule M) {
287 return addLazyIRModule(JD&: *Main, M: std::move(M));
288 }
289
290private:
291
292 // Create a single-threaded LLLazyJIT instance.
293 LLLazyJIT(LLLazyJITBuilderState &S, Error &Err);
294
295 std::unique_ptr<LazyCallThroughManager> LCTMgr;
296 std::unique_ptr<CompileOnDemandLayer> CODLayer;
297};
298
299class LLJITBuilderState {
300public:
301 using ObjectLinkingLayerCreator =
302 std::function<Expected<std::unique_ptr<ObjectLayer>>(ExecutionSession &,
303 const Triple &)>;
304
305 using CompileFunctionCreator =
306 std::function<Expected<std::unique_ptr<IRCompileLayer::IRCompiler>>(
307 JITTargetMachineBuilder JTMB)>;
308
309 using ProcessSymbolsJITDylibSetupFunction =
310 unique_function<Expected<JITDylibSP>(LLJIT &J)>;
311
312 using PlatformSetupFunction = unique_function<Expected<JITDylibSP>(LLJIT &J)>;
313
314 std::unique_ptr<ExecutorProcessControl> EPC;
315 std::unique_ptr<ExecutionSession> ES;
316 std::optional<JITTargetMachineBuilder> JTMB;
317 std::optional<DataLayout> DL;
318 bool LinkProcessSymbolsByDefault = true;
319 ProcessSymbolsJITDylibSetupFunction SetupProcessSymbolsJITDylib;
320 ObjectLinkingLayerCreator CreateObjectLinkingLayer;
321 CompileFunctionCreator CreateCompileFunction;
322 unique_function<Error(LLJIT &)> PrePlatformSetup;
323 PlatformSetupFunction SetUpPlatform;
324 unsigned NumCompileThreads = 0;
325
326 /// Called prior to JIT class construcion to fix up defaults.
327 Error prepareForConstruction();
328};
329
330template <typename JITType, typename SetterImpl, typename State>
331class LLJITBuilderSetters {
332public:
333 /// Set a ExecutorProcessControl for this instance.
334 /// This should not be called if ExecutionSession has already been set.
335 SetterImpl &
336 setExecutorProcessControl(std::unique_ptr<ExecutorProcessControl> EPC) {
337 assert(
338 !impl().ES &&
339 "setExecutorProcessControl should not be called if an ExecutionSession "
340 "has already been set");
341 impl().EPC = std::move(EPC);
342 return impl();
343 }
344
345 /// Set an ExecutionSession for this instance.
346 SetterImpl &setExecutionSession(std::unique_ptr<ExecutionSession> ES) {
347 assert(
348 !impl().EPC &&
349 "setExecutionSession should not be called if an ExecutorProcessControl "
350 "object has already been set");
351 impl().ES = std::move(ES);
352 return impl();
353 }
354
355 /// Set the JITTargetMachineBuilder for this instance.
356 ///
357 /// If this method is not called, JITTargetMachineBuilder::detectHost will be
358 /// used to construct a default target machine builder for the host platform.
359 SetterImpl &setJITTargetMachineBuilder(JITTargetMachineBuilder JTMB) {
360 impl().JTMB = std::move(JTMB);
361 return impl();
362 }
363
364 /// Return a reference to the JITTargetMachineBuilder.
365 ///
366 std::optional<JITTargetMachineBuilder> &getJITTargetMachineBuilder() {
367 return impl().JTMB;
368 }
369
370 /// Set a DataLayout for this instance. If no data layout is specified then
371 /// the target's default data layout will be used.
372 SetterImpl &setDataLayout(std::optional<DataLayout> DL) {
373 impl().DL = std::move(DL);
374 return impl();
375 }
376
377 /// The LinkProcessSymbolsDyDefault flag determines whether the "Process"
378 /// JITDylib will be added to the default link order at LLJIT construction
379 /// time. If true, the Process JITDylib will be added as the last item in the
380 /// default link order. If false (or if the Process JITDylib is disabled via
381 /// setProcessSymbolsJITDylibSetup) then the Process JITDylib will not appear
382 /// in the default link order.
383 SetterImpl &setLinkProcessSymbolsByDefault(bool LinkProcessSymbolsByDefault) {
384 impl().LinkProcessSymbolsByDefault = LinkProcessSymbolsByDefault;
385 return impl();
386 }
387
388 /// Set a setup function for the process symbols dylib. If not provided,
389 /// but LinkProcessSymbolsJITDylibByDefault is true, then the process-symbols
390 /// JITDylib will be configured with a DynamicLibrarySearchGenerator with a
391 /// default symbol filter.
392 SetterImpl &setProcessSymbolsJITDylibSetup(
393 LLJITBuilderState::ProcessSymbolsJITDylibSetupFunction
394 SetupProcessSymbolsJITDylib) {
395 impl().SetupProcessSymbolsJITDylib = std::move(SetupProcessSymbolsJITDylib);
396 return impl();
397 }
398
399 /// Set an ObjectLinkingLayer creation function.
400 ///
401 /// If this method is not called, a default creation function will be used
402 /// that will construct an RTDyldObjectLinkingLayer.
403 SetterImpl &setObjectLinkingLayerCreator(
404 LLJITBuilderState::ObjectLinkingLayerCreator CreateObjectLinkingLayer) {
405 impl().CreateObjectLinkingLayer = std::move(CreateObjectLinkingLayer);
406 return impl();
407 }
408
409 /// Set a CompileFunctionCreator.
410 ///
411 /// If this method is not called, a default creation function wil be used
412 /// that will construct a basic IR compile function that is compatible with
413 /// the selected number of threads (SimpleCompiler for '0' compile threads,
414 /// ConcurrentIRCompiler otherwise).
415 SetterImpl &setCompileFunctionCreator(
416 LLJITBuilderState::CompileFunctionCreator CreateCompileFunction) {
417 impl().CreateCompileFunction = std::move(CreateCompileFunction);
418 return impl();
419 }
420
421 /// Set a setup function to be run just before the PlatformSetupFunction is
422 /// run.
423 ///
424 /// This can be used to customize the LLJIT instance before the platform is
425 /// set up. E.g. By installing a debugger support plugin before the platform
426 /// is set up (when the ORC runtime is loaded) we enable debugging of the
427 /// runtime itself.
428 SetterImpl &
429 setPrePlatformSetup(unique_function<Error(LLJIT &)> PrePlatformSetup) {
430 impl().PrePlatformSetup = std::move(PrePlatformSetup);
431 return impl();
432 }
433
434 /// Set up an PlatformSetupFunction.
435 ///
436 /// If this method is not called then setUpGenericLLVMIRPlatform
437 /// will be used to configure the JIT's platform support.
438 SetterImpl &
439 setPlatformSetUp(LLJITBuilderState::PlatformSetupFunction SetUpPlatform) {
440 impl().SetUpPlatform = std::move(SetUpPlatform);
441 return impl();
442 }
443
444 /// Set the number of compile threads to use.
445 ///
446 /// If set to zero, compilation will be performed on the execution thread when
447 /// JITing in-process. If set to any other number N, a thread pool of N
448 /// threads will be created for compilation.
449 ///
450 /// If this method is not called, behavior will be as if it were called with
451 /// a zero argument.
452 SetterImpl &setNumCompileThreads(unsigned NumCompileThreads) {
453 impl().NumCompileThreads = NumCompileThreads;
454 return impl();
455 }
456
457 /// Set an ExecutorProcessControl object.
458 ///
459 /// If the platform uses ObjectLinkingLayer by default and no
460 /// ObjectLinkingLayerCreator has been set then the ExecutorProcessControl
461 /// object will be used to supply the memory manager for the
462 /// ObjectLinkingLayer.
463 SetterImpl &setExecutorProcessControl(ExecutorProcessControl &EPC) {
464 impl().EPC = &EPC;
465 return impl();
466 }
467
468 /// Create an instance of the JIT.
469 Expected<std::unique_ptr<JITType>> create() {
470 if (auto Err = impl().prepareForConstruction())
471 return std::move(Err);
472
473 Error Err = Error::success();
474 std::unique_ptr<JITType> J(new JITType(impl(), Err));
475 if (Err)
476 return std::move(Err);
477 return std::move(J);
478 }
479
480protected:
481 SetterImpl &impl() { return static_cast<SetterImpl &>(*this); }
482};
483
484/// Constructs LLJIT instances.
485class LLJITBuilder
486 : public LLJITBuilderState,
487 public LLJITBuilderSetters<LLJIT, LLJITBuilder, LLJITBuilderState> {};
488
489class LLLazyJITBuilderState : public LLJITBuilderState {
490 friend class LLLazyJIT;
491
492public:
493 using IndirectStubsManagerBuilderFunction =
494 std::function<std::unique_ptr<IndirectStubsManager>()>;
495
496 Triple TT;
497 ExecutorAddr LazyCompileFailureAddr;
498 std::unique_ptr<LazyCallThroughManager> LCTMgr;
499 IndirectStubsManagerBuilderFunction ISMBuilder;
500
501 Error prepareForConstruction();
502};
503
504template <typename JITType, typename SetterImpl, typename State>
505class LLLazyJITBuilderSetters
506 : public LLJITBuilderSetters<JITType, SetterImpl, State> {
507public:
508 /// Set the address in the target address to call if a lazy compile fails.
509 ///
510 /// If this method is not called then the value will default to 0.
511 SetterImpl &setLazyCompileFailureAddr(ExecutorAddr Addr) {
512 this->impl().LazyCompileFailureAddr = Addr;
513 return this->impl();
514 }
515
516 /// Set the lazy-callthrough manager.
517 ///
518 /// If this method is not called then a default, in-process lazy callthrough
519 /// manager for the host platform will be used.
520 SetterImpl &
521 setLazyCallthroughManager(std::unique_ptr<LazyCallThroughManager> LCTMgr) {
522 this->impl().LCTMgr = std::move(LCTMgr);
523 return this->impl();
524 }
525
526 /// Set the IndirectStubsManager builder function.
527 ///
528 /// If this method is not called then a default, in-process
529 /// IndirectStubsManager builder for the host platform will be used.
530 SetterImpl &setIndirectStubsManagerBuilder(
531 LLLazyJITBuilderState::IndirectStubsManagerBuilderFunction ISMBuilder) {
532 this->impl().ISMBuilder = std::move(ISMBuilder);
533 return this->impl();
534 }
535};
536
537/// Constructs LLLazyJIT instances.
538class LLLazyJITBuilder
539 : public LLLazyJITBuilderState,
540 public LLLazyJITBuilderSetters<LLLazyJIT, LLLazyJITBuilder,
541 LLLazyJITBuilderState> {};
542
543/// Configure the LLJIT instance to use orc runtime support. This overload
544/// assumes that the client has manually configured a Platform object.
545Error setUpOrcPlatformManually(LLJIT &J);
546
547/// Configure the LLJIT instance to use the ORC runtime and the detected
548/// native target for the executor.
549class ExecutorNativePlatform {
550public:
551 /// Set up using path to Orc runtime.
552 ExecutorNativePlatform(std::string OrcRuntimePath)
553 : OrcRuntime(std::move(OrcRuntimePath)) {}
554
555 /// Set up using the given memory buffer.
556 ExecutorNativePlatform(std::unique_ptr<MemoryBuffer> OrcRuntimeMB)
557 : OrcRuntime(std::move(OrcRuntimeMB)) {}
558
559 // TODO: add compiler-rt.
560
561 /// Add a path to the VC runtime.
562 ExecutorNativePlatform &addVCRuntime(std::string VCRuntimePath,
563 bool StaticVCRuntime) {
564 VCRuntime = {std::move(VCRuntimePath), StaticVCRuntime};
565 return *this;
566 }
567
568 Expected<JITDylibSP> operator()(LLJIT &J);
569
570private:
571 std::variant<std::string, std::unique_ptr<MemoryBuffer>> OrcRuntime;
572 std::optional<std::pair<std::string, bool>> VCRuntime;
573};
574
575/// Configure the LLJIT instance to scrape modules for llvm.global_ctors and
576/// llvm.global_dtors variables and (if present) build initialization and
577/// deinitialization functions. Platform specific initialization configurations
578/// should be preferred where available.
579Expected<JITDylibSP> setUpGenericLLVMIRPlatform(LLJIT &J);
580
581/// Configure the LLJIT instance to disable platform support explicitly. This is
582/// useful in two cases: for platforms that don't have such requirements and for
583/// platforms, that we have no explicit support yet and that don't work well
584/// with the generic IR platform.
585Expected<JITDylibSP> setUpInactivePlatform(LLJIT &J);
586
587/// A Platform-support class that implements initialize / deinitialize by
588/// forwarding to ORC runtime dlopen / dlclose operations.
589class ORCPlatformSupport : public LLJIT::PlatformSupport {
590public:
591 ORCPlatformSupport(orc::LLJIT &J) : J(J) {}
592 Error initialize(orc::JITDylib &JD) override;
593 Error deinitialize(orc::JITDylib &JD) override;
594
595private:
596 orc::LLJIT &J;
597 DenseMap<orc::JITDylib *, orc::ExecutorAddr> DSOHandles;
598};
599
600} // End namespace orc
601} // End namespace llvm
602
603#endif // LLVM_EXECUTIONENGINE_ORC_LLJIT_H
604

source code of llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h