forked from OSchip/llvm-project
[Hexagon] Use itinerary for assembler HVX resource checking
This commit is contained in:
parent
90bdb03727
commit
fe085be125
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue