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