forked from OSchip/llvm-project
[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:
parent
cab780a5a0
commit
99e865b618
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue