ExecutionEngine * JIT_to_ExecutionEngine (Module * m) { InitializeNativeTarget(); InitializeNativeTargetAsmPrinter(); InitializeNativeTargetAsmParser(); PassRegistry * Registry = PassRegistry::getPassRegistry(); initializeCore(*Registry); initializeCodeGen(*Registry); initializeLowerIntrinsicsPass(*Registry); std::string errMessage; EngineBuilder builder{std::unique_ptr<Module>(m)}; builder.setErrorStr(&errMessage); builder.setMCPU(sys::getHostCPUName()); TargetOptions opts = InitTargetOptionsFromCodeGenFlags(); builder.setTargetOptions(opts); CodeGenOpt::Level optLevel = CodeGenOpt::Level::None; switch (OptLevel) { case '0': optLevel = CodeGenOpt::None; break; case '1': optLevel = CodeGenOpt::Less; break; case '2': optLevel = CodeGenOpt::Default; break; case '3': optLevel = CodeGenOpt::Aggressive; break; default: errs() << OptLevel << " is an invalid optimization level.\n"; } builder.setOptLevel(optLevel); if ((strncmp(lGetSystemISA(), "avx2", 4) == 0)) { std::vector<std::string> attrs; attrs.push_back("avx2"); builder.setMAttrs(attrs); } // builder.selectTarget(); if (LLVM_UNLIKELY(DumpGeneratedIR)) { if (IROutputFilename.empty()) { m->dump(); } else { std::error_code error; llvm::raw_fd_ostream out(IROutputFilename, error, sys::fs::OpenFlags::F_None); m->print(out, nullptr); } } ExecutionEngine * engine = builder.create(); ICGrepObjectCache * cache = nullptr; if (engine == nullptr) { throw std::runtime_error("Could not create ExecutionEngine: " + errMessage); } if (EnableObjectCache) { if (ObjectCacheDir.empty()) // Default is $HOME/.cache/icgrep cache = new ICGrepObjectCache(); else cache = new ICGrepObjectCache(ObjectCacheDir); engine->setObjectCache(cache); } return engine; }
ExecutionEngine *MCJITHelper::compileModule(Module *M) { assert(EngineMap.find(M) == EngineMap.end()); if (M == CurrentModule) closeCurrentModule(); std::string ErrStr; ExecutionEngine *EE = EngineBuilder(M) .setErrorStr(&ErrStr) .setMCJITMemoryManager(new HelpingMemoryManager(this)) .create(); if (!EE) { fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str()); exit(1); } if (UseObjectCache) EE->setObjectCache(&OurObjectCache); // Get the ModuleID so we can identify IR input files const std::string ModuleID = M->getModuleIdentifier(); // If we've flagged this as an IR file, it doesn't need function passes run. if (0 != ModuleID.compare(0, 3, "IR:")) { FunctionPassManager *FPM = 0; // Create a FPM for this module FPM = new FunctionPassManager(M); // Set up the optimizer pipeline. Start with registering info about how the // target lays out data structures. FPM->add(new DataLayout(*EE->getDataLayout())); // Provide basic AliasAnalysis support for GVN. FPM->add(createBasicAliasAnalysisPass()); // Promote allocas to registers. FPM->add(createPromoteMemoryToRegisterPass()); // Do simple "peephole" optimizations and bit-twiddling optzns. FPM->add(createInstructionCombiningPass()); // Reassociate expressions. FPM->add(createReassociatePass()); // Eliminate Common SubExpressions. FPM->add(createGVNPass()); // Simplify the control flow graph (deleting unreachable blocks, etc). FPM->add(createCFGSimplificationPass()); FPM->doInitialization(); // For each function in the module Module::iterator it; Module::iterator end = M->end(); for (it = M->begin(); it != end; ++it) { // Run the FPM on this function FPM->run(*it); } delete FPM; } EE->finalizeObject(); // Store this engine EngineMap[M] = EE; return EE; }