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 IRCompileLayer2 : 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, std::unique_ptr<Module>)>; 38 39 IRCompileLayer2(ExecutionSession &ES, ObjectLayer &BaseLayer, 40 CompileFunction Compile); 41 42 void setNotifyCompiled(NotifyCompiledFunction NotifyCompiled); 43 44 void emit(MaterializationResponsibility R, VModuleKey K, 45 std::unique_ptr<Module> M) override; 46 47 private: 48 mutable std::mutex IRLayerMutex; 49 ObjectLayer &BaseLayer; 50 CompileFunction Compile; 51 NotifyCompiledFunction NotifyCompiled = NotifyCompiledFunction(); 52 }; 53 54 /// Eager IR compiling layer. 55 /// 56 /// This layer immediately compiles each IR module added via addModule to an 57 /// object file and adds this module file to the layer below, which must 58 /// implement the object layer concept. 59 template <typename BaseLayerT, typename CompileFtor> 60 class IRCompileLayer { 61 public: 62 /// Callback type for notifications when modules are compiled. 63 using NotifyCompiledCallback = 64 std::function<void(VModuleKey K, std::unique_ptr<Module>)>; 65 66 /// Construct an IRCompileLayer with the given BaseLayer, which must 67 /// implement the ObjectLayer concept. 68 IRCompileLayer( 69 BaseLayerT &BaseLayer, CompileFtor Compile, 70 NotifyCompiledCallback NotifyCompiled = NotifyCompiledCallback()) BaseLayer(BaseLayer)71 : BaseLayer(BaseLayer), Compile(std::move(Compile)), 72 NotifyCompiled(std::move(NotifyCompiled)) {} 73 74 /// Get a reference to the compiler functor. getCompiler()75 CompileFtor& getCompiler() { return Compile; } 76 77 /// (Re)set the NotifyCompiled callback. setNotifyCompiled(NotifyCompiledCallback NotifyCompiled)78 void setNotifyCompiled(NotifyCompiledCallback NotifyCompiled) { 79 this->NotifyCompiled = std::move(NotifyCompiled); 80 } 81 82 /// Compile the module, and add the resulting object to the base layer 83 /// along with the given memory manager and symbol resolver. addModule(VModuleKey K,std::unique_ptr<Module> M)84 Error addModule(VModuleKey K, std::unique_ptr<Module> M) { 85 if (auto Err = BaseLayer.addObject(std::move(K), Compile(*M))) 86 return Err; 87 if (NotifyCompiled) 88 NotifyCompiled(std::move(K), std::move(M)); 89 return Error::success(); 90 } 91 92 /// Remove the module associated with the VModuleKey K. removeModule(VModuleKey K)93 Error removeModule(VModuleKey K) { return BaseLayer.removeObject(K); } 94 95 /// Search for the given named symbol. 96 /// @param Name The name of the symbol to search for. 97 /// @param ExportedSymbolsOnly If true, search only for exported symbols. 98 /// @return A handle for the given named symbol, if it exists. findSymbol(const std::string & Name,bool ExportedSymbolsOnly)99 JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) { 100 return BaseLayer.findSymbol(Name, ExportedSymbolsOnly); 101 } 102 103 /// Get the address of the given symbol in compiled module represented 104 /// by the handle H. This call is forwarded to the base layer's 105 /// implementation. 106 /// @param K The VModuleKey for the module to search in. 107 /// @param Name The name of the symbol to search for. 108 /// @param ExportedSymbolsOnly If true, search only for exported symbols. 109 /// @return A handle for the given named symbol, if it is found in the 110 /// given module. findSymbolIn(VModuleKey K,const std::string & Name,bool ExportedSymbolsOnly)111 JITSymbol findSymbolIn(VModuleKey K, const std::string &Name, 112 bool ExportedSymbolsOnly) { 113 return BaseLayer.findSymbolIn(K, Name, ExportedSymbolsOnly); 114 } 115 116 /// Immediately emit and finalize the module represented by the given 117 /// handle. 118 /// @param K The VModuleKey for the module to emit/finalize. emitAndFinalize(VModuleKey K)119 Error emitAndFinalize(VModuleKey K) { return BaseLayer.emitAndFinalize(K); } 120 121 private: 122 BaseLayerT &BaseLayer; 123 CompileFtor Compile; 124 NotifyCompiledCallback NotifyCompiled; 125 }; 126 127 } // end namespace orc 128 129 } // end namespace llvm 130 131 #endif // LLVM_EXECUTIONENGINE_ORC_IRCOMPILINGLAYER_H 132