56#define DEBUG_TYPE "packets"
59 cl::desc(
"Disable Hexagon packetizer pass"));
63 cl::desc(
"Allow slot1 store and slot0 load"));
67 cl::desc(
"Allow non-solo packetization of volatile memory references"));
71 cl::desc(
"Generate all instruction with TC"));
75 cl::desc(
"Disable vector double new-value-stores"));
85 HexagonPacketizer(
bool Min =
false)
88 void getAnalysisUsage(AnalysisUsage &AU)
const override {
91 AU.
addRequired<MachineBranchProbabilityInfoWrapperPass>();
96 StringRef getPassName()
const override {
return "Hexagon Packetizer"; }
97 bool runOnMachineFunction(MachineFunction &Fn)
override;
99 MachineFunctionProperties getRequiredProperties()
const override {
100 return MachineFunctionProperties().setNoVRegs();
104 const HexagonInstrInfo *HII =
nullptr;
105 const HexagonRegisterInfo *HRI =
nullptr;
106 const bool Minimal =
false;
111char HexagonPacketizer::ID = 0;
114 "Hexagon Packetizer",
false,
false)
130 addMutation(std::make_unique<HexagonSubtarget::UsrOverflowMutation>());
131 addMutation(std::make_unique<HexagonSubtarget::HVXMemLatencyMutation>());
132 addMutation(std::make_unique<HexagonSubtarget::BankConflictMutation>());
139 for (
auto &MO : FirstI.
operands()) {
140 if (!MO.isReg() || !MO.isDef())
156 InsertPt = std::next(BundleIt).getInstrIterator();
162 if (
MI.isBundledWithSucc()) {
169 MI.unbundleFromPred();
171 B.splice(InsertPt, &
B,
MI.getIterator());
177 for (++
I;
I !=
E &&
I->isBundledWithPred(); ++
I)
190 BundleIt->eraseFromParent();
199 HII = HST.getInstrInfo();
200 HRI = HST.getRegisterInfo();
201 auto &MLI = getAnalysis<MachineLoopInfoWrapperPass>().getLI();
202 auto *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
204 &getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI();
207 HII->genAllInsnTimingClasses(MF);
212 HexagonPacketizerList
Packetizer(MF, MLI, AA, MBPI, MinOnly);
225 for (MachineBasicBlock &MB : MF) {
232 if (HST.isTinyCoreWithDuplex())
233 HII->translateInstrsForDup(MF,
true);
236 for (
auto &MB : MF) {
237 auto Begin = MB.begin(), End = MB.end();
238 while (Begin != End) {
242 while (RB != End && HII->isSchedulingBoundary(*RB, &MB, MF))
247 while (RE != End && !HII->isSchedulingBoundary(*RE, &MB, MF))
261 if (HST.isTinyCoreWithDuplex())
262 HII->translateInstrsForDup(MF,
false);
282 auto *ExtMI =
MF.CreateMachineInstr(HII->get(Hexagon::A4_ext),
DebugLoc());
284 if (Reserve && Avail)
286 MF.deleteMachineInstr(ExtMI);
293 if (DepReg == HRI->getRARegister())
296 if (HII->isDeallocRet(
MI))
297 if (DepReg == HRI->getFrameRegister() || DepReg == HRI->getStackRegister())
307 if (MO.isReg() && MO.getReg() == DepReg && !MO.isImplicit())
320 return MI.getOpcode() == Hexagon::J2_jump;
324 switch (
MI.getOpcode()) {
325 case Hexagon::Y2_barrier:
332 return MI.getDesc().isTerminator() ||
MI.getDesc().isCall();
339 for (
auto *CSR =
TRI->getCalleeSavedRegs(&MF); CSR && *CSR; ++CSR)
340 if (
MI.modifiesRegister(*CSR,
TRI))
351 if (NewRC == &Hexagon::PredRegsRegClass) {
352 if (HII->isHVXVec(
MI) &&
MI.mayStore())
354 return HII->isPredicated(
MI) && HII->getDotNewPredOp(
MI,
nullptr) > 0;
357 return HII->mayBeNewStore(
MI);
367 int CurOpcode = HII->getDotCurOp(
MI);
368 MI.setDesc(HII->get(CurOpcode));
376 if (HII->isDotCurInst(*BI)) {
381 for (
auto &MO : BI->operands())
382 if (MO.isReg() && MO.getReg() ==
MI->getOperand(0).getReg())
389 MI->setDesc(HII->get(HII->getNonDotCurOp(*
MI)));
397 if (!HII->isHVXVec(
MI))
399 if (!HII->isHVXVec(*MII))
403 if (HII->isDotCurInst(
MI) && !HII->mayBeCurLoad(
MI))
406 if (!HII->mayBeCurLoad(
MI))
415 dbgs() <<
"in packet\n";);
418 dbgs() <<
"Checking CUR against ";
422 bool FoundMatch =
false;
423 for (
auto &MO : MJ.operands())
424 if (MO.isReg() && MO.getReg() == DestReg)
433 if (BI->readsRegister(DepReg,
MF.getSubtarget().getRegisterInfo()))
450 if (RC == &Hexagon::PredRegsRegClass)
451 NewOpcode = HII->getDotNewPredOp(
MI,
MBPI);
453 NewOpcode = HII->getDotNewOp(
MI);
454 MI.setDesc(HII->get(NewOpcode));
459 int NewOpcode = HII->getDotOldOp(
MI);
460 MI.setDesc(HII->get(NewOpcode));
465 unsigned Opc =
MI.getOpcode();
467 case Hexagon::S2_storerd_io:
468 case Hexagon::S2_storeri_io:
469 case Hexagon::S2_storerh_io:
470 case Hexagon::S2_storerb_io:
475 unsigned FrameSize =
MF.getFrameInfo().getStackSize();
478 if (HII->isValidOffset(
Opc, NewOff, HRI)) {
486 unsigned Opc =
MI.getOpcode();
488 case Hexagon::S2_storerd_io:
489 case Hexagon::S2_storeri_io:
490 case Hexagon::S2_storerh_io:
491 case Hexagon::S2_storerb_io:
496 unsigned FrameSize =
MF.getFrameInfo().getStackSize();
509 if (!HII->getBaseAndOffsetPosition(
MI, BPI, OPI))
512 if (!HII->getBaseAndOffsetPosition(MJ, BPJ, OPJ))
520 for (
const auto &PI : SUI->
Preds)
522 (PI.getKind() !=
SDep::Data || PI.getReg() != Reg))
525 if (!HII->getIncrementValue(MJ, Incr))
528 int64_t
Offset =
MI.getOperand(OPI).getImm();
529 if (!HII->isValidOffset(
MI.getOpcode(),
Offset+Incr, HRI))
532 MI.getOperand(OPI).setImm(
Offset + Incr);
541 if (!HII->getBaseAndOffsetPosition(
MI, BP,
OP))
543 MI.getOperand(
OP).setImm(ChangedOffset);
571 for (
auto &MO :
MI.operands())
572 if (MO.isReg() && MO.isDef())
573 DefRegsSet.
insert(MO.getReg());
575 for (
auto &MO :
MI.operands())
576 if (MO.isReg() && MO.isUse() && DefRegsSet.
count(MO.getReg()))
582 assert(Op1.
isReg() &&
"Post increment operand has be to a register.");
585 if (
MI.getDesc().mayStore()) {
588 assert(Op0.
isReg() &&
"Post increment operand has be to a register.");
593 llvm_unreachable(
"mayLoad or mayStore not set for Post Increment operation");
599 return MI.getOperand(
MI.getNumOperands()-1);
603 unsigned Opc =
MI.getOpcode();
605 case Hexagon::L4_loadrd_ap:
606 case Hexagon::L4_loadrb_ap:
607 case Hexagon::L4_loadrh_ap:
608 case Hexagon::L4_loadrub_ap:
609 case Hexagon::L4_loadruh_ap:
610 case Hexagon::L4_loadri_ap:
618 return MI.getOperand(1);
641 if (!HII->mayBeNewStore(
MI))
654 if (PacketRC == &Hexagon::DoubleRegsRegClass)
667 if (HII->isPostIncrement(
MI) &&
672 if (HII->isPostIncrement(PacketMI) && PacketMI.
mayLoad() &&
687 if (HII->isPredicated(PacketMI)) {
688 if (!HII->isPredicated(
MI))
693 unsigned predRegNumSrc = 0;
694 unsigned predRegNumDst = 0;
698 for (
auto &MO : PacketMI.
operands()) {
701 predRegNumSrc = MO.getReg();
702 predRegClass = HRI->getMinimalPhysRegClass(predRegNumSrc);
703 if (predRegClass == &Hexagon::PredRegsRegClass)
706 assert((predRegClass == &Hexagon::PredRegsRegClass) &&
707 "predicate register not found in a predicated PacketMI instruction");
710 for (
auto &MO :
MI.operands()) {
713 predRegNumDst = MO.getReg();
714 predRegClass = HRI->getMinimalPhysRegClass(predRegNumDst);
715 if (predRegClass == &Hexagon::PredRegsRegClass)
718 assert((predRegClass == &Hexagon::PredRegsRegClass) &&
719 "predicate register not found in a predicated MI instruction");
729 if (predRegNumDst != predRegNumSrc ||
730 HII->isDotNewInst(PacketMI) != HII->isDotNewInst(
MI) ||
743 unsigned StartCheck = 0;
752 if (&TempMI != &PacketMI && !StartCheck)
756 if (&TempMI == &PacketMI)
759 for (
auto &MO :
MI.operands())
770 if (!HII->isPostIncrement(
MI)) {
771 for (
unsigned opNum = 0; opNum <
MI.getNumOperands()-1; opNum++) {
782 for (
auto &MO : PacketMI.
operands()) {
783 if (MO.isRegMask() && MO.clobbersPhysReg(DepReg))
785 if (!MO.isReg() || !MO.isDef() || !MO.isImplicit())
788 if (R == DepReg || HRI->isSuperRegister(DepReg, R))
797 for (
auto &MO :
MI.operands()) {
798 if (MO.isReg() && MO.isUse() && MO.isImplicit() && MO.getReg() == DepReg)
808 const SUnit *PacketSU,
unsigned DepReg,
810 if (!HII->mayBeNewStore(
MI))
825 for (
auto &MO :
I.operands()) {
826 if (CheckDef && MO.isRegMask() && MO.clobbersPhysReg(DepReg))
828 if (!MO.isReg() || MO.getReg() != DepReg || !MO.isImplicit())
830 if (CheckDef == MO.isDef())
841 if (HII->isDotNewInst(
MI) && !HII->mayBeNewStore(
MI))
870 if (RC == &Hexagon::PredRegsRegClass)
871 return HII->predCanBeUsedAsDotNew(PI, DepReg);
873 if (RC != &Hexagon::PredRegsRegClass && !HII->mayBeNewStore(
MI))
878 int NewOpcode = (RC != &Hexagon::PredRegsRegClass) ? HII->getDotNewOp(
MI) :
879 HII->getDotNewPredOp(
MI,
MBPI);
882 bool ResourcesAvailable =
ResourceTracker->canReserveResources(*NewMI);
883 MF.deleteMachineInstr(NewMI);
884 if (!ResourcesAvailable)
913 if (!HII->isPredicated(*
I))
922 if (PacketSU->
isSucc(PacketSUDep)) {
923 for (
unsigned i = 0; i < PacketSU->
Succs.size(); ++i) {
924 auto &Dep = PacketSU->
Succs[i];
925 if (Dep.getSUnit() == PacketSUDep && Dep.getKind() ==
SDep::Anti &&
926 Dep.getReg() == DepReg)
942 for (
auto &
Op :
MI.operands()) {
943 if (
Op.isReg() &&
Op.getReg() &&
Op.isUse() &&
944 Hexagon::PredRegsRegClass.contains(
Op.getReg()))
986 if (PacketSU->
isSucc(SU)) {
987 for (
unsigned i = 0; i < PacketSU->
Succs.size(); ++i) {
988 auto Dep = PacketSU->
Succs[i];
993 if (Dep.getSUnit() == SU && Dep.getKind() ==
SDep::Data &&
994 Hexagon::PredRegsRegClass.contains(Dep.getReg())) {
1013 return PReg1 == PReg2 &&
1014 Hexagon::PredRegsRegClass.contains(PReg1) &&
1015 Hexagon::PredRegsRegClass.contains(PReg2) &&
1017 HII->isDotNewInst(MI1) == HII->isDotNewInst(MI2);
1023 PromotedToDotNew =
false;
1024 GlueToNewValueJump =
false;
1025 GlueAllocframeStore =
false;
1026 FoundSequentialDependence =
false;
1033 if (
MI.isDebugInstr())
1036 if (
MI.isCFIInstruction())
1040 if (
MI.isInlineAsm())
1043 if (
MI.isImplicitDef())
1050 return !IS->getUnits();
1058 if (
MI.isEHLabel() ||
MI.isCFIInstruction())
1072 if (HII->isSolo(
MI))
1075 if (
MI.getOpcode() == Hexagon::PATCHABLE_FUNCTION_ENTER ||
1076 MI.getOpcode() == Hexagon::PATCHABLE_FUNCTION_EXIT ||
1077 MI.getOpcode() == Hexagon::PATCHABLE_TAIL_CALL ||
1078 MI.getOpcode() == Hexagon::PATCHABLE_EVENT_CALL ||
1079 MI.getOpcode() == Hexagon::PATCHABLE_TYPED_EVENT_CALL)
1082 if (
MI.getOpcode() == Hexagon::A2_nop)
1111 if (
MI.isInlineAsm())
1119 switch (
MI.getOpcode()) {
1120 case Hexagon::S2_storew_locked:
1121 case Hexagon::S4_stored_locked:
1122 case Hexagon::L2_loadw_locked:
1123 case Hexagon::L4_loadd_locked:
1124 case Hexagon::Y2_dccleana:
1125 case Hexagon::Y2_dccleaninva:
1126 case Hexagon::Y2_dcinva:
1127 case Hexagon::Y2_dczeroa:
1128 case Hexagon::Y4_l2fetch:
1129 case Hexagon::Y5_l2fetch: {
1133 unsigned TJ = HII.
getType(MJ);
1156 for (
auto &
B :
MF) {
1160 BundleIt =
MI.getIterator();
1161 if (!
MI.isInsideBundle())
1170 bool InsertBeforeBundle;
1171 if (
MI.isInlineAsm())
1173 else if (
MI.isDebugInstr())
1174 InsertBeforeBundle =
true;
1185 unsigned Opc =
MI.getOpcode();
1187 case Hexagon::Y2_barrier:
1188 case Hexagon::Y2_dcfetchbo:
1189 case Hexagon::Y4_l2fetch:
1190 case Hexagon::Y5_l2fetch:
1203 if (HII->isPredicated(
I) || HII->isPredicated(J))
1206 BitVector DeadDefs(Hexagon::NUM_TARGET_REGS);
1207 for (
auto &MO :
I.operands()) {
1208 if (!MO.isReg() || !MO.isDef() || !MO.isDead())
1210 DeadDefs[MO.getReg()] =
true;
1214 if (!MO.isReg() || !MO.isDef() || !MO.isDead())
1217 if (R != Hexagon::USR_OVF && DeadDefs[R])
1227 if ((HII->isSaveCalleeSavedRegsCall(
I) &&
1229 (HII->isSaveCalleeSavedRegsCall(J) &&
1241 if (
MI.isCall() || HII->isDeallocRet(
MI) || HII->isNewValueJump(
MI))
1243 if (HII->isPredicated(
MI) && HII->isPredicatedNew(
MI) && HII->isJumpR(
MI))
1248 if (HII->isLoopN(
I) && isBadForLoopN(J))
1250 if (HII->isLoopN(J) && isBadForLoopN(
I))
1255 return HII->isDeallocRet(
I) &&
1273 if (!OpJ.isRegMask())
1275 assert((J.
isCall() || HII->isTailCall(J)) &&
"Regmask on a non-call");
1278 if (OpJ.clobbersPhysReg(OpI.getReg()))
1280 }
else if (OpI.isRegMask()) {
1292 bool StoreI =
I.mayStore(), StoreJ = J.
mayStore();
1293 if ((SysI && StoreJ) || (SysJ && StoreI))
1296 if (StoreI && StoreJ) {
1297 if (HII->isNewValueInst(J) || HII->isMemOp(J) || HII->isMemOp(
I))
1302 bool MopStI = HII->isMemOp(
I) || StoreI;
1303 bool MopStJ = HII->isMemOp(J) || StoreJ;
1304 if (MopStI && MopStJ)
1308 return (StoreJ && HII->isDeallocRet(
I)) || (StoreI && HII->isDeallocRet(J));
1321 IgnoreDepMIs.clear();
1353 if (NextMII !=
I.getParent()->end() && HII->isNewValueJump(*NextMII)) {
1356 bool secondRegMatch =
false;
1360 if (NOp1.
isReg() &&
I.getOperand(0).getReg() == NOp1.
getReg())
1361 secondRegMatch =
true;
1377 if (PI->getOpcode() == Hexagon::S2_allocframe || PI->mayStore() ||
1378 HII->isLoopN(*PI)) {
1384 if (OpR.
isReg() && PI->modifiesRegister(OpR.
getReg(), HRI)) {
1390 GlueToNewValueJump =
true;
1399 for (
unsigned i = 0; i < SUJ->
Succs.size(); ++i) {
1400 if (FoundSequentialDependence)
1403 if (SUJ->
Succs[i].getSUnit() != SUI)
1422 unsigned DepReg = 0;
1425 DepReg = SUJ->
Succs[i].getReg();
1426 RC = HRI->getMinimalPhysRegClass(DepReg);
1429 if (
I.isCall() || HII->isJumpR(
I) ||
I.isReturn() || HII->isTailCall(
I)) {
1443 if (DepType ==
SDep::Data && HII->isDotCurInst(J)) {
1444 if (HII->isHVXVec(
I))
1452 PromotedToDotNew =
true;
1454 FoundSequentialDependence =
true;
1458 if (HII->isNewValueJump(
I))
1464 if (HII->isPredicated(
I) && HII->isPredicated(J) &&
1478 auto Itr =
find(IgnoreDepMIs, &J);
1479 if (Itr != IgnoreDepMIs.end()) {
1483 IgnoreDepMIs.push_back(&
I);
1495 if (
I.isConditionalBranch() && DepType !=
SDep::Data &&
1500 FoundSequentialDependence =
true;
1514 FoundSequentialDependence =
true;
1520 bool LoadI =
I.mayLoad(), StoreI =
I.mayStore();
1521 bool NVStoreJ = HII->isNewValueStore(J);
1522 bool NVStoreI = HII->isNewValueStore(
I);
1523 bool IsVecJ = HII->isHVXVec(J);
1524 bool IsVecI = HII->isHVXVec(
I);
1528 if (LoadJ && LoadI && HII->isPureSlot0(J)) {
1529 FoundSequentialDependence =
true;
1534 ((LoadJ && StoreI && !NVStoreI) ||
1535 (StoreJ && LoadI && !NVStoreJ)) &&
1536 (J.
getOpcode() != Hexagon::S2_allocframe &&
1537 I.getOpcode() != Hexagon::S2_allocframe) &&
1538 (J.
getOpcode() != Hexagon::L2_deallocframe &&
1539 I.getOpcode() != Hexagon::L2_deallocframe) &&
1540 (!HII->isMemOp(J) && !HII->isMemOp(
I)) && (!IsVecJ && !IsVecI))
1543 if (StoreJ && LoadI &&
alias(J,
I)) {
1544 FoundSequentialDependence =
true;
1549 if (!LoadJ || (!LoadI && !StoreI)) {
1552 FoundSequentialDependence =
true;
1567 unsigned Opc =
I.getOpcode();
1569 case Hexagon::S2_storerd_io:
1570 case Hexagon::S2_storeri_io:
1571 case Hexagon::S2_storerh_io:
1572 case Hexagon::S2_storerb_io:
1573 if (
I.getOperand(0).getReg() == HRI->getStackRegister()) {
1579 if (GlueAllocframeStore)
1599 if (
Op.isReg() &&
Op.isDef()) {
1603 }
else if (!
Op.isRegMask()) {
1607 FoundSequentialDependence =
true;
1619 FoundSequentialDependence =
true;
1624 if (FoundSequentialDependence) {
1639 if (Coexist && !Dependence)
1644 if (PromotedToDotNew)
1651 if (GlueAllocframeStore) {
1653 GlueAllocframeStore =
false;
1659 if (GlueToNewValueJump) {
1662 GlueToNewValueJump =
false;
1670 FoundSequentialDependence =
false;
1680 bool FoundLoad =
false;
1681 bool FoundStore =
false;
1684 unsigned Opc = MJ->getOpcode();
1685 if (
Opc == Hexagon::S2_allocframe ||
Opc == Hexagon::L2_deallocframe)
1687 if (HII->isMemOp(*MJ))
1691 if (MJ->mayStore() && !HII->isNewValueStore(*MJ))
1694 return FoundLoad && FoundStore;
1704 PacketStalls =
false;
1705 PacketStallCycles = 0;
1708 PacketStallCycles = std::max(PacketStallCycles,
calcStall(
MI));
1710 if (
MI.isImplicitDef()) {
1718 bool ExtMI = HII->isExtended(
MI) || HII->isConstExtended(
MI);
1721 if (GlueToNewValueJump) {
1731 bool ExtNvjMI = HII->isExtended(NvjMI) || HII->isConstExtended(NvjMI);
1738 if (Good && ExtNvjMI)
1764 if (PromotedToDotNew)
1766 if (GlueAllocframeStore) {
1768 GlueAllocframeStore =
false;
1783 dbgs() <<
"Finalizing packet:\n";
1799 OldPacketMIs.clear();
1802 for (
auto &
I :
make_range(HII->expandVGatherPseudo(*
MI), NextMI))
1803 OldPacketMIs.push_back(&
I);
1807 if (OldPacketMIs.size() > 1) {
1811 auto BundleMII = std::prev(FirstMI);
1812 if (memShufDisabled)
1813 HII->setBundleNoShuf(BundleMII);
1818 PacketHasDuplex =
false;
1819 PacketHasSLOT0OnlyInsn =
false;
1845 PacketHasSLOT0OnlyInsn |= HII->isPureSlot0(*MJ);
1847 int Opcode = HII->getDuplexOpcode(
MI,
false);
1851 if (HII->isDuplexPair(
MI, *MJ) && !PacketHasSLOT0OnlyInsn) {
1852 PacketHasDuplex =
true;
1859 MIRef.
setDesc(HII->get(Opcode));
1876 if (!OldPacketMIs.empty()) {
1877 auto *OldBB = OldPacketMIs.front()->getParent();
1878 auto *ThisBB =
I.getParent();
1879 if (
MLI->getLoopFor(OldBB) !=
MLI->getLoopFor(ThisBB))
1910 for (
auto &Pred : SUI->
Preds)
1911 if (Pred.getSUnit() == SUJ)
1912 if ((Pred.getLatency() == 0 && Pred.isAssignedRegDep()) ||
1913 HII->isNewValueJump(
I) || HII->isToBeScheduledASAP(*J,
I))
1919 for (
auto *J : OldPacketMIs) {
1921 for (
auto &Pred : SUI->
Preds)
1922 if (Pred.getSUnit() == SUJ && Pred.getLatency() > 1)
1923 return Pred.getLatency();
1935 return Latency > PacketStallCycles;
1944 return new HexagonPacketizer(Minimal);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements the BitVector class.
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file defines the DenseSet and SmallDenseSet classes.
cl::opt< bool > ScheduleInlineAsm("hexagon-sched-inline-asm", cl::Hidden, cl::init(false), cl::desc("Do not consider inline-asm a scheduling/" "packetization boundary."))
#define HEXAGON_LRFP_SIZE
cl::opt< bool > DisablePacketizer
static bool cannotCoexistAsymm(const MachineInstr &MI, const MachineInstr &MJ, const HexagonInstrInfo &HII)
static bool isDirectJump(const MachineInstr &MI)
static MachineBasicBlock::iterator moveInstrOut(MachineInstr &MI, MachineBasicBlock::iterator BundleIt, bool Before)
static bool isRegDependence(const SDep::Kind DepType)
static const MachineOperand & getStoreValueOperand(const MachineInstr &MI)
static cl::opt< bool > EnableGenAllInsnClass("enable-gen-insn", cl::Hidden, cl::desc("Generate all instruction with TC"))
static bool isControlFlow(const MachineInstr &MI)
static cl::opt< bool > DisableVecDblNVStores("disable-vecdbl-nv-stores", cl::Hidden, cl::desc("Disable vector double new-value-stores"))
static PredicateKind getPredicateSense(const MachineInstr &MI, const HexagonInstrInfo *HII)
Returns true if an instruction is predicated on p0 and false if it's predicated on !...
static unsigned getPredicatedRegister(MachineInstr &MI, const HexagonInstrInfo *QII)
Gets the predicate register of a predicated instruction.
cl::opt< bool > DisablePacketizer("disable-packetizer", cl::Hidden, cl::desc("Disable Hexagon packetizer pass"))
static cl::opt< bool > Slot1Store("slot1-store-slot0-load", cl::Hidden, cl::init(true), cl::desc("Allow slot1 store and slot0 load"))
static cl::opt< bool > PacketizeVolatiles("hexagon-packetize-volatiles", cl::Hidden, cl::init(true), cl::desc("Allow non-solo packetization of volatile memory references"))
static bool hasWriteToReadDep(const MachineInstr &FirstI, const MachineInstr &SecondI, const TargetRegisterInfo *TRI)
static bool doesModifyCalleeSavedReg(const MachineInstr &MI, const TargetRegisterInfo *TRI)
Returns true if the instruction modifies a callee-saved register.
static bool isLoadAbsSet(const MachineInstr &MI)
static const MachineOperand & getAbsSetOperand(const MachineInstr &MI)
static const MachineOperand & getPostIncrementOperand(const MachineInstr &MI, const HexagonInstrInfo *HII)
static bool isImplicitDependency(const MachineInstr &I, bool CheckDef, unsigned DepReg)
static bool isSchedBarrier(const MachineInstr &MI)
static bool isSystemInstr(const MachineInstr &MI)
Register const TargetRegisterInfo * TRI
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
uint64_t IntrinsicInst * II
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.
AnalysisUsage & addRequired()
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Implements a dense probed hash-table based set.
FunctionPass class - This class is used to implement most global optimizations.
bool isPredicated(const MachineInstr &MI) const override
Returns true if the instruction is already predicated.
bool isHVXMemWithAIndirect(const MachineInstr &I, const MachineInstr &J) const
bool isRestrictNoSlot1Store(const MachineInstr &MI) const
bool isPureSlot0(const MachineInstr &MI) const
bool isPostIncrement(const MachineInstr &MI) const override
Return true for post-incremented instructions.
uint64_t getType(const MachineInstr &MI) const
bool isPredicatedTrue(const MachineInstr &MI) const
bool isNewValueStore(const MachineInstr &MI) const
bool arePredicatesComplements(MachineInstr &MI1, MachineInstr &MI2)
bool updateOffset(SUnit *SUI, SUnit *SUJ)
Return true if we can update the offset in MI so that MI and MJ can be packetized together.
void endPacket(MachineBasicBlock *MBB, MachineBasicBlock::iterator MI) override
bool getmemShufDisabled()
HexagonPacketizerList(MachineFunction &MF, MachineLoopInfo &MLI, AAResults *AA, const MachineBranchProbabilityInfo *MBPI, bool Minimal)
bool isCallDependent(const MachineInstr &MI, SDep::Kind DepType, unsigned DepReg)
bool promoteToDotCur(MachineInstr &MI, SDep::Kind DepType, MachineBasicBlock::iterator &MII, const TargetRegisterClass *RC)
bool promoteToDotNew(MachineInstr &MI, SDep::Kind DepType, MachineBasicBlock::iterator &MII, const TargetRegisterClass *RC)
bool isLegalToPacketizeTogether(SUnit *SUI, SUnit *SUJ) override
bool canPromoteToDotCur(const MachineInstr &MI, const SUnit *PacketSU, unsigned DepReg, MachineBasicBlock::iterator &MII, const TargetRegisterClass *RC)
void useCalleesSP(MachineInstr &MI)
bool demoteToDotOld(MachineInstr &MI)
bool cannotCoexist(const MachineInstr &MI, const MachineInstr &MJ)
const MachineLoopInfo * MLI
bool isSoloInstruction(const MachineInstr &MI) override
bool isLegalToPruneDependencies(SUnit *SUI, SUnit *SUJ) override
void initPacketizerState() override
bool hasControlDependence(const MachineInstr &I, const MachineInstr &J)
bool restrictingDepExistInPacket(MachineInstr &, unsigned)
bool producesStall(const MachineInstr &MI)
void undoChangedOffset(MachineInstr &MI)
Undo the changed offset.
bool hasDualStoreDependence(const MachineInstr &I, const MachineInstr &J)
unsigned int calcStall(const MachineInstr &MI)
bool canPromoteToDotNew(const MachineInstr &MI, const SUnit *PacketSU, unsigned DepReg, MachineBasicBlock::iterator &MII, const TargetRegisterClass *RC)
bool canPromoteToNewValue(const MachineInstr &MI, const SUnit *PacketSU, unsigned DepReg, MachineBasicBlock::iterator &MII)
bool ignorePseudoInstruction(const MachineInstr &MI, const MachineBasicBlock *MBB) override
void unpacketizeSoloInstrs(MachineFunction &MF)
const MachineBranchProbabilityInfo * MBPI
A handle to the branch probability pass.
bool shouldAddToPacket(const MachineInstr &MI) override
bool canReserveResourcesForConstExt()
bool useCallersSP(MachineInstr &MI)
bool canPromoteToNewValueStore(const MachineInstr &MI, const MachineInstr &PacketMI, unsigned DepReg)
bool tryAllocateResourcesForConstExt(bool Reserve)
void setmemShufDisabled(bool val)
void reserveResourcesForConstExt()
MachineBasicBlock::iterator addToPacket(MachineInstr &MI) override
bool hasDeadDependence(const MachineInstr &I, const MachineInstr &J)
bool isNewifiable(const MachineInstr &MI, const TargetRegisterClass *NewRC)
bool hasRegMaskDependence(const MachineInstr &I, const MachineInstr &J)
const HexagonInstrInfo * getInstrInfo() const override
const HexagonRegisterInfo * getRegisterInfo() const override
bool hasV60OpsOnly() const
Describe properties that are true of each instruction in the target description file.
unsigned getSchedClass() const
Return the scheduling class for this instruction.
Instructions::iterator instr_iterator
Instructions::const_iterator const_instr_iterator
MachineInstrBundleIterator< MachineInstr > iterator
Analysis pass which computes a MachineDominatorTree.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineFunctionProperties & getProperties() const
Get the function properties.
instr_iterator getInstrIterator() const
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
bool isTerminator(QueryType Type=AnyInBundle) const
Returns true if this instruction part of the terminator for a basic block.
bool isImplicitDef() const
bool readsRegister(Register Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr reads the specified register.
bool isBarrier(QueryType Type=AnyInBundle) const
Returns true if the specified instruction stops control flow from executing the instruction immediate...
bool isCall(QueryType Type=AnyInBundle) const
bool isBranch(QueryType Type=AnyInBundle) const
Returns true if this is a conditional, unconditional, or indirect branch.
bool modifiesRegister(Register Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr modifies (fully define or partially define) the specified register.
LLVM_ABI void unbundleFromPred()
Break bundle above this instruction.
bool mayLoad(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read memory.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
LLVM_ABI void setDesc(const MCInstrDesc &TID)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one.
LLVM_ABI bool hasOrderedMemoryRef() const
Return true if this instruction may have an ordered or volatile memory reference, or if the informati...
bool mayStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly modify memory.
bool isBundledWithSucc() const
Return true if this instruction is part of a bundle, and it is not the last instruction in the bundle...
const MachineOperand & getOperand(unsigned i) const
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Register getReg() const
getReg - Returns the register number.
Wrapper class representing virtual and physical registers.
Kind
These are the different kinds of scheduling dependencies.
@ Output
A register output-dependence (aka WAW).
@ Order
Any other ordering dependency.
@ Anti
A register anti-dependence (aka WAR).
@ Data
Regular data dependence (aka true-dependence).
Scheduling unit. This is a node in the scheduling DAG.
bool isSucc(const SUnit *N) const
Tests if node N is a successor of this node.
SmallVector< SDep, 4 > Succs
All sunit successors.
SmallVector< SDep, 4 > Preds
All sunit predecessors.
MachineInstr * getInstr() const
Returns the representative MachineInstr for this SUnit.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
VLIWPacketizerList(MachineFunction &MF, MachineLoopInfo &MLI, AAResults *AA)
void addMutation(std::unique_ptr< ScheduleDAGMutation > Mutation)
bool alias(const MachineInstr &MI1, const MachineInstr &MI2, bool UseTBAA=true) const
std::vector< MachineInstr * > CurrentPacketMIs
std::map< MachineInstr *, SUnit * > MIToSUnit
DFAPacketizer * ResourceTracker
std::pair< iterator, bool > insert(const ValueT &V)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI void finalizeBundle(MachineBasicBlock &MBB, MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI)
finalizeBundle - Finalize a machine instruction bundle which includes a sequence of instructions star...
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
std::string utohexstr(uint64_t X, bool LowerCase=false, unsigned Width=0)
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
FunctionPass * createHexagonPacketizer(bool Minimal)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
DWARFExpression::Operation Op
MCRegisterClass TargetRegisterClass