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