[Hexagon] Add new packet iterator which will iterate through duplexes
authorKrzysztof Parzyszek <kparzysz@codeaurora.org>
Tue, 2 May 2017 17:53:51 +0000 (17:53 +0000)
committerKrzysztof Parzyszek <kparzysz@codeaurora.org>
Tue, 2 May 2017 17:53:51 +0000 (17:53 +0000)
Patch by Colin LeMahieu.

llvm-svn: 301945

llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.cpp
llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp
llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.h

index f138a7c..f8b2a52 100644 (file)
@@ -392,26 +392,20 @@ bool HexagonMCChecker::checkRegistersReadOnly() {
 }
 
 bool HexagonMCChecker::registerUsed(MCInst const &Inst, unsigned Register) {
-  if (HexagonMCInstrInfo::isDuplex(MCII, Inst)) {
-    if (registerUsed(*Inst.getOperand(0).getInst(), Register) ||
-        registerUsed(*Inst.getOperand(1).getInst(), Register))
+  unsigned Defs = HexagonMCInstrInfo::getDesc(MCII, Inst).getNumDefs();
+  for (unsigned j = Defs, n = Inst.getNumOperands(); j < n; ++j) {
+    MCOperand const &Operand = Inst.getOperand(j);
+    if (Operand.isReg() && Operand.getReg() == Register)
       return true;
-  } else {
-    unsigned Defs = HexagonMCInstrInfo::getDesc(MCII, Inst).getNumDefs();
-    for (unsigned j = Defs, n = Inst.getNumOperands(); j < n; ++j) {
-      MCOperand const &Operand = Inst.getOperand(j);
-      if (Operand.isReg() && Operand.getReg() == Register)
-        return true;
-    }
   }
   return false;
 }
 
 bool HexagonMCChecker::registerUsed(unsigned Register) {
-  auto Range = HexagonMCInstrInfo::bundleInstructions(MCB);
-  return std::any_of(Range.begin(), Range.end(), [&](MCOperand const &Operand) {
-    return registerUsed(*Operand.getInst(), Register);
-  });
+  for (auto const &I: HexagonMCInstrInfo::bundleInstructions(MCII, MCB))
+    if (registerUsed(I, Register))
+      return true;
+  return false;
 }
 
 void HexagonMCChecker::checkRegisterCurDefs() {
index 30a811a..1c66bd9 100644 (file)
 #include "llvm/MC/MCSubtargetInfo.h"
 
 namespace llvm {
+Hexagon::PacketIterator::PacketIterator(MCInstrInfo const &MCII,
+                                        MCInst const &Inst)
+    : MCII(MCII), BundleCurrent(Inst.begin() +
+                                HexagonMCInstrInfo::bundleInstructionsOffset),
+      BundleEnd(Inst.end()), DuplexCurrent(Inst.end()), DuplexEnd(Inst.end()) {}
+Hexagon::PacketIterator::PacketIterator(MCInstrInfo const &MCII,
+                                        MCInst const &Inst, std::nullptr_t)
+    : MCII(MCII), BundleCurrent(Inst.end()), BundleEnd(Inst.end()),
+      DuplexCurrent(Inst.end()), DuplexEnd(Inst.end()) {}
+Hexagon::PacketIterator &Hexagon::PacketIterator::operator++() {
+  if (DuplexCurrent != DuplexEnd) {
+    ++DuplexCurrent;
+    if (DuplexCurrent == DuplexEnd) {
+      DuplexCurrent = BundleEnd;
+      DuplexEnd = BundleEnd;
+    }
+    return *this;
+  }
+  ++BundleCurrent;
+  if (BundleCurrent != BundleEnd) {
+    MCInst const &Inst = *BundleCurrent->getInst();
+    if (HexagonMCInstrInfo::isDuplex(MCII, Inst)) {
+      DuplexCurrent = Inst.begin();
+      DuplexEnd = Inst.end();
+    }
+  }
+  return *this;
+}
+MCInst const &Hexagon::PacketIterator::operator*() const {
+  if (DuplexCurrent != DuplexEnd)
+    return *DuplexCurrent->getInst();
+  return *BundleCurrent->getInst();
+}
+bool Hexagon::PacketIterator::operator==(PacketIterator const &Other) const {
+  return BundleCurrent == Other.BundleCurrent && BundleEnd == Other.BundleEnd &&
+         DuplexCurrent == Other.DuplexCurrent && DuplexEnd == Other.DuplexEnd;
+}
 void HexagonMCInstrInfo::addConstant(MCInst &MI, uint64_t Value,
                                      MCContext &Context) {
   MI.addOperand(MCOperand::createExpr(MCConstantExpr::create(Value, Context)));
@@ -41,6 +78,14 @@ void HexagonMCInstrInfo::addConstExtender(MCContext &Context,
   MCB.addOperand(MCOperand::createInst(XMCI));
 }
 
+iterator_range<Hexagon::PacketIterator>
+HexagonMCInstrInfo::bundleInstructions(MCInstrInfo const &MCII,
+                                       MCInst const &MCI) {
+  assert(isBundle(MCI));
+  return make_range(Hexagon::PacketIterator(MCII, MCI),
+                    Hexagon::PacketIterator(MCII, MCI, nullptr));
+}
+
 iterator_range<MCInst::const_iterator>
 HexagonMCInstrInfo::bundleInstructions(MCInst const &MCI) {
   assert(isBundle(MCI));
@@ -292,7 +337,7 @@ int HexagonMCInstrInfo::getMinValue(MCInstrInfo const &MCII,
 }
 
 StringRef HexagonMCInstrInfo::getName(MCInstrInfo const &MCII,
-                                        MCInst const &MCI) {
+                                      MCInst const &MCI) {
   return MCII.getName(MCI.getOpcode());
 }
 
@@ -397,9 +442,8 @@ bool HexagonMCInstrInfo::hasDuplex(MCInstrInfo const &MCII, MCInst const &MCI) {
   if (!HexagonMCInstrInfo::isBundle(MCI))
     return false;
 
-  for (const auto &I : HexagonMCInstrInfo::bundleInstructions(MCI)) {
-    auto MI = I.getInst();
-    if (HexagonMCInstrInfo::isDuplex(MCII, *MI))
+  for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCII, MCI)) {
+    if (HexagonMCInstrInfo::isDuplex(MCII, I))
       return true;
   }
 
@@ -410,13 +454,12 @@ bool HexagonMCInstrInfo::hasExtenderForIndex(MCInst const &MCB, size_t Index) {
   return extenderForIndex(MCB, Index) != nullptr;
 }
 
-bool HexagonMCInstrInfo::hasImmExt(MCInst const &MCI) {
+bool HexagonMCInstrInfo::hasImmExt( MCInst const &MCI) {
   if (!HexagonMCInstrInfo::isBundle(MCI))
     return false;
 
   for (const auto &I : HexagonMCInstrInfo::bundleInstructions(MCI)) {
-    auto MI = I.getInst();
-    if (isImmext(*MI))
+    if (isImmext(*I.getInst()))
       return true;
   }
 
@@ -818,4 +861,4 @@ unsigned HexagonMCInstrInfo::SubregisterBit(unsigned Consumer,
     return 0x1;
   return 0;
 }
-}
+} // namespace llvm
index 4d2df4d..710ece7 100644 (file)
@@ -31,6 +31,25 @@ public:
   DuplexCandidate(unsigned i, unsigned j, unsigned iClass)
       : packetIndexI(i), packetIndexJ(j), iClass(iClass) {}
 };
+namespace Hexagon {
+class PacketIterator {
+  MCInstrInfo const &MCII;
+  MCInst::const_iterator BundleCurrent;
+  MCInst::const_iterator BundleEnd;
+  MCInst::const_iterator DuplexCurrent;
+  MCInst::const_iterator DuplexEnd;
+
+public:
+  PacketIterator(MCInstrInfo const &MCII, MCInst const &Inst);
+  PacketIterator(MCInstrInfo const &MCII, MCInst const &Inst, std::nullptr_t);
+  PacketIterator &operator++();
+  MCInst const &operator*() const;
+  bool operator==(PacketIterator const &Other) const;
+  bool operator!=(PacketIterator const &Other) const {
+    return !(*this == Other);
+  }
+};
+} // namespace Hexagon
 namespace HexagonMCInstrInfo {
 size_t const innerLoopOffset = 0;
 int64_t const innerLoopMask = 1 << innerLoopOffset;
@@ -54,6 +73,8 @@ void addConstExtender(MCContext &Context, MCInstrInfo const &MCII, MCInst &MCB,
                       MCInst const &MCI);
 
 // Returns a iterator range of instructions in this bundle
+iterator_range<Hexagon::PacketIterator>
+bundleInstructions(MCInstrInfo const &MCII, MCInst const &MCI);
 iterator_range<MCInst::const_iterator> bundleInstructions(MCInst const &MCI);
 
 // Returns the number of instructions in the bundle
@@ -283,7 +304,7 @@ unsigned SubregisterBit(unsigned Consumer, unsigned Producer,
 // Attempt to find and replace compound pairs
 void tryCompound(MCInstrInfo const &MCII, MCSubtargetInfo const &STI,
                  MCContext &Context, MCInst &MCI);
-}
-}
+} // namespace HexagonMCInstrInfo
+} // namespace llvm
 
 #endif // LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCINSTRINFO_H