Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:53

0001 //===----- LLJIT.h -- An ORC-based JIT for compiling LLVM IR ----*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // An ORC-based JIT for compiling LLVM IR.
0010 //
0011 //===----------------------------------------------------------------------===//
0012 
0013 #ifndef LLVM_EXECUTIONENGINE_ORC_LLJIT_H
0014 #define LLVM_EXECUTIONENGINE_ORC_LLJIT_H
0015 
0016 #include "llvm/ADT/SmallSet.h"
0017 #include "llvm/ExecutionEngine/Orc/AbsoluteSymbols.h"
0018 #include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h"
0019 #include "llvm/ExecutionEngine/Orc/CompileUtils.h"
0020 #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
0021 #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
0022 #include "llvm/ExecutionEngine/Orc/IRPartitionLayer.h"
0023 #include "llvm/ExecutionEngine/Orc/IRTransformLayer.h"
0024 #include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
0025 #include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h"
0026 #include "llvm/Support/Debug.h"
0027 #include "llvm/Support/ThreadPool.h"
0028 #include <variant>
0029 
0030 namespace llvm {
0031 namespace orc {
0032 
0033 class LLJITBuilderState;
0034 class LLLazyJITBuilderState;
0035 class ObjectTransformLayer;
0036 class ExecutorProcessControl;
0037 
0038 /// A pre-fabricated ORC JIT stack that can serve as an alternative to MCJIT.
0039 ///
0040 /// Create instances using LLJITBuilder.
0041 class LLJIT {
0042   template <typename, typename, typename> friend class LLJITBuilderSetters;
0043 
0044   friend Expected<JITDylibSP> setUpGenericLLVMIRPlatform(LLJIT &J);
0045 
0046 public:
0047   /// Initializer support for LLJIT.
0048   class PlatformSupport {
0049   public:
0050     virtual ~PlatformSupport();
0051 
0052     virtual Error initialize(JITDylib &JD) = 0;
0053 
0054     virtual Error deinitialize(JITDylib &JD) = 0;
0055 
0056   protected:
0057     static void setInitTransform(LLJIT &J,
0058                                  IRTransformLayer::TransformFunction T);
0059   };
0060 
0061   /// Destruct this instance. If a multi-threaded instance, waits for all
0062   /// compile threads to complete.
0063   virtual ~LLJIT();
0064 
0065   /// Returns the ExecutionSession for this instance.
0066   ExecutionSession &getExecutionSession() { return *ES; }
0067 
0068   /// Returns a reference to the triple for this instance.
0069   const Triple &getTargetTriple() const { return TT; }
0070 
0071   /// Returns a reference to the DataLayout for this instance.
0072   const DataLayout &getDataLayout() const { return DL; }
0073 
0074   /// Returns a reference to the JITDylib representing the JIT'd main program.
0075   JITDylib &getMainJITDylib() { return *Main; }
0076 
0077   /// Returns the ProcessSymbols JITDylib, which by default reflects non-JIT'd
0078   /// symbols in the host process.
0079   ///
0080   /// Note: JIT'd code should not be added to the ProcessSymbols JITDylib. Use
0081   /// the main JITDylib or a custom JITDylib instead.
0082   JITDylibSP getProcessSymbolsJITDylib();
0083 
0084   /// Returns the Platform JITDylib, which will contain the ORC runtime (if
0085   /// given) and any platform symbols.
0086   ///
0087   /// Note: JIT'd code should not be added to the Platform JITDylib. Use the
0088   /// main JITDylib or a custom JITDylib instead.
0089   JITDylibSP getPlatformJITDylib();
0090 
0091   /// Returns the JITDylib with the given name, or nullptr if no JITDylib with
0092   /// that name exists.
0093   JITDylib *getJITDylibByName(StringRef Name) {
0094     return ES->getJITDylibByName(Name);
0095   }
0096 
0097   /// Load a (real) dynamic library and make its symbols available through a
0098   /// new JITDylib with the same name.
0099   ///
0100   /// If the given *executor* path contains a valid platform dynamic library
0101   /// then that library will be loaded, and a new bare JITDylib whose name is
0102   /// the given path will be created to make the library's symbols available to
0103   /// JIT'd code.
0104   Expected<JITDylib &> loadPlatformDynamicLibrary(const char *Path);
0105 
0106   /// Link a static library into the given JITDylib.
0107   ///
0108   /// If the given MemoryBuffer contains a valid static archive (or a universal
0109   /// binary with an archive slice that fits the LLJIT instance's platform /
0110   /// architecture) then it will be added to the given JITDylib using a
0111   /// StaticLibraryDefinitionGenerator.
0112   Error linkStaticLibraryInto(JITDylib &JD,
0113                               std::unique_ptr<MemoryBuffer> LibBuffer);
0114 
0115   /// Link a static library into the given JITDylib.
0116   ///
0117   /// If the given *host* path contains a valid static archive (or a universal
0118   /// binary with an archive slice that fits the LLJIT instance's platform /
0119   /// architecture) then it will be added to the given JITDylib using a
0120   /// StaticLibraryDefinitionGenerator.
0121   Error linkStaticLibraryInto(JITDylib &JD, const char *Path);
0122 
0123   /// Create a new JITDylib with the given name and return a reference to it.
0124   ///
0125   /// JITDylib names must be unique. If the given name is derived from user
0126   /// input or elsewhere in the environment then the client should check
0127   /// (e.g. by calling getJITDylibByName) that the given name is not already in
0128   /// use.
0129   Expected<JITDylib &> createJITDylib(std::string Name);
0130 
0131   /// Returns the default link order for this LLJIT instance. This link order
0132   /// will be appended to the link order of JITDylibs created by LLJIT's
0133   /// createJITDylib method.
0134   JITDylibSearchOrder defaultLinkOrder() { return DefaultLinks; }
0135 
0136   /// Adds an IR module with the given ResourceTracker.
0137   Error addIRModule(ResourceTrackerSP RT, ThreadSafeModule TSM);
0138 
0139   /// Adds an IR module to the given JITDylib.
0140   Error addIRModule(JITDylib &JD, ThreadSafeModule TSM);
0141 
0142   /// Adds an IR module to the Main JITDylib.
0143   Error addIRModule(ThreadSafeModule TSM) {
0144     return addIRModule(*Main, std::move(TSM));
0145   }
0146 
0147   /// Adds an object file to the given JITDylib.
0148   Error addObjectFile(ResourceTrackerSP RT, std::unique_ptr<MemoryBuffer> Obj);
0149 
0150   /// Adds an object file to the given JITDylib.
0151   Error addObjectFile(JITDylib &JD, std::unique_ptr<MemoryBuffer> Obj);
0152 
0153   /// Adds an object file to the given JITDylib.
0154   Error addObjectFile(std::unique_ptr<MemoryBuffer> Obj) {
0155     return addObjectFile(*Main, std::move(Obj));
0156   }
0157 
0158   /// Look up a symbol in JITDylib JD by the symbol's linker-mangled name (to
0159   /// look up symbols based on their IR name use the lookup function instead).
0160   Expected<ExecutorAddr> lookupLinkerMangled(JITDylib &JD,
0161                                              SymbolStringPtr Name);
0162 
0163   /// Look up a symbol in JITDylib JD by the symbol's linker-mangled name (to
0164   /// look up symbols based on their IR name use the lookup function instead).
0165   Expected<ExecutorAddr> lookupLinkerMangled(JITDylib &JD,
0166                                              StringRef Name) {
0167     return lookupLinkerMangled(JD, ES->intern(Name));
0168   }
0169 
0170   /// Look up a symbol in the main JITDylib by the symbol's linker-mangled name
0171   /// (to look up symbols based on their IR name use the lookup function
0172   /// instead).
0173   Expected<ExecutorAddr> lookupLinkerMangled(StringRef Name) {
0174     return lookupLinkerMangled(*Main, Name);
0175   }
0176 
0177   /// Look up a symbol in JITDylib JD based on its IR symbol name.
0178   Expected<ExecutorAddr> lookup(JITDylib &JD, StringRef UnmangledName) {
0179     return lookupLinkerMangled(JD, mangle(UnmangledName));
0180   }
0181 
0182   /// Look up a symbol in the main JITDylib based on its IR symbol name.
0183   Expected<ExecutorAddr> lookup(StringRef UnmangledName) {
0184     return lookup(*Main, UnmangledName);
0185   }
0186 
0187   /// Set the PlatformSupport instance.
0188   void setPlatformSupport(std::unique_ptr<PlatformSupport> PS) {
0189     this->PS = std::move(PS);
0190   }
0191 
0192   /// Get the PlatformSupport instance.
0193   PlatformSupport *getPlatformSupport() { return PS.get(); }
0194 
0195   /// Run the initializers for the given JITDylib.
0196   Error initialize(JITDylib &JD) {
0197     DEBUG_WITH_TYPE("orc", {
0198       dbgs() << "LLJIT running initializers for JITDylib \"" << JD.getName()
0199              << "\"\n";
0200     });
0201     assert(PS && "PlatformSupport must be set to run initializers.");
0202     return PS->initialize(JD);
0203   }
0204 
0205   /// Run the deinitializers for the given JITDylib.
0206   Error deinitialize(JITDylib &JD) {
0207     DEBUG_WITH_TYPE("orc", {
0208       dbgs() << "LLJIT running deinitializers for JITDylib \"" << JD.getName()
0209              << "\"\n";
0210     });
0211     assert(PS && "PlatformSupport must be set to run initializers.");
0212     return PS->deinitialize(JD);
0213   }
0214 
0215   /// Returns a reference to the ObjLinkingLayer
0216   ObjectLayer &getObjLinkingLayer() { return *ObjLinkingLayer; }
0217 
0218   /// Returns a reference to the object transform layer.
0219   ObjectTransformLayer &getObjTransformLayer() { return *ObjTransformLayer; }
0220 
0221   /// Returns a reference to the IR transform layer.
0222   IRTransformLayer &getIRTransformLayer() { return *TransformLayer; }
0223 
0224   /// Returns a reference to the IR compile layer.
0225   IRCompileLayer &getIRCompileLayer() { return *CompileLayer; }
0226 
0227   /// Returns a linker-mangled version of UnmangledName.
0228   std::string mangle(StringRef UnmangledName) const;
0229 
0230   /// Returns an interned, linker-mangled version of UnmangledName.
0231   SymbolStringPtr mangleAndIntern(StringRef UnmangledName) const {
0232     return ES->intern(mangle(UnmangledName));
0233   }
0234 
0235 protected:
0236   static Expected<std::unique_ptr<ObjectLayer>>
0237   createObjectLinkingLayer(LLJITBuilderState &S, ExecutionSession &ES);
0238 
0239   static Expected<std::unique_ptr<IRCompileLayer::IRCompiler>>
0240   createCompileFunction(LLJITBuilderState &S, JITTargetMachineBuilder JTMB);
0241 
0242   /// Create an LLJIT instance with a single compile thread.
0243   LLJIT(LLJITBuilderState &S, Error &Err);
0244 
0245   Error applyDataLayout(Module &M);
0246 
0247   std::unique_ptr<ExecutionSession> ES;
0248   std::unique_ptr<PlatformSupport> PS;
0249 
0250   JITDylib *ProcessSymbols = nullptr;
0251   JITDylib *Platform = nullptr;
0252   JITDylib *Main = nullptr;
0253 
0254   JITDylibSearchOrder DefaultLinks;
0255 
0256   DataLayout DL;
0257   Triple TT;
0258 
0259   std::unique_ptr<ObjectLayer> ObjLinkingLayer;
0260   std::unique_ptr<ObjectTransformLayer> ObjTransformLayer;
0261   std::unique_ptr<IRCompileLayer> CompileLayer;
0262   std::unique_ptr<IRTransformLayer> TransformLayer;
0263   std::unique_ptr<IRTransformLayer> InitHelperTransformLayer;
0264 };
0265 
0266 /// An extended version of LLJIT that supports lazy function-at-a-time
0267 /// compilation of LLVM IR.
0268 class LLLazyJIT : public LLJIT {
0269   template <typename, typename, typename> friend class LLJITBuilderSetters;
0270 
0271 public:
0272 
0273   /// Sets the partition function.
0274   void setPartitionFunction(IRPartitionLayer::PartitionFunction Partition) {
0275     IPLayer->setPartitionFunction(std::move(Partition));
0276   }
0277 
0278   /// Returns a reference to the on-demand layer.
0279   CompileOnDemandLayer &getCompileOnDemandLayer() { return *CODLayer; }
0280 
0281   /// Add a module to be lazily compiled to JITDylib JD.
0282   Error addLazyIRModule(JITDylib &JD, ThreadSafeModule M);
0283 
0284   /// Add a module to be lazily compiled to the main JITDylib.
0285   Error addLazyIRModule(ThreadSafeModule M) {
0286     return addLazyIRModule(*Main, std::move(M));
0287   }
0288 
0289 private:
0290 
0291   // Create a single-threaded LLLazyJIT instance.
0292   LLLazyJIT(LLLazyJITBuilderState &S, Error &Err);
0293 
0294   std::unique_ptr<LazyCallThroughManager> LCTMgr;
0295   std::unique_ptr<IRPartitionLayer> IPLayer;
0296   std::unique_ptr<CompileOnDemandLayer> CODLayer;
0297 };
0298 
0299 class LLJITBuilderState {
0300 public:
0301   using ObjectLinkingLayerCreator =
0302       std::function<Expected<std::unique_ptr<ObjectLayer>>(ExecutionSession &,
0303                                                            const Triple &)>;
0304 
0305   using CompileFunctionCreator =
0306       std::function<Expected<std::unique_ptr<IRCompileLayer::IRCompiler>>(
0307           JITTargetMachineBuilder JTMB)>;
0308 
0309   using ProcessSymbolsJITDylibSetupFunction =
0310       unique_function<Expected<JITDylibSP>(LLJIT &J)>;
0311 
0312   using PlatformSetupFunction = unique_function<Expected<JITDylibSP>(LLJIT &J)>;
0313 
0314   using NotifyCreatedFunction = std::function<Error(LLJIT &)>;
0315 
0316   std::unique_ptr<ExecutorProcessControl> EPC;
0317   std::unique_ptr<ExecutionSession> ES;
0318   std::optional<JITTargetMachineBuilder> JTMB;
0319   std::optional<DataLayout> DL;
0320   bool LinkProcessSymbolsByDefault = true;
0321   ProcessSymbolsJITDylibSetupFunction SetupProcessSymbolsJITDylib;
0322   ObjectLinkingLayerCreator CreateObjectLinkingLayer;
0323   CompileFunctionCreator CreateCompileFunction;
0324   unique_function<Error(LLJIT &)> PrePlatformSetup;
0325   PlatformSetupFunction SetUpPlatform;
0326   NotifyCreatedFunction NotifyCreated;
0327   unsigned NumCompileThreads = 0;
0328   std::optional<bool> SupportConcurrentCompilation;
0329 
0330   /// Called prior to JIT class construcion to fix up defaults.
0331   Error prepareForConstruction();
0332 };
0333 
0334 template <typename JITType, typename SetterImpl, typename State>
0335 class LLJITBuilderSetters {
0336 public:
0337   /// Set an ExecutorProcessControl for this instance.
0338   /// This should not be called if ExecutionSession has already been set.
0339   SetterImpl &
0340   setExecutorProcessControl(std::unique_ptr<ExecutorProcessControl> EPC) {
0341     assert(
0342         !impl().ES &&
0343         "setExecutorProcessControl should not be called if an ExecutionSession "
0344         "has already been set");
0345     impl().EPC = std::move(EPC);
0346     return impl();
0347   }
0348 
0349   /// Set an ExecutionSession for this instance.
0350   SetterImpl &setExecutionSession(std::unique_ptr<ExecutionSession> ES) {
0351     assert(
0352         !impl().EPC &&
0353         "setExecutionSession should not be called if an ExecutorProcessControl "
0354         "object has already been set");
0355     impl().ES = std::move(ES);
0356     return impl();
0357   }
0358 
0359   /// Set the JITTargetMachineBuilder for this instance.
0360   ///
0361   /// If this method is not called, JITTargetMachineBuilder::detectHost will be
0362   /// used to construct a default target machine builder for the host platform.
0363   SetterImpl &setJITTargetMachineBuilder(JITTargetMachineBuilder JTMB) {
0364     impl().JTMB = std::move(JTMB);
0365     return impl();
0366   }
0367 
0368   /// Return a reference to the JITTargetMachineBuilder.
0369   ///
0370   std::optional<JITTargetMachineBuilder> &getJITTargetMachineBuilder() {
0371     return impl().JTMB;
0372   }
0373 
0374   /// Set a DataLayout for this instance. If no data layout is specified then
0375   /// the target's default data layout will be used.
0376   SetterImpl &setDataLayout(std::optional<DataLayout> DL) {
0377     impl().DL = std::move(DL);
0378     return impl();
0379   }
0380 
0381   /// The LinkProcessSymbolsDyDefault flag determines whether the "Process"
0382   /// JITDylib will be added to the default link order at LLJIT construction
0383   /// time. If true, the Process JITDylib will be added as the last item in the
0384   /// default link order. If false (or if the Process JITDylib is disabled via
0385   /// setProcessSymbolsJITDylibSetup) then the Process JITDylib will not appear
0386   /// in the default link order.
0387   SetterImpl &setLinkProcessSymbolsByDefault(bool LinkProcessSymbolsByDefault) {
0388     impl().LinkProcessSymbolsByDefault = LinkProcessSymbolsByDefault;
0389     return impl();
0390   }
0391 
0392   /// Set a setup function for the process symbols dylib. If not provided,
0393   /// but LinkProcessSymbolsJITDylibByDefault is true, then the process-symbols
0394   /// JITDylib will be configured with a DynamicLibrarySearchGenerator with a
0395   /// default symbol filter.
0396   SetterImpl &setProcessSymbolsJITDylibSetup(
0397       LLJITBuilderState::ProcessSymbolsJITDylibSetupFunction
0398           SetupProcessSymbolsJITDylib) {
0399     impl().SetupProcessSymbolsJITDylib = std::move(SetupProcessSymbolsJITDylib);
0400     return impl();
0401   }
0402 
0403   /// Set an ObjectLinkingLayer creation function.
0404   ///
0405   /// If this method is not called, a default creation function will be used
0406   /// that will construct an RTDyldObjectLinkingLayer.
0407   SetterImpl &setObjectLinkingLayerCreator(
0408       LLJITBuilderState::ObjectLinkingLayerCreator CreateObjectLinkingLayer) {
0409     impl().CreateObjectLinkingLayer = std::move(CreateObjectLinkingLayer);
0410     return impl();
0411   }
0412 
0413   /// Set a CompileFunctionCreator.
0414   ///
0415   /// If this method is not called, a default creation function wil be used
0416   /// that will construct a basic IR compile function that is compatible with
0417   /// the selected number of threads (SimpleCompiler for '0' compile threads,
0418   /// ConcurrentIRCompiler otherwise).
0419   SetterImpl &setCompileFunctionCreator(
0420       LLJITBuilderState::CompileFunctionCreator CreateCompileFunction) {
0421     impl().CreateCompileFunction = std::move(CreateCompileFunction);
0422     return impl();
0423   }
0424 
0425   /// Set a setup function to be run just before the PlatformSetupFunction is
0426   /// run.
0427   ///
0428   /// This can be used to customize the LLJIT instance before the platform is
0429   /// set up. E.g. By installing a debugger support plugin before the platform
0430   /// is set up (when the ORC runtime is loaded) we enable debugging of the
0431   /// runtime itself.
0432   SetterImpl &
0433   setPrePlatformSetup(unique_function<Error(LLJIT &)> PrePlatformSetup) {
0434     impl().PrePlatformSetup = std::move(PrePlatformSetup);
0435     return impl();
0436   }
0437 
0438   /// Set up an PlatformSetupFunction.
0439   ///
0440   /// If this method is not called then setUpGenericLLVMIRPlatform
0441   /// will be used to configure the JIT's platform support.
0442   SetterImpl &
0443   setPlatformSetUp(LLJITBuilderState::PlatformSetupFunction SetUpPlatform) {
0444     impl().SetUpPlatform = std::move(SetUpPlatform);
0445     return impl();
0446   }
0447 
0448   /// Set up a callback after successful construction of the JIT.
0449   ///
0450   /// This is useful to attach generators to JITDylibs or inject initial symbol
0451   /// definitions.
0452   SetterImpl &
0453   setNotifyCreatedCallback(LLJITBuilderState::NotifyCreatedFunction Callback) {
0454     impl().NotifyCreated = std::move(Callback);
0455     return impl();
0456   }
0457 
0458   /// Set the number of compile threads to use.
0459   ///
0460   /// If set to zero, compilation will be performed on the execution thread when
0461   /// JITing in-process. If set to any other number N, a thread pool of N
0462   /// threads will be created for compilation.
0463   ///
0464   /// If this method is not called, behavior will be as if it were called with
0465   /// a zero argument.
0466   ///
0467   /// This setting should not be used if a custom ExecutionSession or
0468   /// ExecutorProcessControl object is set: in those cases a custom
0469   /// TaskDispatcher should be used instead.
0470   SetterImpl &setNumCompileThreads(unsigned NumCompileThreads) {
0471     impl().NumCompileThreads = NumCompileThreads;
0472     return impl();
0473   }
0474 
0475   /// If set, this forces LLJIT concurrent compilation support to be either on
0476   /// or off. This controls the selection of compile function (concurrent vs
0477   /// single threaded) and whether or not sub-modules are cloned to new
0478   /// contexts for lazy emission.
0479   ///
0480   /// If not explicitly set then concurrency support will be turned on if
0481   /// NumCompileThreads is set to a non-zero value, or if a custom
0482   /// ExecutionSession or ExecutorProcessControl instance is provided.
0483   SetterImpl &setSupportConcurrentCompilation(
0484       std::optional<bool> SupportConcurrentCompilation) {
0485     impl().SupportConcurrentCompilation = SupportConcurrentCompilation;
0486     return impl();
0487   }
0488 
0489   /// Create an instance of the JIT.
0490   Expected<std::unique_ptr<JITType>> create() {
0491     if (auto Err = impl().prepareForConstruction())
0492       return std::move(Err);
0493 
0494     Error Err = Error::success();
0495     std::unique_ptr<JITType> J(new JITType(impl(), Err));
0496     if (Err)
0497       return std::move(Err);
0498 
0499     if (impl().NotifyCreated)
0500       if (Error Err = impl().NotifyCreated(*J))
0501         return std::move(Err);
0502 
0503     return std::move(J);
0504   }
0505 
0506 protected:
0507   SetterImpl &impl() { return static_cast<SetterImpl &>(*this); }
0508 };
0509 
0510 /// Constructs LLJIT instances.
0511 class LLJITBuilder
0512     : public LLJITBuilderState,
0513       public LLJITBuilderSetters<LLJIT, LLJITBuilder, LLJITBuilderState> {};
0514 
0515 class LLLazyJITBuilderState : public LLJITBuilderState {
0516   friend class LLLazyJIT;
0517 
0518 public:
0519   using IndirectStubsManagerBuilderFunction =
0520       std::function<std::unique_ptr<IndirectStubsManager>()>;
0521 
0522   Triple TT;
0523   ExecutorAddr LazyCompileFailureAddr;
0524   std::unique_ptr<LazyCallThroughManager> LCTMgr;
0525   IndirectStubsManagerBuilderFunction ISMBuilder;
0526 
0527   Error prepareForConstruction();
0528 };
0529 
0530 template <typename JITType, typename SetterImpl, typename State>
0531 class LLLazyJITBuilderSetters
0532     : public LLJITBuilderSetters<JITType, SetterImpl, State> {
0533 public:
0534   /// Set the address in the target address to call if a lazy compile fails.
0535   ///
0536   /// If this method is not called then the value will default to 0.
0537   SetterImpl &setLazyCompileFailureAddr(ExecutorAddr Addr) {
0538     this->impl().LazyCompileFailureAddr = Addr;
0539     return this->impl();
0540   }
0541 
0542   /// Set the lazy-callthrough manager.
0543   ///
0544   /// If this method is not called then a default, in-process lazy callthrough
0545   /// manager for the host platform will be used.
0546   SetterImpl &
0547   setLazyCallthroughManager(std::unique_ptr<LazyCallThroughManager> LCTMgr) {
0548     this->impl().LCTMgr = std::move(LCTMgr);
0549     return this->impl();
0550   }
0551 
0552   /// Set the IndirectStubsManager builder function.
0553   ///
0554   /// If this method is not called then a default, in-process
0555   /// IndirectStubsManager builder for the host platform will be used.
0556   SetterImpl &setIndirectStubsManagerBuilder(
0557       LLLazyJITBuilderState::IndirectStubsManagerBuilderFunction ISMBuilder) {
0558     this->impl().ISMBuilder = std::move(ISMBuilder);
0559     return this->impl();
0560   }
0561 };
0562 
0563 /// Constructs LLLazyJIT instances.
0564 class LLLazyJITBuilder
0565     : public LLLazyJITBuilderState,
0566       public LLLazyJITBuilderSetters<LLLazyJIT, LLLazyJITBuilder,
0567                                      LLLazyJITBuilderState> {};
0568 
0569 /// Configure the LLJIT instance to use orc runtime support. This overload
0570 /// assumes that the client has manually configured a Platform object.
0571 Error setUpOrcPlatformManually(LLJIT &J);
0572 
0573 /// Configure the LLJIT instance to use the ORC runtime and the detected
0574 /// native target for the executor.
0575 class ExecutorNativePlatform {
0576 public:
0577   /// Set up using path to Orc runtime.
0578   ExecutorNativePlatform(std::string OrcRuntimePath)
0579       : OrcRuntime(std::move(OrcRuntimePath)) {}
0580 
0581   /// Set up using the given memory buffer.
0582   ExecutorNativePlatform(std::unique_ptr<MemoryBuffer> OrcRuntimeMB)
0583       : OrcRuntime(std::move(OrcRuntimeMB)) {}
0584 
0585   // TODO: add compiler-rt.
0586 
0587   /// Add a path to the VC runtime.
0588   ExecutorNativePlatform &addVCRuntime(std::string VCRuntimePath,
0589                                        bool StaticVCRuntime) {
0590     VCRuntime = {std::move(VCRuntimePath), StaticVCRuntime};
0591     return *this;
0592   }
0593 
0594   Expected<JITDylibSP> operator()(LLJIT &J);
0595 
0596 private:
0597   std::variant<std::string, std::unique_ptr<MemoryBuffer>> OrcRuntime;
0598   std::optional<std::pair<std::string, bool>> VCRuntime;
0599 };
0600 
0601 /// Configure the LLJIT instance to scrape modules for llvm.global_ctors and
0602 /// llvm.global_dtors variables and (if present) build initialization and
0603 /// deinitialization functions. Platform specific initialization configurations
0604 /// should be preferred where available.
0605 Expected<JITDylibSP> setUpGenericLLVMIRPlatform(LLJIT &J);
0606 
0607 /// Configure the LLJIT instance to disable platform support explicitly. This is
0608 /// useful in two cases: for platforms that don't have such requirements and for
0609 /// platforms, that we have no explicit support yet and that don't work well
0610 /// with the generic IR platform.
0611 Expected<JITDylibSP> setUpInactivePlatform(LLJIT &J);
0612 
0613 /// A Platform-support class that implements initialize / deinitialize by
0614 /// forwarding to ORC runtime dlopen / dlclose operations.
0615 class ORCPlatformSupport : public LLJIT::PlatformSupport {
0616 public:
0617   ORCPlatformSupport(orc::LLJIT &J) : J(J) {}
0618   Error initialize(orc::JITDylib &JD) override;
0619   Error deinitialize(orc::JITDylib &JD) override;
0620 
0621 private:
0622   orc::LLJIT &J;
0623   DenseMap<orc::JITDylib *, orc::ExecutorAddr> DSOHandles;
0624   SmallPtrSet<JITDylib const *, 8> InitializedDylib;
0625 };
0626 
0627 } // End namespace orc
0628 } // End namespace llvm
0629 
0630 #endif // LLVM_EXECUTIONENGINE_ORC_LLJIT_H