[Hexagon] Misc shuffling fixes

Co-authored-by: Brian Cain <bcain@quicinc.com>
This commit is contained in:
Krzysztof Parzyszek 2020-01-10 11:30:48 -06:00
parent a3573f203e
commit 88397739a3
6 changed files with 68 additions and 49 deletions

View File

@ -128,23 +128,28 @@ bool canonicalizePacketImpl(MCInstrInfo const &MCII, MCSubtargetInfo const &STI,
bool CheckOk = Check ? Check->check(false) : true;
if (!CheckOk)
return false;
MCInst OrigMCB = MCB;
// Examine the packet and convert pairs of instructions to compound
// instructions when possible.
if (!HexagonDisableCompound)
HexagonMCInstrInfo::tryCompound(MCII, STI, Context, MCB);
HexagonMCShuffle(Context, false, MCII, STI, MCB);
const SmallVector<DuplexCandidate, 8> possibleDuplexes =
(STI.getFeatureBits()[Hexagon::FeatureDuplex])
? HexagonMCInstrInfo::getDuplexPossibilties(MCII, STI, MCB)
: SmallVector<DuplexCandidate, 8>();
// Examine the packet and convert pairs of instructions to duplex
// instructions when possible.
if (STI.getFeatureBits() [Hexagon::FeatureDuplex]) {
SmallVector<DuplexCandidate, 8> possibleDuplexes;
possibleDuplexes =
HexagonMCInstrInfo::getDuplexPossibilties(MCII, STI, MCB);
HexagonMCShuffle(Context, MCII, STI, MCB, possibleDuplexes);
}
HexagonMCShuffle(Context, MCII, STI, MCB, possibleDuplexes);
// Examines packet and pad the packet, if needed, when an
// end-loop is in the bundle.
HexagonMCInstrInfo::padEndloop(MCB, Context);
// If compounding and duplexing didn't reduce the size below
// 4 or less we have a packet that is too big.
if (HexagonMCInstrInfo::bundleSize(MCB) > HEXAGON_PACKET_SIZE) {
@ -156,7 +161,9 @@ bool canonicalizePacketImpl(MCInstrInfo const &MCII, MCSubtargetInfo const &STI,
CheckOk = Check ? Check->check(true) : true;
if (!CheckOk)
return false;
HexagonMCShuffle(Context, true, MCII, STI, MCB);
return true;
}
} // namespace

View File

@ -65,18 +65,24 @@ public:
namespace HexagonMCInstrInfo {
size_t const innerLoopOffset = 0;
int64_t const innerLoopMask = 1 << innerLoopOffset;
constexpr size_t innerLoopOffset = 0;
constexpr int64_t innerLoopMask = 1 << innerLoopOffset;
size_t const outerLoopOffset = 1;
int64_t const outerLoopMask = 1 << outerLoopOffset;
constexpr size_t outerLoopOffset = 1;
constexpr int64_t outerLoopMask = 1 << outerLoopOffset;
// do not reorder memory load/stores by default load/stores are re-ordered
// and by default loads can be re-ordered
size_t const memReorderDisabledOffset = 2;
int64_t const memReorderDisabledMask = 1 << memReorderDisabledOffset;
constexpr size_t memReorderDisabledOffset = 2;
constexpr int64_t memReorderDisabledMask = 1 << memReorderDisabledOffset;
size_t const bundleInstructionsOffset = 1;
constexpr size_t splitNoMemOrderOffset = 3;
constexpr int64_t splitNoMemorderMask = 1 << splitNoMemOrderOffset;
constexpr size_t noShuffleOffset = 4;
constexpr int64_t noShuffleMask = 1 << noShuffleOffset;
constexpr size_t bundleInstructionsOffset = 1;
void addConstant(MCInst &MI, uint64_t Value, MCContext &Context);
void addConstExtender(MCContext &Context, MCInstrInfo const &MCII, MCInst &MCB,

View File

@ -127,11 +127,11 @@ bool llvm::HexagonMCShuffle(MCContext &Context, bool Fatal,
return MCS.reshuffleTo(MCB);
}
bool
llvm::HexagonMCShuffle(MCContext &Context, MCInstrInfo const &MCII,
MCSubtargetInfo const &STI, MCInst &MCB,
SmallVector<DuplexCandidate, 8> possibleDuplexes) {
if (DisableShuffle)
bool llvm::HexagonMCShuffle(MCContext &Context, MCInstrInfo const &MCII,
MCSubtargetInfo const &STI, MCInst &MCB,
SmallVector<DuplexCandidate, 8> possibleDuplexes) {
if (DisableShuffle || possibleDuplexes.size() == 0)
return false;
if (!HexagonMCInstrInfo::bundleSize(MCB)) {
@ -172,10 +172,8 @@ llvm::HexagonMCShuffle(MCContext &Context, MCInstrInfo const &MCII,
HexagonMCShuffler MCS(Context, false, MCII, STI, MCB);
doneShuffling = MCS.reshuffleTo(MCB); // shuffle
}
if (!doneShuffling)
return true;
return false;
return doneShuffling;
}
bool llvm::HexagonMCShuffle(MCContext &Context, MCInstrInfo const &MCII,

View File

@ -52,9 +52,11 @@ private:
void init(MCInst &MCB, MCInst const &AddMI, bool InsertAtFront);
};
// Invocation of the shuffler.
bool HexagonMCShuffle(MCContext &Context, bool Fatal, MCInstrInfo const &MCII,
MCSubtargetInfo const &STI, MCInst &MCB);
// Invocation of the shuffler. Returns true if the shuffle succeeded. If
// true, MCB will contain the newly-shuffled packet.
bool HexagonMCShuffle(MCContext &Context, bool ReportErrors,
MCInstrInfo const &MCII, MCSubtargetInfo const &STI,
MCInst &MCB);
bool HexagonMCShuffle(MCContext &Context, MCInstrInfo const &MCII,
MCSubtargetInfo const &STI, MCInst &MCB,
MCInst const &AddMI, int fixupCount);

View File

@ -167,7 +167,8 @@ static bool checkHVXPipes(const HVXInstsT &hvxInsts, unsigned startIdx,
HexagonShuffler::HexagonShuffler(MCContext &Context, bool ReportErrors,
MCInstrInfo const &MCII,
MCSubtargetInfo const &STI)
: Context(Context), MCII(MCII), STI(STI), ReportErrors(ReportErrors) {
: Context(Context), BundleFlags(), MCII(MCII), STI(STI), Loc(),
ReportErrors(ReportErrors), CheckFailure(), AppliedRestrictions() {
reset();
}
@ -244,8 +245,8 @@ void HexagonShuffler::restrictNoSlot1Store(
"Instruction does not allow a store in slot 1"));
}
bool HexagonShuffler::applySlotRestrictions(
HexagonPacketSummary const &Summary) {
bool HexagonShuffler::applySlotRestrictions(HexagonPacketSummary const &Summary,
const bool DoShuffle) {
// These restrictions can modify the slot masks in the instructions
// in the Packet member. They should run unconditionally and their
// order does not matter.
@ -262,7 +263,7 @@ bool HexagonShuffler::applySlotRestrictions(
if (!CheckFailure)
restrictBranchOrder(Summary);
if (!CheckFailure)
restrictPreferSlot3(Summary);
restrictPreferSlot3(Summary, DoShuffle);
return !CheckFailure;
}
@ -306,7 +307,6 @@ void HexagonShuffler::restrictBranchOrder(HexagonPacketSummary const &Summary) {
reportError("invalid instruction packet: out of slots");
}
void HexagonShuffler::permitNonSlot() {
for (HexagonInstr &ISJ : insts()) {
const bool RequiresSlot = HexagonMCInstrInfo::requiresSlot(STI, *ISJ.ID);
@ -321,16 +321,14 @@ bool HexagonShuffler::ValidResourceUsage(HexagonPacketSummary const &Summary) {
if (!ShuffledPacket) {
reportError("invalid instruction packet: slot error");
return false;
} else {
Packet = *ShuffledPacket;
}
// Verify the CVI slot subscriptions.
llvm::stable_sort(*this, HexagonInstr::lessCVI);
llvm::stable_sort(*ShuffledPacket, HexagonInstr::lessCVI);
// create vector of hvx instructions to check
HVXInstsT hvxInsts;
hvxInsts.clear();
for (const auto &I : *this) {
for (const auto &I : *ShuffledPacket) {
struct CVIUnits inst;
inst.Units = I.CVI.getUnits();
inst.Lanes = I.CVI.getLanes();
@ -349,6 +347,9 @@ bool HexagonShuffler::ValidResourceUsage(HexagonPacketSummary const &Summary) {
return false;
}
}
Packet = *ShuffledPacket;
return true;
}
@ -463,7 +464,8 @@ HexagonShuffler::HexagonPacketSummary HexagonShuffler::GetPacketSummary() {
case HexagonII::TypeALU64:
break;
case HexagonII::TypeJ:
Summary.branchInsts.push_back(ISJ);
if (HexagonMCInstrInfo::IsABranchingInst(MCII, STI, *ISJ->ID))
Summary.branchInsts.push_back(ISJ);
break;
case HexagonII::TypeCVI_VM_VP_LDU:
case HexagonII::TypeCVI_VM_LD:
@ -565,14 +567,15 @@ bool HexagonShuffler::ValidPacketMemoryOps(
return !InvalidPacket;
}
void HexagonShuffler::restrictPreferSlot3(HexagonPacketSummary const &Summary) {
void HexagonShuffler::restrictPreferSlot3(HexagonPacketSummary const &Summary,
const bool DoShuffle) {
// flag if an instruction requires to be in slot 3
const bool HasOnlySlot3 = llvm::any_of(insts(), [&](HexagonInstr const &I) {
return (I.Core.getUnits() == Slot3Mask);
});
const bool NeedsPrefSlot3Shuffle =
(Summary.branchInsts.size() <= 1 && !HasOnlySlot3 &&
Summary.pSlot3Cnt == 1 && Summary.PrefSlot3Inst);
const bool NeedsPrefSlot3Shuffle = Summary.branchInsts.size() <= 1 &&
!HasOnlySlot3 && Summary.pSlot3Cnt == 1 &&
Summary.PrefSlot3Inst && DoShuffle;
if (!NeedsPrefSlot3Shuffle)
return;
@ -590,9 +593,9 @@ void HexagonShuffler::restrictPreferSlot3(HexagonPacketSummary const &Summary) {
}
/// Check that the packet is legal and enforce relative insn order.
bool HexagonShuffler::check() {
bool HexagonShuffler::check(const bool RequireShuffle) {
const HexagonPacketSummary Summary = GetPacketSummary();
if (!applySlotRestrictions(Summary))
if (!applySlotRestrictions(Summary, RequireShuffle))
return false;
if (!ValidPacketMemoryOps(Summary)) {
@ -600,13 +603,14 @@ bool HexagonShuffler::check() {
return false;
}
ValidResourceUsage(Summary);
if (RequireShuffle)
ValidResourceUsage(Summary);
return !CheckFailure;
}
llvm::Optional<HexagonShuffler::HexagonPacket>
HexagonShuffler::tryAuction(HexagonPacketSummary const &Summary) const {
HexagonShuffler::tryAuction(HexagonPacketSummary const &Summary) {
HexagonPacket PacketResult = Packet;
HexagonUnitAuction AuctionCore(Summary.ReservedSlotMask);
llvm::stable_sort(PacketResult, HexagonInstr::lessCore);
@ -640,8 +644,8 @@ bool HexagonShuffler::shuffle() {
}
// Check and prepare packet.
bool Ok = true;
if (size() > 1 && (Ok = check()))
bool Ok = check();
if (size() > 1 && Ok)
// Reorder the handles for each slot.
for (unsigned nSlot = 0, emptySlots = 0; nSlot < HEXAGON_PACKET_SIZE;
++nSlot) {

View File

@ -177,21 +177,23 @@ protected:
bool ReportErrors;
bool CheckFailure;
std::vector<std::pair<SMLoc, std::string>> AppliedRestrictions;
bool applySlotRestrictions(HexagonPacketSummary const &Summary);
bool applySlotRestrictions(HexagonPacketSummary const &Summary,
const bool DoShuffle);
void restrictSlot1AOK(HexagonPacketSummary const &Summary);
void restrictNoSlot1Store(HexagonPacketSummary const &Summary);
void restrictNoSlot1();
bool restrictStoreLoadOrder(HexagonPacketSummary const &Summary);
void restrictBranchOrder(HexagonPacketSummary const &Summary);
void restrictPreferSlot3(HexagonPacketSummary const &Summary);
void restrictPreferSlot3(HexagonPacketSummary const &Summary,
const bool DoShuffle);
void permitNonSlot();
Optional<HexagonPacket> tryAuction(HexagonPacketSummary const &Summary) const;
Optional<HexagonPacket> tryAuction(HexagonPacketSummary const &Summary);
HexagonPacketSummary GetPacketSummary();
bool ValidPacketMemoryOps(HexagonPacketSummary const &Summary) const;
bool ValidResourceUsage(HexagonPacketSummary const &Summary);
bool validPacketInsts() const;
public:
using iterator = HexagonPacket::iterator;
@ -205,7 +207,7 @@ public:
// Reset to initial state.
void reset();
// Check if the bundle may be validly shuffled.
bool check();
bool check(const bool RequireShuffle = true);
// Reorder the insn handles in the bundle.
bool shuffle();