blob: ad6481548d5997195332ad6830f1a9d9c2ca7e6e [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===- 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"
Andrew Scullcdfcccc2018-10-05 20:58:37 +010019#include "llvm/ExecutionEngine/Orc/Layer.h"
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010020#include "llvm/Support/Error.h"
Andrew Scullcdfcccc2018-10-05 20:58:37 +010021#include "llvm/Support/MemoryBuffer.h"
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010022#include <memory>
23#include <string>
24
25namespace llvm {
26
27class Module;
28
29namespace orc {
30
Andrew Scullcdfcccc2018-10-05 20:58:37 +010031class IRCompileLayer2 : public IRLayer {
32public:
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
47private:
48 mutable std::mutex IRLayerMutex;
49 ObjectLayer &BaseLayer;
50 CompileFunction Compile;
51 NotifyCompiledFunction NotifyCompiled = NotifyCompiledFunction();
52};
53
54/// Eager IR compiling layer.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010055///
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.
59template <typename BaseLayerT, typename CompileFtor>
60class IRCompileLayer {
61public:
Andrew Scullcdfcccc2018-10-05 20:58:37 +010062 /// Callback type for notifications when modules are compiled.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010063 using NotifyCompiledCallback =
64 std::function<void(VModuleKey K, std::unique_ptr<Module>)>;
65
Andrew Scullcdfcccc2018-10-05 20:58:37 +010066 /// Construct an IRCompileLayer with the given BaseLayer, which must
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010067 /// implement the ObjectLayer concept.
68 IRCompileLayer(
69 BaseLayerT &BaseLayer, CompileFtor Compile,
70 NotifyCompiledCallback NotifyCompiled = NotifyCompiledCallback())
71 : BaseLayer(BaseLayer), Compile(std::move(Compile)),
72 NotifyCompiled(std::move(NotifyCompiled)) {}
73
Andrew Scullcdfcccc2018-10-05 20:58:37 +010074 /// Get a reference to the compiler functor.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010075 CompileFtor& getCompiler() { return Compile; }
76
Andrew Scullcdfcccc2018-10-05 20:58:37 +010077 /// (Re)set the NotifyCompiled callback.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010078 void setNotifyCompiled(NotifyCompiledCallback NotifyCompiled) {
79 this->NotifyCompiled = std::move(NotifyCompiled);
80 }
81
Andrew Scullcdfcccc2018-10-05 20:58:37 +010082 /// Compile the module, and add the resulting object to the base layer
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010083 /// along with the given memory manager and symbol resolver.
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
Andrew Scullcdfcccc2018-10-05 20:58:37 +010092 /// Remove the module associated with the VModuleKey K.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010093 Error removeModule(VModuleKey K) { return BaseLayer.removeObject(K); }
94
Andrew Scullcdfcccc2018-10-05 20:58:37 +010095 /// Search for the given named symbol.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010096 /// @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.
99 JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
100 return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
101 }
102
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100103 /// Get the address of the given symbol in compiled module represented
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100104 /// 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.
111 JITSymbol findSymbolIn(VModuleKey K, const std::string &Name,
112 bool ExportedSymbolsOnly) {
113 return BaseLayer.findSymbolIn(K, Name, ExportedSymbolsOnly);
114 }
115
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100116 /// Immediately emit and finalize the module represented by the given
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100117 /// handle.
118 /// @param K The VModuleKey for the module to emit/finalize.
119 Error emitAndFinalize(VModuleKey K) { return BaseLayer.emitAndFinalize(K); }
120
121private:
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