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()) |
70 | : BaseLayer(BaseLayer), Compile(std::move(Compile)), |
71 | NotifyCompiled(std::move(NotifyCompiled)) {} |
72 | |
73 | /// Get a reference to the compiler functor. |
74 | CompileFtor& getCompiler() { return Compile; } |
75 | |
76 | /// (Re)set the NotifyCompiled callback. |
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. |
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. |
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. |
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. |
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. |
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 | |