forked from OSchip/llvm-project
[Hexagon] Misc shuffling fixes
Co-authored-by: Brian Cain <bcain@quicinc.com>
This commit is contained in:
parent
a3573f203e
commit
88397739a3
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
Loading…
Reference in New Issue