xref: /freebsd-src/contrib/llvm-project/llvm/lib/CodeGen/RDFRegisters.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
10946e70aSDimitry Andric //===- RDFRegisters.cpp ---------------------------------------------------===//
20946e70aSDimitry Andric //
30946e70aSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40946e70aSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50946e70aSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60946e70aSDimitry Andric //
70946e70aSDimitry Andric //===----------------------------------------------------------------------===//
80946e70aSDimitry Andric 
90946e70aSDimitry Andric #include "llvm/ADT/BitVector.h"
100946e70aSDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
110946e70aSDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
120946e70aSDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
130946e70aSDimitry Andric #include "llvm/CodeGen/RDFRegisters.h"
140946e70aSDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
150946e70aSDimitry Andric #include "llvm/MC/LaneBitmask.h"
160946e70aSDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
170946e70aSDimitry Andric #include "llvm/Support/ErrorHandling.h"
1806c3fb27SDimitry Andric #include "llvm/Support/Format.h"
1906c3fb27SDimitry Andric #include "llvm/Support/MathExtras.h"
200946e70aSDimitry Andric #include "llvm/Support/raw_ostream.h"
210946e70aSDimitry Andric #include <cassert>
220946e70aSDimitry Andric #include <cstdint>
230946e70aSDimitry Andric #include <set>
240946e70aSDimitry Andric #include <utility>
250946e70aSDimitry Andric 
2606c3fb27SDimitry Andric namespace llvm::rdf {
270946e70aSDimitry Andric 
PhysicalRegisterInfo(const TargetRegisterInfo & tri,const MachineFunction & mf)280946e70aSDimitry Andric PhysicalRegisterInfo::PhysicalRegisterInfo(const TargetRegisterInfo &tri,
290946e70aSDimitry Andric                                            const MachineFunction &mf)
300946e70aSDimitry Andric     : TRI(tri) {
310946e70aSDimitry Andric   RegInfos.resize(TRI.getNumRegs());
320946e70aSDimitry Andric 
330946e70aSDimitry Andric   BitVector BadRC(TRI.getNumRegs());
340946e70aSDimitry Andric   for (const TargetRegisterClass *RC : TRI.regclasses()) {
350946e70aSDimitry Andric     for (MCPhysReg R : *RC) {
360946e70aSDimitry Andric       RegInfo &RI = RegInfos[R];
370946e70aSDimitry Andric       if (RI.RegClass != nullptr && !BadRC[R]) {
380946e70aSDimitry Andric         if (RC->LaneMask != RI.RegClass->LaneMask) {
390946e70aSDimitry Andric           BadRC.set(R);
400946e70aSDimitry Andric           RI.RegClass = nullptr;
410946e70aSDimitry Andric         }
420946e70aSDimitry Andric       } else
430946e70aSDimitry Andric         RI.RegClass = RC;
440946e70aSDimitry Andric     }
450946e70aSDimitry Andric   }
460946e70aSDimitry Andric 
470946e70aSDimitry Andric   UnitInfos.resize(TRI.getNumRegUnits());
480946e70aSDimitry Andric 
490946e70aSDimitry Andric   for (uint32_t U = 0, NU = TRI.getNumRegUnits(); U != NU; ++U) {
500946e70aSDimitry Andric     if (UnitInfos[U].Reg != 0)
510946e70aSDimitry Andric       continue;
520946e70aSDimitry Andric     MCRegUnitRootIterator R(U, &TRI);
530946e70aSDimitry Andric     assert(R.isValid());
540946e70aSDimitry Andric     RegisterId F = *R;
550946e70aSDimitry Andric     ++R;
560946e70aSDimitry Andric     if (R.isValid()) {
570946e70aSDimitry Andric       UnitInfos[U].Mask = LaneBitmask::getAll();
580946e70aSDimitry Andric       UnitInfos[U].Reg = F;
590946e70aSDimitry Andric     } else {
600946e70aSDimitry Andric       for (MCRegUnitMaskIterator I(F, &TRI); I.isValid(); ++I) {
610946e70aSDimitry Andric         std::pair<uint32_t, LaneBitmask> P = *I;
620946e70aSDimitry Andric         UnitInfo &UI = UnitInfos[P.first];
630946e70aSDimitry Andric         UI.Reg = F;
640946e70aSDimitry Andric         UI.Mask = P.second;
650946e70aSDimitry Andric       }
660946e70aSDimitry Andric     }
670946e70aSDimitry Andric   }
680946e70aSDimitry Andric 
690946e70aSDimitry Andric   for (const uint32_t *RM : TRI.getRegMasks())
700946e70aSDimitry Andric     RegMasks.insert(RM);
710946e70aSDimitry Andric   for (const MachineBasicBlock &B : mf)
720946e70aSDimitry Andric     for (const MachineInstr &In : B)
730946e70aSDimitry Andric       for (const MachineOperand &Op : In.operands())
740946e70aSDimitry Andric         if (Op.isRegMask())
750946e70aSDimitry Andric           RegMasks.insert(Op.getRegMask());
760946e70aSDimitry Andric 
770946e70aSDimitry Andric   MaskInfos.resize(RegMasks.size() + 1);
780946e70aSDimitry Andric   for (uint32_t M = 1, NM = RegMasks.size(); M <= NM; ++M) {
790946e70aSDimitry Andric     BitVector PU(TRI.getNumRegUnits());
800946e70aSDimitry Andric     const uint32_t *MB = RegMasks.get(M);
81e8d8bef9SDimitry Andric     for (unsigned I = 1, E = TRI.getNumRegs(); I != E; ++I) {
82e8d8bef9SDimitry Andric       if (!(MB[I / 32] & (1u << (I % 32))))
830946e70aSDimitry Andric         continue;
8406c3fb27SDimitry Andric       for (MCRegUnit Unit : TRI.regunits(MCRegister::from(I)))
8506c3fb27SDimitry Andric         PU.set(Unit);
860946e70aSDimitry Andric     }
870946e70aSDimitry Andric     MaskInfos[M].Units = PU.flip();
880946e70aSDimitry Andric   }
890946e70aSDimitry Andric 
90e8d8bef9SDimitry Andric   AliasInfos.resize(TRI.getNumRegUnits());
91e8d8bef9SDimitry Andric   for (uint32_t U = 0, NU = TRI.getNumRegUnits(); U != NU; ++U) {
92e8d8bef9SDimitry Andric     BitVector AS(TRI.getNumRegs());
93e8d8bef9SDimitry Andric     for (MCRegUnitRootIterator R(U, &TRI); R.isValid(); ++R)
9406c3fb27SDimitry Andric       for (MCPhysReg S : TRI.superregs_inclusive(*R))
9506c3fb27SDimitry Andric         AS.set(S);
96e8d8bef9SDimitry Andric     AliasInfos[U].Regs = AS;
97e8d8bef9SDimitry Andric   }
980946e70aSDimitry Andric }
990946e70aSDimitry Andric 
alias(RegisterRef RA,RegisterRef RB) const10006c3fb27SDimitry Andric bool PhysicalRegisterInfo::alias(RegisterRef RA, RegisterRef RB) const {
10106c3fb27SDimitry Andric   return !disjoint(getUnits(RA), getUnits(RB));
10206c3fb27SDimitry Andric }
10306c3fb27SDimitry Andric 
getAliasSet(RegisterId Reg) const1040946e70aSDimitry Andric std::set<RegisterId> PhysicalRegisterInfo::getAliasSet(RegisterId Reg) const {
10506c3fb27SDimitry Andric   // Do not include Reg in the alias set.
1060946e70aSDimitry Andric   std::set<RegisterId> AS;
10706c3fb27SDimitry Andric   assert(!RegisterRef::isUnitId(Reg) && "No units allowed");
10806c3fb27SDimitry Andric   if (RegisterRef::isMaskId(Reg)) {
1090946e70aSDimitry Andric     // XXX SLOW
1100946e70aSDimitry Andric     const uint32_t *MB = getRegMaskBits(Reg);
1110946e70aSDimitry Andric     for (unsigned i = 1, e = TRI.getNumRegs(); i != e; ++i) {
1120946e70aSDimitry Andric       if (MB[i / 32] & (1u << (i % 32)))
1130946e70aSDimitry Andric         continue;
1140946e70aSDimitry Andric       AS.insert(i);
1150946e70aSDimitry Andric     }
1160946e70aSDimitry Andric     return AS;
1170946e70aSDimitry Andric   }
1180946e70aSDimitry Andric 
11906c3fb27SDimitry Andric   assert(RegisterRef::isRegId(Reg));
1200946e70aSDimitry Andric   for (MCRegAliasIterator AI(Reg, &TRI, false); AI.isValid(); ++AI)
1210946e70aSDimitry Andric     AS.insert(*AI);
12206c3fb27SDimitry Andric 
1230946e70aSDimitry Andric   return AS;
1240946e70aSDimitry Andric }
1250946e70aSDimitry Andric 
getUnits(RegisterRef RR) const12606c3fb27SDimitry Andric std::set<RegisterId> PhysicalRegisterInfo::getUnits(RegisterRef RR) const {
12706c3fb27SDimitry Andric   std::set<RegisterId> Units;
1280946e70aSDimitry Andric 
12906c3fb27SDimitry Andric   if (RR.Reg == 0)
13006c3fb27SDimitry Andric     return Units; // Empty
13106c3fb27SDimitry Andric 
13206c3fb27SDimitry Andric   if (RR.isReg()) {
13306c3fb27SDimitry Andric     if (RR.Mask.none())
13406c3fb27SDimitry Andric       return Units; // Empty
13506c3fb27SDimitry Andric     for (MCRegUnitMaskIterator UM(RR.idx(), &TRI); UM.isValid(); ++UM) {
13606c3fb27SDimitry Andric       auto [U, M] = *UM;
137*5f757f3fSDimitry Andric       if ((M & RR.Mask).any())
13806c3fb27SDimitry Andric         Units.insert(U);
1390946e70aSDimitry Andric     }
14006c3fb27SDimitry Andric     return Units;
1410946e70aSDimitry Andric   }
1420946e70aSDimitry Andric 
14306c3fb27SDimitry Andric   assert(RR.isMask());
1440946e70aSDimitry Andric   unsigned NumRegs = TRI.getNumRegs();
14506c3fb27SDimitry Andric   const uint32_t *MB = getRegMaskBits(RR.idx());
14606c3fb27SDimitry Andric   for (unsigned I = 0, E = (NumRegs + 31) / 32; I != E; ++I) {
14706c3fb27SDimitry Andric     uint32_t C = ~MB[I]; // Clobbered regs
14806c3fb27SDimitry Andric     if (I == 0)          // Reg 0 should be ignored
14906c3fb27SDimitry Andric       C &= maskLeadingOnes<unsigned>(31);
15006c3fb27SDimitry Andric     if (I + 1 == E && NumRegs % 32 != 0) // Last word may be partial
15106c3fb27SDimitry Andric       C &= maskTrailingOnes<unsigned>(NumRegs % 32);
15206c3fb27SDimitry Andric     if (C == 0)
15306c3fb27SDimitry Andric       continue;
15406c3fb27SDimitry Andric     while (C != 0) {
15506c3fb27SDimitry Andric       unsigned T = llvm::countr_zero(C);
15606c3fb27SDimitry Andric       unsigned CR = 32 * I + T; // Clobbered reg
15706c3fb27SDimitry Andric       for (MCRegUnit U : TRI.regunits(CR))
15806c3fb27SDimitry Andric         Units.insert(U);
15906c3fb27SDimitry Andric       C &= ~(1u << T);
1600946e70aSDimitry Andric     }
16106c3fb27SDimitry Andric   }
16206c3fb27SDimitry Andric   return Units;
1630946e70aSDimitry Andric }
1640946e70aSDimitry Andric 
mapTo(RegisterRef RR,unsigned R) const1650946e70aSDimitry Andric RegisterRef PhysicalRegisterInfo::mapTo(RegisterRef RR, unsigned R) const {
1660946e70aSDimitry Andric   if (RR.Reg == R)
1670946e70aSDimitry Andric     return RR;
1680946e70aSDimitry Andric   if (unsigned Idx = TRI.getSubRegIndex(R, RR.Reg))
1690946e70aSDimitry Andric     return RegisterRef(R, TRI.composeSubRegIndexLaneMask(Idx, RR.Mask));
1700946e70aSDimitry Andric   if (unsigned Idx = TRI.getSubRegIndex(RR.Reg, R)) {
1710946e70aSDimitry Andric     const RegInfo &RI = RegInfos[R];
17206c3fb27SDimitry Andric     LaneBitmask RCM =
17306c3fb27SDimitry Andric         RI.RegClass ? RI.RegClass->LaneMask : LaneBitmask::getAll();
1740946e70aSDimitry Andric     LaneBitmask M = TRI.reverseComposeSubRegIndexLaneMask(Idx, RR.Mask);
1750946e70aSDimitry Andric     return RegisterRef(R, M & RCM);
1760946e70aSDimitry Andric   }
1770946e70aSDimitry Andric   llvm_unreachable("Invalid arguments: unrelated registers?");
1780946e70aSDimitry Andric }
1790946e70aSDimitry Andric 
equal_to(RegisterRef A,RegisterRef B) const18006c3fb27SDimitry Andric bool PhysicalRegisterInfo::equal_to(RegisterRef A, RegisterRef B) const {
18106c3fb27SDimitry Andric   if (!A.isReg() || !B.isReg()) {
18206c3fb27SDimitry Andric     // For non-regs, or comparing reg and non-reg, use only the Reg member.
18306c3fb27SDimitry Andric     return A.Reg == B.Reg;
18406c3fb27SDimitry Andric   }
18506c3fb27SDimitry Andric 
18606c3fb27SDimitry Andric   if (A.Reg == B.Reg)
18706c3fb27SDimitry Andric     return A.Mask == B.Mask;
18806c3fb27SDimitry Andric 
18906c3fb27SDimitry Andric   // Compare reg units lexicographically.
19006c3fb27SDimitry Andric   MCRegUnitMaskIterator AI(A.Reg, &getTRI());
19106c3fb27SDimitry Andric   MCRegUnitMaskIterator BI(B.Reg, &getTRI());
19206c3fb27SDimitry Andric   while (AI.isValid() && BI.isValid()) {
19306c3fb27SDimitry Andric     auto [AReg, AMask] = *AI;
19406c3fb27SDimitry Andric     auto [BReg, BMask] = *BI;
19506c3fb27SDimitry Andric 
19606c3fb27SDimitry Andric     // If both iterators point to a unit contained in both A and B, then
19706c3fb27SDimitry Andric     // compare the units.
19806c3fb27SDimitry Andric     if ((AMask & A.Mask).any() && (BMask & B.Mask).any()) {
19906c3fb27SDimitry Andric       if (AReg != BReg)
20006c3fb27SDimitry Andric         return false;
20106c3fb27SDimitry Andric       // Units are equal, move on to the next ones.
20206c3fb27SDimitry Andric       ++AI;
20306c3fb27SDimitry Andric       ++BI;
20406c3fb27SDimitry Andric       continue;
20506c3fb27SDimitry Andric     }
20606c3fb27SDimitry Andric 
20706c3fb27SDimitry Andric     if ((AMask & A.Mask).none())
20806c3fb27SDimitry Andric       ++AI;
20906c3fb27SDimitry Andric     if ((BMask & B.Mask).none())
21006c3fb27SDimitry Andric       ++BI;
21106c3fb27SDimitry Andric   }
21206c3fb27SDimitry Andric   // One or both have reached the end.
21306c3fb27SDimitry Andric   return static_cast<int>(AI.isValid()) == static_cast<int>(BI.isValid());
21406c3fb27SDimitry Andric }
21506c3fb27SDimitry Andric 
less(RegisterRef A,RegisterRef B) const21606c3fb27SDimitry Andric bool PhysicalRegisterInfo::less(RegisterRef A, RegisterRef B) const {
21706c3fb27SDimitry Andric   if (!A.isReg() || !B.isReg()) {
21806c3fb27SDimitry Andric     // For non-regs, or comparing reg and non-reg, use only the Reg member.
21906c3fb27SDimitry Andric     return A.Reg < B.Reg;
22006c3fb27SDimitry Andric   }
22106c3fb27SDimitry Andric 
22206c3fb27SDimitry Andric   if (A.Reg == B.Reg)
22306c3fb27SDimitry Andric     return A.Mask < B.Mask;
22406c3fb27SDimitry Andric   if (A.Mask == B.Mask)
22506c3fb27SDimitry Andric     return A.Reg < B.Reg;
22606c3fb27SDimitry Andric 
22706c3fb27SDimitry Andric   // Compare reg units lexicographically.
22806c3fb27SDimitry Andric   llvm::MCRegUnitMaskIterator AI(A.Reg, &getTRI());
22906c3fb27SDimitry Andric   llvm::MCRegUnitMaskIterator BI(B.Reg, &getTRI());
23006c3fb27SDimitry Andric   while (AI.isValid() && BI.isValid()) {
23106c3fb27SDimitry Andric     auto [AReg, AMask] = *AI;
23206c3fb27SDimitry Andric     auto [BReg, BMask] = *BI;
23306c3fb27SDimitry Andric 
23406c3fb27SDimitry Andric     // If both iterators point to a unit contained in both A and B, then
23506c3fb27SDimitry Andric     // compare the units.
23606c3fb27SDimitry Andric     if ((AMask & A.Mask).any() && (BMask & B.Mask).any()) {
23706c3fb27SDimitry Andric       if (AReg != BReg)
23806c3fb27SDimitry Andric         return AReg < BReg;
23906c3fb27SDimitry Andric       // Units are equal, move on to the next ones.
24006c3fb27SDimitry Andric       ++AI;
24106c3fb27SDimitry Andric       ++BI;
24206c3fb27SDimitry Andric       continue;
24306c3fb27SDimitry Andric     }
24406c3fb27SDimitry Andric 
24506c3fb27SDimitry Andric     if ((AMask & A.Mask).none())
24606c3fb27SDimitry Andric       ++AI;
24706c3fb27SDimitry Andric     if ((BMask & B.Mask).none())
24806c3fb27SDimitry Andric       ++BI;
24906c3fb27SDimitry Andric   }
25006c3fb27SDimitry Andric   // One or both have reached the end: assume invalid < valid.
25106c3fb27SDimitry Andric   return static_cast<int>(AI.isValid()) < static_cast<int>(BI.isValid());
25206c3fb27SDimitry Andric }
25306c3fb27SDimitry Andric 
print(raw_ostream & OS,RegisterRef A) const25406c3fb27SDimitry Andric void PhysicalRegisterInfo::print(raw_ostream &OS, RegisterRef A) const {
25506c3fb27SDimitry Andric   if (A.Reg == 0 || A.isReg()) {
25606c3fb27SDimitry Andric     if (0 < A.idx() && A.idx() < TRI.getNumRegs())
25706c3fb27SDimitry Andric       OS << TRI.getName(A.idx());
25806c3fb27SDimitry Andric     else
25906c3fb27SDimitry Andric       OS << printReg(A.idx(), &TRI);
26006c3fb27SDimitry Andric     OS << PrintLaneMaskShort(A.Mask);
26106c3fb27SDimitry Andric   } else if (A.isUnit()) {
26206c3fb27SDimitry Andric     OS << printRegUnit(A.idx(), &TRI);
26306c3fb27SDimitry Andric   } else {
26406c3fb27SDimitry Andric     assert(A.isMask());
26506c3fb27SDimitry Andric     // RegMask SS flag is preserved by idx().
26606c3fb27SDimitry Andric     unsigned Idx = Register::stackSlot2Index(A.idx());
26706c3fb27SDimitry Andric     const char *Fmt = Idx < 0x10000 ? "%04x" : "%08x";
26806c3fb27SDimitry Andric     OS << "M#" << format(Fmt, Idx);
26906c3fb27SDimitry Andric   }
27006c3fb27SDimitry Andric }
27106c3fb27SDimitry Andric 
print(raw_ostream & OS,const RegisterAggr & A) const27206c3fb27SDimitry Andric void PhysicalRegisterInfo::print(raw_ostream &OS, const RegisterAggr &A) const {
27306c3fb27SDimitry Andric   OS << '{';
27406c3fb27SDimitry Andric   for (unsigned U : A.units())
27506c3fb27SDimitry Andric     OS << ' ' << printRegUnit(U, &TRI);
27606c3fb27SDimitry Andric   OS << " }";
27706c3fb27SDimitry Andric }
27806c3fb27SDimitry Andric 
hasAliasOf(RegisterRef RR) const2790946e70aSDimitry Andric bool RegisterAggr::hasAliasOf(RegisterRef RR) const {
28006c3fb27SDimitry Andric   if (RR.isMask())
2810946e70aSDimitry Andric     return Units.anyCommon(PRI.getMaskUnits(RR.Reg));
2820946e70aSDimitry Andric 
2830946e70aSDimitry Andric   for (MCRegUnitMaskIterator U(RR.Reg, &PRI.getTRI()); U.isValid(); ++U) {
2840946e70aSDimitry Andric     std::pair<uint32_t, LaneBitmask> P = *U;
285*5f757f3fSDimitry Andric     if ((P.second & RR.Mask).any())
2860946e70aSDimitry Andric       if (Units.test(P.first))
2870946e70aSDimitry Andric         return true;
2880946e70aSDimitry Andric   }
2890946e70aSDimitry Andric   return false;
2900946e70aSDimitry Andric }
2910946e70aSDimitry Andric 
hasCoverOf(RegisterRef RR) const2920946e70aSDimitry Andric bool RegisterAggr::hasCoverOf(RegisterRef RR) const {
29306c3fb27SDimitry Andric   if (RR.isMask()) {
2940946e70aSDimitry Andric     BitVector T(PRI.getMaskUnits(RR.Reg));
2950946e70aSDimitry Andric     return T.reset(Units).none();
2960946e70aSDimitry Andric   }
2970946e70aSDimitry Andric 
2980946e70aSDimitry Andric   for (MCRegUnitMaskIterator U(RR.Reg, &PRI.getTRI()); U.isValid(); ++U) {
2990946e70aSDimitry Andric     std::pair<uint32_t, LaneBitmask> P = *U;
300*5f757f3fSDimitry Andric     if ((P.second & RR.Mask).any())
3010946e70aSDimitry Andric       if (!Units.test(P.first))
3020946e70aSDimitry Andric         return false;
3030946e70aSDimitry Andric   }
3040946e70aSDimitry Andric   return true;
3050946e70aSDimitry Andric }
3060946e70aSDimitry Andric 
insert(RegisterRef RR)3070946e70aSDimitry Andric RegisterAggr &RegisterAggr::insert(RegisterRef RR) {
30806c3fb27SDimitry Andric   if (RR.isMask()) {
3090946e70aSDimitry Andric     Units |= PRI.getMaskUnits(RR.Reg);
3100946e70aSDimitry Andric     return *this;
3110946e70aSDimitry Andric   }
3120946e70aSDimitry Andric 
3130946e70aSDimitry Andric   for (MCRegUnitMaskIterator U(RR.Reg, &PRI.getTRI()); U.isValid(); ++U) {
3140946e70aSDimitry Andric     std::pair<uint32_t, LaneBitmask> P = *U;
315*5f757f3fSDimitry Andric     if ((P.second & RR.Mask).any())
3160946e70aSDimitry Andric       Units.set(P.first);
3170946e70aSDimitry Andric   }
3180946e70aSDimitry Andric   return *this;
3190946e70aSDimitry Andric }
3200946e70aSDimitry Andric 
insert(const RegisterAggr & RG)3210946e70aSDimitry Andric RegisterAggr &RegisterAggr::insert(const RegisterAggr &RG) {
3220946e70aSDimitry Andric   Units |= RG.Units;
3230946e70aSDimitry Andric   return *this;
3240946e70aSDimitry Andric }
3250946e70aSDimitry Andric 
intersect(RegisterRef RR)3260946e70aSDimitry Andric RegisterAggr &RegisterAggr::intersect(RegisterRef RR) {
3270946e70aSDimitry Andric   return intersect(RegisterAggr(PRI).insert(RR));
3280946e70aSDimitry Andric }
3290946e70aSDimitry Andric 
intersect(const RegisterAggr & RG)3300946e70aSDimitry Andric RegisterAggr &RegisterAggr::intersect(const RegisterAggr &RG) {
3310946e70aSDimitry Andric   Units &= RG.Units;
3320946e70aSDimitry Andric   return *this;
3330946e70aSDimitry Andric }
3340946e70aSDimitry Andric 
clear(RegisterRef RR)3350946e70aSDimitry Andric RegisterAggr &RegisterAggr::clear(RegisterRef RR) {
3360946e70aSDimitry Andric   return clear(RegisterAggr(PRI).insert(RR));
3370946e70aSDimitry Andric }
3380946e70aSDimitry Andric 
clear(const RegisterAggr & RG)3390946e70aSDimitry Andric RegisterAggr &RegisterAggr::clear(const RegisterAggr &RG) {
3400946e70aSDimitry Andric   Units.reset(RG.Units);
3410946e70aSDimitry Andric   return *this;
3420946e70aSDimitry Andric }
3430946e70aSDimitry Andric 
intersectWith(RegisterRef RR) const3440946e70aSDimitry Andric RegisterRef RegisterAggr::intersectWith(RegisterRef RR) const {
3450946e70aSDimitry Andric   RegisterAggr T(PRI);
3460946e70aSDimitry Andric   T.insert(RR).intersect(*this);
3470946e70aSDimitry Andric   if (T.empty())
3480946e70aSDimitry Andric     return RegisterRef();
3490946e70aSDimitry Andric   RegisterRef NR = T.makeRegRef();
3500946e70aSDimitry Andric   assert(NR);
3510946e70aSDimitry Andric   return NR;
3520946e70aSDimitry Andric }
3530946e70aSDimitry Andric 
clearIn(RegisterRef RR) const3540946e70aSDimitry Andric RegisterRef RegisterAggr::clearIn(RegisterRef RR) const {
3550946e70aSDimitry Andric   return RegisterAggr(PRI).insert(RR).clear(*this).makeRegRef();
3560946e70aSDimitry Andric }
3570946e70aSDimitry Andric 
makeRegRef() const3580946e70aSDimitry Andric RegisterRef RegisterAggr::makeRegRef() const {
3590946e70aSDimitry Andric   int U = Units.find_first();
3600946e70aSDimitry Andric   if (U < 0)
3610946e70aSDimitry Andric     return RegisterRef();
3620946e70aSDimitry Andric 
3630946e70aSDimitry Andric   // Find the set of all registers that are aliased to all the units
3640946e70aSDimitry Andric   // in this aggregate.
3650946e70aSDimitry Andric 
3660946e70aSDimitry Andric   // Get all the registers aliased to the first unit in the bit vector.
367e8d8bef9SDimitry Andric   BitVector Regs = PRI.getUnitAliases(U);
3680946e70aSDimitry Andric   U = Units.find_next(U);
3690946e70aSDimitry Andric 
3700946e70aSDimitry Andric   // For each other unit, intersect it with the set of all registers
3710946e70aSDimitry Andric   // aliased that unit.
3720946e70aSDimitry Andric   while (U >= 0) {
373e8d8bef9SDimitry Andric     Regs &= PRI.getUnitAliases(U);
3740946e70aSDimitry Andric     U = Units.find_next(U);
3750946e70aSDimitry Andric   }
3760946e70aSDimitry Andric 
3770946e70aSDimitry Andric   // If there is at least one register remaining, pick the first one,
3780946e70aSDimitry Andric   // and consolidate the masks of all of its units contained in this
3790946e70aSDimitry Andric   // aggregate.
3800946e70aSDimitry Andric 
3810946e70aSDimitry Andric   int F = Regs.find_first();
3820946e70aSDimitry Andric   if (F <= 0)
3830946e70aSDimitry Andric     return RegisterRef();
3840946e70aSDimitry Andric 
3850946e70aSDimitry Andric   LaneBitmask M;
3860946e70aSDimitry Andric   for (MCRegUnitMaskIterator I(F, &PRI.getTRI()); I.isValid(); ++I) {
3870946e70aSDimitry Andric     std::pair<uint32_t, LaneBitmask> P = *I;
3880946e70aSDimitry Andric     if (Units.test(P.first))
389*5f757f3fSDimitry Andric       M |= P.second;
3900946e70aSDimitry Andric   }
3910946e70aSDimitry Andric   return RegisterRef(F, M);
3920946e70aSDimitry Andric }
3930946e70aSDimitry Andric 
ref_iterator(const RegisterAggr & RG,bool End)39406c3fb27SDimitry Andric RegisterAggr::ref_iterator::ref_iterator(const RegisterAggr &RG, bool End)
3950946e70aSDimitry Andric     : Owner(&RG) {
3960946e70aSDimitry Andric   for (int U = RG.Units.find_first(); U >= 0; U = RG.Units.find_next(U)) {
3970946e70aSDimitry Andric     RegisterRef R = RG.PRI.getRefForUnit(U);
3980946e70aSDimitry Andric     Masks[R.Reg] |= R.Mask;
3990946e70aSDimitry Andric   }
4000946e70aSDimitry Andric   Pos = End ? Masks.end() : Masks.begin();
4010946e70aSDimitry Andric   Index = End ? Masks.size() : 0;
4020946e70aSDimitry Andric }
403e8d8bef9SDimitry Andric 
operator <<(raw_ostream & OS,const RegisterAggr & A)40406c3fb27SDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const RegisterAggr &A) {
40506c3fb27SDimitry Andric   A.getPRI().print(OS, A);
406e8d8bef9SDimitry Andric   return OS;
407e8d8bef9SDimitry Andric }
40806c3fb27SDimitry Andric 
operator <<(raw_ostream & OS,const PrintLaneMaskShort & P)40906c3fb27SDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const PrintLaneMaskShort &P) {
41006c3fb27SDimitry Andric   if (P.Mask.all())
41106c3fb27SDimitry Andric     return OS;
41206c3fb27SDimitry Andric   if (P.Mask.none())
41306c3fb27SDimitry Andric     return OS << ":*none*";
41406c3fb27SDimitry Andric 
41506c3fb27SDimitry Andric   LaneBitmask::Type Val = P.Mask.getAsInteger();
41606c3fb27SDimitry Andric   if ((Val & 0xffff) == Val)
41706c3fb27SDimitry Andric     return OS << ':' << format("%04llX", Val);
41806c3fb27SDimitry Andric   if ((Val & 0xffffffff) == Val)
41906c3fb27SDimitry Andric     return OS << ':' << format("%08llX", Val);
42006c3fb27SDimitry Andric   return OS << ':' << PrintLaneMask(P.Mask);
42106c3fb27SDimitry Andric }
42206c3fb27SDimitry Andric 
42306c3fb27SDimitry Andric } // namespace llvm::rdf
424