[llvm] r283122 - [RDF] Replace RegisterAliasInfo with target-independent code using lane masks

Krzysztof Parzyszek via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 3 10:14:49 PDT 2016


Author: kparzysz
Date: Mon Oct  3 12:14:48 2016
New Revision: 283122

URL: http://llvm.org/viewvc/llvm-project?rev=283122&view=rev
Log:
[RDF] Replace RegisterAliasInfo with target-independent code using lane masks

Removed:
    llvm/trunk/lib/Target/Hexagon/HexagonRDF.cpp
    llvm/trunk/lib/Target/Hexagon/HexagonRDF.h
Modified:
    llvm/trunk/lib/Target/Hexagon/CMakeLists.txt
    llvm/trunk/lib/Target/Hexagon/HexagonOptAddrMode.cpp
    llvm/trunk/lib/Target/Hexagon/HexagonRDFOpt.cpp
    llvm/trunk/lib/Target/Hexagon/RDFCopy.cpp
    llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp
    llvm/trunk/lib/Target/Hexagon/RDFGraph.h
    llvm/trunk/lib/Target/Hexagon/RDFLiveness.cpp
    llvm/trunk/lib/Target/Hexagon/RDFLiveness.h

Modified: llvm/trunk/lib/Target/Hexagon/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/CMakeLists.txt?rev=283122&r1=283121&r2=283122&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/CMakeLists.txt (original)
+++ llvm/trunk/lib/Target/Hexagon/CMakeLists.txt Mon Oct  3 12:14:48 2016
@@ -42,7 +42,6 @@ add_llvm_target(HexagonCodeGen
   HexagonOptAddrMode.cpp
   HexagonOptimizeSZextends.cpp
   HexagonPeephole.cpp
-  HexagonRDF.cpp
   HexagonRDFOpt.cpp
   HexagonRegisterInfo.cpp
   HexagonSelectionDAGInfo.cpp

Modified: llvm/trunk/lib/Target/Hexagon/HexagonOptAddrMode.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonOptAddrMode.cpp?rev=283122&r1=283121&r2=283122&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonOptAddrMode.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonOptAddrMode.cpp Mon Oct  3 12:14:48 2016
@@ -587,7 +587,7 @@ void HexagonOptAddrMode::updateMap(NodeA
     return;
 
   for (auto &R : RDefMap) {
-    auto F = DefM.find(R.first);
+    auto F = DefM.find(R.first.Reg);
     if (F == DefM.end() || F->second.empty())
       continue;
     R.second[IA.Id] = F->second.top()->Id;
@@ -622,8 +622,7 @@ bool HexagonOptAddrMode::runOnMachineFun
   const auto &TRI = *MF.getSubtarget().getRegisterInfo();
   const TargetOperandInfo TOI(*HII);
 
-  RegisterAliasInfo RAI(TRI);
-  DataFlowGraph G(MF, *HII, TRI, *MDT, MDF, RAI, TOI);
+  DataFlowGraph G(MF, *HII, TRI, *MDT, MDF, TOI);
   G.build();
   DFG = &G;
 

Removed: llvm/trunk/lib/Target/Hexagon/HexagonRDF.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonRDF.cpp?rev=283121&view=auto
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonRDF.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonRDF.cpp (removed)
@@ -1,64 +0,0 @@
-//===--- HexagonRDF.cpp ---------------------------------------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "HexagonRDF.h"
-#include "HexagonInstrInfo.h"
-#include "HexagonRegisterInfo.h"
-
-#include "llvm/CodeGen/MachineInstr.h"
-
-using namespace llvm;
-using namespace rdf;
-
-bool HexagonRegisterAliasInfo::covers(RegisterRef RA, RegisterRef RB,
-      const DataFlowGraph &DFG) const {
-  if (RA == RB)
-    return true;
-
-  if (TargetRegisterInfo::isVirtualRegister(RA.Reg) &&
-      TargetRegisterInfo::isVirtualRegister(RB.Reg)) {
-    // Hexagon-specific cases.
-    if (RA.Reg == RB.Reg) {
-      if (RA.Sub == 0)
-        return true;
-      if (RB.Sub == 0)
-        return false;
-    }
-  }
-
-  return RegisterAliasInfo::covers(RA, RB, DFG);
-}
-
-bool HexagonRegisterAliasInfo::covers(const RegisterSet &RRs, RegisterRef RR,
-      const DataFlowGraph &DFG) const {
-  if (RRs.count(RR))
-    return true;
-
-  // The exact reference RR is not in the set.
-
-  if (TargetRegisterInfo::isVirtualRegister(RR.Reg)) {
-    // Check if the there are references in RRs of the same register,
-    // with both covering subregisters.
-    bool HasLo = RRs.count({RR.Reg, Hexagon::subreg_loreg});
-    bool HasHi = RRs.count({RR.Reg, Hexagon::subreg_hireg});
-    if (HasLo && HasHi)
-      return true;
-  }
-
-  if (TargetRegisterInfo::isPhysicalRegister(RR.Reg)) {
-    // Check if both covering subregisters are present with full
-    // lane masks.
-    unsigned Lo = TRI.getSubReg(RR.Reg, Hexagon::subreg_loreg);
-    unsigned Hi = TRI.getSubReg(RR.Reg, Hexagon::subreg_hireg);
-    if (RRs.count({Lo, 0}) && RRs.count({Hi, 0}))
-      return true;
-  }
-
-  return RegisterAliasInfo::covers(RRs, RR, DFG);
-}

Removed: llvm/trunk/lib/Target/Hexagon/HexagonRDF.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonRDF.h?rev=283121&view=auto
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonRDF.h (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonRDF.h (removed)
@@ -1,30 +0,0 @@
-//===--- HexagonRDF.h -----------------------------------------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef HEXAGON_RDF_H
-#define HEXAGON_RDF_H
-#include "RDFGraph.h"
-
-namespace llvm {
-  class TargetRegisterInfo;
-
-namespace rdf {
-  struct HexagonRegisterAliasInfo : public RegisterAliasInfo {
-    HexagonRegisterAliasInfo(const TargetRegisterInfo &TRI)
-      : RegisterAliasInfo(TRI) {}
-    bool covers(RegisterRef RA, RegisterRef RR,
-          const DataFlowGraph &DFG) const override;
-    bool covers(const RegisterSet &RRs, RegisterRef RR,
-          const DataFlowGraph &DFG) const override;
-  };
-} // namespace rdf
-} // namespace llvm
-
-#endif
-

Modified: llvm/trunk/lib/Target/Hexagon/HexagonRDFOpt.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonRDFOpt.cpp?rev=283122&r1=283121&r2=283122&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonRDFOpt.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonRDFOpt.cpp Mon Oct  3 12:14:48 2016
@@ -8,7 +8,6 @@
 //===----------------------------------------------------------------------===//
 
 #include "HexagonInstrInfo.h"
-#include "HexagonRDF.h"
 #include "HexagonSubtarget.h"
 #include "RDFCopy.h"
 #include "RDFDeadCode.h"
@@ -286,9 +285,8 @@ bool HexagonRDFOpt::runOnMachineFunction
   if (RDFDump)
     MF.print(dbgs() << "Before " << getPassName() << "\n", nullptr);
 
-  HexagonRegisterAliasInfo HAI(HRI);
   TargetOperandInfo TOI(HII);
-  DataFlowGraph G(MF, HII, HRI, *MDT, MDF, HAI, TOI);
+  DataFlowGraph G(MF, HII, HRI, *MDT, MDF, TOI);
   // Dead phi nodes are necessary for copy propagation: we can add a use
   // of a register in a block where it would need a phi node, but which
   // was dead (and removed) during the graph build time.

Modified: llvm/trunk/lib/Target/Hexagon/RDFCopy.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/RDFCopy.cpp?rev=283122&r1=283121&r2=283122&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/RDFCopy.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/RDFCopy.cpp Mon Oct  3 12:14:48 2016
@@ -79,7 +79,7 @@ void CopyPropagation::recordCopy(NodeAdd
   Copies.push_back(SA.Id);
 
   for (auto I : EM) {
-    auto FS = DefM.find(I.second);
+    auto FS = DefM.find(I.second.Reg);
     if (FS == DefM.end() || FS->second.empty())
       continue; // Undefined source
     RDefMap[I.second][SA.Id] = FS->second.top()->Id;
@@ -106,7 +106,7 @@ void CopyPropagation::updateMap(NodeAddr
   for (auto &R : RDefMap) {
     if (!RRs.count(R.first))
       continue;
-    auto F = DefM.find(R.first);
+    auto F = DefM.find(R.first.Reg);
     if (F == DefM.end() || F->second.empty())
       continue;
     R.second[IA.Id] = F->second.top()->Id;

Modified: llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp?rev=283122&r1=283121&r2=283122&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp Mon Oct  3 12:14:48 2016
@@ -36,12 +36,9 @@ raw_ostream &operator<< (raw_ostream &OS
     OS << TRI.getName(P.Obj.Reg);
   else
     OS << '#' << P.Obj.Reg;
-  if (P.Obj.Sub > 0) {
-    OS << ':';
-    if (P.Obj.Sub < TRI.getNumSubRegIndices())
-      OS << TRI.getSubRegIndexName(P.Obj.Sub);
-    else
-      OS << '#' << P.Obj.Sub;
+  if (P.Obj.Sub != 0) {
+    LaneBitmask LM = P.G.getLMI().getLaneMaskForIndex(P.Obj.Sub);
+    OS << ":L" << PrintLaneMask(LM);
   }
   return OS;
 }
@@ -306,6 +303,12 @@ raw_ostream &operator<< (raw_ostream &OS
 }
 
 template<>
+raw_ostream &operator<< (raw_ostream &OS, const Print<RegisterAggr> &P) {
+  P.Obj.print(OS);
+  return OS;
+}
+
+template<>
 raw_ostream &operator<< (raw_ostream &OS,
       const Print<DataFlowGraph::DefStack> &P) {
   for (auto I = P.Obj.top(), E = P.Obj.bottom(); I != E; ) {
@@ -581,152 +584,6 @@ NodeAddr<BlockNode*> FuncNode::getEntryB
 }
 
 
-// Register aliasing information.
-//
-
-LaneBitmask RegisterAliasInfo::getLaneMask(RegisterRef RR,
-      const DataFlowGraph &DFG) const {
-  assert(TargetRegisterInfo::isPhysicalRegister(RR.Reg));
-  const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(RR.Reg);
-  return (RR.Sub != 0) ? DFG.getLaneMaskForIndex(RR.Sub) : RC->LaneMask;
-}
-
-RegisterAliasInfo::CommonRegister::CommonRegister(
-      unsigned RegA, LaneBitmask LA, unsigned RegB, LaneBitmask LB,
-      const TargetRegisterInfo &TRI) {
-  if (RegA == RegB) {
-    SuperReg = RegA;
-    MaskA = LA;
-    MaskB = LB;
-    return;
-  }
-
-  // Find a common super-register.
-  SuperReg = 0;
-  for (MCSuperRegIterator SA(RegA, &TRI, true); SA.isValid(); ++SA) {
-    if (!TRI.isSubRegisterEq(*SA, RegB))
-      continue;
-    SuperReg = *SA;
-    break;
-  }
-  if (SuperReg == 0)
-    return;
-
-  if (unsigned SubA = TRI.getSubRegIndex(SuperReg, RegA))
-    LA = TRI.composeSubRegIndexLaneMask(SubA, LA);
-  if (unsigned SubB = TRI.getSubRegIndex(SuperReg, RegB))
-    LB = TRI.composeSubRegIndexLaneMask(SubB, LB);
-
-  MaskA = LA;
-  MaskB = LB;
-}
-
-// Determine whether RA covers RB.
-bool RegisterAliasInfo::covers(RegisterRef RA, RegisterRef RB,
-      const DataFlowGraph &DFG) const {
-  if (RA == RB)
-    return true;
-  if (TargetRegisterInfo::isVirtualRegister(RA.Reg)) {
-    assert(TargetRegisterInfo::isVirtualRegister(RB.Reg));
-    if (RA.Reg != RB.Reg)
-      return false;
-    if (RA.Sub == 0)
-      return true;
-    return TRI.composeSubRegIndices(RA.Sub, RB.Sub) == RA.Sub;
-  }
-
-  assert(TargetRegisterInfo::isPhysicalRegister(RA.Reg) &&
-         TargetRegisterInfo::isPhysicalRegister(RB.Reg));
-
-  CommonRegister CR(RA.Reg, getLaneMask(RA, DFG),
-                    RB.Reg, getLaneMask(RB, DFG), TRI);
-  if (CR.SuperReg == 0)
-    return false;
-  return (CR.MaskA & CR.MaskB) == CR.MaskB;
-}
-
-// Determine whether RR is covered by the set of references RRs.
-bool RegisterAliasInfo::covers(const RegisterSet &RRs, RegisterRef RR,
-      const DataFlowGraph &DFG) const {
-  if (RRs.count(RR))
-    return true;
-
-  // For virtual registers, we cannot accurately determine covering based
-  // on subregisters. If RR itself is not present in RRs, but it has a sub-
-  // register reference, check for the super-register alone. Otherwise,
-  // assume non-covering.
-  if (TargetRegisterInfo::isVirtualRegister(RR.Reg)) {
-    if (RR.Sub != 0)
-      return RRs.count({RR.Reg, 0});
-    return false;
-  }
-
-  // If any super-register of RR is present, then RR is covered.
-  uint32_t Reg = RR.Sub == 0 ? RR.Reg : TRI.getSubReg(RR.Reg, RR.Sub);
-  for (MCSuperRegIterator SR(Reg, &TRI); SR.isValid(); ++SR)
-    if (RRs.count({*SR, 0}))
-      return true;
-
-  return false;
-}
-
-// Get the list of references aliased to RR. Lane masks are ignored.
-std::vector<RegisterRef> RegisterAliasInfo::getAliasSet(RegisterRef RR) const {
-  // Do not include RR in the alias set. For virtual registers return an
-  // empty set.
-  std::vector<RegisterRef> AS;
-  if (TargetRegisterInfo::isVirtualRegister(RR.Reg))
-    return AS;
-  assert(TargetRegisterInfo::isPhysicalRegister(RR.Reg));
-  uint32_t R = RR.Reg;
-  if (RR.Sub)
-    R = TRI.getSubReg(RR.Reg, RR.Sub);
-
-  for (MCRegAliasIterator AI(R, &TRI, false); AI.isValid(); ++AI)
-    AS.push_back(RegisterRef({*AI, 0}));
-  return AS;
-}
-
-// Check whether RA and RB are aliased.
-bool RegisterAliasInfo::alias(RegisterRef RA, RegisterRef RB,
-      const DataFlowGraph &DFG) const {
-  bool IsVirtA = TargetRegisterInfo::isVirtualRegister(RA.Reg);
-  bool IsVirtB = TargetRegisterInfo::isVirtualRegister(RB.Reg);
-  bool IsPhysA = TargetRegisterInfo::isPhysicalRegister(RA.Reg);
-  bool IsPhysB = TargetRegisterInfo::isPhysicalRegister(RB.Reg);
-
-  if (IsVirtA != IsVirtB)
-    return false;
-
-  if (IsVirtA) {
-    if (RA.Reg != RB.Reg)
-      return false;
-    // RA and RB refer to the same register. If any of them refer to the
-    // whole register, they must be aliased.
-    if (RA.Sub == 0 || RB.Sub == 0)
-      return true;
-    unsigned SA = TRI.getSubRegIdxSize(RA.Sub);
-    unsigned OA = TRI.getSubRegIdxOffset(RA.Sub);
-    unsigned SB = TRI.getSubRegIdxSize(RB.Sub);
-    unsigned OB = TRI.getSubRegIdxOffset(RB.Sub);
-    if (OA <= OB && OA+SA > OB)
-      return true;
-    if (OB <= OA && OB+SB > OA)
-      return true;
-    return false;
-  }
-
-  assert(IsPhysA && IsPhysB);
-  (void)IsPhysA, (void)IsPhysB;
-
-  CommonRegister CR(RA.Reg, getLaneMask(RA, DFG),
-                    RB.Reg, getLaneMask(RB, DFG), TRI);
-  if (CR.SuperReg == 0)
-    return false;
-  return (CR.MaskA & CR.MaskB) != 0;
-}
-
-
 // Target operand information.
 //
 
@@ -778,16 +635,112 @@ bool TargetOperandInfo::isFixedReg(const
 }
 
 
+uint32_t RegisterAggr::getLargestSuperReg(uint32_t Reg) const {
+  uint32_t SuperReg = Reg;
+  while (true) {
+    MCSuperRegIterator SR(SuperReg, &TRI, false);
+    if (!SR.isValid())
+      return SuperReg;
+    SuperReg = *SR;
+  }
+  llvm_unreachable(nullptr);
+}
+
+LaneBitmask RegisterAggr::composeMaskForReg(uint32_t Reg, LaneBitmask LM,
+      uint32_t SuperR) const {
+  uint32_t SubR = TRI.getSubRegIndex(SuperR, Reg);
+  const TargetRegisterClass &RC = *TRI.getMinimalPhysRegClass(Reg);
+  return TRI.composeSubRegIndexLaneMask(SubR, LM & RC.LaneMask);
+}
+
+void RegisterAggr::setMaskRaw(uint32_t Reg, LaneBitmask LM) {
+  uint32_t SuperR = getLargestSuperReg(Reg);
+  LaneBitmask SuperM = composeMaskForReg(Reg, LM, SuperR);
+  auto F = Masks.find(SuperR);
+  if (F == Masks.end())
+    Masks.insert({SuperR, SuperM});
+  else
+    F->second |= SuperM;
+
+  // Visit all register units to see if there are any that were created
+  // by explicit aliases. Add those that were to the bit vector.
+  for (MCRegUnitIterator U(Reg, &TRI); U.isValid(); ++U) {
+    MCRegUnitRootIterator R(*U, &TRI);
+    ++R;
+    if (!R.isValid())
+      continue;
+    ExpAliasUnits.set(*U);
+    CheckUnits = true;
+  }
+}
+
+bool RegisterAggr::hasAliasOf(RegisterRef RR) const {
+  uint32_t SuperR = getLargestSuperReg(RR.Reg);
+  auto F = Masks.find(SuperR);
+  if (F != Masks.end()) {
+    LaneBitmask M = LMI.getLaneMaskForIndex(RR.Sub);
+    if (F->second & composeMaskForReg(RR.Reg, M, SuperR))
+      return true;
+  }
+  if (CheckUnits) {
+    for (MCRegUnitIterator U(RR.Reg, &TRI); U.isValid(); ++U)
+      if (ExpAliasUnits.test(*U))
+        return true;
+  }
+  return false;
+}
+
+bool RegisterAggr::hasCoverOf(RegisterRef RR) const {
+  uint32_t SuperR = getLargestSuperReg(RR.Reg);
+  auto F = Masks.find(SuperR);
+  if (F == Masks.end())
+    return false;
+  LaneBitmask M = LMI.getLaneMaskForIndex(RR.Sub);
+  LaneBitmask SuperM = composeMaskForReg(RR.Reg, M, SuperR);
+  return (SuperM & F->second) == SuperM;
+}
+
+RegisterAggr &RegisterAggr::insert(RegisterRef RR) {
+  setMaskRaw(RR.Reg, LMI.getLaneMaskForIndex(RR.Sub));
+  return *this;
+}
+
+RegisterAggr &RegisterAggr::insert(const RegisterAggr &RG) {
+  for (auto P : RG.Masks)
+    setMaskRaw(P.first, P.second);
+  return *this;
+}
+
+RegisterAggr &RegisterAggr::clear(RegisterRef RR) {
+  uint32_t SuperR = getLargestSuperReg(RR.Reg);
+  auto F = Masks.find(SuperR);
+  if (F == Masks.end())
+    return *this;
+  LaneBitmask M = LMI.getLaneMaskForIndex(RR.Sub);
+  LaneBitmask NewM = F->second & ~composeMaskForReg(RR.Reg, M, SuperR);
+  if (NewM == LaneBitmask(0))
+    Masks.erase(F);
+  else
+    F->second = NewM;
+  return *this;
+}
+
+void RegisterAggr::print(raw_ostream &OS) const {
+  OS << '{';
+  for (auto I : Masks)
+    OS << ' ' << PrintReg(I.first, &TRI) << ':' << PrintLaneMask(I.second);
+  OS << " }";
+}
+
+
 //
 // The data flow graph construction.
 //
 
 DataFlowGraph::DataFlowGraph(MachineFunction &mf, const TargetInstrInfo &tii,
       const TargetRegisterInfo &tri, const MachineDominatorTree &mdt,
-      const MachineDominanceFrontier &mdf, const RegisterAliasInfo &rai,
-      const TargetOperandInfo &toi)
-    : TimeG("rdf"), MF(mf), TII(tii), TRI(tri), MDT(mdt), MDF(mdf), RAI(rai),
-      TOI(toi) {
+      const MachineDominanceFrontier &mdf, const TargetOperandInfo &toi)
+    : TimeG("rdf"), MF(mf), TII(tii), TRI(tri), MDT(mdt), MDF(mdf), TOI(toi) {
 }
 
 
@@ -879,16 +832,33 @@ unsigned DataFlowGraph::DefStack::nextDo
   return P;
 }
 
-std::vector<uint32_t> DataFlowGraph::getLandingPadLiveIns() const {
-  std::vector<uint32_t> LR;
+
+// Register information.
+
+// Get the list of references aliased to RR. Lane masks are ignored.
+RegisterSet DataFlowGraph::getAliasSet(uint32_t Reg) const {
+  // Do not include RR in the alias set. For virtual registers return an
+  // empty set.
+  RegisterSet AS;
+  if (TargetRegisterInfo::isVirtualRegister(Reg))
+    return AS;
+  assert(TargetRegisterInfo::isPhysicalRegister(Reg));
+
+  for (MCRegAliasIterator AI(Reg, &TRI, false); AI.isValid(); ++AI)
+    AS.insert({*AI,0});
+  return AS;
+}
+
+RegisterSet DataFlowGraph::getLandingPadLiveIns() const {
+  RegisterSet LR;
   const Function &F = *MF.getFunction();
   const Constant *PF = F.hasPersonalityFn() ? F.getPersonalityFn()
                                             : nullptr;
   const TargetLowering &TLI = *MF.getSubtarget().getTargetLowering();
-  if (uint32_t EPReg = TLI.getExceptionPointerRegister(PF))
-    LR.push_back(EPReg);
-  if (uint32_t ESReg = TLI.getExceptionSelectorRegister(PF))
-    LR.push_back(ESReg);
+  if (uint32_t R = TLI.getExceptionPointerRegister(PF))
+    LR.insert({R,0});
+  if (uint32_t R = TLI.getExceptionSelectorRegister(PF))
+    LR.insert({R,0});
   return LR;
 }
 
@@ -1037,7 +1007,7 @@ void DataFlowGraph::build(unsigned Optio
   // branches in the program, or fall-throughs from other blocks. They
   // are entered from the exception handling runtime and target's ABI
   // may define certain registers as defined on entry to such a block.
-  std::vector<uint32_t> EHRegs = getLandingPadLiveIns();
+  RegisterSet EHRegs = getLandingPadLiveIns();
   if (!EHRegs.empty()) {
     for (NodeAddr<BlockNode*> BA : Blocks) {
       const MachineBasicBlock &B = *BA.Addr->getCode();
@@ -1050,15 +1020,15 @@ void DataFlowGraph::build(unsigned Optio
         Preds.push_back(findBlock(PB));
 
       // Build phi nodes for each live-in.
-      for (uint32_t R : EHRegs) {
+      for (RegisterRef RR : EHRegs) {
         NodeAddr<PhiNode*> PA = newPhi(BA);
         uint16_t PhiFlags = NodeAttrs::PhiRef | NodeAttrs::Preserving;
         // Add def:
-        NodeAddr<DefNode*> DA = newDef(PA, {R,0}, PhiFlags);
+        NodeAddr<DefNode*> DA = newDef(PA, RR, PhiFlags);
         PA.Addr->addMember(DA, *this);
         // Add uses (no reaching defs for phi uses):
         for (NodeAddr<BlockNode*> PBA : Preds) {
-          NodeAddr<PhiUseNode*> PUA = newPhiUse(PA, {R,0}, PBA);
+          NodeAddr<PhiUseNode*> PUA = newPhiUse(PA, RR, PBA);
           PA.Addr->addMember(PUA, *this);
         }
       }
@@ -1130,9 +1100,9 @@ void DataFlowGraph::pushDefs(NodeAddr<In
   for (NodeAddr<DefNode*> DA : Defs) {
     if (Visited.count(DA.Id))
       continue;
+
     NodeList Rel = getRelatedRefs(IA, DA);
     NodeAddr<DefNode*> PDA = Rel.front();
-    // Push the definition on the stack for the register and all aliases.
     RegisterRef RR = PDA.Addr->getRegRef();
 #ifndef NDEBUG
     // Assert if the register is defined in two or more unrelated defs.
@@ -1145,13 +1115,16 @@ void DataFlowGraph::pushDefs(NodeAddr<In
       llvm_unreachable(nullptr);
     }
 #endif
-    DefM[RR].push(DA);
-    for (auto A : RAI.getAliasSet(RR)) {
+    // Push the definition on the stack for the register and all aliases.
+    // The def stack traversal in linkNodeUp will check the exact aliasing.
+    DefM[RR.Reg].push(DA);
+    for (RegisterRef A : getAliasSet(RR.Reg /*FIXME? use RegisterRef*/)) {
+      // Check that we don't push the same def twice.
       assert(A != RR);
-      DefM[A].push(DA);
+      DefM[A.Reg].push(DA);
     }
     // Mark all the related defs as visited.
-    for (auto T : Rel)
+    for (NodeAddr<NodeBase*> T : Rel)
       Visited.insert(T.Id);
   }
 }
@@ -1171,6 +1144,62 @@ NodeList DataFlowGraph::getRelatedRefs(N
   return Refs;
 }
 
+// Return true if RA and RB overlap, false otherwise.
+bool DataFlowGraph::alias(RegisterRef RA, RegisterRef RB) const {
+  // Handling of physical registers.
+  bool IsPhysA = TargetRegisterInfo::isPhysicalRegister(RA.Reg);
+  bool IsPhysB = TargetRegisterInfo::isPhysicalRegister(RB.Reg);
+  if (IsPhysA != IsPhysB)
+    return false;
+  if (IsPhysA) {
+    LaneBitmask LA = LMI.getLaneMaskForIndex(RA.Sub);
+    LaneBitmask LB = LMI.getLaneMaskForIndex(RB.Sub);
+
+    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 the returned lane mask is 0, it should be treated as ~0
+      // (or the lane mask from the given register ref should be ignored).
+      // This can happen when a register has only one unit.
+      if (PA.first < PB.first || (PA.second && !(PA.second & LA)))
+        ++UMA;
+      else if (PB.first < PA.first || (PB.second && !(PB.second & LB)))
+        ++UMB;
+      else
+        return true;
+    }
+    return false;
+  }
+
+  // Handling of virtual registers.
+  bool IsVirtA = TargetRegisterInfo::isVirtualRegister(RA.Reg);
+  bool IsVirtB = TargetRegisterInfo::isVirtualRegister(RB.Reg);
+  if (IsVirtA != IsVirtB)
+    return false;
+  if (IsVirtA) {
+    if (RA.Reg != RB.Reg)
+      return false;
+    // RA and RB refer to the same register. If any of them refer to the
+    // whole register, they must be aliased.
+    if (RA.Sub == 0 || RB.Sub == 0)
+      return true;
+    unsigned SA = TRI.getSubRegIdxSize(RA.Sub);
+    unsigned OA = TRI.getSubRegIdxOffset(RA.Sub);
+    unsigned SB = TRI.getSubRegIdxSize(RB.Sub);
+    unsigned OB = TRI.getSubRegIdxOffset(RB.Sub);
+    if (OA <= OB && OA+SA > OB)
+      return true;
+    if (OB <= OA && OB+SB > OA)
+      return true;
+    return false;
+  }
+
+  return false;
+}
+
 
 // Clear all information in the graph.
 void DataFlowGraph::reset() {
@@ -1301,7 +1330,7 @@ void DataFlowGraph::buildStmt(NodeAddr<B
       if (!UseOp.isReg() || !UseOp.isUse() || UseOp.isUndef())
         continue;
       RegisterRef UR = { UseOp.getReg(), UseOp.getSubReg() };
-      if (RAI.alias(DR, UR, *this))
+      if (alias(DR, UR))
         return false;
     }
     return true;
@@ -1407,15 +1436,15 @@ void DataFlowGraph::buildStmt(NodeAddr<B
 // that block, and from all blocks dominated by it.
 void DataFlowGraph::buildBlockRefs(NodeAddr<BlockNode*> BA,
       BlockRefsMap &RefM) {
-  auto &Refs = RefM[BA.Id];
+  RegisterSet &Refs = RefM[BA.Id];
   MachineDomTreeNode *N = MDT.getNode(BA.Addr->getCode());
   assert(N);
   for (auto I : *N) {
     MachineBasicBlock *SB = I->getBlock();
-    auto SBA = findBlock(SB);
+    NodeAddr<BlockNode*> SBA = findBlock(SB);
     buildBlockRefs(SBA, RefM);
-    const auto &SRs = RefM[SBA.Id];
-    Refs.insert(SRs.begin(), SRs.end());
+    const RegisterSet &RefsS = RefM[SBA.Id];
+    Refs.insert(RefsS.begin(), RefsS.end());
   }
 
   for (NodeAddr<InstrNode*> IA : BA.Addr->members(*this))
@@ -1451,8 +1480,7 @@ void DataFlowGraph::recordDefsForDF(Bloc
       Defs.insert(RA.Addr->getRegRef());
   }
 
-  // Finally, add the set of defs to each block in the iterated dominance
-  // frontier.
+  // Calculate the iterated dominance frontier of BB.
   const MachineDominanceFrontier::DomSetType &DF = DFLoc->second;
   SetVector<MachineBasicBlock*> IDF(DF.begin(), DF.end());
   for (unsigned i = 0; i < IDF.size(); ++i) {
@@ -1464,13 +1492,15 @@ void DataFlowGraph::recordDefsForDF(Bloc
   // Get the register references that are reachable from this block.
   RegisterSet &Refs = RefM[BA.Id];
   for (auto DB : IDF) {
-    auto DBA = findBlock(DB);
-    const auto &Rs = RefM[DBA.Id];
-    Refs.insert(Rs.begin(), Rs.end());
+    NodeAddr<BlockNode*> DBA = findBlock(DB);
+    const RegisterSet &RefsD = RefM[DBA.Id];
+    Refs.insert(RefsD.begin(), RefsD.end());
   }
 
+  // Finally, add the set of defs to each block in the iterated dominance
+  // frontier.
   for (auto DB : IDF) {
-    auto DBA = findBlock(DB);
+    NodeAddr<BlockNode*> DBA = findBlock(DB);
     PhiM[DBA.Id].insert(Defs.begin(), Defs.end());
   }
 }
@@ -1491,7 +1521,7 @@ void DataFlowGraph::buildPhis(BlockRefsM
 
   auto MaxCoverIn = [this] (RegisterRef RR, RegisterSet &RRs) -> RegisterRef {
     for (auto I : RRs)
-      if (I != RR && RAI.covers(I, RR, *this))
+      if (I != RR && RegisterAggr::isCoverOf(I, RR, LMI, TRI))
         RR = I;
     return RR;
   };
@@ -1518,18 +1548,16 @@ void DataFlowGraph::buildPhis(BlockRefsM
   auto Aliased = [this,&MaxRefs](RegisterRef RR,
                                  std::vector<unsigned> &Closure) -> bool {
     for (auto I : Closure)
-      if (RAI.alias(RR, MaxRefs[I], *this))
+      if (alias(RR, MaxRefs[I]))
         return true;
     return false;
   };
 
   // Prepare a list of NodeIds of the block's predecessors.
-  std::vector<NodeId> PredList;
+  NodeList Preds;
   const MachineBasicBlock *MBB = BA.Addr->getCode();
-  for (auto PB : MBB->predecessors()) {
-    auto B = findBlock(PB);
-    PredList.push_back(B.Id);
-  }
+  for (auto PB : MBB->predecessors())
+    Preds.push_back(findBlock(PB));
 
   while (!MaxRefs.empty()) {
     // Put the first element in the closure, and then add all subsequent
@@ -1553,8 +1581,7 @@ void DataFlowGraph::buildPhis(BlockRefsM
       PA.Addr->addMember(DA, *this);
     }
     // Add phi uses.
-    for (auto P : PredList) {
-      auto PBA = addr<BlockNode*>(P);
+    for (NodeAddr<BlockNode*> PBA : Preds) {
       for (unsigned X = 0; X != CS; ++X) {
         RegisterRef RR = MaxRefs[ClosureIdx[X]];
         NodeAddr<PhiUseNode*> PUA = newPhiUse(PA, RR, PBA);
@@ -1632,21 +1659,21 @@ void DataFlowGraph::linkRefUp(NodeAddr<I
   NodeAddr<T> TAP;
 
   // References from the def stack that have been examined so far.
-  RegisterSet Defs;
+  RegisterAggr Defs(LMI, TRI);
 
   for (auto I = DS.top(), E = DS.bottom(); I != E; I.down()) {
     RegisterRef QR = I->Addr->getRegRef();
-    auto AliasQR = [QR,this] (RegisterRef RR) -> bool {
-      return RAI.alias(QR, RR, *this);
-    };
-    bool PrecUp = RAI.covers(QR, RR, *this);
+
     // Skip all defs that are aliased to any of the defs that we have already
-    // seen. If we encounter a covering def, stop the stack traversal early.
-    if (any_of(Defs, AliasQR)) {
-      if (PrecUp)
+    // seen. If this completes a cover of RR, stop the stack traversal.
+    bool Alias = Defs.hasAliasOf(QR);
+    bool Cover = Defs.insert(QR).hasCoverOf(RR);
+    if (Alias) {
+      if (Cover)
         break;
       continue;
     }
+
     // The reaching def.
     NodeAddr<DefNode*> RDA = *I;
 
@@ -1662,27 +1689,29 @@ void DataFlowGraph::linkRefUp(NodeAddr<I
     // Create the link.
     TAP.Addr->linkToDef(TAP.Id, RDA);
 
-    if (PrecUp)
+    if (Cover)
       break;
-    Defs.insert(QR);
   }
 }
 
 // Create data-flow links for all reference nodes in the statement node SA.
 void DataFlowGraph::linkStmtRefs(DefStackMap &DefM, NodeAddr<StmtNode*> SA) {
+#ifndef NDEBUG
   RegisterSet Defs;
+#endif
 
   // Link all nodes (upwards in the data-flow) with their reaching defs.
   for (NodeAddr<RefNode*> RA : SA.Addr->members(*this)) {
     uint16_t Kind = RA.Addr->getKind();
     assert(Kind == NodeAttrs::Def || Kind == NodeAttrs::Use);
     RegisterRef RR = RA.Addr->getRegRef();
-    // Do not process multiple defs of the same reference.
-    if (Kind == NodeAttrs::Def && Defs.count(RR))
-      continue;
+#ifndef NDEBUG
+    // Do not expect multiple defs of the same reference.
+    assert(Kind != NodeAttrs::Def || !Defs.count(RR));
     Defs.insert(RR);
+#endif
 
-    auto F = DefM.find(RR);
+    auto F = DefM.find(RR.Reg);
     if (F == DefM.end())
       continue;
     DefStack &DS = F->second;
@@ -1732,7 +1761,7 @@ void DataFlowGraph::linkBlockRefs(DefSta
     return PUA.Addr->getPredecessor() == BA.Id;
   };
 
-  std::vector<uint32_t> EHLiveIns = getLandingPadLiveIns();
+  RegisterSet EHLiveIns = getLandingPadLiveIns();
   MachineBasicBlock *MBB = BA.Addr->getCode();
 
   for (auto SB : MBB->successors()) {
@@ -1744,14 +1773,14 @@ void DataFlowGraph::linkBlockRefs(DefSta
         // Find what register this phi is for.
         NodeAddr<RefNode*> RA = IA.Addr->getFirstMember(*this);
         assert(RA.Id != 0);
-        if (find(EHLiveIns, RA.Addr->getRegRef().Reg) != EHLiveIns.end())
+        if (EHLiveIns.count(RA.Addr->getRegRef()))
           continue;
       }
       // Go over each phi use associated with MBB, and link it.
       for (auto U : IA.Addr->members_if(IsUseForBA, *this)) {
         NodeAddr<PhiUseNode*> PUA = U;
         RegisterRef RR = PUA.Addr->getRegRef();
-        linkRefUp<UseNode*>(IA, PUA, DefM[RR]);
+        linkRefUp<UseNode*>(IA, PUA, DefM[RR.Reg]);
       }
     }
   }

Modified: llvm/trunk/lib/Target/Hexagon/RDFGraph.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/RDFGraph.h?rev=283122&r1=283121&r2=283122&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/RDFGraph.h (original)
+++ llvm/trunk/lib/Target/Hexagon/RDFGraph.h Mon Oct  3 12:14:48 2016
@@ -224,6 +224,7 @@
 #ifndef RDF_GRAPH_H
 #define RDF_GRAPH_H
 
+#include "llvm/ADT/BitVector.h"
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/raw_ostream.h"
@@ -236,6 +237,11 @@
 #include <unordered_map>
 #include <vector>
 
+// RDF uses uint32_t to refer to registers. This is to ensure that the type
+// size remains specific. In other places, registers are often stored using
+// unsigned.
+static_assert(sizeof(uint32_t) == sizeof(unsigned), "Those should be equal");
+
 namespace llvm {
   class MachineBasicBlock;
   class MachineFunction;
@@ -421,32 +427,6 @@ namespace rdf {
   };
   typedef std::set<RegisterRef> RegisterSet;
 
-  struct RegisterAliasInfo {
-    RegisterAliasInfo(const TargetRegisterInfo &tri) : TRI(tri) {}
-    virtual ~RegisterAliasInfo() {}
-
-    virtual std::vector<RegisterRef> getAliasSet(RegisterRef RR) const;
-    virtual bool alias(RegisterRef RA, RegisterRef RB,
-                       const DataFlowGraph &DFG) const;
-    virtual bool covers(RegisterRef RA, RegisterRef RB,
-                        const DataFlowGraph &DFG) const;
-    virtual bool covers(const RegisterSet &RRs, RegisterRef RR,
-                        const DataFlowGraph &DFG) const;
-
-    const TargetRegisterInfo &TRI;
-
-  protected:
-    LaneBitmask getLaneMask(RegisterRef RR, const DataFlowGraph &DFG) const;
-
-    struct CommonRegister {
-      CommonRegister(unsigned RegA, LaneBitmask LA,
-                     unsigned RegB, LaneBitmask LB,
-                     const TargetRegisterInfo &TRI);
-      unsigned SuperReg;
-      LaneBitmask MaskA, MaskB;
-    };
-  };
-
   struct TargetOperandInfo {
     TargetOperandInfo(const TargetInstrInfo &tii) : TII(tii) {}
     virtual ~TargetOperandInfo() {}
@@ -463,7 +443,7 @@ namespace rdf {
   // as invalid and is never allocated.
   template <typename T, unsigned N = 32>
   struct IndexedSet {
-    IndexedSet() : Map(N) {}
+    IndexedSet() : Map() { Map.reserve(N); }
     const T get(uint32_t Idx) const {
       // Index Idx corresponds to Map[Idx-1].
       assert(Idx != 0 && !Map.empty() && Idx-1 < Map.size());
@@ -473,7 +453,7 @@ namespace rdf {
       // Linear search.
       auto F = find(Map, Val);
       if (F != Map.end())
-        return *F;
+        return F - Map.begin();
       Map.push_back(Val);
       return Map.size();  // Return actual_index + 1.
     }
@@ -482,6 +462,55 @@ namespace rdf {
     std::vector<T> Map;
   };
 
+  struct LaneMaskIndex : private IndexedSet<LaneBitmask> {
+    LaneBitmask getLaneMaskForIndex(uint32_t K) const {
+      return K == 0 ? ~LaneBitmask(0) : get(K);
+    }
+    uint32_t getIndexForLaneMask(LaneBitmask LM) {
+      assert(LM != LaneBitmask(0));
+      return LM == ~LaneBitmask(0) ? 0 : insert(LM);
+    }
+  };
+
+  struct RegisterAggr {
+    typedef std::pair<uint32_t,LaneBitmask> ValueType;
+
+    RegisterAggr(const LaneMaskIndex &m, const TargetRegisterInfo &tri)
+        : Masks(), ExpAliasUnits(tri.getNumRegUnits()), CheckUnits(false),
+          LMI(m), TRI(tri) {}
+    RegisterAggr(const RegisterAggr &RG)
+        : Masks(RG.Masks), ExpAliasUnits(RG.ExpAliasUnits),
+          CheckUnits(RG.CheckUnits), LMI(RG.LMI), TRI(RG.TRI) {}
+
+    bool empty() const { return Masks.empty(); }
+    bool hasAliasOf(RegisterRef RR) const;
+    bool hasCoverOf(RegisterRef RR) const;
+    static bool isCoverOf(RegisterRef RefA, RegisterRef RefB,
+                     const LaneMaskIndex &LMI, const TargetRegisterInfo &TRI) {
+      return RegisterAggr(LMI, TRI).insert(RefA).hasCoverOf(RefB);
+    }
+
+    RegisterAggr &insert(RegisterRef RR);
+    RegisterAggr &insert(const RegisterAggr &RG);
+    RegisterAggr &clear(RegisterRef RR);
+
+    void print(raw_ostream &OS) const;
+
+  private:
+    typedef std::unordered_map<ValueType::first_type,
+                               ValueType::second_type> MapType;
+    MapType Masks;
+    BitVector ExpAliasUnits; // Register units for explicit aliases.
+    bool CheckUnits;
+    const LaneMaskIndex &LMI;
+    const TargetRegisterInfo &TRI;
+
+    uint32_t getLargestSuperReg(uint32_t Reg) const;
+    void setMaskRaw(uint32_t Reg, LaneBitmask LM);
+    LaneBitmask composeMaskForReg(uint32_t Reg, LaneBitmask LM,
+                                  uint32_t SuperR) const;
+  };
+
 
   struct NodeBase {
   public:
@@ -669,8 +698,7 @@ namespace rdf {
   struct DataFlowGraph {
     DataFlowGraph(MachineFunction &mf, const TargetInstrInfo &tii,
         const TargetRegisterInfo &tri, const MachineDominatorTree &mdt,
-        const MachineDominanceFrontier &mdf, const RegisterAliasInfo &rai,
-        const TargetOperandInfo &toi);
+        const MachineDominanceFrontier &mdf, const TargetOperandInfo &toi);
 
     NodeBase *ptr(NodeId N) const;
     template <typename T> T ptr(NodeId N) const {
@@ -682,34 +710,14 @@ namespace rdf {
       return { ptr<T>(N), N };
     }
 
-    NodeAddr<FuncNode*> getFunc() const {
-      return Func;
-    }
-    MachineFunction &getMF() const {
-      return MF;
-    }
-    const TargetInstrInfo &getTII() const {
-      return TII;
-    }
-    const TargetRegisterInfo &getTRI() const {
-      return TRI;
-    }
-    const MachineDominatorTree &getDT() const {
-      return MDT;
-    }
-    const MachineDominanceFrontier &getDF() const {
-      return MDF;
-    }
-    const RegisterAliasInfo &getRAI() const {
-      return RAI;
-    }
-
-    LaneBitmask getLaneMaskForIndex(uint32_t K) const {
-      return LMMap.get(K);
-    }
-    uint32_t getIndexForLaneMask(LaneBitmask LM) {
-      return LMMap.insert(LM);
-    }
+    NodeAddr<FuncNode*> getFunc() const { return Func; }
+    MachineFunction &getMF() const { return MF; }
+    LaneMaskIndex &getLMI() { return LMI; }
+    const LaneMaskIndex &getLMI() const { return LMI; }
+    const TargetInstrInfo &getTII() const { return TII; }
+    const TargetRegisterInfo &getTRI() const { return TRI; }
+    const MachineDominatorTree &getDT() const { return MDT; }
+    const MachineDominanceFrontier &getDF() const { return MDF; }
 
     struct DefStack {
       DefStack() = default;
@@ -759,14 +767,9 @@ namespace rdf {
       StorageType Stack;
     };
 
-    struct RegisterRefHasher {
-      unsigned operator() (RegisterRef RR) const {
-        return RR.Reg | (RR.Sub << 24);
-      }
-    };
     // Make this std::unordered_map for speed of accessing elements.
-    typedef std::unordered_map<RegisterRef,DefStack,RegisterRefHasher>
-          DefStackMap;
+    // Map: Register (physical or virtual) -> DefStack
+    typedef std::unordered_map<uint32_t,DefStack> DefStackMap;
 
     void build(unsigned Options = BuildOptions::None);
     void pushDefs(NodeAddr<InstrNode*> IA, DefStackMap &DM);
@@ -826,10 +829,14 @@ namespace rdf {
       return (Flags & NodeAttrs::Preserving) && !(Flags & NodeAttrs::Undef);
     }
 
+    // Register aliasing.
+    bool alias(RegisterRef RA, RegisterRef RB) const;
+
   private:
     void reset();
 
-    std::vector<uint32_t> getLandingPadLiveIns() const;
+    RegisterSet getAliasSet(uint32_t Reg) const;
+    RegisterSet getLandingPadLiveIns() const;
 
     NodeAddr<NodeBase*> newNode(uint16_t Attrs);
     NodeAddr<NodeBase*> cloneNode(const NodeAddr<NodeBase*> B);
@@ -886,14 +893,13 @@ namespace rdf {
     // Local map:  MachineBasicBlock -> NodeAddr<BlockNode*>
     std::map<MachineBasicBlock*,NodeAddr<BlockNode*>> BlockNodes;
     // Lane mask map.
-    IndexedSet<LaneBitmask> LMMap;
+    LaneMaskIndex LMI;
 
     MachineFunction &MF;
     const TargetInstrInfo &TII;
     const TargetRegisterInfo &TRI;
     const MachineDominatorTree &MDT;
     const MachineDominanceFrontier &MDF;
-    const RegisterAliasInfo &RAI;
     const TargetOperandInfo &TOI;
   };  // struct DataFlowGraph
 

Modified: llvm/trunk/lib/Target/Hexagon/RDFLiveness.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/RDFLiveness.cpp?rev=283122&r1=283121&r2=283122&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/RDFLiveness.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/RDFLiveness.cpp Mon Oct  3 12:14:48 2016
@@ -85,7 +85,7 @@ namespace rdf {
 // the data-flow.
 
 NodeList Liveness::getAllReachingDefs(RegisterRef RefRR,
-      NodeAddr<RefNode*> RefA, bool FullChain, const RegisterSet &DefRRs) {
+      NodeAddr<RefNode*> RefA, bool FullChain, const RegisterAggr &DefRRs) {
   NodeList RDefs; // Return value.
   SetVector<NodeId> DefQ;
   SetVector<NodeId> Owners;
@@ -118,8 +118,9 @@ NodeList Liveness::getAllReachingDefs(Re
       continue;
     // Stop at the covering/overwriting def of the initial register reference.
     RegisterRef RR = TA.Addr->getRegRef();
-    if (!DFG.IsPreservingDef(TA) && RAI.covers(RR, RefRR, DFG))
-      continue;
+    if (!DFG.IsPreservingDef(TA))
+      if (RegisterAggr::isCoverOf(RR, RefRR, DFG.getLMI(), TRI))
+        continue;
     // Get the next level of reaching defs. This will include multiple
     // reaching defs for shadows.
     for (auto S : DFG.getRelatedRefs(TA.Addr->getOwner(DFG), TA))
@@ -133,7 +134,7 @@ NodeList Liveness::getAllReachingDefs(Re
   for (auto N : DefQ) {
     auto TA = DFG.addr<DefNode*>(N);
     bool IsPhi = TA.Addr->getFlags() & NodeAttrs::PhiRef;
-    if (!IsPhi && !RAI.alias(RefRR, TA.Addr->getRegRef(), DFG))
+    if (!IsPhi && !DFG.alias(RefRR, TA.Addr->getRegRef()))
       continue;
     Defs.insert(TA.Id);
     Owners.insert(TA.Addr->getOwner(DFG).Id);
@@ -195,14 +196,14 @@ NodeList Liveness::getAllReachingDefs(Re
   //                     covered if we added A first, and A would be covered
   //                     if we added B first.
 
-  RegisterSet RRs = DefRRs;
+  RegisterAggr RRs(DefRRs);
 
   auto DefInSet = [&Defs] (NodeAddr<RefNode*> TA) -> bool {
     return TA.Addr->getKind() == NodeAttrs::Def &&
            Defs.count(TA.Id);
   };
   for (auto T : Tmp) {
-    if (!FullChain && RAI.covers(RRs, RefRR, DFG))
+    if (!FullChain && RRs.hasCoverOf(RefRR))
       break;
     auto TA = DFG.addr<InstrNode*>(T);
     bool IsPhi = DFG.IsCode<NodeAttrs::Phi>(TA);
@@ -217,7 +218,7 @@ NodeList Liveness::getAllReachingDefs(Re
       //   phi d1<R3>(,d2,), ...  Phi def d1 is covered by d2.
       //   d2<R3>(d1,,u3), ...
       //   ..., u3<D1>(d2)        This use needs to be live on entry.
-      if (FullChain || IsPhi || !RAI.covers(RRs, QR, DFG))
+      if (FullChain || IsPhi || !RRs.hasCoverOf(QR))
         Ds.push_back(DA);
     }
     RDefs.insert(RDefs.end(), Ds.begin(), Ds.end());
@@ -240,19 +241,12 @@ NodeList Liveness::getAllReachingDefs(Re
 }
 
 
-static const RegisterSet NoRegs;
-
-NodeList Liveness::getAllReachingDefs(NodeAddr<RefNode*> RefA) {
-  return getAllReachingDefs(RefA.Addr->getRegRef(), RefA, false, NoRegs);
-}
-
-
 NodeSet Liveness::getAllReachingDefsRec(RegisterRef RefRR,
       NodeAddr<RefNode*> RefA, NodeSet &Visited, const NodeSet &Defs) {
   // Collect all defined registers. Do not consider phis to be defining
   // anything, only collect "real" definitions.
-  RegisterSet DefRRs;
-  for (const auto D : Defs) {
+  RegisterAggr DefRRs(DFG.getLMI(), TRI);
+  for (NodeId D : Defs) {
     const auto DA = DFG.addr<const DefNode*>(D);
     if (!(DA.Addr->getFlags() & NodeAttrs::PhiRef))
       DefRRs.insert(DA.Addr->getRegRef());
@@ -289,12 +283,12 @@ NodeSet Liveness::getAllReachingDefsRec(
 
 
 NodeSet Liveness::getAllReachedUses(RegisterRef RefRR,
-      NodeAddr<DefNode*> DefA, const RegisterSet &DefRRs) {
+      NodeAddr<DefNode*> DefA, const RegisterAggr &DefRRs) {
   NodeSet Uses;
 
   // If the original register is already covered by all the intervening
   // defs, no more uses can be reached.
-  if (RAI.covers(DefRRs, RefRR, DFG))
+  if (DefRRs.hasCoverOf(RefRR))
     return Uses;
 
   // Add all directly reached uses.
@@ -305,7 +299,7 @@ NodeSet Liveness::getAllReachedUses(Regi
     auto UA = DFG.addr<UseNode*>(U);
     if (!(UA.Addr->getFlags() & NodeAttrs::Undef)) {
       auto UR = UA.Addr->getRegRef();
-      if (RAI.alias(RefRR, UR, DFG) && !RAI.covers(DefRRs, UR, DFG))
+      if (DFG.alias(RefRR, UR) && !DefRRs.hasCoverOf(UR))
         Uses.insert(U);
     }
     U = UA.Addr->getSibling();
@@ -318,14 +312,14 @@ NodeSet Liveness::getAllReachedUses(Regi
     auto DR = DA.Addr->getRegRef();
     // If this def is already covered, it cannot reach anything new.
     // Similarly, skip it if it is not aliased to the interesting register.
-    if (RAI.covers(DefRRs, DR, DFG) || !RAI.alias(RefRR, DR, DFG))
+    if (DefRRs.hasCoverOf(DR) || !DFG.alias(RefRR, DR))
       continue;
     NodeSet T;
     if (DFG.IsPreservingDef(DA)) {
       // If it is a preserving def, do not update the set of intervening defs.
       T = getAllReachedUses(RefRR, DA, DefRRs);
     } else {
-      RegisterSet NewDefRRs = DefRRs;
+      RegisterAggr NewDefRRs = DefRRs;
       NewDefRRs.insert(DR);
       T = getAllReachedUses(RefRR, DA, NewDefRRs);
     }
@@ -347,21 +341,21 @@ void Liveness::computePhiInfo() {
   }
 
   // phi use -> (map: reaching phi -> set of registers defined in between)
-  std::map<NodeId,std::map<NodeId,RegisterSet>> PhiUp;
+  std::map<NodeId,std::map<NodeId,RegisterAggr>> PhiUp;
   std::vector<NodeId> PhiUQ;  // Work list of phis for upward propagation.
 
   // Go over all phis.
   for (NodeAddr<PhiNode*> PhiA : Phis) {
     // Go over all defs and collect the reached uses that are non-phi uses
     // (i.e. the "real uses").
-    auto &RealUses = RealUseMap[PhiA.Id];
-    auto PhiRefs = PhiA.Addr->members(DFG);
+    RefMap &RealUses = RealUseMap[PhiA.Id];
+    NodeList PhiRefs = PhiA.Addr->members(DFG);
 
     // Have a work queue of defs whose reached uses need to be found.
     // For each def, add to the queue all reached (non-phi) defs.
     SetVector<NodeId> DefQ;
     NodeSet PhiDefs;
-    for (auto R : PhiRefs) {
+    for (NodeAddr<RefNode*> R : PhiRefs) {
       if (!DFG.IsRef<NodeAttrs::Def>(R))
         continue;
       DefQ.insert(R.Id);
@@ -466,12 +460,17 @@ void Liveness::computePhiInfo() {
 
       for (NodeAddr<UseNode*> VA : DFG.getRelatedRefs(PhiA, UA)) {
         SeenUses.insert(VA.Id);
-        RegisterSet DefRRs;
+        RegisterAggr DefRRs(DFG.getLMI(), TRI);
         for (NodeAddr<DefNode*> DA : getAllReachingDefs(VA)) {
           if (DA.Addr->getFlags() & NodeAttrs::PhiRef) {
             NodeId RP = DA.Addr->getOwner(DFG).Id;
             NodeId FU = FirstUse.insert({RP,VA.Id}).first->second;
-            PhiUp[FU][RP].insert(DefRRs.begin(), DefRRs.end());
+            std::map<NodeId,RegisterAggr> &M = PhiUp[FU];
+            auto F = M.find(RP);
+            if (F == M.end())
+              M.insert(std::make_pair(RP, DefRRs));
+            else
+              F->second.insert(DefRRs);
           }
           DefRRs.insert(DA.Addr->getRegRef());
         }
@@ -485,7 +484,7 @@ void Liveness::computePhiInfo() {
       dbgs() << "phi " << Print<NodeId>(I.first, DFG) << " -> {";
       for (auto R : I.second)
         dbgs() << ' ' << Print<NodeId>(R.first, DFG)
-               << Print<RegisterSet>(R.second, DFG);
+               << Print<RegisterAggr>(R.second, DFG);
       dbgs() << " }\n";
     }
   }
@@ -520,10 +519,10 @@ void Liveness::computePhiInfo() {
 
     for (auto U : PUs) {
       NodeAddr<UseNode*> UA = U;
-      std::map<NodeId,RegisterSet> &PUM = PhiUp[UA.Id];
-      for (const std::pair<NodeId,RegisterSet> &P : PUM) {
+      std::map<NodeId,RegisterAggr> &PUM = PhiUp[UA.Id];
+      for (const std::pair<NodeId,RegisterAggr> &P : PUM) {
         bool Changed = false;
-        RegisterSet MidDefs = P.second;
+        const RegisterAggr &MidDefs = P.second;
 
         // Collect the set UpReached of uses that are reached by the current
         // phi PA, and are not covered by any intervening def between PA and
@@ -533,7 +532,7 @@ void Liveness::computePhiInfo() {
           RegisterRef R = T.first;
           if (!isRestrictedToRef(PA, UA, R))
             R = getRestrictedRegRef(UA);
-          if (!RAI.covers(MidDefs, R, DFG))
+          if (!MidDefs.hasCoverOf(R))
             UpReached.insert(R);
         }
         if (UpReached.empty())
@@ -654,7 +653,7 @@ void Liveness::computeLiveIns() {
           // The restricted ref may be different from the ref that was
           // accessed in the "real use". This means that this phi use
           // is not the one that carries this reference, so skip it.
-          if (!RAI.alias(R.first, RR, DFG))
+          if (!DFG.alias(R.first, RR))
             continue;
           for (auto D : getAllReachingDefs(RR, UA))
             LOX[RR].insert(D.Id);
@@ -787,7 +786,7 @@ bool Liveness::isRestrictedToRef(NodeAdd
     NodeId RD = TA.Addr->getReachingDef();
     if (RD == 0)
       continue;
-    if (RAI.alias(RR, DFG.addr<DefNode*>(RD).Addr->getRegRef(), DFG))
+    if (DFG.alias(RR, DFG.addr<DefNode*>(RD).Addr->getRegRef()))
       return false;
   }
   return true;
@@ -805,13 +804,6 @@ RegisterRef Liveness::getRestrictedRegRe
 }
 
 
-unsigned Liveness::getPhysReg(RegisterRef RR) const {
-  if (!TargetRegisterInfo::isPhysicalRegister(RR.Reg))
-    return 0;
-  return RR.Sub ? TRI.getSubReg(RR.Reg, RR.Sub) : RR.Reg;
-}
-
-
 // Helper function to obtain the basic block containing the reaching def
 // of the given use.
 MachineBasicBlock *Liveness::getBlockWithRef(NodeId RN) const {
@@ -899,13 +891,15 @@ void Liveness::traverse(MachineBasicBloc
       else {
         bool IsPreserving = DFG.IsPreservingDef(DA);
         if (IA.Addr->getKind() != NodeAttrs::Phi && !IsPreserving) {
-          bool Covering = RAI.covers(DDR, I.first, DFG);
+          bool Covering = RegisterAggr::isCoverOf(DDR, I.first,
+                                                  DFG.getLMI(), TRI);
           NodeId U = DA.Addr->getReachedUse();
           while (U && Covering) {
             auto DUA = DFG.addr<UseNode*>(U);
             if (!(DUA.Addr->getFlags() & NodeAttrs::Undef)) {
               RegisterRef Q = DUA.Addr->getRegRef();
-              Covering = RAI.covers(DA.Addr->getRegRef(), Q, DFG);
+              Covering = RegisterAggr::isCoverOf(DA.Addr->getRegRef(), Q,
+                                                 DFG.getLMI(), TRI);
             }
             U = DUA.Addr->getSibling();
           }
@@ -919,7 +913,7 @@ void Liveness::traverse(MachineBasicBloc
     for (auto R : Rest) {
       auto DA = DFG.addr<DefNode*>(R);
       RegisterRef DRR = DA.Addr->getRegRef();
-      RegisterSet RRs;
+      RegisterAggr RRs(DFG.getLMI(), TRI);
       for (NodeAddr<DefNode*> TA : getAllReachingDefs(DA)) {
         NodeAddr<InstrNode*> IA = TA.Addr->getOwner(DFG);
         NodeAddr<BlockNode*> BA = IA.Addr->getOwner(DFG);
@@ -928,7 +922,7 @@ void Liveness::traverse(MachineBasicBloc
           RRs.insert(TA.Addr->getRegRef());
         if (BA.Addr->getCode() == B)
           continue;
-        if (RAI.covers(RRs, DRR, DFG))
+        if (RRs.hasCoverOf(DRR))
           break;
         Defs.insert(TA.Id);
       }

Modified: llvm/trunk/lib/Target/Hexagon/RDFLiveness.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/RDFLiveness.h?rev=283122&r1=283121&r2=283122&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/RDFLiveness.h (original)
+++ llvm/trunk/lib/Target/Hexagon/RDFLiveness.h Mon Oct  3 12:14:48 2016
@@ -35,15 +35,24 @@ namespace rdf {
 
     Liveness(MachineRegisterInfo &mri, const DataFlowGraph &g)
       : DFG(g), TRI(g.getTRI()), MDT(g.getDT()), MDF(g.getDF()),
-        RAI(g.getRAI()), MRI(mri), Empty(), Trace(false) {}
+        MRI(mri), Empty(), NoRegs(g.getLMI(), g.getTRI()),
+        Trace(false) {}
 
     NodeList getAllReachingDefs(RegisterRef RefRR, NodeAddr<RefNode*> RefA,
-        bool FullChain = false, const RegisterSet &DefRRs = RegisterSet());
-    NodeList getAllReachingDefs(NodeAddr<RefNode*> RefA);
+        bool FullChain, const RegisterAggr &DefRRs);
+    NodeList getAllReachingDefs(NodeAddr<RefNode*> RefA) {
+      return getAllReachingDefs(RefA.Addr->getRegRef(), RefA, false, NoRegs);
+    }
+    NodeList getAllReachingDefs(RegisterRef RefRR, NodeAddr<RefNode*> RefA) {
+      return getAllReachingDefs(RefRR, RefA, false, NoRegs);
+    }
     NodeSet getAllReachingDefsRec(RegisterRef RefRR, NodeAddr<RefNode*> RefA,
         NodeSet &Visited, const NodeSet &Defs);
     NodeSet getAllReachedUses(RegisterRef RefRR, NodeAddr<DefNode*> DefA,
-        const RegisterSet &DefRRs = RegisterSet());
+        const RegisterAggr &DefRRs);
+    NodeSet getAllReachedUses(RegisterRef RefRR, NodeAddr<DefNode*> DefA) {
+      return getAllReachedUses(RefRR, DefA, NoRegs);
+    }
 
     LiveMapType &getLiveMap() { return LiveMap; }
     const LiveMapType &getLiveMap() const { return LiveMap; }
@@ -65,10 +74,10 @@ namespace rdf {
     const TargetRegisterInfo &TRI;
     const MachineDominatorTree &MDT;
     const MachineDominanceFrontier &MDF;
-    const RegisterAliasInfo &RAI;
     MachineRegisterInfo &MRI;
     LiveMapType LiveMap;
     const RefMap Empty;
+    const RegisterAggr NoRegs;
     bool Trace;
 
     // Cache of mapping from node ids (for RefNodes) to the containing
@@ -99,7 +108,6 @@ namespace rdf {
     bool isRestrictedToRef(NodeAddr<InstrNode*> IA, NodeAddr<RefNode*> RA,
         RegisterRef RR) const;
     RegisterRef getRestrictedRegRef(NodeAddr<RefNode*> RA) const;
-    unsigned getPhysReg(RegisterRef RR) const;
     MachineBasicBlock *getBlockWithRef(NodeId RN) const;
     void traverse(MachineBasicBlock *B, RefMap &LiveIn);
     void emptify(RefMap &M);




More information about the llvm-commits mailing list