//===-- llvm/Support/StandardPasses.h - Standard pass lists -----*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file defines utility functions for creating a "standard" set of // optimization passes, so that compilers and tools which use optimization // passes use the same set of standard passes. // // These are implemented as inline functions so that we do not have to worry // about link issues. // //===----------------------------------------------------------------------===// #ifndef LLVM_SUPPORT_STANDARDPASSES_H #define LLVM_SUPPORT_STANDARDPASSES_H #include "llvm/PassManager.h" #include "llvm/DefaultPasses.h" #include "llvm/Analysis/Passes.h" #include "llvm/Analysis/Verifier.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/IPO.h" namespace llvm { //template static Pass *CreatePassFn(void) { return X(); } /// RegisterStandardPassLists solves a circular dependency problem. The /// default list of passes has to live somewhere. It can't live in the core /// modules, because these don't link to the libraries that actually define /// the passes. It's in this header, so that a copy is created in every /// library that requests the default set, while still allowing plugins to /// register new passes without requiring them to link anything more than /// VMCore. class RegisterStandardPassLists { public: RegisterStandardPassLists() { StandardPass::RegisterDefaultPasses = RegisterStandardPassList; StandardPass::CreateVerifierPass = CreateVerifierPass; } private: /// Define a set of function overloads that does the casting for us, so /// that we can perform safe function pointer casts, but catch unsafe ones. PassInfo::NormalCtor_t static CreatePassFn(llvm::ImmutablePass*(*X)(void)) { return reinterpret_cast(X); } PassInfo::NormalCtor_t static CreatePassFn(llvm::ModulePass*(*X)(void)) { return reinterpret_cast(X); } PassInfo::NormalCtor_t static CreatePassFn(llvm::FunctionPass*(*X)(void)) { return reinterpret_cast(X); } PassInfo::NormalCtor_t static CreatePassFn(llvm::Pass*(*X)(void)) { return reinterpret_cast(X); } static llvm::Pass *CreateVerifierPass() { return createVerifierPass(); } /// Passes must be registered with functions that take no arguments, so we have /// to wrap their existing constructors. static Pass *createScalarReplAggregatesPass(void) { return llvm::createScalarReplAggregatesPass(); } static Pass *createSSAScalarReplAggregatesPass(void) { return llvm::createScalarReplAggregatesPass(-1, false); } static Pass *createDefaultLoopUnswitchPass(void) { return createLoopUnswitchPass(false); } static Pass *createSizeOptimizingLoopUnswitchPass(void) { return createLoopUnswitchPass(true); } static Pass *createArgumentPromotionPass(void) { return llvm::createArgumentPromotionPass(); } static Pass *createLoopUnrollPass(void) { return llvm::createLoopUnrollPass(); } static Pass *createGVNPass(void) { return llvm::createGVNPass(); } static void RegisterStandardPassList(void) { // Standard alias analysis passes // Add TypeBasedAliasAnalysis before BasicAliasAnalysis so that // BasicAliasAnalysis wins if they disagree. This is intended to help // support "obvious" type-punning idioms. #define DEFAULT_ALIAS_ANALYSIS_PASS(pass, flags)\ StandardPass::RegisterDefaultPass(\ CreatePassFn(create ## pass ## Pass),\ &DefaultStandardPasses::pass ## ID, (unsigned char*)0, StandardPass::AliasAnalysis, flags) DEFAULT_ALIAS_ANALYSIS_PASS(TypeBasedAliasAnalysis, 0); DEFAULT_ALIAS_ANALYSIS_PASS(BasicAliasAnalysis, 0); #undef DEFAULT_ALIAS_ANALYSIS_PASS #define DEFAULT_FUNCTION_PASS(pass, flags)\ StandardPass::RegisterDefaultPass(\ CreatePassFn(create ## pass ## Pass),\ &DefaultStandardPasses::pass ## ID, 0, StandardPass::Function, flags) DEFAULT_FUNCTION_PASS(CFGSimplification, StandardPass::OptimzationFlags(1)); DEFAULT_FUNCTION_PASS(ScalarReplAggregates, StandardPass::OptimzationFlags(1)); DEFAULT_FUNCTION_PASS(EarlyCSE, StandardPass::OptimzationFlags(1)); #undef DEFAULT_FUNCTION_PASS #define DEFAULT_MODULE_PASS(pass, flags)\ StandardPass::RegisterDefaultPass(\ CreatePassFn(create ## pass ## Pass),\ &DefaultStandardPasses::pass ## ID, 0, StandardPass::Module, flags) // Optimize out global vars DEFAULT_MODULE_PASS(GlobalOptimizer, StandardPass::OptimzationFlags(0, 0, StandardPass::UnitAtATime)); // IP SCCP DEFAULT_MODULE_PASS(IPSCCP, StandardPass::OptimzationFlags(0, 0, StandardPass::UnitAtATime)); // Dead argument elimination DEFAULT_MODULE_PASS(DeadArgElimination, StandardPass::OptimzationFlags(0, 0, StandardPass::UnitAtATime)); // Clean up after IPCP & DAE DEFAULT_MODULE_PASS(InstructionCombining, StandardPass::OptimzationFlags(0, 0, StandardPass::UnitAtATime)); // Clean up after IPCP & DAE DEFAULT_MODULE_PASS(CFGSimplification, StandardPass::OptimzationFlags(0, 0, StandardPass::UnitAtATime)); // Remove dead EH info DEFAULT_MODULE_PASS(PruneEH, StandardPass::OptimzationFlags(0, 0, StandardPass::UnitAtATime | StandardPass::HaveExceptions)); // Placeholder that will be replaced by an inliner if one is specified StandardPass::RegisterDefaultPass(0, &DefaultStandardPasses::InlinerPlaceholderID, 0, StandardPass::Module); // Set readonly/readnone attrs DEFAULT_MODULE_PASS(FunctionAttrs, StandardPass::OptimzationFlags(0, 0, StandardPass::UnitAtATime)); // Scalarize uninlined fn args DEFAULT_MODULE_PASS(ArgumentPromotion, StandardPass::OptimzationFlags(3)); // Start of function pass. // Break up aggregate allocas, using SSAUpdater. StandardPass::RegisterDefaultPass( CreatePassFn(createSSAScalarReplAggregatesPass), &DefaultStandardPasses::ScalarReplAggregatesID, 0, StandardPass::Module, 0); // Catch trivial redundancies DEFAULT_MODULE_PASS(EarlyCSE, 0); // Library Call Optimizations DEFAULT_MODULE_PASS(SimplifyLibCalls, StandardPass::OptimzationFlags(0, 0, StandardPass::SimplifyLibCalls)); // Thread jumps DEFAULT_MODULE_PASS(JumpThreading, 0); // Propagate conditionals DEFAULT_MODULE_PASS(CorrelatedValuePropagation, 0); // Merge & remove BBs DEFAULT_MODULE_PASS(CFGSimplification, 0); // Combine silly seq's DEFAULT_MODULE_PASS(InstructionCombining, 0); // Eliminate tail calls DEFAULT_MODULE_PASS(TailCallElimination, 0); // Merge & remove BBs DEFAULT_MODULE_PASS(CFGSimplification, 0); // Reassociate expressions DEFAULT_MODULE_PASS(Reassociate, 0); // Rotate Loop DEFAULT_MODULE_PASS(LoopRotate, 0); // Hoist loop invariants DEFAULT_MODULE_PASS(LICM, 0); // Optimize for size if the optimzation level is 0-2 StandardPass::RegisterDefaultPass( CreatePassFn(createSizeOptimizingLoopUnswitchPass), &DefaultStandardPasses::LoopUnswitchID, 0, StandardPass::Module, StandardPass::OptimzationFlags(0, 2)); // Optimize for size if the optimzation level is >2, and OptimizeSize is // set StandardPass::RegisterDefaultPass( CreatePassFn(createSizeOptimizingLoopUnswitchPass), &DefaultStandardPasses::LoopUnswitchID, 0, StandardPass::Module, StandardPass::OptimzationFlags(3, 0, StandardPass::OptimizeSize)); // Don't optimize for size if optimisation level is >2 and OptimizeSize // is not set StandardPass::RegisterDefaultPass( CreatePassFn(createDefaultLoopUnswitchPass), &DefaultStandardPasses::LoopUnswitchID, 0, StandardPass::Module, StandardPass::OptimzationFlags(3, 0, 0, StandardPass::OptimizeSize)); DEFAULT_MODULE_PASS(InstructionCombining, 0); // Canonicalize indvars DEFAULT_MODULE_PASS(IndVarSimplify, 0); // Recognize idioms like memset. DEFAULT_MODULE_PASS(LoopIdiom, 0); // Delete dead loops DEFAULT_MODULE_PASS(LoopDeletion, 0); // Unroll small loops DEFAULT_MODULE_PASS(LoopUnroll, StandardPass::OptimzationFlags(0, 0, StandardPass::UnrollLoops)); // Remove redundancies DEFAULT_MODULE_PASS(GVN, StandardPass::OptimzationFlags(2)); // Remove memcpy / form memset DEFAULT_MODULE_PASS(MemCpyOpt, 0); // Constant prop with SCCP DEFAULT_MODULE_PASS(SCCP, 0); // Run instcombine after redundancy elimination to exploit opportunities // opened up by them. DEFAULT_MODULE_PASS(InstructionCombining, 0); // Thread jumps DEFAULT_MODULE_PASS(JumpThreading, 0); DEFAULT_MODULE_PASS(CorrelatedValuePropagation, 0); // Delete dead stores DEFAULT_MODULE_PASS(DeadStoreElimination, 0); // Delete dead instructions DEFAULT_MODULE_PASS(AggressiveDCE, 0); // Merge & remove BBs DEFAULT_MODULE_PASS(CFGSimplification, 0); // Clean up after everything. DEFAULT_MODULE_PASS(InstructionCombining, 0); // Get rid of dead prototypes DEFAULT_MODULE_PASS(StripDeadPrototypes, StandardPass::OptimzationFlags(0, 0, StandardPass::UnitAtATime)); // Eliminate dead types DEFAULT_MODULE_PASS(DeadTypeElimination, StandardPass::OptimzationFlags(0, 0, StandardPass::UnitAtATime)); // GlobalOpt already deletes dead functions and globals, at -O3 try a // late pass of GlobalDCE. It is capable of deleting dead cycles. // Remove dead fns and globals. DEFAULT_MODULE_PASS(GlobalDCE, StandardPass::OptimzationFlags(3, 0, StandardPass::UnitAtATime)); // Merge dup global constants DEFAULT_MODULE_PASS(ConstantMerge, StandardPass::OptimzationFlags(2, 0, StandardPass::UnitAtATime)); #undef DEFAULT_MODULE_PASS #define DEFAULT_LTO_PASS(pass, flags)\ StandardPass::RegisterDefaultPass(\ CreatePassFn(create ## pass ## Pass),\ &DefaultStandardPasses::pass ## ID, 0, StandardPass::LTO, flags) // LTO passes // Propagate constants at call sites into the functions they call. This // opens opportunities for globalopt (and inlining) by substituting function // pointers passed as arguments to direct uses of functions. DEFAULT_LTO_PASS(IPSCCP, 0); // Now that we internalized some globals, see if we can hack on them! DEFAULT_LTO_PASS(GlobalOptimizer, 0); // Linking modules together can lead to duplicated global constants, only // keep one copy of each constant... DEFAULT_LTO_PASS(ConstantMerge, 0); // Remove unused arguments from functions... DEFAULT_LTO_PASS(DeadArgElimination, 0); // Reduce the code after globalopt and ipsccp. Both can open up significant // simplification opportunities, and both can propagate functions through // function pointers. When this happens, we often have to resolve varargs // calls, etc, so let instcombine do this. DEFAULT_LTO_PASS(InstructionCombining, 0); // Inline small functions DEFAULT_LTO_PASS(FunctionInlining, StandardPass::OptimzationFlags(0, 0xf, StandardPass::RunInliner)); // Remove dead EH info. DEFAULT_LTO_PASS(PruneEH, 0); // Optimize globals again if we ran the inliner. DEFAULT_LTO_PASS(GlobalOptimizer, StandardPass::OptimzationFlags(0, 0xf, StandardPass::RunInliner)); DEFAULT_LTO_PASS(GlobalDCE, 0); // 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. DEFAULT_LTO_PASS(ArgumentPromotion, 0); // The IPO passes may leave cruft around. Clean up after them. DEFAULT_LTO_PASS(InstructionCombining, 0); DEFAULT_LTO_PASS(JumpThreading, 0); // Break up allocas DEFAULT_LTO_PASS(ScalarReplAggregates, 0); // Run a few AA driven optimizations here and now, to cleanup the code. // Add nocapture. DEFAULT_LTO_PASS(FunctionAttrs, 0); // IP alias analysis. DEFAULT_LTO_PASS(GlobalsModRef, 0); // Hoist loop invariants. DEFAULT_LTO_PASS(LICM, 0); // Remove redundancies. DEFAULT_LTO_PASS(GVN, 0); // Remove dead memcpys. DEFAULT_LTO_PASS(MemCpyOpt, 0); // Nuke dead stores. DEFAULT_LTO_PASS(DeadStoreElimination, 0); // Cleanup and simplify the code after the scalar optimizations. DEFAULT_LTO_PASS(InstructionCombining, 0); DEFAULT_LTO_PASS(JumpThreading, 0); // Delete basic blocks, which optimization passes may have killed. DEFAULT_LTO_PASS(CFGSimplification, 0); // Now that we have optimized the program, discard unreachable functions. DEFAULT_LTO_PASS(GlobalDCE, 0); #undef DEFAULT_LTO_PASS } }; static RegisterStandardPassLists AutoRegister; static inline void createStandardAliasAnalysisPasses(PassManagerBase *PM) { StandardPass::AddPassesFromSet(PM, StandardPass::AliasAnalysis); } /// createStandardFunctionPasses - Add the standard list of function passes to /// the provided pass manager. /// /// \arg OptimizationLevel - The optimization level, corresponding to -O0, /// -O1, etc. static inline void createStandardFunctionPasses(PassManagerBase *PM, unsigned OptimizationLevel) { StandardPass::AddPassesFromSet(PM, StandardPass::AliasAnalysis); StandardPass::AddPassesFromSet(PM, StandardPass::Function, OptimizationLevel); } /// createStandardModulePasses - Add the standard list of module passes to the /// provided pass manager. /// /// \arg OptimizationLevel - The optimization level, corresponding to -O0, /// -O1, etc. /// \arg OptimizeSize - Whether the transformations should optimize for size. /// \arg UnitAtATime - Allow passes which may make global module changes. /// \arg UnrollLoops - Allow loop unrolling. /// \arg SimplifyLibCalls - Allow library calls to be simplified. /// \arg HaveExceptions - Whether the module may have code using exceptions. /// \arg InliningPass - The inlining pass to use, if any, or null. This will /// always be added, even at -O0. static inline void createStandardModulePasses(PassManagerBase *PM, unsigned OptimizationLevel, bool OptimizeSize, bool UnitAtATime, bool UnrollLoops, bool SimplifyLibCalls, bool HaveExceptions, Pass *InliningPass) { createStandardAliasAnalysisPasses(PM); // If all optimizations are disabled, just run the always-inline pass. if (OptimizationLevel == 0) { if (InliningPass) PM->add(InliningPass); return; } StandardPass::AddPassesFromSet(PM, StandardPass::Module, StandardPass::OptimzationFlags(OptimizationLevel, 0, (OptimizeSize ? StandardPass::OptimizeSize : 0) | (UnitAtATime ? StandardPass::UnitAtATime : 0) | (UnrollLoops ? StandardPass::UnrollLoops : 0) | (SimplifyLibCalls ? StandardPass::SimplifyLibCalls : 0) | (HaveExceptions ? StandardPass::HaveExceptions : 0)), false, InliningPass); } /// createStandardLTOPasses - Add the standard list of module passes suitable /// for link time optimization. /// /// Internalize - Run the internalize pass. /// RunInliner - Use a function inlining pass. /// VerifyEach - Run the verifier after each pass. static inline void createStandardLTOPasses(PassManagerBase *PM, bool Internalize, bool RunInliner, bool VerifyEach) { // Provide AliasAnalysis services for optimizations. createStandardAliasAnalysisPasses(PM); // Now that composite has been compiled, scan through the module, looking // for a main function. If main is defined, mark all other functions // internal. if (Internalize) { PM->add(createInternalizePass(true)); if (VerifyEach) PM->add(createVerifierPass()); } StandardPass::AddPassesFromSet(PM, StandardPass::LTO, StandardPass::OptimzationFlags(0, 0, RunInliner ? StandardPass::RunInliner : 0), VerifyEach); } } #endif