109467b48Spatrick //===---------------- Layer.h -- Layer interfaces --------------*- C++ -*-===// 209467b48Spatrick // 309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information. 509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 609467b48Spatrick // 709467b48Spatrick //===----------------------------------------------------------------------===// 809467b48Spatrick // 909467b48Spatrick // Layer interfaces. 1009467b48Spatrick // 1109467b48Spatrick //===----------------------------------------------------------------------===// 1209467b48Spatrick 1309467b48Spatrick #ifndef LLVM_EXECUTIONENGINE_ORC_LAYER_H 1409467b48Spatrick #define LLVM_EXECUTIONENGINE_ORC_LAYER_H 1509467b48Spatrick 1609467b48Spatrick #include "llvm/ExecutionEngine/Orc/Core.h" 17097a140dSpatrick #include "llvm/ExecutionEngine/Orc/Mangling.h" 1809467b48Spatrick #include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h" 1909467b48Spatrick #include "llvm/IR/Module.h" 2073471bf0Spatrick #include "llvm/Support/Casting.h" 2173471bf0Spatrick #include "llvm/Support/ExtensibleRTTI.h" 2209467b48Spatrick #include "llvm/Support/MemoryBuffer.h" 2309467b48Spatrick 2409467b48Spatrick namespace llvm { 2509467b48Spatrick namespace orc { 2609467b48Spatrick 2709467b48Spatrick /// IRMaterializationUnit is a convenient base class for MaterializationUnits 2809467b48Spatrick /// wrapping LLVM IR. Represents materialization responsibility for all symbols 2909467b48Spatrick /// in the given module. If symbols are overridden by other definitions, then 3009467b48Spatrick /// their linkage is changed to available-externally. 3109467b48Spatrick class IRMaterializationUnit : public MaterializationUnit { 3209467b48Spatrick public: 3309467b48Spatrick using SymbolNameToDefinitionMap = std::map<SymbolStringPtr, GlobalValue *>; 3409467b48Spatrick 3509467b48Spatrick /// Create an IRMaterializationLayer. Scans the module to build the 3609467b48Spatrick /// SymbolFlags and SymbolToDefinition maps. 37097a140dSpatrick IRMaterializationUnit(ExecutionSession &ES, 38097a140dSpatrick const IRSymbolMapper::ManglingOptions &MO, 3973471bf0Spatrick ThreadSafeModule TSM); 4009467b48Spatrick 4109467b48Spatrick /// Create an IRMaterializationLayer from a module, and pre-existing 4209467b48Spatrick /// SymbolFlags and SymbolToDefinition maps. The maps must provide 4309467b48Spatrick /// entries for each definition in M. 4409467b48Spatrick /// This constructor is useful for delegating work from one 4509467b48Spatrick /// IRMaterializationUnit to another. 46*d415bd75Srobert IRMaterializationUnit(ThreadSafeModule TSM, Interface I, 4709467b48Spatrick SymbolNameToDefinitionMap SymbolToDefinition); 4809467b48Spatrick 4909467b48Spatrick /// Return the ModuleIdentifier as the name for this MaterializationUnit. 5009467b48Spatrick StringRef getName() const override; 5109467b48Spatrick 52097a140dSpatrick /// Return a reference to the contained ThreadSafeModule. getModule()5309467b48Spatrick const ThreadSafeModule &getModule() const { return TSM; } 5409467b48Spatrick 5509467b48Spatrick protected: 5609467b48Spatrick ThreadSafeModule TSM; 5709467b48Spatrick SymbolNameToDefinitionMap SymbolToDefinition; 5809467b48Spatrick 5909467b48Spatrick private: 60097a140dSpatrick static SymbolStringPtr getInitSymbol(ExecutionSession &ES, 61097a140dSpatrick const ThreadSafeModule &TSM); 62097a140dSpatrick 6309467b48Spatrick void discard(const JITDylib &JD, const SymbolStringPtr &Name) override; 6409467b48Spatrick }; 6509467b48Spatrick 6609467b48Spatrick /// Interface for layers that accept LLVM IR. 6709467b48Spatrick class IRLayer { 6809467b48Spatrick public: IRLayer(ExecutionSession & ES,const IRSymbolMapper::ManglingOptions * & MO)69097a140dSpatrick IRLayer(ExecutionSession &ES, const IRSymbolMapper::ManglingOptions *&MO) 7009467b48Spatrick : ES(ES), MO(MO) {} 7109467b48Spatrick 7209467b48Spatrick virtual ~IRLayer(); 7309467b48Spatrick 7409467b48Spatrick /// Returns the ExecutionSession for this layer. getExecutionSession()7509467b48Spatrick ExecutionSession &getExecutionSession() { return ES; } 7609467b48Spatrick 7709467b48Spatrick /// Get the mangling options for this layer. getManglingOptions()78097a140dSpatrick const IRSymbolMapper::ManglingOptions *&getManglingOptions() const { 7909467b48Spatrick return MO; 8009467b48Spatrick } 8109467b48Spatrick 8209467b48Spatrick /// Sets the CloneToNewContextOnEmit flag (false by default). 8309467b48Spatrick /// 8409467b48Spatrick /// When set, IR modules added to this layer will be cloned on to a new 8509467b48Spatrick /// context before emit is called. This can be used by clients who want 8609467b48Spatrick /// to load all IR using one LLVMContext (to save memory via type and 8709467b48Spatrick /// constant uniquing), but want to move Modules to fresh contexts before 8809467b48Spatrick /// compiling them to enable concurrent compilation. 8909467b48Spatrick /// Single threaded clients, or clients who load every module on a new 9009467b48Spatrick /// context, need not set this. setCloneToNewContextOnEmit(bool CloneToNewContextOnEmit)9109467b48Spatrick void setCloneToNewContextOnEmit(bool CloneToNewContextOnEmit) { 9209467b48Spatrick this->CloneToNewContextOnEmit = CloneToNewContextOnEmit; 9309467b48Spatrick } 9409467b48Spatrick 9509467b48Spatrick /// Returns the current value of the CloneToNewContextOnEmit flag. getCloneToNewContextOnEmit()9609467b48Spatrick bool getCloneToNewContextOnEmit() const { return CloneToNewContextOnEmit; } 9709467b48Spatrick 9873471bf0Spatrick /// Add a MaterializatinoUnit representing the given IR to the JITDylib 9973471bf0Spatrick /// targeted by the given tracker. 10073471bf0Spatrick virtual Error add(ResourceTrackerSP RT, ThreadSafeModule TSM); 10173471bf0Spatrick 10209467b48Spatrick /// Adds a MaterializationUnit representing the given IR to the given 10373471bf0Spatrick /// JITDylib. If RT is not specif add(JITDylib & JD,ThreadSafeModule TSM)10473471bf0Spatrick Error add(JITDylib &JD, ThreadSafeModule TSM) { 10573471bf0Spatrick return add(JD.getDefaultResourceTracker(), std::move(TSM)); 10673471bf0Spatrick } 10709467b48Spatrick 10809467b48Spatrick /// Emit should materialize the given IR. 10973471bf0Spatrick virtual void emit(std::unique_ptr<MaterializationResponsibility> R, 11073471bf0Spatrick ThreadSafeModule TSM) = 0; 11109467b48Spatrick 11209467b48Spatrick private: 11309467b48Spatrick bool CloneToNewContextOnEmit = false; 11409467b48Spatrick ExecutionSession &ES; 115097a140dSpatrick const IRSymbolMapper::ManglingOptions *&MO; 11609467b48Spatrick }; 11709467b48Spatrick 11809467b48Spatrick /// MaterializationUnit that materializes modules by calling the 'emit' method 11909467b48Spatrick /// on the given IRLayer. 12009467b48Spatrick class BasicIRLayerMaterializationUnit : public IRMaterializationUnit { 12109467b48Spatrick public: 122097a140dSpatrick BasicIRLayerMaterializationUnit(IRLayer &L, 123097a140dSpatrick const IRSymbolMapper::ManglingOptions &MO, 12473471bf0Spatrick ThreadSafeModule TSM); 12509467b48Spatrick 12609467b48Spatrick private: 12773471bf0Spatrick void materialize(std::unique_ptr<MaterializationResponsibility> R) override; 12809467b48Spatrick 12909467b48Spatrick IRLayer &L; 13009467b48Spatrick }; 13109467b48Spatrick 13209467b48Spatrick /// Interface for Layers that accept object files. 13373471bf0Spatrick class ObjectLayer : public RTTIExtends<ObjectLayer, RTTIRoot> { 13409467b48Spatrick public: 13573471bf0Spatrick static char ID; 13673471bf0Spatrick 13709467b48Spatrick ObjectLayer(ExecutionSession &ES); 13809467b48Spatrick virtual ~ObjectLayer(); 13909467b48Spatrick 14009467b48Spatrick /// Returns the execution session for this layer. getExecutionSession()14109467b48Spatrick ExecutionSession &getExecutionSession() { return ES; } 14209467b48Spatrick 143*d415bd75Srobert /// Adds a MaterializationUnit for the object file in the given memory buffer 144*d415bd75Srobert /// to the JITDylib for the given ResourceTracker. 145*d415bd75Srobert virtual Error add(ResourceTrackerSP RT, std::unique_ptr<MemoryBuffer> O, 146*d415bd75Srobert MaterializationUnit::Interface I); 14773471bf0Spatrick 148*d415bd75Srobert /// Adds a MaterializationUnit for the object file in the given memory buffer 149*d415bd75Srobert /// to the JITDylib for the given ResourceTracker. The interface for the 150*d415bd75Srobert /// object will be built using the default object interface builder. 151*d415bd75Srobert Error add(ResourceTrackerSP RT, std::unique_ptr<MemoryBuffer> O); 152*d415bd75Srobert 153*d415bd75Srobert /// Adds a MaterializationUnit for the object file in the given memory buffer 154*d415bd75Srobert /// to the given JITDylib. add(JITDylib & JD,std::unique_ptr<MemoryBuffer> O,MaterializationUnit::Interface I)155*d415bd75Srobert Error add(JITDylib &JD, std::unique_ptr<MemoryBuffer> O, 156*d415bd75Srobert MaterializationUnit::Interface I) { 157*d415bd75Srobert return add(JD.getDefaultResourceTracker(), std::move(O), std::move(I)); 15873471bf0Spatrick } 15909467b48Spatrick 160*d415bd75Srobert /// Adds a MaterializationUnit for the object file in the given memory buffer 161*d415bd75Srobert /// to the given JITDylib. The interface for the object will be built using 162*d415bd75Srobert /// the default object interface builder. 163*d415bd75Srobert Error add(JITDylib &JD, std::unique_ptr<MemoryBuffer> O); 164*d415bd75Srobert 16509467b48Spatrick /// Emit should materialize the given IR. 16673471bf0Spatrick virtual void emit(std::unique_ptr<MaterializationResponsibility> R, 16709467b48Spatrick std::unique_ptr<MemoryBuffer> O) = 0; 16809467b48Spatrick 16909467b48Spatrick private: 17009467b48Spatrick ExecutionSession &ES; 17109467b48Spatrick }; 17209467b48Spatrick 17309467b48Spatrick /// Materializes the given object file (represented by a MemoryBuffer 17409467b48Spatrick /// instance) by calling 'emit' on the given ObjectLayer. 17509467b48Spatrick class BasicObjectLayerMaterializationUnit : public MaterializationUnit { 17609467b48Spatrick public: 177*d415bd75Srobert /// Create using the default object interface builder function. 17809467b48Spatrick static Expected<std::unique_ptr<BasicObjectLayerMaterializationUnit>> 17973471bf0Spatrick Create(ObjectLayer &L, std::unique_ptr<MemoryBuffer> O); 18009467b48Spatrick 18173471bf0Spatrick BasicObjectLayerMaterializationUnit(ObjectLayer &L, 18209467b48Spatrick std::unique_ptr<MemoryBuffer> O, 183*d415bd75Srobert Interface I); 18409467b48Spatrick 18509467b48Spatrick /// Return the buffer's identifier as the name for this MaterializationUnit. 18609467b48Spatrick StringRef getName() const override; 18709467b48Spatrick 18809467b48Spatrick private: 18973471bf0Spatrick void materialize(std::unique_ptr<MaterializationResponsibility> R) override; 19009467b48Spatrick void discard(const JITDylib &JD, const SymbolStringPtr &Name) override; 19109467b48Spatrick 19209467b48Spatrick ObjectLayer &L; 19309467b48Spatrick std::unique_ptr<MemoryBuffer> O; 19409467b48Spatrick }; 19509467b48Spatrick 19609467b48Spatrick } // End namespace orc 19709467b48Spatrick } // End namespace llvm 19809467b48Spatrick 19909467b48Spatrick #endif // LLVM_EXECUTIONENGINE_ORC_LAYER_H 200