Index: include/llvm/CodeGen/Passes.h =================================================================== --- include/llvm/CodeGen/Passes.h +++ include/llvm/CodeGen/Passes.h @@ -120,9 +120,6 @@ /// Default setting for -enable-tail-merge on this target. bool EnableTailMerge; - /// Default setting for -enable-shrink-wrap on this target. - bool EnableShrinkWrap; - public: TargetPassConfig(TargetMachine *tm, PassManagerBase &pm); // Dummy constructor. @@ -190,9 +187,6 @@ /// Return true if the optimized regalloc pipeline is enabled. bool getOptimizeRegAlloc() const; - /// Return true if shrink wrapping is enabled. - bool getEnableShrinkWrap() const; - /// Return true if the default global register allocator is in use and /// has not be overriden on the command line with '-regalloc=...' bool usingDefaultRegAlloc() const; @@ -361,6 +355,14 @@ /// Add a pass to perform basic verification of the machine function if /// verification is enabled. void addVerifyPass(const std::string &Banner); + + /// Create an instance of ShrinkWrap using the runShrinkWrap predicate + /// function. + FunctionPass *createShrinkWrapPass(); + + /// Predicate function passed to a ShrinkWrap object to determine if shrink + /// wrapping should be run on a MachineFunction. + virtual bool runShrinkWrap(const MachineFunction &Fn) const; }; } // namespace llvm Index: lib/CodeGen/Passes.cpp =================================================================== --- lib/CodeGen/Passes.cpp +++ lib/CodeGen/Passes.cpp @@ -52,9 +52,6 @@ cl::desc("Disable Machine LICM")); static cl::opt DisableMachineCSE("disable-machine-cse", cl::Hidden, cl::desc("Disable Machine Common Subexpression Elimination")); -static cl::opt - EnableShrinkWrapOpt("enable-shrink-wrap", cl::Hidden, - cl::desc("enable the shrink-wrapping pass")); static cl::opt OptimizeRegAlloc( "optimize-regalloc", cl::Hidden, cl::desc("Enable optimized register allocation compilation path.")); @@ -217,7 +214,7 @@ : ImmutablePass(ID), PM(&pm), StartBefore(nullptr), StartAfter(nullptr), StopAfter(nullptr), Started(true), Stopped(false), AddingMachinePasses(false), TM(tm), Impl(nullptr), Initialized(false), - DisableVerify(false), EnableTailMerge(true), EnableShrinkWrap(false) { + DisableVerify(false), EnableTailMerge(true) { Impl = new PassConfigImpl(); @@ -539,8 +536,7 @@ addPostRegAlloc(); // Insert prolog/epilog code. Eliminate abstract frame index references... - if (getEnableShrinkWrap()) - addPass(&ShrinkWrapID); + addPass(createShrinkWrapPass()); addPass(&PrologEpilogCodeInserterID); /// Add passes that optimize machine instructions after register allocation. @@ -619,21 +615,6 @@ addPass(&DeadMachineInstructionElimID); } -bool TargetPassConfig::getEnableShrinkWrap() const { - switch (EnableShrinkWrapOpt) { - case cl::BOU_UNSET: - return EnableShrinkWrap && getOptLevel() != CodeGenOpt::None; - // If EnableShrinkWrap is set, it takes precedence on whatever the - // target sets. The rational is that we assume we want to test - // something related to shrink-wrapping. - case cl::BOU_TRUE: - return true; - case cl::BOU_FALSE: - return false; - } - llvm_unreachable("Invalid shrink-wrapping state"); -} - //===---------------------------------------------------------------------===// /// Register Allocation Pass Configuration //===---------------------------------------------------------------------===// Index: lib/CodeGen/ShrinkWrap.cpp =================================================================== --- lib/CodeGen/ShrinkWrap.cpp +++ lib/CodeGen/ShrinkWrap.cpp @@ -68,11 +68,16 @@ #include "llvm/Target/TargetInstrInfo.h" // To access TargetInstrInfo. #include "llvm/Target/TargetSubtargetInfo.h" +#include "llvm/Support/CommandLine.h" #define DEBUG_TYPE "shrink-wrap" using namespace llvm; +static cl::opt + EnableShrinkWrapOpt("enable-shrink-wrap", cl::Hidden, + cl::desc("enable the shrink-wrapping pass")); + STATISTIC(NumFunc, "Number of functions"); STATISTIC(NumCandidates, "Number of shrink-wrapping candidates"); STATISTIC(NumCandidatesDropped, @@ -154,6 +159,11 @@ ShrinkWrap() : MachineFunctionPass(ID) { initializeShrinkWrapPass(*PassRegistry::getPassRegistry()); } + + ShrinkWrap(std::function Ftor) : + MachineFunctionPass(ID), PredicateFtor(Ftor) { + initializeShrinkWrapPass(*PassRegistry::getPassRegistry()); + } void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesAll(); @@ -171,6 +181,15 @@ /// \brief Perform the shrink-wrapping analysis and update /// the MachineFrameInfo attached to \p MF with the results. bool runOnMachineFunction(MachineFunction &MF) override; + +private: + /// \brief Predicate function to determine if shrink wrapping should run + /// + /// This function will be run at the beginning of shrink wrapping and + /// determine whether shrink wrapping should run on the given MachineFunction + /// \param[in] MF The MachineFunction to run shrink wrapping on + /// \return true if shrink wrapping should be run, false otherwise + std::function PredicateFtor; }; } // End anonymous namespace. @@ -301,6 +320,9 @@ } bool ShrinkWrap::runOnMachineFunction(MachineFunction &MF) { + if (PredicateFtor && !PredicateFtor(MF)) + return false; + if (MF.empty()) return false; DEBUG(dbgs() << "**** Analysing " << MF.getName() << '\n'); @@ -386,3 +408,26 @@ ++NumCandidates; return false; } + +/// If EnableShrinkWrap is set run shrink wrapping on the given Machine +/// Function. Otherwise, shrink wrapping is disabled. +/// This function can be overridden in each target-specific TargetPassConfig +/// class to allow different predicate logic for each target. +bool TargetPassConfig::runShrinkWrap(const MachineFunction &Fn) const { + switch (EnableShrinkWrapOpt) { + case cl::BOU_TRUE: + return true; + case cl::BOU_UNSET: + case cl::BOU_FALSE: + return false; + } + llvm_unreachable("Invalid shrink-wrapping state"); +} + +/// Create a ShrinkWrap FunctionPass using the runShrinkWrap predicate +/// function. +FunctionPass *TargetPassConfig::createShrinkWrapPass() { + std::function Ftor = + std::bind(&TargetPassConfig::runShrinkWrap, this, std::placeholders::_1); + return new ShrinkWrap(Ftor); +}