File: | build/source/llvm/lib/CodeGen/RegisterClassInfo.cpp |
Warning: | line 95, column 35 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===- RegisterClassInfo.cpp - Dynamic Register Class Info ----------------===// | |||
2 | // | |||
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |||
4 | // See https://llvm.org/LICENSE.txt for license information. | |||
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |||
6 | // | |||
7 | //===----------------------------------------------------------------------===// | |||
8 | // | |||
9 | // This file implements the RegisterClassInfo class which provides dynamic | |||
10 | // information about target register classes. Callee-saved vs. caller-saved and | |||
11 | // reserved registers depend on calling conventions and other dynamic | |||
12 | // information, so some things cannot be determined statically. | |||
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/TargetRegisterInfo.h" | |||
23 | #include "llvm/CodeGen/TargetSubtargetInfo.h" | |||
24 | #include "llvm/MC/MCRegisterInfo.h" | |||
25 | #include "llvm/Support/CommandLine.h" | |||
26 | #include "llvm/Support/Debug.h" | |||
27 | #include "llvm/Support/raw_ostream.h" | |||
28 | #include <algorithm> | |||
29 | #include <cassert> | |||
30 | #include <cstdint> | |||
31 | ||||
32 | using namespace llvm; | |||
33 | ||||
34 | #define DEBUG_TYPE"regalloc" "regalloc" | |||
35 | ||||
36 | static cl::opt<unsigned> | |||
37 | StressRA("stress-regalloc", cl::Hidden, cl::init(0), cl::value_desc("N"), | |||
38 | cl::desc("Limit all regclasses to N registers")); | |||
39 | ||||
40 | RegisterClassInfo::RegisterClassInfo() = default; | |||
41 | ||||
42 | void RegisterClassInfo::runOnMachineFunction(const MachineFunction &mf) { | |||
43 | bool Update = false; | |||
44 | MF = &mf; | |||
45 | ||||
46 | auto &STI = MF->getSubtarget(); | |||
47 | ||||
48 | // Allocate new array the first time we see a new target. | |||
49 | if (STI.getRegisterInfo() != TRI) { | |||
| ||||
50 | TRI = STI.getRegisterInfo(); | |||
51 | RegClass.reset(new RCInfo[TRI->getNumRegClasses()]); | |||
52 | Update = true; | |||
53 | } | |||
54 | ||||
55 | // Test if CSRs have changed from the previous function. | |||
56 | const MachineRegisterInfo &MRI = MF->getRegInfo(); | |||
57 | const MCPhysReg *CSR = MRI.getCalleeSavedRegs(); | |||
58 | bool CSRChanged = true; | |||
59 | if (!Update
| |||
60 | CSRChanged = false; | |||
61 | size_t LastSize = LastCalleeSavedRegs.size(); | |||
62 | for (unsigned I = 0;; ++I) { | |||
63 | if (CSR[I] == 0) { | |||
64 | CSRChanged = I != LastSize; | |||
65 | break; | |||
66 | } | |||
67 | if (I >= LastSize) { | |||
68 | CSRChanged = true; | |||
69 | break; | |||
70 | } | |||
71 | if (CSR[I] != LastCalleeSavedRegs[I]) { | |||
72 | CSRChanged = true; | |||
73 | break; | |||
74 | } | |||
75 | } | |||
76 | } | |||
77 | ||||
78 | // Get the callee saved registers. | |||
79 | if (CSRChanged
| |||
80 | LastCalleeSavedRegs.clear(); | |||
81 | // Build a CSRAlias map. Every CSR alias saves the last | |||
82 | // overlapping CSR. | |||
83 | CalleeSavedAliases.assign(TRI->getNumRegs(), 0); | |||
84 | for (const MCPhysReg *I = CSR; *I; ++I) { | |||
85 | for (MCRegAliasIterator AI(*I, TRI, true); AI.isValid(); ++AI) | |||
86 | CalleeSavedAliases[*AI] = *I; | |||
87 | LastCalleeSavedRegs.push_back(*I); | |||
88 | } | |||
89 | ||||
90 | Update = true; | |||
91 | } | |||
92 | ||||
93 | // Even if CSR list is same, we could have had a different allocation order | |||
94 | // if ignoreCSRForAllocationOrder is evaluated differently. | |||
95 | BitVector CSRHintsForAllocOrder(TRI->getNumRegs()); | |||
| ||||
96 | for (const MCPhysReg *I = CSR; *I; ++I) | |||
97 | for (MCRegAliasIterator AI(*I, TRI, true); AI.isValid(); ++AI) | |||
98 | CSRHintsForAllocOrder[*AI] = STI.ignoreCSRForAllocationOrder(mf, *AI); | |||
99 | if (IgnoreCSRForAllocOrder.size() != CSRHintsForAllocOrder.size() || | |||
100 | IgnoreCSRForAllocOrder != CSRHintsForAllocOrder) { | |||
101 | Update = true; | |||
102 | IgnoreCSRForAllocOrder = CSRHintsForAllocOrder; | |||
103 | } | |||
104 | ||||
105 | RegCosts = TRI->getRegisterCosts(*MF); | |||
106 | ||||
107 | // Different reserved registers? | |||
108 | const BitVector &RR = MF->getRegInfo().getReservedRegs(); | |||
109 | if (Reserved.size() != RR.size() || RR != Reserved) { | |||
110 | Update = true; | |||
111 | Reserved = RR; | |||
112 | } | |||
113 | ||||
114 | // Invalidate cached information from previous function. | |||
115 | if (Update) { | |||
116 | unsigned NumPSets = TRI->getNumRegPressureSets(); | |||
117 | PSetLimits.reset(new unsigned[NumPSets]); | |||
118 | std::fill(&PSetLimits[0], &PSetLimits[NumPSets], 0); | |||
119 | ++Tag; | |||
120 | } | |||
121 | } | |||
122 | ||||
123 | /// compute - Compute the preferred allocation order for RC with reserved | |||
124 | /// registers filtered out. Volatile registers come first followed by CSR | |||
125 | /// aliases ordered according to the CSR order specified by the target. | |||
126 | void RegisterClassInfo::compute(const TargetRegisterClass *RC) const { | |||
127 | assert(RC && "no register class given")(static_cast <bool> (RC && "no register class given" ) ? void (0) : __assert_fail ("RC && \"no register class given\"" , "llvm/lib/CodeGen/RegisterClassInfo.cpp", 127, __extension__ __PRETTY_FUNCTION__)); | |||
128 | RCInfo &RCI = RegClass[RC->getID()]; | |||
129 | auto &STI = MF->getSubtarget(); | |||
130 | ||||
131 | // Raw register count, including all reserved regs. | |||
132 | unsigned NumRegs = RC->getNumRegs(); | |||
133 | ||||
134 | if (!RCI.Order) | |||
135 | RCI.Order.reset(new MCPhysReg[NumRegs]); | |||
136 | ||||
137 | unsigned N = 0; | |||
138 | SmallVector<MCPhysReg, 16> CSRAlias; | |||
139 | uint8_t MinCost = uint8_t(~0u); | |||
140 | uint8_t LastCost = uint8_t(~0u); | |||
141 | unsigned LastCostChange = 0; | |||
142 | ||||
143 | // FIXME: Once targets reserve registers instead of removing them from the | |||
144 | // allocation order, we can simply use begin/end here. | |||
145 | ArrayRef<MCPhysReg> RawOrder = RC->getRawAllocationOrder(*MF); | |||
146 | for (unsigned PhysReg : RawOrder) { | |||
147 | // Remove reserved registers from the allocation order. | |||
148 | if (Reserved.test(PhysReg)) | |||
149 | continue; | |||
150 | uint8_t Cost = RegCosts[PhysReg]; | |||
151 | MinCost = std::min(MinCost, Cost); | |||
152 | ||||
153 | if (CalleeSavedAliases[PhysReg] && | |||
154 | !STI.ignoreCSRForAllocationOrder(*MF, PhysReg)) | |||
155 | // PhysReg aliases a CSR, save it for later. | |||
156 | CSRAlias.push_back(PhysReg); | |||
157 | else { | |||
158 | if (Cost != LastCost) | |||
159 | LastCostChange = N; | |||
160 | RCI.Order[N++] = PhysReg; | |||
161 | LastCost = Cost; | |||
162 | } | |||
163 | } | |||
164 | RCI.NumRegs = N + CSRAlias.size(); | |||
165 | assert(RCI.NumRegs <= NumRegs && "Allocation order larger than regclass")(static_cast <bool> (RCI.NumRegs <= NumRegs && "Allocation order larger than regclass") ? void (0) : __assert_fail ("RCI.NumRegs <= NumRegs && \"Allocation order larger than regclass\"" , "llvm/lib/CodeGen/RegisterClassInfo.cpp", 165, __extension__ __PRETTY_FUNCTION__)); | |||
166 | ||||
167 | // CSR aliases go after the volatile registers, preserve the target's order. | |||
168 | for (unsigned i = 0, e = CSRAlias.size(); i != e; ++i) { | |||
169 | unsigned PhysReg = CSRAlias[i]; | |||
170 | uint8_t Cost = RegCosts[PhysReg]; | |||
171 | if (Cost != LastCost) | |||
172 | LastCostChange = N; | |||
173 | RCI.Order[N++] = PhysReg; | |||
174 | LastCost = Cost; | |||
175 | } | |||
176 | ||||
177 | // Register allocator stress test. Clip register class to N registers. | |||
178 | if (StressRA && RCI.NumRegs > StressRA) | |||
179 | RCI.NumRegs = StressRA; | |||
180 | ||||
181 | // Check if RC is a proper sub-class. | |||
182 | if (const TargetRegisterClass *Super = | |||
183 | TRI->getLargestLegalSuperClass(RC, *MF)) | |||
184 | if (Super != RC && getNumAllocatableRegs(Super) > RCI.NumRegs) | |||
185 | RCI.ProperSubClass = true; | |||
186 | ||||
187 | RCI.MinCost = MinCost; | |||
188 | RCI.LastCostChange = LastCostChange; | |||
189 | ||||
190 | LLVM_DEBUG({do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("regalloc")) { { dbgs() << "AllocationOrder(" << TRI->getRegClassName(RC) << ") = ["; for (unsigned I = 0; I != RCI.NumRegs; ++I) dbgs() << ' ' << printReg (RCI.Order[I], TRI); dbgs() << (RCI.ProperSubClass ? " ] (sub-class)\n" : " ]\n"); }; } } while (false) | |||
191 | dbgs() << "AllocationOrder(" << TRI->getRegClassName(RC) << ") = [";do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("regalloc")) { { dbgs() << "AllocationOrder(" << TRI->getRegClassName(RC) << ") = ["; for (unsigned I = 0; I != RCI.NumRegs; ++I) dbgs() << ' ' << printReg (RCI.Order[I], TRI); dbgs() << (RCI.ProperSubClass ? " ] (sub-class)\n" : " ]\n"); }; } } while (false) | |||
192 | for (unsigned I = 0; I != RCI.NumRegs; ++I)do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("regalloc")) { { dbgs() << "AllocationOrder(" << TRI->getRegClassName(RC) << ") = ["; for (unsigned I = 0; I != RCI.NumRegs; ++I) dbgs() << ' ' << printReg (RCI.Order[I], TRI); dbgs() << (RCI.ProperSubClass ? " ] (sub-class)\n" : " ]\n"); }; } } while (false) | |||
193 | dbgs() << ' ' << printReg(RCI.Order[I], TRI);do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("regalloc")) { { dbgs() << "AllocationOrder(" << TRI->getRegClassName(RC) << ") = ["; for (unsigned I = 0; I != RCI.NumRegs; ++I) dbgs() << ' ' << printReg (RCI.Order[I], TRI); dbgs() << (RCI.ProperSubClass ? " ] (sub-class)\n" : " ]\n"); }; } } while (false) | |||
194 | dbgs() << (RCI.ProperSubClass ? " ] (sub-class)\n" : " ]\n");do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("regalloc")) { { dbgs() << "AllocationOrder(" << TRI->getRegClassName(RC) << ") = ["; for (unsigned I = 0; I != RCI.NumRegs; ++I) dbgs() << ' ' << printReg (RCI.Order[I], TRI); dbgs() << (RCI.ProperSubClass ? " ] (sub-class)\n" : " ]\n"); }; } } while (false) | |||
195 | })do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType ("regalloc")) { { dbgs() << "AllocationOrder(" << TRI->getRegClassName(RC) << ") = ["; for (unsigned I = 0; I != RCI.NumRegs; ++I) dbgs() << ' ' << printReg (RCI.Order[I], TRI); dbgs() << (RCI.ProperSubClass ? " ] (sub-class)\n" : " ]\n"); }; } } while (false); | |||
196 | ||||
197 | // RCI is now up-to-date. | |||
198 | RCI.Tag = Tag; | |||
199 | } | |||
200 | ||||
201 | /// This is not accurate because two overlapping register sets may have some | |||
202 | /// nonoverlapping reserved registers. However, computing the allocation order | |||
203 | /// for all register classes would be too expensive. | |||
204 | unsigned RegisterClassInfo::computePSetLimit(unsigned Idx) const { | |||
205 | const TargetRegisterClass *RC = nullptr; | |||
206 | unsigned NumRCUnits = 0; | |||
207 | for (const TargetRegisterClass *C : TRI->regclasses()) { | |||
208 | const int *PSetID = TRI->getRegClassPressureSets(C); | |||
209 | for (; *PSetID != -1; ++PSetID) { | |||
210 | if ((unsigned)*PSetID == Idx) | |||
211 | break; | |||
212 | } | |||
213 | if (*PSetID == -1) | |||
214 | continue; | |||
215 | ||||
216 | // Found a register class that counts against this pressure set. | |||
217 | // For efficiency, only compute the set order for the largest set. | |||
218 | unsigned NUnits = TRI->getRegClassWeight(C).WeightLimit; | |||
219 | if (!RC || NUnits > NumRCUnits) { | |||
220 | RC = C; | |||
221 | NumRCUnits = NUnits; | |||
222 | } | |||
223 | } | |||
224 | assert(RC && "Failed to find register class")(static_cast <bool> (RC && "Failed to find register class" ) ? void (0) : __assert_fail ("RC && \"Failed to find register class\"" , "llvm/lib/CodeGen/RegisterClassInfo.cpp", 224, __extension__ __PRETTY_FUNCTION__)); | |||
225 | compute(RC); | |||
226 | unsigned NAllocatableRegs = getNumAllocatableRegs(RC); | |||
227 | unsigned RegPressureSetLimit = TRI->getRegPressureSetLimit(*MF, Idx); | |||
228 | // If all the regs are reserved, return raw RegPressureSetLimit. | |||
229 | // One example is VRSAVERC in PowerPC. | |||
230 | // Avoid returning zero, getRegPressureSetLimit(Idx) assumes computePSetLimit | |||
231 | // return non-zero value. | |||
232 | if (NAllocatableRegs == 0) | |||
233 | return RegPressureSetLimit; | |||
234 | unsigned NReserved = RC->getNumRegs() - NAllocatableRegs; | |||
235 | return RegPressureSetLimit - TRI->getRegClassWeight(RC).RegWeight * NReserved; | |||
236 | } |