[TargetRegisterInfo] Add a couple of target hooks for the greedy register allocator

Before this patch, the last chance recoloring and deferred spilling
techniques were solely controled by command line options.
This patch adds target hooks for these two techniques so that it
is easier for backend writers to override the default behavior.

The default behavior of the hooks preserves the default values of
the related command line options.

NFC
This commit is contained in:
Quentin Colombet 2020-09-17 14:47:12 -07:00
parent cab780a5a0
commit 99e865b618
2 changed files with 36 additions and 1 deletions

View File

@ -977,6 +977,36 @@ public:
virtual bool shouldRegionSplitForVirtReg(const MachineFunction &MF,
const LiveInterval &VirtReg) const;
/// Last chance recoloring has a high compile time cost especially for
/// targets with a lot of registers.
/// This method is used to decide whether or not \p VirtReg should
/// go through this expensive heuristic.
/// When this target hook is hit, by returning false, there is a high
/// chance that the register allocation will fail altogether (usually with
/// ran out of registers).
/// That said, this error usually points to another problem in the
/// optimization pipeline.
virtual bool
shouldUseLastChanceRecoloringForVirtReg(const MachineFunction &MF,
const LiveInterval &VirtReg) const {
return true;
}
/// Deferred spilling delais the spill insertion of a virtual register
/// after every other allocations. By deferring the spilling, it is
/// sometimes possible to eliminate that spilling altogether because
/// something else could have been eliminated, thus leaving some space
/// for the virtual register.
/// However, this comes with a compile time impact because it adds one
/// more stage to the greedy register allocator.
/// This method is used to decide whether \p VirtReg should use the deferred
/// spilling stage instead of being spilled right away.
virtual bool
shouldUseDeferredSpillingForVirtReg(const MachineFunction &MF,
const LiveInterval &VirtReg) const {
return false;
}
//===--------------------------------------------------------------------===//
/// Debug information queries.

View File

@ -2590,6 +2590,9 @@ unsigned RAGreedy::tryLastChanceRecoloring(LiveInterval &VirtReg,
SmallVectorImpl<Register> &NewVRegs,
SmallVirtRegSet &FixedRegisters,
unsigned Depth) {
if (!TRI->shouldUseLastChanceRecoloringForVirtReg(*MF, VirtReg))
return ~0u;
LLVM_DEBUG(dbgs() << "Try last chance recoloring for " << VirtReg << '\n');
// Ranges must be Done.
assert((getStage(VirtReg) >= RS_Done || !VirtReg.isSpillable()) &&
@ -3096,7 +3099,9 @@ Register RAGreedy::selectOrSplitImpl(LiveInterval &VirtReg,
Depth);
// Finally spill VirtReg itself.
if (EnableDeferredSpilling && getStage(VirtReg) < RS_Memory) {
if ((EnableDeferredSpilling ||
TRI->shouldUseDeferredSpillingForVirtReg(*MF, VirtReg)) &&
getStage(VirtReg) < RS_Memory) {
// TODO: This is experimental and in particular, we do not model
// the live range splitting done by spilling correctly.
// We would need a deep integration with the spiller to do the