mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-09-30 04:56:49 +00:00
RegAllocGreedy: Allow target to specify register class ordering.
Specify an allocation order with a register class. This is used by register allocators with a greedy heuristic. This is usefull as it is sometimes beneficial to color more constrained classes first. Differential Revision: http://reviews.llvm.org/D8626 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@233743 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
3f1ec42ec7
commit
8e4eaabdb8
@ -207,6 +207,12 @@ class RegisterClass<string namespace, list<ValueType> regTypes, int alignment,
|
|||||||
// The function should return 0 to select the default order defined by
|
// The function should return 0 to select the default order defined by
|
||||||
// MemberList, 1 to select the first AltOrders entry and so on.
|
// MemberList, 1 to select the first AltOrders entry and so on.
|
||||||
code AltOrderSelect = [{}];
|
code AltOrderSelect = [{}];
|
||||||
|
|
||||||
|
// Specify allocation priority for register allocators using a greedy
|
||||||
|
// heuristic. Classes with high priority are assigned first. It is sometimes
|
||||||
|
// beneficial to assign registers to highly constrained classes first.
|
||||||
|
// The priority has to be in the range [0,63].
|
||||||
|
int AllocationPriority = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The memberList in a RegisterClass is a dag of set operations. TableGen
|
// The memberList in a RegisterClass is a dag of set operations. TableGen
|
||||||
|
@ -46,6 +46,9 @@ public:
|
|||||||
const uint32_t *SubClassMask;
|
const uint32_t *SubClassMask;
|
||||||
const uint16_t *SuperRegIndices;
|
const uint16_t *SuperRegIndices;
|
||||||
const unsigned LaneMask;
|
const unsigned LaneMask;
|
||||||
|
/// Classes with high priority should be assigned first by register allocators
|
||||||
|
/// with a greedy heuristic. The priority is a value in the range [0,63].
|
||||||
|
const uint8_t AllocationPriority;
|
||||||
/// Whether the class supports two (or more) disjunct subregister indices.
|
/// Whether the class supports two (or more) disjunct subregister indices.
|
||||||
const bool HasDisjunctSubRegs;
|
const bool HasDisjunctSubRegs;
|
||||||
const sc_iterator SuperClasses;
|
const sc_iterator SuperClasses;
|
||||||
|
@ -538,8 +538,9 @@ void RAGreedy::enqueue(PQueue &CurQueue, LiveInterval *LI) {
|
|||||||
// Giant live ranges fall back to the global assignment heuristic, which
|
// Giant live ranges fall back to the global assignment heuristic, which
|
||||||
// prevents excessive spilling in pathological cases.
|
// prevents excessive spilling in pathological cases.
|
||||||
bool ReverseLocal = TRI->reverseLocalAssignment();
|
bool ReverseLocal = TRI->reverseLocalAssignment();
|
||||||
|
const TargetRegisterClass &RC = *MRI->getRegClass(Reg);
|
||||||
bool ForceGlobal = !ReverseLocal &&
|
bool ForceGlobal = !ReverseLocal &&
|
||||||
(Size / SlotIndex::InstrDist) > (2 * MRI->getRegClass(Reg)->getNumRegs());
|
(Size / SlotIndex::InstrDist) > (2 * RC.getNumRegs());
|
||||||
|
|
||||||
if (ExtraRegInfo[Reg].Stage == RS_Assign && !ForceGlobal && !LI->empty() &&
|
if (ExtraRegInfo[Reg].Stage == RS_Assign && !ForceGlobal && !LI->empty() &&
|
||||||
LIS->intervalIsInOneMBB(*LI)) {
|
LIS->intervalIsInOneMBB(*LI)) {
|
||||||
@ -554,8 +555,8 @@ void RAGreedy::enqueue(PQueue &CurQueue, LiveInterval *LI) {
|
|||||||
// large blocks on targets with many physical registers.
|
// large blocks on targets with many physical registers.
|
||||||
Prio = Indexes->getZeroIndex().getInstrDistance(LI->endIndex());
|
Prio = Indexes->getZeroIndex().getInstrDistance(LI->endIndex());
|
||||||
}
|
}
|
||||||
}
|
Prio |= RC.AllocationPriority << 24;
|
||||||
else {
|
} else {
|
||||||
// Allocate global and split ranges in long->short order. Long ranges that
|
// Allocate global and split ranges in long->short order. Long ranges that
|
||||||
// don't fit should be spilled (or split) ASAP so they don't create
|
// don't fit should be spilled (or split) ASAP so they don't create
|
||||||
// interference. Mark a bit to prioritize global above local ranges.
|
// interference. Mark a bit to prioritize global above local ranges.
|
||||||
|
@ -711,6 +711,10 @@ CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank, Record *R)
|
|||||||
CopyCost = R->getValueAsInt("CopyCost");
|
CopyCost = R->getValueAsInt("CopyCost");
|
||||||
Allocatable = R->getValueAsBit("isAllocatable");
|
Allocatable = R->getValueAsBit("isAllocatable");
|
||||||
AltOrderSelect = R->getValueAsString("AltOrderSelect");
|
AltOrderSelect = R->getValueAsString("AltOrderSelect");
|
||||||
|
int AllocationPriority = R->getValueAsInt("AllocationPriority");
|
||||||
|
if (AllocationPriority < 0 || AllocationPriority > 63)
|
||||||
|
PrintFatalError(R->getLoc(), "AllocationPriority out of range [0,63]");
|
||||||
|
this->AllocationPriority = AllocationPriority;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create an inferred register class that was missing from the .td files.
|
// Create an inferred register class that was missing from the .td files.
|
||||||
|
@ -306,6 +306,7 @@ namespace llvm {
|
|||||||
int CopyCost;
|
int CopyCost;
|
||||||
bool Allocatable;
|
bool Allocatable;
|
||||||
std::string AltOrderSelect;
|
std::string AltOrderSelect;
|
||||||
|
uint8_t AllocationPriority;
|
||||||
/// Contains the combination of the lane masks of all subregisters.
|
/// Contains the combination of the lane masks of all subregisters.
|
||||||
unsigned LaneMask;
|
unsigned LaneMask;
|
||||||
/// True if there are at least 2 subregisters which do not interfere.
|
/// True if there are at least 2 subregisters which do not interfere.
|
||||||
|
@ -1287,6 +1287,7 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
|
|||||||
<< "SubClassMask,\n SuperRegIdxSeqs + "
|
<< "SubClassMask,\n SuperRegIdxSeqs + "
|
||||||
<< SuperRegIdxSeqs.get(SuperRegIdxLists[RC.EnumValue]) << ",\n "
|
<< SuperRegIdxSeqs.get(SuperRegIdxLists[RC.EnumValue]) << ",\n "
|
||||||
<< format("0x%08x,\n ", RC.LaneMask)
|
<< format("0x%08x,\n ", RC.LaneMask)
|
||||||
|
<< (unsigned)RC.AllocationPriority << ",\n "
|
||||||
<< (RC.HasDisjunctSubRegs?"true":"false")
|
<< (RC.HasDisjunctSubRegs?"true":"false")
|
||||||
<< ", /* HasDisjunctSubRegs */\n ";
|
<< ", /* HasDisjunctSubRegs */\n ";
|
||||||
if (RC.getSuperClasses().empty())
|
if (RC.getSuperClasses().empty())
|
||||||
|
Loading…
Reference in New Issue
Block a user