Layer.h revision 353358
1//===---------------- Layer.h -- Layer interfaces --------------*- 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// Layer interfaces.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_EXECUTIONENGINE_ORC_LAYER_H
14#define LLVM_EXECUTIONENGINE_ORC_LAYER_H
15
16#include "llvm/ExecutionEngine/Orc/Core.h"
17#include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h"
18#include "llvm/IR/Module.h"
19#include "llvm/Support/MemoryBuffer.h"
20
21namespace llvm {
22namespace orc {
23
24/// Interface for layers that accept LLVM IR.
25class IRLayer {
26public:
27  IRLayer(ExecutionSession &ES);
28  virtual ~IRLayer();
29
30  /// Returns the ExecutionSession for this layer.
31  ExecutionSession &getExecutionSession() { return ES; }
32
33  /// Sets the CloneToNewContextOnEmit flag (false by default).
34  ///
35  /// When set, IR modules added to this layer will be cloned on to a new
36  /// context before emit is called. This can be used by clients who want
37  /// to load all IR using one LLVMContext (to save memory via type and
38  /// constant uniquing), but want to move Modules to fresh contexts before
39  /// compiling them to enable concurrent compilation.
40  /// Single threaded clients, or clients who load every module on a new
41  /// context, need not set this.
42  void setCloneToNewContextOnEmit(bool CloneToNewContextOnEmit) {
43    this->CloneToNewContextOnEmit = CloneToNewContextOnEmit;
44  }
45
46  /// Returns the current value of the CloneToNewContextOnEmit flag.
47  bool getCloneToNewContextOnEmit() const { return CloneToNewContextOnEmit; }
48
49  /// Adds a MaterializationUnit representing the given IR to the given
50  /// JITDylib.
51  virtual Error add(JITDylib &JD, ThreadSafeModule TSM,
52                    VModuleKey K = VModuleKey());
53
54  /// Emit should materialize the given IR.
55  virtual void emit(MaterializationResponsibility R, ThreadSafeModule TSM) = 0;
56
57private:
58  bool CloneToNewContextOnEmit = false;
59  ExecutionSession &ES;
60};
61
62/// IRMaterializationUnit is a convenient base class for MaterializationUnits
63/// wrapping LLVM IR. Represents materialization responsibility for all symbols
64/// in the given module. If symbols are overridden by other definitions, then
65/// their linkage is changed to available-externally.
66class IRMaterializationUnit : public MaterializationUnit {
67public:
68  using SymbolNameToDefinitionMap = std::map<SymbolStringPtr, GlobalValue *>;
69
70  /// Create an IRMaterializationLayer. Scans the module to build the
71  /// SymbolFlags and SymbolToDefinition maps.
72  IRMaterializationUnit(ExecutionSession &ES, ThreadSafeModule TSM,
73                        VModuleKey K);
74
75  /// Create an IRMaterializationLayer from a module, and pre-existing
76  /// SymbolFlags and SymbolToDefinition maps. The maps must provide
77  /// entries for each definition in M.
78  /// This constructor is useful for delegating work from one
79  /// IRMaterializationUnit to another.
80  IRMaterializationUnit(ThreadSafeModule TSM, VModuleKey K,
81                        SymbolFlagsMap SymbolFlags,
82                        SymbolNameToDefinitionMap SymbolToDefinition);
83
84  /// Return the ModuleIdentifier as the name for this MaterializationUnit.
85  StringRef getName() const override;
86
87  const ThreadSafeModule &getModule() const { return TSM; }
88
89protected:
90  ThreadSafeModule TSM;
91  SymbolNameToDefinitionMap SymbolToDefinition;
92
93private:
94  void discard(const JITDylib &JD, const SymbolStringPtr &Name) override;
95};
96
97/// MaterializationUnit that materializes modules by calling the 'emit' method
98/// on the given IRLayer.
99class BasicIRLayerMaterializationUnit : public IRMaterializationUnit {
100public:
101  BasicIRLayerMaterializationUnit(IRLayer &L, VModuleKey K,
102                                  ThreadSafeModule TSM);
103
104private:
105
106  void materialize(MaterializationResponsibility R) override;
107
108  IRLayer &L;
109  VModuleKey K;
110};
111
112/// Interface for Layers that accept object files.
113class ObjectLayer {
114public:
115  ObjectLayer(ExecutionSession &ES);
116  virtual ~ObjectLayer();
117
118  /// Returns the execution session for this layer.
119  ExecutionSession &getExecutionSession() { return ES; }
120
121  /// Adds a MaterializationUnit representing the given IR to the given
122  /// JITDylib.
123  virtual Error add(JITDylib &JD, std::unique_ptr<MemoryBuffer> O,
124                    VModuleKey K = VModuleKey());
125
126  /// Emit should materialize the given IR.
127  virtual void emit(MaterializationResponsibility R,
128                    std::unique_ptr<MemoryBuffer> O) = 0;
129
130private:
131  ExecutionSession &ES;
132};
133
134/// Materializes the given object file (represented by a MemoryBuffer
135/// instance) by calling 'emit' on the given ObjectLayer.
136class BasicObjectLayerMaterializationUnit : public MaterializationUnit {
137public:
138  static Expected<std::unique_ptr<BasicObjectLayerMaterializationUnit>>
139  Create(ObjectLayer &L, VModuleKey K, std::unique_ptr<MemoryBuffer> O);
140
141  BasicObjectLayerMaterializationUnit(ObjectLayer &L, VModuleKey K,
142                                      std::unique_ptr<MemoryBuffer> O,
143                                      SymbolFlagsMap SymbolFlags);
144
145  /// Return the buffer's identifier as the name for this MaterializationUnit.
146  StringRef getName() const override;
147
148private:
149
150  void materialize(MaterializationResponsibility R) override;
151  void discard(const JITDylib &JD, const SymbolStringPtr &Name) override;
152
153  ObjectLayer &L;
154  std::unique_ptr<MemoryBuffer> O;
155};
156
157/// Returns a SymbolFlagsMap for the object file represented by the given
158/// buffer, or an error if the buffer does not contain a valid object file.
159// FIXME: Maybe move to Core.h?
160Expected<SymbolFlagsMap> getObjectSymbolFlags(ExecutionSession &ES,
161                                              MemoryBufferRef ObjBuffer);
162
163} // End namespace orc
164} // End namespace llvm
165
166#endif // LLVM_EXECUTIONENGINE_ORC_LAYER_H
167