1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-18 18:42:46 +02:00

[Hexagon] Use itinerary for assembler HVX resource checking

This commit is contained in:
Mike Lambert 2020-01-17 13:13:28 -06:00 committed by Krzysztof Parzyszek
parent 62ee34a755
commit 34ba727056
6 changed files with 97 additions and 58 deletions

View File

@ -394,6 +394,26 @@ unsigned HexagonMCInstrInfo::getType(MCInstrInfo const &MCII,
return ((F >> HexagonII::TypePos) & HexagonII::TypeMask);
}
/// Return the resources used by this instruction
unsigned HexagonMCInstrInfo::getCVIResources(MCInstrInfo const &MCII,
MCSubtargetInfo const &STI,
MCInst const &MCI) {
const InstrItinerary *II = STI.getSchedModel().InstrItineraries;
int SchedClass = HexagonMCInstrInfo::getDesc(MCII, MCI).getSchedClass();
int Size = II[SchedClass].LastStage - II[SchedClass].FirstStage;
// HVX resources used are currenty located at the second to last stage.
// This could also be done with a linear search of the stages looking for:
// CVI_ALL, CVI_MPY01, CVI_XLSHF, CVI_MPY0, CVI_MPY1, CVI_SHIFT, CVI_XLANE,
// CVI_ZW
unsigned Stage = II[SchedClass].LastStage - 1;
if (Size < 2)
return 0;
return ((Stage + HexagonStages)->getUnits());
}
/// Return the slots this instruction can execute out of
unsigned HexagonMCInstrInfo::getUnits(MCInstrInfo const &MCII,
MCSubtargetInfo const &STI,

View File

@ -165,6 +165,11 @@ MCOperand const &getNewValueOperand2(MCInstrInfo const &MCII,
// Return the Hexagon ISA class for the insn.
unsigned getType(MCInstrInfo const &MCII, MCInst const &MCI);
/// Return the resources used by this instruction
unsigned getCVIResources(MCInstrInfo const &MCII,
MCSubtargetInfo const &STI,
MCInst const &MCI);
/// Return the slots used by the insn.
unsigned getUnits(MCInstrInfo const &MCII, MCSubtargetInfo const &STI,
MCInst const &MCI);

View File

@ -127,6 +127,55 @@ StringRef Hexagon_MC::selectHexagonCPU(StringRef CPU) {
unsigned llvm::HexagonGetLastSlot() { return HexagonItinerariesV5FU::SLOT3; }
unsigned llvm::HexagonConvertUnits(unsigned ItinUnits, unsigned *Lanes) {
enum {
CVI_NONE = 0,
CVI_XLANE = 1 << 0,
CVI_SHIFT = 1 << 1,
CVI_MPY0 = 1 << 2,
CVI_MPY1 = 1 << 3,
CVI_ZW = 1 << 4
};
if (ItinUnits == HexagonItinerariesV62FU::CVI_ALL ||
ItinUnits == HexagonItinerariesV62FU::CVI_ALL_NOMEM)
return (*Lanes = 4, CVI_XLANE);
else if (ItinUnits & HexagonItinerariesV62FU::CVI_MPY01 &&
ItinUnits & HexagonItinerariesV62FU::CVI_XLSHF)
return (*Lanes = 2, CVI_XLANE | CVI_MPY0);
else if (ItinUnits & HexagonItinerariesV62FU::CVI_MPY01)
return (*Lanes = 2, CVI_MPY0);
else if (ItinUnits & HexagonItinerariesV62FU::CVI_XLSHF)
return (*Lanes = 2, CVI_XLANE);
else if (ItinUnits & HexagonItinerariesV62FU::CVI_XLANE &&
ItinUnits & HexagonItinerariesV62FU::CVI_SHIFT &&
ItinUnits & HexagonItinerariesV62FU::CVI_MPY0 &&
ItinUnits & HexagonItinerariesV62FU::CVI_MPY1)
return (*Lanes = 1, CVI_XLANE | CVI_SHIFT | CVI_MPY0 | CVI_MPY1);
else if (ItinUnits & HexagonItinerariesV62FU::CVI_XLANE &&
ItinUnits & HexagonItinerariesV62FU::CVI_SHIFT)
return (*Lanes = 1, CVI_XLANE | CVI_SHIFT);
else if (ItinUnits & HexagonItinerariesV62FU::CVI_MPY0 &&
ItinUnits & HexagonItinerariesV62FU::CVI_MPY1)
return (*Lanes = 1, CVI_MPY0 | CVI_MPY1);
else if (ItinUnits == HexagonItinerariesV62FU::CVI_ZW)
return (*Lanes = 1, CVI_ZW);
else if (ItinUnits == HexagonItinerariesV62FU::CVI_XLANE)
return (*Lanes = 1, CVI_XLANE);
else if (ItinUnits == HexagonItinerariesV62FU::CVI_SHIFT)
return (*Lanes = 1, CVI_SHIFT);
return (*Lanes = 0, CVI_NONE);
}
namespace llvm {
namespace HexagonFUnits {
bool isSlot0Only(unsigned units) {
return (HexagonItinerariesV62FU::SLOT0 == units);
}
}
}
namespace {
class HexagonTargetAsmStreamer : public HexagonTargetStreamer {

View File

@ -94,6 +94,7 @@ std::unique_ptr<MCObjectTargetWriter>
createHexagonELFObjectWriter(uint8_t OSABI, StringRef CPU);
unsigned HexagonGetLastSlot();
unsigned HexagonConvertUnits(unsigned ItinUnits, unsigned *Lanes);
} // End llvm namespace

View File

@ -105,62 +105,30 @@ unsigned HexagonResource::setWeight(unsigned s) {
return Weight;
}
void HexagonCVIResource::SetupTUL(TypeUnitsAndLanes *TUL, StringRef CPU) {
(*TUL)[HexagonII::TypeCVI_VA] =
UnitsAndLanes(CVI_XLANE | CVI_SHIFT | CVI_MPY0 | CVI_MPY1, 1);
(*TUL)[HexagonII::TypeCVI_VA_DV] = UnitsAndLanes(CVI_XLANE | CVI_MPY0, 2);
(*TUL)[HexagonII::TypeCVI_VX] = UnitsAndLanes(CVI_MPY0 | CVI_MPY1, 1);
(*TUL)[HexagonII::TypeCVI_VX_LATE] = UnitsAndLanes(CVI_MPY0 | CVI_MPY1, 1);
(*TUL)[HexagonII::TypeCVI_VX_DV] = UnitsAndLanes(CVI_MPY0, 2);
(*TUL)[HexagonII::TypeCVI_VP] = UnitsAndLanes(CVI_XLANE, 1);
(*TUL)[HexagonII::TypeCVI_VP_VS] = UnitsAndLanes(CVI_XLANE, 2);
(*TUL)[HexagonII::TypeCVI_VS] = UnitsAndLanes(CVI_SHIFT, 1);
(*TUL)[HexagonII::TypeCVI_VS_VX] = UnitsAndLanes(CVI_XLANE | CVI_SHIFT, 1);
(*TUL)[HexagonII::TypeCVI_VINLANESAT] =
(CPU == "hexagonv60")
? UnitsAndLanes(CVI_SHIFT, 1)
: UnitsAndLanes(CVI_XLANE | CVI_SHIFT | CVI_MPY0 | CVI_MPY1, 1);
(*TUL)[HexagonII::TypeCVI_VM_LD] =
UnitsAndLanes(CVI_XLANE | CVI_SHIFT | CVI_MPY0 | CVI_MPY1, 1);
(*TUL)[HexagonII::TypeCVI_VM_TMP_LD] = UnitsAndLanes(CVI_NONE, 0);
(*TUL)[HexagonII::TypeCVI_VM_VP_LDU] = UnitsAndLanes(CVI_XLANE, 1);
(*TUL)[HexagonII::TypeCVI_VM_ST] =
UnitsAndLanes(CVI_XLANE | CVI_SHIFT | CVI_MPY0 | CVI_MPY1, 1);
(*TUL)[HexagonII::TypeCVI_VM_NEW_ST] = UnitsAndLanes(CVI_NONE, 0);
(*TUL)[HexagonII::TypeCVI_VM_STU] = UnitsAndLanes(CVI_XLANE, 1);
(*TUL)[HexagonII::TypeCVI_HIST] = UnitsAndLanes(CVI_XLANE, 4);
(*TUL)[HexagonII::TypeCVI_GATHER] =
UnitsAndLanes(CVI_XLANE | CVI_SHIFT | CVI_MPY0 | CVI_MPY1, 1);
(*TUL)[HexagonII::TypeCVI_SCATTER] =
UnitsAndLanes(CVI_XLANE | CVI_SHIFT | CVI_MPY0 | CVI_MPY1, 1);
(*TUL)[HexagonII::TypeCVI_SCATTER_DV] =
UnitsAndLanes(CVI_XLANE | CVI_MPY0, 2);
(*TUL)[HexagonII::TypeCVI_SCATTER_NEW_ST] =
UnitsAndLanes(CVI_XLANE | CVI_SHIFT | CVI_MPY0 | CVI_MPY1, 1);
(*TUL)[HexagonII::TypeCVI_4SLOT_MPY] = UnitsAndLanes(CVI_XLANE, 4);
(*TUL)[HexagonII::TypeCVI_ZW] = UnitsAndLanes(CVI_ZW, 1);
}
HexagonCVIResource::HexagonCVIResource(TypeUnitsAndLanes *TUL,
MCInstrInfo const &MCII, unsigned s,
HexagonCVIResource::HexagonCVIResource(MCInstrInfo const &MCII,
MCSubtargetInfo const &STI,
unsigned s,
MCInst const *id)
: HexagonResource(s) {
unsigned T = HexagonMCInstrInfo::getType(MCII, *id);
if (TUL->count(T)) {
// For an HVX insn.
Valid = true;
setUnits((*TUL)[T].first);
setLanes((*TUL)[T].second);
setLoad(HexagonMCInstrInfo::getDesc(MCII, *id).mayLoad());
setStore(HexagonMCInstrInfo::getDesc(MCII, *id).mayStore());
} else {
const unsigned ItinUnits = HexagonMCInstrInfo::getCVIResources(MCII, STI, *id);
unsigned Lanes;
const unsigned Units = HexagonConvertUnits(ItinUnits, &Lanes);
if (Units == 0 && Lanes == 0) {
// For core insns.
Valid = false;
setUnits(0);
setLanes(0);
setLoad(false);
setStore(false);
} else {
// For an HVX insn.
Valid = true;
setUnits(Units);
setLanes(Lanes);
setLoad(HexagonMCInstrInfo::getDesc(MCII, *id).mayLoad());
setStore(HexagonMCInstrInfo::getDesc(MCII, *id).mayStore());
}
}
@ -201,7 +169,6 @@ HexagonShuffler::HexagonShuffler(MCContext &Context, bool ReportErrors,
MCSubtargetInfo const &STI)
: Context(Context), MCII(MCII), STI(STI), ReportErrors(ReportErrors) {
reset();
HexagonCVIResource::SetupTUL(&TUL, STI.getCPU());
}
void HexagonShuffler::reset() {
@ -212,7 +179,7 @@ void HexagonShuffler::reset() {
void HexagonShuffler::append(MCInst const &ID, MCInst const *Extender,
unsigned S) {
HexagonInstr PI(&TUL, MCII, &ID, Extender, S);
HexagonInstr PI(MCII, STI, &ID, Extender, S);
Packet.push_back(PI);
}
@ -362,6 +329,7 @@ bool HexagonShuffler::ValidResourceUsage(HexagonPacketSummary const &Summary) {
continue; // not an hvx inst or an hvx inst that doesn't uses any pipes
hvxInsts.push_back(inst);
}
// if there are any hvx instructions in this packet, check pipe usage
if (hvxInsts.size() > 0) {
unsigned startIdx, usedUnits;

View File

@ -67,7 +67,6 @@ public:
class HexagonCVIResource : public HexagonResource {
public:
using UnitsAndLanes = std::pair<unsigned, unsigned>;
using TypeUnitsAndLanes = DenseMap<unsigned, UnitsAndLanes>;
private:
// Available HVX slots.
@ -92,11 +91,10 @@ private:
void setStore(bool f = true) { Store = f; }
public:
HexagonCVIResource(TypeUnitsAndLanes *TUL, MCInstrInfo const &MCII,
HexagonCVIResource(MCInstrInfo const &MCII,
MCSubtargetInfo const &STI,
unsigned s, MCInst const *id);
static void SetupTUL(TypeUnitsAndLanes *TUL, StringRef CPU);
bool isValid() const { return Valid; }
unsigned getLanes() const { return Lanes; }
bool mayLoad() const { return Load; }
@ -113,10 +111,10 @@ class HexagonInstr {
HexagonCVIResource CVI;
public:
HexagonInstr(HexagonCVIResource::TypeUnitsAndLanes *T,
MCInstrInfo const &MCII, MCInst const *id,
HexagonInstr(MCInstrInfo const &MCII,
MCSubtargetInfo const &STI, MCInst const *id,
MCInst const *Extender, unsigned s)
: ID(id), Extender(Extender), Core(s), CVI(T, MCII, s, id) {}
: ID(id), Extender(Extender), Core(s), CVI(MCII, STI, s, id){};
MCInst const &getDesc() const { return *ID; }
MCInst const *getExtender() const { return Extender; }
@ -167,8 +165,6 @@ class HexagonShuffler {
// Insn handles in a bundle.
HexagonPacket Packet;
HexagonCVIResource::TypeUnitsAndLanes TUL;
protected:
MCContext &Context;
int64_t BundleFlags;