LLVM 22.0.0git
RDFRegisters.cpp
Go to the documentation of this file.
1//===- RDFRegisters.cpp ---------------------------------------------------===//
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
15#include "llvm/MC/LaneBitmask.h"
18#include "llvm/Support/Format.h"
21#include <cassert>
22#include <cstdint>
23#include <set>
24#include <utility>
25
26namespace llvm::rdf {
27
29 const MachineFunction &mf)
30 : TRI(tri) {
31 RegInfos.resize(TRI.getNumRegs());
32
33 BitVector BadRC(TRI.getNumRegs());
34 for (const TargetRegisterClass *RC : TRI.regclasses()) {
35 for (MCPhysReg R : *RC) {
36 RegInfo &RI = RegInfos[R];
37 if (RI.RegClass != nullptr && !BadRC[R]) {
38 if (RC->LaneMask != RI.RegClass->LaneMask) {
39 BadRC.set(R);
40 RI.RegClass = nullptr;
41 }
42 } else
43 RI.RegClass = RC;
44 }
45 }
46
47 UnitInfos.resize(TRI.getNumRegUnits());
48
49 for (MCRegUnit U : TRI.regunits()) {
50 if (UnitInfos[U].Reg != 0)
51 continue;
52 MCRegUnitRootIterator R(U, &TRI);
53 assert(R.isValid());
54 RegisterId F = *R;
55 ++R;
56 if (R.isValid()) {
57 UnitInfos[U].Mask = LaneBitmask::getAll();
58 UnitInfos[U].Reg = F;
59 } else {
60 for (MCRegUnitMaskIterator I(F, &TRI); I.isValid(); ++I) {
61 std::pair<MCRegUnit, LaneBitmask> P = *I;
62 UnitInfo &UI = UnitInfos[P.first];
63 UI.Reg = F;
64 UI.Mask = P.second;
65 }
66 }
67 }
68
69 for (const uint32_t *RM : TRI.getRegMasks())
70 RegMasks.insert(RM);
71 for (const MachineBasicBlock &B : mf)
72 for (const MachineInstr &In : B)
73 for (const MachineOperand &Op : In.operands())
74 if (Op.isRegMask())
75 RegMasks.insert(Op.getRegMask());
76
77 MaskInfos.resize(RegMasks.size() + 1);
78 for (uint32_t M = 1, NM = RegMasks.size(); M <= NM; ++M) {
79 BitVector PU(TRI.getNumRegUnits());
80 const uint32_t *MB = RegMasks.get(M);
81 for (unsigned I = 1, E = TRI.getNumRegs(); I != E; ++I) {
82 if (!(MB[I / 32] & (1u << (I % 32))))
83 continue;
84 for (MCRegUnit Unit : TRI.regunits(MCRegister::from(I)))
85 PU.set(static_cast<unsigned>(Unit));
86 }
87 MaskInfos[M].Units = PU.flip();
88 }
89
90 AliasInfos.resize(TRI.getNumRegUnits());
91 for (MCRegUnit U : TRI.regunits()) {
92 BitVector AS(TRI.getNumRegs());
93 for (MCRegUnitRootIterator R(U, &TRI); R.isValid(); ++R)
94 for (MCPhysReg S : TRI.superregs_inclusive(*R))
95 AS.set(S);
96 AliasInfos[U].Regs = AS;
97 }
98}
99
103
104std::set<RegisterId> PhysicalRegisterInfo::getAliasSet(RegisterRef RR) const {
105 // Do not include Reg in the alias set.
106 std::set<RegisterId> AS;
107 assert(!RR.isUnit() && "No units allowed");
108 if (RR.isMask()) {
109 // XXX SLOW
110 const uint32_t *MB = getRegMaskBits(RR);
111 for (unsigned i = 1, e = TRI.getNumRegs(); i != e; ++i) {
112 if (MB[i / 32] & (1u << (i % 32)))
113 continue;
114 AS.insert(i);
115 }
116 return AS;
117 }
118
119 assert(RR.isReg());
120 for (MCRegAliasIterator AI(RR.asMCReg(), &TRI, false); AI.isValid(); ++AI)
121 AS.insert(*AI);
122
123 return AS;
124}
125
126std::set<RegisterId> PhysicalRegisterInfo::getUnits(RegisterRef RR) const {
127 std::set<RegisterId> Units;
128
129 if (RR.isReg()) {
130 if (RR.Mask.none())
131 return Units; // Empty
132 for (MCRegUnitMaskIterator UM(RR.asMCReg(), &TRI); UM.isValid(); ++UM) {
133 auto [U, M] = *UM;
134 if ((M & RR.Mask).any())
135 Units.insert(static_cast<unsigned>(U));
136 }
137 return Units;
138 }
139
140 assert(RR.isMask());
141 unsigned NumRegs = TRI.getNumRegs();
142 const uint32_t *MB = getRegMaskBits(RR);
143 for (unsigned I = 0, E = (NumRegs + 31) / 32; I != E; ++I) {
144 uint32_t C = ~MB[I]; // Clobbered regs
145 if (I == 0) // Reg 0 should be ignored
147 if (I + 1 == E && NumRegs % 32 != 0) // Last word may be partial
148 C &= maskTrailingOnes<unsigned>(NumRegs % 32);
149 if (C == 0)
150 continue;
151 while (C != 0) {
152 unsigned T = llvm::countr_zero(C);
153 unsigned CR = 32 * I + T; // Clobbered reg
154 for (MCRegUnit U : TRI.regunits(CR))
155 Units.insert(static_cast<unsigned>(U));
156 C &= ~(1u << T);
157 }
158 }
159 return Units;
160}
161
163 if (RR.Id == R)
164 return RR;
165 if (unsigned Idx = TRI.getSubRegIndex(RegisterRef(R).asMCReg(), RR.asMCReg()))
166 return RegisterRef(R, TRI.composeSubRegIndexLaneMask(Idx, RR.Mask));
167 if (unsigned Idx =
168 TRI.getSubRegIndex(RR.asMCReg(), RegisterRef(R).asMCReg())) {
169 const RegInfo &RI = RegInfos[R];
170 LaneBitmask RCM =
171 RI.RegClass ? RI.RegClass->LaneMask : LaneBitmask::getAll();
172 LaneBitmask M = TRI.reverseComposeSubRegIndexLaneMask(Idx, RR.Mask);
173 return RegisterRef(R, M & RCM);
174 }
175 llvm_unreachable("Invalid arguments: unrelated registers?");
176}
177
179 if (!A.isReg() || !B.isReg()) {
180 // For non-regs, or comparing reg and non-reg, use only the Id member.
181 return A.Id == B.Id;
182 }
183
184 if (A.Id == B.Id)
185 return A.Mask == B.Mask;
186
187 // Compare reg units lexicographically.
188 MCRegUnitMaskIterator AI(A.asMCReg(), &getTRI());
189 MCRegUnitMaskIterator BI(B.asMCReg(), &getTRI());
190 while (AI.isValid() && BI.isValid()) {
191 auto [AReg, AMask] = *AI;
192 auto [BReg, BMask] = *BI;
193
194 // If both iterators point to a unit contained in both A and B, then
195 // compare the units.
196 if ((AMask & A.Mask).any() && (BMask & B.Mask).any()) {
197 if (AReg != BReg)
198 return false;
199 // Units are equal, move on to the next ones.
200 ++AI;
201 ++BI;
202 continue;
203 }
204
205 if ((AMask & A.Mask).none())
206 ++AI;
207 if ((BMask & B.Mask).none())
208 ++BI;
209 }
210 // One or both have reached the end.
211 return static_cast<int>(AI.isValid()) == static_cast<int>(BI.isValid());
212}
213
215 if (!A.isReg() || !B.isReg()) {
216 // For non-regs, or comparing reg and non-reg, use only the Id member.
217 return A.Id < B.Id;
218 }
219
220 if (A.Id == B.Id)
221 return A.Mask < B.Mask;
222 if (A.Mask == B.Mask)
223 return A.Id < B.Id;
224
225 // Compare reg units lexicographically.
226 llvm::MCRegUnitMaskIterator AI(A.asMCReg(), &getTRI());
227 llvm::MCRegUnitMaskIterator BI(B.asMCReg(), &getTRI());
228 while (AI.isValid() && BI.isValid()) {
229 auto [AReg, AMask] = *AI;
230 auto [BReg, BMask] = *BI;
231
232 // If both iterators point to a unit contained in both A and B, then
233 // compare the units.
234 if ((AMask & A.Mask).any() && (BMask & B.Mask).any()) {
235 if (AReg != BReg)
236 return AReg < BReg;
237 // Units are equal, move on to the next ones.
238 ++AI;
239 ++BI;
240 continue;
241 }
242
243 if ((AMask & A.Mask).none())
244 ++AI;
245 if ((BMask & B.Mask).none())
246 ++BI;
247 }
248 // One or both have reached the end: assume invalid < valid.
249 return static_cast<int>(AI.isValid()) < static_cast<int>(BI.isValid());
250}
251
253 if (A.isReg()) {
254 MCRegister Reg = A.asMCReg();
255 if (Reg && Reg.id() < TRI.getNumRegs())
256 OS << TRI.getName(Reg);
257 else
258 OS << printReg(Reg, &TRI);
259 OS << PrintLaneMaskShort(A.Mask);
260 } else if (A.isUnit()) {
261 OS << printRegUnit(A.asMCRegUnit(), &TRI);
262 } else {
263 unsigned Idx = A.asMaskIdx();
264 const char *Fmt = Idx < 0x10000 ? "%04x" : "%08x";
265 OS << "M#" << format(Fmt, Idx);
266 }
267}
268
270 OS << '{';
271 for (unsigned U : A.units())
272 OS << ' ' << printRegUnit(static_cast<MCRegUnit>(U), &TRI);
273 OS << " }";
274}
275
277 if (RR.isMask())
278 return Units.anyCommon(PRI.getMaskUnits(RR));
279
280 for (MCRegUnitMaskIterator U(RR.asMCReg(), &PRI.getTRI()); U.isValid(); ++U) {
281 auto [Unit, LaneMask] = *U;
282 if ((LaneMask & RR.Mask).any())
283 if (Units.test(static_cast<unsigned>(Unit)))
284 return true;
285 }
286 return false;
287}
288
290 if (RR.isMask()) {
291 BitVector T(PRI.getMaskUnits(RR));
292 return T.reset(Units).none();
293 }
294
295 for (MCRegUnitMaskIterator U(RR.asMCReg(), &PRI.getTRI()); U.isValid(); ++U) {
296 auto [Unit, LaneMask] = *U;
297 if ((LaneMask & RR.Mask).any())
298 if (!Units.test(static_cast<unsigned>(Unit)))
299 return false;
300 }
301 return true;
302}
303
305 if (RR.isMask()) {
306 Units |= PRI.getMaskUnits(RR);
307 return *this;
308 }
309
310 for (MCRegUnitMaskIterator U(RR.asMCReg(), &PRI.getTRI()); U.isValid(); ++U) {
311 auto [Unit, LaneMask] = *U;
312 if ((LaneMask & RR.Mask).any())
313 Units.set(static_cast<unsigned>(Unit));
314 }
315 return *this;
316}
317
319 Units |= RG.Units;
320 return *this;
321}
322
326
328 Units &= RG.Units;
329 return *this;
330}
331
335
337 Units.reset(RG.Units);
338 return *this;
339}
340
342 RegisterAggr T(PRI);
343 T.insert(RR).intersect(*this);
344 if (T.empty())
345 return RegisterRef();
346 RegisterRef NR = T.makeRegRef();
347 assert(NR);
348 return NR;
349}
350
352 return RegisterAggr(PRI).insert(RR).clear(*this).makeRegRef();
353}
354
356 int U = Units.find_first();
357 if (U < 0)
358 return RegisterRef();
359
360 // Find the set of all registers that are aliased to all the units
361 // in this aggregate.
362
363 // Get all the registers aliased to the first unit in the bit vector.
364 BitVector Regs = PRI.getUnitAliases(static_cast<MCRegUnit>(U));
365 U = Units.find_next(U);
366
367 // For each other unit, intersect it with the set of all registers
368 // aliased that unit.
369 while (U >= 0) {
370 Regs &= PRI.getUnitAliases(static_cast<MCRegUnit>(U));
371 U = Units.find_next(U);
372 }
373
374 // If there is at least one register remaining, pick the first one,
375 // and consolidate the masks of all of its units contained in this
376 // aggregate.
377
378 int F = Regs.find_first();
379 if (F <= 0)
380 return RegisterRef();
381
382 LaneBitmask M;
383 for (MCRegUnitMaskIterator I(F, &PRI.getTRI()); I.isValid(); ++I) {
384 auto [Unit, LaneMask] = *I;
385 if (Units.test(static_cast<unsigned>(Unit)))
386 M |= LaneMask;
387 }
388 return RegisterRef(F, M);
389}
390
392 : Owner(&RG) {
393 for (int U = RG.Units.find_first(); U >= 0; U = RG.Units.find_next(U)) {
394 RegisterRef R = RG.PRI.getRefForUnit(static_cast<MCRegUnit>(U));
395 Masks[R.Id] |= R.Mask;
396 }
397 Pos = End ? Masks.end() : Masks.begin();
398 Index = End ? Masks.size() : 0;
399}
400
402 A.getPRI().print(OS, A);
403 return OS;
404}
405
407 if (P.Mask.all())
408 return OS;
409 if (P.Mask.none())
410 return OS << ":*none*";
411
412 LaneBitmask::Type Val = P.Mask.getAsInteger();
413 if ((Val & 0xffff) == Val)
414 return OS << ':' << format("%04llX", Val);
415 if ((Val & 0xffffffff) == Val)
416 return OS << ':' << format("%08llX", Val);
417 return OS << ':' << PrintLaneMask(P.Mask);
418}
419
420} // namespace llvm::rdf
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements the BitVector class.
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
A common definition of LaneBitmask for use in TableGen and CodeGen.
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Register Reg
Register const TargetRegisterInfo * TRI
static Interval intersect(const Interval &I1, const Interval &I2)
#define T
#define P(N)
if(PassOpts->AAPipeline)
SI optimize exec mask operations pre RA
int find_first() const
find_first - Returns the index of the first set bit, -1 if none of the bits are set.
Definition BitVector.h:319
int find_next(unsigned Prev) const
find_next - Returns the index of the next set bit following the "Prev" bit.
Definition BitVector.h:327
MCRegAliasIterator enumerates all registers aliasing Reg.
MCRegUnitMaskIterator enumerates a list of register units and their associated lane masks for Reg.
bool isValid() const
Returns true if this iterator is not yet at the end.
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:41
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
uint32_t RegisterId
raw_ostream & operator<<(raw_ostream &OS, const Print< RegisterRef > &P)
Definition RDFGraph.cpp:44
bool disjoint(const std::set< T > &A, const std::set< T > &B)
constexpr T maskLeadingOnes(unsigned N)
Create a bitmask with the N left-most bits set to 1, and all other bits set to 0.
Definition MathExtras.h:88
Printable PrintLaneMask(LaneBitmask LaneMask)
Create Printable object to print LaneBitmasks on a raw_ostream.
Definition LaneBitmask.h:92
LLVM_ABI Printable printRegUnit(MCRegUnit Unit, const TargetRegisterInfo *TRI)
Create Printable object to print register units on a raw_ostream.
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
Definition bit.h:202
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition Format.h:129
DWARFExpression::Operation Op
constexpr T maskTrailingOnes(unsigned N)
Create a bitmask with the N right-most bits set to 1, and all other bits set to 0.
Definition MathExtras.h:77
LLVM_ABI Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
static constexpr LaneBitmask getAll()
Definition LaneBitmask.h:82
constexpr bool none() const
Definition LaneBitmask.h:52
PhysicalRegisterInfo(const TargetRegisterInfo &tri, const MachineFunction &mf)
void print(raw_ostream &OS, RegisterRef A) const
const TargetRegisterInfo & getTRI() const
bool equal_to(RegisterRef A, RegisterRef B) const
const uint32_t * getRegMaskBits(RegisterRef RR) const
bool alias(RegisterRef RA, RegisterRef RB) const
std::set< RegisterId > getAliasSet(RegisterRef RR) const
bool less(RegisterRef A, RegisterRef B) const
RegisterRef mapTo(RegisterRef RR, RegisterId R) const
std::set< RegisterId > getUnits(RegisterRef RR) const
ref_iterator(const RegisterAggr &RG, bool End)
RegisterAggr & insert(RegisterRef RR)
RegisterAggr(const PhysicalRegisterInfo &pri)
RegisterRef clearIn(RegisterRef RR) const
RegisterAggr & clear(RegisterRef RR)
RegisterRef makeRegRef() const
RegisterAggr & intersect(RegisterRef RR)
bool hasAliasOf(RegisterRef RR) const
RegisterRef intersectWith(RegisterRef RR) const
bool hasCoverOf(RegisterRef RR) const
constexpr bool isReg() const
constexpr bool isMask() const
constexpr bool isUnit() const
constexpr MCRegister asMCReg() const