Index: llvm/include/llvm/CodeGen/TargetRegisterInfo.h =================================================================== --- llvm/include/llvm/CodeGen/TargetRegisterInfo.h +++ llvm/include/llvm/CodeGen/TargetRegisterInfo.h @@ -54,10 +54,12 @@ 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. Index: llvm/include/llvm/Target/Target.td =================================================================== --- llvm/include/llvm/Target/Target.td +++ llvm/include/llvm/Target/Target.td @@ -278,11 +278,14 @@ // 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 = 0; + // 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; Index: llvm/lib/CodeGen/RegAllocGreedy.cpp =================================================================== --- llvm/lib/CodeGen/RegAllocGreedy.cpp +++ llvm/lib/CodeGen/RegAllocGreedy.cpp @@ -302,7 +302,7 @@ bool ForceGlobal = !ReverseLocal && (Size / SlotIndex::InstrDist) > (2 * RegClassInfo.getNumAllocatableRegs(&RC)); - unsigned GlobalBit = 0; + unsigned GlobalBit = RC.GlobalPriority; if (Stage == RS_Assign && !ForceGlobal && !LI->empty() && LIS->intervalIsInOneMBB(*LI)) { @@ -324,6 +324,18 @@ Prio = Size; GlobalBit = 1; } + + // Priority bit layout: + // 31 RS_Assign priority + // 30 Preference priority + // 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 Index: llvm/lib/Target/PowerPC/PPCRegisterInfoMMA.td =================================================================== --- llvm/lib/Target/PowerPC/PPCRegisterInfoMMA.td +++ llvm/lib/Target/PowerPC/PPCRegisterInfoMMA.td @@ -47,13 +47,16 @@ } 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; } @@ -74,7 +77,8 @@ // 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 = 30; + let GlobalPriority = true; let Size = 512; } Index: llvm/utils/TableGen/CodeGenRegisters.h =================================================================== --- llvm/utils/TableGen/CodeGenRegisters.h +++ llvm/utils/TableGen/CodeGenRegisters.h @@ -331,6 +331,7 @@ bool Allocatable; StringRef AltOrderSelect; uint8_t AllocationPriority; + bool GlobalPriority; uint8_t TSFlags; /// Contains the combination of the lane masks of all subregisters. LaneBitmask LaneMask; Index: llvm/utils/TableGen/CodeGenRegisters.cpp =================================================================== --- llvm/utils/TableGen/CodeGenRegisters.cpp +++ llvm/utils/TableGen/CodeGenRegisters.cpp @@ -803,10 +803,12 @@ 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 (AllocationPriority < 0 || !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(TSF->getBit(I)); @@ -821,7 +823,8 @@ 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) { @@ -849,6 +852,7 @@ }); AltOrderSelect = Super.AltOrderSelect; AllocationPriority = Super.AllocationPriority; + GlobalPriority = Super.GlobalPriority; TSFlags = Super.TSFlags; GeneratePressureSet |= Super.GeneratePressureSet; Index: llvm/utils/TableGen/RegisterInfoEmitter.cpp =================================================================== --- llvm/utils/TableGen/RegisterInfoEmitter.cpp +++ llvm/utils/TableGen/RegisterInfoEmitter.cpp @@ -1425,10 +1425,11 @@ << 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 ";