xref: /aosp_15_r20/external/llvm/lib/CodeGen/RegisterClassInfo.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- RegisterClassInfo.cpp - Dynamic Register Class Info ---------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file implements the RegisterClassInfo class which provides dynamic
11*9880d681SAndroid Build Coastguard Worker // information about target register classes. Callee-saved vs. caller-saved and
12*9880d681SAndroid Build Coastguard Worker // reserved registers depend on calling conventions and other dynamic
13*9880d681SAndroid Build Coastguard Worker // information, so some things cannot be determined statically.
14*9880d681SAndroid Build Coastguard Worker //
15*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
16*9880d681SAndroid Build Coastguard Worker 
17*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/RegisterClassInfo.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunction.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineRegisterInfo.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/CommandLine.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
23*9880d681SAndroid Build Coastguard Worker 
24*9880d681SAndroid Build Coastguard Worker using namespace llvm;
25*9880d681SAndroid Build Coastguard Worker 
26*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "regalloc"
27*9880d681SAndroid Build Coastguard Worker 
28*9880d681SAndroid Build Coastguard Worker static cl::opt<unsigned>
29*9880d681SAndroid Build Coastguard Worker StressRA("stress-regalloc", cl::Hidden, cl::init(0), cl::value_desc("N"),
30*9880d681SAndroid Build Coastguard Worker          cl::desc("Limit all regclasses to N registers"));
31*9880d681SAndroid Build Coastguard Worker 
RegisterClassInfo()32*9880d681SAndroid Build Coastguard Worker RegisterClassInfo::RegisterClassInfo()
33*9880d681SAndroid Build Coastguard Worker   : Tag(0), MF(nullptr), TRI(nullptr), CalleeSaved(nullptr) {}
34*9880d681SAndroid Build Coastguard Worker 
runOnMachineFunction(const MachineFunction & mf)35*9880d681SAndroid Build Coastguard Worker void RegisterClassInfo::runOnMachineFunction(const MachineFunction &mf) {
36*9880d681SAndroid Build Coastguard Worker   bool Update = false;
37*9880d681SAndroid Build Coastguard Worker   MF = &mf;
38*9880d681SAndroid Build Coastguard Worker 
39*9880d681SAndroid Build Coastguard Worker   // Allocate new array the first time we see a new target.
40*9880d681SAndroid Build Coastguard Worker   if (MF->getSubtarget().getRegisterInfo() != TRI) {
41*9880d681SAndroid Build Coastguard Worker     TRI = MF->getSubtarget().getRegisterInfo();
42*9880d681SAndroid Build Coastguard Worker     RegClass.reset(new RCInfo[TRI->getNumRegClasses()]);
43*9880d681SAndroid Build Coastguard Worker     unsigned NumPSets = TRI->getNumRegPressureSets();
44*9880d681SAndroid Build Coastguard Worker     PSetLimits.reset(new unsigned[NumPSets]);
45*9880d681SAndroid Build Coastguard Worker     std::fill(&PSetLimits[0], &PSetLimits[NumPSets], 0);
46*9880d681SAndroid Build Coastguard Worker     Update = true;
47*9880d681SAndroid Build Coastguard Worker   }
48*9880d681SAndroid Build Coastguard Worker 
49*9880d681SAndroid Build Coastguard Worker   // Does this MF have different CSRs?
50*9880d681SAndroid Build Coastguard Worker   assert(TRI && "no register info set");
51*9880d681SAndroid Build Coastguard Worker   const MCPhysReg *CSR = TRI->getCalleeSavedRegs(MF);
52*9880d681SAndroid Build Coastguard Worker   if (Update || CSR != CalleeSaved) {
53*9880d681SAndroid Build Coastguard Worker     // Build a CSRNum map. Every CSR alias gets an entry pointing to the last
54*9880d681SAndroid Build Coastguard Worker     // overlapping CSR.
55*9880d681SAndroid Build Coastguard Worker     CSRNum.clear();
56*9880d681SAndroid Build Coastguard Worker     CSRNum.resize(TRI->getNumRegs(), 0);
57*9880d681SAndroid Build Coastguard Worker     for (unsigned N = 0; unsigned Reg = CSR[N]; ++N)
58*9880d681SAndroid Build Coastguard Worker       for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI)
59*9880d681SAndroid Build Coastguard Worker         CSRNum[*AI] = N + 1; // 0 means no CSR, 1 means CalleeSaved[0], ...
60*9880d681SAndroid Build Coastguard Worker     Update = true;
61*9880d681SAndroid Build Coastguard Worker   }
62*9880d681SAndroid Build Coastguard Worker   CalleeSaved = CSR;
63*9880d681SAndroid Build Coastguard Worker 
64*9880d681SAndroid Build Coastguard Worker   // Different reserved registers?
65*9880d681SAndroid Build Coastguard Worker   const BitVector &RR = MF->getRegInfo().getReservedRegs();
66*9880d681SAndroid Build Coastguard Worker   if (Reserved.size() != RR.size() || RR != Reserved) {
67*9880d681SAndroid Build Coastguard Worker     Update = true;
68*9880d681SAndroid Build Coastguard Worker     Reserved = RR;
69*9880d681SAndroid Build Coastguard Worker   }
70*9880d681SAndroid Build Coastguard Worker 
71*9880d681SAndroid Build Coastguard Worker   // Invalidate cached information from previous function.
72*9880d681SAndroid Build Coastguard Worker   if (Update)
73*9880d681SAndroid Build Coastguard Worker     ++Tag;
74*9880d681SAndroid Build Coastguard Worker }
75*9880d681SAndroid Build Coastguard Worker 
76*9880d681SAndroid Build Coastguard Worker /// compute - Compute the preferred allocation order for RC with reserved
77*9880d681SAndroid Build Coastguard Worker /// registers filtered out. Volatile registers come first followed by CSR
78*9880d681SAndroid Build Coastguard Worker /// aliases ordered according to the CSR order specified by the target.
compute(const TargetRegisterClass * RC) const79*9880d681SAndroid Build Coastguard Worker void RegisterClassInfo::compute(const TargetRegisterClass *RC) const {
80*9880d681SAndroid Build Coastguard Worker   assert(RC && "no register class given");
81*9880d681SAndroid Build Coastguard Worker   RCInfo &RCI = RegClass[RC->getID()];
82*9880d681SAndroid Build Coastguard Worker 
83*9880d681SAndroid Build Coastguard Worker   // Raw register count, including all reserved regs.
84*9880d681SAndroid Build Coastguard Worker   unsigned NumRegs = RC->getNumRegs();
85*9880d681SAndroid Build Coastguard Worker 
86*9880d681SAndroid Build Coastguard Worker   if (!RCI.Order)
87*9880d681SAndroid Build Coastguard Worker     RCI.Order.reset(new MCPhysReg[NumRegs]);
88*9880d681SAndroid Build Coastguard Worker 
89*9880d681SAndroid Build Coastguard Worker   unsigned N = 0;
90*9880d681SAndroid Build Coastguard Worker   SmallVector<MCPhysReg, 16> CSRAlias;
91*9880d681SAndroid Build Coastguard Worker   unsigned MinCost = 0xff;
92*9880d681SAndroid Build Coastguard Worker   unsigned LastCost = ~0u;
93*9880d681SAndroid Build Coastguard Worker   unsigned LastCostChange = 0;
94*9880d681SAndroid Build Coastguard Worker 
95*9880d681SAndroid Build Coastguard Worker   // FIXME: Once targets reserve registers instead of removing them from the
96*9880d681SAndroid Build Coastguard Worker   // allocation order, we can simply use begin/end here.
97*9880d681SAndroid Build Coastguard Worker   ArrayRef<MCPhysReg> RawOrder = RC->getRawAllocationOrder(*MF);
98*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0; i != RawOrder.size(); ++i) {
99*9880d681SAndroid Build Coastguard Worker     unsigned PhysReg = RawOrder[i];
100*9880d681SAndroid Build Coastguard Worker     // Remove reserved registers from the allocation order.
101*9880d681SAndroid Build Coastguard Worker     if (Reserved.test(PhysReg))
102*9880d681SAndroid Build Coastguard Worker       continue;
103*9880d681SAndroid Build Coastguard Worker     unsigned Cost = TRI->getCostPerUse(PhysReg);
104*9880d681SAndroid Build Coastguard Worker     MinCost = std::min(MinCost, Cost);
105*9880d681SAndroid Build Coastguard Worker 
106*9880d681SAndroid Build Coastguard Worker     if (CSRNum[PhysReg])
107*9880d681SAndroid Build Coastguard Worker       // PhysReg aliases a CSR, save it for later.
108*9880d681SAndroid Build Coastguard Worker       CSRAlias.push_back(PhysReg);
109*9880d681SAndroid Build Coastguard Worker     else {
110*9880d681SAndroid Build Coastguard Worker       if (Cost != LastCost)
111*9880d681SAndroid Build Coastguard Worker         LastCostChange = N;
112*9880d681SAndroid Build Coastguard Worker       RCI.Order[N++] = PhysReg;
113*9880d681SAndroid Build Coastguard Worker       LastCost = Cost;
114*9880d681SAndroid Build Coastguard Worker     }
115*9880d681SAndroid Build Coastguard Worker   }
116*9880d681SAndroid Build Coastguard Worker   RCI.NumRegs = N + CSRAlias.size();
117*9880d681SAndroid Build Coastguard Worker   assert (RCI.NumRegs <= NumRegs && "Allocation order larger than regclass");
118*9880d681SAndroid Build Coastguard Worker 
119*9880d681SAndroid Build Coastguard Worker   // CSR aliases go after the volatile registers, preserve the target's order.
120*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, e = CSRAlias.size(); i != e; ++i) {
121*9880d681SAndroid Build Coastguard Worker     unsigned PhysReg = CSRAlias[i];
122*9880d681SAndroid Build Coastguard Worker     unsigned Cost = TRI->getCostPerUse(PhysReg);
123*9880d681SAndroid Build Coastguard Worker     if (Cost != LastCost)
124*9880d681SAndroid Build Coastguard Worker       LastCostChange = N;
125*9880d681SAndroid Build Coastguard Worker     RCI.Order[N++] = PhysReg;
126*9880d681SAndroid Build Coastguard Worker     LastCost = Cost;
127*9880d681SAndroid Build Coastguard Worker   }
128*9880d681SAndroid Build Coastguard Worker 
129*9880d681SAndroid Build Coastguard Worker   // Register allocator stress test.  Clip register class to N registers.
130*9880d681SAndroid Build Coastguard Worker   if (StressRA && RCI.NumRegs > StressRA)
131*9880d681SAndroid Build Coastguard Worker     RCI.NumRegs = StressRA;
132*9880d681SAndroid Build Coastguard Worker 
133*9880d681SAndroid Build Coastguard Worker   // Check if RC is a proper sub-class.
134*9880d681SAndroid Build Coastguard Worker   if (const TargetRegisterClass *Super =
135*9880d681SAndroid Build Coastguard Worker           TRI->getLargestLegalSuperClass(RC, *MF))
136*9880d681SAndroid Build Coastguard Worker     if (Super != RC && getNumAllocatableRegs(Super) > RCI.NumRegs)
137*9880d681SAndroid Build Coastguard Worker       RCI.ProperSubClass = true;
138*9880d681SAndroid Build Coastguard Worker 
139*9880d681SAndroid Build Coastguard Worker   RCI.MinCost = uint8_t(MinCost);
140*9880d681SAndroid Build Coastguard Worker   RCI.LastCostChange = LastCostChange;
141*9880d681SAndroid Build Coastguard Worker 
142*9880d681SAndroid Build Coastguard Worker   DEBUG({
143*9880d681SAndroid Build Coastguard Worker     dbgs() << "AllocationOrder(" << TRI->getRegClassName(RC) << ") = [";
144*9880d681SAndroid Build Coastguard Worker     for (unsigned I = 0; I != RCI.NumRegs; ++I)
145*9880d681SAndroid Build Coastguard Worker       dbgs() << ' ' << PrintReg(RCI.Order[I], TRI);
146*9880d681SAndroid Build Coastguard Worker     dbgs() << (RCI.ProperSubClass ? " ] (sub-class)\n" : " ]\n");
147*9880d681SAndroid Build Coastguard Worker   });
148*9880d681SAndroid Build Coastguard Worker 
149*9880d681SAndroid Build Coastguard Worker   // RCI is now up-to-date.
150*9880d681SAndroid Build Coastguard Worker   RCI.Tag = Tag;
151*9880d681SAndroid Build Coastguard Worker }
152*9880d681SAndroid Build Coastguard Worker 
153*9880d681SAndroid Build Coastguard Worker /// This is not accurate because two overlapping register sets may have some
154*9880d681SAndroid Build Coastguard Worker /// nonoverlapping reserved registers. However, computing the allocation order
155*9880d681SAndroid Build Coastguard Worker /// for all register classes would be too expensive.
computePSetLimit(unsigned Idx) const156*9880d681SAndroid Build Coastguard Worker unsigned RegisterClassInfo::computePSetLimit(unsigned Idx) const {
157*9880d681SAndroid Build Coastguard Worker   const TargetRegisterClass *RC = nullptr;
158*9880d681SAndroid Build Coastguard Worker   unsigned NumRCUnits = 0;
159*9880d681SAndroid Build Coastguard Worker   for (TargetRegisterInfo::regclass_iterator
160*9880d681SAndroid Build Coastguard Worker          RI = TRI->regclass_begin(), RE = TRI->regclass_end(); RI != RE; ++RI) {
161*9880d681SAndroid Build Coastguard Worker     const int *PSetID = TRI->getRegClassPressureSets(*RI);
162*9880d681SAndroid Build Coastguard Worker     for (; *PSetID != -1; ++PSetID) {
163*9880d681SAndroid Build Coastguard Worker       if ((unsigned)*PSetID == Idx)
164*9880d681SAndroid Build Coastguard Worker         break;
165*9880d681SAndroid Build Coastguard Worker     }
166*9880d681SAndroid Build Coastguard Worker     if (*PSetID == -1)
167*9880d681SAndroid Build Coastguard Worker       continue;
168*9880d681SAndroid Build Coastguard Worker 
169*9880d681SAndroid Build Coastguard Worker     // Found a register class that counts against this pressure set.
170*9880d681SAndroid Build Coastguard Worker     // For efficiency, only compute the set order for the largest set.
171*9880d681SAndroid Build Coastguard Worker     unsigned NUnits = TRI->getRegClassWeight(*RI).WeightLimit;
172*9880d681SAndroid Build Coastguard Worker     if (!RC || NUnits > NumRCUnits) {
173*9880d681SAndroid Build Coastguard Worker       RC = *RI;
174*9880d681SAndroid Build Coastguard Worker       NumRCUnits = NUnits;
175*9880d681SAndroid Build Coastguard Worker     }
176*9880d681SAndroid Build Coastguard Worker   }
177*9880d681SAndroid Build Coastguard Worker   compute(RC);
178*9880d681SAndroid Build Coastguard Worker   unsigned NReserved = RC->getNumRegs() - getNumAllocatableRegs(RC);
179*9880d681SAndroid Build Coastguard Worker   return TRI->getRegPressureSetLimit(*MF, Idx) -
180*9880d681SAndroid Build Coastguard Worker          TRI->getRegClassWeight(RC).RegWeight * NReserved;
181*9880d681SAndroid Build Coastguard Worker }
182