/// Optimize merged modules using various IPO passes bool LTOCodeGenerator::generateAssemblyCode(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 options were requested, set them if ( !_codegenOptions.empty() ) cl::ParseCommandLineOptions(_codegenOptions.size(), const_cast<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())); formatted_raw_ostream Out(out); 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 }
// Unfortunately, the LLVM C API doesn't provide an easy way of iterating over // all the functions in a module, so we do that manually here. You'll find // similar code in clang's BackendUtil.cpp file. extern "C" void LLVMRustRunFunctionPassManager(LLVMPassManagerRef PM, LLVMModuleRef M) { FunctionPassManager *P = unwrap<FunctionPassManager>(PM); P->doInitialization(); for (Module::iterator I = unwrap(M)->begin(), E = unwrap(M)->end(); I != E; ++I) if (!I->isDeclaration()) P->run(*I); P->doFinalization(); }
bool JITOptimizations::runOnFunction(Function& F) { this->LI = &getAnalysis<LoopInfo>(); bool changed = false; FPM = new FunctionPassManager(F.getParent()); // if the user input something we use those passes std::vector<const PassInfo *> &customPasses = JPD->getPassList(); if (customPasses.size() > 0) { for (int i=0; i<customPasses.size();i++) { const PassInfo *pass = customPasses[i]; FPM->add(pass->createPass()); } } else { // Optimization ordering: // - ADCE // - inline // - DSE <---- THIS causes seg faults when running on sqlite3 // test in llvm test-suite // - Instruction Combining // ---- IF LOOPS ---- // - LICM // - Loop Simplify // - Loop Strength Reduction // ------------------ // - SCCP // - Simplify CFG // - SROA FPM->add(createAggressiveDCEPass()); if (JPD->getThresholdT2() != 0) FPM->add(createDynamicInlinerPass(JPD)); FPM->add(createInstructionCombiningPass()); // --- Loop optimizations --- // if (LI->begin() != LI->end()) { FPM->add(createLICMPass()); FPM->add(createLoopSimplifyPass()); FPM->add(createLoopStrengthReducePass()); } // -------------------------- // FPM->add(createSCCPPass()); FPM->add(createCFGSimplificationPass()); FPM->add(createSROAPass(false)); } changed = changed | FPM->doInitialization(); changed = changed | FPM->run(F); changed = changed | FPM->doFinalization(); delete FPM; return changed; }
Function &OptimizeForRuntime(Function &F) { #ifdef DEBUG static PassManagerBuilder Builder = getDebugBuilder(); #else static PassManagerBuilder Builder = getBuilder(); #endif Module *M = F.getParent(); opt::GenerateOutput = true; polly::opt::PollyParallel = true; FunctionPassManager PM = FunctionPassManager(M); Builder.populateFunctionPassManager(PM); PM.doInitialization(); PM.run(F); PM.doFinalization(); if (opt::havePapi()) { PassManager MPM; Builder.populateModulePassManager(MPM); MPM.add(polli::createTraceMarkerPass()); MPM.run(*M); } if (opt::haveLikwid()) { PassManager MPM; Builder.populateModulePassManager(MPM); MPM.add(polli::createLikwidMarkerPass()); MPM.run(*M); } DEBUG( StoreModule(*M, M->getModuleIdentifier() + ".after.polly.ll") ); opt::GenerateOutput = false; return F; }
/// 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 }
/// 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 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; }
/// 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 }
/// 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->getTargetAsmInfo()->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(new ExistingModuleProvider(mergedModule)); codeGenPasses->add(new TargetData(*_target->getTargetData())); ObjectCodeEmitter* oce = NULL; switch (_target->addPassesToEmitFile(*codeGenPasses, out, TargetMachine::AssemblyFile, CodeGenOpt::Aggressive)) { case FileModel::MachOFile: oce = AddMachOWriter(*codeGenPasses, out, *_target); break; case FileModel::ElfFile: oce = 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, oce, CodeGenOpt::Aggressive)) { 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(); out.flush(); return false; // success }