[Hexagon] Better determination of register classes in bit tracker
authorKrzysztof Parzyszek <kparzysz@codeaurora.org>
Mon, 25 Sep 2017 19:12:55 +0000 (19:12 +0000)
committerKrzysztof Parzyszek <kparzysz@codeaurora.org>
Mon, 25 Sep 2017 19:12:55 +0000 (19:12 +0000)
Add two callbacks to MachineEvaluator, so that specific implementations
can specify more details about register classes:
- composeWithSubRegIndex(RC,Idx), to provide the register class for a
  register from RC used in conjunction with a subregister index Idx.
- getPhysRegBitWidth(Reg), to provide the size in bits of the given
  physical register.

llvm-svn: 314136

llvm/lib/Target/Hexagon/BitTracker.cpp
llvm/lib/Target/Hexagon/BitTracker.h
llvm/lib/Target/Hexagon/HexagonBitTracker.cpp
llvm/lib/Target/Hexagon/HexagonBitTracker.h

index 0c6ee1a..0b0d48a 100644 (file)
@@ -335,20 +335,13 @@ uint16_t BT::MachineEvaluator::getRegBitWidth(const RegisterRef &RR) const {
   // 1. find a physical register PhysR from the same class as RR.Reg,
   // 2. find a physical register PhysS that corresponds to PhysR:RR.Sub,
   // 3. find a register class that contains PhysS.
-  unsigned PhysR;
   if (TargetRegisterInfo::isVirtualRegister(RR.Reg)) {
-    const TargetRegisterClass *VC = MRI.getRegClass(RR.Reg);
-    assert(VC->begin() != VC->end() && "Empty register class");
-    PhysR = *VC->begin();
-  } else {
-    assert(TargetRegisterInfo::isPhysicalRegister(RR.Reg));
-    PhysR = RR.Reg;
+    const auto &VC = composeWithSubRegIndex(*MRI.getRegClass(RR.Reg), RR.Sub);
+    return TRI.getRegSizeInBits(VC);
   }
-
-  unsigned PhysS = (RR.Sub == 0) ? PhysR : TRI.getSubReg(PhysR, RR.Sub);
-  const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(PhysS);
-  uint16_t BW = TRI.getRegSizeInBits(*RC);
-  return BW;
+  assert(TargetRegisterInfo::isPhysicalRegister(RR.Reg));
+  unsigned PhysR = (RR.Sub == 0) ? RR.Reg : TRI.getSubReg(RR.Reg, RR.Sub);
+  return getPhysRegBitWidth(PhysR);
 }
 
 BT::RegisterCell BT::MachineEvaluator::getCell(const RegisterRef &RR,
@@ -717,6 +710,12 @@ BT::BitMask BT::MachineEvaluator::mask(unsigned Reg, unsigned Sub) const {
   return BitMask(0, W-1);
 }
 
+uint16_t BT::MachineEvaluator::getPhysRegBitWidth(unsigned Reg) const {
+  assert(TargetRegisterInfo::isPhysicalRegister(Reg));
+  const TargetRegisterClass &PC = *TRI.getMinimalPhysRegClass(Reg);
+  return TRI.getRegSizeInBits(PC);
+}
+
 bool BT::MachineEvaluator::evaluate(const MachineInstr &MI,
                                     const CellMapType &Inputs,
                                     CellMapType &Outputs) const {
index 4933ed5..8a0f657 100644 (file)
@@ -435,6 +435,16 @@ struct BitTracker::MachineEvaluator {
   // has been successfully computed, "false" otherwise.
   virtual bool evaluate(const MachineInstr &BI, const CellMapType &Inputs,
                         BranchTargetList &Targets, bool &FallsThru) const = 0;
+  // Given a register class RC, return a register class that should be assumed
+  // when a register from class RC is used with a subregister of index Idx.
+  virtual const TargetRegisterClass&
+  composeWithSubRegIndex(const TargetRegisterClass &RC, unsigned Idx) const {
+    if (Idx == 0)
+      return RC;
+    llvm_unreachable("Unimplemented composeWithSubRegIndex");
+  }
+  // Return the size in bits of the physical register Reg.
+  virtual uint16_t getPhysRegBitWidth(unsigned Reg) const;
 
   const TargetRegisterInfo &TRI;
   MachineRegisterInfo &MRI;
index ea438c6..7e8fc83 100644 (file)
@@ -11,6 +11,7 @@
 #include "Hexagon.h"
 #include "HexagonInstrInfo.h"
 #include "HexagonRegisterInfo.h"
+#include "HexagonSubtarget.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineInstr.h"
@@ -91,8 +92,6 @@ HexagonEvaluator::HexagonEvaluator(const HexagonRegisterInfo &tri,
 }
 
 BT::BitMask HexagonEvaluator::mask(unsigned Reg, unsigned Sub) const {
-  using namespace Hexagon;
-
   if (Sub == 0)
     return MachineEvaluator::mask(Reg, 0);
   const TargetRegisterClass &RC = *MRI.getRegClass(Reg);
@@ -101,8 +100,8 @@ BT::BitMask HexagonEvaluator::mask(unsigned Reg, unsigned Sub) const {
   auto &HRI = static_cast<const HexagonRegisterInfo&>(TRI);
   bool IsSubLo = (Sub == HRI.getHexagonSubRegIndex(RC, Hexagon::ps_sub_lo));
   switch (ID) {
-    case DoubleRegsRegClassID:
-    case HvxWRRegClassID:
+    case Hexagon::DoubleRegsRegClassID:
+    case Hexagon::HvxWRRegClassID:
       return IsSubLo ? BT::BitMask(0, RW-1)
                      : BT::BitMask(RW, 2*RW-1);
     default:
@@ -115,6 +114,45 @@ BT::BitMask HexagonEvaluator::mask(unsigned Reg, unsigned Sub) const {
   llvm_unreachable("Unexpected register/subregister");
 }
 
+uint16_t HexagonEvaluator::getPhysRegBitWidth(unsigned Reg) const {
+  assert(TargetRegisterInfo::isPhysicalRegister(Reg));
+
+  using namespace Hexagon;
+  for (auto &RC : {HvxVRRegClass, HvxWRRegClass, HvxQRRegClass})
+    if (RC.contains(Reg))
+      return TRI.getRegSizeInBits(RC);
+  // Default treatment for other physical registers.
+  if (const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(Reg))
+    return TRI.getRegSizeInBits(*RC);
+
+  StringRef E = "Unhandled physical register";
+  llvm_unreachable((Twine(E) + TRI.getName(Reg)).str().c_str());
+}
+
+const TargetRegisterClass &HexagonEvaluator::composeWithSubRegIndex(
+      const TargetRegisterClass &RC, unsigned Idx) const {
+  if (Idx == 0)
+    return RC;
+
+  const auto &HRI = static_cast<const HexagonRegisterInfo&>(TRI);
+  bool IsSubLo = (Idx == HRI.getHexagonSubRegIndex(RC, Hexagon::ps_sub_lo));
+  bool IsSubHi = (Idx == HRI.getHexagonSubRegIndex(RC, Hexagon::ps_sub_hi));
+  assert(IsSubLo != IsSubHi && "Must refer to either low or high subreg");
+
+  switch (RC.getID()) {
+    case Hexagon::DoubleRegsRegClassID:
+      return Hexagon::IntRegsRegClass;
+    case Hexagon::HvxWRRegClassID:
+      return Hexagon::HvxVRRegClass;
+    default:
+      break;
+  }
+#ifndef DEBUG
+  dbgs() << "Reg class id: " << RC.getID() << " idx: " << Idx << '\n';
+#endif
+  llvm_unreachable("Unimplemented combination of reg class/subreg idx");
+}
+
 namespace {
 
 class RegisterRefs {
index 94accb1..d9dd04e 100644 (file)
@@ -39,6 +39,11 @@ struct HexagonEvaluator : public BitTracker::MachineEvaluator {
 
   BitTracker::BitMask mask(unsigned Reg, unsigned Sub) const override;
 
+  uint16_t getPhysRegBitWidth(unsigned Reg) const override;
+
+  const TargetRegisterClass &composeWithSubRegIndex(
+        const TargetRegisterClass &RC, unsigned Idx) const override;
+
   MachineFunction &MF;
   MachineFrameInfo &MFI;
   const HexagonInstrInfo &TII;