| //===--------- 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; |
| } |