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