1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | #include "llvm/CodeGen/RegisterClassInfo.h" |
17 | #include "llvm/ADT/ArrayRef.h" |
18 | #include "llvm/ADT/BitVector.h" |
19 | #include "llvm/ADT/SmallVector.h" |
20 | #include "llvm/CodeGen/MachineFunction.h" |
21 | #include "llvm/CodeGen/MachineRegisterInfo.h" |
22 | #include "llvm/CodeGen/TargetFrameLowering.h" |
23 | #include "llvm/CodeGen/TargetRegisterInfo.h" |
24 | #include "llvm/CodeGen/TargetSubtargetInfo.h" |
25 | #include "llvm/MC/MCRegisterInfo.h" |
26 | #include "llvm/Support/CommandLine.h" |
27 | #include "llvm/Support/Debug.h" |
28 | #include "llvm/Support/raw_ostream.h" |
29 | #include <algorithm> |
30 | #include <cassert> |
31 | #include <cstdint> |
32 | |
33 | using namespace llvm; |
34 | |
35 | #define DEBUG_TYPE "regalloc" |
36 | |
37 | static cl::opt<unsigned> |
38 | StressRA("stress-regalloc", cl::Hidden, cl::init(0), cl::value_desc("N"), |
39 | cl::desc("Limit all regclasses to N registers")); |
40 | |
41 | RegisterClassInfo::RegisterClassInfo() = default; |
42 | |
43 | void RegisterClassInfo::runOnMachineFunction(const MachineFunction &mf) { |
44 | bool Update = false; |
45 | MF = &mf; |
46 | |
47 | |
48 | if (MF->getSubtarget().getRegisterInfo() != TRI) { |
49 | TRI = MF->getSubtarget().getRegisterInfo(); |
50 | RegClass.reset(new RCInfo[TRI->getNumRegClasses()]); |
51 | Update = true; |
52 | } |
53 | |
54 | |
55 | assert(TRI && "no register info set"); |
56 | |
57 | |
58 | const MCPhysReg *CSR = MF->getRegInfo().getCalleeSavedRegs(); |
59 | if (Update || CSR != CalleeSavedRegs) { |
60 | |
61 | |
62 | CalleeSavedAliases.assign(TRI->getNumRegs(), 0); |
63 | for (const MCPhysReg *I = CSR; *I; ++I) |
64 | for (MCRegAliasIterator AI(*I, TRI, true); AI.isValid(); ++AI) |
65 | CalleeSavedAliases[*AI] = *I; |
66 | |
67 | Update = true; |
68 | } |
69 | CalleeSavedRegs = CSR; |
70 | |
71 | RegCosts = TRI->getRegisterCosts(*MF); |
72 | |
73 | |
74 | const BitVector &RR = MF->getRegInfo().getReservedRegs(); |
75 | if (Reserved.size() != RR.size() || RR != Reserved) { |
76 | Update = true; |
77 | Reserved = RR; |
78 | } |
79 | |
80 | |
81 | if (Update) { |
82 | unsigned NumPSets = TRI->getNumRegPressureSets(); |
83 | PSetLimits.reset(new unsigned[NumPSets]); |
84 | std::fill(&PSetLimits[0], &PSetLimits[NumPSets], 0); |
85 | ++Tag; |
86 | } |
87 | } |
88 | |
89 | |
90 | |
91 | |
92 | void RegisterClassInfo::compute(const TargetRegisterClass *RC) const { |
93 | assert(RC && "no register class given"); |
94 | RCInfo &RCI = RegClass[RC->getID()]; |
| 5 | | Called C++ object pointer is null |
|
95 | auto &STI = MF->getSubtarget(); |
96 | |
97 | |
98 | unsigned NumRegs = RC->getNumRegs(); |
99 | |
100 | if (!RCI.Order) |
101 | RCI.Order.reset(new MCPhysReg[NumRegs]); |
102 | |
103 | unsigned N = 0; |
104 | SmallVector<MCPhysReg, 16> CSRAlias; |
105 | uint8_t MinCost = uint8_t(~0u); |
106 | uint8_t LastCost = uint8_t(~0u); |
107 | unsigned LastCostChange = 0; |
108 | |
109 | |
110 | |
111 | ArrayRef<MCPhysReg> RawOrder = RC->getRawAllocationOrder(*MF); |
112 | for (unsigned i = 0; i != RawOrder.size(); ++i) { |
113 | unsigned PhysReg = RawOrder[i]; |
114 | |
115 | if (Reserved.test(PhysReg)) |
116 | continue; |
117 | uint8_t Cost = RegCosts[PhysReg]; |
118 | MinCost = std::min(MinCost, Cost); |
119 | |
120 | if (CalleeSavedAliases[PhysReg] && |
121 | !STI.ignoreCSRForAllocationOrder(*MF, PhysReg)) |
122 | |
123 | CSRAlias.push_back(PhysReg); |
124 | else { |
125 | if (Cost != LastCost) |
126 | LastCostChange = N; |
127 | RCI.Order[N++] = PhysReg; |
128 | LastCost = Cost; |
129 | } |
130 | } |
131 | RCI.NumRegs = N + CSRAlias.size(); |
132 | assert(RCI.NumRegs <= NumRegs && "Allocation order larger than regclass"); |
133 | |
134 | |
135 | for (unsigned i = 0, e = CSRAlias.size(); i != e; ++i) { |
136 | unsigned PhysReg = CSRAlias[i]; |
137 | uint8_t Cost = RegCosts[PhysReg]; |
138 | if (Cost != LastCost) |
139 | LastCostChange = N; |
140 | RCI.Order[N++] = PhysReg; |
141 | LastCost = Cost; |
142 | } |
143 | |
144 | |
145 | if (StressRA && RCI.NumRegs > StressRA) |
146 | RCI.NumRegs = StressRA; |
147 | |
148 | |
149 | if (const TargetRegisterClass *Super = |
150 | TRI->getLargestLegalSuperClass(RC, *MF)) |
151 | if (Super != RC && getNumAllocatableRegs(Super) > RCI.NumRegs) |
152 | RCI.ProperSubClass = true; |
153 | |
154 | RCI.MinCost = MinCost; |
155 | RCI.LastCostChange = LastCostChange; |
156 | |
157 | LLVM_DEBUG({ |
158 | dbgs() << "AllocationOrder(" << TRI->getRegClassName(RC) << ") = ["; |
159 | for (unsigned I = 0; I != RCI.NumRegs; ++I) |
160 | dbgs() << ' ' << printReg(RCI.Order[I], TRI); |
161 | dbgs() << (RCI.ProperSubClass ? " ] (sub-class)\n" : " ]\n"); |
162 | }); |
163 | |
164 | |
165 | RCI.Tag = Tag; |
166 | } |
167 | |
168 | |
169 | |
170 | |
171 | unsigned RegisterClassInfo::computePSetLimit(unsigned Idx) const { |
172 | const TargetRegisterClass *RC = nullptr; |
| 1 | 'RC' initialized to a null pointer value | |
|
173 | unsigned NumRCUnits = 0; |
174 | for (const TargetRegisterClass *C : TRI->regclasses()) { |
| 2 | | Assuming '__begin1' is equal to '__end1' | |
|
175 | const int *PSetID = TRI->getRegClassPressureSets(C); |
176 | for (; *PSetID != -1; ++PSetID) { |
177 | if ((unsigned)*PSetID == Idx) |
178 | break; |
179 | } |
180 | if (*PSetID == -1) |
181 | continue; |
182 | |
183 | |
184 | |
185 | unsigned NUnits = TRI->getRegClassWeight(C).WeightLimit; |
186 | if (!RC || NUnits > NumRCUnits) { |
187 | RC = C; |
188 | NumRCUnits = NUnits; |
189 | } |
190 | } |
191 | assert(RC && "Failed to find register class"); |
192 | compute(RC); |
| 3 | | Passing null pointer value via 1st parameter 'RC' | |
|
| 4 | | Calling 'RegisterClassInfo::compute' | |
|
193 | unsigned NAllocatableRegs = getNumAllocatableRegs(RC); |
194 | unsigned RegPressureSetLimit = TRI->getRegPressureSetLimit(*MF, Idx); |
195 | |
196 | |
197 | |
198 | |
199 | if (NAllocatableRegs == 0) |
200 | return RegPressureSetLimit; |
201 | unsigned NReserved = RC->getNumRegs() - NAllocatableRegs; |
202 | return RegPressureSetLimit - TRI->getRegClassWeight(RC).RegWeight * NReserved; |
203 | } |