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