[Hexagon] Add new packet iterator which will iterate through duplexes

Patch by Colin LeMahieu.

llvm-svn: 301945
This commit is contained in:
Krzysztof Parzyszek 2017-05-02 17:53:51 +00:00
parent a0aae2757d
commit 1cc6bfbc83
3 changed files with 82 additions and 24 deletions

View 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() {

View File

@ -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<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

View 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