Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  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.  
  26. namespace llvm {
  27. namespace orc {
  28.  
  29. class LLJITBuilderState;
  30. class LLLazyJITBuilderState;
  31. class ObjectTransformLayer;
  32. class ExecutorProcessControl;
  33.  
  34. /// A pre-fabricated ORC JIT stack that can serve as an alternative to MCJIT.
  35. ///
  36. /// Create instances using LLJITBuilder.
  37. class LLJIT {
  38.   template <typename, typename, typename> friend class LLJITBuilderSetters;
  39.  
  40.   friend void setUpGenericLLVMIRPlatform(LLJIT &J);
  41.  
  42. public:
  43.   /// Initializer support for LLJIT.
  44.   class PlatformSupport {
  45.   public:
  46.     virtual ~PlatformSupport();
  47.  
  48.     virtual Error initialize(JITDylib &JD) = 0;
  49.  
  50.     virtual Error deinitialize(JITDylib &JD) = 0;
  51.  
  52.   protected:
  53.     static void setInitTransform(LLJIT &J,
  54.                                  IRTransformLayer::TransformFunction T);
  55.   };
  56.  
  57.   /// Destruct this instance. If a multi-threaded instance, waits for all
  58.   /// compile threads to complete.
  59.   virtual ~LLJIT();
  60.  
  61.   /// Returns the ExecutionSession for this instance.
  62.   ExecutionSession &getExecutionSession() { return *ES; }
  63.  
  64.   /// Returns a reference to the triple for this instance.
  65.   const Triple &getTargetTriple() const { return TT; }
  66.  
  67.   /// Returns a reference to the DataLayout for this instance.
  68.   const DataLayout &getDataLayout() const { return DL; }
  69.  
  70.   /// Returns a reference to the JITDylib representing the JIT'd main program.
  71.   JITDylib &getMainJITDylib() { return *Main; }
  72.  
  73.   /// Returns the JITDylib with the given name, or nullptr if no JITDylib with
  74.   /// that name exists.
  75.   JITDylib *getJITDylibByName(StringRef Name) {
  76.     return ES->getJITDylibByName(Name);
  77.   }
  78.  
  79.   /// Create a new JITDylib with the given name and return a reference to it.
  80.   ///
  81.   /// JITDylib names must be unique. If the given name is derived from user
  82.   /// input or elsewhere in the environment then the client should check
  83.   /// (e.g. by calling getJITDylibByName) that the given name is not already in
  84.   /// use.
  85.   Expected<JITDylib &> createJITDylib(std::string Name) {
  86.     return ES->createJITDylib(std::move(Name));
  87.   }
  88.  
  89.   /// Adds an IR module with the given ResourceTracker.
  90.   Error addIRModule(ResourceTrackerSP RT, ThreadSafeModule TSM);
  91.  
  92.   /// Adds an IR module to the given JITDylib.
  93.   Error addIRModule(JITDylib &JD, ThreadSafeModule TSM);
  94.  
  95.   /// Adds an IR module to the Main JITDylib.
  96.   Error addIRModule(ThreadSafeModule TSM) {
  97.     return addIRModule(*Main, std::move(TSM));
  98.   }
  99.  
  100.   /// Adds an object file to the given JITDylib.
  101.   Error addObjectFile(ResourceTrackerSP RT, std::unique_ptr<MemoryBuffer> Obj);
  102.  
  103.   /// Adds an object file to the given JITDylib.
  104.   Error addObjectFile(JITDylib &JD, std::unique_ptr<MemoryBuffer> Obj);
  105.  
  106.   /// Adds an object file to the given JITDylib.
  107.   Error addObjectFile(std::unique_ptr<MemoryBuffer> Obj) {
  108.     return addObjectFile(*Main, std::move(Obj));
  109.   }
  110.  
  111.   /// Look up a symbol in JITDylib JD by the symbol's linker-mangled name (to
  112.   /// look up symbols based on their IR name use the lookup function instead).
  113.   Expected<ExecutorAddr> lookupLinkerMangled(JITDylib &JD,
  114.                                              SymbolStringPtr Name);
  115.  
  116.   /// Look up a symbol in JITDylib JD by the symbol's linker-mangled name (to
  117.   /// look up symbols based on their IR name use the lookup function instead).
  118.   Expected<ExecutorAddr> lookupLinkerMangled(JITDylib &JD,
  119.                                              StringRef Name) {
  120.     return lookupLinkerMangled(JD, ES->intern(Name));
  121.   }
  122.  
  123.   /// Look up a symbol in the main JITDylib by the symbol's linker-mangled name
  124.   /// (to look up symbols based on their IR name use the lookup function
  125.   /// instead).
  126.   Expected<ExecutorAddr> lookupLinkerMangled(StringRef Name) {
  127.     return lookupLinkerMangled(*Main, Name);
  128.   }
  129.  
  130.   /// Look up a symbol in JITDylib JD based on its IR symbol name.
  131.   Expected<ExecutorAddr> lookup(JITDylib &JD, StringRef UnmangledName) {
  132.     return lookupLinkerMangled(JD, mangle(UnmangledName));
  133.   }
  134.  
  135.   /// Look up a symbol in the main JITDylib based on its IR symbol name.
  136.   Expected<ExecutorAddr> lookup(StringRef UnmangledName) {
  137.     return lookup(*Main, UnmangledName);
  138.   }
  139.  
  140.   /// Set the PlatformSupport instance.
  141.   void setPlatformSupport(std::unique_ptr<PlatformSupport> PS) {
  142.     this->PS = std::move(PS);
  143.   }
  144.  
  145.   /// Get the PlatformSupport instance.
  146.   PlatformSupport *getPlatformSupport() { return PS.get(); }
  147.  
  148.   /// Run the initializers for the given JITDylib.
  149.   Error initialize(JITDylib &JD) {
  150.     DEBUG_WITH_TYPE("orc", {
  151.       dbgs() << "LLJIT running initializers for JITDylib \"" << JD.getName()
  152.              << "\"\n";
  153.     });
  154.     assert(PS && "PlatformSupport must be set to run initializers.");
  155.     return PS->initialize(JD);
  156.   }
  157.  
  158.   /// Run the deinitializers for the given JITDylib.
  159.   Error deinitialize(JITDylib &JD) {
  160.     DEBUG_WITH_TYPE("orc", {
  161.       dbgs() << "LLJIT running deinitializers for JITDylib \"" << JD.getName()
  162.              << "\"\n";
  163.     });
  164.     assert(PS && "PlatformSupport must be set to run initializers.");
  165.     return PS->deinitialize(JD);
  166.   }
  167.  
  168.   /// Returns a reference to the ObjLinkingLayer
  169.   ObjectLayer &getObjLinkingLayer() { return *ObjLinkingLayer; }
  170.  
  171.   /// Returns a reference to the object transform layer.
  172.   ObjectTransformLayer &getObjTransformLayer() { return *ObjTransformLayer; }
  173.  
  174.   /// Returns a reference to the IR transform layer.
  175.   IRTransformLayer &getIRTransformLayer() { return *TransformLayer; }
  176.  
  177.   /// Returns a reference to the IR compile layer.
  178.   IRCompileLayer &getIRCompileLayer() { return *CompileLayer; }
  179.  
  180.   /// Returns a linker-mangled version of UnmangledName.
  181.   std::string mangle(StringRef UnmangledName) const;
  182.  
  183.   /// Returns an interned, linker-mangled version of UnmangledName.
  184.   SymbolStringPtr mangleAndIntern(StringRef UnmangledName) const {
  185.     return ES->intern(mangle(UnmangledName));
  186.   }
  187.  
  188. protected:
  189.   static Expected<std::unique_ptr<ObjectLayer>>
  190.   createObjectLinkingLayer(LLJITBuilderState &S, ExecutionSession &ES);
  191.  
  192.   static Expected<std::unique_ptr<IRCompileLayer::IRCompiler>>
  193.   createCompileFunction(LLJITBuilderState &S, JITTargetMachineBuilder JTMB);
  194.  
  195.   /// Create an LLJIT instance with a single compile thread.
  196.   LLJIT(LLJITBuilderState &S, Error &Err);
  197.  
  198.   Error applyDataLayout(Module &M);
  199.  
  200.   void recordCtorDtors(Module &M);
  201.  
  202.   std::unique_ptr<ExecutionSession> ES;
  203.   std::unique_ptr<PlatformSupport> PS;
  204.  
  205.   JITDylib *Main = nullptr;
  206.  
  207.   DataLayout DL;
  208.   Triple TT;
  209.   std::unique_ptr<ThreadPool> CompileThreads;
  210.  
  211.   std::unique_ptr<ObjectLayer> ObjLinkingLayer;
  212.   std::unique_ptr<ObjectTransformLayer> ObjTransformLayer;
  213.   std::unique_ptr<IRCompileLayer> CompileLayer;
  214.   std::unique_ptr<IRTransformLayer> TransformLayer;
  215.   std::unique_ptr<IRTransformLayer> InitHelperTransformLayer;
  216. };
  217.  
  218. /// An extended version of LLJIT that supports lazy function-at-a-time
  219. /// compilation of LLVM IR.
  220. class LLLazyJIT : public LLJIT {
  221.   template <typename, typename, typename> friend class LLJITBuilderSetters;
  222.  
  223. public:
  224.  
  225.   /// Sets the partition function.
  226.   void
  227.   setPartitionFunction(CompileOnDemandLayer::PartitionFunction Partition) {
  228.     CODLayer->setPartitionFunction(std::move(Partition));
  229.   }
  230.  
  231.   /// Returns a reference to the on-demand layer.
  232.   CompileOnDemandLayer &getCompileOnDemandLayer() { return *CODLayer; }
  233.  
  234.   /// Add a module to be lazily compiled to JITDylib JD.
  235.   Error addLazyIRModule(JITDylib &JD, ThreadSafeModule M);
  236.  
  237.   /// Add a module to be lazily compiled to the main JITDylib.
  238.   Error addLazyIRModule(ThreadSafeModule M) {
  239.     return addLazyIRModule(*Main, std::move(M));
  240.   }
  241.  
  242. private:
  243.  
  244.   // Create a single-threaded LLLazyJIT instance.
  245.   LLLazyJIT(LLLazyJITBuilderState &S, Error &Err);
  246.  
  247.   std::unique_ptr<LazyCallThroughManager> LCTMgr;
  248.   std::unique_ptr<CompileOnDemandLayer> CODLayer;
  249. };
  250.  
  251. class LLJITBuilderState {
  252. public:
  253.   using ObjectLinkingLayerCreator =
  254.       std::function<Expected<std::unique_ptr<ObjectLayer>>(ExecutionSession &,
  255.                                                            const Triple &)>;
  256.  
  257.   using CompileFunctionCreator =
  258.       std::function<Expected<std::unique_ptr<IRCompileLayer::IRCompiler>>(
  259.           JITTargetMachineBuilder JTMB)>;
  260.  
  261.   using PlatformSetupFunction = std::function<Error(LLJIT &J)>;
  262.  
  263.   std::unique_ptr<ExecutorProcessControl> EPC;
  264.   std::unique_ptr<ExecutionSession> ES;
  265.   std::optional<JITTargetMachineBuilder> JTMB;
  266.   std::optional<DataLayout> DL;
  267.   ObjectLinkingLayerCreator CreateObjectLinkingLayer;
  268.   CompileFunctionCreator CreateCompileFunction;
  269.   PlatformSetupFunction SetUpPlatform;
  270.   unsigned NumCompileThreads = 0;
  271.  
  272.   /// Called prior to JIT class construcion to fix up defaults.
  273.   Error prepareForConstruction();
  274. };
  275.  
  276. template <typename JITType, typename SetterImpl, typename State>
  277. class LLJITBuilderSetters {
  278. public:
  279.   /// Set a ExecutorProcessControl for this instance.
  280.   /// This should not be called if ExecutionSession has already been set.
  281.   SetterImpl &
  282.   setExecutorProcessControl(std::unique_ptr<ExecutorProcessControl> EPC) {
  283.     assert(
  284.         !impl().ES &&
  285.         "setExecutorProcessControl should not be called if an ExecutionSession "
  286.         "has already been set");
  287.     impl().EPC = std::move(EPC);
  288.     return impl();
  289.   }
  290.  
  291.   /// Set an ExecutionSession for this instance.
  292.   SetterImpl &setExecutionSession(std::unique_ptr<ExecutionSession> ES) {
  293.     impl().ES = std::move(ES);
  294.     return impl();
  295.   }
  296.  
  297.   /// Set the JITTargetMachineBuilder for this instance.
  298.   ///
  299.   /// If this method is not called, JITTargetMachineBuilder::detectHost will be
  300.   /// used to construct a default target machine builder for the host platform.
  301.   SetterImpl &setJITTargetMachineBuilder(JITTargetMachineBuilder JTMB) {
  302.     impl().JTMB = std::move(JTMB);
  303.     return impl();
  304.   }
  305.  
  306.   /// Return a reference to the JITTargetMachineBuilder.
  307.   ///
  308.   std::optional<JITTargetMachineBuilder> &getJITTargetMachineBuilder() {
  309.     return impl().JTMB;
  310.   }
  311.  
  312.   /// Set a DataLayout for this instance. If no data layout is specified then
  313.   /// the target's default data layout will be used.
  314.   SetterImpl &setDataLayout(std::optional<DataLayout> DL) {
  315.     impl().DL = std::move(DL);
  316.     return impl();
  317.   }
  318.  
  319.   /// Set an ObjectLinkingLayer creation function.
  320.   ///
  321.   /// If this method is not called, a default creation function will be used
  322.   /// that will construct an RTDyldObjectLinkingLayer.
  323.   SetterImpl &setObjectLinkingLayerCreator(
  324.       LLJITBuilderState::ObjectLinkingLayerCreator CreateObjectLinkingLayer) {
  325.     impl().CreateObjectLinkingLayer = std::move(CreateObjectLinkingLayer);
  326.     return impl();
  327.   }
  328.  
  329.   /// Set a CompileFunctionCreator.
  330.   ///
  331.   /// If this method is not called, a default creation function wil be used
  332.   /// that will construct a basic IR compile function that is compatible with
  333.   /// the selected number of threads (SimpleCompiler for '0' compile threads,
  334.   /// ConcurrentIRCompiler otherwise).
  335.   SetterImpl &setCompileFunctionCreator(
  336.       LLJITBuilderState::CompileFunctionCreator CreateCompileFunction) {
  337.     impl().CreateCompileFunction = std::move(CreateCompileFunction);
  338.     return impl();
  339.   }
  340.  
  341.   /// Set up an PlatformSetupFunction.
  342.   ///
  343.   /// If this method is not called then setUpGenericLLVMIRPlatform
  344.   /// will be used to configure the JIT's platform support.
  345.   SetterImpl &
  346.   setPlatformSetUp(LLJITBuilderState::PlatformSetupFunction SetUpPlatform) {
  347.     impl().SetUpPlatform = std::move(SetUpPlatform);
  348.     return impl();
  349.   }
  350.  
  351.   /// Set the number of compile threads to use.
  352.   ///
  353.   /// If set to zero, compilation will be performed on the execution thread when
  354.   /// JITing in-process. If set to any other number N, a thread pool of N
  355.   /// threads will be created for compilation.
  356.   ///
  357.   /// If this method is not called, behavior will be as if it were called with
  358.   /// a zero argument.
  359.   SetterImpl &setNumCompileThreads(unsigned NumCompileThreads) {
  360.     impl().NumCompileThreads = NumCompileThreads;
  361.     return impl();
  362.   }
  363.  
  364.   /// Set an ExecutorProcessControl object.
  365.   ///
  366.   /// If the platform uses ObjectLinkingLayer by default and no
  367.   /// ObjectLinkingLayerCreator has been set then the ExecutorProcessControl
  368.   /// object will be used to supply the memory manager for the
  369.   /// ObjectLinkingLayer.
  370.   SetterImpl &setExecutorProcessControl(ExecutorProcessControl &EPC) {
  371.     impl().EPC = &EPC;
  372.     return impl();
  373.   }
  374.  
  375.   /// Create an instance of the JIT.
  376.   Expected<std::unique_ptr<JITType>> create() {
  377.     if (auto Err = impl().prepareForConstruction())
  378.       return std::move(Err);
  379.  
  380.     Error Err = Error::success();
  381.     std::unique_ptr<JITType> J(new JITType(impl(), Err));
  382.     if (Err)
  383.       return std::move(Err);
  384.     return std::move(J);
  385.   }
  386.  
  387. protected:
  388.   SetterImpl &impl() { return static_cast<SetterImpl &>(*this); }
  389. };
  390.  
  391. /// Constructs LLJIT instances.
  392. class LLJITBuilder
  393.     : public LLJITBuilderState,
  394.       public LLJITBuilderSetters<LLJIT, LLJITBuilder, LLJITBuilderState> {};
  395.  
  396. class LLLazyJITBuilderState : public LLJITBuilderState {
  397.   friend class LLLazyJIT;
  398.  
  399. public:
  400.   using IndirectStubsManagerBuilderFunction =
  401.       std::function<std::unique_ptr<IndirectStubsManager>()>;
  402.  
  403.   Triple TT;
  404.   ExecutorAddr LazyCompileFailureAddr;
  405.   std::unique_ptr<LazyCallThroughManager> LCTMgr;
  406.   IndirectStubsManagerBuilderFunction ISMBuilder;
  407.  
  408.   Error prepareForConstruction();
  409. };
  410.  
  411. template <typename JITType, typename SetterImpl, typename State>
  412. class LLLazyJITBuilderSetters
  413.     : public LLJITBuilderSetters<JITType, SetterImpl, State> {
  414. public:
  415.   /// Set the address in the target address to call if a lazy compile fails.
  416.   ///
  417.   /// If this method is not called then the value will default to 0.
  418.   SetterImpl &setLazyCompileFailureAddr(ExecutorAddr Addr) {
  419.     this->impl().LazyCompileFailureAddr = Addr;
  420.     return this->impl();
  421.   }
  422.  
  423.   /// Set the lazy-callthrough manager.
  424.   ///
  425.   /// If this method is not called then a default, in-process lazy callthrough
  426.   /// manager for the host platform will be used.
  427.   SetterImpl &
  428.   setLazyCallthroughManager(std::unique_ptr<LazyCallThroughManager> LCTMgr) {
  429.     this->impl().LCTMgr = std::move(LCTMgr);
  430.     return this->impl();
  431.   }
  432.  
  433.   /// Set the IndirectStubsManager builder function.
  434.   ///
  435.   /// If this method is not called then a default, in-process
  436.   /// IndirectStubsManager builder for the host platform will be used.
  437.   SetterImpl &setIndirectStubsManagerBuilder(
  438.       LLLazyJITBuilderState::IndirectStubsManagerBuilderFunction ISMBuilder) {
  439.     this->impl().ISMBuilder = std::move(ISMBuilder);
  440.     return this->impl();
  441.   }
  442. };
  443.  
  444. /// Constructs LLLazyJIT instances.
  445. class LLLazyJITBuilder
  446.     : public LLLazyJITBuilderState,
  447.       public LLLazyJITBuilderSetters<LLLazyJIT, LLLazyJITBuilder,
  448.                                      LLLazyJITBuilderState> {};
  449.  
  450. /// Configure the LLJIT instance to use orc runtime support.
  451. Error setUpOrcPlatform(LLJIT& J);
  452.  
  453. /// Configure the LLJIT instance to scrape modules for llvm.global_ctors and
  454. /// llvm.global_dtors variables and (if present) build initialization and
  455. /// deinitialization functions. Platform specific initialization configurations
  456. /// should be preferred where available.
  457. void setUpGenericLLVMIRPlatform(LLJIT &J);
  458.  
  459. /// Configure the LLJIT instance to disable platform support explicitly. This is
  460. /// useful in two cases: for platforms that don't have such requirements and for
  461. /// platforms, that we have no explicit support yet and that don't work well
  462. /// with the generic IR platform.
  463. Error setUpInactivePlatform(LLJIT &J);
  464.  
  465. } // End namespace orc
  466. } // End namespace llvm
  467.  
  468. #endif // LLVM_EXECUTIONENGINE_ORC_LLJIT_H
  469.