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