[llvm-commits] [llvm] r131556 - in /llvm/trunk: include/llvm/DefaultPasses.h include/llvm/Support/StandardPasses.h lib/Support/StandardPasses.cpp
Eli Friedman
eli.friedman at gmail.com
Wed May 18 13:46:00 PDT 2011
Reverted in r131567; this is breaking clang tests. See, for example,
the failure on http://google1.osuosl.org:8011/builders/clang-x86_64-darwin10-cross-mingw32/builds/452
.
-Eli
On Wed, May 18, 2011 at 12:00 PM, David Chisnall <csdavec at swan.ac.uk> wrote:
> Author: theraven
> Date: Wed May 18 14:00:41 2011
> New Revision: 131556
>
> URL: http://llvm.org/viewvc/llvm-project?rev=131556&view=rev
> Log:
> Second pass at allowing plugins to modify default passes. This time without bonus inter-library dependencies.
>
>
> Added:
> llvm/trunk/include/llvm/DefaultPasses.h
> llvm/trunk/lib/Support/StandardPasses.cpp
> Modified:
> llvm/trunk/include/llvm/Support/StandardPasses.h
>
> Added: llvm/trunk/include/llvm/DefaultPasses.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DefaultPasses.h?rev=131556&view=auto
> ==============================================================================
> --- llvm/trunk/include/llvm/DefaultPasses.h (added)
> +++ llvm/trunk/include/llvm/DefaultPasses.h Wed May 18 14:00:41 2011
> @@ -0,0 +1,162 @@
> +//===- llvm/DefaultPasses.h - Default Pass Support code --------*- 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 the infrastructure for registering the standard pass list.
> +// This defines sets of standard optimizations that plugins can modify and
> +// front ends can use.
> +//===----------------------------------------------------------------------===//
> +
> +#ifndef LLVM_DEFAULT_PASS_SUPPORT_H
> +#define LLVM_DEFAULT_PASS_SUPPORT_H
> +
> +namespace llvm {
> +
> +class PassManagerBase;
> +
> +/// Unique identifiers for the default standard passes. The addresses of
> +/// these symbols are used to uniquely identify passes from the default list.
> +namespace DefaultStandardPasses {
> +extern unsigned char AggressiveDCEID;
> +extern unsigned char ArgumentPromotionID;
> +extern unsigned char BasicAliasAnalysisID;
> +extern unsigned char CFGSimplificationID;
> +extern unsigned char ConstantMergeID;
> +extern unsigned char CorrelatedValuePropagationID;
> +extern unsigned char DeadArgEliminationID;
> +extern unsigned char DeadStoreEliminationID;
> +extern unsigned char DeadTypeEliminationID;
> +extern unsigned char EarlyCSEID;
> +extern unsigned char FunctionAttrsID;
> +extern unsigned char FunctionInliningID;
> +extern unsigned char GVNID;
> +extern unsigned char GlobalDCEID;
> +extern unsigned char GlobalOptimizerID;
> +extern unsigned char GlobalsModRefID;
> +extern unsigned char IPSCCPID;
> +extern unsigned char IndVarSimplifyID;
> +extern unsigned char InlinerPlaceholderID;
> +extern unsigned char InstructionCombiningID;
> +extern unsigned char JumpThreadingID;
> +extern unsigned char LICMID;
> +extern unsigned char LoopDeletionID;
> +extern unsigned char LoopIdiomID;
> +extern unsigned char LoopRotateID;
> +extern unsigned char LoopUnrollID;
> +extern unsigned char LoopUnswitchID;
> +extern unsigned char MemCpyOptID;
> +extern unsigned char PruneEHID;
> +extern unsigned char ReassociateID;
> +extern unsigned char SCCPID;
> +extern unsigned char ScalarReplAggregatesID;
> +extern unsigned char SimplifyLibCallsID;
> +extern unsigned char StripDeadPrototypesID;
> +extern unsigned char TailCallEliminationID;
> +extern unsigned char TypeBasedAliasAnalysisID;
> +}
> +
> +/// StandardPass - The class responsible for maintaining the lists of standard
> +class StandardPass {
> + friend class RegisterStandardPassLists;
> + public:
> + /// Predefined standard sets of passes
> + enum StandardSet {
> + AliasAnalysis,
> + Function,
> + Module,
> + LTO
> + };
> + /// Flags to specify whether a pass should be enabled. Passes registered
> + /// with the standard sets may specify a minimum optimization level and one
> + /// or more flags that must be set when constructing the set for the pass to
> + /// be used.
> + enum OptimizationFlags {
> + /// Optimize for size was requested.
> + OptimizeSize = 1<<0,
> + /// Allow passes which may make global module changes.
> + UnitAtATime = 1<<1,
> + /// UnrollLoops - Allow loop unrolling.
> + UnrollLoops = 1<<2,
> + /// Allow library calls to be simplified.
> + SimplifyLibCalls = 1<<3,
> + /// Whether the module may have code using exceptions.
> + HaveExceptions = 1<<4,
> + // Run an inliner pass as part of this set.
> + RunInliner = 1<<5
> + };
> + enum OptimizationFlagComponents {
> + /// The low bits are used to store the optimization level. When requesting
> + /// passes, this should store the requested optimisation level. When
> + /// setting passes, this should set the minimum optimization level at which
> + /// the pass will run.
> + OptimizationLevelMask=0xf,
> + /// The maximum optimisation level at which the pass is run.
> + MaxOptimizationLevelMask=0xf0,
> + // Flags that must be set
> + RequiredFlagMask=0xff00,
> + // Flags that may not be set.
> + DisallowedFlagMask=0xff0000,
> + MaxOptimizationLevelShift=4,
> + RequiredFlagShift=8,
> + DisallowedFlagShift=16
> + };
> + /// Returns the optimisation level from a set of flags.
> + static unsigned OptimizationLevel(unsigned flags) {
> + return flags & OptimizationLevelMask ; };
> + /// Returns the maximum optimization level for this set of flags
> + static unsigned MaxOptimizationLevel(unsigned flags) {
> + return (flags & MaxOptimizationLevelMask) >> 4; };
> + /// Constructs a set of flags from the specified minimum and maximum
> + /// optimisation level
> + static unsigned OptimzationFlags(unsigned minLevel=0, unsigned maxLevel=0xf,
> + unsigned requiredFlags=0, unsigned disallowedFlags=0) {
> + return ((minLevel & OptimizationLevelMask) |
> + ((maxLevel<<MaxOptimizationLevelShift) & MaxOptimizationLevelMask)
> + | ((requiredFlags<<RequiredFlagShift) & RequiredFlagMask)
> + | ((disallowedFlags<<DisallowedFlagShift) & DisallowedFlagMask)); }
> + /// Returns the flags that must be set for this to match
> + static unsigned RequiredFlags(unsigned flags) {
> + return (flags & RequiredFlagMask) >> RequiredFlagShift; };
> + /// Returns the flags that must not be set for this to match
> + static unsigned DisallowedFlags(unsigned flags) {
> + return (flags & DisallowedFlagMask) >> DisallowedFlagShift; };
> + /// Register a standard pass in the specified set. If flags is non-zero,
> + /// then the pass will only be returned when the specified flags are set.
> + template<typename passName>
> + class RegisterStandardPass {
> + public:
> + RegisterStandardPass(StandardSet set, unsigned char *runBefore=0,
> + unsigned flags=0, unsigned char *ID=0) {
> + // Use the pass's ID if one is not specified
> + RegisterDefaultPass(PassInfo::NormalCtor_t(callDefaultCtor<passName>),
> + ID ? ID : (unsigned char*)&passName::ID, runBefore, set, flags);
> + };
> + };
> + /// Adds the passes from the specified set to the provided pass manager
> + static void AddPassesFromSet(PassManagerBase *PM,
> + StandardSet set,
> + unsigned flags=0,
> + bool VerifyEach=false,
> + Pass *inliner=0);
> + private:
> + /// Registers the default passes. This is set by RegisterStandardPassLists
> + /// and is called lazily.
> + static void (*RegisterDefaultPasses)(void);
> + /// Creates the verifier pass that is inserted when a VerifyEach is passed to
> + /// AddPassesFromSet()
> + static Pass* (*CreateVerifierPass)(void);
> + /// Registers the pass
> + static void RegisterDefaultPass(PassInfo::NormalCtor_t constructor,
> + unsigned char *newPass,
> + unsigned char *oldPass,
> + StandardSet set,
> + unsigned flags=0);
> +};
> +
> +} // namespace llvm
> +
> +#endif
>
> Modified: llvm/trunk/include/llvm/Support/StandardPasses.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/StandardPasses.h?rev=131556&r1=131555&r2=131556&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Support/StandardPasses.h (original)
> +++ llvm/trunk/include/llvm/Support/StandardPasses.h Wed May 18 14:00:41 2011
> @@ -20,6 +20,7 @@
> #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"
> @@ -27,12 +28,273 @@
>
> namespace llvm {
>
> + /// 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:
> + 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 *createDefaultScalarReplAggregatesPass(void) {
> + return createScalarReplAggregatesPass(-1, false);
> + }
> + static Pass *createDefaultLoopUnswitchPass(void) {
> + return createLoopUnswitchPass(false);
> + }
> + static Pass *createDefaultLoopUnrollPass(void) {
> + return createLoopUnrollPass();
> + }
> + static Pass *createSizeOptimizingLoopUnswitchPass(void) {
> + return createLoopUnswitchPass(true);
> + }
> + 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(\
> + PassInfo::NormalCtor_t(create ## pass ## Pass),\
> + &DefaultStandardPasses::pass ## ID, 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(\
> + PassInfo::NormalCtor_t(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(\
> + PassInfo::NormalCtor_t(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(2));
> + // Start of function pass.
> + // Break up aggregate allocas, using SSAUpdater.
> + StandardPass::RegisterDefaultPass(
> + PassInfo::NormalCtor_t(createDefaultScalarReplAggregatesPass),
> + &DefaultStandardPasses::ScalarReplAggregatesID, 0,
> + StandardPass::Module);
> + // 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(
> + PassInfo::NormalCtor_t(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(
> + PassInfo::NormalCtor_t(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(
> + PassInfo::NormalCtor_t(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
> + StandardPass::RegisterDefaultPass(
> + PassInfo::NormalCtor_t(createDefaultLoopUnrollPass),
> + &DefaultStandardPasses::LoopUnrollID, 0,
> + StandardPass::Module,
> + 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(\
> + PassInfo::NormalCtor_t(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) {
> - // Add TypeBasedAliasAnalysis before BasicAliasAnalysis so that
> - // BasicAliasAnalysis wins if they disagree. This is intended to help
> - // support "obvious" type-punning idioms.
> - PM->add(createTypeBasedAliasAnalysisPass());
> - PM->add(createBasicAliasAnalysisPass());
> + StandardPass::AddPassesFromSet(PM, StandardPass::AliasAnalysis);
> }
>
> /// createStandardFunctionPasses - Add the standard list of function passes to
> @@ -42,12 +304,8 @@
> /// -O1, etc.
> static inline void createStandardFunctionPasses(PassManagerBase *PM,
> unsigned OptimizationLevel) {
> - if (OptimizationLevel > 0) {
> - createStandardAliasAnalysisPasses(PM);
> - PM->add(createCFGSimplificationPass());
> - PM->add(createScalarReplAggregatesPass());
> - PM->add(createEarlyCSEPass());
> - }
> + StandardPass::AddPassesFromSet(PM, StandardPass::AliasAnalysis);
> + StandardPass::AddPassesFromSet(PM, StandardPass::Function, OptimizationLevel);
> }
>
> /// createStandardModulePasses - Add the standard list of module passes to the
> @@ -78,84 +336,17 @@
> PM->add(InliningPass);
> return;
> }
> -
> - if (UnitAtATime) {
> - PM->add(createGlobalOptimizerPass()); // Optimize out global vars
> -
> - PM->add(createIPSCCPPass()); // IP SCCP
> - PM->add(createDeadArgEliminationPass()); // Dead argument elimination
> -
> - PM->add(createInstructionCombiningPass());// Clean up after IPCP & DAE
> - PM->add(createCFGSimplificationPass()); // Clean up after IPCP & DAE
> - }
> -
> - // Start of CallGraph SCC passes.
> - if (UnitAtATime && HaveExceptions)
> - PM->add(createPruneEHPass()); // Remove dead EH info
> - if (InliningPass)
> - PM->add(InliningPass);
> - if (UnitAtATime)
> - PM->add(createFunctionAttrsPass()); // Set readonly/readnone attrs
> - if (OptimizationLevel > 2)
> - PM->add(createArgumentPromotionPass()); // Scalarize uninlined fn args
> -
> - // Start of function pass.
> - // Break up aggregate allocas, using SSAUpdater.
> - PM->add(createScalarReplAggregatesPass(-1, false));
> - PM->add(createEarlyCSEPass()); // Catch trivial redundancies
> - if (SimplifyLibCalls)
> - PM->add(createSimplifyLibCallsPass()); // Library Call Optimizations
> - PM->add(createJumpThreadingPass()); // Thread jumps.
> - PM->add(createCorrelatedValuePropagationPass()); // Propagate conditionals
> - PM->add(createCFGSimplificationPass()); // Merge & remove BBs
> - PM->add(createInstructionCombiningPass()); // Combine silly seq's
> -
> - 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(OptimizeSize || OptimizationLevel < 3));
> - PM->add(createInstructionCombiningPass());
> - PM->add(createIndVarSimplifyPass()); // Canonicalize indvars
> - PM->add(createLoopIdiomPass()); // Recognize idioms like memset.
> - PM->add(createLoopDeletionPass()); // Delete dead loops
> - if (UnrollLoops)
> - PM->add(createLoopUnrollPass()); // Unroll small loops
> - if (OptimizationLevel > 1)
> - PM->add(createGVNPass()); // Remove redundancies
> - PM->add(createMemCpyOptPass()); // Remove memcpy / form memset
> - PM->add(createSCCPPass()); // Constant prop with SCCP
> -
> - // Run instcombine after redundancy elimination to exploit opportunities
> - // opened up by them.
> - PM->add(createInstructionCombiningPass());
> - PM->add(createJumpThreadingPass()); // Thread jumps
> - PM->add(createCorrelatedValuePropagationPass());
> - PM->add(createDeadStoreEliminationPass()); // Delete dead stores
> - PM->add(createAggressiveDCEPass()); // Delete dead instructions
> - PM->add(createCFGSimplificationPass()); // Merge & remove BBs
> - PM->add(createInstructionCombiningPass()); // Clean up after everything.
> -
> - if (UnitAtATime) {
> - PM->add(createStripDeadPrototypesPass()); // Get rid of dead prototypes
> - PM->add(createDeadTypeEliminationPass()); // Eliminate dead types
>
> - // GlobalOpt already deletes dead functions and globals, at -O3 try a
> - // late pass of GlobalDCE. It is capable of deleting dead cycles.
> - if (OptimizationLevel > 2)
> - PM->add(createGlobalDCEPass()); // Remove dead fns and globals.
> + 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);
>
> - if (OptimizationLevel > 1)
> - PM->add(createConstantMergePass()); // Merge dup global constants
> - }
> - }
> -
> - static inline void addOnePass(PassManagerBase *PM, Pass *P, bool AndVerify) {
> - PM->add(P);
> -
> - if (AndVerify)
> - PM->add(createVerifierPass());
> }
>
> /// createStandardLTOPasses - Add the standard list of module passes suitable
> @@ -174,70 +365,15 @@
> // 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)
> - addOnePass(PM, createInternalizePass(true), VerifyEach);
> -
> - // 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.
> - addOnePass(PM, createIPSCCPPass(), VerifyEach);
> -
> - // Now that we internalized some globals, see if we can hack on them!
> - addOnePass(PM, createGlobalOptimizerPass(), VerifyEach);
> -
> - // Linking modules together can lead to duplicated global constants, only
> - // keep one copy of each constant...
> - addOnePass(PM, createConstantMergePass(), VerifyEach);
> -
> - // Remove unused arguments from functions...
> - addOnePass(PM, createDeadArgEliminationPass(), VerifyEach);
> -
> - // 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.
> - addOnePass(PM, createInstructionCombiningPass(), VerifyEach);
> -
> - // Inline small functions
> - if (RunInliner)
> - addOnePass(PM, createFunctionInliningPass(), VerifyEach);
> -
> - addOnePass(PM, createPruneEHPass(), VerifyEach); // Remove dead EH info.
> - // Optimize globals again if we ran the inliner.
> - if (RunInliner)
> - addOnePass(PM, createGlobalOptimizerPass(), VerifyEach);
> - addOnePass(PM, createGlobalDCEPass(), VerifyEach); // 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.
> - addOnePass(PM, createArgumentPromotionPass(), VerifyEach);
> -
> - // The IPO passes may leave cruft around. Clean up after them.
> - addOnePass(PM, createInstructionCombiningPass(), VerifyEach);
> - addOnePass(PM, createJumpThreadingPass(), VerifyEach);
> - // Break up allocas
> - addOnePass(PM, createScalarReplAggregatesPass(), VerifyEach);
> -
> - // Run a few AA driven optimizations here and now, to cleanup the code.
> - addOnePass(PM, createFunctionAttrsPass(), VerifyEach); // Add nocapture.
> - addOnePass(PM, createGlobalsModRefPass(), VerifyEach); // IP alias analysis.
> -
> - addOnePass(PM, createLICMPass(), VerifyEach); // Hoist loop invariants.
> - addOnePass(PM, createGVNPass(), VerifyEach); // Remove redundancies.
> - addOnePass(PM, createMemCpyOptPass(), VerifyEach); // Remove dead memcpys.
> - // Nuke dead stores.
> - addOnePass(PM, createDeadStoreEliminationPass(), VerifyEach);
> -
> - // Cleanup and simplify the code after the scalar optimizations.
> - addOnePass(PM, createInstructionCombiningPass(), VerifyEach);
> -
> - addOnePass(PM, createJumpThreadingPass(), VerifyEach);
> -
> - // Delete basic blocks, which optimization passes may have killed.
> - addOnePass(PM, createCFGSimplificationPass(), VerifyEach);
> + if (Internalize) {
> + PM->add(createInternalizePass(true));
> + if (VerifyEach)
> + PM->add(createVerifierPass());
> + }
>
> - // Now that we have optimized the program, discard unreachable functions.
> - addOnePass(PM, createGlobalDCEPass(), VerifyEach);
> + StandardPass::AddPassesFromSet(PM, StandardPass::LTO,
> + StandardPass::OptimzationFlags(0, 0, RunInliner ?
> + StandardPass::RunInliner : 0), VerifyEach);
> }
> }
>
>
> Added: llvm/trunk/lib/Support/StandardPasses.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/StandardPasses.cpp?rev=131556&view=auto
> ==============================================================================
> --- llvm/trunk/lib/Support/StandardPasses.cpp (added)
> +++ llvm/trunk/lib/Support/StandardPasses.cpp Wed May 18 14:00:41 2011
> @@ -0,0 +1,247 @@
> +//===-- lib/Support/StandardPasses.cpp - 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.
> +//
> +// This allows the creation of multiple standard sets, and their later
> +// modification by plugins and front ends.
> +//
> +//===----------------------------------------------------------------------===//
> +
> +#include "llvm/PassManager.h"
> +#include "llvm/Support/ErrorHandling.h"
> +#include "llvm/Support/ManagedStatic.h"
> +#include "llvm/DefaultPasses.h"
> +#include "llvm/Support/Mutex.h"
> +
> +using namespace llvm::DefaultStandardPasses;
> +using namespace llvm;
> +
> +namespace {
> +
> +/// Entry in the standard passes list.
> +struct StandardPassEntry {
> + /// Function called to create the pass
> + PassInfo::NormalCtor_t createPass;
> + /// Unique identifier for this pass
> + unsigned char *passID;
> + /// Flags specifying when this pass should be run
> + unsigned flags;
> +
> + StandardPassEntry(PassInfo::NormalCtor_t constructor, unsigned char *ID,
> + unsigned f) : createPass(constructor), passID(ID), flags(f) {};
> +};
> +
> +/// Standard alias analysis passes
> +static llvm::SmallVector<StandardPassEntry, 4> AAPasses;
> +/// Standard function passes
> +static llvm::SmallVector<StandardPassEntry, 32> FunctionPasses;
> +/// Standard module passes
> +static llvm::SmallVector<StandardPassEntry, 32> ModulePasses;
> +/// Standard link-time optimization passes
> +static llvm::SmallVector<StandardPassEntry, 32> LTOPasses;
> +
> +/// Entry in the unresolved standard pass list. IF a pass is inserted in front
> +/// of a pass that is not yet registered in the standard pass list then it is
> +/// stored in a separate list and resolved later.
> +struct UnresolvedStandardPass : public StandardPassEntry {
> + /// The set into which this is stored
> + StandardPass::StandardSet set;
> + /// The unique ID of the pass that should follow this one in the sequence
> + unsigned char *next;
> + UnresolvedStandardPass(PassInfo::NormalCtor_t constructor,
> + unsigned char *newPass,
> + unsigned char *oldPass,
> + StandardPass::StandardSet s,
> + unsigned f) :
> + StandardPassEntry(constructor, newPass, f), set(s), next(oldPass) {}
> +};
> +
> +/// The passes that can not be inserted into the correct lists yet because of
> +/// their place in the sequence.
> +static llvm::SmallVector<UnresolvedStandardPass, 16> UnresolvedPasses;
> +
> +/// Returns a reference to the pass list for the corresponding set of
> +/// optimisations.
> +llvm::SmallVectorImpl<StandardPassEntry>&
> +PassList(StandardPass::StandardSet set) {
> + switch (set) {
> + case StandardPass::AliasAnalysis: return AAPasses;
> + case StandardPass::Function: return FunctionPasses;
> + case StandardPass::Module: return ModulePasses;
> + case StandardPass::LTO: return LTOPasses;
> + }
> + // We could use a map of standard pass lists to allow definition of new
> + // default sets
> + llvm_unreachable("Invalid standard optimization set requested");
> +}
> +
> +static ManagedStatic<sys::SmartMutex<true> > Lock;
> +
> +/// Registers the default set of standard passes. This is called lazily when
> +/// an attempt is made to read or modify the standard pass list
> +void RegisterDefaultStandardPasses(void(*doRegister)(void)) {
> + // Only initialize the standard passes once
> + static volatile bool initialized = false;
> + if (initialized) return;
> +
> + llvm::sys::SmartScopedLock<true> Guard(*Lock);
> + if (initialized) return;
> + if (doRegister) {
> + assert("No passes registered before setting default passes" &&
> + AAPasses.size() == 0 &&
> + FunctionPasses.size() == 0 &&
> + LTOPasses.size() == 0 &&
> + ModulePasses.size() == 0);
> +
> + // We must set initialized to true before calling this function, because
> + // the doRegister() function will probably call RegisterDefaultPasses(),
> + // which will call this function, and we'd end up with infinite recursion
> + // and breakage if we didn't.
> + initialized = true;
> + doRegister();
> + }
> +}
> +
> +} // Anonymous namespace
> +
> +void (*StandardPass::RegisterDefaultPasses)(void);
> +Pass* (*StandardPass::CreateVerifierPass)(void);
> +
> +void StandardPass::RegisterDefaultPass(PassInfo::NormalCtor_t constructor,
> + unsigned char *newPass,
> + unsigned char *oldPass,
> + StandardPass::StandardSet set,
> + unsigned flags) {
> + // Make sure that the standard sets are already regstered
> + RegisterDefaultStandardPasses(RegisterDefaultPasses);
> + // Get the correct list to modify
> + llvm::SmallVectorImpl<StandardPassEntry>& passList = PassList(set);
> +
> + // If there is no old pass specified, then we are adding a new final pass, so
> + // just push it onto the end.
> + if (!oldPass) {
> + StandardPassEntry pass(constructor, newPass, flags);
> + passList.push_back(pass);
> + return;
> + }
> +
> + // Find the correct place to insert the pass. This is a linear search, but
> + // this shouldn't be too slow since the SmallVector will store the values in
> + // a contiguous block of memory. Each entry is just three words of memory, so
> + // in most cases we are only going to be looking in one or two cache lines.
> + // The extra memory accesses from a more complex search structure would
> + // offset any performance gain (unless someone decides to add an insanely
> + // large set of standard passes to a set)
> + for (SmallVectorImpl<StandardPassEntry>::iterator i=passList.begin(),
> + e=passList.end() ; i!=e ; ++i) {
> + if (i->passID == oldPass) {
> + StandardPassEntry pass(constructor, newPass, flags);
> + passList.insert(i, pass);
> + // If we've added a new pass, then there may have gained the ability to
> + // insert one of the previously unresolved ones. If so, insert the new
> + // one.
> + for (SmallVectorImpl<UnresolvedStandardPass>::iterator
> + u=UnresolvedPasses.begin(), eu=UnresolvedPasses.end() ; u!=eu ; ++u){
> + if (u->next == newPass && u->set == set) {
> + UnresolvedStandardPass p = *u;
> + UnresolvedPasses.erase(u);
> + RegisterDefaultPass(p.createPass, p.passID, p.next, p.set, p.flags);
> + }
> + }
> + return;
> + }
> + }
> + // If we get to here, then we didn't find the correct place to insert the new
> + // pass
> + UnresolvedStandardPass pass(constructor, newPass, oldPass, set, flags);
> + UnresolvedPasses.push_back(pass);
> +}
> +
> +void StandardPass::AddPassesFromSet(PassManagerBase *PM,
> + StandardSet set,
> + unsigned flags,
> + bool VerifyEach,
> + Pass *inliner) {
> + RegisterDefaultStandardPasses(RegisterDefaultPasses);
> + unsigned level = OptimizationLevel(flags);
> + flags = RequiredFlags(flags);
> + llvm::SmallVectorImpl<StandardPassEntry>& passList = PassList(set);
> +
> + // Add all of the passes from this set
> + for (SmallVectorImpl<StandardPassEntry>::iterator i=passList.begin(),
> + e=passList.end() ; i!=e ; ++i) {
> + // Skip passes that don't have conditions that match the ones specified
> + // here. For a pass to match:
> + // - Its minimum optimisation level must be less than or equal to the
> + // specified level.
> + // - Its maximum optimisation level must be greater than or equal to the
> + // specified level
> + // - All of its required flags must be set
> + // - None of its disallowed flags may be set
> + if ((level >= OptimizationLevel(i->flags)) &&
> + ((level <= MaxOptimizationLevel(i->flags))
> + || MaxOptimizationLevel(i->flags) == 0) &&
> + ((RequiredFlags(i->flags) & flags) == RequiredFlags(i->flags)) &&
> + ((DisallowedFlags(i->flags) & flags) == 0)) {
> + // This is quite an ugly way of allowing us to specify an inliner pass to
> + // insert. Ideally, we'd replace this with a general mechanism allowing
> + // callers to replace arbitrary passes in the list.
> + Pass *p = 0;
> + if (&InlinerPlaceholderID == i->passID) {
> + p = inliner;
> + } else if (i->createPass)
> + p = i->createPass();
> + if (p) {
> + PM->add(p);
> + if (VerifyEach)
> + PM->add(CreateVerifierPass());
> + }
> + }
> + }
> +}
> +
> +unsigned char DefaultStandardPasses::AggressiveDCEID;
> +unsigned char DefaultStandardPasses::ArgumentPromotionID;
> +unsigned char DefaultStandardPasses::BasicAliasAnalysisID;
> +unsigned char DefaultStandardPasses::CFGSimplificationID;
> +unsigned char DefaultStandardPasses::ConstantMergeID;
> +unsigned char DefaultStandardPasses::CorrelatedValuePropagationID;
> +unsigned char DefaultStandardPasses::DeadArgEliminationID;
> +unsigned char DefaultStandardPasses::DeadStoreEliminationID;
> +unsigned char DefaultStandardPasses::DeadTypeEliminationID;
> +unsigned char DefaultStandardPasses::EarlyCSEID;
> +unsigned char DefaultStandardPasses::FunctionAttrsID;
> +unsigned char DefaultStandardPasses::FunctionInliningID;
> +unsigned char DefaultStandardPasses::GVNID;
> +unsigned char DefaultStandardPasses::GlobalDCEID;
> +unsigned char DefaultStandardPasses::GlobalOptimizerID;
> +unsigned char DefaultStandardPasses::GlobalsModRefID;
> +unsigned char DefaultStandardPasses::IPSCCPID;
> +unsigned char DefaultStandardPasses::IndVarSimplifyID;
> +unsigned char DefaultStandardPasses::InlinerPlaceholderID;
> +unsigned char DefaultStandardPasses::InstructionCombiningID;
> +unsigned char DefaultStandardPasses::JumpThreadingID;
> +unsigned char DefaultStandardPasses::LICMID;
> +unsigned char DefaultStandardPasses::LoopDeletionID;
> +unsigned char DefaultStandardPasses::LoopIdiomID;
> +unsigned char DefaultStandardPasses::LoopRotateID;
> +unsigned char DefaultStandardPasses::LoopUnrollID;
> +unsigned char DefaultStandardPasses::LoopUnswitchID;
> +unsigned char DefaultStandardPasses::MemCpyOptID;
> +unsigned char DefaultStandardPasses::PruneEHID;
> +unsigned char DefaultStandardPasses::ReassociateID;
> +unsigned char DefaultStandardPasses::SCCPID;
> +unsigned char DefaultStandardPasses::ScalarReplAggregatesID;
> +unsigned char DefaultStandardPasses::SimplifyLibCallsID;
> +unsigned char DefaultStandardPasses::StripDeadPrototypesID;
> +unsigned char DefaultStandardPasses::TailCallEliminationID;
> +unsigned char DefaultStandardPasses::TypeBasedAliasAnalysisID;
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
More information about the llvm-commits
mailing list