1//===--------- LLJITRemovableCode.cpp -- LLJIT with Code Removal ----------===//
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// In this example we will use an the resource management APIs to transfer
10// ownership of modules, remove modules from a JITDylib, and then a whole
11// JITDylib from the ExecutionSession.
12//
13//===----------------------------------------------------------------------===//
14
15#include "llvm/ExecutionEngine/Orc/LLJIT.h"
16#include "llvm/IR/LegacyPassManager.h"
17#include "llvm/Pass.h"
18#include "llvm/Support/InitLLVM.h"
19#include "llvm/Support/TargetSelect.h"
20#include "llvm/Support/raw_ostream.h"
21#include "llvm/Transforms/IPO.h"
22#include "llvm/Transforms/Scalar.h"
23
24#include "../ExampleModules.h"
25
26using namespace llvm;
27using namespace llvm::orc;
28
29ExitOnError ExitOnErr;
30
31// Example IR modules.
32//
33// We will use a few modules containing no-op functions to demonstrate the code
34// removal APIs.
35
36const llvm::StringRef FooMod =
37 R"(
38 define void @foo() {
39 entry:
40 ret void
41 }
42)";
43
44const llvm::StringRef BarMod =
45 R"(
46 define void @bar() {
47 entry:
48 ret void
49 }
50)";
51
52const llvm::StringRef BazMod =
53 R"(
54 define void @baz() {
55 entry:
56 ret void
57 }
58)";
59
60int main(int argc, char *argv[]) {
61 // Initialize LLVM.
62 InitLLVM X(argc, argv);
63
64 InitializeNativeTarget();
65 InitializeNativeTargetAsmPrinter();
66
67 ExitOnErr.setBanner(std::string(argv[0]) + ": ");
68
69 // (1) Create LLJIT instance.
70 auto J = ExitOnErr(LLJITBuilder().create());
71
72 // (2) Create a new JITDylib to use for this example.
73 auto &JD = ExitOnErr(J->createJITDylib(Name: "JD"));
74
75 // (3) Add the 'foo' module with no explicit resource tracker. The resources
76 // for 'foo' will be tracked by the default tracker for JD. We will not be
77 // able to free it separately, but its resources will still be freed when we
78 // clear or remove JD.
79 ExitOnErr(J->addIRModule(JD, TSM: ExitOnErr(parseExampleModule(Source: FooMod, Name: "foo"))));
80
81 // (4) Create a tracker for the module 'bar' and use it to add that module.
82 auto BarRT = JD.createResourceTracker();
83 ExitOnErr(
84 J->addIRModule(RT: BarRT, TSM: ExitOnErr(parseExampleModule(Source: BarMod, Name: "bar"))));
85
86 // (5) Create a tracker for the module 'baz' and use it to add that module.
87 auto BazRT = JD.createResourceTracker();
88 ExitOnErr(
89 J->addIRModule(RT: BazRT, TSM: ExitOnErr(parseExampleModule(Source: BazMod, Name: "baz"))));
90
91 // (6) Print out the symbols in their initial state:
92 auto PrintSymbol = [&](StringRef Name) {
93 dbgs() << Name << " = ";
94 if (auto Sym = J->lookup(JD, UnmangledName: Name))
95 dbgs() << *Sym << "\n";
96 else
97 dbgs() << "error: " << toString(E: Sym.takeError()) << "\n";
98 };
99
100 dbgs() << "Initially:\n";
101 PrintSymbol("foo");
102 PrintSymbol("bar");
103 PrintSymbol("baz");
104
105 // (7) Reset BazRT. This will implicitly transfer tracking of module baz to
106 // JD's default resource tracker.
107 dbgs() << "After implicitly transferring ownership of baz to JD's default "
108 "tracker:\n";
109 BazRT = nullptr;
110 PrintSymbol("foo");
111 PrintSymbol("bar");
112 PrintSymbol("baz");
113
114 // (8) Remove BarRT. This should remove the bar symbol.
115 dbgs() << "After removing bar (lookup for bar should yield a missing symbol "
116 "error):\n";
117 ExitOnErr(BarRT->remove());
118 PrintSymbol("foo");
119 PrintSymbol("bar");
120 PrintSymbol("baz");
121
122 // (9) Clear JD. This should remove all symbols currently in the JITDylib.
123 dbgs() << "After clearing JD (lookup should yield missing symbol errors for "
124 "all symbols):\n";
125 ExitOnErr(JD.clear());
126 PrintSymbol("foo");
127 PrintSymbol("bar");
128 PrintSymbol("baz");
129
130 // (10) Remove JD from the ExecutionSession. JD can no longer be used.
131 dbgs() << "Removing JD.\n";
132 ExitOnErr(J->getExecutionSession().removeJITDylib(JD));
133
134 dbgs() << "done.\n";
135
136 return 0;
137}
138

source code of llvm/examples/OrcV2Examples/LLJITRemovableCode/LLJITRemovableCode.cpp