[llvm] r293538 - [RDF] Add support for regmasks

Krzysztof Parzyszek via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 30 11:16:30 PST 2017


Author: kparzysz
Date: Mon Jan 30 13:16:30 2017
New Revision: 293538

URL: http://llvm.org/viewvc/llvm-project?rev=293538&view=rev
Log:
[RDF] Add support for regmasks

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

Modified: llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp?rev=293538&r1=293537&r2=293538&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/RDFGraph.cpp Mon Jan 30 13:16:30 2017
@@ -424,7 +424,7 @@ RegisterRef RefNode::getRegRef(const Dat
   if (NodeAttrs::flags(Attrs) & NodeAttrs::PhiRef)
     return G.unpack(Ref.PR);
   assert(Ref.Op != nullptr);
-  return G.makeRegRef(Ref.Op->getReg(), Ref.Op->getSubReg());
+  return G.makeRegRef(*Ref.Op);
 }
 
 // Set the register reference in the reference node directly (for references
@@ -755,17 +755,6 @@ unsigned DataFlowGraph::DefStack::nextDo
 
 // Register information.
 
-// Get the list of references aliased to RR. Lane masks are ignored.
-RegisterSet DataFlowGraph::getAliasSet(RegisterId Reg) const {
-  // Do not include RR in the alias set.
-  RegisterSet AS;
-  assert(TargetRegisterInfo::isPhysicalRegister(Reg));
-
-  for (MCRegAliasIterator AI(Reg, &TRI, false); AI.isValid(); ++AI)
-    AS.insert(RegisterRef(*AI));
-  return AS;
-}
-
 RegisterSet DataFlowGraph::getLandingPadLiveIns() const {
   RegisterSet LR;
   const Function &F = *MF.getFunction();
@@ -977,26 +966,34 @@ void DataFlowGraph::build(unsigned Optio
 }
 
 RegisterRef DataFlowGraph::makeRegRef(unsigned Reg, unsigned Sub) const {
-  assert(TargetRegisterInfo::isPhysicalRegister(Reg));
+  assert(PhysicalRegisterInfo::isRegMaskId(Reg) ||
+         TargetRegisterInfo::isPhysicalRegister(Reg));
+  assert(Reg != 0);
   if (Sub != 0)
     Reg = TRI.getSubReg(Reg, Sub);
   return RegisterRef(Reg);
 }
 
+RegisterRef DataFlowGraph::makeRegRef(const MachineOperand &Op) const {
+  assert(Op.isReg() || Op.isRegMask());
+  if (Op.isReg())
+    return makeRegRef(Op.getReg(), Op.getSubReg());
+  return RegisterRef(PRI.getRegMaskId(Op.getRegMask()), LaneBitmask::getAll());
+}
+
 RegisterRef DataFlowGraph::normalizeRef(RegisterRef RR) const {
   // FIXME copied from RegisterAggr
-  RegisterId SuperReg = RR.Reg;
-  while (true) {
-    MCSuperRegIterator SR(SuperReg, &TRI, false);
-    if (!SR.isValid())
-      break;
-    SuperReg = *SR;
-  }
-
-  uint32_t Sub = TRI.getSubRegIndex(SuperReg, RR.Reg);
-  const TargetRegisterClass &RC = *TRI.getMinimalPhysRegClass(RR.Reg);
-  LaneBitmask SuperMask = RR.Mask &
-                          TRI.composeSubRegIndexLaneMask(Sub, RC.LaneMask);
+  if (PhysicalRegisterInfo::isRegMaskId(RR.Reg))
+    return RR;
+  const TargetRegisterClass *RC = PRI.RegInfos[RR.Reg].RegClass;
+  LaneBitmask RCMask = RC != nullptr ? RC->LaneMask : LaneBitmask(0x00000001);
+  LaneBitmask Common = RR.Mask & RCMask;
+
+  RegisterId SuperReg = PRI.RegInfos[RR.Reg].MaxSuper;
+// Ex: IP/EIP/RIP
+//  assert(RC != nullptr || RR.Reg == SuperReg);
+  uint32_t Sub = PRI.getTRI().getSubRegIndex(SuperReg, RR.Reg);
+  LaneBitmask SuperMask = PRI.getTRI().composeSubRegIndexLaneMask(Sub, Common);
   return RegisterRef(SuperReg, SuperMask);
 }
 
@@ -1012,7 +1009,7 @@ RegisterRef DataFlowGraph::restrictRef(R
 #endif
   // This isn't strictly correct, because the overlap may happen in the
   // part masked out.
-  if (TRI.regsOverlap(AR.Reg, BR.Reg))
+  if (PRI.alias(AR, BR))
     return AR;
   return RegisterRef();
 }
@@ -1083,10 +1080,10 @@ void DataFlowGraph::pushDefs(NodeAddr<In
     // 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*/)) {
+    for (RegisterId A : PRI.getAliasSet(RR.Reg)) {
       // Check that we don't push the same def twice.
-      assert(A != RR);
-      DefM[A.Reg].push(DA);
+      assert(A != RR.Reg);
+      DefM[A].push(DA);
     }
     // Mark all the related defs as visited.
     for (NodeAddr<NodeBase*> T : Rel)
@@ -1223,20 +1220,26 @@ void DataFlowGraph::buildStmt(NodeAddr<B
     if (In.isCall())
       return true;
     // Is tail call?
-    if (In.isBranch())
+    if (In.isBranch()) {
       for (const MachineOperand &Op : In.operands())
         if (Op.isGlobal() || Op.isSymbol())
           return true;
+      // Assume indirect branches are calls. This is for the purpose of
+      // keeping implicit operands, and so it won't hurt on intra-function
+      // indirect branches.
+      if (In.isIndirectBranch())
+        return true;
+    }
     return false;
   };
 
   auto isDefUndef = [this] (const MachineInstr &In, RegisterRef DR) -> bool {
     // This instruction defines DR. Check if there is a use operand that
     // would make DR live on entry to the instruction.
-    for (const MachineOperand &UseOp : In.operands()) {
-      if (!UseOp.isReg() || !UseOp.isUse() || UseOp.isUndef())
+    for (const MachineOperand &Op : In.operands()) {
+      if (!Op.isReg() || Op.getReg() == 0 || !Op.isUse() || Op.isUndef())
         continue;
-      RegisterRef UR = makeRegRef(UseOp.getReg(), UseOp.getSubReg());
+      RegisterRef UR = makeRegRef(Op);
       if (PRI.alias(DR, UR))
         return false;
     }
@@ -1263,18 +1266,20 @@ void DataFlowGraph::buildStmt(NodeAddr<B
   // defs that define registers that overlap, but it is not clear how to
   // interpret that in the absence of explicit defs. Overlapping explicit
   // defs are likely illegal already.
-  RegisterSet DoneDefs;
+  BitVector DoneDefs(TRI.getNumRegs());
   // Process explicit defs first.
   for (unsigned OpN = 0; OpN < NumOps; ++OpN) {
     MachineOperand &Op = In.getOperand(OpN);
     if (!Op.isReg() || !Op.isDef() || Op.isImplicit())
       continue;
-    RegisterRef RR = makeRegRef(Op.getReg(), Op.getSubReg());
+    unsigned R = Op.getReg();
+    if (!R || !TargetRegisterInfo::isPhysicalRegister(R))
+      continue;
     uint16_t Flags = NodeAttrs::None;
     if (TOI.isPreserving(In, OpN)) {
       Flags |= NodeAttrs::Preserving;
       // If the def is preserving, check if it is also undefined.
-      if (isDefUndef(In, RR))
+      if (isDefUndef(In, makeRegRef(Op)))
         Flags |= NodeAttrs::Undef;
     }
     if (TOI.isClobbering(In, OpN))
@@ -1285,7 +1290,25 @@ void DataFlowGraph::buildStmt(NodeAddr<B
       Flags |= NodeAttrs::Dead;
     NodeAddr<DefNode*> DA = newDef(SA, Op, Flags);
     SA.Addr->addMember(DA, *this);
-    DoneDefs.insert(RR);
+    assert(!DoneDefs.test(R));
+    DoneDefs.set(R);
+  }
+
+  // Process reg-masks (as clobbers).
+  BitVector DoneClobbers(TRI.getNumRegs());
+  for (unsigned OpN = 0; OpN < NumOps; ++OpN) {
+    MachineOperand &Op = In.getOperand(OpN);
+    if (!Op.isRegMask())
+      continue;
+    uint16_t Flags = NodeAttrs::Clobbering | NodeAttrs::Fixed |
+                     NodeAttrs::Dead;
+    NodeAddr<DefNode*> DA = newDef(SA, Op, Flags);
+    SA.Addr->addMember(DA, *this);
+    // Record all clobbered registers in DoneDefs.
+    const uint32_t *RM = Op.getRegMask();
+    for (unsigned i = 1, e = TRI.getNumRegs(); i != e; ++i)
+      if (!(RM[i/32] & (1u << (i%32))))
+        DoneClobbers.set(i);
   }
 
   // Process implicit defs, skipping those that have already been added
@@ -1294,10 +1317,11 @@ void DataFlowGraph::buildStmt(NodeAddr<B
     MachineOperand &Op = In.getOperand(OpN);
     if (!Op.isReg() || !Op.isDef() || !Op.isImplicit())
       continue;
-    RegisterRef RR = makeRegRef(Op.getReg(), Op.getSubReg());
-    if (!NeedsImplicit && !ImpDefs.count(RR))
+    unsigned R = Op.getReg();
+    if (!R || !TargetRegisterInfo::isPhysicalRegister(R) || DoneDefs.test(R))
       continue;
-    if (DoneDefs.count(RR))
+    RegisterRef RR = makeRegRef(Op);
+    if (!NeedsImplicit && !ImpDefs.count(RR))
       continue;
     uint16_t Flags = NodeAttrs::None;
     if (TOI.isPreserving(In, OpN)) {
@@ -1310,18 +1334,24 @@ void DataFlowGraph::buildStmt(NodeAddr<B
       Flags |= NodeAttrs::Clobbering;
     if (TOI.isFixedReg(In, OpN))
       Flags |= NodeAttrs::Fixed;
-    if (IsCall && Op.isDead())
+    if (IsCall && Op.isDead()) {
+      if (DoneClobbers.test(R))
+        continue;
       Flags |= NodeAttrs::Dead;
+    }
     NodeAddr<DefNode*> DA = newDef(SA, Op, Flags);
     SA.Addr->addMember(DA, *this);
-    DoneDefs.insert(RR);
+    DoneDefs.set(R);
   }
 
   for (unsigned OpN = 0; OpN < NumOps; ++OpN) {
     MachineOperand &Op = In.getOperand(OpN);
     if (!Op.isReg() || !Op.isUse())
       continue;
-    RegisterRef RR = makeRegRef(Op.getReg(), Op.getSubReg());
+    unsigned R = Op.getReg();
+    if (!R || !TargetRegisterInfo::isPhysicalRegister(R))
+      continue;
+    RegisterRef RR = makeRegRef(Op);
     // Add implicit uses on return and call instructions, and on predicated
     // instructions regardless of whether or not they appear in the instruction
     // descriptor's list.

Modified: llvm/trunk/lib/Target/Hexagon/RDFGraph.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/RDFGraph.h?rev=293538&r1=293537&r2=293538&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/RDFGraph.h (original)
+++ llvm/trunk/lib/Target/Hexagon/RDFGraph.h Mon Jan 30 13:16:30 2017
@@ -431,39 +431,6 @@ namespace rdf {
     uint32_t MaskId;
   };
 
-  // Template class for a map translating uint32_t into arbitrary types.
-  // The map will act like an indexed set: upon insertion of a new object,
-  // it will automatically assign a new index to it. Index of 0 is treated
-  // as invalid and is never allocated.
-  template <typename T, unsigned N = 32>
-  struct IndexedSet {
-    IndexedSet() : Map() { Map.reserve(N); }
-
-    T get(uint32_t Idx) const {
-      // Index Idx corresponds to Map[Idx-1].
-      assert(Idx != 0 && !Map.empty() && Idx-1 < Map.size());
-      return Map[Idx-1];
-    }
-
-    uint32_t insert(T Val) {
-      // Linear search.
-      auto F = llvm::find(Map, Val);
-      if (F != Map.end())
-        return F - Map.begin() + 1;
-      Map.push_back(Val);
-      return Map.size();  // Return actual_index + 1.
-    }
-
-    uint32_t find(T Val) const {
-      auto F = llvm::find(Map, Val);
-      assert(F != Map.end());
-      return F - Map.begin();
-    }
-
-  private:
-    std::vector<T> Map;
-  };
-
   struct LaneMaskIndex : private IndexedSet<LaneBitmask> {
     LaneMaskIndex() = default;
 
@@ -777,6 +744,7 @@ namespace rdf {
     }
 
     RegisterRef makeRegRef(unsigned Reg, unsigned Sub) const;
+    RegisterRef makeRegRef(const MachineOperand &Op) const;
     RegisterRef normalizeRef(RegisterRef RR) const;
     RegisterRef restrictRef(RegisterRef AR, RegisterRef BR) const;
 
@@ -842,7 +810,6 @@ namespace rdf {
   private:
     void reset();
 
-    RegisterSet getAliasSet(RegisterId Reg) const;
     RegisterSet getLandingPadLiveIns() const;
 
     NodeAddr<NodeBase*> newNode(uint16_t Attrs);

Modified: llvm/trunk/lib/Target/Hexagon/RDFRegisters.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/RDFRegisters.cpp?rev=293538&r1=293537&r2=293538&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/RDFRegisters.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/RDFRegisters.cpp Mon Jan 30 13:16:30 2017
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "RDFRegisters.h"
+#include "llvm/ADT/BitVector.h"
 #include "llvm/CodeGen/MachineFunction.h"
 
 using namespace llvm;
@@ -38,9 +39,38 @@ PhysicalRegisterInfo::PhysicalRegisterIn
       SuperR = *S;
     RegInfos[R].MaxSuper = SuperR;
   }
+
+  for (const uint32_t *RM : TRI.getRegMasks())
+    RegMasks.insert(RM);
+  for (const MachineBasicBlock &B : mf)
+    for (const MachineInstr &In : B)
+      for (const MachineOperand &Op : In.operands())
+        if (Op.isRegMask())
+          RegMasks.insert(Op.getRegMask());
 }
 
-bool PhysicalRegisterInfo::alias(RegisterRef RA, RegisterRef RB) const {
+std::set<RegisterId> PhysicalRegisterInfo::getAliasSet(RegisterId Reg) const {
+  // Do not include RR in the alias set.
+  std::set<RegisterId> AS;
+  assert(isRegMaskId(Reg) || TargetRegisterInfo::isPhysicalRegister(Reg));
+  if (isRegMaskId(Reg)) {
+    // XXX SLOW
+    // XXX Add other regmasks to the set.
+    const uint32_t *MB = getRegMaskBits(Reg);
+    for (unsigned i = 1, e = TRI.getNumRegs(); i != e; ++i) {
+      if (MB[i/32] & (1u << (i%32)))
+        continue;
+      AS.insert(i);
+    }
+    return AS;
+  }
+
+  for (MCRegAliasIterator AI(Reg, &TRI, false); AI.isValid(); ++AI)
+    AS.insert(*AI);
+  return AS;
+}
+
+bool PhysicalRegisterInfo::aliasRR(RegisterRef RA, RegisterRef RB) const {
   assert(TargetRegisterInfo::isPhysicalRegister(RA.Reg));
   assert(TargetRegisterInfo::isPhysicalRegister(RB.Reg));
   MCRegUnitMaskIterator UMA(RA.Reg, &TRI);
@@ -92,7 +122,73 @@ bool PhysicalRegisterInfo::alias(Registe
   return false;
 }
 
+bool PhysicalRegisterInfo::aliasRM(RegisterRef RR, RegisterRef RM) const {
+  assert(TargetRegisterInfo::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;
+
+  // 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;
+  }
+
+  return true;
+}
+
+bool PhysicalRegisterInfo::aliasMM(RegisterRef RM, RegisterRef RN) const {
+  assert(isRegMaskId(RM.Reg) && isRegMaskId(RN.Reg));
+  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;
+  }
+
+  // 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;
+}
+
+
 RegisterRef RegisterAggr::normalize(RegisterRef RR) const {
+  if (PhysicalRegisterInfo::isRegMaskId(RR.Reg))
+    return RR;
   const TargetRegisterClass *RC = PRI.RegInfos[RR.Reg].RegClass;
   LaneBitmask RCMask = RC != nullptr ? RC->LaneMask : LaneBitmask(0x00000001);
   LaneBitmask Common = RR.Mask & RCMask;
@@ -106,6 +202,17 @@ RegisterRef RegisterAggr::normalize(Regi
 }
 
 bool RegisterAggr::hasAliasOf(RegisterRef RR) const {
+  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;
+      if (hasAliasOf(RegisterRef(i, LaneBitmask::getAll())))
+        return true;
+    }
+  }
+
   RegisterRef NR = normalize(RR);
   auto F = Masks.find(NR.Reg);
   if (F != Masks.end()) {
@@ -121,6 +228,18 @@ bool RegisterAggr::hasAliasOf(RegisterRe
 }
 
 bool RegisterAggr::hasCoverOf(RegisterRef RR) const {
+  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;
+      if (!hasCoverOf(RegisterRef(i, LaneBitmask::getAll())))
+        return false;
+    }
+    return true;
+  }
+
   // Always have a cover for empty lane mask.
   RegisterRef NR = normalize(RR);
   if (NR.Mask.none())
@@ -132,6 +251,17 @@ bool RegisterAggr::hasCoverOf(RegisterRe
 }
 
 RegisterAggr &RegisterAggr::insert(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;
+      insert(RegisterRef(i, LaneBitmask::getAll()));
+    }
+    return *this;
+  }
+
   RegisterRef NR = normalize(RR);
   auto F = Masks.find(NR.Reg);
   if (F == Masks.end())
@@ -160,6 +290,17 @@ RegisterAggr &RegisterAggr::insert(const
 }
 
 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 = normalize(RR);
   auto F = Masks.find(NR.Reg);
   if (F == Masks.end())

Modified: llvm/trunk/lib/Target/Hexagon/RDFRegisters.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/RDFRegisters.h?rev=293538&r1=293537&r2=293538&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/RDFRegisters.h (original)
+++ llvm/trunk/lib/Target/Hexagon/RDFRegisters.h Mon Jan 30 13:16:30 2017
@@ -13,6 +13,7 @@
 #include "llvm/ADT/BitVector.h"
 #include "llvm/Target/TargetRegisterInfo.h"
 
+#include <set>
 #include <unordered_map>
 #include <vector>
 
@@ -21,6 +22,39 @@ namespace rdf {
 
   typedef uint32_t RegisterId;
 
+  // Template class for a map translating uint32_t into arbitrary types.
+  // The map will act like an indexed set: upon insertion of a new object,
+  // it will automatically assign a new index to it. Index of 0 is treated
+  // as invalid and is never allocated.
+  template <typename T, unsigned N = 32>
+  struct IndexedSet {
+    IndexedSet() : Map() { Map.reserve(N); }
+
+    T get(uint32_t Idx) const {
+      // Index Idx corresponds to Map[Idx-1].
+      assert(Idx != 0 && !Map.empty() && Idx-1 < Map.size());
+      return Map[Idx-1];
+    }
+
+    uint32_t insert(T Val) {
+      // Linear search.
+      auto F = llvm::find(Map, Val);
+      if (F != Map.end())
+        return F - Map.begin() + 1;
+      Map.push_back(Val);
+      return Map.size();  // Return actual_index + 1.
+    }
+
+    uint32_t find(T Val) const {
+      auto F = llvm::find(Map, Val);
+      assert(F != Map.end());
+      return F - Map.begin() + 1;
+    }
+
+  private:
+    std::vector<T> Map;
+  };
+
   struct RegisterRef {
     RegisterId Reg = 0;
     LaneBitmask Mask = LaneBitmask::getNone();
@@ -48,7 +82,22 @@ namespace rdf {
     PhysicalRegisterInfo(const TargetRegisterInfo &tri,
                          const MachineFunction &mf);
 
-    bool alias(RegisterRef RA, RegisterRef RB) const;
+    static bool isRegMaskId(RegisterId R) {
+      return TargetRegisterInfo::isStackSlot(R);
+    }
+    RegisterId getRegMaskId(const uint32_t *RM) const {
+      return TargetRegisterInfo::index2StackSlot(RegMasks.find(RM));
+    }
+    const uint32_t *getRegMaskBits(RegisterId R) const {
+      return RegMasks.get(TargetRegisterInfo::stackSlot2Index(R));
+    }
+
+    bool alias(RegisterRef RA, RegisterRef RB) const {
+      if (!isRegMaskId(RA.Reg))
+        return !isRegMaskId(RB.Reg) ? aliasRR(RA, RB) : aliasRM(RA, RB);
+      return !isRegMaskId(RB.Reg) ? aliasRM(RB, RA) : aliasMM(RA, RB);
+    }
+    std::set<RegisterId> getAliasSet(RegisterId Reg) const;
 
     const TargetRegisterInfo &getTRI() const { return TRI; }
 
@@ -60,6 +109,11 @@ namespace rdf {
 
     const TargetRegisterInfo &TRI;
     std::vector<RegInfo> RegInfos;
+    IndexedSet<const uint32_t*> RegMasks;
+
+    bool aliasRR(RegisterRef RA, RegisterRef RB) const;
+    bool aliasRM(RegisterRef RR, RegisterRef RM) const;
+    bool aliasMM(RegisterRef RM, RegisterRef RN) const;
   };
 
 
@@ -101,6 +155,7 @@ namespace rdf {
     const PhysicalRegisterInfo &PRI;
   };
 
+
   // Optionally print the lane mask, if it is not ~0.
   struct PrintLaneMaskOpt {
     PrintLaneMaskOpt(LaneBitmask M) : Mask(M) {}




More information about the llvm-commits mailing list