1 //===- IRCompileLayer.h -- Eagerly compile IR for JIT -----------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // Contains the definition for a basic, eagerly compiling layer of the JIT. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_EXECUTIONENGINE_ORC_IRCOMPILELAYER_H 15 #define LLVM_EXECUTIONENGINE_ORC_IRCOMPILELAYER_H 16 17 #include "llvm/ADT/STLExtras.h" 18 #include "llvm/ExecutionEngine/JITSymbol.h" 19 #include "llvm/ExecutionEngine/Orc/Layer.h" 20 #include "llvm/Support/Error.h" 21 #include "llvm/Support/MemoryBuffer.h" 22 #include <memory> 23 #include <string> 24 25 namespace llvm { 26 27 class Module; 28 29 namespace orc { 30 31 class IRCompileLayer : public IRLayer { 32 public: 33 using CompileFunction = 34 std::function<Expected<std::unique_ptr<MemoryBuffer>>(Module &)>; 35 36 using NotifyCompiledFunction = 37 std::function<void(VModuleKey K, ThreadSafeModule TSM)>; 38 39 IRCompileLayer(ExecutionSession &ES, ObjectLayer &BaseLayer, 40 CompileFunction Compile); 41 42 void setNotifyCompiled(NotifyCompiledFunction NotifyCompiled); 43 44 void emit(MaterializationResponsibility R, ThreadSafeModule TSM) override; 45 46 private: 47 mutable std::mutex IRLayerMutex; 48 ObjectLayer &BaseLayer; 49 CompileFunction Compile; 50 NotifyCompiledFunction NotifyCompiled = NotifyCompiledFunction(); 51 }; 52 53 /// Eager IR compiling layer. 54 /// 55 /// This layer immediately compiles each IR module added via addModule to an 56 /// object file and adds this module file to the layer below, which must 57 /// implement the object layer concept. 58 template <typename BaseLayerT, typename CompileFtor> 59 class LegacyIRCompileLayer { 60 public: 61 /// Callback type for notifications when modules are compiled. 62 using NotifyCompiledCallback = 63 std::function<void(VModuleKey K, std::unique_ptr<Module>)>; 64 65 /// Construct an LegacyIRCompileLayer with the given BaseLayer, which must 66 /// implement the ObjectLayer concept. 67 LegacyIRCompileLayer( 68 BaseLayerT &BaseLayer, CompileFtor Compile, 69 NotifyCompiledCallback NotifyCompiled = NotifyCompiledCallback()) BaseLayer(BaseLayer)70 : BaseLayer(BaseLayer), Compile(std::move(Compile)), 71 NotifyCompiled(std::move(NotifyCompiled)) {} 72 73 /// Get a reference to the compiler functor. getCompiler()74 CompileFtor& getCompiler() { return Compile; } 75 76 /// (Re)set the NotifyCompiled callback. setNotifyCompiled(NotifyCompiledCallback NotifyCompiled)77 void setNotifyCompiled(NotifyCompiledCallback NotifyCompiled) { 78 this->NotifyCompiled = std::move(NotifyCompiled); 79 } 80 81 /// Compile the module, and add the resulting object to the base layer 82 /// along with the given memory manager and symbol resolver. addModule(VModuleKey K,std::unique_ptr<Module> M)83 Error addModule(VModuleKey K, std::unique_ptr<Module> M) { 84 if (auto Err = BaseLayer.addObject(std::move(K), Compile(*M))) 85 return Err; 86 if (NotifyCompiled) 87 NotifyCompiled(std::move(K), std::move(M)); 88 return Error::success(); 89 } 90 91 /// Remove the module associated with the VModuleKey K. removeModule(VModuleKey K)92 Error removeModule(VModuleKey K) { return BaseLayer.removeObject(K); } 93 94 /// Search for the given named symbol. 95 /// @param Name The name of the symbol to search for. 96 /// @param ExportedSymbolsOnly If true, search only for exported symbols. 97 /// @return A handle for the given named symbol, if it exists. findSymbol(const std::string & Name,bool ExportedSymbolsOnly)98 JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) { 99 return BaseLayer.findSymbol(Name, ExportedSymbolsOnly); 100 } 101 102 /// Get the address of the given symbol in compiled module represented 103 /// by the handle H. This call is forwarded to the base layer's 104 /// implementation. 105 /// @param K The VModuleKey for the module to search in. 106 /// @param Name The name of the symbol to search for. 107 /// @param ExportedSymbolsOnly If true, search only for exported symbols. 108 /// @return A handle for the given named symbol, if it is found in the 109 /// given module. findSymbolIn(VModuleKey K,const std::string & Name,bool ExportedSymbolsOnly)110 JITSymbol findSymbolIn(VModuleKey K, const std::string &Name, 111 bool ExportedSymbolsOnly) { 112 return BaseLayer.findSymbolIn(K, Name, ExportedSymbolsOnly); 113 } 114 115 /// Immediately emit and finalize the module represented by the given 116 /// handle. 117 /// @param K The VModuleKey for the module to emit/finalize. emitAndFinalize(VModuleKey K)118 Error emitAndFinalize(VModuleKey K) { return BaseLayer.emitAndFinalize(K); } 119 120 private: 121 BaseLayerT &BaseLayer; 122 CompileFtor Compile; 123 NotifyCompiledCallback NotifyCompiled; 124 }; 125 126 } // end namespace orc 127 128 } // end namespace llvm 129 130 #endif // LLVM_EXECUTIONENGINE_ORC_IRCOMPILINGLAYER_H 131