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