[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