1 //===---------------- Layer.h -- Layer interfaces --------------*- 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 // Layer interfaces. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_EXECUTIONENGINE_ORC_LAYER_H 14 #define LLVM_EXECUTIONENGINE_ORC_LAYER_H 15 16 #include "llvm/ExecutionEngine/Orc/Core.h" 17 #include "llvm/ExecutionEngine/Orc/Mangling.h" 18 #include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h" 19 #include "llvm/IR/Module.h" 20 #include "llvm/Support/MemoryBuffer.h" 21 22 namespace llvm { 23 namespace orc { 24 25 /// IRMaterializationUnit is a convenient base class for MaterializationUnits 26 /// wrapping LLVM IR. Represents materialization responsibility for all symbols 27 /// in the given module. If symbols are overridden by other definitions, then 28 /// their linkage is changed to available-externally. 29 class IRMaterializationUnit : public MaterializationUnit { 30 public: 31 using SymbolNameToDefinitionMap = std::map<SymbolStringPtr, GlobalValue *>; 32 33 /// Create an IRMaterializationLayer. Scans the module to build the 34 /// SymbolFlags and SymbolToDefinition maps. 35 IRMaterializationUnit(ExecutionSession &ES, 36 const IRSymbolMapper::ManglingOptions &MO, 37 ThreadSafeModule TSM, VModuleKey K); 38 39 /// Create an IRMaterializationLayer from a module, and pre-existing 40 /// SymbolFlags and SymbolToDefinition maps. The maps must provide 41 /// entries for each definition in M. 42 /// This constructor is useful for delegating work from one 43 /// IRMaterializationUnit to another. 44 IRMaterializationUnit(ThreadSafeModule TSM, VModuleKey K, 45 SymbolFlagsMap SymbolFlags, SymbolStringPtr InitSymbol, 46 SymbolNameToDefinitionMap SymbolToDefinition); 47 48 /// Return the ModuleIdentifier as the name for this MaterializationUnit. 49 StringRef getName() const override; 50 51 /// Return a reference to the contained ThreadSafeModule. 52 const ThreadSafeModule &getModule() const { return TSM; } 53 54 protected: 55 ThreadSafeModule TSM; 56 SymbolNameToDefinitionMap SymbolToDefinition; 57 58 private: 59 static SymbolStringPtr getInitSymbol(ExecutionSession &ES, 60 const ThreadSafeModule &TSM); 61 62 void discard(const JITDylib &JD, const SymbolStringPtr &Name) override; 63 }; 64 65 /// Interface for layers that accept LLVM IR. 66 class IRLayer { 67 public: 68 IRLayer(ExecutionSession &ES, const IRSymbolMapper::ManglingOptions *&MO) 69 : ES(ES), MO(MO) {} 70 71 virtual ~IRLayer(); 72 73 /// Returns the ExecutionSession for this layer. 74 ExecutionSession &getExecutionSession() { return ES; } 75 76 /// Get the mangling options for this layer. 77 const IRSymbolMapper::ManglingOptions *&getManglingOptions() const { 78 return MO; 79 } 80 81 /// Sets the CloneToNewContextOnEmit flag (false by default). 82 /// 83 /// When set, IR modules added to this layer will be cloned on to a new 84 /// context before emit is called. This can be used by clients who want 85 /// to load all IR using one LLVMContext (to save memory via type and 86 /// constant uniquing), but want to move Modules to fresh contexts before 87 /// compiling them to enable concurrent compilation. 88 /// Single threaded clients, or clients who load every module on a new 89 /// context, need not set this. 90 void setCloneToNewContextOnEmit(bool CloneToNewContextOnEmit) { 91 this->CloneToNewContextOnEmit = CloneToNewContextOnEmit; 92 } 93 94 /// Returns the current value of the CloneToNewContextOnEmit flag. 95 bool getCloneToNewContextOnEmit() const { return CloneToNewContextOnEmit; } 96 97 /// Adds a MaterializationUnit representing the given IR to the given 98 /// JITDylib. 99 virtual Error add(JITDylib &JD, ThreadSafeModule TSM, 100 VModuleKey K = VModuleKey()); 101 102 /// Emit should materialize the given IR. 103 virtual void emit(MaterializationResponsibility R, ThreadSafeModule TSM) = 0; 104 105 private: 106 bool CloneToNewContextOnEmit = false; 107 ExecutionSession &ES; 108 const IRSymbolMapper::ManglingOptions *&MO; 109 }; 110 111 /// MaterializationUnit that materializes modules by calling the 'emit' method 112 /// on the given IRLayer. 113 class BasicIRLayerMaterializationUnit : public IRMaterializationUnit { 114 public: 115 BasicIRLayerMaterializationUnit(IRLayer &L, 116 const IRSymbolMapper::ManglingOptions &MO, 117 ThreadSafeModule TSM, VModuleKey K); 118 119 private: 120 121 void materialize(MaterializationResponsibility R) override; 122 123 IRLayer &L; 124 VModuleKey K; 125 }; 126 127 /// Interface for Layers that accept object files. 128 class ObjectLayer { 129 public: 130 ObjectLayer(ExecutionSession &ES); 131 virtual ~ObjectLayer(); 132 133 /// Returns the execution session for this layer. 134 ExecutionSession &getExecutionSession() { return ES; } 135 136 /// Adds a MaterializationUnit representing the given IR to the given 137 /// JITDylib. 138 virtual Error add(JITDylib &JD, std::unique_ptr<MemoryBuffer> O, 139 VModuleKey K = VModuleKey()); 140 141 /// Emit should materialize the given IR. 142 virtual void emit(MaterializationResponsibility R, 143 std::unique_ptr<MemoryBuffer> O) = 0; 144 145 private: 146 ExecutionSession &ES; 147 }; 148 149 /// Materializes the given object file (represented by a MemoryBuffer 150 /// instance) by calling 'emit' on the given ObjectLayer. 151 class BasicObjectLayerMaterializationUnit : public MaterializationUnit { 152 public: 153 static Expected<std::unique_ptr<BasicObjectLayerMaterializationUnit>> 154 Create(ObjectLayer &L, VModuleKey K, std::unique_ptr<MemoryBuffer> O); 155 156 BasicObjectLayerMaterializationUnit(ObjectLayer &L, VModuleKey K, 157 std::unique_ptr<MemoryBuffer> O, 158 SymbolFlagsMap SymbolFlags, 159 SymbolStringPtr InitSymbol); 160 161 /// Return the buffer's identifier as the name for this MaterializationUnit. 162 StringRef getName() const override; 163 164 private: 165 166 void materialize(MaterializationResponsibility R) override; 167 void discard(const JITDylib &JD, const SymbolStringPtr &Name) override; 168 169 ObjectLayer &L; 170 std::unique_ptr<MemoryBuffer> O; 171 }; 172 173 } // End namespace orc 174 } // End namespace llvm 175 176 #endif // LLVM_EXECUTIONENGINE_ORC_LAYER_H 177