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