xref: /llvm-project/llvm/examples/HowToUseLLJIT/HowToUseLLJIT.cpp (revision e3748b5a85759b6a01661ba34707b297d3a35c12)
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