HowToUseLLJIT.cpp 2.8 KB

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