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