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