1 //===-- examples/HowToUseJIT/HowToUseJIT.cpp - An example use of the JIT --===// 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 #include "llvm/ExecutionEngine/Orc/LLJIT.h" 10 #include "llvm/IR/Function.h" 11 #include "llvm/IR/IRBuilder.h" 12 #include "llvm/IR/Module.h" 13 #include "llvm/Support/InitLLVM.h" 14 #include "llvm/Support/TargetSelect.h" 15 #include "llvm/Support/raw_ostream.h" 16 17 using namespace llvm; 18 using namespace llvm::orc; 19 20 ExitOnError ExitOnErr; 21 22 ThreadSafeModule createDemoModule() { 23 auto Context = std::make_unique<LLVMContext>(); 24 auto M = std::make_unique<Module>("test", *Context); 25 26 // Create the add1 function entry and insert this entry into module M. The 27 // function will have a return type of "int" and take an argument of "int". 28 Function *Add1F = 29 Function::Create(FunctionType::get(Type::getInt32Ty(*Context), 30 {Type::getInt32Ty(*Context)}, false), 31 Function::ExternalLinkage, "add1", M.get()); 32 33 // Add a basic block to the function. As before, it automatically inserts 34 // because of the last argument. 35 BasicBlock *BB = BasicBlock::Create(*Context, "EntryBlock", Add1F); 36 37 // Create a basic block builder with default parameters. The builder will 38 // automatically append instructions to the basic block `BB'. 39 IRBuilder<> builder(BB); 40 41 // Get pointers to the constant `1'. 42 Value *One = builder.getInt32(1); 43 44 // Get pointers to the integer argument of the add1 function... 45 assert(Add1F->arg_begin() != Add1F->arg_end()); // Make sure there's an arg 46 Argument *ArgX = &*Add1F->arg_begin(); // Get the arg 47 ArgX->setName("AnArg"); // Give it a nice symbolic name for fun. 48 49 // Create the add instruction, inserting it into the end of BB. 50 Value *Add = builder.CreateAdd(One, ArgX); 51 52 // Create the return instruction and add it to the basic block 53 builder.CreateRet(Add); 54 55 return ThreadSafeModule(std::move(M), std::move(Context)); 56 } 57 58 int main(int argc, char *argv[]) { 59 // Initialize LLVM. 60 InitLLVM X(argc, argv); 61 62 InitializeNativeTarget(); 63 InitializeNativeTargetAsmPrinter(); 64 65 cl::ParseCommandLineOptions(argc, argv, "HowToUseLLJIT"); 66 ExitOnErr.setBanner(std::string(argv[0]) + ": "); 67 68 // Create an LLJIT instance. 69 auto J = ExitOnErr(LLJITBuilder().create()); 70 auto M = createDemoModule(); 71 72 ExitOnErr(J->addIRModule(std::move(M))); 73 74 // Look up the JIT'd function, cast it to a function pointer, then call it. 75 auto Add1Sym = ExitOnErr(J->lookup("add1")); 76 int (*Add1)(int) = (int (*)(int))Add1Sym.getAddress(); 77 78 int Result = Add1(42); 79 outs() << "add1(42) = " << Result << "\n"; 80 81 return 0; 82 } 83