/// 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.
/// 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;
/// 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
cl::desc("Disable Machine LICM"));
static cl::opt<bool> DisableMachineCSE("disable-machine-cse", cl::Hidden,
cl::desc("Disable Machine Common Subexpression Elimination"));
-static cl::opt<cl::boolOrDefault>
- EnableShrinkWrapOpt("enable-shrink-wrap", cl::Hidden,
- cl::desc("enable the shrink-wrapping pass"));
static cl::opt<cl::boolOrDefault> OptimizeRegAlloc(
"optimize-regalloc", cl::Hidden,
cl::desc("Enable optimized register allocation compilation path."));
: 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();
addPostRegAlloc();
// Insert prolog/epilog code. Eliminate abstract frame index references...
- if (getEnableShrinkWrap())
- addPass(&ShrinkWrapID);
+ if (getOptLevel() != CodeGenOpt::None)
+ addPass(createShrinkWrapPass());
addPass(&PrologEpilogCodeInserterID);
/// Add passes that optimize machine instructions after register allocation.
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
//===---------------------------------------------------------------------===//
#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<cl::boolOrDefault>
+ 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,
ShrinkWrap() : MachineFunctionPass(ID) {
initializeShrinkWrapPass(*PassRegistry::getPassRegistry());
}
+
+ ShrinkWrap(std::function<bool(const MachineFunction &)> Ftor) :
+ MachineFunctionPass(ID), PredicateFtor(Ftor) {
+ initializeShrinkWrapPass(*PassRegistry::getPassRegistry());
+ }
void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.setPreservesAll();
/// \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<bool(const MachineFunction &MF)> PredicateFtor;
};
} // End anonymous namespace.
}
bool ShrinkWrap::runOnMachineFunction(MachineFunction &MF) {
- if (MF.empty())
+ if (PredicateFtor && !PredicateFtor(MF))
return false;
+
+ if (MF.empty() || skipOptnoneFunction(*MF.getFunction()))
+ return false;
+
DEBUG(dbgs() << "**** Analysing " << MF.getName() << '\n');
init(MF);
++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<bool(const MachineFunction &Fn)> Ftor =
+ std::bind(&TargetPassConfig::runShrinkWrap, this, std::placeholders::_1);
+ return new ShrinkWrap(Ftor);
+}