From 1cc6bfbc83652c217371e38cbbd9235fa74f1cd3 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Tue, 2 May 2017 17:53:51 +0000 Subject: [PATCH] [Hexagon] Add new packet iterator which will iterate through duplexes Patch by Colin LeMahieu. llvm-svn: 301945 --- .../Hexagon/MCTargetDesc/HexagonMCChecker.cpp | 22 +++---- .../MCTargetDesc/HexagonMCInstrInfo.cpp | 59 ++++++++++++++++--- .../Hexagon/MCTargetDesc/HexagonMCInstrInfo.h | 25 +++++++- 3 files changed, 82 insertions(+), 24 deletions(-) diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.cpp b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.cpp index f138a7c3e2f2..f8b2a52cd500 100644 --- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.cpp +++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.cpp @@ -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() { diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp index 30a811a36406..1c66bd96526c 100644 --- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp +++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp @@ -22,6 +22,43 @@ #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 +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 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 diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.h b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.h index 4d2df4d0eb69..710ece71c536 100644 --- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.h +++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.h @@ -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 +bundleInstructions(MCInstrInfo const &MCII, MCInst const &MCI); iterator_range 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