[llvm] r300345 - [RDF] Switch RegisterAggr to a bit vector of register units

Krzysztof Parzyszek via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 14 10:25:14 PDT 2017


Author: kparzysz
Date: Fri Apr 14 12:25:13 2017
New Revision: 300345

URL: http://llvm.org/viewvc/llvm-project?rev=300345&view=rev
Log:
[RDF] Switch RegisterAggr to a bit vector of register units

This avoids many complications related to the complex register
aliasing schemes.

Modified:
    llvm/trunk/lib/Target/Hexagon/HexagonOptAddrMode.cpp
    llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp
    llvm/trunk/lib/Target/Hexagon/RDFLiveness.cpp
    llvm/trunk/lib/Target/Hexagon/RDFRegisters.cpp
    llvm/trunk/lib/Target/Hexagon/RDFRegisters.h

Modified: llvm/trunk/lib/Target/Hexagon/HexagonOptAddrMode.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonOptAddrMode.cpp?rev=300345&r1=300344&r2=300345&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonOptAddrMode.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonOptAddrMode.cpp Fri Apr 14 12:25:13 2017
@@ -259,7 +259,7 @@ void HexagonOptAddrMode::getAllRealUses(
                      << Print<Liveness::RefMap>(phiUse, *DFG) << "\n");
         if (!phiUse.empty()) {
           for (auto I : phiUse) {
-            if (DR.Reg != I.first)
+            if (!DFG->getPRI().alias(RegisterRef(I.first), DR))
               continue;
             auto phiUseSet = I.second;
             for (auto phiUI : phiUseSet) {

Modified: llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp?rev=300345&r1=300344&r2=300345&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp Fri Apr 14 12:25:13 2017
@@ -913,10 +913,11 @@ void DataFlowGraph::build(unsigned Optio
   }
 
   // Add function-entry phi nodes for the live-in registers.
-  for (std::pair<RegisterId,LaneBitmask> P : LiveIns) {
+  //for (std::pair<RegisterId,LaneBitmask> P : LiveIns) {
+  for (auto I = LiveIns.rr_begin(), E = LiveIns.rr_end(); I != E; ++I) {
+    RegisterRef RR = *I;
     NodeAddr<PhiNode*> PA = newPhi(EA);
     uint16_t PhiFlags = NodeAttrs::PhiRef | NodeAttrs::Preserving;
-    RegisterRef RR(P.first, P.second);
     NodeAddr<DefNode*> DA = newDef(PA, RR, PhiFlags);
     PA.Addr->addMember(DA, *this);
   }
@@ -993,9 +994,9 @@ RegisterRef DataFlowGraph::restrictRef(R
     return M.any() ? RegisterRef(AR.Reg, M) : RegisterRef();
   }
 #ifndef NDEBUG
-  RegisterRef NAR = PRI.normalize(AR);
-  RegisterRef NBR = PRI.normalize(BR);
-  assert(NAR.Reg != NBR.Reg);
+//  RegisterRef NAR = PRI.normalize(AR);
+//  RegisterRef NBR = PRI.normalize(BR);
+//  assert(NAR.Reg != NBR.Reg);
 #endif
   // This isn't strictly correct, because the overlap may happen in the
   // part masked out.

Modified: llvm/trunk/lib/Target/Hexagon/RDFLiveness.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/RDFLiveness.cpp?rev=300345&r1=300344&r2=300345&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/RDFLiveness.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/RDFLiveness.cpp Fri Apr 14 12:25:13 2017
@@ -797,19 +797,9 @@ void Liveness::computeLiveIns() {
       //dbgs() << "\tcomp = " << Print<RegisterAggr>(LiveMap[&B], DFG) << '\n';
 
       LV.clear();
-      for (std::pair<RegisterId,LaneBitmask> P : LiveMap[&B]) {
-        MCSubRegIndexIterator S(P.first, &TRI);
-        if (!S.isValid()) {
-          LV.push_back(RegisterRef(P.first));
-          continue;
-        }
-        do {
-          LaneBitmask M = TRI.getSubRegIndexLaneMask(S.getSubRegIndex());
-          if ((M & P.second).any())
-            LV.push_back(RegisterRef(S.getSubReg()));
-          ++S;
-        } while (S.isValid());
-      }
+      const RegisterAggr &LG = LiveMap[&B];
+      for (auto I = LG.rr_begin(), E = LG.rr_end(); I != E; ++I)
+        LV.push_back(*I);
       std::sort(LV.begin(), LV.end());
       dbgs() << "\tcomp = {";
       for (auto I : LV)
@@ -830,9 +820,10 @@ void Liveness::resetLiveIns() {
     for (auto I : T)
       B.removeLiveIn(I);
     // Add the newly computed live-ins.
-    auto &LiveIns = LiveMap[&B];
-    for (auto I : LiveIns) {
-      B.addLiveIn({MCPhysReg(I.first), I.second});
+    const RegisterAggr &LiveIns = LiveMap[&B];
+    for (auto I = LiveIns.rr_begin(), E = LiveIns.rr_end(); I != E; ++I) {
+      RegisterRef R = *I;
+      B.addLiveIn({MCPhysReg(R.Reg), R.Mask});
     }
   }
 }
@@ -1032,10 +1023,9 @@ void Liveness::traverse(MachineBasicBloc
           // registers are not covering LRef. The first def from the
           // upward chain will be live.
           // Subtract all accumulated defs (RRs) from LRef.
-          RegisterAggr L(PRI);
-          L.insert(LRef).clear(RRs);
-          assert(!L.empty());
-          NewDefs.insert({TA.Id,L.begin()->second});
+          RegisterRef T = RRs.clearIn(LRef);
+          assert(T);
+          NewDefs.insert({TA.Id,T.Mask});
           break;
         }
 

Modified: llvm/trunk/lib/Target/Hexagon/RDFRegisters.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/RDFRegisters.cpp?rev=300345&r1=300344&r2=300345&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/RDFRegisters.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/RDFRegisters.cpp Fri Apr 14 12:25:13 2017
@@ -33,22 +33,33 @@ 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);
+  UnitInfos.resize(TRI.getNumRegUnits());
 
-  for (MCPhysReg R = 1, NR = TRI.getNumRegs(); R != NR; ++R) {
-    MCPhysReg SuperR = R;
-    for (MCSuperRegIterator S(R, &TRI, false); S.isValid(); ++S)
-      if (!RegInfos[*S].Partial)
-        SuperR = *S;
-    RegInfos[R].MaxSuper = SuperR;
+  for (uint32_t U = 0, NU = TRI.getNumRegUnits(); U != NU; ++U) {
+    if (UnitInfos[U].Reg != 0)
+      continue;
+    MCRegUnitRootIterator R(U, &TRI);
+    assert(R.isValid());
+    RegisterId F = *R;
+    ++R;
+    if (R.isValid()) {
+      UnitInfos[U].Mask = LaneBitmask::getAll();
+      UnitInfos[U].Reg = F;
+    } else {
+      for (MCRegUnitMaskIterator I(F, &TRI); I.isValid(); ++I) {
+        std::pair<uint32_t,LaneBitmask> P = *I;
+        UnitInfo &UI = UnitInfos[P.first];
+        UI.Reg = F;
+        if (P.second.any()) {
+          UI.Mask = P.second;
+        } else {
+          if (const TargetRegisterClass *RC = RegInfos[F].RegClass)
+            UI.Mask = RC->LaneMask;
+          else
+            UI.Mask = LaneBitmask::getAll();
+        }
+      }
+    }
   }
 
   for (const uint32_t *RM : TRI.getRegMasks())
@@ -61,22 +72,7 @@ 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;
-
-// 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);
+  return RR;
 }
 
 std::set<RegisterId> PhysicalRegisterInfo::getAliasSet(RegisterId Reg) const {
@@ -217,19 +213,11 @@ bool RegisterAggr::hasAliasOf(RegisterRe
     return false;
   }
 
-  RegisterRef NR = PRI.normalize(RR);
-  auto F = Masks.find(NR.Reg);
-  if (F != Masks.end()) {
-    if ((F->second & NR.Mask).any())
-      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;
-    }
+  for (MCRegUnitMaskIterator U(RR.Reg, &PRI.getTRI()); U.isValid(); ++U) {
+    std::pair<uint32_t,LaneBitmask> P = *U;
+    if (P.second.none() || (P.second & RR.Mask).any())
+      if (Units.test(P.first))
+        return true;
   }
   return false;
 }
@@ -247,25 +235,13 @@ bool RegisterAggr::hasCoverOf(RegisterRe
     return true;
   }
 
-  // Always have a cover for empty lane mask.
-  RegisterRef NR = PRI.normalize(RR);
-  if (NR.Mask.none())
-    return true;
-  auto F = Masks.find(NR.Reg);
-  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;
+  for (MCRegUnitMaskIterator U(RR.Reg, &PRI.getTRI()); U.isValid(); ++U) {
+    std::pair<uint32_t,LaneBitmask> P = *U;
+    if (P.second.none() || (P.second & RR.Mask).any())
+      if (!Units.test(P.first))
+        return false;
   }
-  return false;
+  return true;
 }
 
 RegisterAggr &RegisterAggr::insert(RegisterRef RR) {
@@ -280,99 +256,34 @@ RegisterAggr &RegisterAggr::insert(Regis
     return *this;
   }
 
-  RegisterRef NR = PRI.normalize(RR);
-  auto F = Masks.find(NR.Reg);
-  if (F == Masks.end())
-    Masks.insert({NR.Reg, NR.Mask});
-  else
-    F->second |= NR.Mask;
-
-  // 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;
-    }
+  for (MCRegUnitMaskIterator U(RR.Reg, &PRI.getTRI()); U.isValid(); ++U) {
+    std::pair<uint32_t,LaneBitmask> P = *U;
+    if (P.second.none() || (P.second & RR.Mask).any())
+      Units.set(P.first);
   }
   return *this;
 }
 
 RegisterAggr &RegisterAggr::insert(const RegisterAggr &RG) {
-  for (std::pair<RegisterId,LaneBitmask> P : RG.Masks)
-    insert(RegisterRef(P.first, P.second));
+  Units |= RG.Units;
   return *this;
 }
 
 RegisterAggr &RegisterAggr::intersect(RegisterRef RR) {
-  if (PhysicalRegisterInfo::isRegMaskId(RR.Reg))
-    return intersect(RegisterAggr(PRI).insert(RR));
-
-  RegisterRef NR = PRI.normalize(RR);
-  auto F = Masks.find(NR.Reg);
-  LaneBitmask M;
-  if (F != Masks.end())
-    M = NR.Mask & F->second;
-  Masks.clear();
-  ExpUnits.clear();
-  CheckUnits = false;
-  if (M.any())
-    insert(RegisterRef(NR.Reg, M));
-  return *this;
+  return intersect(RegisterAggr(PRI).insert(RR));
 }
 
 RegisterAggr &RegisterAggr::intersect(const RegisterAggr &RG) {
-  for (auto I = Masks.begin(); I != Masks.end(); ) {
-    auto F = RG.Masks.find(I->first);
-    if (F == RG.Masks.end()) {
-      I = Masks.erase(I);
-    } else {
-      I->second &= F->second;
-      ++I;
-    }
-  }
-  if (CheckUnits && RG.CheckUnits) {
-    ExpUnits &= RG.ExpUnits;
-    if (ExpUnits.empty())
-      CheckUnits = false;
-  } else {
-    ExpUnits.clear();
-    CheckUnits = false;
-  }
+  Units &= RG.Units;
   return *this;
 }
 
 RegisterAggr &RegisterAggr::clear(RegisterRef RR) {
-  if (PhysicalRegisterInfo::isRegMaskId(RR.Reg)) {
-    // XXX SLOW
-    const uint32_t *MB = PRI.getRegMaskBits(RR.Reg);
-    for (unsigned i = 1, e = PRI.getTRI().getNumRegs(); i != e; ++i) {
-      if (MB[i/32] & (1u << (i%32)))
-        continue;
-      clear(RegisterRef(i, LaneBitmask::getAll()));
-    }
-    return *this;
-  }
-
-  RegisterRef NR = PRI.normalize(RR);
-  auto F = Masks.find(NR.Reg);
-  if (F == Masks.end())
-    return *this;
-  LaneBitmask NewM = F->second & ~NR.Mask;
-  if (NewM.none())
-    Masks.erase(F);
-  else
-    F->second = NewM;
-  return *this;
+  return clear(RegisterAggr(PRI).insert(RR));
 }
 
 RegisterAggr &RegisterAggr::clear(const RegisterAggr &RG) {
-  for (std::pair<RegisterId,LaneBitmask> P : RG.Masks)
-    clear(RegisterRef(P.first, P.second));
+  Units.reset(RG.Units);
   return *this;
 }
 
@@ -381,22 +292,75 @@ RegisterRef RegisterAggr::intersectWith(
   T.insert(RR).intersect(*this);
   if (T.empty())
     return RegisterRef();
-  return RegisterRef(T.begin()->first, T.begin()->second);
+  RegisterRef NR = T.makeRegRef();
+  assert(NR);
+  return NR;
 }
 
 RegisterRef RegisterAggr::clearIn(RegisterRef RR) const {
-  RegisterAggr T(PRI);
-  T.insert(RR).clear(*this);
-  if (T.empty())
+  return RegisterAggr(PRI).insert(RR).clear(*this).makeRegRef();
+}
+
+RegisterRef RegisterAggr::makeRegRef() const {
+  int U = Units.find_first();
+  if (U < 0)
+    return RegisterRef();
+
+  auto AliasedRegs = [this] (uint32_t Unit, BitVector &Regs) {
+    for (MCRegUnitRootIterator R(Unit, &PRI.getTRI()); R.isValid(); ++R)
+      for (MCSuperRegIterator S(*R, &PRI.getTRI(), true); S.isValid(); ++S)
+        Regs.set(*S);
+  };
+
+  // Find the set of all registers that are aliased to all the units
+  // in this aggregate.
+
+  // Get all the registers aliased to the first unit in the bit vector.
+  BitVector Regs(PRI.getTRI().getNumRegs());
+  AliasedRegs(U, Regs);
+  U = Units.find_next(U);
+
+  // For each other unit, intersect it with the set of all registers
+  // aliased that unit.
+  while (U >= 0) {
+    BitVector AR(PRI.getTRI().getNumRegs());
+    AliasedRegs(U, AR);
+    Regs &= AR;
+    U = Units.find_next(U);
+  }
+
+  // If there is at least one register remaining, pick the first one,
+  // and consolidate the masks of all of its units contained in this
+  // aggregate.
+
+  int F = Regs.find_first();
+  if (F <= 0)
     return RegisterRef();
-  return RegisterRef(T.begin()->first, T.begin()->second);
+
+  LaneBitmask M;
+  for (MCRegUnitMaskIterator I(F, &PRI.getTRI()); I.isValid(); ++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 (auto I : Masks)
-    OS << ' ' << PrintReg(I.first, &PRI.getTRI())
-       << PrintLaneMaskOpt(I.second);
+  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)
+    : Owner(&RG) {
+  for (int U = RG.Units.find_first(); U >= 0; U = RG.Units.find_next(U)) {
+    RegisterRef R = RG.PRI.getRefForUnit(U);
+    Masks[R.Reg] |= R.Mask;
+  }
+  Pos = End ? Masks.end() : Masks.begin();
+  Index = End ? Masks.size() : 0;
+}
+

Modified: llvm/trunk/lib/Target/Hexagon/RDFRegisters.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/RDFRegisters.h?rev=300345&r1=300344&r2=300345&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/RDFRegisters.h (original)
+++ llvm/trunk/lib/Target/Hexagon/RDFRegisters.h Fri Apr 14 12:25:13 2017
@@ -103,21 +103,25 @@ 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;
+
+    RegisterRef getRefForUnit(uint32_t U) const {
+      return RegisterRef(UnitInfos[U].Reg, UnitInfos[U].Mask);
     }
 
     const TargetRegisterInfo &getTRI() const { return TRI; }
 
   private:
     struct RegInfo {
-      unsigned MaxSuper = 0;
       const TargetRegisterClass *RegClass = nullptr;
-      bool Partial = false;
+    };
+    struct UnitInfo {
+      RegisterId Reg = 0;
+      LaneBitmask Mask;
     };
 
     const TargetRegisterInfo &TRI;
     std::vector<RegInfo> RegInfos;
+    std::vector<UnitInfo> UnitInfos;
     IndexedSet<const uint32_t*> RegMasks;
 
     bool aliasRR(RegisterRef RA, RegisterRef RB) const;
@@ -128,10 +132,10 @@ namespace rdf {
 
   struct RegisterAggr {
     RegisterAggr(const PhysicalRegisterInfo &pri)
-        : ExpUnits(pri.getTRI().getNumRegUnits()), PRI(pri) {}
+        : Units(pri.getTRI().getNumRegUnits()), PRI(pri) {}
     RegisterAggr(const RegisterAggr &RG) = default;
 
-    bool empty() const { return Masks.empty(); }
+    bool empty() const { return Units.empty(); }
     bool hasAliasOf(RegisterRef RR) const;
     bool hasCoverOf(RegisterRef RR) const;
     static bool isCoverOf(RegisterRef RA, RegisterRef RB,
@@ -148,21 +152,45 @@ namespace rdf {
 
     RegisterRef intersectWith(RegisterRef RR) const;
     RegisterRef clearIn(RegisterRef RR) const;
+    RegisterRef makeRegRef() const;
 
     void print(raw_ostream &OS) const;
 
-  private:
-    typedef std::unordered_map<RegisterId, LaneBitmask> MapType;
+    struct rr_iterator {
+      typedef std::map<RegisterId,LaneBitmask> MapType;
+    private:
+      MapType Masks;
+      MapType::iterator Pos;
+      unsigned Index;
+      const RegisterAggr *Owner;
+    public:
+      rr_iterator(const RegisterAggr &RG, bool End);
+      RegisterRef operator*() const {
+        return RegisterRef(Pos->first, Pos->second);
+      }
+      rr_iterator &operator++() {
+        ++Pos;
+        ++Index;
+        return *this;
+      }
+      bool operator==(const rr_iterator &I) const {
+        assert(Owner == I.Owner);
+        return Index == I.Index;
+      }
+      bool operator!=(const rr_iterator &I) const {
+        return !(*this == I);
+      }
+    };
 
-  public:
-    typedef MapType::const_iterator iterator;
-    iterator begin() const { return Masks.begin(); }
-    iterator end() const { return Masks.end(); }
+    rr_iterator rr_begin() const {
+      return rr_iterator(*this, false);
+    }
+    rr_iterator rr_end() const {
+      return rr_iterator(*this, true);
+    }
 
   private:
-    MapType Masks;
-    BitVector ExpUnits; // Register units for explicit checks.
-    bool CheckUnits = false;
+    BitVector Units;
     const PhysicalRegisterInfo &PRI;
   };
 




More information about the llvm-commits mailing list