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, SymbolFlagsMap SymbolFlags,
47 SymbolStringPtr InitSymbol,
48 SymbolNameToDefinitionMap SymbolToDefinition);
49
50 /// Return the ModuleIdentifier as the name for this MaterializationUnit.
51 StringRef getName() const override;
52
53 /// Return a reference to the contained ThreadSafeModule.
54 const ThreadSafeModule &getModule() const { return TSM; }
55
56protected:
57 ThreadSafeModule TSM;
58 SymbolNameToDefinitionMap SymbolToDefinition;
59
60private:
61 static SymbolStringPtr getInitSymbol(ExecutionSession &ES,
62 const ThreadSafeModule &TSM);
63
64 void discard(const JITDylib &JD, const SymbolStringPtr &Name) override;
65};
66
67/// Interface for layers that accept LLVM IR.
68class IRLayer {
69public:
70 IRLayer(ExecutionSession &ES, const IRSymbolMapper::ManglingOptions *&MO)
71 : ES(ES), MO(MO) {}
72
73 virtual ~IRLayer();
74
75 /// Returns the ExecutionSession for this layer.
76 ExecutionSession &getExecutionSession() { return ES; }
77
78 /// Get the mangling options for this layer.
79 const IRSymbolMapper::ManglingOptions *&getManglingOptions() const {
80 return MO;
81 }
82
83 /// Sets the CloneToNewContextOnEmit flag (false by default).
84 ///
85 /// When set, IR modules added to this layer will be cloned on to a new
86 /// context before emit is called. This can be used by clients who want
87 /// to load all IR using one LLVMContext (to save memory via type and
88 /// constant uniquing), but want to move Modules to fresh contexts before
89 /// compiling them to enable concurrent compilation.
90 /// Single threaded clients, or clients who load every module on a new
91 /// context, need not set this.
92 void setCloneToNewContextOnEmit(bool CloneToNewContextOnEmit) {
93 this->CloneToNewContextOnEmit = CloneToNewContextOnEmit;
94 }
95
96 /// Returns the current value of the CloneToNewContextOnEmit flag.
97 bool getCloneToNewContextOnEmit() const { return CloneToNewContextOnEmit; }
98
99 /// Add a MaterializatinoUnit representing the given IR to the JITDylib
100 /// targeted by the given tracker.
101 virtual Error add(ResourceTrackerSP RT, ThreadSafeModule TSM);
102
103 /// Adds a MaterializationUnit representing the given IR to the given
104 /// JITDylib. If RT is not specif
105 Error add(JITDylib &JD, ThreadSafeModule TSM) {
106 return add(JD.getDefaultResourceTracker(), std::move(TSM));
107 }
108
109 /// Emit should materialize the given IR.
110 virtual void emit(std::unique_ptr<MaterializationResponsibility> R,
111 ThreadSafeModule TSM) = 0;
112
113private:
114 bool CloneToNewContextOnEmit = false;
115 ExecutionSession &ES;
116 const IRSymbolMapper::ManglingOptions *&MO;
117};
118
119/// MaterializationUnit that materializes modules by calling the 'emit' method
120/// on the given IRLayer.
121class BasicIRLayerMaterializationUnit : public IRMaterializationUnit {
122public:
123 BasicIRLayerMaterializationUnit(IRLayer &L,
124 const IRSymbolMapper::ManglingOptions &MO,
125 ThreadSafeModule TSM);
126
127private:
128 void materialize(std::unique_ptr<MaterializationResponsibility> R) override;
129
130 IRLayer &L;
131};
132
133/// Interface for Layers that accept object files.
134class ObjectLayer : public RTTIExtends<ObjectLayer, RTTIRoot> {
135public:
136 static char ID;
137
138 ObjectLayer(ExecutionSession &ES);
139 virtual ~ObjectLayer();
140
141 /// Returns the execution session for this layer.
142 ExecutionSession &getExecutionSession() { return ES; }
143
144 /// Adds a MaterializationUnit representing the given IR to the given
145 /// JITDylib.
146 virtual Error add(ResourceTrackerSP RT, std::unique_ptr<MemoryBuffer> O);
147
148 Error add(JITDylib &JD, std::unique_ptr<MemoryBuffer> O) {
149 return add(JD.getDefaultResourceTracker(), std::move(O));
150 }
151
152 /// Emit should materialize the given IR.
153 virtual void emit(std::unique_ptr<MaterializationResponsibility> R,
154 std::unique_ptr<MemoryBuffer> O) = 0;
155
156private:
157 ExecutionSession &ES;
158};
159
160/// Materializes the given object file (represented by a MemoryBuffer
161/// instance) by calling 'emit' on the given ObjectLayer.
162class BasicObjectLayerMaterializationUnit : public MaterializationUnit {
163public:
164 static Expected<std::unique_ptr<BasicObjectLayerMaterializationUnit>>
165 Create(ObjectLayer &L, std::unique_ptr<MemoryBuffer> O);
166
167 BasicObjectLayerMaterializationUnit(ObjectLayer &L,
168 std::unique_ptr<MemoryBuffer> O,
169 SymbolFlagsMap SymbolFlags,
170 SymbolStringPtr InitSymbol);
171
172 /// Return the buffer's identifier as the name for this MaterializationUnit.
173 StringRef getName() const override;
174
175private:
176 void materialize(std::unique_ptr<MaterializationResponsibility> R) override;
177 void discard(const JITDylib &JD, const SymbolStringPtr &Name) override;
178
179 ObjectLayer &L;
180 std::unique_ptr<MemoryBuffer> O;
181};
182
183} // End namespace orc
184} // End namespace llvm
185
186#endif // LLVM_EXECUTIONENGINE_ORC_LAYER_H
187