Rework of the new interface for shrink wrapping

Based on comments from Hal
(http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20150810/292978.html),
I've changed the interface to add a callback mechanism to the
TargetFrameLowering class to query whether the specific target
supports shrink wrapping.  By default, shrink wrapping is disabled by
default. Each target can override the default behaviour using the
TargetFrameLowering::targetSupportsShrinkWrapping() method. Shrink
wrapping can still be explicitly enabled or disabled from the command
line, using the existing -enable-shrink-wrap=<true|false> option.

Phabricator: http://reviews.llvm.org/D12293
llvm-svn: 246463
This commit is contained in:
Kit Barton 2015-08-31 18:26:45 +00:00
parent 0acbd08f3c
commit d3cc1678e8
4 changed files with 34 additions and 24 deletions

View File

@ -120,9 +120,6 @@ protected:
/// Default setting for -enable-tail-merge on this target. /// Default setting for -enable-tail-merge on this target.
bool EnableTailMerge; bool EnableTailMerge;
/// Default setting for -enable-shrink-wrap on this target.
bool EnableShrinkWrap;
public: public:
TargetPassConfig(TargetMachine *tm, PassManagerBase &pm); TargetPassConfig(TargetMachine *tm, PassManagerBase &pm);
// Dummy constructor. // Dummy constructor.

View File

@ -141,6 +141,11 @@ public:
return false; return false;
} }
/// Returns true if the target will correctly handle shrink wrapping.
virtual bool enableShrinkWrapping(const MachineFunction &MF) const {
return false;
}
/// emitProlog/emitEpilog - These methods insert prolog and epilog code into /// emitProlog/emitEpilog - These methods insert prolog and epilog code into
/// the function. /// the function.
virtual void emitPrologue(MachineFunction &MF, virtual void emitPrologue(MachineFunction &MF,

View File

@ -56,9 +56,6 @@ static cl::opt<bool> DisableMachineLICM("disable-machine-licm", cl::Hidden,
cl::desc("Disable Machine LICM")); cl::desc("Disable Machine LICM"));
static cl::opt<bool> DisableMachineCSE("disable-machine-cse", cl::Hidden, static cl::opt<bool> DisableMachineCSE("disable-machine-cse", cl::Hidden,
cl::desc("Disable Machine Common Subexpression Elimination")); 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( static cl::opt<cl::boolOrDefault> OptimizeRegAlloc(
"optimize-regalloc", cl::Hidden, "optimize-regalloc", cl::Hidden,
cl::desc("Enable optimized register allocation compilation path.")); cl::desc("Enable optimized register allocation compilation path."));
@ -221,7 +218,7 @@ TargetPassConfig::TargetPassConfig(TargetMachine *tm, PassManagerBase &pm)
: ImmutablePass(ID), PM(&pm), StartBefore(nullptr), StartAfter(nullptr), : ImmutablePass(ID), PM(&pm), StartBefore(nullptr), StartAfter(nullptr),
StopAfter(nullptr), Started(true), Stopped(false), StopAfter(nullptr), Started(true), Stopped(false),
AddingMachinePasses(false), TM(tm), Impl(nullptr), Initialized(false), AddingMachinePasses(false), TM(tm), Impl(nullptr), Initialized(false),
DisableVerify(false), EnableTailMerge(true), EnableShrinkWrap(false) { DisableVerify(false), EnableTailMerge(true) {
Impl = new PassConfigImpl(); Impl = new PassConfigImpl();
@ -543,8 +540,9 @@ void TargetPassConfig::addMachinePasses() {
addPostRegAlloc(); addPostRegAlloc();
// Insert prolog/epilog code. Eliminate abstract frame index references... // Insert prolog/epilog code. Eliminate abstract frame index references...
if (getEnableShrinkWrap()) if (getOptLevel() != CodeGenOpt::None)
addPass(&ShrinkWrapID); addPass(&ShrinkWrapID);
addPass(&PrologEpilogCodeInserterID); addPass(&PrologEpilogCodeInserterID);
/// Add passes that optimize machine instructions after register allocation. /// Add passes that optimize machine instructions after register allocation.
@ -623,21 +621,6 @@ void TargetPassConfig::addMachineSSAOptimization() {
addPass(&DeadMachineInstructionElimID); 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 /// Register Allocation Pass Configuration
//===---------------------------------------------------------------------===// //===---------------------------------------------------------------------===//

View File

@ -78,6 +78,10 @@ STATISTIC(NumCandidates, "Number of shrink-wrapping candidates");
STATISTIC(NumCandidatesDropped, STATISTIC(NumCandidatesDropped,
"Number of shrink-wrapping candidates dropped because of frequency"); "Number of shrink-wrapping candidates dropped because of frequency");
static cl::opt<cl::boolOrDefault>
EnableShrinkWrapOpt("enable-shrink-wrap", cl::Hidden,
cl::desc("enable the shrink-wrapping pass"));
namespace { namespace {
/// \brief Class to determine where the safe point to insert the /// \brief Class to determine where the safe point to insert the
/// prologue and epilogue are. /// prologue and epilogue are.
@ -148,6 +152,9 @@ class ShrinkWrap : public MachineFunctionPass {
/// shrink-wrapping. /// shrink-wrapping.
bool ArePointsInteresting() const { return Save != Entry && Save && Restore; } bool ArePointsInteresting() const { return Save != Entry && Save && Restore; }
/// \brief Check if shrink wrapping is enabled for this target and function.
static bool isShrinkWrapEnabled(const MachineFunction &MF);
public: public:
static char ID; static char ID;
@ -319,8 +326,9 @@ void ShrinkWrap::updateSaveRestorePoints(MachineBasicBlock &MBB) {
} }
bool ShrinkWrap::runOnMachineFunction(MachineFunction &MF) { bool ShrinkWrap::runOnMachineFunction(MachineFunction &MF) {
if (MF.empty()) if (MF.empty() || !isShrinkWrapEnabled(MF))
return false; return false;
DEBUG(dbgs() << "**** Analysing " << MF.getName() << '\n'); DEBUG(dbgs() << "**** Analysing " << MF.getName() << '\n');
init(MF); init(MF);
@ -404,3 +412,20 @@ bool ShrinkWrap::runOnMachineFunction(MachineFunction &MF) {
++NumCandidates; ++NumCandidates;
return false; return false;
} }
bool ShrinkWrap::isShrinkWrapEnabled(const MachineFunction &MF) {
const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
switch (EnableShrinkWrapOpt) {
case cl::BOU_UNSET:
return TFI->enableShrinkWrapping(MF);
// 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");
}