diff options
Diffstat (limited to 'llvm/lib/CodeGen/RDFRegisters.cpp')
| -rw-r--r-- | llvm/lib/CodeGen/RDFRegisters.cpp | 321 |
1 files changed, 192 insertions, 129 deletions
diff --git a/llvm/lib/CodeGen/RDFRegisters.cpp b/llvm/lib/CodeGen/RDFRegisters.cpp index 8760ba118934..90520c4c3c71 100644 --- a/llvm/lib/CodeGen/RDFRegisters.cpp +++ b/llvm/lib/CodeGen/RDFRegisters.cpp @@ -15,17 +15,18 @@ #include "llvm/MC/LaneBitmask.h" #include "llvm/MC/MCRegisterInfo.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/Format.h" +#include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" #include <cassert> #include <cstdint> #include <set> #include <utility> -using namespace llvm; -using namespace rdf; +namespace llvm::rdf { PhysicalRegisterInfo::PhysicalRegisterInfo(const TargetRegisterInfo &tri, - const MachineFunction &mf) + const MachineFunction &mf) : TRI(tri) { RegInfos.resize(TRI.getNumRegs()); @@ -57,7 +58,7 @@ PhysicalRegisterInfo::PhysicalRegisterInfo(const TargetRegisterInfo &tri, UnitInfos[U].Reg = F; } else { for (MCRegUnitMaskIterator I(F, &TRI); I.isValid(); ++I) { - std::pair<uint32_t,LaneBitmask> P = *I; + std::pair<uint32_t, LaneBitmask> P = *I; UnitInfo &UI = UnitInfos[P.first]; UI.Reg = F; if (P.second.any()) { @@ -80,15 +81,15 @@ PhysicalRegisterInfo::PhysicalRegisterInfo(const TargetRegisterInfo &tri, if (Op.isRegMask()) RegMasks.insert(Op.getRegMask()); - MaskInfos.resize(RegMasks.size()+1); + MaskInfos.resize(RegMasks.size() + 1); for (uint32_t M = 1, NM = RegMasks.size(); M <= NM; ++M) { BitVector PU(TRI.getNumRegUnits()); const uint32_t *MB = RegMasks.get(M); for (unsigned I = 1, E = TRI.getNumRegs(); I != E; ++I) { if (!(MB[I / 32] & (1u << (I % 32)))) continue; - for (MCRegUnitIterator U(MCRegister::from(I), &TRI); U.isValid(); ++U) - PU.set(*U); + for (MCRegUnit Unit : TRI.regunits(MCRegister::from(I))) + PU.set(Unit); } MaskInfos[M].Units = PU.flip(); } @@ -97,134 +98,75 @@ PhysicalRegisterInfo::PhysicalRegisterInfo(const TargetRegisterInfo &tri, for (uint32_t U = 0, NU = TRI.getNumRegUnits(); U != NU; ++U) { BitVector AS(TRI.getNumRegs()); for (MCRegUnitRootIterator R(U, &TRI); R.isValid(); ++R) - for (MCSuperRegIterator S(*R, &TRI, true); S.isValid(); ++S) - AS.set(*S); + for (MCPhysReg S : TRI.superregs_inclusive(*R)) + AS.set(S); AliasInfos[U].Regs = AS; } } +bool PhysicalRegisterInfo::alias(RegisterRef RA, RegisterRef RB) const { + return !disjoint(getUnits(RA), getUnits(RB)); +} + std::set<RegisterId> PhysicalRegisterInfo::getAliasSet(RegisterId Reg) const { - // Do not include RR in the alias set. + // Do not include Reg in the alias set. std::set<RegisterId> AS; - assert(isRegMaskId(Reg) || Register::isPhysicalRegister(Reg)); - if (isRegMaskId(Reg)) { + assert(!RegisterRef::isUnitId(Reg) && "No units allowed"); + if (RegisterRef::isMaskId(Reg)) { // XXX SLOW const uint32_t *MB = getRegMaskBits(Reg); for (unsigned i = 1, e = TRI.getNumRegs(); i != e; ++i) { - if (MB[i/32] & (1u << (i%32))) + if (MB[i / 32] & (1u << (i % 32))) continue; AS.insert(i); } - for (const uint32_t *RM : RegMasks) { - RegisterId MI = getRegMaskId(RM); - if (MI != Reg && aliasMM(RegisterRef(Reg), RegisterRef(MI))) - AS.insert(MI); - } return AS; } + assert(RegisterRef::isRegId(Reg)); for (MCRegAliasIterator AI(Reg, &TRI, false); AI.isValid(); ++AI) AS.insert(*AI); - for (const uint32_t *RM : RegMasks) { - RegisterId MI = getRegMaskId(RM); - if (aliasRM(RegisterRef(Reg), RegisterRef(MI))) - AS.insert(MI); - } + return AS; } -bool PhysicalRegisterInfo::aliasRR(RegisterRef RA, RegisterRef RB) const { - assert(Register::isPhysicalRegister(RA.Reg)); - assert(Register::isPhysicalRegister(RB.Reg)); - - MCRegUnitMaskIterator UMA(RA.Reg, &TRI); - MCRegUnitMaskIterator UMB(RB.Reg, &TRI); - // Reg units are returned in the numerical order. - while (UMA.isValid() && UMB.isValid()) { - // Skip units that are masked off in RA. - std::pair<RegisterId,LaneBitmask> PA = *UMA; - if (PA.second.any() && (PA.second & RA.Mask).none()) { - ++UMA; - continue; - } - // Skip units that are masked off in RB. - std::pair<RegisterId,LaneBitmask> PB = *UMB; - if (PB.second.any() && (PB.second & RB.Mask).none()) { - ++UMB; - continue; - } - - if (PA.first == PB.first) - return true; - if (PA.first < PB.first) - ++UMA; - else if (PB.first < PA.first) - ++UMB; - } - return false; -} +std::set<RegisterId> PhysicalRegisterInfo::getUnits(RegisterRef RR) const { + std::set<RegisterId> Units; -bool PhysicalRegisterInfo::aliasRM(RegisterRef RR, RegisterRef RM) const { - assert(Register::isPhysicalRegister(RR.Reg) && isRegMaskId(RM.Reg)); - const uint32_t *MB = getRegMaskBits(RM.Reg); - bool Preserved = MB[RR.Reg/32] & (1u << (RR.Reg%32)); - // If the lane mask information is "full", e.g. when the given lane mask - // is a superset of the lane mask from the register class, check the regmask - // bit directly. - if (RR.Mask == LaneBitmask::getAll()) - return !Preserved; - const TargetRegisterClass *RC = RegInfos[RR.Reg].RegClass; - if (RC != nullptr && (RR.Mask & RC->LaneMask) == RC->LaneMask) - return !Preserved; + if (RR.Reg == 0) + return Units; // Empty - // Otherwise, check all subregisters whose lane mask overlaps the given - // mask. For each such register, if it is preserved by the regmask, then - // clear the corresponding bits in the given mask. If at the end, all - // bits have been cleared, the register does not alias the regmask (i.e. - // is it preserved by it). - LaneBitmask M = RR.Mask; - for (MCSubRegIndexIterator SI(RR.Reg, &TRI); SI.isValid(); ++SI) { - LaneBitmask SM = TRI.getSubRegIndexLaneMask(SI.getSubRegIndex()); - if ((SM & RR.Mask).none()) - continue; - unsigned SR = SI.getSubReg(); - if (!(MB[SR/32] & (1u << (SR%32)))) - continue; - // The subregister SR is preserved. - M &= ~SM; - if (M.none()) - return false; + if (RR.isReg()) { + if (RR.Mask.none()) + return Units; // Empty + for (MCRegUnitMaskIterator UM(RR.idx(), &TRI); UM.isValid(); ++UM) { + auto [U, M] = *UM; + if (M.none() || (M & RR.Mask).any()) + Units.insert(U); + } + return Units; } - return true; -} - -bool PhysicalRegisterInfo::aliasMM(RegisterRef RM, RegisterRef RN) const { - assert(isRegMaskId(RM.Reg) && isRegMaskId(RN.Reg)); + assert(RR.isMask()); unsigned NumRegs = TRI.getNumRegs(); - const uint32_t *BM = getRegMaskBits(RM.Reg); - const uint32_t *BN = getRegMaskBits(RN.Reg); - - for (unsigned w = 0, nw = NumRegs/32; w != nw; ++w) { - // Intersect the negations of both words. Disregard reg=0, - // i.e. 0th bit in the 0th word. - uint32_t C = ~BM[w] & ~BN[w]; - if (w == 0) - C &= ~1; - if (C) - return true; + const uint32_t *MB = getRegMaskBits(RR.idx()); + for (unsigned I = 0, E = (NumRegs + 31) / 32; I != E; ++I) { + uint32_t C = ~MB[I]; // Clobbered regs + if (I == 0) // Reg 0 should be ignored + C &= maskLeadingOnes<unsigned>(31); + if (I + 1 == E && NumRegs % 32 != 0) // Last word may be partial + C &= maskTrailingOnes<unsigned>(NumRegs % 32); + if (C == 0) + continue; + while (C != 0) { + unsigned T = llvm::countr_zero(C); + unsigned CR = 32 * I + T; // Clobbered reg + for (MCRegUnit U : TRI.regunits(CR)) + Units.insert(U); + C &= ~(1u << T); + } } - - // Check the remaining registers in the last word. - unsigned TailRegs = NumRegs % 32; - if (TailRegs == 0) - return false; - unsigned TW = NumRegs / 32; - uint32_t TailMask = (1u << TailRegs) - 1; - if (~BM[TW] & ~BN[TW] & TailMask) - return true; - - return false; + return Units; } RegisterRef PhysicalRegisterInfo::mapTo(RegisterRef RR, unsigned R) const { @@ -234,20 +176,133 @@ RegisterRef PhysicalRegisterInfo::mapTo(RegisterRef RR, unsigned R) const { return RegisterRef(R, TRI.composeSubRegIndexLaneMask(Idx, RR.Mask)); if (unsigned Idx = TRI.getSubRegIndex(RR.Reg, R)) { const RegInfo &RI = RegInfos[R]; - LaneBitmask RCM = RI.RegClass ? RI.RegClass->LaneMask - : LaneBitmask::getAll(); + LaneBitmask RCM = + RI.RegClass ? RI.RegClass->LaneMask : LaneBitmask::getAll(); LaneBitmask M = TRI.reverseComposeSubRegIndexLaneMask(Idx, RR.Mask); return RegisterRef(R, M & RCM); } llvm_unreachable("Invalid arguments: unrelated registers?"); } +bool PhysicalRegisterInfo::equal_to(RegisterRef A, RegisterRef B) const { + if (!A.isReg() || !B.isReg()) { + // For non-regs, or comparing reg and non-reg, use only the Reg member. + return A.Reg == B.Reg; + } + + if (A.Reg == B.Reg) + return A.Mask == B.Mask; + + // Compare reg units lexicographically. + MCRegUnitMaskIterator AI(A.Reg, &getTRI()); + MCRegUnitMaskIterator BI(B.Reg, &getTRI()); + while (AI.isValid() && BI.isValid()) { + auto [AReg, AMask] = *AI; + auto [BReg, BMask] = *BI; + + // Lane masks are "none" for units that don't correspond to subregs + // e.g. a single unit in a leaf register, or aliased unit. + if (AMask.none()) + AMask = LaneBitmask::getAll(); + if (BMask.none()) + BMask = LaneBitmask::getAll(); + + // If both iterators point to a unit contained in both A and B, then + // compare the units. + if ((AMask & A.Mask).any() && (BMask & B.Mask).any()) { + if (AReg != BReg) + return false; + // Units are equal, move on to the next ones. + ++AI; + ++BI; + continue; + } + + if ((AMask & A.Mask).none()) + ++AI; + if ((BMask & B.Mask).none()) + ++BI; + } + // One or both have reached the end. + return static_cast<int>(AI.isValid()) == static_cast<int>(BI.isValid()); +} + +bool PhysicalRegisterInfo::less(RegisterRef A, RegisterRef B) const { + if (!A.isReg() || !B.isReg()) { + // For non-regs, or comparing reg and non-reg, use only the Reg member. + return A.Reg < B.Reg; + } + + if (A.Reg == B.Reg) + return A.Mask < B.Mask; + if (A.Mask == B.Mask) + return A.Reg < B.Reg; + + // Compare reg units lexicographically. + llvm::MCRegUnitMaskIterator AI(A.Reg, &getTRI()); + llvm::MCRegUnitMaskIterator BI(B.Reg, &getTRI()); + while (AI.isValid() && BI.isValid()) { + auto [AReg, AMask] = *AI; + auto [BReg, BMask] = *BI; + + // Lane masks are "none" for units that don't correspond to subregs + // e.g. a single unit in a leaf register, or aliased unit. + if (AMask.none()) + AMask = LaneBitmask::getAll(); + if (BMask.none()) + BMask = LaneBitmask::getAll(); + + // If both iterators point to a unit contained in both A and B, then + // compare the units. + if ((AMask & A.Mask).any() && (BMask & B.Mask).any()) { + if (AReg != BReg) + return AReg < BReg; + // Units are equal, move on to the next ones. + ++AI; + ++BI; + continue; + } + + if ((AMask & A.Mask).none()) + ++AI; + if ((BMask & B.Mask).none()) + ++BI; + } + // One or both have reached the end: assume invalid < valid. + return static_cast<int>(AI.isValid()) < static_cast<int>(BI.isValid()); +} + +void PhysicalRegisterInfo::print(raw_ostream &OS, RegisterRef A) const { + if (A.Reg == 0 || A.isReg()) { + if (0 < A.idx() && A.idx() < TRI.getNumRegs()) + OS << TRI.getName(A.idx()); + else + OS << printReg(A.idx(), &TRI); + OS << PrintLaneMaskShort(A.Mask); + } else if (A.isUnit()) { + OS << printRegUnit(A.idx(), &TRI); + } else { + assert(A.isMask()); + // RegMask SS flag is preserved by idx(). + unsigned Idx = Register::stackSlot2Index(A.idx()); + const char *Fmt = Idx < 0x10000 ? "%04x" : "%08x"; + OS << "M#" << format(Fmt, Idx); + } +} + +void PhysicalRegisterInfo::print(raw_ostream &OS, const RegisterAggr &A) const { + OS << '{'; + for (unsigned U : A.units()) + OS << ' ' << printRegUnit(U, &TRI); + OS << " }"; +} + bool RegisterAggr::hasAliasOf(RegisterRef RR) const { - if (PhysicalRegisterInfo::isRegMaskId(RR.Reg)) + if (RR.isMask()) return Units.anyCommon(PRI.getMaskUnits(RR.Reg)); for (MCRegUnitMaskIterator U(RR.Reg, &PRI.getTRI()); U.isValid(); ++U) { - std::pair<uint32_t,LaneBitmask> P = *U; + std::pair<uint32_t, LaneBitmask> P = *U; if (P.second.none() || (P.second & RR.Mask).any()) if (Units.test(P.first)) return true; @@ -256,13 +311,13 @@ bool RegisterAggr::hasAliasOf(RegisterRef RR) const { } bool RegisterAggr::hasCoverOf(RegisterRef RR) const { - if (PhysicalRegisterInfo::isRegMaskId(RR.Reg)) { + if (RR.isMask()) { BitVector T(PRI.getMaskUnits(RR.Reg)); return T.reset(Units).none(); } for (MCRegUnitMaskIterator U(RR.Reg, &PRI.getTRI()); U.isValid(); ++U) { - std::pair<uint32_t,LaneBitmask> P = *U; + std::pair<uint32_t, LaneBitmask> P = *U; if (P.second.none() || (P.second & RR.Mask).any()) if (!Units.test(P.first)) return false; @@ -271,13 +326,13 @@ bool RegisterAggr::hasCoverOf(RegisterRef RR) const { } RegisterAggr &RegisterAggr::insert(RegisterRef RR) { - if (PhysicalRegisterInfo::isRegMaskId(RR.Reg)) { + if (RR.isMask()) { Units |= PRI.getMaskUnits(RR.Reg); return *this; } for (MCRegUnitMaskIterator U(RR.Reg, &PRI.getTRI()); U.isValid(); ++U) { - std::pair<uint32_t,LaneBitmask> P = *U; + std::pair<uint32_t, LaneBitmask> P = *U; if (P.second.none() || (P.second & RR.Mask).any()) Units.set(P.first); } @@ -350,22 +405,14 @@ RegisterRef RegisterAggr::makeRegRef() const { LaneBitmask M; for (MCRegUnitMaskIterator I(F, &PRI.getTRI()); I.isValid(); ++I) { - std::pair<uint32_t,LaneBitmask> P = *I; + std::pair<uint32_t, LaneBitmask> P = *I; if (Units.test(P.first)) M |= P.second.none() ? LaneBitmask::getAll() : P.second; } return RegisterRef(F, M); } -void RegisterAggr::print(raw_ostream &OS) const { - OS << '{'; - for (int U = Units.find_first(); U >= 0; U = Units.find_next(U)) - OS << ' ' << printRegUnit(U, &PRI.getTRI()); - OS << " }"; -} - -RegisterAggr::rr_iterator::rr_iterator(const RegisterAggr &RG, - bool End) +RegisterAggr::ref_iterator::ref_iterator(const RegisterAggr &RG, bool End) : Owner(&RG) { for (int U = RG.Units.find_first(); U >= 0; U = RG.Units.find_next(U)) { RegisterRef R = RG.PRI.getRefForUnit(U); @@ -375,7 +422,23 @@ RegisterAggr::rr_iterator::rr_iterator(const RegisterAggr &RG, Index = End ? Masks.size() : 0; } -raw_ostream &rdf::operator<<(raw_ostream &OS, const RegisterAggr &A) { - A.print(OS); +raw_ostream &operator<<(raw_ostream &OS, const RegisterAggr &A) { + A.getPRI().print(OS, A); return OS; } + +raw_ostream &operator<<(raw_ostream &OS, const PrintLaneMaskShort &P) { + if (P.Mask.all()) + return OS; + if (P.Mask.none()) + return OS << ":*none*"; + + LaneBitmask::Type Val = P.Mask.getAsInteger(); + if ((Val & 0xffff) == Val) + return OS << ':' << format("%04llX", Val); + if ((Val & 0xffffffff) == Val) + return OS << ':' << format("%08llX", Val); + return OS << ':' << PrintLaneMask(P.Mask); +} + +} // namespace llvm::rdf |
