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