int main(int argc, char**argv) { // Create an LLVM Module by calling makeLLVMModule() // Access the LLVM Module through a module owner std::unique_ptr<Module> Owner(makeLLVMModule()); Module* Mod = Owner.get(); // Verify the LLVM Module - check syntax and semantics verifyModule(*Mod, &errs()); // Create a 'Pass Manager' for the compiler pipeline // Configure the Pass Manager with available / custom passes legacy::PassManager PM; PM.add(createPrintModulePass(outs())); // Run the LLVM Module through the pipeline managed by the Pass Manager. // The pipeline has a single 'print' pass which will stream out the LLVM Module as LLVM IR PM.run(*Mod); // Now let's check if the LLVM Module is functionally correct. To do this, we will test the module // with concrete values, execute the module on an 'ExecutionEngine' (which can be configured as a // JIT compiler or an interpreter), and verify if the output matches the expected result. std::string errStr; ExecutionEngine *Engine = EngineBuilder(std::move(Owner)).setErrorStr(&errStr).create(); if (!Engine) { errs() << argv[0] << ": Failed to construct the Execution Engine: " << errStr << "\n"; return -1; // Add a error macro } // Input values 2,3,4. // Expected value: mul_add(2,3,4) = 2 * 3 + 4 = 10 std::vector<GenericValue> Args(3); Args[0].IntVal = APInt(32, 2); Args[1].IntVal = APInt(32, 3); Args[2].IntVal = APInt(32, 4); GenericValue GV = Engine->runFunction(mul_add, Args); outs() << "\nCalling mul_add( " << Args[0].IntVal << ", " << Args[1].IntVal << ", " << Args[2].IntVal <<" )"; outs() << "\nResult: " << GV.IntVal << "\n"; if( GV.IntVal == (Args[0].IntVal * Args[1].IntVal + Args[2].IntVal) ) { outs() << "\n\nResult matches expectation!!"; outs() << "\nMyFirstModule is a perfect LLVM Module :)"; } else { outs() << "\n\nOops! Result doesn't match expectation. Check mul_add again."; } delete Mod; return 0; }
int main(int argc, char **argv) { int n = argc > 1 ? atol(argv[1]) : 24; LLVMContext Context; // Create some module to put our function into it. Module *M = new Module("test", Context); // We are about to create the "fib" function: Function *FibF = CreateFibFunction(M, Context); // Now we going to create JIT ExecutionEngine *EE = EngineBuilder(M).create(); errs() << "verifying... "; if (verifyModule(*M)) { errs() << argv[0] << ": Error constructing function!\n"; return 1; } errs() << "OK\n"; errs() << "We just constructed this LLVM module:\n\n---------\n" << *M; errs() << "---------\nstarting fibonacci(" << n << ") with JIT...\n"; // Call the Fibonacci function with argument n: std::vector<GenericValue> Args(1); Args[0].IntVal = APInt(32, n); GenericValue GV = EE->runFunction(FibF, Args); // import result of execution outs() << "Result: " << GV.IntVal << "\n"; return 0; }
GenericValue CodeGenContext::runCode() { std::cout << "Running code ...\n"; ExecutionEngine* ee = EngineBuilder(module_).create(); vector<GenericValue> noargs; GenericValue v = ee->runFunction(main_func_, noargs); std::cout << "Code was run.\n"; return v; }
/* Executes the AST by running the main function */ GenericValue CodeGenContext::runCode() { std::cout << "Running code...\n"; ExistingModuleProvider *mp = new ExistingModuleProvider(module); ExecutionEngine *ee = ExecutionEngine::create(mp, false); vector<GenericValue> noargs; GenericValue v = ee->runFunction(mainFunction, noargs); std::cout << "Code was run.\n"; return v; }
/* Executes the AST by running the main function */ GenericValue CodeGenContext::runCode() { std::cout << "Running code...\n"; InitializeNativeTarget(); ExecutionEngine *ee = ExecutionEngine::create(module, false); vector<GenericValue> noargs; GenericValue v = ee->runFunction(mainFunction, noargs); std::cout << "Code was run.\n"; return v; }
GenericValue execute(Function *ep, vector<GenericValue>& args) { if (engine) return engine->runFunction(ep, args); GenericValue v; v.DoubleVal = 0; return v; }
/* Executes the AST by running the main function */ GenericValue CodeGenContext::runCode() { std::cout << "Running begining...\n"; std::cout << "========================================" << std::endl; ExecutionEngine *ee = EngineBuilder(module).create(); std::vector<GenericValue> noargs; GenericValue v = ee->runFunction(mainFunction, noargs); std::cout << "========================================" << std::endl; std::cout << "Running end.\n"; return v; }
GenericValue CodeGenContext::runCode() { std::cout << "Executing code...\n"; ExecutionEngine* ee = EngineBuilder(module).create(); vector<GenericValue> noargs; GenericValue v = ee->runFunction(mainFunction, noargs); std::cout << "Code execution complete.\n"; return v; }
int main(int argc, char **argv) { int n = argc > 1 ? atol(argv[1]) : 24; InitializeNativeTarget(); LLVMContext Context; // Create some module to put our function into it. OwningPtr<Module> M(new Module("test", Context)); // We are about to create the "fib" function: Type* ty=Type::getInt64Ty(Context); //if (n<30) ty=Type::getInt32Ty(Context); // decide on type at runtime Function *FibF = CreateFibFunction(M.get(), Context, ty); // Now we going to create JIT //auto engine=EngineKind::Interpreter; auto engine=EngineKind::JIT; std::string errStr; ExecutionEngine *EE = EngineBuilder(M.get()) .setErrorStr(&errStr) .setEngineKind(engine) .create(); if (!EE) { errs() << argv[0] << ": Failed to construct ExecutionEngine: " << errStr << "\n"; return 1; } errs() << "verifying... "; if (verifyModule(*M)) { errs() << argv[0] << ": Error constructing function!\n"; return 1; } errs() << "OK\n"; errs() << "We just constructed this LLVM module:\n\n---------\n" << *M; errs() << "---------\nstarting fibonacci(" << n << ") with "<<(engine==EngineKind::Interpreter?"interpreter":(engine==EngineKind::JIT)?"JIT":"???")<<" ...\n"; // Call the Fibonacci function with argument n: std::vector<GenericValue> Args(1); Args[0].IntVal = APInt(32, n); GenericValue GV = EE->runFunction(FibF, Args); // import result of execution outs() << "Result: " << GV.IntVal << "\n"; return 0; }
int main(int argc, char **argv) { int n = argc > 1 ? atol(argv[1]) : 24; InitializeNativeTarget(); InitializeNativeTargetAsmPrinter(); LLVMContext Context; // Create some module to put our function into it. std::unique_ptr<Module> Owner(new Module("test", Context)); Module *M = Owner.get(); // We are about to create the "fib" function: Function *FibF = CreateFibFunction(M, Context); // Now we going to create JIT std::string errStr; ExecutionEngine *EE = EngineBuilder(std::move(Owner)) .setErrorStr(&errStr) .create(); if (!EE) { errs() << argv[0] << ": Failed to construct ExecutionEngine: " << errStr << "\n"; return 1; } errs() << "verifying... "; if (verifyModule(*M)) { errs() << argv[0] << ": Error constructing function!\n"; return 1; } errs() << "OK\n"; errs() << "We just constructed this LLVM module:\n\n---------\n" << *M; errs() << "---------\nstarting fibonacci(" << n << ") with JIT...\n"; // Call the Fibonacci function with argument n: std::vector<GenericValue> Args(1); Args[0].IntVal = APInt(32, n); GenericValue GV = EE->runFunction(FibF, Args); // import result of execution outs() << "Result: " << GV.IntVal << "\n"; return 0; }
void LoadPlugin(const std::string& path, const std::string& name, MetaScriptRunner* msr) { SMDiagnostic error; std::unique_ptr<Module> Owner = getLazyIRFileModule(path, error, context); if(Owner == nullptr) { cout << "Load Error: " << path << endl; Owner->dump(); return; } initEE(std::move(Owner)); string func_name = name + "_elite_plugin_init"; Function* func = EE->FindFunctionNamed(func_name.c_str()); std::vector<GenericValue> args; args.push_back(GenericValue(msr->getCodeGenContext())); GenericValue gv = EE->runFunction(func, args); }
int main(int argc, char**argv) { InitializeNativeTarget(); InitializeNativeTargetAsmPrinter(); Module* Mod = makeLLVMModule(); verifyModule(*Mod, PrintMessageAction); PassManager PM; PM.add(createPrintModulePass(&outs())); PM.run(*Mod); //ExecutionEngine *exe=::llvm::Interpreter::create(Mod); //ExecutionEngine *exe = EngineBuilder(Mod).create(); //printf("----%p\n",exe); EngineBuilder eb = EngineBuilder(Mod); #if LLVM_VERSION >= 33 eb.setEngineKind(EngineKind::JIT); eb.setJITMemoryManager(JITMemoryManager::CreateDefaultMemManager()); eb.setAllocateGVsWithCode(false); eb.setOptLevel(CodeGenOpt::Aggressive); eb.setCodeModel(CodeModel::JITDefault); #endif eb.setMArch("x86-64"); eb.setMCPU("corei7-avx"); eb.setUseMCJIT(true); ExecutionEngine *exe = eb.create(); std::vector<GenericValue> args; GenericValue GVArgc; GVArgc.IntVal = APInt(32, 24); args.push_back(GVArgc); //printf("xxxx:%p,%p\n",func_factorial,(void*)(&exe->runFunction)); GenericValue ret=exe->runFunction(func_factorial, args); printf("ret=%llu\n",ret.IntVal.getZExtValue()); #if LLVM_VERSION < 33 exe->freeMachineCodeForFunction(func_factorial); #endif delete exe; //llvm_shutdown(); return 0; }
llvm::GenericValue minipascal::CodeGenContext::runCode() { std::cout << "Running code...\n"; ExecutionEngine* execueng = EngineBuilder(mmodule).create(); std::cout << "Code was run1.\n"; vector<GenericValue> noargs; GenericValue retval; std::cout << "Code was run2.\n"; if (execueng == nullptr) { cout << "nullptr executionenigine\n"; return retval; } else { cout << "not nullptr\n"; } execueng->runFunction(currentFunction(), noargs); std::cout << "Code was run3.\n"; return retval; }
int main(int argc, char **argv) { InitializeNativeTarget(); InitializeNativeTargetAsmPrinter(); InitializeNativeTargetAsmParser(); // Create a module containing the `calc` function LLVMContext context; Module* module = new Module("test", context); // Create the expression and compile it Expr* expression = parseExpression(argv[1]); Function* calcFunction = compileFunction(context, module, "calc", expression); // Initialize the LLVM JIT engine. ExecutionEngine* engine = createEngine(module); // Compute the result and print it out auto calcArgs = parseArguments(argc - 2, argv + 2); GenericValue calcValue = engine->runFunction(calcFunction, calcArgs); outs() << "RESULT: " << calcValue.IntVal << "\n"; return 0; }
int main(int argc, char **argv, char **envp) { sys::PrintStackTraceOnErrorSignal(); PrettyStackTraceProgram X(argc, argv); llvm_shutdown_obj Y; InitializeAllTargets(); InitializeAllTargetInfos(); InitializeAllTargetDCs(); InitializeAllTargetMCs(); InitializeAllAsmParsers(); InitializeAllDisassemblers(); cl::ParseCommandLineOptions(argc, argv, "Function disassembler\n"); ToolName = argv[0]; std::unique_ptr<MemoryBuffer> FileBuf; if (error_code ec = MemoryBuffer::getFile(InputFilename, FileBuf)) { errs() << ToolName << ": '" << InputFilename << "': " << ec.message() << ".\n"; return 1; } ErrorOr<Binary *> BinaryOrErr = createBinary( MemoryBuffer::getMemBufferCopy(FileBuf->getBuffer())); if (error_code ec = BinaryOrErr.getError()) { errs() << ToolName << ": '" << InputFilename << "': " << ec.message() << ".\n"; return 1; } std::unique_ptr<Binary> binary(BinaryOrErr.get()); ObjectFile *Obj; if (!(Obj = dyn_cast<ObjectFile>(binary.get()))) errs() << ToolName << ": '" << InputFilename << "': " << "Unrecognized file type.\n"; const Target *TheTarget = getTarget(Obj); std::unique_ptr<const MCRegisterInfo> MRI( TheTarget->createMCRegInfo(TripleName)); if (!MRI) { errs() << "error: no register info for target " << TripleName << "\n"; return 1; } // Set up disassembler. std::unique_ptr<const MCAsmInfo> MAI( TheTarget->createMCAsmInfo(*MRI, TripleName)); if (!MAI) { errs() << "error: no assembly info for target " << TripleName << "\n"; return 1; } std::unique_ptr<const MCSubtargetInfo> STI( TheTarget->createMCSubtargetInfo(TripleName, "", "")); if (!STI) { errs() << "error: no subtarget info for target " << TripleName << "\n"; return 1; } std::unique_ptr<const MCInstrInfo> MII(TheTarget->createMCInstrInfo()); if (!MII) { errs() << "error: no instruction info for target " << TripleName << "\n"; return 1; } std::unique_ptr<MCDisassembler> DisAsm(TheTarget->createMCDisassembler(*STI)); if (!DisAsm) { errs() << "error: no disassembler for target " << TripleName << "\n"; return 1; } std::unique_ptr<MCInstPrinter> MIP( TheTarget->createMCInstPrinter(0, *MAI, *MII, *MRI, *STI)); if (!MIP) { errs() << "error: no instprinter for target " << TripleName << "\n"; return 1; } std::unique_ptr<const MCInstrAnalysis> MIA(TheTarget->createMCInstrAnalysis(MII.get())); std::unique_ptr<MCObjectDisassembler> OD( new MCObjectDisassembler(*Obj, *DisAsm, *MIA)); std::unique_ptr<MCModule> MCM(OD->buildEmptyModule()); if (!MCM) return 1; TransOpt::Level TOLvl; switch (TransOptLevel) { default: errs() << ToolName << ": invalid optimization level.\n"; return 1; case 0: TOLvl = TransOpt::None; break; case 1: TOLvl = TransOpt::Less; break; case 2: TOLvl = TransOpt::Default; break; case 3: TOLvl = TransOpt::Aggressive; break; } std::unique_ptr<DCRegisterSema> DRS( TheTarget->createDCRegisterSema(TripleName, *MRI, *MII)); if (!DRS) { errs() << "error: no dc register sema for target " << TripleName << "\n"; return 1; } std::unique_ptr<DCInstrSema> DIS( TheTarget->createDCInstrSema(TripleName, *DRS, *MRI, *MII)); if (!DIS) { errs() << "error: no dc instruction sema for target " << TripleName << "\n"; return 1; } std::unique_ptr<DCTranslator> DT(new DCTranslator(getGlobalContext(), TOLvl, *DIS, *DRS, *MIP, *MCM, OD.get(), AnnotateIROutput)); // Now run it ! Module *Mod = DT->getModule(); std::string ErrorMsg; EngineBuilder Builder(Mod); Builder.setErrorStr(&ErrorMsg); Builder.setOptLevel(CodeGenOpt::Aggressive); Builder.setEngineKind(EngineKind::JIT); Builder.setAllocateGVsWithCode(false); ExecutionEngine *EE = Builder.create(); if (!EE) { errs() << "error: Unable to create ExecutionEngine: " << ErrorMsg << "\n"; return -1; } const DataLayout *DL = EE->getDataLayout(); const StructLayout *SL = DL->getStructLayout(DRS->getRegSetType()); uint8_t *RegSet = new uint8_t[SL->getSizeInBytes()]; const unsigned StackSize = 8192; uint8_t *StackPtr = new uint8_t[StackSize]; std::vector<GenericValue> Args; GenericValue GV; GV.PointerVal = RegSet; Args.push_back(GV); GV.PointerVal = StackPtr; Args.push_back(GV); GV.IntVal = APInt(32, StackSize); Args.push_back(GV); GV.IntVal = APInt(32, argc - 2); Args.push_back(GV); GV.PointerVal = argv + 2; Args.push_back(GV); EE->runFunction(DT->getInitRegSetFunction(), Args); Args.clear(); GV.PointerVal = RegSet; Args.push_back(GV); unsigned PCSize, PCOffset; DRS->getRegOffsetInRegSet(DL, MRI->getProgramCounter(), PCSize, PCOffset); __dc_DT = DT.get(); __dc_EE = EE; uint64_t CurPC = DT->getEntrypoint(); while (CurPC != ~0ULL) { Function *Fn = DT->getFunctionAt(CurPC); DEBUG(dbgs() << "Executing function " << Fn->getName() << "\n"); EE->runFunction(Fn, Args); CurPC = loadRegFromSet(RegSet, PCOffset, PCSize); } // Dump the IR we found. if (DumpIR) Mod->dump(); GV = EE->runFunction(DT->getFiniRegSetFunction(), Args); return GV.IntVal.getZExtValue(); }
int main() { InitializeNativeTarget(); LLVMContext& Context = getGlobalContext(); Module *M = new Module("test C++ exception handling ", Context); StructType* MyStructType = StructType::create(Context, "struct.MyStruct"); Type* MyStructFields[] = { Type::getInt32Ty(Context), Type::getInt32Ty(Context) }; MyStructType->setBody(MyStructFields); GlobalValue* throwFunc = cast<GlobalValue>(M->getOrInsertFunction("throwMyStruct", Type::getVoidTy(Context), NULL)); GlobalValue* MyStructTypeInfo = cast<GlobalValue>(M->getOrInsertGlobal("MyStructTypeInfo", Type::getInt8Ty(Context))); Function* gxx_personality = Function::Create(FunctionType::get(Type::getInt32Ty(Context), true), Function::ExternalLinkage, "__gxx_personality_v0", M); Function* begin_catch = Function::Create(FunctionType::get(Type::getInt8PtrTy(Context), Type::getInt8PtrTy(Context), false), Function::ExternalLinkage, "__cxa_begin_catch", M); Function* end_catch = Function::Create(FunctionType::get(Type::getVoidTy(Context), false), Function::ExternalLinkage, "__cxa_end_catch", M); Function* testExceptions = cast<Function>(M->getOrInsertFunction("testExceptions", Type::getInt32Ty(Context), NULL)); BasicBlock* entryBB = BasicBlock::Create(Context, "", testExceptions); BasicBlock* landPadBB = BasicBlock::Create(Context, "landPad", testExceptions); BasicBlock* noErrorBB = BasicBlock::Create(Context, "noError", testExceptions); IRBuilder<> builder(entryBB); Value* invokeThrow = builder.CreateInvoke(throwFunc, noErrorBB, landPadBB); builder.SetInsertPoint(noErrorBB); builder.CreateRet( builder.getInt32(666) ); // should never happen //writing landingpad! <<<<<<< builder.SetInsertPoint(landPadBB); Value* gxx_personality_i8 = builder.CreateBitCast(gxx_personality, Type::getInt8PtrTy(Context)); Type* caughtType = StructType::get(builder.getInt8PtrTy(), builder.getInt32Ty(), NULL); LandingPadInst* caughtResult = builder.CreateLandingPad(caughtType, gxx_personality_i8, 1); // we can catch any C++ exception we want // but now we are catching MyStruct caughtResult->addClause(MyStructTypeInfo); //we are sure to catch MyStruct so no other checks are needed //if throwMyStruct() throws anything but MyStruct it won't pass to the current landingpad BB Value* thrownExctn = builder.CreateExtractValue(caughtResult, 0); Value* thrownObject = builder.CreateCall(begin_catch, thrownExctn); Value* object = builder.CreateBitCast(thrownObject, MyStructType->getPointerTo()); Value* resultPtr = builder.CreateStructGEP(object, 1); Value* result = builder.CreateLoad(resultPtr); builder.CreateCall(end_catch); builder.CreateRet( result ); // << z.y TargetOptions Opts; Opts.JITExceptionHandling = true; // DO NOT FORGET THIS OPTION !!!!!!11 ExecutionEngine* EE = EngineBuilder(M) .setEngineKind(EngineKind::JIT) .setTargetOptions(Opts) .create(); EE->addGlobalMapping(throwFunc, reinterpret_cast<void*>(&throwMyStruct)); EE->addGlobalMapping(MyStructTypeInfo, MyStruct::getTypeInfo()); verifyFunction(*testExceptions); outs() << *testExceptions; std::vector<GenericValue> noArgs; GenericValue gv = EE->runFunction(testExceptions, noArgs); outs() << "\ntestExceptions result: " << gv.IntVal << "\n"; delete EE; llvm_shutdown(); return 0; }
int main(int argc, char **argv) { cl::ParseCommandLineOptions(argc, argv, " BrainF compiler\n"); LLVMContext Context; if (InputFilename == "") { errs() << "Error: You must specify the filename of the program to " "be compiled. Use --help to see the options.\n"; abort(); } //Get the output stream raw_ostream *out = &outs(); if (!JIT) { if (OutputFilename == "") { std::string base = InputFilename; if (InputFilename == "-") { base = "a"; } // Use default filename. OutputFilename = base+".bc"; } if (OutputFilename != "-") { std::error_code EC; out = new raw_fd_ostream(OutputFilename, EC, sys::fs::F_None); } } //Get the input stream std::istream *in = &std::cin; if (InputFilename != "-") in = new std::ifstream(InputFilename.c_str()); //Gather the compile flags BrainF::CompileFlags cf = BrainF::flag_off; if (ArrayBoundsChecking) cf = BrainF::CompileFlags(cf | BrainF::flag_arraybounds); //Read the BrainF program BrainF bf; std::unique_ptr<Module> Mod(bf.parse(in, 65536, cf, Context)); // 64 KiB if (in != &std::cin) delete in; addMainFunction(Mod.get()); //Verify generated code if (verifyModule(*Mod)) { errs() << "Error: module failed verification. This shouldn't happen.\n"; abort(); } //Write it out if (JIT) { InitializeNativeTarget(); outs() << "------- Running JIT -------\n"; Module &M = *Mod; ExecutionEngine *ee = EngineBuilder(std::move(Mod)).create(); std::vector<GenericValue> args; Function *brainf_func = M.getFunction("brainf"); GenericValue gv = ee->runFunction(brainf_func, args); } else { WriteBitcodeToFile(Mod.get(), *out); } //Clean up if (out != &outs()) delete out; llvm_shutdown(); return 0; }
int main() { InitializeNativeTarget(); LLVMContext Context; // Create some module to put our function into it. Module *M = new Module("test", Context); // Create the add1 function entry and insert this entry into module M. The // function will have a return type of "int" and take an argument of "int". // The '0' terminates the list of argument types. Function *Add1F = cast<Function>(M->getOrInsertFunction("add1", Type::getInt32Ty(Context), Type::getInt32Ty(Context), (Type *)0)); // Add a basic block to the function. As before, it automatically inserts // because of the last argument. BasicBlock *BB = BasicBlock::Create(Context, "EntryBlock", Add1F); // Create a basic block builder with default parameters. The builder will // automatically append instructions to the basic block `BB'. IRBuilder<> builder(BB); // Get pointers to the constant `1'. Value *One = builder.getInt32(1); // Get pointers to the integer argument of the add1 function... assert(Add1F->arg_begin() != Add1F->arg_end()); // Make sure there's an arg Argument *ArgX = Add1F->arg_begin(); // Get the arg ArgX->setName("AnArg"); // Give it a nice symbolic name for fun. // Create the add instruction, inserting it into the end of BB. Value *Add = builder.CreateAdd(One, ArgX); // Create the return instruction and add it to the basic block builder.CreateRet(Add); // Now, function add1 is ready. // Now we're going to create function `foo', which returns an int and takes no // arguments. Function *FooF = cast<Function>(M->getOrInsertFunction("foo", Type::getInt32Ty(Context), (Type *)0)); // Add a basic block to the FooF function. BB = BasicBlock::Create(Context, "EntryBlock", FooF); // Tell the basic block builder to attach itself to the new basic block builder.SetInsertPoint(BB); // Get pointer to the constant `10'. Value *Ten = builder.getInt32(10); // Pass Ten to the call to Add1F CallInst *Add1CallRes = builder.CreateCall(Add1F, Ten); Add1CallRes->setTailCall(true); // Create the return instruction and add it to the basic block. builder.CreateRet(Add1CallRes); // Now we create the JIT. ExecutionEngine* EE = EngineBuilder(M).create(); outs() << "We just constructed this LLVM module:\n\n" << *M; outs() << "\n\nRunning foo: "; outs().flush(); // Call the `foo' function with no arguments: std::vector<GenericValue> noargs; GenericValue gv = EE->runFunction(FooF, noargs); // Import result of execution: outs() << "Result: " << gv.IntVal << "\n"; EE->freeMachineCodeForFunction(FooF); delete EE; llvm_shutdown(); return 0; }
int main() { // Create some module to put our function into it. Module *M = new Module("test"); // Create the add1 function entry and insert this entry into module M. The // function will have a return type of "int" and take an argument of "int". // The '0' terminates the list of argument types. Function *Add1F = cast<Function>(M->getOrInsertFunction("add1", Type::Int32Ty, Type::Int32Ty, (Type *)0)); // Add a basic block to the function. As before, it automatically inserts // because of the last argument. BasicBlock *BB = BasicBlock::Create("EntryBlock", Add1F); // Get pointers to the constant `1'. Value *One = ConstantInt::get(Type::Int32Ty, 1); // Get pointers to the integer argument of the add1 function... assert(Add1F->arg_begin() != Add1F->arg_end()); // Make sure there's an arg Argument *ArgX = Add1F->arg_begin(); // Get the arg ArgX->setName("AnArg"); // Give it a nice symbolic name for fun. // Create the add instruction, inserting it into the end of BB. Instruction *Add = BinaryOperator::CreateAdd(One, ArgX, "addresult", BB); // Create the return instruction and add it to the basic block ReturnInst::Create(Add, BB); // Now, function add1 is ready. // Now we going to create function `foo', which returns an int and takes no // arguments. Function *FooF = cast<Function>(M->getOrInsertFunction("foo", Type::Int32Ty, (Type *)0)); // Add a basic block to the FooF function. BB = BasicBlock::Create("EntryBlock", FooF); // Get pointers to the constant `10'. Value *Ten = ConstantInt::get(Type::Int32Ty, 10); // Pass Ten to the call call: CallInst *Add1CallRes = CallInst::Create(Add1F, Ten, "add1", BB); Add1CallRes->setTailCall(true); // Create the return instruction and add it to the basic block. ReturnInst::Create(Add1CallRes, BB); // Now we create the JIT. ExistingModuleProvider* MP = new ExistingModuleProvider(M); ExecutionEngine* EE = ExecutionEngine::create(MP, false); outs() << "We just constructed this LLVM module:\n\n" << *M; outs() << "\n\nRunning foo: "; outs().flush(); // Call the `foo' function with no arguments: std::vector<GenericValue> noargs; GenericValue gv = EE->runFunction(FooF, noargs); // Import result of execution: outs() << "Result: " << gv.IntVal << "\n"; return 0; }