[llvm] r295883 - [RDF] Support for partial structural aliases in RegisterAggr
Krzysztof Parzyszek via llvm-commits
llvm-commits at lists.llvm.org
Wed Feb 22 13:42:15 PST 2017
Author: kparzysz
Date: Wed Feb 22 15:42:15 2017
New Revision: 295883
URL: http://llvm.org/viewvc/llvm-project?rev=295883&view=rev
Log:
[RDF] Support for partial structural aliases in RegisterAggr
Modified:
llvm/trunk/lib/Target/Hexagon/RDFRegisters.cpp
llvm/trunk/lib/Target/Hexagon/RDFRegisters.h
Modified: llvm/trunk/lib/Target/Hexagon/RDFRegisters.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/RDFRegisters.cpp?rev=295883&r1=295882&r2=295883&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/RDFRegisters.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/RDFRegisters.cpp Wed Feb 22 15:42:15 2017
@@ -33,10 +33,21 @@ PhysicalRegisterInfo::PhysicalRegisterIn
}
}
+ auto HasPartialOverlaps = [this] (uint32_t Reg) -> bool {
+ for (MCRegAliasIterator A(Reg, &TRI, false); A.isValid(); ++A)
+ if (!TRI.isSubRegister(Reg, *A) && !TRI.isSubRegister(*A, Reg))
+ return true;
+ return false;
+ };
+
+ for (MCPhysReg R = 1, NR = TRI.getNumRegs(); R != NR; ++R)
+ RegInfos[R].Partial = HasPartialOverlaps(R);
+
for (MCPhysReg R = 1, NR = TRI.getNumRegs(); R != NR; ++R) {
MCPhysReg SuperR = R;
for (MCSuperRegIterator S(R, &TRI, false); S.isValid(); ++S)
- SuperR = *S;
+ if (!RegInfos[*S].Partial)
+ SuperR = *S;
RegInfos[R].MaxSuper = SuperR;
}
@@ -52,15 +63,19 @@ PhysicalRegisterInfo::PhysicalRegisterIn
RegisterRef PhysicalRegisterInfo::normalize(RegisterRef RR) const {
if (PhysicalRegisterInfo::isRegMaskId(RR.Reg))
return RR;
+ RegisterId SuperReg = RegInfos[RR.Reg].MaxSuper;
+ if (RR.Reg == SuperReg)
+ return RR;
+
const TargetRegisterClass *RC = RegInfos[RR.Reg].RegClass;
LaneBitmask RCMask = RC != nullptr ? RC->LaneMask : LaneBitmask(0x00000001);
LaneBitmask Common = RR.Mask & RCMask;
- RegisterId SuperReg = RegInfos[RR.Reg].MaxSuper;
// Ex: IP/EIP/RIP
// assert(RC != nullptr || RR.Reg == SuperReg);
uint32_t Sub = TRI.getSubRegIndex(SuperReg, RR.Reg);
LaneBitmask SuperMask = TRI.composeSubRegIndexLaneMask(Sub, Common);
+ assert(RR.Mask.none() || SuperMask.any());
return RegisterRef(SuperReg, SuperMask);
}
@@ -98,54 +113,25 @@ bool PhysicalRegisterInfo::aliasRR(Regis
assert(TargetRegisterInfo::isPhysicalRegister(RA.Reg));
assert(TargetRegisterInfo::isPhysicalRegister(RB.Reg));
- RegisterRef NA = normalize(RA);
- RegisterRef NB = normalize(RB);
- if (NA.Reg == NB.Reg)
- return (NA.Mask & NB.Mask).any();
-
- // The code below relies on the fact that RA and RB do not share a common
- // super-register.
MCRegUnitMaskIterator UMA(RA.Reg, &TRI);
MCRegUnitMaskIterator UMB(RB.Reg, &TRI);
// Reg units are returned in the numerical order.
while (UMA.isValid() && UMB.isValid()) {
- std::pair<uint32_t,LaneBitmask> PA = *UMA;
- std::pair<uint32_t,LaneBitmask> PB = *UMB;
- if (PA.first == PB.first) {
- // Lane mask of 0 (given by the iterator) should be treated as "full".
- // This can happen when the register has only one unit, or when the
- // unit corresponds to explicit aliasing. In such cases, the lane mask
- // from RegisterRef should be ignored.
- if (PA.second.none() || PB.second.none())
- return true;
-
- // At this point the common unit corresponds to a subregister. The lane
- // masks correspond to the lane mask of that unit within the original
- // register, for example assuming register quadruple q0 = r3:0, and
- // a register pair d1 = r3:2, the lane mask of r2 in q0 may be 0b0100,
- // while the lane mask of r2 in d1 may be 0b0001.
- LaneBitmask LA = PA.second & RA.Mask;
- LaneBitmask LB = PB.second & RB.Mask;
- if (LA.any() && LB.any()) {
- unsigned Root = *MCRegUnitRootIterator(PA.first, &TRI);
- // If register units were guaranteed to only have 1 bit in any lane
- // mask, the code below would not be necessary. This is because LA
- // and LB would have at most 1 bit set each, and that bit would be
- // guaranteed to correspond to the given register unit.
- uint32_t SubA = TRI.getSubRegIndex(RA.Reg, Root);
- uint32_t SubB = TRI.getSubRegIndex(RB.Reg, Root);
- const TargetRegisterClass *RC = RegInfos[Root].RegClass;
- LaneBitmask RCMask = RC != nullptr ? RC->LaneMask : LaneBitmask(0x1);
- LaneBitmask MaskA = TRI.reverseComposeSubRegIndexLaneMask(SubA, LA);
- LaneBitmask MaskB = TRI.reverseComposeSubRegIndexLaneMask(SubB, LB);
- if ((MaskA & MaskB & RCMask).any())
- return true;
- }
-
+ // 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)
@@ -228,6 +214,7 @@ bool RegisterAggr::hasAliasOf(RegisterRe
if (hasAliasOf(RegisterRef(i, LaneBitmask::getAll())))
return true;
}
+ return false;
}
RegisterRef NR = PRI.normalize(RR);
@@ -236,10 +223,13 @@ bool RegisterAggr::hasAliasOf(RegisterRe
if ((F->second & NR.Mask).any())
return true;
}
- if (CheckUnits) {
- for (MCRegUnitIterator U(RR.Reg, &PRI.getTRI()); U.isValid(); ++U)
- if (ExpAliasUnits.test(*U))
- return true;
+ if (CheckUnits || PRI.hasPartialOverlaps(NR.Reg)) {
+ for (MCRegUnitMaskIterator U(RR.Reg, &PRI.getTRI()); U.isValid(); ++U) {
+ std::pair<RegisterId,LaneBitmask> P = *U;
+ if (P.second.none() || (P.second & RR.Mask).any())
+ if (ExpUnits.test(P.first))
+ return true;
+ }
}
return false;
}
@@ -262,9 +252,20 @@ bool RegisterAggr::hasCoverOf(RegisterRe
if (NR.Mask.none())
return true;
auto F = Masks.find(NR.Reg);
- if (F == Masks.end())
- return false;
- return (NR.Mask & F->second) == NR.Mask;
+ if (F != Masks.end()) {
+ if ((NR.Mask & F->second) == NR.Mask)
+ return true;
+ }
+ if (CheckUnits || PRI.hasPartialOverlaps(NR.Reg)) {
+ for (MCRegUnitMaskIterator U(RR.Reg, &PRI.getTRI()); U.isValid(); ++U) {
+ std::pair<RegisterId,LaneBitmask> P = *U;
+ if (P.second.none() || (P.second & RR.Mask).any())
+ if (!ExpUnits.test(P.first))
+ return false;
+ }
+ return true;
+ }
+ return false;
}
RegisterAggr &RegisterAggr::insert(RegisterRef RR) {
@@ -286,16 +287,17 @@ RegisterAggr &RegisterAggr::insert(Regis
else
F->second |= NR.Mask;
- // Visit all register units to see if there are any that were created
- // by explicit aliases. Add those that were to the bit vector.
- const TargetRegisterInfo &TRI = PRI.getTRI();
- for (MCRegUnitIterator U(RR.Reg, &TRI); U.isValid(); ++U) {
- MCRegUnitRootIterator R(*U, &TRI);
- ++R;
- if (!R.isValid())
- continue;
- ExpAliasUnits.set(*U);
- CheckUnits = true;
+ // If the register has any partial overlaps, the mask will not be sufficient
+ // to accurately represent aliasing/covering information. Add all units to
+ // the bit vector.
+ if (PRI.hasPartialOverlaps(NR.Reg)) {
+ for (MCRegUnitMaskIterator U(RR.Reg, &PRI.getTRI()); U.isValid(); ++U) {
+ std::pair<RegisterId,LaneBitmask> P = *U;
+ if (P.second.none() || (P.second & RR.Mask).none())
+ continue;
+ ExpUnits.set(P.first);
+ CheckUnits = true;
+ }
}
return *this;
}
Modified: llvm/trunk/lib/Target/Hexagon/RDFRegisters.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/RDFRegisters.h?rev=295883&r1=295882&r2=295883&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/RDFRegisters.h (original)
+++ llvm/trunk/lib/Target/Hexagon/RDFRegisters.h Wed Feb 22 15:42:15 2017
@@ -103,6 +103,9 @@ namespace rdf {
return !isRegMaskId(RB.Reg) ? aliasRM(RB, RA) : aliasMM(RA, RB);
}
std::set<RegisterId> getAliasSet(RegisterId Reg) const;
+ bool hasPartialOverlaps(RegisterId Reg) const {
+ return RegInfos[Reg].Partial;
+ }
const TargetRegisterInfo &getTRI() const { return TRI; }
@@ -110,6 +113,7 @@ namespace rdf {
struct RegInfo {
unsigned MaxSuper = 0;
const TargetRegisterClass *RegClass = nullptr;
+ bool Partial = false;
};
const TargetRegisterInfo &TRI;
@@ -124,7 +128,7 @@ namespace rdf {
struct RegisterAggr {
RegisterAggr(const PhysicalRegisterInfo &pri)
- : ExpAliasUnits(pri.getTRI().getNumRegUnits()), PRI(pri) {}
+ : ExpUnits(pri.getTRI().getNumRegUnits()), PRI(pri) {}
RegisterAggr(const RegisterAggr &RG) = default;
bool empty() const { return Masks.empty(); }
@@ -154,7 +158,7 @@ namespace rdf {
private:
MapType Masks;
- BitVector ExpAliasUnits; // Register units for explicit aliases.
+ BitVector ExpUnits; // Register units for explicit checks.
bool CheckUnits = false;
const PhysicalRegisterInfo &PRI;
};
More information about the llvm-commits
mailing list