1//===- LinkGraphLayer.h - Add LinkGraphs to an ExecutionSession -*- 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// LinkGraphLayer and associated utilities.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_EXECUTIONENGINE_ORC_LINKGRAPHLAYER_H
14#define LLVM_EXECUTIONENGINE_ORC_LINKGRAPHLAYER_H
15
16#include "llvm/ExecutionEngine/JITLink/JITLink.h"
17#include "llvm/ExecutionEngine/Orc/Core.h"
18#include "llvm/Support/Compiler.h"
19#include "llvm/Support/Error.h"
20#include "llvm/Support/MemoryBuffer.h"
21
22#include <atomic>
23#include <memory>
24
25namespace llvm::orc {
26
27class LLVM_ABI LinkGraphLayer {
28public:
29 LinkGraphLayer(ExecutionSession &ES) : ES(ES) {}
30
31 virtual ~LinkGraphLayer();
32
33 ExecutionSession &getExecutionSession() { return ES; }
34
35 /// Adds a LinkGraph to the JITDylib for the given ResourceTracker.
36 virtual Error add(ResourceTrackerSP RT, std::unique_ptr<jitlink::LinkGraph> G,
37 MaterializationUnit::Interface I);
38
39 /// Adds a LinkGraph to the JITDylib for the given ResourceTracker. The
40 /// interface for the graph will be built using getLinkGraphInterface.
41 Error add(ResourceTrackerSP RT, std::unique_ptr<jitlink::LinkGraph> G) {
42 auto LGI = getInterface(G&: *G);
43 return add(RT: std::move(RT), G: std::move(G), I: std::move(LGI));
44 }
45
46 /// Adds a LinkGraph to the given JITDylib.
47 Error add(JITDylib &JD, std::unique_ptr<jitlink::LinkGraph> G,
48 MaterializationUnit::Interface I) {
49 return add(RT: JD.getDefaultResourceTracker(), G: std::move(G), I: std::move(I));
50 }
51
52 /// Adds a LinkGraph to the given JITDylib. The interface for the object will
53 /// be built using getLinkGraphInterface.
54 Error add(JITDylib &JD, std::unique_ptr<jitlink::LinkGraph> G) {
55 return add(RT: JD.getDefaultResourceTracker(), G: std::move(G));
56 }
57
58 /// Emit should materialize the given IR.
59 virtual void emit(std::unique_ptr<MaterializationResponsibility> R,
60 std::unique_ptr<jitlink::LinkGraph> G) = 0;
61
62 /// Get the interface for the given LinkGraph.
63 MaterializationUnit::Interface getInterface(jitlink::LinkGraph &G);
64
65 /// Get the JITSymbolFlags for the given symbol.
66 static JITSymbolFlags getJITSymbolFlagsForSymbol(jitlink::Symbol &Sym);
67
68private:
69 ExecutionSession &ES;
70 std::atomic<uint64_t> Counter{0};
71};
72
73/// MaterializationUnit for wrapping LinkGraphs.
74class LLVM_ABI LinkGraphMaterializationUnit : public MaterializationUnit {
75public:
76 LinkGraphMaterializationUnit(LinkGraphLayer &LGLayer,
77 std::unique_ptr<jitlink::LinkGraph> G,
78 Interface I)
79 : MaterializationUnit(I), LGLayer(LGLayer), G(std::move(G)) {}
80
81 LinkGraphMaterializationUnit(LinkGraphLayer &LGLayer,
82 std::unique_ptr<jitlink::LinkGraph> G)
83 : MaterializationUnit(LGLayer.getInterface(G&: *G)), LGLayer(LGLayer),
84 G(std::move(G)) {}
85
86 StringRef getName() const override;
87
88 void materialize(std::unique_ptr<MaterializationResponsibility> MR) override {
89 LGLayer.emit(R: std::move(MR), G: std::move(G));
90 }
91
92private:
93 void discard(const JITDylib &JD, const SymbolStringPtr &Name) override;
94
95 LinkGraphLayer &LGLayer;
96 std::unique_ptr<jitlink::LinkGraph> G;
97};
98
99inline Error LinkGraphLayer::add(ResourceTrackerSP RT,
100 std::unique_ptr<jitlink::LinkGraph> G,
101 MaterializationUnit::Interface I) {
102 auto &JD = RT->getJITDylib();
103
104 return JD.define(MU: std::make_unique<LinkGraphMaterializationUnit>(
105 args&: *this, args: std::move(G), args: std::move(I)),
106 RT: std::move(RT));
107}
108
109} // end namespace llvm::orc
110
111#endif // LLVM_EXECUTIONENGINE_ORC_LINKGRAPHLAYER_H
112