const uint16_t *SuperRegIndices;
const LaneBitmask LaneMask;
/// Classes with a higher priority value are assigned first by register
- /// allocators using a greedy heuristic. The value is in the range [0,63].
- /// Values >= 32 should be used with care since they may overlap with other
- /// fields in the allocator's priority heuristics.
+ /// allocators using a greedy heuristic. The value is in the range [0,31].
const uint8_t AllocationPriority;
+
+ // Change allocation priority heuristic used by greedy.
+ const bool GlobalPriority;
+
/// Configurable target specific flags.
const uint8_t TSFlags;
/// Whether the class supports two (or more) disjunct subregister indices.
// Specify allocation priority for register allocators using a greedy
// heuristic. Classes with higher priority values are assigned first. This is
// useful as it is sometimes beneficial to assign registers to highly
- // constrained classes first. The value has to be in the range [0,63].
- // Values >= 32 should be used with care since they may overlap with other
- // fields in the allocator's priority heuristics.
+ // constrained classes first. The value has to be in the range [0,31].
int AllocationPriority = 0;
+ // Force register class to use greedy's global heuristic for all
+ // registers in this class. This should more aggressively try to
+ // avoid spilling in pathological cases.
+ bit GlobalPriority = false;
+
// Generate register pressure set for this register class and any class
// synthesized from it. Set to 0 to inhibit unneeded pressure sets.
bit GeneratePressureSet = true;
// Giant live ranges fall back to the global assignment heuristic, which
// prevents excessive spilling in pathological cases.
const TargetRegisterClass &RC = *MRI->getRegClass(Reg);
- bool ForceGlobal = !ReverseLocalAssignment &&
- (Size / SlotIndex::InstrDist) >
- (2 * RegClassInfo.getNumAllocatableRegs(&RC));
+ bool ForceGlobal = RC.GlobalPriority ||
+ (!ReverseLocalAssignment &&
+ (Size / SlotIndex::InstrDist) >
+ (2 * RegClassInfo.getNumAllocatableRegs(&RC)));
unsigned GlobalBit = 0;
if (Stage == RS_Assign && !ForceGlobal && !LI.empty() &&
Prio = Size;
GlobalBit = 1;
}
+
+ // Priority bit layout:
+ // 31 RS_Assign priority
+ // 30 Preference priority
+ // if (RegClassPriorityTrumpsGlobalness)
+ // 29-25 AllocPriority
+ // 24 GlobalBit
+ // else
+ // 29 Global bit
+ // 28-24 AllocPriority
+ // 0-23 Size/Instr distance
+
+ // Clamp the size to fit with the priority masking scheme
+ Prio = std::min(Prio, (unsigned)maxUIntN(24));
+ assert(isUInt<5>(RC.AllocationPriority) && "allocation priority overflow");
+
if (RegClassPriorityTrumpsGlobalness)
Prio |= RC.AllocationPriority << 25 | GlobalBit << 24;
else
}
def ACCRC : RegisterClass<"PPC", [v512i1], 128, (add ACC0, ACC1, ACC2, ACC3,
ACC4, ACC5, ACC6, ACC7)> {
- // The AllocationPriority is in the range [0, 63]. Assigned the ACC registers
+ // The AllocationPriority is in the range [0, 31]. Assigned the ACC registers
// the highest possible priority in this range to force the register allocator
// to assign these registers first. This is done because the ACC registers
// must represent 4 advacent vector registers. For example ACC1 must be
- // VS4 - VS7. The value here must be at least 32 as we want to allocate
- // these registers even before we allocate global ranges.
- let AllocationPriority = 63;
+ // VS4 - VS7.
+ let AllocationPriority = 31;
+
+ // We want to allocate these registers even before we allocate
+ // global ranges.
+ let GlobalPriority = true;
let Size = 512;
}
// least 32 as we want to allocate these registers before we allocate other
// global ranges. The value must be less than the AllocationPriority of the
// ACC registers.
- let AllocationPriority = 36;
+ let AllocationPriority = 4;
+ let GlobalPriority = true;
let Size = 512;
}
Allocatable = R->getValueAsBit("isAllocatable");
AltOrderSelect = R->getValueAsString("AltOrderSelect");
int AllocationPriority = R->getValueAsInt("AllocationPriority");
- if (AllocationPriority < 0 || AllocationPriority > 63)
- PrintFatalError(R->getLoc(), "AllocationPriority out of range [0,63]");
+ if (!isUInt<5>(AllocationPriority))
+ PrintFatalError(R->getLoc(), "AllocationPriority out of range [0,31]");
this->AllocationPriority = AllocationPriority;
+ GlobalPriority = R->getValueAsBit("GlobalPriority");
+
BitsInit *TSF = R->getValueAsBitsInit("TSFlags");
for (unsigned I = 0, E = TSF->getNumBits(); I != E; ++I) {
BitInit *Bit = cast<BitInit>(TSF->getBit(I));
StringRef Name, Key Props)
: Members(*Props.Members), TheDef(nullptr), Name(std::string(Name)),
TopoSigs(RegBank.getNumTopoSigs()), EnumValue(-1), RSI(Props.RSI),
- CopyCost(0), Allocatable(true), AllocationPriority(0), TSFlags(0) {
+ CopyCost(0), Allocatable(true), AllocationPriority(0),
+ GlobalPriority(false), TSFlags(0) {
Artificial = true;
GeneratePressureSet = false;
for (const auto R : Members) {
});
AltOrderSelect = Super.AltOrderSelect;
AllocationPriority = Super.AllocationPriority;
+ GlobalPriority = Super.GlobalPriority;
TSFlags = Super.TSFlags;
GeneratePressureSet |= Super.GeneratePressureSet;
bool Allocatable;
StringRef AltOrderSelect;
uint8_t AllocationPriority;
+ bool GlobalPriority;
uint8_t TSFlags;
/// Contains the combination of the lane masks of all subregisters.
LaneBitmask LaneMask;
<< SuperRegIdxSeqs.get(SuperRegIdxLists[RC.EnumValue]) << ",\n ";
printMask(OS, RC.LaneMask);
OS << ",\n " << (unsigned)RC.AllocationPriority << ",\n "
+ << (RC.GlobalPriority ? "true" : "false") << ",\n "
<< format("0x%02x", RC.TSFlags) << ", /* TSFlags */\n "
- << (RC.HasDisjunctSubRegs?"true":"false")
+ << (RC.HasDisjunctSubRegs ? "true" : "false")
<< ", /* HasDisjunctSubRegs */\n "
- << (RC.CoveredBySubRegs?"true":"false")
+ << (RC.CoveredBySubRegs ? "true" : "false")
<< ", /* CoveredBySubRegs */\n ";
if (RC.getSuperClasses().empty())
OS << "NullRegClasses,\n ";