MonoEERef mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, FunctionEmittedCb *emitted_cb, ExceptionTableCb *exception_cb, DlSymCb *dlsym_cb, LLVMExecutionEngineRef *ee) { alloc_code_mem_cb = alloc_cb; InitializeNativeTarget (); InitializeNativeTargetAsmPrinter(); EnableMonoEH = true; MonoEHFrameSymbol = "mono_eh_frame"; EngineBuilder EB; #if defined(TARGET_AMD64) || defined(TARGET_X86) std::vector<std::string> attrs; // FIXME: Autodetect this attrs.push_back("sse3"); attrs.push_back("sse4.1"); EB.setMAttrs (attrs); #endif auto TM = EB.selectTarget (); assert (TM); jit = new MonoLLVMJIT (TM); return NULL; }
int llvm::runOrcLazyJIT(std::vector<std::unique_ptr<Module>> Ms, const std::vector<std::string> &Args) { // Add the program's symbols into the JIT's search space. if (sys::DynamicLibrary::LoadLibraryPermanently(nullptr)) { errs() << "Error loading program symbols.\n"; return 1; } // Grab a target machine and try to build a factory function for the // target-specific Orc callback manager. EngineBuilder EB; EB.setOptLevel(getOptLevel()); auto TM = std::unique_ptr<TargetMachine>(EB.selectTarget()); Triple T(TM->getTargetTriple()); auto CompileCallbackMgr = orc::createLocalCompileCallbackManager(T, 0); // If we couldn't build the factory function then there must not be a callback // manager for this target. Bail out. if (!CompileCallbackMgr) { errs() << "No callback manager available for target '" << TM->getTargetTriple().str() << "'.\n"; return 1; } auto IndirectStubsMgrBuilder = orc::createLocalIndirectStubsManagerBuilder(T); // If we couldn't build a stubs-manager-builder for this target then bail out. if (!IndirectStubsMgrBuilder) { errs() << "No indirect stubs manager available for target '" << TM->getTargetTriple().str() << "'.\n"; return 1; } // Everything looks good. Build the JIT. OrcLazyJIT J(std::move(TM), std::move(CompileCallbackMgr), std::move(IndirectStubsMgrBuilder), OrcInlineStubs); // Add the module, look up main and run it. for (auto &M : Ms) cantFail(J.addModule(std::shared_ptr<Module>(std::move(M)))); if (auto MainSym = J.findSymbol("main")) { typedef int (*MainFnPtr)(int, const char*[]); std::vector<const char *> ArgV; for (auto &Arg : Args) ArgV.push_back(Arg.c_str()); auto Main = fromTargetAddress<MainFnPtr>(cantFail(MainSym.getAddress())); return Main(ArgV.size(), (const char**)ArgV.data()); } else if (auto Err = MainSym.takeError()) logAllUnhandledErrors(std::move(Err), llvm::errs(), ""); else errs() << "Could not find main function.\n"; return 1; }
void Builder::createJIT() { InitializeNativeTarget(); std::string err; EngineBuilder eb = EngineBuilder(this->_mod); eb.setErrorStr(&err); auto jit = eb.create(); this->_jit = jit; if (!jit) { std::cerr << "Impossible de créer le moteur JIT : " << err << std::endl; } }
int llvm::runOrcLazyJIT(std::unique_ptr<Module> M, int ArgC, char* ArgV[]) { // Add the program's symbols into the JIT's search space. if (sys::DynamicLibrary::LoadLibraryPermanently(nullptr)) { errs() << "Error loading program symbols.\n"; return 1; } // Grab a target machine and try to build a factory function for the // target-specific Orc callback manager. EngineBuilder EB; EB.setOptLevel(getOptLevel()); auto TM = std::unique_ptr<TargetMachine>(EB.selectTarget()); auto &Context = getGlobalContext(); auto CallbackMgrBuilder = OrcLazyJIT::createCallbackMgrBuilder(Triple(TM->getTargetTriple())); // If we couldn't build the factory function then there must not be a callback // manager for this target. Bail out. if (!CallbackMgrBuilder) { errs() << "No callback manager available for target '" << TM->getTargetTriple().str() << "'.\n"; return 1; } auto IndirectStubsMgrBuilder = OrcLazyJIT::createIndirectStubsMgrBuilder(Triple(TM->getTargetTriple())); // If we couldn't build a stubs-manager-builder for this target then bail out. if (!IndirectStubsMgrBuilder) { errs() << "No indirect stubs manager available for target '" << TM->getTargetTriple().str() << "'.\n"; return 1; } // Everything looks good. Build the JIT. OrcLazyJIT J(std::move(TM), Context, CallbackMgrBuilder, std::move(IndirectStubsMgrBuilder), OrcInlineStubs); // Add the module, look up main and run it. auto MainHandle = J.addModule(std::move(M)); auto MainSym = J.findSymbolIn(MainHandle, "main"); if (!MainSym) { errs() << "Could not find main function.\n"; return 1; } typedef int (*MainFnPtr)(int, char*[]); auto Main = fromTargetAddress<MainFnPtr>(MainSym.getAddress()); return Main(ArgC, ArgV); }
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; }
ExecutionEngine* createExecutionEngine(Module* mod) { if (globalExecEngine == 0) { //we first have to initialize the native target for code generation const bool initFailed = InitializeNativeTarget(); if (initFailed) { errs() << "ERROR: could not initialize native target (required for " << "LLVM execution engine)\n"; return NULL; } std::string errorMessage = ""; EngineBuilder eb = EngineBuilder(mod); eb.setEngineKind(EngineKind::JIT); eb.setErrorStr(&errorMessage); eb.setJITMemoryManager(JITMemoryManager::CreateDefaultMemManager()); eb.setOptLevel(CodeGenOpt::Aggressive); eb.setAllocateGVsWithCode(false); eb.setCodeModel(CodeModel::Default); //eb.setMArch("x86-64"); //eb.setMCPU("corei7"); //std::vector<std::string> attrs; //attrs.push_back("+sse41"); //eb.setMAttrs(attrs); globalExecEngine = eb.create(); if (errorMessage != "") { errs() << "ERROR: could not create execution engine for module " << mod->getModuleIdentifier() << ": " << errorMessage << "\n"; return NULL; } if (!globalExecEngine) { errs() << "ERROR: could not create execution engine for module " << mod->getModuleIdentifier() << "!\n"; return NULL; } } return globalExecEngine; }
LLVMExecutionEngineRef mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, FunctionEmittedCb *emitted_cb, ExceptionTableCb *exception_cb, DlSymCb *dlsym_cb) { std::string Error; force_pass_linking (); #ifdef TARGET_ARM LLVMInitializeARMTarget (); LLVMInitializeARMTargetInfo (); LLVMInitializeARMTargetMC (); #else LLVMInitializeX86Target (); LLVMInitializeX86TargetInfo (); LLVMInitializeX86TargetMC (); #endif mono_mm = new MonoJITMemoryManager (); mono_mm->alloc_cb = alloc_cb; mono_mm->dlsym_cb = dlsym_cb; //JITExceptionHandling = true; // PrettyStackTrace installs signal handlers which trip up libgc DisablePrettyStackTrace = true; /* * The Default code model doesn't seem to work on amd64, * test_0_fields_with_big_offsets (among others) crashes, because LLVM tries to call * memset using a normal pcrel code which is in 32bit memory, while memset isn't. */ TargetOptions opts; opts.JITExceptionHandling = 1; EngineBuilder b (unwrap (MP)); #ifdef TARGET_AMD64 ExecutionEngine *EE = b.setJITMemoryManager (mono_mm).setTargetOptions (opts).setCodeModel (CodeModel::Large).setAllocateGVsWithCode (true).create (); #else ExecutionEngine *EE = b.setJITMemoryManager (mono_mm).setTargetOptions (opts).setAllocateGVsWithCode (true).create (); #endif g_assert (EE); #if 0 ExecutionEngine *EE = ExecutionEngine::createJIT (unwrap (MP), &Error, mono_mm, CodeGenOpt::Default, true, Reloc::Default, CodeModel::Large); if (!EE) { errs () << "Unable to create LLVM ExecutionEngine: " << Error << "\n"; g_assert_not_reached (); } #endif EE->InstallExceptionTableRegister (exception_cb); mono_event_listener = new MonoJITEventListener (emitted_cb); EE->RegisterJITEventListener (mono_event_listener); fpm = new FunctionPassManager (unwrap (MP)); fpm->add(new DataLayout(*EE->getDataLayout())); PassRegistry &Registry = *PassRegistry::getPassRegistry(); initializeCore(Registry); initializeScalarOpts(Registry); //initializeIPO(Registry); initializeAnalysis(Registry); initializeIPA(Registry); initializeTransformUtils(Registry); initializeInstCombine(Registry); //initializeInstrumentation(Registry); initializeTarget(Registry); llvm::cl::ParseEnvironmentOptions("mono", "MONO_LLVM", ""); if (PassList.size() > 0) { /* Use the passes specified by the env variable */ /* Only the passes in force_pass_linking () can be used */ for (unsigned i = 0; i < PassList.size(); ++i) { const PassInfo *PassInf = PassList[i]; Pass *P = 0; if (PassInf->getNormalCtor()) P = PassInf->getNormalCtor()(); fpm->add (P); } } else { /* Use the same passes used by 'opt' by default, without the ipo passes */ const char *opts = "-simplifycfg -domtree -domfrontier -scalarrepl -instcombine -simplifycfg -domtree -domfrontier -scalarrepl -simplify-libcalls -instcombine -simplifycfg -instcombine -simplifycfg -reassociate -domtree -loops -loop-simplify -domfrontier -loop-simplify -lcssa -loop-rotate -licm -lcssa -loop-unswitch -instcombine -scalar-evolution -loop-simplify -lcssa -iv-users -indvars -loop-deletion -loop-simplify -lcssa -loop-unroll -instcombine -memdep -gvn -memdep -memcpyopt -sccp -instcombine -domtree -memdep -dse -adce -gvn -simplifycfg -preverify -domtree -verify"; char **args; int i; args = g_strsplit (opts, " ", 1000); for (i = 0; args [i]; i++) ; llvm::cl::ParseCommandLineOptions (i, args, ""); g_strfreev (args); for (unsigned i = 0; i < PassList.size(); ++i) { const PassInfo *PassInf = PassList[i]; Pass *P = 0; if (PassInf->getNormalCtor()) P = PassInf->getNormalCtor()(); g_assert (P->getPassKind () == llvm::PT_Function || P->getPassKind () == llvm::PT_Loop); fpm->add (P); } /* fpm->add(createInstructionCombiningPass()); fpm->add(createReassociatePass()); fpm->add(createGVNPass()); fpm->add(createCFGSimplificationPass()); */ } return wrap(EE); }
MonoEERef mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, FunctionEmittedCb *emitted_cb, ExceptionTableCb *exception_cb, DlSymCb *dlsym_cb, LLVMExecutionEngineRef *ee) { std::string Error; MonoEE *mono_ee; init_llvm (); mono_ee = new MonoEE (); MonoJITMemoryManager *mono_mm = new MonoJITMemoryManager (); mono_mm->alloc_cb = alloc_cb; mono_mm->dlsym_cb = dlsym_cb; mono_mm->exception_cb = exception_cb; mono_ee->mm = mono_mm; /* * The Default code model doesn't seem to work on amd64, * test_0_fields_with_big_offsets (among others) crashes, because LLVM tries to call * memset using a normal pcrel code which is in 32bit memory, while memset isn't. */ TargetOptions opts; opts.JITExceptionHandling = 1; StringRef cpu_name = sys::getHostCPUName (); // EngineBuilder no longer has a copy assignment operator (?) std::unique_ptr<Module> Owner(unwrap(MP)); EngineBuilder b (std::move(Owner)); ExecutionEngine *EE = b.setJITMemoryManager (mono_mm).setTargetOptions (opts).setAllocateGVsWithCode (true).setMCPU (cpu_name).create (); g_assert (EE); mono_ee->EE = EE; MonoJITEventListener *listener = new MonoJITEventListener (emitted_cb); EE->RegisterJITEventListener (listener); mono_ee->listener = listener; FunctionPassManager *fpm = new FunctionPassManager (unwrap (MP)); mono_ee->fpm = fpm; fpm->add(new DataLayoutPass(*EE->getDataLayout())); if (PassList.size() > 0) { /* Use the passes specified by the env variable */ /* Only the passes in force_pass_linking () can be used */ for (unsigned i = 0; i < PassList.size(); ++i) { const PassInfo *PassInf = PassList[i]; Pass *P = 0; if (PassInf->getNormalCtor()) P = PassInf->getNormalCtor()(); fpm->add (P); } } else { /* Use the same passes used by 'opt' by default, without the ipo passes */ const char *opts = "-simplifycfg -domtree -domfrontier -scalarrepl -instcombine -simplifycfg -domtree -domfrontier -scalarrepl -instcombine -simplifycfg -instcombine -simplifycfg -reassociate -domtree -loops -loop-simplify -domfrontier -loop-simplify -lcssa -loop-rotate -licm -lcssa -loop-unswitch -instcombine -scalar-evolution -loop-simplify -lcssa -iv-users -indvars -loop-deletion -loop-simplify -lcssa -loop-unroll -instcombine -memdep -gvn -memdep -memcpyopt -sccp -instcombine -domtree -memdep -dse -adce -gvn -simplifycfg"; char **args; int i; args = g_strsplit (opts, " ", 1000); for (i = 0; args [i]; i++) ; llvm::cl::ParseCommandLineOptions (i, args, ""); g_strfreev (args); for (unsigned i = 0; i < PassList.size(); ++i) { const PassInfo *PassInf = PassList[i]; Pass *P = 0; if (PassInf->getNormalCtor()) P = PassInf->getNormalCtor()(); g_assert (P->getPassKind () == llvm::PT_Function || P->getPassKind () == llvm::PT_Loop); fpm->add (P); } /* fpm->add(createInstructionCombiningPass()); fpm->add(createReassociatePass()); fpm->add(createGVNPass()); fpm->add(createCFGSimplificationPass()); */ } *ee = wrap (EE); return mono_ee; }