1080dd10fSScott Constable //===- RDFRegisters.cpp ---------------------------------------------------===//
2080dd10fSScott Constable //
3080dd10fSScott Constable // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4080dd10fSScott Constable // See https://llvm.org/LICENSE.txt for license information.
5080dd10fSScott Constable // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6080dd10fSScott Constable //
7080dd10fSScott Constable //===----------------------------------------------------------------------===//
8080dd10fSScott Constable
9080dd10fSScott Constable #include "llvm/ADT/BitVector.h"
10080dd10fSScott Constable #include "llvm/CodeGen/MachineFunction.h"
11080dd10fSScott Constable #include "llvm/CodeGen/MachineInstr.h"
12080dd10fSScott Constable #include "llvm/CodeGen/MachineOperand.h"
13080dd10fSScott Constable #include "llvm/CodeGen/RDFRegisters.h"
14080dd10fSScott Constable #include "llvm/CodeGen/TargetRegisterInfo.h"
15080dd10fSScott Constable #include "llvm/MC/LaneBitmask.h"
16080dd10fSScott Constable #include "llvm/MC/MCRegisterInfo.h"
17080dd10fSScott Constable #include "llvm/Support/ErrorHandling.h"
182af7036dSKrzysztof Parzyszek #include "llvm/Support/Format.h"
19d57646b2SKrzysztof Parzyszek #include "llvm/Support/MathExtras.h"
20080dd10fSScott Constable #include "llvm/Support/raw_ostream.h"
21080dd10fSScott Constable #include <cassert>
22080dd10fSScott Constable #include <cstdint>
23080dd10fSScott Constable #include <set>
24080dd10fSScott Constable #include <utility>
25080dd10fSScott Constable
26375d7980SKrzysztof Parzyszek namespace llvm::rdf {
27080dd10fSScott Constable
PhysicalRegisterInfo(const TargetRegisterInfo & tri,const MachineFunction & mf)28080dd10fSScott Constable PhysicalRegisterInfo::PhysicalRegisterInfo(const TargetRegisterInfo &tri,
29080dd10fSScott Constable const MachineFunction &mf)
30080dd10fSScott Constable : TRI(tri) {
31080dd10fSScott Constable RegInfos.resize(TRI.getNumRegs());
32080dd10fSScott Constable
33080dd10fSScott Constable BitVector BadRC(TRI.getNumRegs());
34080dd10fSScott Constable for (const TargetRegisterClass *RC : TRI.regclasses()) {
35080dd10fSScott Constable for (MCPhysReg R : *RC) {
36080dd10fSScott Constable RegInfo &RI = RegInfos[R];
37080dd10fSScott Constable if (RI.RegClass != nullptr && !BadRC[R]) {
38080dd10fSScott Constable if (RC->LaneMask != RI.RegClass->LaneMask) {
39080dd10fSScott Constable BadRC.set(R);
40080dd10fSScott Constable RI.RegClass = nullptr;
41080dd10fSScott Constable }
42080dd10fSScott Constable } else
43080dd10fSScott Constable RI.RegClass = RC;
44080dd10fSScott Constable }
45080dd10fSScott Constable }
46080dd10fSScott Constable
47080dd10fSScott Constable UnitInfos.resize(TRI.getNumRegUnits());
48080dd10fSScott Constable
49080dd10fSScott Constable for (uint32_t U = 0, NU = TRI.getNumRegUnits(); U != NU; ++U) {
50080dd10fSScott Constable if (UnitInfos[U].Reg != 0)
51080dd10fSScott Constable continue;
52080dd10fSScott Constable MCRegUnitRootIterator R(U, &TRI);
53080dd10fSScott Constable assert(R.isValid());
54080dd10fSScott Constable RegisterId F = *R;
55080dd10fSScott Constable ++R;
56080dd10fSScott Constable if (R.isValid()) {
57080dd10fSScott Constable UnitInfos[U].Mask = LaneBitmask::getAll();
58080dd10fSScott Constable UnitInfos[U].Reg = F;
59080dd10fSScott Constable } else {
60080dd10fSScott Constable for (MCRegUnitMaskIterator I(F, &TRI); I.isValid(); ++I) {
61080dd10fSScott Constable std::pair<uint32_t, LaneBitmask> P = *I;
62080dd10fSScott Constable UnitInfo &UI = UnitInfos[P.first];
63080dd10fSScott Constable UI.Reg = F;
64080dd10fSScott Constable UI.Mask = P.second;
65080dd10fSScott Constable }
66080dd10fSScott Constable }
67080dd10fSScott Constable }
68080dd10fSScott Constable
69080dd10fSScott Constable for (const uint32_t *RM : TRI.getRegMasks())
70080dd10fSScott Constable RegMasks.insert(RM);
71080dd10fSScott Constable for (const MachineBasicBlock &B : mf)
72080dd10fSScott Constable for (const MachineInstr &In : B)
73080dd10fSScott Constable for (const MachineOperand &Op : In.operands())
74080dd10fSScott Constable if (Op.isRegMask())
75080dd10fSScott Constable RegMasks.insert(Op.getRegMask());
76080dd10fSScott Constable
77080dd10fSScott Constable MaskInfos.resize(RegMasks.size() + 1);
78080dd10fSScott Constable for (uint32_t M = 1, NM = RegMasks.size(); M <= NM; ++M) {
79080dd10fSScott Constable BitVector PU(TRI.getNumRegUnits());
80080dd10fSScott Constable const uint32_t *MB = RegMasks.get(M);
81e24537d4SMircea Trofin for (unsigned I = 1, E = TRI.getNumRegs(); I != E; ++I) {
82e24537d4SMircea Trofin if (!(MB[I / 32] & (1u << (I % 32))))
83080dd10fSScott Constable continue;
84aa2d0fbcSSergei Barannikov for (MCRegUnit Unit : TRI.regunits(MCRegister::from(I)))
85aa2d0fbcSSergei Barannikov PU.set(Unit);
86080dd10fSScott Constable }
87080dd10fSScott Constable MaskInfos[M].Units = PU.flip();
88080dd10fSScott Constable }
89f0f467aeSKrzysztof Parzyszek
90f0f467aeSKrzysztof Parzyszek AliasInfos.resize(TRI.getNumRegUnits());
91f0f467aeSKrzysztof Parzyszek for (uint32_t U = 0, NU = TRI.getNumRegUnits(); U != NU; ++U) {
92f0f467aeSKrzysztof Parzyszek BitVector AS(TRI.getNumRegs());
93f0f467aeSKrzysztof Parzyszek for (MCRegUnitRootIterator R(U, &TRI); R.isValid(); ++R)
9414bc3748SJay Foad for (MCPhysReg S : TRI.superregs_inclusive(*R))
9514bc3748SJay Foad AS.set(S);
96f0f467aeSKrzysztof Parzyszek AliasInfos[U].Regs = AS;
97f0f467aeSKrzysztof Parzyszek }
98080dd10fSScott Constable }
99080dd10fSScott Constable
alias(RegisterRef RA,RegisterRef RB) const100d57646b2SKrzysztof Parzyszek bool PhysicalRegisterInfo::alias(RegisterRef RA, RegisterRef RB) const {
101d57646b2SKrzysztof Parzyszek return !disjoint(getUnits(RA), getUnits(RB));
102d57646b2SKrzysztof Parzyszek }
103d57646b2SKrzysztof Parzyszek
getAliasSet(RegisterId Reg) const104080dd10fSScott Constable std::set<RegisterId> PhysicalRegisterInfo::getAliasSet(RegisterId Reg) const {
1052af7036dSKrzysztof Parzyszek // Do not include Reg in the alias set.
106080dd10fSScott Constable std::set<RegisterId> AS;
1072af7036dSKrzysztof Parzyszek assert(!RegisterRef::isUnitId(Reg) && "No units allowed");
1082af7036dSKrzysztof Parzyszek if (RegisterRef::isMaskId(Reg)) {
109080dd10fSScott Constable // XXX SLOW
110080dd10fSScott Constable const uint32_t *MB = getRegMaskBits(Reg);
111080dd10fSScott Constable for (unsigned i = 1, e = TRI.getNumRegs(); i != e; ++i) {
112080dd10fSScott Constable if (MB[i / 32] & (1u << (i % 32)))
113080dd10fSScott Constable continue;
114080dd10fSScott Constable AS.insert(i);
115080dd10fSScott Constable }
116080dd10fSScott Constable return AS;
117080dd10fSScott Constable }
118080dd10fSScott Constable
1192af7036dSKrzysztof Parzyszek assert(RegisterRef::isRegId(Reg));
120080dd10fSScott Constable for (MCRegAliasIterator AI(Reg, &TRI, false); AI.isValid(); ++AI)
121080dd10fSScott Constable AS.insert(*AI);
122bd66f4b1SKrzysztof Parzyszek
123080dd10fSScott Constable return AS;
124080dd10fSScott Constable }
125080dd10fSScott Constable
getUnits(RegisterRef RR) const126d57646b2SKrzysztof Parzyszek std::set<RegisterId> PhysicalRegisterInfo::getUnits(RegisterRef RR) const {
127d57646b2SKrzysztof Parzyszek std::set<RegisterId> Units;
128080dd10fSScott Constable
129d57646b2SKrzysztof Parzyszek if (RR.Reg == 0)
130d57646b2SKrzysztof Parzyszek return Units; // Empty
131d57646b2SKrzysztof Parzyszek
132d57646b2SKrzysztof Parzyszek if (RR.isReg()) {
133d57646b2SKrzysztof Parzyszek if (RR.Mask.none())
134d57646b2SKrzysztof Parzyszek return Units; // Empty
135d57646b2SKrzysztof Parzyszek for (MCRegUnitMaskIterator UM(RR.idx(), &TRI); UM.isValid(); ++UM) {
136d57646b2SKrzysztof Parzyszek auto [U, M] = *UM;
137*6551cfa8SJay Foad if ((M & RR.Mask).any())
138d57646b2SKrzysztof Parzyszek Units.insert(U);
139080dd10fSScott Constable }
140d57646b2SKrzysztof Parzyszek return Units;
141080dd10fSScott Constable }
142080dd10fSScott Constable
143d57646b2SKrzysztof Parzyszek assert(RR.isMask());
144080dd10fSScott Constable unsigned NumRegs = TRI.getNumRegs();
145d57646b2SKrzysztof Parzyszek const uint32_t *MB = getRegMaskBits(RR.idx());
146d57646b2SKrzysztof Parzyszek for (unsigned I = 0, E = (NumRegs + 31) / 32; I != E; ++I) {
147d57646b2SKrzysztof Parzyszek uint32_t C = ~MB[I]; // Clobbered regs
148d57646b2SKrzysztof Parzyszek if (I == 0) // Reg 0 should be ignored
149d57646b2SKrzysztof Parzyszek C &= maskLeadingOnes<unsigned>(31);
150d57646b2SKrzysztof Parzyszek if (I + 1 == E && NumRegs % 32 != 0) // Last word may be partial
151d57646b2SKrzysztof Parzyszek C &= maskTrailingOnes<unsigned>(NumRegs % 32);
152d57646b2SKrzysztof Parzyszek if (C == 0)
153d57646b2SKrzysztof Parzyszek continue;
154d57646b2SKrzysztof Parzyszek while (C != 0) {
155d57646b2SKrzysztof Parzyszek unsigned T = llvm::countr_zero(C);
156d57646b2SKrzysztof Parzyszek unsigned CR = 32 * I + T; // Clobbered reg
157da7892f7SJay Foad for (MCRegUnit U : TRI.regunits(CR))
158da7892f7SJay Foad Units.insert(U);
159d57646b2SKrzysztof Parzyszek C &= ~(1u << T);
160080dd10fSScott Constable }
161d57646b2SKrzysztof Parzyszek }
162d57646b2SKrzysztof Parzyszek return Units;
163080dd10fSScott Constable }
164080dd10fSScott Constable
mapTo(RegisterRef RR,unsigned R) const165080dd10fSScott Constable RegisterRef PhysicalRegisterInfo::mapTo(RegisterRef RR, unsigned R) const {
166080dd10fSScott Constable if (RR.Reg == R)
167080dd10fSScott Constable return RR;
168080dd10fSScott Constable if (unsigned Idx = TRI.getSubRegIndex(R, RR.Reg))
169080dd10fSScott Constable return RegisterRef(R, TRI.composeSubRegIndexLaneMask(Idx, RR.Mask));
170080dd10fSScott Constable if (unsigned Idx = TRI.getSubRegIndex(RR.Reg, R)) {
171080dd10fSScott Constable const RegInfo &RI = RegInfos[R];
1727fc73104SKrzysztof Parzyszek LaneBitmask RCM =
1737fc73104SKrzysztof Parzyszek RI.RegClass ? RI.RegClass->LaneMask : LaneBitmask::getAll();
174080dd10fSScott Constable LaneBitmask M = TRI.reverseComposeSubRegIndexLaneMask(Idx, RR.Mask);
175080dd10fSScott Constable return RegisterRef(R, M & RCM);
176080dd10fSScott Constable }
177080dd10fSScott Constable llvm_unreachable("Invalid arguments: unrelated registers?");
178080dd10fSScott Constable }
179080dd10fSScott Constable
equal_to(RegisterRef A,RegisterRef B) const1802af7036dSKrzysztof Parzyszek bool PhysicalRegisterInfo::equal_to(RegisterRef A, RegisterRef B) const {
1812af7036dSKrzysztof Parzyszek if (!A.isReg() || !B.isReg()) {
1822af7036dSKrzysztof Parzyszek // For non-regs, or comparing reg and non-reg, use only the Reg member.
1832af7036dSKrzysztof Parzyszek return A.Reg == B.Reg;
1842af7036dSKrzysztof Parzyszek }
1852af7036dSKrzysztof Parzyszek
1862af7036dSKrzysztof Parzyszek if (A.Reg == B.Reg)
1872af7036dSKrzysztof Parzyszek return A.Mask == B.Mask;
1882af7036dSKrzysztof Parzyszek
1892af7036dSKrzysztof Parzyszek // Compare reg units lexicographically.
1902af7036dSKrzysztof Parzyszek MCRegUnitMaskIterator AI(A.Reg, &getTRI());
1912af7036dSKrzysztof Parzyszek MCRegUnitMaskIterator BI(B.Reg, &getTRI());
1922af7036dSKrzysztof Parzyszek while (AI.isValid() && BI.isValid()) {
1932af7036dSKrzysztof Parzyszek auto [AReg, AMask] = *AI;
1942af7036dSKrzysztof Parzyszek auto [BReg, BMask] = *BI;
1952af7036dSKrzysztof Parzyszek
1962af7036dSKrzysztof Parzyszek // If both iterators point to a unit contained in both A and B, then
1972af7036dSKrzysztof Parzyszek // compare the units.
1982af7036dSKrzysztof Parzyszek if ((AMask & A.Mask).any() && (BMask & B.Mask).any()) {
1992af7036dSKrzysztof Parzyszek if (AReg != BReg)
2002af7036dSKrzysztof Parzyszek return false;
2012af7036dSKrzysztof Parzyszek // Units are equal, move on to the next ones.
2022af7036dSKrzysztof Parzyszek ++AI;
2032af7036dSKrzysztof Parzyszek ++BI;
2042af7036dSKrzysztof Parzyszek continue;
2052af7036dSKrzysztof Parzyszek }
2062af7036dSKrzysztof Parzyszek
2072af7036dSKrzysztof Parzyszek if ((AMask & A.Mask).none())
2082af7036dSKrzysztof Parzyszek ++AI;
2092af7036dSKrzysztof Parzyszek if ((BMask & B.Mask).none())
2102af7036dSKrzysztof Parzyszek ++BI;
2112af7036dSKrzysztof Parzyszek }
2122af7036dSKrzysztof Parzyszek // One or both have reached the end.
2132af7036dSKrzysztof Parzyszek return static_cast<int>(AI.isValid()) == static_cast<int>(BI.isValid());
2142af7036dSKrzysztof Parzyszek }
2152af7036dSKrzysztof Parzyszek
less(RegisterRef A,RegisterRef B) const2162af7036dSKrzysztof Parzyszek bool PhysicalRegisterInfo::less(RegisterRef A, RegisterRef B) const {
2172af7036dSKrzysztof Parzyszek if (!A.isReg() || !B.isReg()) {
2182af7036dSKrzysztof Parzyszek // For non-regs, or comparing reg and non-reg, use only the Reg member.
2192af7036dSKrzysztof Parzyszek return A.Reg < B.Reg;
2202af7036dSKrzysztof Parzyszek }
2212af7036dSKrzysztof Parzyszek
2222af7036dSKrzysztof Parzyszek if (A.Reg == B.Reg)
2232af7036dSKrzysztof Parzyszek return A.Mask < B.Mask;
2242af7036dSKrzysztof Parzyszek if (A.Mask == B.Mask)
2252af7036dSKrzysztof Parzyszek return A.Reg < B.Reg;
2262af7036dSKrzysztof Parzyszek
2272af7036dSKrzysztof Parzyszek // Compare reg units lexicographically.
2282af7036dSKrzysztof Parzyszek llvm::MCRegUnitMaskIterator AI(A.Reg, &getTRI());
2292af7036dSKrzysztof Parzyszek llvm::MCRegUnitMaskIterator BI(B.Reg, &getTRI());
2302af7036dSKrzysztof Parzyszek while (AI.isValid() && BI.isValid()) {
2312af7036dSKrzysztof Parzyszek auto [AReg, AMask] = *AI;
2322af7036dSKrzysztof Parzyszek auto [BReg, BMask] = *BI;
2332af7036dSKrzysztof Parzyszek
2342af7036dSKrzysztof Parzyszek // If both iterators point to a unit contained in both A and B, then
2352af7036dSKrzysztof Parzyszek // compare the units.
2362af7036dSKrzysztof Parzyszek if ((AMask & A.Mask).any() && (BMask & B.Mask).any()) {
2372af7036dSKrzysztof Parzyszek if (AReg != BReg)
2382af7036dSKrzysztof Parzyszek return AReg < BReg;
2392af7036dSKrzysztof Parzyszek // Units are equal, move on to the next ones.
2402af7036dSKrzysztof Parzyszek ++AI;
2412af7036dSKrzysztof Parzyszek ++BI;
2422af7036dSKrzysztof Parzyszek continue;
2432af7036dSKrzysztof Parzyszek }
2442af7036dSKrzysztof Parzyszek
2452af7036dSKrzysztof Parzyszek if ((AMask & A.Mask).none())
2462af7036dSKrzysztof Parzyszek ++AI;
2472af7036dSKrzysztof Parzyszek if ((BMask & B.Mask).none())
2482af7036dSKrzysztof Parzyszek ++BI;
2492af7036dSKrzysztof Parzyszek }
2502af7036dSKrzysztof Parzyszek // One or both have reached the end: assume invalid < valid.
2512af7036dSKrzysztof Parzyszek return static_cast<int>(AI.isValid()) < static_cast<int>(BI.isValid());
2522af7036dSKrzysztof Parzyszek }
2532af7036dSKrzysztof Parzyszek
print(raw_ostream & OS,RegisterRef A) const2542af7036dSKrzysztof Parzyszek void PhysicalRegisterInfo::print(raw_ostream &OS, RegisterRef A) const {
2552af7036dSKrzysztof Parzyszek if (A.Reg == 0 || A.isReg()) {
256dbee6567SKrzysztof Parzyszek if (0 < A.idx() && A.idx() < TRI.getNumRegs())
257dbee6567SKrzysztof Parzyszek OS << TRI.getName(A.idx());
2582af7036dSKrzysztof Parzyszek else
259369dba54SKrzysztof Parzyszek OS << printReg(A.idx(), &TRI);
2602af7036dSKrzysztof Parzyszek OS << PrintLaneMaskShort(A.Mask);
2612af7036dSKrzysztof Parzyszek } else if (A.isUnit()) {
262dbee6567SKrzysztof Parzyszek OS << printRegUnit(A.idx(), &TRI);
2632af7036dSKrzysztof Parzyszek } else {
2642af7036dSKrzysztof Parzyszek assert(A.isMask());
265369dba54SKrzysztof Parzyszek // RegMask SS flag is preserved by idx().
266369dba54SKrzysztof Parzyszek unsigned Idx = Register::stackSlot2Index(A.idx());
267369dba54SKrzysztof Parzyszek const char *Fmt = Idx < 0x10000 ? "%04x" : "%08x";
268369dba54SKrzysztof Parzyszek OS << "M#" << format(Fmt, Idx);
2692af7036dSKrzysztof Parzyszek }
2702af7036dSKrzysztof Parzyszek }
2712af7036dSKrzysztof Parzyszek
print(raw_ostream & OS,const RegisterAggr & A) const2722af7036dSKrzysztof Parzyszek void PhysicalRegisterInfo::print(raw_ostream &OS, const RegisterAggr &A) const {
2732af7036dSKrzysztof Parzyszek OS << '{';
2742af7036dSKrzysztof Parzyszek for (unsigned U : A.units())
2752af7036dSKrzysztof Parzyszek OS << ' ' << printRegUnit(U, &TRI);
2762af7036dSKrzysztof Parzyszek OS << " }";
2772af7036dSKrzysztof Parzyszek }
2782af7036dSKrzysztof Parzyszek
hasAliasOf(RegisterRef RR) const279080dd10fSScott Constable bool RegisterAggr::hasAliasOf(RegisterRef RR) const {
2802af7036dSKrzysztof Parzyszek if (RR.isMask())
281080dd10fSScott Constable return Units.anyCommon(PRI.getMaskUnits(RR.Reg));
282080dd10fSScott Constable
283080dd10fSScott Constable for (MCRegUnitMaskIterator U(RR.Reg, &PRI.getTRI()); U.isValid(); ++U) {
284080dd10fSScott Constable std::pair<uint32_t, LaneBitmask> P = *U;
285*6551cfa8SJay Foad if ((P.second & RR.Mask).any())
286080dd10fSScott Constable if (Units.test(P.first))
287080dd10fSScott Constable return true;
288080dd10fSScott Constable }
289080dd10fSScott Constable return false;
290080dd10fSScott Constable }
291080dd10fSScott Constable
hasCoverOf(RegisterRef RR) const292080dd10fSScott Constable bool RegisterAggr::hasCoverOf(RegisterRef RR) const {
2932af7036dSKrzysztof Parzyszek if (RR.isMask()) {
294080dd10fSScott Constable BitVector T(PRI.getMaskUnits(RR.Reg));
295080dd10fSScott Constable return T.reset(Units).none();
296080dd10fSScott Constable }
297080dd10fSScott Constable
298080dd10fSScott Constable for (MCRegUnitMaskIterator U(RR.Reg, &PRI.getTRI()); U.isValid(); ++U) {
299080dd10fSScott Constable std::pair<uint32_t, LaneBitmask> P = *U;
300*6551cfa8SJay Foad if ((P.second & RR.Mask).any())
301080dd10fSScott Constable if (!Units.test(P.first))
302080dd10fSScott Constable return false;
303080dd10fSScott Constable }
304080dd10fSScott Constable return true;
305080dd10fSScott Constable }
306080dd10fSScott Constable
insert(RegisterRef RR)307080dd10fSScott Constable RegisterAggr &RegisterAggr::insert(RegisterRef RR) {
3082af7036dSKrzysztof Parzyszek if (RR.isMask()) {
309080dd10fSScott Constable Units |= PRI.getMaskUnits(RR.Reg);
310080dd10fSScott Constable return *this;
311080dd10fSScott Constable }
312080dd10fSScott Constable
313080dd10fSScott Constable for (MCRegUnitMaskIterator U(RR.Reg, &PRI.getTRI()); U.isValid(); ++U) {
314080dd10fSScott Constable std::pair<uint32_t, LaneBitmask> P = *U;
315*6551cfa8SJay Foad if ((P.second & RR.Mask).any())
316080dd10fSScott Constable Units.set(P.first);
317080dd10fSScott Constable }
318080dd10fSScott Constable return *this;
319080dd10fSScott Constable }
320080dd10fSScott Constable
insert(const RegisterAggr & RG)321080dd10fSScott Constable RegisterAggr &RegisterAggr::insert(const RegisterAggr &RG) {
322080dd10fSScott Constable Units |= RG.Units;
323080dd10fSScott Constable return *this;
324080dd10fSScott Constable }
325080dd10fSScott Constable
intersect(RegisterRef RR)326080dd10fSScott Constable RegisterAggr &RegisterAggr::intersect(RegisterRef RR) {
327080dd10fSScott Constable return intersect(RegisterAggr(PRI).insert(RR));
328080dd10fSScott Constable }
329080dd10fSScott Constable
intersect(const RegisterAggr & RG)330080dd10fSScott Constable RegisterAggr &RegisterAggr::intersect(const RegisterAggr &RG) {
331080dd10fSScott Constable Units &= RG.Units;
332080dd10fSScott Constable return *this;
333080dd10fSScott Constable }
334080dd10fSScott Constable
clear(RegisterRef RR)335080dd10fSScott Constable RegisterAggr &RegisterAggr::clear(RegisterRef RR) {
336080dd10fSScott Constable return clear(RegisterAggr(PRI).insert(RR));
337080dd10fSScott Constable }
338080dd10fSScott Constable
clear(const RegisterAggr & RG)339080dd10fSScott Constable RegisterAggr &RegisterAggr::clear(const RegisterAggr &RG) {
340080dd10fSScott Constable Units.reset(RG.Units);
341080dd10fSScott Constable return *this;
342080dd10fSScott Constable }
343080dd10fSScott Constable
intersectWith(RegisterRef RR) const344080dd10fSScott Constable RegisterRef RegisterAggr::intersectWith(RegisterRef RR) const {
345080dd10fSScott Constable RegisterAggr T(PRI);
346080dd10fSScott Constable T.insert(RR).intersect(*this);
347080dd10fSScott Constable if (T.empty())
348080dd10fSScott Constable return RegisterRef();
349080dd10fSScott Constable RegisterRef NR = T.makeRegRef();
350080dd10fSScott Constable assert(NR);
351080dd10fSScott Constable return NR;
352080dd10fSScott Constable }
353080dd10fSScott Constable
clearIn(RegisterRef RR) const354080dd10fSScott Constable RegisterRef RegisterAggr::clearIn(RegisterRef RR) const {
355080dd10fSScott Constable return RegisterAggr(PRI).insert(RR).clear(*this).makeRegRef();
356080dd10fSScott Constable }
357080dd10fSScott Constable
makeRegRef() const358080dd10fSScott Constable RegisterRef RegisterAggr::makeRegRef() const {
359080dd10fSScott Constable int U = Units.find_first();
360080dd10fSScott Constable if (U < 0)
361080dd10fSScott Constable return RegisterRef();
362080dd10fSScott Constable
363080dd10fSScott Constable // Find the set of all registers that are aliased to all the units
364080dd10fSScott Constable // in this aggregate.
365080dd10fSScott Constable
366080dd10fSScott Constable // Get all the registers aliased to the first unit in the bit vector.
367f0f467aeSKrzysztof Parzyszek BitVector Regs = PRI.getUnitAliases(U);
368080dd10fSScott Constable U = Units.find_next(U);
369080dd10fSScott Constable
370080dd10fSScott Constable // For each other unit, intersect it with the set of all registers
371080dd10fSScott Constable // aliased that unit.
372080dd10fSScott Constable while (U >= 0) {
373f0f467aeSKrzysztof Parzyszek Regs &= PRI.getUnitAliases(U);
374080dd10fSScott Constable U = Units.find_next(U);
375080dd10fSScott Constable }
376080dd10fSScott Constable
377080dd10fSScott Constable // If there is at least one register remaining, pick the first one,
378080dd10fSScott Constable // and consolidate the masks of all of its units contained in this
379080dd10fSScott Constable // aggregate.
380080dd10fSScott Constable
381080dd10fSScott Constable int F = Regs.find_first();
382080dd10fSScott Constable if (F <= 0)
383080dd10fSScott Constable return RegisterRef();
384080dd10fSScott Constable
385080dd10fSScott Constable LaneBitmask M;
386080dd10fSScott Constable for (MCRegUnitMaskIterator I(F, &PRI.getTRI()); I.isValid(); ++I) {
387080dd10fSScott Constable std::pair<uint32_t, LaneBitmask> P = *I;
388080dd10fSScott Constable if (Units.test(P.first))
389*6551cfa8SJay Foad M |= P.second;
390080dd10fSScott Constable }
391080dd10fSScott Constable return RegisterRef(F, M);
392080dd10fSScott Constable }
393080dd10fSScott Constable
ref_iterator(const RegisterAggr & RG,bool End)3942af7036dSKrzysztof Parzyszek RegisterAggr::ref_iterator::ref_iterator(const RegisterAggr &RG, bool End)
395080dd10fSScott Constable : Owner(&RG) {
396080dd10fSScott Constable for (int U = RG.Units.find_first(); U >= 0; U = RG.Units.find_next(U)) {
397080dd10fSScott Constable RegisterRef R = RG.PRI.getRefForUnit(U);
398080dd10fSScott Constable Masks[R.Reg] |= R.Mask;
399080dd10fSScott Constable }
400080dd10fSScott Constable Pos = End ? Masks.end() : Masks.begin();
401080dd10fSScott Constable Index = End ? Masks.size() : 0;
402080dd10fSScott Constable }
40306d42573SKrzysztof Parzyszek
operator <<(raw_ostream & OS,const RegisterAggr & A)404375d7980SKrzysztof Parzyszek raw_ostream &operator<<(raw_ostream &OS, const RegisterAggr &A) {
4052af7036dSKrzysztof Parzyszek A.getPRI().print(OS, A);
40606d42573SKrzysztof Parzyszek return OS;
40706d42573SKrzysztof Parzyszek }
4082af7036dSKrzysztof Parzyszek
operator <<(raw_ostream & OS,const PrintLaneMaskShort & P)409375d7980SKrzysztof Parzyszek raw_ostream &operator<<(raw_ostream &OS, const PrintLaneMaskShort &P) {
4102af7036dSKrzysztof Parzyszek if (P.Mask.all())
4112af7036dSKrzysztof Parzyszek return OS;
4122af7036dSKrzysztof Parzyszek if (P.Mask.none())
4132af7036dSKrzysztof Parzyszek return OS << ":*none*";
4142af7036dSKrzysztof Parzyszek
4152af7036dSKrzysztof Parzyszek LaneBitmask::Type Val = P.Mask.getAsInteger();
4162af7036dSKrzysztof Parzyszek if ((Val & 0xffff) == Val)
4172af7036dSKrzysztof Parzyszek return OS << ':' << format("%04llX", Val);
4182af7036dSKrzysztof Parzyszek if ((Val & 0xffffffff) == Val)
4192af7036dSKrzysztof Parzyszek return OS << ':' << format("%08llX", Val);
4202af7036dSKrzysztof Parzyszek return OS << ':' << PrintLaneMask(P.Mask);
4212af7036dSKrzysztof Parzyszek }
422375d7980SKrzysztof Parzyszek
423375d7980SKrzysztof Parzyszek } // namespace llvm::rdf
424