xref: /src/contrib/llvm-project/llvm/lib/CodeGen/RDFRegisters.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
1044eb2f6SDimitry Andric //===- RDFRegisters.cpp ---------------------------------------------------===//
271d5a254SDimitry Andric //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
671d5a254SDimitry Andric //
771d5a254SDimitry Andric //===----------------------------------------------------------------------===//
871d5a254SDimitry Andric 
971d5a254SDimitry Andric #include "llvm/ADT/BitVector.h"
1071d5a254SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
11044eb2f6SDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
12044eb2f6SDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
13cfca06d7SDimitry Andric #include "llvm/CodeGen/RDFRegisters.h"
14044eb2f6SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
15044eb2f6SDimitry Andric #include "llvm/MC/LaneBitmask.h"
16044eb2f6SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
17044eb2f6SDimitry Andric #include "llvm/Support/ErrorHandling.h"
187fa27ce4SDimitry Andric #include "llvm/Support/Format.h"
197fa27ce4SDimitry Andric #include "llvm/Support/MathExtras.h"
20044eb2f6SDimitry Andric #include "llvm/Support/raw_ostream.h"
21044eb2f6SDimitry Andric #include <cassert>
22044eb2f6SDimitry Andric #include <cstdint>
23044eb2f6SDimitry Andric #include <set>
24044eb2f6SDimitry Andric #include <utility>
2571d5a254SDimitry Andric 
267fa27ce4SDimitry Andric namespace llvm::rdf {
2771d5a254SDimitry Andric 
PhysicalRegisterInfo(const TargetRegisterInfo & tri,const MachineFunction & mf)2871d5a254SDimitry Andric PhysicalRegisterInfo::PhysicalRegisterInfo(const TargetRegisterInfo &tri,
2971d5a254SDimitry Andric                                            const MachineFunction &mf)
3071d5a254SDimitry Andric     : TRI(tri) {
3171d5a254SDimitry Andric   RegInfos.resize(TRI.getNumRegs());
3271d5a254SDimitry Andric 
3371d5a254SDimitry Andric   BitVector BadRC(TRI.getNumRegs());
3471d5a254SDimitry Andric   for (const TargetRegisterClass *RC : TRI.regclasses()) {
3571d5a254SDimitry Andric     for (MCPhysReg R : *RC) {
3671d5a254SDimitry Andric       RegInfo &RI = RegInfos[R];
3771d5a254SDimitry Andric       if (RI.RegClass != nullptr && !BadRC[R]) {
3871d5a254SDimitry Andric         if (RC->LaneMask != RI.RegClass->LaneMask) {
3971d5a254SDimitry Andric           BadRC.set(R);
4071d5a254SDimitry Andric           RI.RegClass = nullptr;
4171d5a254SDimitry Andric         }
4271d5a254SDimitry Andric       } else
4371d5a254SDimitry Andric         RI.RegClass = RC;
4471d5a254SDimitry Andric     }
4571d5a254SDimitry Andric   }
4671d5a254SDimitry Andric 
4771d5a254SDimitry Andric   UnitInfos.resize(TRI.getNumRegUnits());
4871d5a254SDimitry Andric 
4971d5a254SDimitry Andric   for (uint32_t U = 0, NU = TRI.getNumRegUnits(); U != NU; ++U) {
5071d5a254SDimitry Andric     if (UnitInfos[U].Reg != 0)
5171d5a254SDimitry Andric       continue;
5271d5a254SDimitry Andric     MCRegUnitRootIterator R(U, &TRI);
5371d5a254SDimitry Andric     assert(R.isValid());
5471d5a254SDimitry Andric     RegisterId F = *R;
5571d5a254SDimitry Andric     ++R;
5671d5a254SDimitry Andric     if (R.isValid()) {
5771d5a254SDimitry Andric       UnitInfos[U].Mask = LaneBitmask::getAll();
5871d5a254SDimitry Andric       UnitInfos[U].Reg = F;
5971d5a254SDimitry Andric     } else {
6071d5a254SDimitry Andric       for (MCRegUnitMaskIterator I(F, &TRI); I.isValid(); ++I) {
6171d5a254SDimitry Andric         std::pair<uint32_t, LaneBitmask> P = *I;
6271d5a254SDimitry Andric         UnitInfo &UI = UnitInfos[P.first];
6371d5a254SDimitry Andric         UI.Reg = F;
6471d5a254SDimitry Andric         UI.Mask = P.second;
6571d5a254SDimitry Andric       }
6671d5a254SDimitry Andric     }
6771d5a254SDimitry Andric   }
6871d5a254SDimitry Andric 
6971d5a254SDimitry Andric   for (const uint32_t *RM : TRI.getRegMasks())
7071d5a254SDimitry Andric     RegMasks.insert(RM);
7171d5a254SDimitry Andric   for (const MachineBasicBlock &B : mf)
7271d5a254SDimitry Andric     for (const MachineInstr &In : B)
7371d5a254SDimitry Andric       for (const MachineOperand &Op : In.operands())
7471d5a254SDimitry Andric         if (Op.isRegMask())
7571d5a254SDimitry Andric           RegMasks.insert(Op.getRegMask());
76d99dafe2SDimitry Andric 
77d99dafe2SDimitry Andric   MaskInfos.resize(RegMasks.size() + 1);
78d99dafe2SDimitry Andric   for (uint32_t M = 1, NM = RegMasks.size(); M <= NM; ++M) {
79d99dafe2SDimitry Andric     BitVector PU(TRI.getNumRegUnits());
80d99dafe2SDimitry Andric     const uint32_t *MB = RegMasks.get(M);
81b60736ecSDimitry Andric     for (unsigned I = 1, E = TRI.getNumRegs(); I != E; ++I) {
82b60736ecSDimitry Andric       if (!(MB[I / 32] & (1u << (I % 32))))
83d99dafe2SDimitry Andric         continue;
847fa27ce4SDimitry Andric       for (MCRegUnit Unit : TRI.regunits(MCRegister::from(I)))
857fa27ce4SDimitry Andric         PU.set(Unit);
86d99dafe2SDimitry Andric     }
87d99dafe2SDimitry Andric     MaskInfos[M].Units = PU.flip();
88d99dafe2SDimitry Andric   }
8971d5a254SDimitry Andric 
90b60736ecSDimitry Andric   AliasInfos.resize(TRI.getNumRegUnits());
91b60736ecSDimitry Andric   for (uint32_t U = 0, NU = TRI.getNumRegUnits(); U != NU; ++U) {
92b60736ecSDimitry Andric     BitVector AS(TRI.getNumRegs());
93b60736ecSDimitry Andric     for (MCRegUnitRootIterator R(U, &TRI); R.isValid(); ++R)
947fa27ce4SDimitry Andric       for (MCPhysReg S : TRI.superregs_inclusive(*R))
957fa27ce4SDimitry Andric         AS.set(S);
96b60736ecSDimitry Andric     AliasInfos[U].Regs = AS;
97b60736ecSDimitry Andric   }
9871d5a254SDimitry Andric }
9971d5a254SDimitry Andric 
alias(RegisterRef RA,RegisterRef RB) const1007fa27ce4SDimitry Andric bool PhysicalRegisterInfo::alias(RegisterRef RA, RegisterRef RB) const {
1017fa27ce4SDimitry Andric   return !disjoint(getUnits(RA), getUnits(RB));
1027fa27ce4SDimitry Andric }
1037fa27ce4SDimitry Andric 
getAliasSet(RegisterId Reg) const10471d5a254SDimitry Andric std::set<RegisterId> PhysicalRegisterInfo::getAliasSet(RegisterId Reg) const {
1057fa27ce4SDimitry Andric   // Do not include Reg in the alias set.
10671d5a254SDimitry Andric   std::set<RegisterId> AS;
1077fa27ce4SDimitry Andric   assert(!RegisterRef::isUnitId(Reg) && "No units allowed");
1087fa27ce4SDimitry Andric   if (RegisterRef::isMaskId(Reg)) {
10971d5a254SDimitry Andric     // XXX SLOW
11071d5a254SDimitry Andric     const uint32_t *MB = getRegMaskBits(Reg);
11171d5a254SDimitry Andric     for (unsigned i = 1, e = TRI.getNumRegs(); i != e; ++i) {
11271d5a254SDimitry Andric       if (MB[i / 32] & (1u << (i % 32)))
11371d5a254SDimitry Andric         continue;
11471d5a254SDimitry Andric       AS.insert(i);
11571d5a254SDimitry Andric     }
11671d5a254SDimitry Andric     return AS;
11771d5a254SDimitry Andric   }
11871d5a254SDimitry Andric 
1197fa27ce4SDimitry Andric   assert(RegisterRef::isRegId(Reg));
12071d5a254SDimitry Andric   for (MCRegAliasIterator AI(Reg, &TRI, false); AI.isValid(); ++AI)
12171d5a254SDimitry Andric     AS.insert(*AI);
1227fa27ce4SDimitry Andric 
12371d5a254SDimitry Andric   return AS;
12471d5a254SDimitry Andric }
12571d5a254SDimitry Andric 
getUnits(RegisterRef RR) const1267fa27ce4SDimitry Andric std::set<RegisterId> PhysicalRegisterInfo::getUnits(RegisterRef RR) const {
1277fa27ce4SDimitry Andric   std::set<RegisterId> Units;
12871d5a254SDimitry Andric 
1297fa27ce4SDimitry Andric   if (RR.Reg == 0)
1307fa27ce4SDimitry Andric     return Units; // Empty
1317fa27ce4SDimitry Andric 
1327fa27ce4SDimitry Andric   if (RR.isReg()) {
1337fa27ce4SDimitry Andric     if (RR.Mask.none())
1347fa27ce4SDimitry Andric       return Units; // Empty
1357fa27ce4SDimitry Andric     for (MCRegUnitMaskIterator UM(RR.idx(), &TRI); UM.isValid(); ++UM) {
1367fa27ce4SDimitry Andric       auto [U, M] = *UM;
137b1c73532SDimitry Andric       if ((M & RR.Mask).any())
1387fa27ce4SDimitry Andric         Units.insert(U);
13971d5a254SDimitry Andric     }
1407fa27ce4SDimitry Andric     return Units;
14171d5a254SDimitry Andric   }
14271d5a254SDimitry Andric 
1437fa27ce4SDimitry Andric   assert(RR.isMask());
14471d5a254SDimitry Andric   unsigned NumRegs = TRI.getNumRegs();
1457fa27ce4SDimitry Andric   const uint32_t *MB = getRegMaskBits(RR.idx());
1467fa27ce4SDimitry Andric   for (unsigned I = 0, E = (NumRegs + 31) / 32; I != E; ++I) {
1477fa27ce4SDimitry Andric     uint32_t C = ~MB[I]; // Clobbered regs
1487fa27ce4SDimitry Andric     if (I == 0)          // Reg 0 should be ignored
1497fa27ce4SDimitry Andric       C &= maskLeadingOnes<unsigned>(31);
1507fa27ce4SDimitry Andric     if (I + 1 == E && NumRegs % 32 != 0) // Last word may be partial
1517fa27ce4SDimitry Andric       C &= maskTrailingOnes<unsigned>(NumRegs % 32);
1527fa27ce4SDimitry Andric     if (C == 0)
1537fa27ce4SDimitry Andric       continue;
1547fa27ce4SDimitry Andric     while (C != 0) {
1557fa27ce4SDimitry Andric       unsigned T = llvm::countr_zero(C);
1567fa27ce4SDimitry Andric       unsigned CR = 32 * I + T; // Clobbered reg
1577fa27ce4SDimitry Andric       for (MCRegUnit U : TRI.regunits(CR))
1587fa27ce4SDimitry Andric         Units.insert(U);
1597fa27ce4SDimitry Andric       C &= ~(1u << T);
16071d5a254SDimitry Andric     }
1617fa27ce4SDimitry Andric   }
1627fa27ce4SDimitry Andric   return Units;
16371d5a254SDimitry Andric }
16471d5a254SDimitry Andric 
mapTo(RegisterRef RR,unsigned R) const165c46e6a59SDimitry Andric RegisterRef PhysicalRegisterInfo::mapTo(RegisterRef RR, unsigned R) const {
166c46e6a59SDimitry Andric   if (RR.Reg == R)
167c46e6a59SDimitry Andric     return RR;
168c46e6a59SDimitry Andric   if (unsigned Idx = TRI.getSubRegIndex(R, RR.Reg))
169c46e6a59SDimitry Andric     return RegisterRef(R, TRI.composeSubRegIndexLaneMask(Idx, RR.Mask));
170c46e6a59SDimitry Andric   if (unsigned Idx = TRI.getSubRegIndex(RR.Reg, R)) {
171c46e6a59SDimitry Andric     const RegInfo &RI = RegInfos[R];
1727fa27ce4SDimitry Andric     LaneBitmask RCM =
1737fa27ce4SDimitry Andric         RI.RegClass ? RI.RegClass->LaneMask : LaneBitmask::getAll();
174c46e6a59SDimitry Andric     LaneBitmask M = TRI.reverseComposeSubRegIndexLaneMask(Idx, RR.Mask);
175c46e6a59SDimitry Andric     return RegisterRef(R, M & RCM);
176c46e6a59SDimitry Andric   }
177c46e6a59SDimitry Andric   llvm_unreachable("Invalid arguments: unrelated registers?");
178c46e6a59SDimitry Andric }
179c46e6a59SDimitry Andric 
equal_to(RegisterRef A,RegisterRef B) const1807fa27ce4SDimitry Andric bool PhysicalRegisterInfo::equal_to(RegisterRef A, RegisterRef B) const {
1817fa27ce4SDimitry Andric   if (!A.isReg() || !B.isReg()) {
1827fa27ce4SDimitry Andric     // For non-regs, or comparing reg and non-reg, use only the Reg member.
1837fa27ce4SDimitry Andric     return A.Reg == B.Reg;
1847fa27ce4SDimitry Andric   }
1857fa27ce4SDimitry Andric 
1867fa27ce4SDimitry Andric   if (A.Reg == B.Reg)
1877fa27ce4SDimitry Andric     return A.Mask == B.Mask;
1887fa27ce4SDimitry Andric 
1897fa27ce4SDimitry Andric   // Compare reg units lexicographically.
1907fa27ce4SDimitry Andric   MCRegUnitMaskIterator AI(A.Reg, &getTRI());
1917fa27ce4SDimitry Andric   MCRegUnitMaskIterator BI(B.Reg, &getTRI());
1927fa27ce4SDimitry Andric   while (AI.isValid() && BI.isValid()) {
1937fa27ce4SDimitry Andric     auto [AReg, AMask] = *AI;
1947fa27ce4SDimitry Andric     auto [BReg, BMask] = *BI;
1957fa27ce4SDimitry Andric 
1967fa27ce4SDimitry Andric     // If both iterators point to a unit contained in both A and B, then
1977fa27ce4SDimitry Andric     // compare the units.
1987fa27ce4SDimitry Andric     if ((AMask & A.Mask).any() && (BMask & B.Mask).any()) {
1997fa27ce4SDimitry Andric       if (AReg != BReg)
2007fa27ce4SDimitry Andric         return false;
2017fa27ce4SDimitry Andric       // Units are equal, move on to the next ones.
2027fa27ce4SDimitry Andric       ++AI;
2037fa27ce4SDimitry Andric       ++BI;
2047fa27ce4SDimitry Andric       continue;
2057fa27ce4SDimitry Andric     }
2067fa27ce4SDimitry Andric 
2077fa27ce4SDimitry Andric     if ((AMask & A.Mask).none())
2087fa27ce4SDimitry Andric       ++AI;
2097fa27ce4SDimitry Andric     if ((BMask & B.Mask).none())
2107fa27ce4SDimitry Andric       ++BI;
2117fa27ce4SDimitry Andric   }
2127fa27ce4SDimitry Andric   // One or both have reached the end.
2137fa27ce4SDimitry Andric   return static_cast<int>(AI.isValid()) == static_cast<int>(BI.isValid());
2147fa27ce4SDimitry Andric }
2157fa27ce4SDimitry Andric 
less(RegisterRef A,RegisterRef B) const2167fa27ce4SDimitry Andric bool PhysicalRegisterInfo::less(RegisterRef A, RegisterRef B) const {
2177fa27ce4SDimitry Andric   if (!A.isReg() || !B.isReg()) {
2187fa27ce4SDimitry Andric     // For non-regs, or comparing reg and non-reg, use only the Reg member.
2197fa27ce4SDimitry Andric     return A.Reg < B.Reg;
2207fa27ce4SDimitry Andric   }
2217fa27ce4SDimitry Andric 
2227fa27ce4SDimitry Andric   if (A.Reg == B.Reg)
2237fa27ce4SDimitry Andric     return A.Mask < B.Mask;
2247fa27ce4SDimitry Andric   if (A.Mask == B.Mask)
2257fa27ce4SDimitry Andric     return A.Reg < B.Reg;
2267fa27ce4SDimitry Andric 
2277fa27ce4SDimitry Andric   // Compare reg units lexicographically.
2287fa27ce4SDimitry Andric   llvm::MCRegUnitMaskIterator AI(A.Reg, &getTRI());
2297fa27ce4SDimitry Andric   llvm::MCRegUnitMaskIterator BI(B.Reg, &getTRI());
2307fa27ce4SDimitry Andric   while (AI.isValid() && BI.isValid()) {
2317fa27ce4SDimitry Andric     auto [AReg, AMask] = *AI;
2327fa27ce4SDimitry Andric     auto [BReg, BMask] = *BI;
2337fa27ce4SDimitry Andric 
2347fa27ce4SDimitry Andric     // If both iterators point to a unit contained in both A and B, then
2357fa27ce4SDimitry Andric     // compare the units.
2367fa27ce4SDimitry Andric     if ((AMask & A.Mask).any() && (BMask & B.Mask).any()) {
2377fa27ce4SDimitry Andric       if (AReg != BReg)
2387fa27ce4SDimitry Andric         return AReg < BReg;
2397fa27ce4SDimitry Andric       // Units are equal, move on to the next ones.
2407fa27ce4SDimitry Andric       ++AI;
2417fa27ce4SDimitry Andric       ++BI;
2427fa27ce4SDimitry Andric       continue;
2437fa27ce4SDimitry Andric     }
2447fa27ce4SDimitry Andric 
2457fa27ce4SDimitry Andric     if ((AMask & A.Mask).none())
2467fa27ce4SDimitry Andric       ++AI;
2477fa27ce4SDimitry Andric     if ((BMask & B.Mask).none())
2487fa27ce4SDimitry Andric       ++BI;
2497fa27ce4SDimitry Andric   }
2507fa27ce4SDimitry Andric   // One or both have reached the end: assume invalid < valid.
2517fa27ce4SDimitry Andric   return static_cast<int>(AI.isValid()) < static_cast<int>(BI.isValid());
2527fa27ce4SDimitry Andric }
2537fa27ce4SDimitry Andric 
print(raw_ostream & OS,RegisterRef A) const2547fa27ce4SDimitry Andric void PhysicalRegisterInfo::print(raw_ostream &OS, RegisterRef A) const {
2557fa27ce4SDimitry Andric   if (A.Reg == 0 || A.isReg()) {
2567fa27ce4SDimitry Andric     if (0 < A.idx() && A.idx() < TRI.getNumRegs())
2577fa27ce4SDimitry Andric       OS << TRI.getName(A.idx());
2587fa27ce4SDimitry Andric     else
2597fa27ce4SDimitry Andric       OS << printReg(A.idx(), &TRI);
2607fa27ce4SDimitry Andric     OS << PrintLaneMaskShort(A.Mask);
2617fa27ce4SDimitry Andric   } else if (A.isUnit()) {
2627fa27ce4SDimitry Andric     OS << printRegUnit(A.idx(), &TRI);
2637fa27ce4SDimitry Andric   } else {
2647fa27ce4SDimitry Andric     assert(A.isMask());
2657fa27ce4SDimitry Andric     // RegMask SS flag is preserved by idx().
2667fa27ce4SDimitry Andric     unsigned Idx = Register::stackSlot2Index(A.idx());
2677fa27ce4SDimitry Andric     const char *Fmt = Idx < 0x10000 ? "%04x" : "%08x";
2687fa27ce4SDimitry Andric     OS << "M#" << format(Fmt, Idx);
2697fa27ce4SDimitry Andric   }
2707fa27ce4SDimitry Andric }
2717fa27ce4SDimitry Andric 
print(raw_ostream & OS,const RegisterAggr & A) const2727fa27ce4SDimitry Andric void PhysicalRegisterInfo::print(raw_ostream &OS, const RegisterAggr &A) const {
2737fa27ce4SDimitry Andric   OS << '{';
2747fa27ce4SDimitry Andric   for (unsigned U : A.units())
2757fa27ce4SDimitry Andric     OS << ' ' << printRegUnit(U, &TRI);
2767fa27ce4SDimitry Andric   OS << " }";
2777fa27ce4SDimitry Andric }
2787fa27ce4SDimitry Andric 
hasAliasOf(RegisterRef RR) const27971d5a254SDimitry Andric bool RegisterAggr::hasAliasOf(RegisterRef RR) const {
2807fa27ce4SDimitry Andric   if (RR.isMask())
281d99dafe2SDimitry Andric     return Units.anyCommon(PRI.getMaskUnits(RR.Reg));
28271d5a254SDimitry Andric 
28371d5a254SDimitry Andric   for (MCRegUnitMaskIterator U(RR.Reg, &PRI.getTRI()); U.isValid(); ++U) {
28471d5a254SDimitry Andric     std::pair<uint32_t, LaneBitmask> P = *U;
285b1c73532SDimitry Andric     if ((P.second & RR.Mask).any())
28671d5a254SDimitry Andric       if (Units.test(P.first))
28771d5a254SDimitry Andric         return true;
28871d5a254SDimitry Andric   }
28971d5a254SDimitry Andric   return false;
29071d5a254SDimitry Andric }
29171d5a254SDimitry Andric 
hasCoverOf(RegisterRef RR) const29271d5a254SDimitry Andric bool RegisterAggr::hasCoverOf(RegisterRef RR) const {
2937fa27ce4SDimitry Andric   if (RR.isMask()) {
294d99dafe2SDimitry Andric     BitVector T(PRI.getMaskUnits(RR.Reg));
295d99dafe2SDimitry Andric     return T.reset(Units).none();
29671d5a254SDimitry Andric   }
29771d5a254SDimitry Andric 
29871d5a254SDimitry Andric   for (MCRegUnitMaskIterator U(RR.Reg, &PRI.getTRI()); U.isValid(); ++U) {
29971d5a254SDimitry Andric     std::pair<uint32_t, LaneBitmask> P = *U;
300b1c73532SDimitry Andric     if ((P.second & RR.Mask).any())
30171d5a254SDimitry Andric       if (!Units.test(P.first))
30271d5a254SDimitry Andric         return false;
30371d5a254SDimitry Andric   }
30471d5a254SDimitry Andric   return true;
30571d5a254SDimitry Andric }
30671d5a254SDimitry Andric 
insert(RegisterRef RR)30771d5a254SDimitry Andric RegisterAggr &RegisterAggr::insert(RegisterRef RR) {
3087fa27ce4SDimitry Andric   if (RR.isMask()) {
309d99dafe2SDimitry Andric     Units |= PRI.getMaskUnits(RR.Reg);
31071d5a254SDimitry Andric     return *this;
31171d5a254SDimitry Andric   }
31271d5a254SDimitry Andric 
31371d5a254SDimitry Andric   for (MCRegUnitMaskIterator U(RR.Reg, &PRI.getTRI()); U.isValid(); ++U) {
31471d5a254SDimitry Andric     std::pair<uint32_t, LaneBitmask> P = *U;
315b1c73532SDimitry Andric     if ((P.second & RR.Mask).any())
31671d5a254SDimitry Andric       Units.set(P.first);
31771d5a254SDimitry Andric   }
31871d5a254SDimitry Andric   return *this;
31971d5a254SDimitry Andric }
32071d5a254SDimitry Andric 
insert(const RegisterAggr & RG)32171d5a254SDimitry Andric RegisterAggr &RegisterAggr::insert(const RegisterAggr &RG) {
32271d5a254SDimitry Andric   Units |= RG.Units;
32371d5a254SDimitry Andric   return *this;
32471d5a254SDimitry Andric }
32571d5a254SDimitry Andric 
intersect(RegisterRef RR)32671d5a254SDimitry Andric RegisterAggr &RegisterAggr::intersect(RegisterRef RR) {
32771d5a254SDimitry Andric   return intersect(RegisterAggr(PRI).insert(RR));
32871d5a254SDimitry Andric }
32971d5a254SDimitry Andric 
intersect(const RegisterAggr & RG)33071d5a254SDimitry Andric RegisterAggr &RegisterAggr::intersect(const RegisterAggr &RG) {
33171d5a254SDimitry Andric   Units &= RG.Units;
33271d5a254SDimitry Andric   return *this;
33371d5a254SDimitry Andric }
33471d5a254SDimitry Andric 
clear(RegisterRef RR)33571d5a254SDimitry Andric RegisterAggr &RegisterAggr::clear(RegisterRef RR) {
33671d5a254SDimitry Andric   return clear(RegisterAggr(PRI).insert(RR));
33771d5a254SDimitry Andric }
33871d5a254SDimitry Andric 
clear(const RegisterAggr & RG)33971d5a254SDimitry Andric RegisterAggr &RegisterAggr::clear(const RegisterAggr &RG) {
34071d5a254SDimitry Andric   Units.reset(RG.Units);
34171d5a254SDimitry Andric   return *this;
34271d5a254SDimitry Andric }
34371d5a254SDimitry Andric 
intersectWith(RegisterRef RR) const34471d5a254SDimitry Andric RegisterRef RegisterAggr::intersectWith(RegisterRef RR) const {
34571d5a254SDimitry Andric   RegisterAggr T(PRI);
34671d5a254SDimitry Andric   T.insert(RR).intersect(*this);
34771d5a254SDimitry Andric   if (T.empty())
34871d5a254SDimitry Andric     return RegisterRef();
34971d5a254SDimitry Andric   RegisterRef NR = T.makeRegRef();
35071d5a254SDimitry Andric   assert(NR);
35171d5a254SDimitry Andric   return NR;
35271d5a254SDimitry Andric }
35371d5a254SDimitry Andric 
clearIn(RegisterRef RR) const35471d5a254SDimitry Andric RegisterRef RegisterAggr::clearIn(RegisterRef RR) const {
35571d5a254SDimitry Andric   return RegisterAggr(PRI).insert(RR).clear(*this).makeRegRef();
35671d5a254SDimitry Andric }
35771d5a254SDimitry Andric 
makeRegRef() const35871d5a254SDimitry Andric RegisterRef RegisterAggr::makeRegRef() const {
35971d5a254SDimitry Andric   int U = Units.find_first();
36071d5a254SDimitry Andric   if (U < 0)
36171d5a254SDimitry Andric     return RegisterRef();
36271d5a254SDimitry Andric 
36371d5a254SDimitry Andric   // Find the set of all registers that are aliased to all the units
36471d5a254SDimitry Andric   // in this aggregate.
36571d5a254SDimitry Andric 
36671d5a254SDimitry Andric   // Get all the registers aliased to the first unit in the bit vector.
367b60736ecSDimitry Andric   BitVector Regs = PRI.getUnitAliases(U);
36871d5a254SDimitry Andric   U = Units.find_next(U);
36971d5a254SDimitry Andric 
37071d5a254SDimitry Andric   // For each other unit, intersect it with the set of all registers
37171d5a254SDimitry Andric   // aliased that unit.
37271d5a254SDimitry Andric   while (U >= 0) {
373b60736ecSDimitry Andric     Regs &= PRI.getUnitAliases(U);
37471d5a254SDimitry Andric     U = Units.find_next(U);
37571d5a254SDimitry Andric   }
37671d5a254SDimitry Andric 
37771d5a254SDimitry Andric   // If there is at least one register remaining, pick the first one,
37871d5a254SDimitry Andric   // and consolidate the masks of all of its units contained in this
37971d5a254SDimitry Andric   // aggregate.
38071d5a254SDimitry Andric 
38171d5a254SDimitry Andric   int F = Regs.find_first();
38271d5a254SDimitry Andric   if (F <= 0)
38371d5a254SDimitry Andric     return RegisterRef();
38471d5a254SDimitry Andric 
38571d5a254SDimitry Andric   LaneBitmask M;
38671d5a254SDimitry Andric   for (MCRegUnitMaskIterator I(F, &PRI.getTRI()); I.isValid(); ++I) {
38771d5a254SDimitry Andric     std::pair<uint32_t, LaneBitmask> P = *I;
38871d5a254SDimitry Andric     if (Units.test(P.first))
389b1c73532SDimitry Andric       M |= P.second;
39071d5a254SDimitry Andric   }
39171d5a254SDimitry Andric   return RegisterRef(F, M);
39271d5a254SDimitry Andric }
39371d5a254SDimitry Andric 
ref_iterator(const RegisterAggr & RG,bool End)3947fa27ce4SDimitry Andric RegisterAggr::ref_iterator::ref_iterator(const RegisterAggr &RG, bool End)
39571d5a254SDimitry Andric     : Owner(&RG) {
39671d5a254SDimitry Andric   for (int U = RG.Units.find_first(); U >= 0; U = RG.Units.find_next(U)) {
39771d5a254SDimitry Andric     RegisterRef R = RG.PRI.getRefForUnit(U);
39871d5a254SDimitry Andric     Masks[R.Reg] |= R.Mask;
39971d5a254SDimitry Andric   }
40071d5a254SDimitry Andric   Pos = End ? Masks.end() : Masks.begin();
40171d5a254SDimitry Andric   Index = End ? Masks.size() : 0;
40271d5a254SDimitry Andric }
403b60736ecSDimitry Andric 
operator <<(raw_ostream & OS,const RegisterAggr & A)4047fa27ce4SDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const RegisterAggr &A) {
4057fa27ce4SDimitry Andric   A.getPRI().print(OS, A);
406b60736ecSDimitry Andric   return OS;
407b60736ecSDimitry Andric }
4087fa27ce4SDimitry Andric 
operator <<(raw_ostream & OS,const PrintLaneMaskShort & P)4097fa27ce4SDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const PrintLaneMaskShort &P) {
4107fa27ce4SDimitry Andric   if (P.Mask.all())
4117fa27ce4SDimitry Andric     return OS;
4127fa27ce4SDimitry Andric   if (P.Mask.none())
4137fa27ce4SDimitry Andric     return OS << ":*none*";
4147fa27ce4SDimitry Andric 
4157fa27ce4SDimitry Andric   LaneBitmask::Type Val = P.Mask.getAsInteger();
4167fa27ce4SDimitry Andric   if ((Val & 0xffff) == Val)
4177fa27ce4SDimitry Andric     return OS << ':' << format("%04llX", Val);
4187fa27ce4SDimitry Andric   if ((Val & 0xffffffff) == Val)
4197fa27ce4SDimitry Andric     return OS << ':' << format("%08llX", Val);
4207fa27ce4SDimitry Andric   return OS << ':' << PrintLaneMask(P.Mask);
4217fa27ce4SDimitry Andric }
4227fa27ce4SDimitry Andric 
4237fa27ce4SDimitry Andric } // namespace llvm::rdf
424