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/Mangling.h"
18#include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h"
19#include "llvm/IR/Module.h"
20#include "llvm/Support/Casting.h"
21#include "llvm/Support/ExtensibleRTTI.h"
22#include "llvm/Support/MemoryBuffer.h"
23
24namespace llvm {
25namespace orc {
26
27/// IRMaterializationUnit is a convenient base class for MaterializationUnits
28/// wrapping LLVM IR. Represents materialization responsibility for all symbols
29/// in the given module. If symbols are overridden by other definitions, then
30/// their linkage is changed to available-externally.
31class IRMaterializationUnit : public MaterializationUnit {
32public:
33 using SymbolNameToDefinitionMap = std::map<SymbolStringPtr, GlobalValue *>;
34
35 /// Create an IRMaterializationLayer. Scans the module to build the
36 /// SymbolFlags and SymbolToDefinition maps.
37 IRMaterializationUnit(ExecutionSession &ES,
38 const IRSymbolMapper::ManglingOptions &MO,
39 ThreadSafeModule TSM);
40
41 /// Create an IRMaterializationLayer from a module, and pre-existing
42 /// SymbolFlags and SymbolToDefinition maps. The maps must provide
43 /// entries for each definition in M.
44 /// This constructor is useful for delegating work from one
45 /// IRMaterializationUnit to another.
46 IRMaterializationUnit(ThreadSafeModule TSM, Interface I,
47 SymbolNameToDefinitionMap SymbolToDefinition);
48
49 /// Return the ModuleIdentifier as the name for this MaterializationUnit.
50 StringRef getName() const override;
51
52 /// Return a reference to the contained ThreadSafeModule.
53 const ThreadSafeModule &getModule() const { return TSM; }
54
55protected:
56 ThreadSafeModule TSM;
57 SymbolNameToDefinitionMap SymbolToDefinition;
58
59private:
60 static SymbolStringPtr getInitSymbol(ExecutionSession &ES,
61 const ThreadSafeModule &TSM);
62
63 void discard(const JITDylib &JD, const SymbolStringPtr &Name) override;
64};
65
66/// Interface for layers that accept LLVM IR.
67class IRLayer {
68public:
69 IRLayer(ExecutionSession &ES, const IRSymbolMapper::ManglingOptions *&MO)
70 : ES(ES), MO(MO) {}
71
72 virtual ~IRLayer();
73
74 /// Returns the ExecutionSession for this layer.
75 ExecutionSession &getExecutionSession() { return ES; }
76
77 /// Get the mangling options for this layer.
78 const IRSymbolMapper::ManglingOptions *&getManglingOptions() const {
79 return MO;
80 }
81
82 /// Sets the CloneToNewContextOnEmit flag (false by default).
83 ///
84 /// When set, IR modules added to this layer will be cloned on to a new
85 /// context before emit is called. This can be used by clients who want
86 /// to load all IR using one LLVMContext (to save memory via type and
87 /// constant uniquing), but want to move Modules to fresh contexts before
88 /// compiling them to enable concurrent compilation.
89 /// Single threaded clients, or clients who load every module on a new
90 /// context, need not set this.
91 void setCloneToNewContextOnEmit(bool CloneToNewContextOnEmit) {
92 this->CloneToNewContextOnEmit = CloneToNewContextOnEmit;
93 }
94
95 /// Returns the current value of the CloneToNewContextOnEmit flag.
96 bool getCloneToNewContextOnEmit() const { return CloneToNewContextOnEmit; }
97
98 /// Add a MaterializatinoUnit representing the given IR to the JITDylib
99 /// targeted by the given tracker.
100 virtual Error add(ResourceTrackerSP RT, ThreadSafeModule TSM);
101
102 /// Adds a MaterializationUnit representing the given IR to the given
103 /// JITDylib. If RT is not specif
104 Error add(JITDylib &JD, ThreadSafeModule TSM) {
105 return add(JD.getDefaultResourceTracker(), std::move(TSM));
106 }
107
108 /// Emit should materialize the given IR.
109 virtual void emit(std::unique_ptr<MaterializationResponsibility> R,
110 ThreadSafeModule TSM) = 0;
111
112private:
113 bool CloneToNewContextOnEmit = false;
114 ExecutionSession &ES;
115 const IRSymbolMapper::ManglingOptions *&MO;
116};
117
118/// MaterializationUnit that materializes modules by calling the 'emit' method
119/// on the given IRLayer.
120class BasicIRLayerMaterializationUnit : public IRMaterializationUnit {
121public:
122 BasicIRLayerMaterializationUnit(IRLayer &L,
123 const IRSymbolMapper::ManglingOptions &MO,
124 ThreadSafeModule TSM);
125
126private:
127 void materialize(std::unique_ptr<MaterializationResponsibility> R) override;
128
129 IRLayer &L;
130};
131
132/// Interface for Layers that accept object files.
133class ObjectLayer : public RTTIExtends<ObjectLayer, RTTIRoot> {
134public:
135 static char ID;
136
137 ObjectLayer(ExecutionSession &ES);
138 virtual ~ObjectLayer();
139
140 /// Returns the execution session for this layer.
141 ExecutionSession &getExecutionSession() { return ES; }
142
143 /// Adds a MaterializationUnit for the object file in the given memory buffer
144 /// to the JITDylib for the given ResourceTracker.
145 virtual Error add(ResourceTrackerSP RT, std::unique_ptr<MemoryBuffer> O,
146 MaterializationUnit::Interface I);
147
148 /// Adds a MaterializationUnit for the object file in the given memory buffer
149 /// to the JITDylib for the given ResourceTracker. The interface for the
150 /// object will be built using the default object interface builder.
151 Error add(ResourceTrackerSP RT, std::unique_ptr<MemoryBuffer> O);
152
153 /// Adds a MaterializationUnit for the object file in the given memory buffer
154 /// to the given JITDylib.
155 Error add(JITDylib &JD, std::unique_ptr<MemoryBuffer> O,
156 MaterializationUnit::Interface I) {
157 return add(JD.getDefaultResourceTracker(), std::move(O), std::move(I));
158 }
159
160 /// Adds a MaterializationUnit for the object file in the given memory buffer
161 /// to the given JITDylib. The interface for the object will be built using
162 /// the default object interface builder.
163 Error add(JITDylib &JD, std::unique_ptr<MemoryBuffer> O);
164
165 /// Emit should materialize the given IR.
166 virtual void emit(std::unique_ptr<MaterializationResponsibility> R,
167 std::unique_ptr<MemoryBuffer> O) = 0;
168
169private:
170 ExecutionSession &ES;
171};
172
173/// Materializes the given object file (represented by a MemoryBuffer
174/// instance) by calling 'emit' on the given ObjectLayer.
175class BasicObjectLayerMaterializationUnit : public MaterializationUnit {
176public:
177 /// Create using the default object interface builder function.
178 static Expected<std::unique_ptr<BasicObjectLayerMaterializationUnit>>
179 Create(ObjectLayer &L, std::unique_ptr<MemoryBuffer> O);
180
181 BasicObjectLayerMaterializationUnit(ObjectLayer &L,
182 std::unique_ptr<MemoryBuffer> O,
183 Interface I);
184
185 /// Return the buffer's identifier as the name for this MaterializationUnit.
186 StringRef getName() const override;
187
188private:
189 void materialize(std::unique_ptr<MaterializationResponsibility> R) override;
190 void discard(const JITDylib &JD, const SymbolStringPtr &Name) override;
191
192 ObjectLayer &L;
193 std::unique_ptr<MemoryBuffer> O;
194};
195
196} // End namespace orc
197} // End namespace llvm
198
199#endif // LLVM_EXECUTIONENGINE_ORC_LAYER_H
200

source code of llvm/include/llvm/ExecutionEngine/Orc/Layer.h