1 //===--------- LLJITRemovableCode.cpp -- LLJIT with Code Removal ----------===//
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
7 //===----------------------------------------------------------------------===//
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.
13 //===----------------------------------------------------------------------===//
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"
24 #include "../ExampleModules.h"
27 using namespace llvm::orc
;
29 ExitOnError ExitOnErr
;
31 // Example IR modules.
33 // We will use a few modules containing no-op functions to demonstrate the code
36 const llvm::StringRef FooMod
=
44 const llvm::StringRef BarMod
=
52 const llvm::StringRef BazMod
=
60 int main(int argc
, char *argv
[]) {
62 InitLLVM
X(argc
, argv
);
64 InitializeNativeTarget();
65 InitializeNativeTargetAsmPrinter();
67 ExitOnErr
.setBanner(std::string(argv
[0]) + ": ");
69 // (1) Create LLJIT instance.
70 auto J
= ExitOnErr(LLJITBuilder().create());
72 // (2) Create a new JITDylib to use for this example.
73 auto &JD
= ExitOnErr(J
->createJITDylib("JD"));
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
, ExitOnErr(parseExampleModule(FooMod
, "foo"))));
81 // (4) Create a tracker for the module 'bar' and use it to add that module.
82 auto BarRT
= JD
.createResourceTracker();
84 J
->addIRModule(BarRT
, ExitOnErr(parseExampleModule(BarMod
, "bar"))));
86 // (5) Create a tracker for the module 'baz' and use it to add that module.
87 auto BazRT
= JD
.createResourceTracker();
89 J
->addIRModule(BazRT
, ExitOnErr(parseExampleModule(BazMod
, "baz"))));
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
, Name
))
97 dbgs() << "error: " << toString(Sym
.takeError()) << "\n";
100 dbgs() << "Initially:\n";
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 "
114 // (8) Remove BarRT. This should remove the bar symbol.
115 dbgs() << "After removing bar (lookup for bar should yield a missing symbol "
117 ExitOnErr(BarRT
->remove());
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 "
125 ExitOnErr(JD
.clear());
130 // (10) Remove JD from the ExecutionSession. JD can no longer be used.
131 dbgs() << "Removing JD.\n";
132 ExitOnErr(J
->getExecutionSession().removeJITDylib(JD
));