171d5a254SDimitry Andric //===- RegisterClassInfo.cpp - Dynamic Register Class Info ----------------===//
256fe8f14SDimitry Andric //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
656fe8f14SDimitry Andric //
756fe8f14SDimitry Andric //===----------------------------------------------------------------------===//
856fe8f14SDimitry Andric //
956fe8f14SDimitry Andric // This file implements the RegisterClassInfo class which provides dynamic
105ca98fd9SDimitry Andric // information about target register classes. Callee-saved vs. caller-saved and
115ca98fd9SDimitry Andric // reserved registers depend on calling conventions and other dynamic
125ca98fd9SDimitry Andric // information, so some things cannot be determined statically.
1356fe8f14SDimitry Andric //
1456fe8f14SDimitry Andric //===----------------------------------------------------------------------===//
1556fe8f14SDimitry Andric
167ab83427SDimitry Andric #include "llvm/CodeGen/RegisterClassInfo.h"
1771d5a254SDimitry Andric #include "llvm/ADT/ArrayRef.h"
1871d5a254SDimitry Andric #include "llvm/ADT/BitVector.h"
1971d5a254SDimitry Andric #include "llvm/ADT/SmallVector.h"
20522600a2SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
21522600a2SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
22044eb2f6SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
23044eb2f6SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
2471d5a254SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
2563faed5bSDimitry Andric #include "llvm/Support/CommandLine.h"
2656fe8f14SDimitry Andric #include "llvm/Support/Debug.h"
2756fe8f14SDimitry Andric #include "llvm/Support/raw_ostream.h"
2871d5a254SDimitry Andric #include <algorithm>
2971d5a254SDimitry Andric #include <cassert>
3071d5a254SDimitry Andric #include <cstdint>
3156fe8f14SDimitry Andric
3256fe8f14SDimitry Andric using namespace llvm;
3356fe8f14SDimitry Andric
345ca98fd9SDimitry Andric #define DEBUG_TYPE "regalloc"
355ca98fd9SDimitry Andric
3663faed5bSDimitry Andric static cl::opt<unsigned>
3763faed5bSDimitry Andric StressRA("stress-regalloc", cl::Hidden, cl::init(0), cl::value_desc("N"),
3863faed5bSDimitry Andric cl::desc("Limit all regclasses to N registers"));
3963faed5bSDimitry Andric
4071d5a254SDimitry Andric RegisterClassInfo::RegisterClassInfo() = default;
4156fe8f14SDimitry Andric
runOnMachineFunction(const MachineFunction & mf)4256fe8f14SDimitry Andric void RegisterClassInfo::runOnMachineFunction(const MachineFunction &mf) {
4356fe8f14SDimitry Andric bool Update = false;
4456fe8f14SDimitry Andric MF = &mf;
4556fe8f14SDimitry Andric
46145449b1SDimitry Andric auto &STI = MF->getSubtarget();
47145449b1SDimitry Andric
4856fe8f14SDimitry Andric // Allocate new array the first time we see a new target.
49145449b1SDimitry Andric if (STI.getRegisterInfo() != TRI) {
50145449b1SDimitry Andric TRI = STI.getRegisterInfo();
5156fe8f14SDimitry Andric RegClass.reset(new RCInfo[TRI->getNumRegClasses()]);
5256fe8f14SDimitry Andric Update = true;
5356fe8f14SDimitry Andric }
5456fe8f14SDimitry Andric
55e3b55780SDimitry Andric // Test if CSRs have changed from the previous function.
56e3b55780SDimitry Andric const MachineRegisterInfo &MRI = MF->getRegInfo();
57e3b55780SDimitry Andric const MCPhysReg *CSR = MRI.getCalleeSavedRegs();
58e3b55780SDimitry Andric bool CSRChanged = true;
59e3b55780SDimitry Andric if (!Update) {
60e3b55780SDimitry Andric CSRChanged = false;
61e3b55780SDimitry Andric size_t LastSize = LastCalleeSavedRegs.size();
62e3b55780SDimitry Andric for (unsigned I = 0;; ++I) {
63e3b55780SDimitry Andric if (CSR[I] == 0) {
64e3b55780SDimitry Andric CSRChanged = I != LastSize;
65e3b55780SDimitry Andric break;
66e3b55780SDimitry Andric }
67e3b55780SDimitry Andric if (I >= LastSize) {
68e3b55780SDimitry Andric CSRChanged = true;
69e3b55780SDimitry Andric break;
70e3b55780SDimitry Andric }
71e3b55780SDimitry Andric if (CSR[I] != LastCalleeSavedRegs[I]) {
72e3b55780SDimitry Andric CSRChanged = true;
73e3b55780SDimitry Andric break;
74e3b55780SDimitry Andric }
75e3b55780SDimitry Andric }
76e3b55780SDimitry Andric }
7771d5a254SDimitry Andric
7871d5a254SDimitry Andric // Get the callee saved registers.
79e3b55780SDimitry Andric if (CSRChanged) {
80e3b55780SDimitry Andric LastCalleeSavedRegs.clear();
8171d5a254SDimitry Andric // Build a CSRAlias map. Every CSR alias saves the last
8256fe8f14SDimitry Andric // overlapping CSR.
83ac9a064cSDimitry Andric CalleeSavedAliases.assign(TRI->getNumRegUnits(), 0);
84e3b55780SDimitry Andric for (const MCPhysReg *I = CSR; *I; ++I) {
85ac9a064cSDimitry Andric for (MCRegUnit U : TRI->regunits(*I))
86ac9a064cSDimitry Andric CalleeSavedAliases[U] = *I;
87e3b55780SDimitry Andric LastCalleeSavedRegs.push_back(*I);
88e3b55780SDimitry Andric }
8971d5a254SDimitry Andric
9056fe8f14SDimitry Andric Update = true;
9156fe8f14SDimitry Andric }
9256fe8f14SDimitry Andric
93145449b1SDimitry Andric // Even if CSR list is same, we could have had a different allocation order
94145449b1SDimitry Andric // if ignoreCSRForAllocationOrder is evaluated differently.
95145449b1SDimitry Andric BitVector CSRHintsForAllocOrder(TRI->getNumRegs());
96145449b1SDimitry Andric for (const MCPhysReg *I = CSR; *I; ++I)
97145449b1SDimitry Andric for (MCRegAliasIterator AI(*I, TRI, true); AI.isValid(); ++AI)
98145449b1SDimitry Andric CSRHintsForAllocOrder[*AI] = STI.ignoreCSRForAllocationOrder(mf, *AI);
99ac9a064cSDimitry Andric if (IgnoreCSRForAllocOrder != CSRHintsForAllocOrder) {
100145449b1SDimitry Andric Update = true;
101145449b1SDimitry Andric IgnoreCSRForAllocOrder = CSRHintsForAllocOrder;
102145449b1SDimitry Andric }
103145449b1SDimitry Andric
104344a3780SDimitry Andric RegCosts = TRI->getRegisterCosts(*MF);
105344a3780SDimitry Andric
10656fe8f14SDimitry Andric // Different reserved registers?
107522600a2SDimitry Andric const BitVector &RR = MF->getRegInfo().getReservedRegs();
108ac9a064cSDimitry Andric if (RR != Reserved) {
10956fe8f14SDimitry Andric Update = true;
11056fe8f14SDimitry Andric Reserved = RR;
111522600a2SDimitry Andric }
11256fe8f14SDimitry Andric
11356fe8f14SDimitry Andric // Invalidate cached information from previous function.
114eb11fae6SDimitry Andric if (Update) {
115eb11fae6SDimitry Andric unsigned NumPSets = TRI->getNumRegPressureSets();
116eb11fae6SDimitry Andric PSetLimits.reset(new unsigned[NumPSets]);
117eb11fae6SDimitry Andric std::fill(&PSetLimits[0], &PSetLimits[NumPSets], 0);
11856fe8f14SDimitry Andric ++Tag;
11956fe8f14SDimitry Andric }
120eb11fae6SDimitry Andric }
12156fe8f14SDimitry Andric
12256fe8f14SDimitry Andric /// compute - Compute the preferred allocation order for RC with reserved
12356fe8f14SDimitry Andric /// registers filtered out. Volatile registers come first followed by CSR
12456fe8f14SDimitry Andric /// aliases ordered according to the CSR order specified by the target.
compute(const TargetRegisterClass * RC) const12556fe8f14SDimitry Andric void RegisterClassInfo::compute(const TargetRegisterClass *RC) const {
12667c32a98SDimitry Andric assert(RC && "no register class given");
12756fe8f14SDimitry Andric RCInfo &RCI = RegClass[RC->getID()];
128e6d15924SDimitry Andric auto &STI = MF->getSubtarget();
12956fe8f14SDimitry Andric
13056fe8f14SDimitry Andric // Raw register count, including all reserved regs.
13156fe8f14SDimitry Andric unsigned NumRegs = RC->getNumRegs();
13256fe8f14SDimitry Andric
13356fe8f14SDimitry Andric if (!RCI.Order)
1344a16efa3SDimitry Andric RCI.Order.reset(new MCPhysReg[NumRegs]);
13556fe8f14SDimitry Andric
13656fe8f14SDimitry Andric unsigned N = 0;
1374a16efa3SDimitry Andric SmallVector<MCPhysReg, 16> CSRAlias;
138344a3780SDimitry Andric uint8_t MinCost = uint8_t(~0u);
139344a3780SDimitry Andric uint8_t LastCost = uint8_t(~0u);
1404a16efa3SDimitry Andric unsigned LastCostChange = 0;
14156fe8f14SDimitry Andric
14256fe8f14SDimitry Andric // FIXME: Once targets reserve registers instead of removing them from the
14356fe8f14SDimitry Andric // allocation order, we can simply use begin/end here.
1444a16efa3SDimitry Andric ArrayRef<MCPhysReg> RawOrder = RC->getRawAllocationOrder(*MF);
14577fc4c14SDimitry Andric for (unsigned PhysReg : RawOrder) {
14656fe8f14SDimitry Andric // Remove reserved registers from the allocation order.
14756fe8f14SDimitry Andric if (Reserved.test(PhysReg))
14856fe8f14SDimitry Andric continue;
149344a3780SDimitry Andric uint8_t Cost = RegCosts[PhysReg];
1504a16efa3SDimitry Andric MinCost = std::min(MinCost, Cost);
1514a16efa3SDimitry Andric
152ac9a064cSDimitry Andric if (getLastCalleeSavedAlias(PhysReg) &&
153e6d15924SDimitry Andric !STI.ignoreCSRForAllocationOrder(*MF, PhysReg))
15456fe8f14SDimitry Andric // PhysReg aliases a CSR, save it for later.
15556fe8f14SDimitry Andric CSRAlias.push_back(PhysReg);
1564a16efa3SDimitry Andric else {
1574a16efa3SDimitry Andric if (Cost != LastCost)
1584a16efa3SDimitry Andric LastCostChange = N;
15956fe8f14SDimitry Andric RCI.Order[N++] = PhysReg;
1604a16efa3SDimitry Andric LastCost = Cost;
1614a16efa3SDimitry Andric }
16256fe8f14SDimitry Andric }
16356fe8f14SDimitry Andric RCI.NumRegs = N + CSRAlias.size();
16456fe8f14SDimitry Andric assert(RCI.NumRegs <= NumRegs && "Allocation order larger than regclass");
16556fe8f14SDimitry Andric
16656fe8f14SDimitry Andric // CSR aliases go after the volatile registers, preserve the target's order.
16799aabd70SDimitry Andric for (unsigned PhysReg : CSRAlias) {
168344a3780SDimitry Andric uint8_t Cost = RegCosts[PhysReg];
1694a16efa3SDimitry Andric if (Cost != LastCost)
1704a16efa3SDimitry Andric LastCostChange = N;
1714a16efa3SDimitry Andric RCI.Order[N++] = PhysReg;
1724a16efa3SDimitry Andric LastCost = Cost;
1734a16efa3SDimitry Andric }
17456fe8f14SDimitry Andric
17563faed5bSDimitry Andric // Register allocator stress test. Clip register class to N registers.
17663faed5bSDimitry Andric if (StressRA && RCI.NumRegs > StressRA)
17763faed5bSDimitry Andric RCI.NumRegs = StressRA;
17863faed5bSDimitry Andric
17930815c53SDimitry Andric // Check if RC is a proper sub-class.
1805a5ac124SDimitry Andric if (const TargetRegisterClass *Super =
1815a5ac124SDimitry Andric TRI->getLargestLegalSuperClass(RC, *MF))
18230815c53SDimitry Andric if (Super != RC && getNumAllocatableRegs(Super) > RCI.NumRegs)
18330815c53SDimitry Andric RCI.ProperSubClass = true;
18430815c53SDimitry Andric
185344a3780SDimitry Andric RCI.MinCost = MinCost;
1864a16efa3SDimitry Andric RCI.LastCostChange = LastCostChange;
1874a16efa3SDimitry Andric
188eb11fae6SDimitry Andric LLVM_DEBUG({
18967c32a98SDimitry Andric dbgs() << "AllocationOrder(" << TRI->getRegClassName(RC) << ") = [";
190411bd29eSDimitry Andric for (unsigned I = 0; I != RCI.NumRegs; ++I)
191044eb2f6SDimitry Andric dbgs() << ' ' << printReg(RCI.Order[I], TRI);
19230815c53SDimitry Andric dbgs() << (RCI.ProperSubClass ? " ] (sub-class)\n" : " ]\n");
19356fe8f14SDimitry Andric });
19456fe8f14SDimitry Andric
19556fe8f14SDimitry Andric // RCI is now up-to-date.
19656fe8f14SDimitry Andric RCI.Tag = Tag;
19756fe8f14SDimitry Andric }
19856fe8f14SDimitry Andric
199f8af5cf6SDimitry Andric /// This is not accurate because two overlapping register sets may have some
200f8af5cf6SDimitry Andric /// nonoverlapping reserved registers. However, computing the allocation order
201f8af5cf6SDimitry Andric /// for all register classes would be too expensive.
computePSetLimit(unsigned Idx) const202f8af5cf6SDimitry Andric unsigned RegisterClassInfo::computePSetLimit(unsigned Idx) const {
2035ca98fd9SDimitry Andric const TargetRegisterClass *RC = nullptr;
204f8af5cf6SDimitry Andric unsigned NumRCUnits = 0;
20571d5a254SDimitry Andric for (const TargetRegisterClass *C : TRI->regclasses()) {
20671d5a254SDimitry Andric const int *PSetID = TRI->getRegClassPressureSets(C);
207f8af5cf6SDimitry Andric for (; *PSetID != -1; ++PSetID) {
208f8af5cf6SDimitry Andric if ((unsigned)*PSetID == Idx)
209f8af5cf6SDimitry Andric break;
210f8af5cf6SDimitry Andric }
211f8af5cf6SDimitry Andric if (*PSetID == -1)
212f8af5cf6SDimitry Andric continue;
213f8af5cf6SDimitry Andric
214f8af5cf6SDimitry Andric // Found a register class that counts against this pressure set.
215f8af5cf6SDimitry Andric // For efficiency, only compute the set order for the largest set.
21671d5a254SDimitry Andric unsigned NUnits = TRI->getRegClassWeight(C).WeightLimit;
217f8af5cf6SDimitry Andric if (!RC || NUnits > NumRCUnits) {
21871d5a254SDimitry Andric RC = C;
219f8af5cf6SDimitry Andric NumRCUnits = NUnits;
220f8af5cf6SDimitry Andric }
221f8af5cf6SDimitry Andric }
222706b4fc4SDimitry Andric assert(RC && "Failed to find register class");
223f8af5cf6SDimitry Andric compute(RC);
224b60736ecSDimitry Andric unsigned NAllocatableRegs = getNumAllocatableRegs(RC);
225b60736ecSDimitry Andric unsigned RegPressureSetLimit = TRI->getRegPressureSetLimit(*MF, Idx);
226b60736ecSDimitry Andric // If all the regs are reserved, return raw RegPressureSetLimit.
227b60736ecSDimitry Andric // One example is VRSAVERC in PowerPC.
228b60736ecSDimitry Andric // Avoid returning zero, getRegPressureSetLimit(Idx) assumes computePSetLimit
229b60736ecSDimitry Andric // return non-zero value.
230b60736ecSDimitry Andric if (NAllocatableRegs == 0)
231b60736ecSDimitry Andric return RegPressureSetLimit;
232b60736ecSDimitry Andric unsigned NReserved = RC->getNumRegs() - NAllocatableRegs;
233b60736ecSDimitry Andric return RegPressureSetLimit - TRI->getRegClassWeight(RC).RegWeight * NReserved;
234f8af5cf6SDimitry Andric }
235