IRCompileLayer.h revision 360784
1//===- IRCompileLayer.h -- Eagerly compile IR for JIT -----------*- 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// Contains the definition for a basic, eagerly compiling layer of the JIT.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_EXECUTIONENGINE_ORC_IRCOMPILELAYER_H
14#define LLVM_EXECUTIONENGINE_ORC_IRCOMPILELAYER_H
15
16#include "llvm/ADT/STLExtras.h"
17#include "llvm/ExecutionEngine/JITSymbol.h"
18#include "llvm/ExecutionEngine/Orc/Layer.h"
19#include "llvm/Support/Error.h"
20#include "llvm/Support/MemoryBuffer.h"
21#include <memory>
22#include <string>
23
24namespace llvm {
25
26class Module;
27
28namespace orc {
29
30class IRCompileLayer : public IRLayer {
31public:
32  class IRCompiler {
33  public:
34    IRCompiler(IRMaterializationUnit::ManglingOptions MO) : MO(std::move(MO)) {}
35    virtual ~IRCompiler();
36    const IRMaterializationUnit::ManglingOptions &getManglingOptions() const {
37      return MO;
38    }
39    virtual Expected<std::unique_ptr<MemoryBuffer>> operator()(Module &M) = 0;
40
41  protected:
42    IRMaterializationUnit::ManglingOptions &manglingOptions() { return MO; }
43
44  private:
45    IRMaterializationUnit::ManglingOptions MO;
46  };
47
48  using NotifyCompiledFunction =
49      std::function<void(VModuleKey K, ThreadSafeModule TSM)>;
50
51  IRCompileLayer(ExecutionSession &ES, ObjectLayer &BaseLayer,
52                 std::unique_ptr<IRCompiler> Compile);
53
54  IRCompiler &getCompiler() { return *Compile; }
55
56  void setNotifyCompiled(NotifyCompiledFunction NotifyCompiled);
57
58  void emit(MaterializationResponsibility R, ThreadSafeModule TSM) override;
59
60private:
61  mutable std::mutex IRLayerMutex;
62  ObjectLayer &BaseLayer;
63  std::unique_ptr<IRCompiler> Compile;
64  const IRMaterializationUnit::ManglingOptions *ManglingOpts;
65  NotifyCompiledFunction NotifyCompiled = NotifyCompiledFunction();
66};
67
68/// Eager IR compiling layer.
69///
70///   This layer immediately compiles each IR module added via addModule to an
71/// object file and adds this module file to the layer below, which must
72/// implement the object layer concept.
73template <typename BaseLayerT, typename CompileFtor>
74class LegacyIRCompileLayer {
75public:
76  /// Callback type for notifications when modules are compiled.
77  using NotifyCompiledCallback =
78      std::function<void(VModuleKey K, std::unique_ptr<Module>)>;
79
80  /// Construct an LegacyIRCompileLayer with the given BaseLayer, which must
81  ///        implement the ObjectLayer concept.
82  LLVM_ATTRIBUTE_DEPRECATED(
83      LegacyIRCompileLayer(
84          BaseLayerT &BaseLayer, CompileFtor Compile,
85          NotifyCompiledCallback NotifyCompiled = NotifyCompiledCallback()),
86      "ORCv1 layers (layers with the 'Legacy' prefix) are deprecated. Please "
87      "use "
88      "the ORCv2 IRCompileLayer instead");
89
90  /// Legacy layer constructor with deprecation acknowledgement.
91  LegacyIRCompileLayer(
92      ORCv1DeprecationAcknowledgement, BaseLayerT &BaseLayer,
93      CompileFtor Compile,
94      NotifyCompiledCallback NotifyCompiled = NotifyCompiledCallback())
95      : BaseLayer(BaseLayer), Compile(std::move(Compile)),
96        NotifyCompiled(std::move(NotifyCompiled)) {}
97
98  /// Get a reference to the compiler functor.
99  CompileFtor& getCompiler() { return Compile; }
100
101  /// (Re)set the NotifyCompiled callback.
102  void setNotifyCompiled(NotifyCompiledCallback NotifyCompiled) {
103    this->NotifyCompiled = std::move(NotifyCompiled);
104  }
105
106  /// Compile the module, and add the resulting object to the base layer
107  ///        along with the given memory manager and symbol resolver.
108  Error addModule(VModuleKey K, std::unique_ptr<Module> M) {
109    auto Obj = Compile(*M);
110    if (!Obj)
111      return Obj.takeError();
112    if (auto Err = BaseLayer.addObject(std::move(K), std::move(*Obj)))
113      return Err;
114    if (NotifyCompiled)
115      NotifyCompiled(std::move(K), std::move(M));
116    return Error::success();
117  }
118
119  /// Remove the module associated with the VModuleKey K.
120  Error removeModule(VModuleKey K) { return BaseLayer.removeObject(K); }
121
122  /// Search for the given named symbol.
123  /// @param Name The name of the symbol to search for.
124  /// @param ExportedSymbolsOnly If true, search only for exported symbols.
125  /// @return A handle for the given named symbol, if it exists.
126  JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
127    return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
128  }
129
130  /// Get the address of the given symbol in compiled module represented
131  ///        by the handle H. This call is forwarded to the base layer's
132  ///        implementation.
133  /// @param K The VModuleKey for the module to search in.
134  /// @param Name The name of the symbol to search for.
135  /// @param ExportedSymbolsOnly If true, search only for exported symbols.
136  /// @return A handle for the given named symbol, if it is found in the
137  ///         given module.
138  JITSymbol findSymbolIn(VModuleKey K, const std::string &Name,
139                         bool ExportedSymbolsOnly) {
140    return BaseLayer.findSymbolIn(K, Name, ExportedSymbolsOnly);
141  }
142
143  /// Immediately emit and finalize the module represented by the given
144  ///        handle.
145  /// @param K The VModuleKey for the module to emit/finalize.
146  Error emitAndFinalize(VModuleKey K) { return BaseLayer.emitAndFinalize(K); }
147
148private:
149  BaseLayerT &BaseLayer;
150  CompileFtor Compile;
151  NotifyCompiledCallback NotifyCompiled;
152};
153
154template <typename BaseLayerT, typename CompileFtor>
155LegacyIRCompileLayer<BaseLayerT, CompileFtor>::LegacyIRCompileLayer(
156    BaseLayerT &BaseLayer, CompileFtor Compile,
157    NotifyCompiledCallback NotifyCompiled)
158    : BaseLayer(BaseLayer), Compile(std::move(Compile)),
159      NotifyCompiled(std::move(NotifyCompiled)) {}
160
161} // end namespace orc
162} // end namespace llvm
163
164#endif // LLVM_EXECUTIONENGINE_ORC_IRCOMPILINGLAYER_H
165