Skip to content

Commit 99e865b

Browse files
author
Quentin Colombet
committed
[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
1 parent cab780a commit 99e865b

File tree

2 files changed

+36
-1
lines changed

2 files changed

+36
-1
lines changed

llvm/include/llvm/CodeGen/TargetRegisterInfo.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -977,6 +977,36 @@ class TargetRegisterInfo : public MCRegisterInfo {
977977
virtual bool shouldRegionSplitForVirtReg(const MachineFunction &MF,
978978
const LiveInterval &VirtReg) const;
979979

980+
/// Last chance recoloring has a high compile time cost especially for
981+
/// targets with a lot of registers.
982+
/// This method is used to decide whether or not \p VirtReg should
983+
/// go through this expensive heuristic.
984+
/// When this target hook is hit, by returning false, there is a high
985+
/// chance that the register allocation will fail altogether (usually with
986+
/// ran out of registers).
987+
/// That said, this error usually points to another problem in the
988+
/// optimization pipeline.
989+
virtual bool
990+
shouldUseLastChanceRecoloringForVirtReg(const MachineFunction &MF,
991+
const LiveInterval &VirtReg) const {
992+
return true;
993+
}
994+
995+
/// Deferred spilling delais the spill insertion of a virtual register
996+
/// after every other allocations. By deferring the spilling, it is
997+
/// sometimes possible to eliminate that spilling altogether because
998+
/// something else could have been eliminated, thus leaving some space
999+
/// for the virtual register.
1000+
/// However, this comes with a compile time impact because it adds one
1001+
/// more stage to the greedy register allocator.
1002+
/// This method is used to decide whether \p VirtReg should use the deferred
1003+
/// spilling stage instead of being spilled right away.
1004+
virtual bool
1005+
shouldUseDeferredSpillingForVirtReg(const MachineFunction &MF,
1006+
const LiveInterval &VirtReg) const {
1007+
return false;
1008+
}
1009+
9801010
//===--------------------------------------------------------------------===//
9811011
/// Debug information queries.
9821012

llvm/lib/CodeGen/RegAllocGreedy.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2590,6 +2590,9 @@ unsigned RAGreedy::tryLastChanceRecoloring(LiveInterval &VirtReg,
25902590
SmallVectorImpl<Register> &NewVRegs,
25912591
SmallVirtRegSet &FixedRegisters,
25922592
unsigned Depth) {
2593+
if (!TRI->shouldUseLastChanceRecoloringForVirtReg(*MF, VirtReg))
2594+
return ~0u;
2595+
25932596
LLVM_DEBUG(dbgs() << "Try last chance recoloring for " << VirtReg << '\n');
25942597
// Ranges must be Done.
25952598
assert((getStage(VirtReg) >= RS_Done || !VirtReg.isSpillable()) &&
@@ -3096,7 +3099,9 @@ Register RAGreedy::selectOrSplitImpl(LiveInterval &VirtReg,
30963099
Depth);
30973100

30983101
// Finally spill VirtReg itself.
3099-
if (EnableDeferredSpilling && getStage(VirtReg) < RS_Memory) {
3102+
if ((EnableDeferredSpilling ||
3103+
TRI->shouldUseDeferredSpillingForVirtReg(*MF, VirtReg)) &&
3104+
getStage(VirtReg) < RS_Memory) {
31003105
// TODO: This is experimental and in particular, we do not model
31013106
// the live range splitting done by spilling correctly.
31023107
// We would need a deep integration with the spiller to do the

0 commit comments

Comments
 (0)