1336809Sdim//===---------------- Layer.h -- Layer interfaces --------------*- C++ -*-===//
2336809Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6336809Sdim//
7336809Sdim//===----------------------------------------------------------------------===//
8336809Sdim//
9336809Sdim// Layer interfaces.
10336809Sdim//
11336809Sdim//===----------------------------------------------------------------------===//
12336809Sdim
13336809Sdim#ifndef LLVM_EXECUTIONENGINE_ORC_LAYER_H
14336809Sdim#define LLVM_EXECUTIONENGINE_ORC_LAYER_H
15336809Sdim
16336809Sdim#include "llvm/ExecutionEngine/Orc/Core.h"
17344779Sdim#include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h"
18336809Sdim#include "llvm/IR/Module.h"
19344779Sdim#include "llvm/Support/MemoryBuffer.h"
20336809Sdim
21336809Sdimnamespace llvm {
22336809Sdimnamespace orc {
23336809Sdim
24360784Sdim/// IRMaterializationUnit is a convenient base class for MaterializationUnits
25360784Sdim/// wrapping LLVM IR. Represents materialization responsibility for all symbols
26360784Sdim/// in the given module. If symbols are overridden by other definitions, then
27360784Sdim/// their linkage is changed to available-externally.
28360784Sdimclass IRMaterializationUnit : public MaterializationUnit {
29360784Sdimpublic:
30360784Sdim  struct ManglingOptions {
31360784Sdim    bool EmulatedTLS = false;
32360784Sdim  };
33360784Sdim
34360784Sdim  using SymbolNameToDefinitionMap = std::map<SymbolStringPtr, GlobalValue *>;
35360784Sdim
36360784Sdim  /// Create an IRMaterializationLayer. Scans the module to build the
37360784Sdim  /// SymbolFlags and SymbolToDefinition maps.
38360784Sdim  IRMaterializationUnit(ExecutionSession &ES, const ManglingOptions &MO,
39360784Sdim                        ThreadSafeModule TSM, VModuleKey K);
40360784Sdim
41360784Sdim  /// Create an IRMaterializationLayer from a module, and pre-existing
42360784Sdim  /// SymbolFlags and SymbolToDefinition maps. The maps must provide
43360784Sdim  /// entries for each definition in M.
44360784Sdim  /// This constructor is useful for delegating work from one
45360784Sdim  /// IRMaterializationUnit to another.
46360784Sdim  IRMaterializationUnit(ThreadSafeModule TSM, VModuleKey K,
47360784Sdim                        SymbolFlagsMap SymbolFlags,
48360784Sdim                        SymbolNameToDefinitionMap SymbolToDefinition);
49360784Sdim
50360784Sdim  /// Return the ModuleIdentifier as the name for this MaterializationUnit.
51360784Sdim  StringRef getName() const override;
52360784Sdim
53360784Sdim  const ThreadSafeModule &getModule() const { return TSM; }
54360784Sdim
55360784Sdimprotected:
56360784Sdim  ThreadSafeModule TSM;
57360784Sdim  SymbolNameToDefinitionMap SymbolToDefinition;
58360784Sdim
59360784Sdimprivate:
60360784Sdim  void discard(const JITDylib &JD, const SymbolStringPtr &Name) override;
61360784Sdim};
62360784Sdim
63336809Sdim/// Interface for layers that accept LLVM IR.
64336809Sdimclass IRLayer {
65336809Sdimpublic:
66360784Sdim  IRLayer(ExecutionSession &ES,
67360784Sdim          const IRMaterializationUnit::ManglingOptions *&MO)
68360784Sdim      : ES(ES), MO(MO) {}
69360784Sdim
70336809Sdim  virtual ~IRLayer();
71336809Sdim
72336809Sdim  /// Returns the ExecutionSession for this layer.
73336809Sdim  ExecutionSession &getExecutionSession() { return ES; }
74336809Sdim
75360784Sdim  /// Get the mangling options for this layer.
76360784Sdim  const IRMaterializationUnit::ManglingOptions *&getManglingOptions() const {
77360784Sdim    return MO;
78360784Sdim  }
79360784Sdim
80344779Sdim  /// Sets the CloneToNewContextOnEmit flag (false by default).
81344779Sdim  ///
82344779Sdim  /// When set, IR modules added to this layer will be cloned on to a new
83344779Sdim  /// context before emit is called. This can be used by clients who want
84344779Sdim  /// to load all IR using one LLVMContext (to save memory via type and
85344779Sdim  /// constant uniquing), but want to move Modules to fresh contexts before
86344779Sdim  /// compiling them to enable concurrent compilation.
87344779Sdim  /// Single threaded clients, or clients who load every module on a new
88344779Sdim  /// context, need not set this.
89344779Sdim  void setCloneToNewContextOnEmit(bool CloneToNewContextOnEmit) {
90344779Sdim    this->CloneToNewContextOnEmit = CloneToNewContextOnEmit;
91344779Sdim  }
92336809Sdim
93344779Sdim  /// Returns the current value of the CloneToNewContextOnEmit flag.
94344779Sdim  bool getCloneToNewContextOnEmit() const { return CloneToNewContextOnEmit; }
95344779Sdim
96344779Sdim  /// Adds a MaterializationUnit representing the given IR to the given
97344779Sdim  /// JITDylib.
98344779Sdim  virtual Error add(JITDylib &JD, ThreadSafeModule TSM,
99344779Sdim                    VModuleKey K = VModuleKey());
100344779Sdim
101336809Sdim  /// Emit should materialize the given IR.
102344779Sdim  virtual void emit(MaterializationResponsibility R, ThreadSafeModule TSM) = 0;
103336809Sdim
104336809Sdimprivate:
105344779Sdim  bool CloneToNewContextOnEmit = false;
106336809Sdim  ExecutionSession &ES;
107360784Sdim  const IRMaterializationUnit::ManglingOptions *&MO;
108336809Sdim};
109336809Sdim
110336809Sdim/// MaterializationUnit that materializes modules by calling the 'emit' method
111336809Sdim/// on the given IRLayer.
112336809Sdimclass BasicIRLayerMaterializationUnit : public IRMaterializationUnit {
113336809Sdimpublic:
114360784Sdim  BasicIRLayerMaterializationUnit(IRLayer &L, const ManglingOptions &MO,
115360784Sdim                                  ThreadSafeModule TSM, VModuleKey K);
116344779Sdim
117336809Sdimprivate:
118336809Sdim
119336809Sdim  void materialize(MaterializationResponsibility R) override;
120336809Sdim
121336809Sdim  IRLayer &L;
122336809Sdim  VModuleKey K;
123336809Sdim};
124336809Sdim
125336809Sdim/// Interface for Layers that accept object files.
126336809Sdimclass ObjectLayer {
127336809Sdimpublic:
128336809Sdim  ObjectLayer(ExecutionSession &ES);
129336809Sdim  virtual ~ObjectLayer();
130336809Sdim
131336809Sdim  /// Returns the execution session for this layer.
132336809Sdim  ExecutionSession &getExecutionSession() { return ES; }
133336809Sdim
134344779Sdim  /// Adds a MaterializationUnit representing the given IR to the given
135344779Sdim  /// JITDylib.
136344779Sdim  virtual Error add(JITDylib &JD, std::unique_ptr<MemoryBuffer> O,
137344779Sdim                    VModuleKey K = VModuleKey());
138336809Sdim
139336809Sdim  /// Emit should materialize the given IR.
140344779Sdim  virtual void emit(MaterializationResponsibility R,
141336809Sdim                    std::unique_ptr<MemoryBuffer> O) = 0;
142336809Sdim
143336809Sdimprivate:
144336809Sdim  ExecutionSession &ES;
145336809Sdim};
146336809Sdim
147336809Sdim/// Materializes the given object file (represented by a MemoryBuffer
148336809Sdim/// instance) by calling 'emit' on the given ObjectLayer.
149336809Sdimclass BasicObjectLayerMaterializationUnit : public MaterializationUnit {
150336809Sdimpublic:
151344779Sdim  static Expected<std::unique_ptr<BasicObjectLayerMaterializationUnit>>
152344779Sdim  Create(ObjectLayer &L, VModuleKey K, std::unique_ptr<MemoryBuffer> O);
153336809Sdim
154336809Sdim  BasicObjectLayerMaterializationUnit(ObjectLayer &L, VModuleKey K,
155344779Sdim                                      std::unique_ptr<MemoryBuffer> O,
156344779Sdim                                      SymbolFlagsMap SymbolFlags);
157336809Sdim
158344779Sdim  /// Return the buffer's identifier as the name for this MaterializationUnit.
159344779Sdim  StringRef getName() const override;
160344779Sdim
161336809Sdimprivate:
162344779Sdim
163336809Sdim  void materialize(MaterializationResponsibility R) override;
164344779Sdim  void discard(const JITDylib &JD, const SymbolStringPtr &Name) override;
165336809Sdim
166336809Sdim  ObjectLayer &L;
167336809Sdim  std::unique_ptr<MemoryBuffer> O;
168336809Sdim};
169336809Sdim
170344779Sdim/// Returns a SymbolFlagsMap for the object file represented by the given
171344779Sdim/// buffer, or an error if the buffer does not contain a valid object file.
172344779Sdim// FIXME: Maybe move to Core.h?
173344779SdimExpected<SymbolFlagsMap> getObjectSymbolFlags(ExecutionSession &ES,
174344779Sdim                                              MemoryBufferRef ObjBuffer);
175344779Sdim
176336809Sdim} // End namespace orc
177336809Sdim} // End namespace llvm
178336809Sdim
179336809Sdim#endif // LLVM_EXECUTIONENGINE_ORC_LAYER_H
180