[llvm-commits] [llvm] r131155 - in /llvm/trunk: include/llvm/PassSupport.h include/llvm/Support/StandardPasses.h lib/VMCore/StandardPasses.cpp

Nick Lewycky nlewycky at google.com
Tue May 10 15:30:23 PDT 2011


Sorry, but I had to back this out. The reason this functionality hasn't
happened so far is that it's tricky. :-)

This broke our build because it introduces a new dependency from VMCore on
the headers of Analysis and Transforms. Unfortunately, it can't go into
Support either since that can't depend on Analysis or Transforms either. I'm
not sure how to fix this, but now you have another requirement on your
design!

Nick

On 10 May 2011 14:36, David Chisnall <csdavec at swan.ac.uk> wrote:

> Author: theraven
> Date: Tue May 10 16:36:48 2011
> New Revision: 131155
>
> URL: http://llvm.org/viewvc/llvm-project?rev=131155&view=rev
> Log:
> Add support for plugins add passes to the default set of passes.  The
> standard set of passes used by front ends can now be modified by LLVM
> plugins, without needing to modify any front ends.
>
> Still to do:
>
> - Allow replacing / removing passes (infrastructure there, just needs an
> infrastructure exposed)
> - Defining sets of passes to be added or removed as a group
> - Extending the support to allow user-defined groups of optimisations
> - Allow plugins to be specified for loading automatically (e.g. from
> plugins.conf or some similar mechanism)
>
> Reviewed by Nick Lewycky.
>
>
> Added:
>    llvm/trunk/lib/VMCore/StandardPasses.cpp
> Modified:
>    llvm/trunk/include/llvm/PassSupport.h
>    llvm/trunk/include/llvm/Support/StandardPasses.h
>
> Modified: llvm/trunk/include/llvm/PassSupport.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/PassSupport.h?rev=131155&r1=131154&r2=131155&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/PassSupport.h (original)
> +++ llvm/trunk/include/llvm/PassSupport.h Tue May 10 16:36:48 2011
> @@ -29,6 +29,8 @@
>
>  namespace llvm {
>
> +  class PassManagerBase;
> +
>
>  //===---------------------------------------------------------------------------
>  /// PassInfo class - An instance of this class exists for every pass known
> by
>  /// the system, and can be obtained from a live Pass by calling its
> @@ -207,6 +209,149 @@
>   }
>  };
>
> +  /// 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;
> +  }
> +
> +
> +class RegisterStandardPass;
> +/// RegisterStandardPass - Registers a pass as a member of a standard set.
> +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 OptimizationFlags(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) >> RequiredFlagShift;
> +  }
> +  /// 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 {
> +    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 : &passName::ID, runBefore, set, flags);
> +    };
> +  };
> +  /// Adds the passes from the specified set to a 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);
> +  /// Registers the pass
> +  static void RegisterDefaultPass(PassInfo::NormalCtor_t constructor,
> +                                  unsigned char *newPass,
> +                                  unsigned char *oldPass,
> +                                  StandardSet set,
> +                                  unsigned flags=0);
> +};
> +
>
>  /// RegisterAnalysisGroup - Register a Pass as a member of an analysis
> _group_.
>  /// Analysis groups are used to define an interface (which need not derive
> from
>
> Modified: llvm/trunk/include/llvm/Support/StandardPasses.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/StandardPasses.h?rev=131155&r1=131154&r2=131155&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/Support/StandardPasses.h (original)
> +++ llvm/trunk/include/llvm/Support/StandardPasses.h Tue May 10 16:36:48
> 2011
> @@ -20,6 +20,7 @@
>  #define LLVM_SUPPORT_STANDARDPASSES_H
>
>  #include "llvm/PassManager.h"
> +#include "llvm/PassSupport.h"
>  #include "llvm/Analysis/Passes.h"
>  #include "llvm/Analysis/Verifier.h"
>  #include "llvm/Transforms/Scalar.h"
> @@ -27,12 +28,259 @@
>
>  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;
> +    }
> +    private:
> +    /// 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 *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(BasicAliasAnalysis, 0);
> +      DEFAULT_ALIAS_ANALYSIS_PASS(TypeBasedAliasAnalysis, 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::OptimizationFlags(1));
> +      DEFAULT_FUNCTION_PASS(ScalarReplAggregates,
> +          StandardPass::OptimizationFlags(1));
> +      DEFAULT_FUNCTION_PASS(EarlyCSE, StandardPass::OptimizationFlags(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::UnitAtATime);
> +      // IP SCCP
> +      DEFAULT_MODULE_PASS(IPSCCP,
> +          StandardPass::OptimizationFlags(0, 0,
> StandardPass::UnitAtATime));
> +      // Dead argument elimination
> +      DEFAULT_MODULE_PASS(DeadArgElimination,
> +          StandardPass::OptimizationFlags(0, 0,
> StandardPass::UnitAtATime));
> +      // Clean up after IPCP & DAE
> +      DEFAULT_MODULE_PASS(InstructionCombining,
> +          StandardPass::OptimizationFlags(0, 0,
> StandardPass::UnitAtATime));
> +      // Clean up after IPCP & DAE
> +      DEFAULT_MODULE_PASS(CFGSimplification,
> +          StandardPass::OptimizationFlags(0, 0,
> StandardPass::UnitAtATime));
> +
> +      // Placeholder that will be replaced by an inliner if one is
> specified
> +      StandardPass::RegisterDefaultPass(0,
> +        &DefaultStandardPasses::InlinerPlaceholderID , 0,
> +        StandardPass::Module);
> +      // Remove dead EH info
> +      DEFAULT_MODULE_PASS(PruneEH, StandardPass::OptimizationFlags(0, 0,
> +            StandardPass::UnitAtATime | StandardPass::HaveExceptions));
> +      // Set readonly/readnone attrs
> +      DEFAULT_MODULE_PASS(FunctionAttrs,
> StandardPass::OptimizationFlags(0, 0,
> +            StandardPass::UnitAtATime));
> +      // Scalarize uninlined fn args
> +      DEFAULT_MODULE_PASS(ArgumentPromotion, 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::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::OptimizationFlags(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::OptimizationFlags(0, 3,
> StandardPass::OptimizeSize));
> +      // Don't optimize for size if optimisation level is >2 and
> OptimizeSize
> +      // is not set
> +      StandardPass::RegisterDefaultPass(
> +          PassInfo::NormalCtor_t(createSizeOptimizingLoopUnswitchPass),
> +          &DefaultStandardPasses::LoopUnswitchID, 0,
> +          StandardPass::Module,
> +          StandardPass::OptimizationFlags(0, 3, 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::UnrollLoops);
> +      // Remove redundancies
> +      DEFAULT_MODULE_PASS(GVN, 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::UnitAtATime);
> +      // Eliminate dead types
> +      DEFAULT_MODULE_PASS(DeadTypeElimination, 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, 3 | StandardPass::UnitAtATime);
> +      // Merge dup global constants
> +      DEFAULT_MODULE_PASS(ConstantMerge, 2 | 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::OptimizationFlags(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::OptimizationFlags(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 +290,7 @@
>   /// -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::Function,
> OptimizationLevel);
>   }
>
>   /// createStandardModulePasses - Add the standard list of module passes
> to the
> @@ -78,84 +321,16 @@
>         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::OptimizationFlags(OptimizationLevel,
> +        (OptimizeSize ? StandardPass::OptimizeSize : 0) |
> +        (UnitAtATime ? StandardPass::UnitAtATime : 0) |
> +        (UnrollLoops ? StandardPass::UnrollLoops : 0) |
> +        (SimplifyLibCalls ? StandardPass::SimplifyLibCalls : 0) |
> +        (HaveExceptions ? StandardPass::HaveExceptions : 0)),
> +      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 +349,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::OptimizationFlags(0, 0, RunInliner ?
> +        StandardPass::RunInliner : 0), VerifyEach);
>   }
>  }
>
>
> Added: llvm/trunk/lib/VMCore/StandardPasses.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/StandardPasses.cpp?rev=131155&view=auto
>
> ==============================================================================
> --- llvm/trunk/lib/VMCore/StandardPasses.cpp (added)
> +++ llvm/trunk/lib/VMCore/StandardPasses.cpp Tue May 10 16:36:48 2011
> @@ -0,0 +1,240 @@
> +//=========-- 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.
> +//
>
> +//===----------------------------------------------------------------------===//
> +
> +#include "llvm/PassManager.h"
> +#include "llvm/Analysis/Passes.h"
> +#include "llvm/Analysis/Verifier.h"
> +#include "llvm/Analysis/Verifier.h"
> +#include "llvm/Support/ErrorHandling.h"
> +#include "llvm/Support/ManagedStatic.h"
> +#include "llvm/Support/Mutex.h"
> +#include "llvm/Support/DynamicLibrary.h"
> +#include "llvm/Transforms/Scalar.h"
> +#include "llvm/Transforms/IPO.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 bool initialized = false;
> +  if (initialized) return;
> +
> +  llvm::sys::SmartScopedLock<true> Guard(*Lock);
> +  if (initialized) return;
> +  if (doRegister) {
> +    // 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);
> +
> +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
> +  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 = inliner;
> +      if ((&InlinerPlaceholderID != i->passID) && 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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20110510/85f8afe5/attachment.html>


More information about the llvm-commits mailing list