static void llvm_init(){ ExecutionEngine *ee = tcg_llvm_ctx->getExecutionEngine(); FunctionPassManager *fpm = tcg_llvm_ctx->getFunctionPassManager(); Module *mod = tcg_llvm_ctx->getModule(); LLVMContext &ctx = mod->getContext(); // Link logging function in with JIT Function *logFunc; std::vector<Type*> argTypes; // DynValBuffer* argTypes.push_back(IntegerType::get(ctx, 8*sizeof(uintptr_t))); // DynValEntryType argTypes.push_back(IntegerType::get(ctx, 8*sizeof(DynValEntryType))); // LogOp argTypes.push_back(IntegerType::get(ctx, 8*sizeof(LogOp))); // Dynamic value argTypes.push_back(IntegerType::get(ctx, 8*sizeof(uintptr_t))); logFunc = Function::Create( FunctionType::get(Type::getVoidTy(ctx), argTypes, false), Function::ExternalLinkage, "log_dynval", mod); logFunc->addFnAttr(Attribute::AlwaysInline); ee->addGlobalMapping(logFunc, (void*) &log_dynval); // Create instrumentation pass and add to function pass manager llvm::FunctionPass *instfp = createPandaInstrFunctionPass(mod); fpm->add(instfp); PIFP = static_cast<PandaInstrFunctionPass*>(instfp); }
int main() { // Module Construction LLVMContext &context = llvm::getGlobalContext(); Module *module = new Module("test", context); //declare 'value' and 'foo' in module 'test' GlobalVariable *v = cast<GlobalVariable>(module->getOrInsertGlobal("value", Type::getInt32Ty(context))); // prototype of foo is: int foo(int x) Function *f = cast<Function>(module->getOrInsertFunction("foo", Type::getInt32Ty(context), Type::getInt32Ty(context), NULL)); //create a LLVM function 'bar' Function* bar = cast<Function>(module->getOrInsertFunction("bar", Type::getInt32Ty(context),NULL)); //basic block construction BasicBlock* entry = BasicBlock::Create(context, "entry", bar); IRBuilder<> builder(entry); //read 'value' Value * v_IR = builder.CreateLoad(v); //call foo(value) Value * ret = builder.CreateCall(f, v_IR); //return return value of 'foo' builder.CreateRet(ret); //now bind global value and global function //create execution engine first InitializeNativeTarget(); ExecutionEngine *ee = EngineBuilder(module).setEngineKind(EngineKind::JIT).create(); //map global variable ee->addGlobalMapping(v, &value); //map global function ee->addGlobalMapping(f, (void *)foo); // JIT and run void *barAddr = ee->getPointerToFunction(bar); typedef int (*FuncType)(); FuncType barFunc = (FuncType)barAddr; std::cout << barFunc() << std::endl; return 0; }
int main() { ygt_print("Hello!\n"); InitializeNativeTarget(); InitializeNativeTargetAsmPrinter(); InitializeNativeTargetAsmParser(); InitializeNativeTargetDisassembler(); ygt_print("Creating LLVM context and module...\n"); LLVMContext ctx; auto m = make_unique<Module>("the_module", ctx); ygt_print("Creating StackMapHelper...\n"); StackMapHelper smhelper; ygt_print("Declaring yg_stack_swap as an LLVM-level function...\n"); declare_ss(ctx, *m); ygt_print("Constructing bar, the ss leaf...\n"); Function *bar; smid_t bar_smid; tie(bar, bar_smid) = make_ss_leaf("barss", &main_stack, &coro_stack, smhelper, ctx, *m); verifyFunction(*bar); ygt_print("Constructing foo, the caller...\n"); Function *foo; smid_t foo_smid; tie(foo, foo_smid) = make_caller("foo", bar, smhelper, ctx, *m); verifyFunction(*foo); m->dump(); Function *ss_func = m->getFunction("yg_stack_swap"); ygt_print("Creating execution engine...\n"); ExecutionEngine *ee = EngineBuilder(move(m)).setEngineKind(EngineKind::JIT).create(); ygt_print("Execution engine created.\n"); StackMapSectionRecorder smsr; ygt_print("Registering JIT event listener...\n"); ee->RegisterJITEventListener(&smsr); EHFrameSectionRegisterer reg; ygt_print("Registering EHFrame registerer...\n"); ee->RegisterJITEventListener(®); ygt_print("Adding global mapping yg_stack_swap...\n"); ee->addGlobalMapping(ss_func, reinterpret_cast<void*>(yg_stack_swap)); ygt_print("JIT compiling...\n"); ee->finalizeObject(); ygt_print("Adding stack map sections...\n"); smhelper.add_stackmap_sections(smsr, *ee); ygt_print("Registering EH frames...\n"); reg.registerEHFrameSections(); uintptr_t yg_stack_swap_addr = ee->getFunctionAddress("yg_stack_swap"); ygt_print("yg_stack_swap_addr=%" PRIxPTR ", yg_stack_swap=%p\n", yg_stack_swap_addr, yg_stack_swap); assert(yg_stack_swap_addr == reinterpret_cast<uintptr_t>(yg_stack_swap)); ygt_print("Getting foo...\n"); void (*the_real_foo)(int32_t, int64_t, float, double) = (void(*)(int32_t, int64_t, float, double)) ee->getFunctionAddress("foo"); ygt_print("the_real_foo == %p\n", the_real_foo); ygt_print("Prepare corotine for introspection...\n"); coro_stack = YGStack::alloc(8*1024*1024); coro_stack.init(reinterpret_cast<uintptr_t>(coro)); MyCtx my_ctx = { foo_smid, bar_smid, &smhelper }; ygt_print("Swap-stack to prepare the coroutine...\n"); yg_stack_swap(&main_stack, &coro_stack, reinterpret_cast<uintptr_t>(&my_ctx)); ygt_print("Back from coro.\n"); ygt_print("Calling the_real_foo...\n"); the_real_foo(100, 200, 300.0f, 400.0); ygt_print("Returned from foo.\n"); return 0; }
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; }