void PassManagerBuilder::populateFunctionPassManager(FunctionPassManager &FPM) { addExtensionsToPM(EP_EarlyAsPossible, FPM); // Add LibraryInfo if we have some. if (LibraryInfo) FPM.add(new TargetLibraryInfo(*LibraryInfo)); if (OptLevel == 0) return; addInitialAliasAnalysisPasses(FPM); FPM.add(createCFGSimplificationPass()); if (UseNewSROA) FPM.add(createSROAPass()); else FPM.add(createScalarReplAggregatesPass()); FPM.add(createEarlyCSEPass()); FPM.add(createLowerExpectIntrinsicPass()); }
/// AddOptimizationPasses - This routine adds optimization passes /// based on selected optimization level, OptLevel. This routine /// duplicates llvm-gcc behaviour. /// /// OptLevel - Optimization Level static void AddOptimizationPasses(PassManagerBase &MPM,FunctionPassManager &FPM, unsigned OptLevel) { FPM.add(createVerifierPass()); // Verify that input is correct PassManagerBuilder Builder; Builder.OptLevel = OptLevel; if (DisableInline) { // No inlining pass } else if (OptLevel > 1) { unsigned Threshold = 225; if (OptLevel > 2) Threshold = 275; Builder.Inliner = createFunctionInliningPass(Threshold); } else { Builder.Inliner = createAlwaysInlinerPass(); } Builder.DisableUnitAtATime = !UnitAtATime; Builder.DisableUnrollLoops = OptLevel == 0; Builder.DisableSimplifyLibCalls = DisableSimplifyLibCalls; Builder.populateFunctionPassManager(FPM); Builder.populateModulePassManager(MPM); }
FunctionPassManager* Builder::getStandardOptimizer() { FunctionPassManager* optimizer = new FunctionPassManager(this->_mod); // Set up the optimizer pipeline. Start with registering info about how the // target lays out data structures. if (this->_jit) { optimizer->add(new DataLayoutPass(*this->_jit->getDataLayout())); } // Provide basic AliasAnalysis support for GVN. optimizer->add(createBasicAliasAnalysisPass()); // Do simple "peephole" optimizations and bit-twiddling optzns. optimizer->add(createInstructionCombiningPass()); // Reassociate expressions. optimizer->add(createReassociatePass()); // Eliminate Common SubExpressions. optimizer->add(createGVNPass()); // Simplify the control flow graph (deleting unreachable blocks, etc). optimizer->add(createCFGSimplificationPass()); optimizer->doInitialization(); return optimizer; }
/// Optimize merged modules using various IPO passes bool LTOCodeGenerator::generateObjectFile(raw_ostream &out, std::string &errMsg) { if ( this->determineTarget(errMsg) ) return true; Module* mergedModule = _linker.getModule(); // if options were requested, set them if ( !_codegenOptions.empty() ) cl::ParseCommandLineOptions(_codegenOptions.size(), const_cast<char **>(&_codegenOptions[0])); // mark which symbols can not be internalized this->applyScopeRestrictions(); // Instantiate the pass manager to organize the passes. PassManager passes; // Start off with a verification pass. passes.add(createVerifierPass()); // Add an appropriate TargetData instance for this module... passes.add(new TargetData(*_target->getTargetData())); // Enabling internalize here would use its AllButMain variant. It // keeps only main if it exists and does nothing for libraries. Instead // we create the pass ourselves with the symbol list provided by the linker. PassManagerBuilder().populateLTOPassManager(passes, /*Internalize=*/false, !DisableInline, DisableGVNLoadPRE); // Make sure everything is still good. passes.add(createVerifierPass()); FunctionPassManager *codeGenPasses = new FunctionPassManager(mergedModule); codeGenPasses->add(new TargetData(*_target->getTargetData())); formatted_raw_ostream Out(out); if (_target->addPassesToEmitFile(*codeGenPasses, Out, TargetMachine::CGFT_ObjectFile)) { errMsg = "target file type not supported"; return true; } bool UsingSAFECode = false; // Add the SAFECode optimization/finalization passes. // Note that we only run these passes (which require DSA) if we detect // that run-time checks have been added to the code. for (unsigned index = 0; index < numChecks; ++index) { if (mergedModule->getFunction(RuntimeChecks[index].name)) { UsingSAFECode = true; break; } } if (UsingSAFECode) { passes.add(new TargetData(*_target->getTargetData())); passes.add(createSAFECodeMSCInfoPass()); passes.add(createExactCheckOptPass()); passes.add(new ScalarEvolution()); passes.add(createLocalArrayBoundsAnalysisPass()); passes.add(createOptimizeFastMemoryChecksPass()); passes.add(createOptimizeIdenticalLSChecksPass()); passes.add(new DominatorTree()); passes.add(new ScalarEvolution()); passes.add(createOptimizeImpliedFastLSChecksPass()); if (mergedModule->getFunction("main")) { passes.add(new CompleteChecks()); } #ifdef POOLALLOC LowerSafecodeIntrinsic::IntrinsicMappingEntry *MapStart, *MapEnd; MapStart = RuntimeDebug; MapEnd = &RuntimeDebug[sizeof(RuntimeDebug) / sizeof(RuntimeDebug[0])]; // Add the automatic pool allocation passes passes.add(new OptimizeSafeLoadStore()); passes.add(new PA::AllNodesHeuristic()); //passes.add(new PoolAllocate()); passes.add(new PoolAllocateSimple()); // SAFECode's debug runtime needs to replace some of the poolalloc // intrinsics; LowerSafecodeIntrinsic handles the replacement. passes.add(new LowerSafecodeIntrinsic(MapStart, MapEnd)); #endif // Run our queue of passes all at once now, efficiently. passes.run(*mergedModule); #ifdef POOLALLOC if (const char *OutFileName = getenv("PA_BITCODE_FILE")) { // Write out the pool allocated bitcode file for debugging purposes. std::cerr << "Writing out poolalloc bitcode file to " << OutFileName; std::cerr << std::endl; std::string error; tool_output_file PAFile(OutFileName, error, raw_fd_ostream::F_Binary); if (!error.empty()) { std::cerr << "Error writing out poolalloc bitcode file: " << error; std::cerr << std::endl; } else { WriteBitcodeToFile(mergedModule, PAFile.os()); PAFile.os().close(); PAFile.keep(); } } #endif } // Run the code generator, and write assembly file codeGenPasses->doInitialization(); // Run our queue of passes all at once now, efficiently. passes.run(*mergedModule); // Run the code generator, and write assembly file codeGenPasses->doInitialization(); for (Module::iterator it = mergedModule->begin(), e = mergedModule->end(); it != e; ++it) if (!it->isDeclaration()) codeGenPasses->run(*it); codeGenPasses->doFinalization(); delete codeGenPasses; return false; // success }
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; }
/// Optimize merged modules using various IPO passes bool LTOCodeGenerator::generateAssemblyCode(std::ostream& out, std::string& errMsg) { if ( this->determineTarget(errMsg) ) return true; // mark which symbols can not be internalized this->applyScopeRestrictions(); Module* mergedModule = _linker.getModule(); // If target supports exception handling then enable it now. if ( _target->getTargetAsmInfo()->doesSupportExceptionHandling() ) llvm::ExceptionHandling = true; // set codegen model switch( _codeModel ) { case LTO_CODEGEN_PIC_MODEL_STATIC: _target->setRelocationModel(Reloc::Static); break; case LTO_CODEGEN_PIC_MODEL_DYNAMIC: _target->setRelocationModel(Reloc::PIC_); break; case LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC: _target->setRelocationModel(Reloc::DynamicNoPIC); break; } // Instantiate the pass manager to organize the passes. PassManager passes; // Start off with a verification pass. passes.add(createVerifierPass()); // Add an appropriate TargetData instance for this module... passes.add(new TargetData(*_target->getTargetData())); // Now that we internalized some globals, see if we can hack on them! passes.add(createGlobalOptimizerPass()); // Linking modules together can lead to duplicated global constants, only // keep one copy of each constant... passes.add(createConstantMergePass()); // If the -s command line option was specified, strip the symbols out of the // resulting program to make it smaller. -s is a GLD option that we are // supporting. passes.add(createStripSymbolsPass()); // Propagate constants at call sites into the functions they call. passes.add(createIPConstantPropagationPass()); // Remove unused arguments from functions... passes.add(createDeadArgEliminationPass()); passes.add(createFunctionInliningPass()); // Inline small functions passes.add(createPruneEHPass()); // Remove dead EH info passes.add(createGlobalDCEPass()); // Remove dead functions // If we didn't decide to inline a function, check to see if we can // transform it to pass arguments by value instead of by reference. passes.add(createArgumentPromotionPass()); // The IPO passes may leave cruft around. Clean up after them. passes.add(createInstructionCombiningPass()); passes.add(createJumpThreadingPass()); // Thread jumps. passes.add(createScalarReplAggregatesPass()); // Break up allocas // Run a few AA driven optimizations here and now, to cleanup the code. passes.add(createGlobalsModRefPass()); // IP alias analysis passes.add(createLICMPass()); // Hoist loop invariants passes.add(createGVNPass()); // Remove common subexprs passes.add(createMemCpyOptPass()); // Remove dead memcpy's passes.add(createDeadStoreEliminationPass()); // Nuke dead stores // Cleanup and simplify the code after the scalar optimizations. passes.add(createInstructionCombiningPass()); passes.add(createJumpThreadingPass()); // Thread jumps. // Delete basic blocks, which optimization passes may have killed... passes.add(createCFGSimplificationPass()); // Now that we have optimized the program, discard unreachable functions... passes.add(createGlobalDCEPass()); // Make sure everything is still good. passes.add(createVerifierPass()); FunctionPassManager* codeGenPasses = new FunctionPassManager(new ExistingModuleProvider(mergedModule)); codeGenPasses->add(new TargetData(*_target->getTargetData())); MachineCodeEmitter* mce = NULL; switch (_target->addPassesToEmitFile(*codeGenPasses, out, TargetMachine::AssemblyFile, true)) { case FileModel::MachOFile: mce = AddMachOWriter(*codeGenPasses, out, *_target); break; case FileModel::ElfFile: mce = AddELFWriter(*codeGenPasses, out, *_target); break; case FileModel::AsmFile: break; case FileModel::Error: case FileModel::None: errMsg = "target file type not supported"; return true; } if (_target->addPassesToEmitFileFinish(*codeGenPasses, mce, true)) { errMsg = "target does not support generation of this file type"; return true; } // Run our queue of passes all at once now, efficiently. passes.run(*mergedModule); // Run the code generator, and write assembly file codeGenPasses->doInitialization(); for (Module::iterator it = mergedModule->begin(), e = mergedModule->end(); it != e; ++it) { if (!it->isDeclaration()) codeGenPasses->run(*it); } codeGenPasses->doFinalization(); return false; // success }
/// Optimize merged modules using various IPO passes bool LTOCodeGenerator::generateAssemblyCode(formatted_raw_ostream& out, std::string& errMsg) { if ( this->determineTarget(errMsg) ) return true; // mark which symbols can not be internalized this->applyScopeRestrictions(); Module* mergedModule = _linker.getModule(); // If target supports exception handling then enable it now. switch (_target->getMCAsmInfo()->getExceptionHandlingType()) { case ExceptionHandling::Dwarf: llvm::DwarfExceptionHandling = true; break; case ExceptionHandling::SjLj: llvm::SjLjExceptionHandling = true; break; case ExceptionHandling::None: break; default: assert (0 && "Unknown exception handling model!"); } // if options were requested, set them if ( !_codegenOptions.empty() ) cl::ParseCommandLineOptions(_codegenOptions.size(), (char**)&_codegenOptions[0]); // Instantiate the pass manager to organize the passes. PassManager passes; // Start off with a verification pass. passes.add(createVerifierPass()); // Add an appropriate TargetData instance for this module... passes.add(new TargetData(*_target->getTargetData())); createStandardLTOPasses(&passes, /*Internalize=*/ false, !DisableInline, /*VerifyEach=*/ false); // Make sure everything is still good. passes.add(createVerifierPass()); FunctionPassManager* codeGenPasses = new FunctionPassManager(mergedModule); codeGenPasses->add(new TargetData(*_target->getTargetData())); if (_target->addPassesToEmitFile(*codeGenPasses, out, TargetMachine::CGFT_AssemblyFile, CodeGenOpt::Aggressive)) { errMsg = "target file type not supported"; return true; } // Run our queue of passes all at once now, efficiently. passes.run(*mergedModule); // Run the code generator, and write assembly file codeGenPasses->doInitialization(); for (Module::iterator it = mergedModule->begin(), e = mergedModule->end(); it != e; ++it) if (!it->isDeclaration()) codeGenPasses->run(*it); codeGenPasses->doFinalization(); return false; // success }
static void addOptimizationPasses(PassManagerBase &mpm, FunctionPassManager &fpm, #endif unsigned optLevel, unsigned sizeLevel) { fpm.add(createVerifierPass()); // Verify that input is correct PassManagerBuilder builder; builder.OptLevel = optLevel; builder.SizeLevel = sizeLevel; if (willInline()) { unsigned threshold = 225; if (sizeLevel == 1) // -Os threshold = 75; else if (sizeLevel == 2) // -Oz threshold = 25; if (optLevel > 2) threshold = 275; builder.Inliner = createFunctionInliningPass(threshold); } else { builder.Inliner = createAlwaysInlinerPass(); } #if LDC_LLVM_VER < 304 builder.DisableSimplifyLibCalls = disableSimplifyLibCalls; #endif builder.DisableUnitAtATime = !unitAtATime; builder.DisableUnrollLoops = optLevel == 0; #if LDC_LLVM_VER >= 304 builder.DisableUnrollLoops = (disableLoopUnrolling.getNumOccurrences() > 0) ? disableLoopUnrolling : optLevel == 0; // This is final, unless there is a #pragma vectorize enable if (disableLoopVectorization) builder.LoopVectorize = false; // If option wasn't forced via cmd line (-vectorize-loops, -loop-vectorize) else if (!builder.LoopVectorize) builder.LoopVectorize = optLevel > 1 && sizeLevel < 2; // When #pragma vectorize is on for SLP, do the same as above builder.SLPVectorize = disableSLPVectorization ? false : optLevel > 1 && sizeLevel < 2; #else /* builder.Vectorize is set in ctor from command line switch */ #endif #if LDC_LLVM_VER >= 303 if (opts::sanitize == opts::AddressSanitizer) { builder.addExtension(PassManagerBuilder::EP_OptimizerLast, addAddressSanitizerPasses); builder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addAddressSanitizerPasses); } if (opts::sanitize == opts::MemorySanitizer) { builder.addExtension(PassManagerBuilder::EP_OptimizerLast, addMemorySanitizerPass); builder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addMemorySanitizerPass); } if (opts::sanitize == opts::ThreadSanitizer) { builder.addExtension(PassManagerBuilder::EP_OptimizerLast, addThreadSanitizerPass); builder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addThreadSanitizerPass); } #endif if (!disableLangSpecificPasses) { if (!disableSimplifyDruntimeCalls) builder.addExtension(PassManagerBuilder::EP_LoopOptimizerEnd, addSimplifyDRuntimeCallsPass); if (!disableGCToStack) builder.addExtension(PassManagerBuilder::EP_LoopOptimizerEnd, addGarbageCollect2StackPass); } // EP_OptimizerLast does not exist in LLVM 3.0, add it manually below. builder.addExtension(PassManagerBuilder::EP_OptimizerLast, addStripExternalsPass); builder.populateFunctionPassManager(fpm); builder.populateModulePassManager(mpm); }
//===----------------------------------------------------------------------===// // main for opt // int main(int argc, char **argv) { llvm_shutdown_obj X; // Call llvm_shutdown() on exit. try { cl::ParseCommandLineOptions(argc, argv, "llvm .bc -> .bc modular optimizer and analysis printer\n"); sys::PrintStackTraceOnErrorSignal(); // Allocate a full target machine description only if necessary. // FIXME: The choice of target should be controllable on the command line. std::auto_ptr<TargetMachine> target; std::string ErrorMessage; // Load the input module... std::auto_ptr<Module> M; if (MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(InputFilename, &ErrorMessage)) { M.reset(ParseBitcodeFile(Buffer, &ErrorMessage)); delete Buffer; } if (M.get() == 0) { cerr << argv[0] << ": "; if (ErrorMessage.size()) cerr << ErrorMessage << "\n"; else cerr << "bitcode didn't read correctly.\n"; return 1; } // Figure out what stream we are supposed to write to... // FIXME: cout is not binary! std::ostream *Out = &std::cout; // Default to printing to stdout... if (OutputFilename != "-") { if (!Force && std::ifstream(OutputFilename.c_str())) { // If force is not specified, make sure not to overwrite a file! cerr << argv[0] << ": error opening '" << OutputFilename << "': file exists!\n" << "Use -f command line argument to force output\n"; return 1; } std::ios::openmode io_mode = std::ios::out | std::ios::trunc | std::ios::binary; Out = new std::ofstream(OutputFilename.c_str(), io_mode); if (!Out->good()) { cerr << argv[0] << ": error opening " << OutputFilename << "!\n"; return 1; } // Make sure that the Output file gets unlinked from the disk if we get a // SIGINT sys::RemoveFileOnSignal(sys::Path(OutputFilename)); } // If the output is set to be emitted to standard out, and standard out is a // console, print out a warning message and refuse to do it. We don't // impress anyone by spewing tons of binary goo to a terminal. if (!Force && !NoOutput && CheckBitcodeOutputToConsole(Out,!Quiet)) { NoOutput = true; } // Create a PassManager to hold and optimize the collection of passes we are // about to build... // PassManager Passes; // Add an appropriate TargetData instance for this module... Passes.add(new TargetData(M.get())); FunctionPassManager *FPasses = NULL; if (OptLevelO1 || OptLevelO2 || OptLevelO3) { FPasses = new FunctionPassManager(new ExistingModuleProvider(M.get())); FPasses->add(new TargetData(M.get())); } // If the -strip-debug command line option was specified, add it. If // -std-compile-opts was also specified, it will handle StripDebug. if (StripDebug && !StandardCompileOpts) addPass(Passes, createStripSymbolsPass(true)); // Create a new optimization pass for each one specified on the command line for (unsigned i = 0; i < PassList.size(); ++i) { // Check to see if -std-compile-opts was specified before this option. If // so, handle it. if (StandardCompileOpts && StandardCompileOpts.getPosition() < PassList.getPosition(i)) { AddStandardCompilePasses(Passes); StandardCompileOpts = false; } if (OptLevelO1 && OptLevelO1.getPosition() < PassList.getPosition(i)) { AddOptimizationPasses(Passes, *FPasses, 1); OptLevelO1 = false; } if (OptLevelO2 && OptLevelO2.getPosition() < PassList.getPosition(i)) { AddOptimizationPasses(Passes, *FPasses, 2); OptLevelO2 = false; } if (OptLevelO3 && OptLevelO3.getPosition() < PassList.getPosition(i)) { AddOptimizationPasses(Passes, *FPasses, 3); OptLevelO3 = false; } const PassInfo *PassInf = PassList[i]; Pass *P = 0; if (PassInf->getNormalCtor()) P = PassInf->getNormalCtor()(); else cerr << argv[0] << ": cannot create pass: "******"\n"; if (P) { bool isBBPass = dynamic_cast<BasicBlockPass*>(P) != 0; bool isLPass = !isBBPass && dynamic_cast<LoopPass*>(P) != 0; bool isFPass = !isLPass && dynamic_cast<FunctionPass*>(P) != 0; bool isCGSCCPass = !isFPass && dynamic_cast<CallGraphSCCPass*>(P) != 0; addPass(Passes, P); if (AnalyzeOnly) { if (isBBPass) Passes.add(new BasicBlockPassPrinter(PassInf)); else if (isLPass) Passes.add(new LoopPassPrinter(PassInf)); else if (isFPass) Passes.add(new FunctionPassPrinter(PassInf)); else if (isCGSCCPass) Passes.add(new CallGraphSCCPassPrinter(PassInf)); else Passes.add(new ModulePassPrinter(PassInf)); } } if (PrintEachXForm) Passes.add(createPrintModulePass(&errs())); } // If -std-compile-opts was specified at the end of the pass list, add them. if (StandardCompileOpts) { AddStandardCompilePasses(Passes); StandardCompileOpts = false; } if (OptLevelO1) { AddOptimizationPasses(Passes, *FPasses, 1); } if (OptLevelO2) { AddOptimizationPasses(Passes, *FPasses, 2); } if (OptLevelO3) { AddOptimizationPasses(Passes, *FPasses, 3); } if (OptLevelO1 || OptLevelO2 || OptLevelO3) { for (Module::iterator I = M.get()->begin(), E = M.get()->end(); I != E; ++I) FPasses->run(*I); } // Check that the module is well formed on completion of optimization if (!NoVerify && !VerifyEach) Passes.add(createVerifierPass()); // Write bitcode out to disk or cout as the last step... if (!NoOutput && !AnalyzeOnly) Passes.add(CreateBitcodeWriterPass(*Out)); // Now that we have all of the passes ready, run them. Passes.run(*M.get()); // Delete the ofstream. if (Out != &std::cout) delete Out; return 0; } catch (const std::string& msg) { cerr << argv[0] << ": " << msg << "\n"; } catch (...) { cerr << argv[0] << ": Unexpected unknown exception occurred.\n"; } llvm_shutdown(); return 1; }
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; }
void EmitAssemblyHelper::CreatePasses(TargetMachine *TM) { unsigned OptLevel = CodeGenOpts.OptimizationLevel; CodeGenOptions::InliningMethod Inlining = CodeGenOpts.getInlining(); // Handle disabling of LLVM optimization, where we want to preserve the // internal module before any optimization. if (CodeGenOpts.DisableLLVMOpts) { OptLevel = 0; Inlining = CodeGenOpts.NoInlining; } PassManagerBuilderWrapper PMBuilder(CodeGenOpts, LangOpts); PMBuilder.OptLevel = OptLevel; PMBuilder.SizeLevel = CodeGenOpts.OptimizeSize; PMBuilder.BBVectorize = CodeGenOpts.VectorizeBB; PMBuilder.SLPVectorize = CodeGenOpts.VectorizeSLP; PMBuilder.LoopVectorize = CodeGenOpts.VectorizeLoop; PMBuilder.DisableUnitAtATime = !CodeGenOpts.UnitAtATime; PMBuilder.DisableUnrollLoops = !CodeGenOpts.UnrollLoops; // In ObjC ARC mode, add the main ARC optimization passes. if (LangOpts.ObjCAutoRefCount) { PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible, addObjCARCExpandPass); PMBuilder.addExtension(PassManagerBuilder::EP_ModuleOptimizerEarly, addObjCARCAPElimPass); PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate, addObjCARCOptPass); } if (LangOpts.Sanitize.Bounds) { PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate, addBoundsCheckingPass); PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addBoundsCheckingPass); } if (LangOpts.Sanitize.Address) { PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, addAddressSanitizerPasses); PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addAddressSanitizerPasses); } if (LangOpts.Sanitize.Memory) { PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, addMemorySanitizerPass); PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addMemorySanitizerPass); } if (LangOpts.Sanitize.Thread) { PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, addThreadSanitizerPass); PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addThreadSanitizerPass); } // This should depend on duetto, non on byte addressable if (!TM->getDataLayout()->isByteAddressable()) PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible, addDuettoNativeRewriterPass); // Figure out TargetLibraryInfo. Triple TargetTriple(TheModule->getTargetTriple()); PMBuilder.LibraryInfo = new TargetLibraryInfo(TargetTriple); if (!CodeGenOpts.SimplifyLibCalls) PMBuilder.LibraryInfo->disableAllFunctions(); switch (Inlining) { case CodeGenOptions::NoInlining: break; case CodeGenOptions::NormalInlining: { // FIXME: Derive these constants in a principled fashion. unsigned Threshold = 225; if (CodeGenOpts.OptimizeSize == 1) // -Os Threshold = 75; else if (CodeGenOpts.OptimizeSize == 2) // -Oz Threshold = 25; else if (OptLevel > 2) Threshold = 275; PMBuilder.Inliner = createFunctionInliningPass(Threshold); break; } case CodeGenOptions::OnlyAlwaysInlining: // Respect always_inline. if (OptLevel == 0) // Do not insert lifetime intrinsics at -O0. PMBuilder.Inliner = createAlwaysInlinerPass(false); else PMBuilder.Inliner = createAlwaysInlinerPass(); break; } // Set up the per-function pass manager. FunctionPassManager *FPM = getPerFunctionPasses(TM); if (CodeGenOpts.VerifyModule) FPM->add(createVerifierPass()); PMBuilder.populateFunctionPassManager(*FPM); // Set up the per-module pass manager. PassManager *MPM = getPerModulePasses(TM); if (!CodeGenOpts.DisableGCov && (CodeGenOpts.EmitGcovArcs || CodeGenOpts.EmitGcovNotes)) { // Not using 'GCOVOptions::getDefault' allows us to avoid exiting if // LLVM's -default-gcov-version flag is set to something invalid. GCOVOptions Options; Options.EmitNotes = CodeGenOpts.EmitGcovNotes; Options.EmitData = CodeGenOpts.EmitGcovArcs; memcpy(Options.Version, CodeGenOpts.CoverageVersion, 4); Options.UseCfgChecksum = CodeGenOpts.CoverageExtraChecksum; Options.NoRedZone = CodeGenOpts.DisableRedZone; Options.FunctionNamesInData = !CodeGenOpts.CoverageNoFunctionNamesInData; MPM->add(createGCOVProfilerPass(Options)); if (CodeGenOpts.getDebugInfo() == CodeGenOptions::NoDebugInfo) MPM->add(createStripSymbolsPass(true)); } PMBuilder.populateModulePassManager(*MPM); }
void EmitAssemblyHelper::CreatePasses() { unsigned OptLevel = CodeGenOpts.OptimizationLevel; CodeGenOptions::InliningMethod Inlining = CodeGenOpts.Inlining; // Handle disabling of LLVM optimization, where we want to preserve the // internal module before any optimization. if (CodeGenOpts.DisableLLVMOpts) { OptLevel = 0; Inlining = CodeGenOpts.NoInlining; } PassManagerBuilder PMBuilder; PMBuilder.OptLevel = OptLevel; PMBuilder.SizeLevel = CodeGenOpts.OptimizeSize; PMBuilder.DisableSimplifyLibCalls = !CodeGenOpts.SimplifyLibCalls; PMBuilder.DisableUnitAtATime = !CodeGenOpts.UnitAtATime; PMBuilder.DisableUnrollLoops = !CodeGenOpts.UnrollLoops; // In ObjC ARC mode, add the main ARC optimization passes. if (LangOpts.ObjCAutoRefCount) { PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible, addObjCARCExpandPass); PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate, addObjCARCOptPass); } if (LangOpts.AddressSanitizer) { PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate, addAddressSanitizerPass); PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addAddressSanitizerPass); } // Figure out TargetLibraryInfo. Triple TargetTriple(TheModule->getTargetTriple()); PMBuilder.LibraryInfo = new TargetLibraryInfo(TargetTriple); if (!CodeGenOpts.SimplifyLibCalls) PMBuilder.LibraryInfo->disableAllFunctions(); switch (Inlining) { case CodeGenOptions::NoInlining: break; case CodeGenOptions::NormalInlining: { // FIXME: Derive these constants in a principled fashion. unsigned Threshold = 225; if (CodeGenOpts.OptimizeSize == 1) // -Os Threshold = 75; else if (CodeGenOpts.OptimizeSize == 2) // -Oz Threshold = 25; else if (OptLevel > 2) Threshold = 275; PMBuilder.Inliner = createFunctionInliningPass(Threshold); break; } case CodeGenOptions::OnlyAlwaysInlining: // Respect always_inline. PMBuilder.Inliner = createAlwaysInlinerPass(); break; } // Set up the per-function pass manager. FunctionPassManager *FPM = getPerFunctionPasses(); if (CodeGenOpts.VerifyModule) FPM->add(createVerifierPass()); PMBuilder.populateFunctionPassManager(*FPM); // Set up the per-module pass manager. PassManager *MPM = getPerModulePasses(); if (CodeGenOpts.EmitGcovArcs || CodeGenOpts.EmitGcovNotes) { MPM->add(createGCOVProfilerPass(CodeGenOpts.EmitGcovNotes, CodeGenOpts.EmitGcovArcs, TargetTriple.isMacOSX())); if (!CodeGenOpts.DebugInfo) MPM->add(createStripSymbolsPass(true)); } PMBuilder.populateModulePassManager(*MPM); }
void *MCJITHelper::getPointerToFunction(Function* F) { // See if an existing instance of MCJIT has this function. EngineVector::iterator begin = Engines.begin(); EngineVector::iterator end = Engines.end(); EngineVector::iterator it; for (it = begin; it != end; ++it) { void *P = (*it)->getPointerToFunction(F); if (P) return P; } // If we didn't find the function, see if we can generate it. if (OpenModule) { std::string ErrStr; ExecutionEngine *NewEngine = EngineBuilder(OpenModule) .setErrorStr(&ErrStr) .setMCJITMemoryManager(new HelpingMemoryManager(this)) .create(); if (!NewEngine) { fprintf(stderr, "Could not create ExecutionEngine: %s\n", ErrStr.c_str()); exit(1); } // Create a function pass manager for this engine FunctionPassManager *FPM = new FunctionPassManager(OpenModule); // Set up the optimizer pipeline. Start with registering info about how the // target lays out data structures. FPM->add(new DataLayout(*NewEngine->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 = OpenModule->end(); for (it = OpenModule->begin(); it != end; ++it) { // Run the FPM on this function FPM->run(*it); } // We don't need this anymore delete FPM; OpenModule = NULL; Engines.push_back(NewEngine); NewEngine->finalizeObject(); return NewEngine->getPointerToFunction(F); } return NULL; }
void BackendPass::CreatePasses(const clang::LangOptions& LangOpts, const clang::CodeGenOptions& CodeGenOpts) { // See clang/lib/CodeGen/BackendUtil.cpp EmitAssemblyHelper::CreatePasses() unsigned OptLevel = CodeGenOpts.OptimizationLevel; CodeGenOptions::InliningMethod Inlining = CodeGenOpts.getInlining(); // Handle disabling of LLVM optimization, where we want to preserve the // internal module before any optimization. if (CodeGenOpts.DisableLLVMOpts) { OptLevel = 0; Inlining = CodeGenOpts.NoInlining; } PassManagerBuilderWithOpts PMBuilder(LangOpts, CodeGenOpts); PMBuilder.OptLevel = OptLevel; PMBuilder.SizeLevel = CodeGenOpts.OptimizeSize; PMBuilder.BBVectorize = CodeGenOpts.VectorizeBB; PMBuilder.SLPVectorize = CodeGenOpts.VectorizeSLP; PMBuilder.LoopVectorize = CodeGenOpts.VectorizeLoop; PMBuilder.DisableUnitAtATime = !CodeGenOpts.UnitAtATime; PMBuilder.DisableUnrollLoops = !CodeGenOpts.UnrollLoops; PMBuilder.RerollLoops = CodeGenOpts.RerollLoops; #if 0 if (!CodeGenOpts.SampleProfileFile.empty()) PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible, addSampleProfileLoaderPass); #endif // In ObjC ARC mode, add the main ARC optimization passes. if (LangOpts.ObjCAutoRefCount) { PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible, addObjCARCExpandPass); PMBuilder.addExtension(PassManagerBuilder::EP_ModuleOptimizerEarly, addObjCARCAPElimPass); PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate, addObjCARCOptPass); } if (LangOpts.Sanitize.LocalBounds) { PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate, addBoundsCheckingPass); PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addBoundsCheckingPass); } if (LangOpts.Sanitize.Address) { PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, addAddressSanitizerPasses); PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addAddressSanitizerPasses); } if (LangOpts.Sanitize.Memory) { PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, addMemorySanitizerPass); PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addMemorySanitizerPass); } if (LangOpts.Sanitize.Thread) { PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, addThreadSanitizerPass); PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addThreadSanitizerPass); } if (LangOpts.Sanitize.DataFlow) { PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, addDataFlowSanitizerPass); PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addDataFlowSanitizerPass); } // Figure out TargetLibraryInfo. Triple TargetTriple(m_Module->getTargetTriple()); PMBuilder.LibraryInfo = new TargetLibraryInfo(TargetTriple); if (!CodeGenOpts.SimplifyLibCalls) PMBuilder.LibraryInfo->disableAllFunctions(); switch (Inlining) { case CodeGenOptions::NoInlining: break; case CodeGenOptions::NormalInlining: { // FIXME: Derive these constants in a principled fashion. unsigned Threshold = 225; if (CodeGenOpts.OptimizeSize == 1) // -Os Threshold = 75; else if (CodeGenOpts.OptimizeSize == 2) // -Oz Threshold = 25; else if (OptLevel > 2) Threshold = 275; // Creates a SimpleInliner that requests InsertLifetime. PMBuilder.Inliner = new InlinerKeepDeadFunc(createFunctionInliningPass(Threshold)); break; } case CodeGenOptions::OnlyAlwaysInlining: // Respect always_inline. if (OptLevel == 0) // Do not insert lifetime intrinsics at -O0. PMBuilder.Inliner = new InlinerKeepDeadFunc(createAlwaysInlinerPass(false)); else PMBuilder.Inliner = new InlinerKeepDeadFunc(createAlwaysInlinerPass()); break; } // Set up the per-function pass manager. FunctionPassManager *FPM = getPerFunctionPasses(); if (CodeGenOpts.VerifyModule) FPM->add(createVerifierPass()); PMBuilder.populateFunctionPassManager(*FPM); // The Inliner is a module pass; register it. PMBuilder.populateModulePassManager(*getPerModulePasses()); }
int main(int argc, char **argv){ cl::ParseCommandLineOptions(argc, argv, "llvm_trace_test\n"); char directory[250]; strncpy(directory, LogDir.c_str(), 250); int len = strlen(directory); if (len > 230){ printf("Directory name too long\n"); exit(1); } LLVMContext &Context = getGlobalContext(); // Load the bitcode... SMDiagnostic Err; Module *Mod = ParseIRFile(strncat(directory, "/llvm-mod.bc", 12), Err, Context); if (!Mod) { Err.print(argv[0], errs()); exit(1); } // Load dynamic log directory[len] = '\0'; dlog = fopen(strncat(directory, "/llvm-memlog.log", 16), "r"); if (!dlog){ printf("Could not find log of dynamic values in specified directory\n"); exit(1); } // Load function log directory[len] = '\0'; flog = fopen(strncat(directory, "/llvm-functions.log", 19), "r"); if (!flog){ printf("Could not find log of LLVM functions in specified directory\n"); exit(1); } // Initialize test function pass FunctionPassManager *FPasses = new FunctionPassManager(Mod); FunctionPass *fp = static_cast<FunctionPass*>(createTestFunctionPass()); FPasses->add(fp); FPasses->doInitialization(); char funcline[500]; Function *F; // Check trace while (true){ strncpy(funcline, "\0", 1); char *s = fgets(funcline, sizeof(funcline), flog); if (feof(flog)){ break; // Done processing trace } // System call information - ignore for test if (!strncmp(funcline, "taint", 5)){ continue; } funcline[strlen(funcline)-1] = '\0'; // remove newline F = Mod->getFunction(funcline); if (F == NULL){ fprintf(stderr, "Error: unknown function, %s\n", funcline); exit(1); } //printf("%s\n", F->getName().str().c_str()); FPasses->run(*F); // Call runOnFunction() } fclose(flog); fclose(dlog); printf("Trace and dynamic log are aligned.\n"); return 0; }
static void createOptimizationPasses() { // Create and set up the per-function pass manager. // FIXME: Move the code generator to be function-at-a-time. PerFunctionPasses = new FunctionPassManager(new ExistingModuleProvider(TheModule)); PerFunctionPasses->add(new TargetData(*TheTarget->getTargetData())); // In -O0 if checking is disabled, we don't even have per-function passes. bool HasPerFunctionPasses = false; #ifdef ENABLE_CHECKING PerFunctionPasses->add(createVerifierPass()); HasPerFunctionPasses = true; #endif if (optimize > 0 && !DisableLLVMOptimizations) { HasPerFunctionPasses = true; PerFunctionPasses->add(createCFGSimplificationPass()); if (optimize == 1) PerFunctionPasses->add(createPromoteMemoryToRegisterPass()); else PerFunctionPasses->add(createScalarReplAggregatesPass()); PerFunctionPasses->add(createInstructionCombiningPass()); // PerFunctionPasses->add(createCFGSimplificationPass()); } // FIXME: AT -O0/O1, we should stream out functions at a time. PerModulePasses = new PassManager(); PerModulePasses->add(new TargetData(*TheTarget->getTargetData())); bool HasPerModulePasses = false; if (optimize > 0 && !DisableLLVMOptimizations) { HasPerModulePasses = true; PassManager *PM = PerModulePasses; if (flag_unit_at_a_time) PM->add(createRaiseAllocationsPass()); // call %malloc -> malloc inst PM->add(createCFGSimplificationPass()); // Clean up disgusting code PM->add(createPromoteMemoryToRegisterPass()); // Kill useless allocas if (flag_unit_at_a_time) { PM->add(createGlobalOptimizerPass()); // Optimize out global vars PM->add(createGlobalDCEPass()); // Remove unused fns and globs PM->add(createIPConstantPropagationPass()); // IP Constant Propagation PM->add(createDeadArgEliminationPass()); // Dead argument elimination } PM->add(createInstructionCombiningPass()); // Clean up after IPCP & DAE // DISABLE PREDSIMPLIFY UNTIL PR967 is fixed. //PM->add(createPredicateSimplifierPass()); // Canonicalize registers PM->add(createCFGSimplificationPass()); // Clean up after IPCP & DAE if (flag_unit_at_a_time) PM->add(createPruneEHPass()); // Remove dead EH info if (optimize > 1) { if (flag_inline_trees > 1) // respect -fno-inline-functions PM->add(createFunctionInliningPass()); // Inline small functions if (flag_unit_at_a_time && !lang_hooks.flag_no_builtin()) PM->add(createSimplifyLibCallsPass()); // Library Call Optimizations if (optimize > 2) PM->add(createArgumentPromotionPass()); // Scalarize uninlined fn args } PM->add(createTailDuplicationPass()); // Simplify cfg by copying code PM->add(createInstructionCombiningPass()); // Cleanup for scalarrepl. PM->add(createCFGSimplificationPass()); // Merge & remove BBs PM->add(createScalarReplAggregatesPass()); // Break up aggregate allocas PM->add(createInstructionCombiningPass()); // Combine silly seq's PM->add(createCondPropagationPass()); // Propagate conditionals PM->add(createTailCallEliminationPass()); // Eliminate tail calls PM->add(createCFGSimplificationPass()); // Merge & remove BBs PM->add(createReassociatePass()); // Reassociate expressions PM->add(createLoopRotatePass()); // Rotate Loop PM->add(createLICMPass()); // Hoist loop invariants PM->add(createLoopUnswitchPass(optimize_size ? true : false)); PM->add(createInstructionCombiningPass()); // Clean up after LICM/reassoc PM->add(createIndVarSimplifyPass()); // Canonicalize indvars if (flag_unroll_loops) PM->add(createLoopUnrollPass()); // Unroll small loops PM->add(createInstructionCombiningPass()); // Clean up after the unroller PM->add(createLoadValueNumberingPass()); // GVN for load instructions PM->add(createGCSEPass()); // Remove common subexprs PM->add(createSCCPPass()); // Constant prop with SCCP // Run instcombine after redundancy elimination to exploit opportunities // opened up by them. PM->add(createInstructionCombiningPass()); PM->add(createCondPropagationPass()); // Propagate conditionals PM->add(createDeadStoreEliminationPass()); // Delete dead stores PM->add(createAggressiveDCEPass()); // SSA based 'Aggressive DCE' PM->add(createCFGSimplificationPass()); // Merge & remove BBs if (optimize > 1 && flag_unit_at_a_time) PM->add(createConstantMergePass()); // Merge dup global constants PM->add(createStripDeadPrototypesPass()); // Get rid of dead prototypes } if (emit_llvm_bc) { // Emit an LLVM .bc file to the output. This is used when passed // -emit-llvm -c to the GCC driver. PerModulePasses->add(CreateBitcodeWriterPass(*AsmOutStream)); // Disable emission of .ident into the output file... which is completely // wrong for llvm/.bc emission cases. flag_no_ident = 1; HasPerModulePasses = true; } else if (emit_llvm) { // Emit an LLVM .ll file to the output. This is used when passed // -emit-llvm -S to the GCC driver. PerModulePasses->add(new PrintModulePass(AsmOutFile)); // Disable emission of .ident into the output file... which is completely // wrong for llvm/.bc emission cases. flag_no_ident = 1; HasPerModulePasses = true; } else { FunctionPassManager *PM; // If there are passes we have to run on the entire module, we do codegen // as a separate "pass" after that happens. // FIXME: This is disabled right now until bugs can be worked out. Reenable // this for fast -O0 compiles! if (HasPerModulePasses || 1) { CodeGenPasses = PM = new FunctionPassManager(new ExistingModuleProvider(TheModule)); PM->add(new TargetData(*TheTarget->getTargetData())); } else { // If there are no module-level passes that have to be run, we codegen as // each function is parsed. PM = PerFunctionPasses; HasPerFunctionPasses = true; } // Normal mode, emit a .s file by running the code generator. switch (TheTarget->addPassesToEmitFile(*PM, *AsmOutStream, TargetMachine::AssemblyFile, /*FAST*/optimize == 0)) { default: case FileModel::Error: cerr << "Error interfacing to target machine!\n"; exit(1); case FileModel::AsmFile: break; } if (TheTarget->addPassesToEmitFileFinish(*PM, 0, /*Fast*/optimize == 0)) { cerr << "Error interfacing to target machine!\n"; exit(1); } } if (HasPerFunctionPasses) { PerFunctionPasses->doInitialization(); } else { delete PerFunctionPasses; PerFunctionPasses = 0; } if (!HasPerModulePasses) { delete PerModulePasses; PerModulePasses = 0; } }
/// Optimize merged modules using various IPO passes bool LTOCodeGenerator::generateObjectFile(raw_ostream &out, std::string &errMsg) { // if options were requested, set them if (!_codegenOptions.empty()) cl::ParseCommandLineOptions(_codegenOptions.size(), const_cast<char **>(&_codegenOptions[0])); if (this->determineTarget(errMsg)) return true; Module* mergedModule = _linker.getModule(); // mark which symbols can not be internalized this->applyScopeRestrictions(); // Instantiate the pass manager to organize the passes. PassManager passes; // Start off with a verification pass. passes.add(createVerifierPass()); // Add an appropriate DataLayout instance for this module... passes.add(new DataLayout(*_target->getDataLayout())); passes.add(new TargetTransformInfo(_target->getScalarTargetTransformInfo(), _target->getVectorTargetTransformInfo())); // Enabling internalize here would use its AllButMain variant. It // keeps only main if it exists and does nothing for libraries. Instead // we create the pass ourselves with the symbol list provided by the linker. PassManagerBuilder().populateLTOPassManager(passes, /*Internalize=*/false, !DisableInline, DisableGVNLoadPRE); // Make sure everything is still good. passes.add(createVerifierPass()); FunctionPassManager *codeGenPasses = new FunctionPassManager(mergedModule); codeGenPasses->add(new DataLayout(*_target->getDataLayout())); formatted_raw_ostream Out(out); if (_target->addPassesToEmitFile(*codeGenPasses, Out, TargetMachine::CGFT_ObjectFile)) { errMsg = "target file type not supported"; return true; } // Run our queue of passes all at once now, efficiently. passes.run(*mergedModule); // Run the code generator, and write assembly file codeGenPasses->doInitialization(); for (Module::iterator it = mergedModule->begin(), e = mergedModule->end(); it != e; ++it) if (!it->isDeclaration()) codeGenPasses->run(*it); codeGenPasses->doFinalization(); delete codeGenPasses; return false; // success }
void EmitAssemblyHelper::CreatePasses() { unsigned OptLevel = CodeGenOpts.OptimizationLevel; CodeGenOptions::InliningMethod Inlining = CodeGenOpts.getInlining(); // Handle disabling of LLVM optimization, where we want to preserve the // internal module before any optimization. if (CodeGenOpts.DisableLLVMOpts) { OptLevel = 0; Inlining = CodeGenOpts.NoInlining; } PassManagerBuilderWrapper PMBuilder(CodeGenOpts, LangOpts); PMBuilder.OptLevel = OptLevel; PMBuilder.SizeLevel = CodeGenOpts.OptimizeSize; PMBuilder.BBVectorize = CodeGenOpts.VectorizeBB; PMBuilder.SLPVectorize = CodeGenOpts.VectorizeSLP; PMBuilder.LoopVectorize = CodeGenOpts.VectorizeLoop; PMBuilder.DisableTailCalls = CodeGenOpts.DisableTailCalls; PMBuilder.DisableUnitAtATime = !CodeGenOpts.UnitAtATime; PMBuilder.DisableUnrollLoops = !CodeGenOpts.UnrollLoops; PMBuilder.MergeFunctions = CodeGenOpts.MergeFunctions; PMBuilder.RerollLoops = CodeGenOpts.RerollLoops; PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible, addAddDiscriminatorsPass); if (!CodeGenOpts.SampleProfileFile.empty()) PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible, addSampleProfileLoaderPass); // In ObjC ARC mode, add the main ARC optimization passes. if (LangOpts.ObjCAutoRefCount) { PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible, addObjCARCExpandPass); PMBuilder.addExtension(PassManagerBuilder::EP_ModuleOptimizerEarly, addObjCARCAPElimPass); PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate, addObjCARCOptPass); } if (!CodeGenOpts.FsSemanticConfFile.empty()) PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible, addFsSemanticPass); if (LangOpts.Sanitize.has(SanitizerKind::LocalBounds)) { PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate, addBoundsCheckingPass); PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addBoundsCheckingPass); } if (CodeGenOpts.SanitizeCoverage) { PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, addSanitizerCoveragePass); PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addSanitizerCoveragePass); } if (LangOpts.Sanitize.has(SanitizerKind::Address)) { PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, addAddressSanitizerPasses); PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addAddressSanitizerPasses); } if (LangOpts.Sanitize.has(SanitizerKind::Memory)) { PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, addMemorySanitizerPass); PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addMemorySanitizerPass); } if (LangOpts.Sanitize.has(SanitizerKind::Thread)) { PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, addThreadSanitizerPass); PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addThreadSanitizerPass); } if (LangOpts.Sanitize.has(SanitizerKind::DataFlow)) { PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, addDataFlowSanitizerPass); PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addDataFlowSanitizerPass); } // Figure out TargetLibraryInfo. Triple TargetTriple(TheModule->getTargetTriple()); PMBuilder.LibraryInfo = createTLI(TargetTriple, CodeGenOpts); switch (Inlining) { case CodeGenOptions::NoInlining: break; case CodeGenOptions::NormalInlining: { PMBuilder.Inliner = createFunctionInliningPass(OptLevel, CodeGenOpts.OptimizeSize); break; } case CodeGenOptions::OnlyAlwaysInlining: // Respect always_inline. if (OptLevel == 0) // Do not insert lifetime intrinsics at -O0. PMBuilder.Inliner = createAlwaysInlinerPass(false); else PMBuilder.Inliner = createAlwaysInlinerPass(); break; } // Set up the per-function pass manager. FunctionPassManager *FPM = getPerFunctionPasses(); if (CodeGenOpts.VerifyModule) FPM->add(createVerifierPass()); PMBuilder.populateFunctionPassManager(*FPM); // Set up the per-module pass manager. PassManager *MPM = getPerModulePasses(); if (CodeGenOpts.VerifyModule) MPM->add(createDebugInfoVerifierPass()); if (!CodeGenOpts.DisableGCov && (CodeGenOpts.EmitGcovArcs || CodeGenOpts.EmitGcovNotes)) { // Not using 'GCOVOptions::getDefault' allows us to avoid exiting if // LLVM's -default-gcov-version flag is set to something invalid. GCOVOptions Options; Options.EmitNotes = CodeGenOpts.EmitGcovNotes; Options.EmitData = CodeGenOpts.EmitGcovArcs; memcpy(Options.Version, CodeGenOpts.CoverageVersion, 4); Options.UseCfgChecksum = CodeGenOpts.CoverageExtraChecksum; Options.NoRedZone = CodeGenOpts.DisableRedZone; Options.FunctionNamesInData = !CodeGenOpts.CoverageNoFunctionNamesInData; MPM->add(createGCOVProfilerPass(Options)); if (CodeGenOpts.getDebugInfo() == CodeGenOptions::NoDebugInfo) MPM->add(createStripSymbolsPass(true)); } PMBuilder.populateModulePassManager(*MPM); }
/// Optimize module M using various IPO passes. Use exportList to /// internalize selected symbols. Target platform is selected /// based on information available to module M. No new target /// features are selected. enum LTOStatus LTO::optimize(Module *M, std::ostream &Out, std::vector<const char *> &exportList) { // Instantiate the pass manager to organize the passes. PassManager Passes; // Collect Target info getTarget(M); if (!Target) return LTO_NO_TARGET; // If target supports exception handling then enable it now. if (Target->getTargetAsmInfo()->doesSupportExceptionHandling()) ExceptionHandling = true; // Start off with a verification pass. Passes.add(createVerifierPass()); // Add an appropriate TargetData instance for this module... Passes.add(new TargetData(*Target->getTargetData())); // Internalize symbols if export list is nonemty if (!exportList.empty()) Passes.add(createInternalizePass(exportList)); // Now that we internalized some globals, see if we can hack on them! Passes.add(createGlobalOptimizerPass()); // Linking modules together can lead to duplicated global constants, only // keep one copy of each constant... Passes.add(createConstantMergePass()); // If the -s command line option was specified, strip the symbols out of the // resulting program to make it smaller. -s is a GLD option that we are // supporting. Passes.add(createStripSymbolsPass()); // Propagate constants at call sites into the functions they call. Passes.add(createIPConstantPropagationPass()); // Remove unused arguments from functions... Passes.add(createDeadArgEliminationPass()); Passes.add(createFunctionInliningPass()); // Inline small functions Passes.add(createPruneEHPass()); // Remove dead EH info Passes.add(createGlobalDCEPass()); // Remove dead functions // If we didn't decide to inline a function, check to see if we can // transform it to pass arguments by value instead of by reference. Passes.add(createArgumentPromotionPass()); // The IPO passes may leave cruft around. Clean up after them. Passes.add(createInstructionCombiningPass()); Passes.add(createScalarReplAggregatesPass()); // Break up allocas // Run a few AA driven optimizations here and now, to cleanup the code. Passes.add(createGlobalsModRefPass()); // IP alias analysis Passes.add(createLICMPass()); // Hoist loop invariants Passes.add(createGVNPass()); // Remove common subexprs Passed.add(createMemCpyOptPass()); // Remove dead memcpy's Passes.add(createDeadStoreEliminationPass()); // Nuke dead stores // Cleanup and simplify the code after the scalar optimizations. Passes.add(createInstructionCombiningPass()); // Delete basic blocks, which optimization passes may have killed... Passes.add(createCFGSimplificationPass()); // Now that we have optimized the program, discard unreachable functions... Passes.add(createGlobalDCEPass()); // Make sure everything is still good. Passes.add(createVerifierPass()); FunctionPassManager *CodeGenPasses = new FunctionPassManager(new ExistingModuleProvider(M)); CodeGenPasses->add(new TargetData(*Target->getTargetData())); MachineCodeEmitter *MCE = 0; switch (Target->addPassesToEmitFile(*CodeGenPasses, Out, TargetMachine::AssemblyFile, true)) { default: case FileModel::Error: return LTO_WRITE_FAILURE; case FileModel::AsmFile: break; case FileModel::MachOFile: MCE = AddMachOWriter(*CodeGenPasses, Out, *Target); break; case FileModel::ElfFile: MCE = AddELFWriter(*CodeGenPasses, Out, *Target); break; } if (Target->addPassesToEmitFileFinish(*CodeGenPasses, MCE, true)) return LTO_WRITE_FAILURE; // Run our queue of passes all at once now, efficiently. Passes.run(*M); // Run the code generator, if present. CodeGenPasses->doInitialization(); for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) { if (!I->isDeclaration()) CodeGenPasses->run(*I); } CodeGenPasses->doFinalization(); return LTO_OPT_SUCCESS; }
//===----------------------------------------------------------------------===// // main for opt // int main(int argc, char **argv) { sys::PrintStackTraceOnErrorSignal(); llvm::PrettyStackTraceProgram X(argc, argv); // Enable debug stream buffering. EnableDebugBuffering = true; llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. LLVMContext &Context = getGlobalContext(); cl::ParseCommandLineOptions(argc, argv, "llvm .bc -> .bc modular optimizer and analysis printer\n"); // Allocate a full target machine description only if necessary. // FIXME: The choice of target should be controllable on the command line. std::auto_ptr<TargetMachine> target; SMDiagnostic Err; // Load the input module... std::auto_ptr<Module> M; M.reset(ParseIRFile(InputFilename, Err, Context)); if (M.get() == 0) { Err.Print(argv[0], errs()); return 1; } // Figure out what stream we are supposed to write to... // FIXME: outs() is not binary! raw_ostream *Out = &outs(); // Default to printing to stdout... if (OutputFilename != "-") { if (NoOutput || AnalyzeOnly) { errs() << "WARNING: The -o (output filename) option is ignored when\n" "the --disable-output or --analyze options are used.\n"; } else { // Make sure that the Output file gets unlinked from the disk if we get a // SIGINT sys::RemoveFileOnSignal(sys::Path(OutputFilename)); std::string ErrorInfo; Out = new raw_fd_ostream(OutputFilename.c_str(), ErrorInfo, raw_fd_ostream::F_Binary); if (!ErrorInfo.empty()) { errs() << ErrorInfo << '\n'; delete Out; return 1; } } } // If the output is set to be emitted to standard out, and standard out is a // console, print out a warning message and refuse to do it. We don't // impress anyone by spewing tons of binary goo to a terminal. if (!Force && !NoOutput && !AnalyzeOnly && !OutputAssembly) if (CheckBitcodeOutputToConsole(*Out, !Quiet)) NoOutput = true; // Create a PassManager to hold and optimize the collection of passes we are // about to build... // PassManager Passes; // Add an appropriate TargetData instance for this module... TargetData *TD = 0; const std::string &ModuleDataLayout = M.get()->getDataLayout(); if (!ModuleDataLayout.empty()) TD = new TargetData(ModuleDataLayout); else if (!DefaultDataLayout.empty()) TD = new TargetData(DefaultDataLayout); if (TD) Passes.add(TD); FunctionPassManager *FPasses = NULL; if (OptLevelO1 || OptLevelO2 || OptLevelO3) { FPasses = new FunctionPassManager(M.get()); if (TD) FPasses->add(new TargetData(*TD)); } // If the -strip-debug command line option was specified, add it. If // -std-compile-opts was also specified, it will handle StripDebug. if (StripDebug && !StandardCompileOpts) addPass(Passes, createStripSymbolsPass(true)); // Create a new optimization pass for each one specified on the command line for (unsigned i = 0; i < PassList.size(); ++i) { // Check to see if -std-compile-opts was specified before this option. If // so, handle it. if (StandardCompileOpts && StandardCompileOpts.getPosition() < PassList.getPosition(i)) { AddStandardCompilePasses(Passes); StandardCompileOpts = false; } if (StandardLinkOpts && StandardLinkOpts.getPosition() < PassList.getPosition(i)) { AddStandardLinkPasses(Passes); StandardLinkOpts = false; } if (OptLevelO1 && OptLevelO1.getPosition() < PassList.getPosition(i)) { AddOptimizationPasses(Passes, *FPasses, 1); OptLevelO1 = false; } if (OptLevelO2 && OptLevelO2.getPosition() < PassList.getPosition(i)) { AddOptimizationPasses(Passes, *FPasses, 2); OptLevelO2 = false; } if (OptLevelO3 && OptLevelO3.getPosition() < PassList.getPosition(i)) { AddOptimizationPasses(Passes, *FPasses, 3); OptLevelO3 = false; } const PassInfo *PassInf = PassList[i]; Pass *P = 0; if (PassInf->getNormalCtor()) P = PassInf->getNormalCtor()(); else errs() << argv[0] << ": cannot create pass: "******"\n"; if (P) { PassKind Kind = P->getPassKind(); addPass(Passes, P); if (AnalyzeOnly) { switch (Kind) { case PT_BasicBlock: Passes.add(new BasicBlockPassPrinter(PassInf)); break; case PT_Loop: Passes.add(new LoopPassPrinter(PassInf)); break; case PT_Function: Passes.add(new FunctionPassPrinter(PassInf)); break; case PT_CallGraphSCC: Passes.add(new CallGraphSCCPassPrinter(PassInf)); break; default: Passes.add(new ModulePassPrinter(PassInf)); break; } } } if (PrintEachXForm) Passes.add(createPrintModulePass(&errs())); } // If -std-compile-opts was specified at the end of the pass list, add them. if (StandardCompileOpts) { AddStandardCompilePasses(Passes); StandardCompileOpts = false; } if (StandardLinkOpts) { AddStandardLinkPasses(Passes); StandardLinkOpts = false; } if (OptLevelO1) AddOptimizationPasses(Passes, *FPasses, 1); if (OptLevelO2) AddOptimizationPasses(Passes, *FPasses, 2); if (OptLevelO3) AddOptimizationPasses(Passes, *FPasses, 3); if (OptLevelO1 || OptLevelO2 || OptLevelO3) { FPasses->doInitialization(); for (Module::iterator I = M.get()->begin(), E = M.get()->end(); I != E; ++I) FPasses->run(*I); } // Check that the module is well formed on completion of optimization if (!NoVerify && !VerifyEach) Passes.add(createVerifierPass()); // Write bitcode or assembly out to disk or outs() as the last step... if (!NoOutput && !AnalyzeOnly) { if (OutputAssembly) Passes.add(createPrintModulePass(Out)); else Passes.add(createBitcodeWriterPass(*Out)); } // Now that we have all of the passes ready, run them. Passes.run(*M.get()); // Delete the raw_fd_ostream. if (Out != &outs()) delete Out; return 0; }
void EmitAssemblyHelper::CreatePasses() { unsigned OptLevel = CodeGenOpts.OptimizationLevel; CodeGenOptions::InliningMethod Inlining = CodeGenOpts.Inlining; // Handle disabling of LLVM optimization, where we want to preserve the // internal module before any optimization. if (CodeGenOpts.DisableLLVMOpts) { OptLevel = 0; Inlining = CodeGenOpts.NoInlining; } PassManagerBuilder PMBuilder; PMBuilder.OptLevel = OptLevel; PMBuilder.SizeLevel = CodeGenOpts.OptimizeSize; PMBuilder.DisableSimplifyLibCalls = !CodeGenOpts.SimplifyLibCalls; PMBuilder.DisableUnitAtATime = !CodeGenOpts.UnitAtATime; PMBuilder.DisableUnrollLoops = !CodeGenOpts.UnrollLoops; // In ObjC ARC mode, add the main ARC optimization passes. if (LangOpts.ObjCAutoRefCount) { PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible, addObjCARCExpandPass); PMBuilder.addExtension(PassManagerBuilder::EP_ModuleOptimizerEarly, addObjCARCAPElimPass); PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate, addObjCARCOptPass); } if (CodeGenOpts.BoundsChecking > 0) { BoundsChecking = CodeGenOpts.BoundsChecking; PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate, addBoundsCheckingPass); PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addBoundsCheckingPass); } if (LangOpts.AddressSanitizer) { PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate, addAddressSanitizerPass); PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addAddressSanitizerPass); } if (LangOpts.ThreadSanitizer) { PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, addThreadSanitizerPass); PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, addThreadSanitizerPass); } // Figure out TargetLibraryInfo. Triple TargetTriple(TheModule->getTargetTriple()); PMBuilder.LibraryInfo = new TargetLibraryInfo(TargetTriple); if (!CodeGenOpts.SimplifyLibCalls) PMBuilder.LibraryInfo->disableAllFunctions(); switch (Inlining) { case CodeGenOptions::NoInlining: break; case CodeGenOptions::NormalInlining: { // FIXME: Derive these constants in a principled fashion. unsigned Threshold = 225; if (CodeGenOpts.OptimizeSize == 1) // -Os Threshold = 75; else if (CodeGenOpts.OptimizeSize == 2) // -Oz Threshold = 25; else if (OptLevel > 2) Threshold = 275; PMBuilder.Inliner = createFunctionInliningPass(Threshold); break; } case CodeGenOptions::OnlyAlwaysInlining: // Respect always_inline. if (OptLevel == 0) // Do not insert lifetime intrinsics at -O0. PMBuilder.Inliner = createAlwaysInlinerPass(false); else PMBuilder.Inliner = createAlwaysInlinerPass(); break; } // Set up the per-function pass manager. FunctionPassManager *FPM = getPerFunctionPasses(); if (CodeGenOpts.VerifyModule) FPM->add(createVerifierPass()); PMBuilder.populateFunctionPassManager(*FPM); // Set up the per-module pass manager. PassManager *MPM = getPerModulePasses(); if (CodeGenOpts.EmitGcovArcs || CodeGenOpts.EmitGcovNotes) { MPM->add(createGCOVProfilerPass(CodeGenOpts.EmitGcovNotes, CodeGenOpts.EmitGcovArcs, TargetTriple.isMacOSX())); if (CodeGenOpts.DebugInfo == CodeGenOptions::NoDebugInfo) MPM->add(createStripSymbolsPass(true)); } // Add the memory safety passes for control-flow integrity if (CodeGenOpts.MemSafety) { // Make sure everything that can be in an LLVM register is. MPM->add (createPromoteMemoryToRegisterPass()); MPM->add (createUnifyFunctionExitNodesPass()); MPM->add (new CFIChecks()); } PMBuilder.populateModulePassManager(*MPM); if (CodeGenOpts.SoftBound) { // Make sure SoftBound+CETS is run after optimization with atleast mem2reg run MPM->add(new DominatorTree()); MPM->add(new DominanceFrontier()); MPM->add(new LoopInfo()); MPM->add(new InitializeSoftBound()); MPM->add(new SoftBoundCETSPass()); } // Add the memory safety passes if (CodeGenOpts.MemSafety) { MPM->add (createCommonMSCInfoPass()); MPM->add (createSAFECodeMSCInfoPass()); // C standard library / format string function transforms if (!CodeGenOpts.BaggyBounds) { MPM->add (new StringTransform()); MPM->add (new FormatStringTransform()); MPM->add (new RegisterVarargCallSites()); MPM->add (new LoggingFunctions()); } MPM->add (new InitAllocas()); MPM->add (createRegisterGlobalsPass(/*RegUncertain=*/true, /*MakeInternal=*/false)); MPM->add (createRemoveUnsuitableGlobalRegistrationsPass()); MPM->add (new RegisterMainArgs()); MPM->add (createInstrumentFreeCallsPass()); MPM->add (new RegisterCustomizedAllocation()); MPM->add (new LoopInfo ()); MPM->add (new DominatorTree ()); MPM->add (createRegisterStackPoolsPass(/*RegByval=*/true)); MPM->add (createUnregisterStackPoolsPass()); MPM->add (createSpecializeCMSCallsPass()); MPM->add (new RegisterRuntimeInitializer(CodeGenOpts.MemSafetyLogFile.c_str())); MPM->add (new DebugInstrument()); MPM->add (createInstrumentMemoryAccessesPass()); MPM->add (createInstrumentGEPsPass()); MPM->add (createSpecializeCMSCallsPass()); MPM->add (new ScalarEvolution()); MPM->add (new ArrayBoundsCheckLocal()); MPM->add (createOptimizeGEPChecksPass()); MPM->add (createExactCheckOptPass()); MPM->add (new ScalarEvolution()); MPM->add (createLocalArrayBoundsAnalysisPass()); MPM->add (createOptimizeFastMemoryChecksPass()); MPM->add (createOptimizeIdenticalLSChecksPass()); MPM->add (new DominatorTree()); MPM->add (new ScalarEvolution()); MPM->add (createOptimizeImpliedFastLSChecksPass()); MPM->add (new OptimizeChecks()); MPM->add (createOptimizeMemoryRegistrationsPass(/*AllowFastChecks=*/true)); if (CodeGenOpts.MemSafeTerminate) { MPM->add (llvm::createSCTerminatePass ()); } } if (CodeGenOpts.BaggyBounds) { MPM->add (new InsertBaggyBoundsChecks()); } // // Rerun the LLVM optimizations again. // PMBuilder.populateModulePassManager(*MPM); // For SAFECode, do the debug instrumentation and OOB rewriting after // all optimization is done. if (CodeGenOpts.MemSafety) { MPM->add (new DebugInstrument()); MPM->add (new RewriteOOB()); } }