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"; }
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>());
133 addMutation(std::make_unique<HexagonSubtarget::HLXPseudoMutation>());
140 for (
auto &MO : FirstI.
operands()) {
141 if (!MO.isReg() || !MO.isDef())
157 InsertPt = std::next(BundleIt).getInstrIterator();
163 if (
MI.isBundledWithSucc()) {
170 MI.unbundleFromPred();
172 B.splice(InsertPt, &
B,
MI.getIterator());
178 for (++
I;
I !=
E &&
I->isBundledWithPred(); ++
I)
191 BundleIt->eraseFromParent();
200 HII = HST.getInstrInfo();
201 HRI = HST.getRegisterInfo();
202 auto &MLI = getAnalysis<MachineLoopInfoWrapperPass>().getLI();
203 auto *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
205 &getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI();
208 HII->genAllInsnTimingClasses(MF);
213 HexagonPacketizerList
Packetizer(MF, MLI, AA, MBPI, MinOnly);
226 for (MachineBasicBlock &MB : MF) {
233 if (HST.isTinyCoreWithDuplex())
234 HII->translateInstrsForDup(MF,
true);
237 for (
auto &MB : MF) {
238 auto Begin = MB.begin(),
End = MB.end();
239 while (Begin !=
End) {
243 while (RB !=
End && HII->isSchedulingBoundary(*RB, &MB, MF))
248 while (RE !=
End && !HII->isSchedulingBoundary(*RE, &MB, MF))
262 if (HST.isTinyCoreWithDuplex())
263 HII->translateInstrsForDup(MF,
false);
283 auto *ExtMI =
MF.CreateMachineInstr(HII->get(Hexagon::A4_ext),
DebugLoc());
285 if (Reserve && Avail)
287 MF.deleteMachineInstr(ExtMI);
294 if (DepReg == HRI->getRARegister())
297 if (HII->isDeallocRet(
MI))
298 if (DepReg == HRI->getFrameRegister() || DepReg == HRI->getStackRegister())
308 if (MO.isReg() && MO.getReg() == DepReg && !MO.isImplicit())
321 return MI.getOpcode() == Hexagon::J2_jump;
325 switch (
MI.getOpcode()) {
326 case Hexagon::Y2_barrier:
333 return MI.getDesc().isTerminator() ||
MI.getDesc().isCall();
340 for (
auto *CSR =
TRI->getCalleeSavedRegs(&MF); CSR && *CSR; ++CSR)
341 if (
MI.modifiesRegister(*CSR,
TRI))
352 if (NewRC == &Hexagon::PredRegsRegClass) {
353 if (HII->isHVXVec(
MI) &&
MI.mayStore())
355 return HII->isPredicated(
MI) && HII->getDotNewPredOp(
MI,
nullptr) > 0;
358 return HII->mayBeNewStore(
MI);
368 int CurOpcode = HII->getDotCurOp(
MI);
369 MI.setDesc(HII->get(CurOpcode));
377 if (HII->isDotCurInst(*BI)) {
382 for (
auto &MO : BI->operands())
383 if (MO.isReg() && MO.getReg() ==
MI->getOperand(0).getReg())
390 MI->setDesc(HII->get(HII->getNonDotCurOp(*
MI)));
398 if (!HII->isHVXVec(
MI))
400 if (!HII->isHVXVec(*MII))
404 if (HII->isDotCurInst(
MI) && !HII->mayBeCurLoad(
MI))
407 if (!HII->mayBeCurLoad(
MI))
416 dbgs() <<
"in packet\n";);
419 dbgs() <<
"Checking CUR against ";
423 bool FoundMatch =
false;
424 for (
auto &MO : MJ.operands())
425 if (MO.isReg() && MO.getReg() == DestReg)
434 if (BI->readsRegister(DepReg,
MF.getSubtarget().getRegisterInfo()))
451 if (RC == &Hexagon::PredRegsRegClass)
452 NewOpcode = HII->getDotNewPredOp(
MI,
MBPI);
454 NewOpcode = HII->getDotNewOp(
MI);
455 MI.setDesc(HII->get(NewOpcode));
460 int NewOpcode = HII->getDotOldOp(
MI);
461 MI.setDesc(HII->get(NewOpcode));
466 unsigned Opc =
MI.getOpcode();
468 case Hexagon::S2_storerd_io:
469 case Hexagon::S2_storeri_io:
470 case Hexagon::S2_storerh_io:
471 case Hexagon::S2_storerb_io:
476 unsigned FrameSize =
MF.getFrameInfo().getStackSize();
479 if (HII->isValidOffset(
Opc, NewOff)) {
487 unsigned Opc =
MI.getOpcode();
489 case Hexagon::S2_storerd_io:
490 case Hexagon::S2_storeri_io:
491 case Hexagon::S2_storerh_io:
492 case Hexagon::S2_storerb_io:
497 unsigned FrameSize =
MF.getFrameInfo().getStackSize();
510 if (!HII->getBaseAndOffsetPosition(
MI, BPI, OPI))
513 if (!HII->getBaseAndOffsetPosition(MJ, BPJ, OPJ))
521 for (
const auto &PI : SUI->
Preds)
523 (PI.getKind() !=
SDep::Data || PI.getReg() != Reg))
526 if (!HII->getIncrementValue(MJ, Incr))
529 int64_t
Offset =
MI.getOperand(OPI).getImm();
530 if (!HII->isValidOffset(
MI.getOpcode(),
Offset + Incr))
533 MI.getOperand(OPI).setImm(
Offset + Incr);
542 if (!HII->getBaseAndOffsetPosition(
MI, BP,
OP))
544 MI.getOperand(
OP).setImm(ChangedOffset);
572 for (
auto &MO :
MI.operands())
573 if (MO.isReg() && MO.isDef())
574 DefRegsSet.
insert(MO.getReg());
576 for (
auto &MO :
MI.operands())
577 if (MO.isReg() && MO.isUse() && DefRegsSet.
count(MO.getReg()))
583 assert(Op1.
isReg() &&
"Post increment operand has be to a register.");
586 if (
MI.getDesc().mayStore()) {
589 assert(Op0.
isReg() &&
"Post increment operand has be to a register.");
594 llvm_unreachable(
"mayLoad or mayStore not set for Post Increment operation");
600 return MI.getOperand(
MI.getNumOperands()-1);
604 unsigned Opc =
MI.getOpcode();
606 case Hexagon::L4_loadrd_ap:
607 case Hexagon::L4_loadrb_ap:
608 case Hexagon::L4_loadrh_ap:
609 case Hexagon::L4_loadrub_ap:
610 case Hexagon::L4_loadruh_ap:
611 case Hexagon::L4_loadri_ap:
619 return MI.getOperand(1);
642 if (!HII->mayBeNewStore(
MI))
655 if (PacketRC == &Hexagon::DoubleRegsRegClass)
668 if (HII->isPostIncrement(
MI) &&
673 if (HII->isPostIncrement(PacketMI) && PacketMI.
mayLoad() &&
688 if (HII->isPredicated(PacketMI)) {
689 if (!HII->isPredicated(
MI))
694 unsigned predRegNumSrc = 0;
695 unsigned predRegNumDst = 0;
699 for (
auto &MO : PacketMI.
operands()) {
702 predRegNumSrc = MO.getReg();
703 predRegClass = HRI->getMinimalPhysRegClass(predRegNumSrc);
704 if (predRegClass == &Hexagon::PredRegsRegClass)
707 assert((predRegClass == &Hexagon::PredRegsRegClass) &&
708 "predicate register not found in a predicated PacketMI instruction");
711 for (
auto &MO :
MI.operands()) {
714 predRegNumDst = MO.getReg();
715 predRegClass = HRI->getMinimalPhysRegClass(predRegNumDst);
716 if (predRegClass == &Hexagon::PredRegsRegClass)
719 assert((predRegClass == &Hexagon::PredRegsRegClass) &&
720 "predicate register not found in a predicated MI instruction");
730 if (predRegNumDst != predRegNumSrc ||
731 HII->isDotNewInst(PacketMI) != HII->isDotNewInst(
MI) ||
744 unsigned StartCheck = 0;
753 if (&TempMI != &PacketMI && !StartCheck)
757 if (&TempMI == &PacketMI)
760 for (
auto &MO :
MI.operands())
771 if (!HII->isPostIncrement(
MI)) {
772 for (
unsigned opNum = 0; opNum <
MI.getNumOperands()-1; opNum++) {
783 for (
auto &MO : PacketMI.
operands()) {
784 if (MO.isRegMask() && MO.clobbersPhysReg(DepReg))
786 if (!MO.isReg() || !MO.isDef() || !MO.isImplicit())
789 if (R == DepReg || HRI->isSuperRegister(DepReg, R))
798 for (
auto &MO :
MI.operands()) {
799 if (MO.isReg() && MO.isUse() && MO.isImplicit() && MO.getReg() == DepReg)
809 const SUnit *PacketSU,
unsigned DepReg,
811 if (!HII->mayBeNewStore(
MI))
826 for (
auto &MO :
I.operands()) {
827 if (CheckDef && MO.isRegMask() && MO.clobbersPhysReg(DepReg))
829 if (!MO.isReg() || MO.getReg() != DepReg || !MO.isImplicit())
831 if (CheckDef == MO.isDef())
842 if (HII->isDotNewInst(
MI) && !HII->mayBeNewStore(
MI))
871 if (RC == &Hexagon::PredRegsRegClass)
872 return HII->predCanBeUsedAsDotNew(PI, DepReg);
874 if (RC != &Hexagon::PredRegsRegClass && !HII->mayBeNewStore(
MI))
879 int NewOpcode = (RC != &Hexagon::PredRegsRegClass) ? HII->getDotNewOp(
MI) :
880 HII->getDotNewPredOp(
MI,
MBPI);
883 bool ResourcesAvailable =
ResourceTracker->canReserveResources(*NewMI);
884 MF.deleteMachineInstr(NewMI);
885 if (!ResourcesAvailable)
914 if (!HII->isPredicated(*
I))
923 if (PacketSU->
isSucc(PacketSUDep)) {
924 for (
unsigned i = 0; i < PacketSU->
Succs.size(); ++i) {
925 auto &Dep = PacketSU->
Succs[i];
926 if (Dep.getSUnit() == PacketSUDep && Dep.getKind() ==
SDep::Anti &&
927 Dep.getReg() == DepReg)
943 for (
auto &
Op :
MI.operands()) {
944 if (
Op.isReg() &&
Op.getReg() &&
Op.isUse() &&
945 Hexagon::PredRegsRegClass.contains(
Op.getReg()))
987 if (PacketSU->
isSucc(SU)) {
988 for (
unsigned i = 0; i < PacketSU->
Succs.size(); ++i) {
989 auto Dep = PacketSU->
Succs[i];
994 if (Dep.getSUnit() == SU && Dep.getKind() ==
SDep::Data &&
995 Hexagon::PredRegsRegClass.contains(Dep.getReg())) {
1014 return PReg1 == PReg2 &&
1015 Hexagon::PredRegsRegClass.contains(PReg1) &&
1016 Hexagon::PredRegsRegClass.contains(PReg2) &&
1018 HII->isDotNewInst(MI1) == HII->isDotNewInst(MI2);
1024 PromotedToDotNew =
false;
1025 GlueToNewValueJump =
false;
1026 GlueAllocframeStore =
false;
1027 FoundSequentialDependence =
false;
1034 if (
MI.isDebugInstr())
1037 if (
MI.isCFIInstruction())
1041 if (
MI.isInlineAsm())
1044 if (
MI.isImplicitDef())
1051 return !IS->getUnits();
1059 if (
MI.isEHLabel() ||
MI.isCFIInstruction())
1073 if (HII->isSolo(
MI))
1076 if (
MI.getOpcode() == Hexagon::PATCHABLE_FUNCTION_ENTER ||
1077 MI.getOpcode() == Hexagon::PATCHABLE_FUNCTION_EXIT ||
1078 MI.getOpcode() == Hexagon::PATCHABLE_TAIL_CALL ||
1079 MI.getOpcode() == Hexagon::PATCHABLE_EVENT_CALL ||
1080 MI.getOpcode() == Hexagon::PATCHABLE_TYPED_EVENT_CALL)
1083 if (
MI.getOpcode() == Hexagon::A2_nop)
1112 if (
MI.isInlineAsm())
1129 else if (MO.isReg() && Hexagon::IntRegsRegClass.contains(MO.getReg()))
1131 else if (MO.isReg() &&
1132 Hexagon::DoubleRegsRegClass.contains(MO.getReg()))
1138 if ((getScalarUses(
MI) & 4) && getScalarUses(MJ))
1142 switch (
MI.getOpcode()) {
1143 case Hexagon::S2_storew_locked:
1144 case Hexagon::S4_stored_locked:
1145 case Hexagon::L2_loadw_locked:
1146 case Hexagon::L4_loadd_locked:
1147 case Hexagon::Y2_dccleana:
1148 case Hexagon::Y2_dccleaninva:
1149 case Hexagon::Y2_dcinva:
1150 case Hexagon::Y2_dczeroa:
1151 case Hexagon::Y4_l2fetch:
1152 case Hexagon::Y5_l2fetch: {
1156 unsigned TJ = HII.
getType(MJ);
1163 case Hexagon::LX_S16b_pseudo: {
1170 return HRI.isSuperRegisterEq(StReg, Def.getReg());
1191 for (
auto &
B :
MF) {
1195 BundleIt =
MI.getIterator();
1196 if (!
MI.isInsideBundle())
1205 bool InsertBeforeBundle;
1206 if (
MI.isInlineAsm())
1208 else if (
MI.isDebugInstr())
1209 InsertBeforeBundle =
true;
1220 unsigned Opc =
MI.getOpcode();
1222 case Hexagon::Y2_barrier:
1223 case Hexagon::Y2_dcfetchbo:
1224 case Hexagon::Y4_l2fetch:
1225 case Hexagon::Y5_l2fetch:
1238 if (HII->isPredicated(
I) || HII->isPredicated(J))
1241 BitVector DeadDefs(Hexagon::NUM_TARGET_REGS);
1242 for (
auto &MO :
I.operands()) {
1243 if (!MO.isReg() || !MO.isDef() || !MO.isDead())
1245 DeadDefs[MO.getReg()] =
true;
1249 if (!MO.isReg() || !MO.isDef() || !MO.isDead())
1252 if (R != Hexagon::USR_OVF && DeadDefs[R])
1262 if ((HII->isSaveCalleeSavedRegsCall(
I) &&
1264 (HII->isSaveCalleeSavedRegsCall(J) &&
1276 if (
MI.isCall() || HII->isDeallocRet(
MI) || HII->isNewValueJump(
MI))
1278 if (HII->isPredicated(
MI) && HII->isPredicatedNew(
MI) && HII->isJumpR(
MI))
1283 if (HII->isLoopN(
I) && isBadForLoopN(J))
1285 if (HII->isLoopN(J) && isBadForLoopN(
I))
1290 return HII->isDeallocRet(
I) &&
1308 if (!OpJ.isRegMask())
1310 assert((J.
isCall() || HII->isTailCall(J)) &&
"Regmask on a non-call");
1313 if (OpJ.clobbersPhysReg(OpI.getReg()))
1315 }
else if (OpI.isRegMask()) {
1327 bool StoreI =
I.mayStore(), StoreJ = J.
mayStore();
1328 if ((SysI && StoreJ) || (SysJ && StoreI))
1331 if (StoreI && StoreJ) {
1332 if (HII->isNewValueInst(J) || HII->isMemOp(J) || HII->isMemOp(
I))
1337 bool MopStI = HII->isMemOp(
I) || StoreI;
1338 bool MopStJ = HII->isMemOp(J) || StoreJ;
1339 if (MopStI && MopStJ)
1343 return (StoreJ && HII->isDeallocRet(
I)) || (StoreI && HII->isDeallocRet(J));
1356 IgnoreDepMIs.clear();
1388 if (NextMII !=
I.getParent()->end() && HII->isNewValueJump(*NextMII)) {
1391 bool secondRegMatch =
false;
1395 if (NOp1.
isReg() &&
I.getOperand(0).getReg() == NOp1.
getReg())
1396 secondRegMatch =
true;
1412 if (PI->getOpcode() == Hexagon::S2_allocframe || PI->mayStore() ||
1413 HII->isLoopN(*PI)) {
1419 if (OpR.
isReg() && PI->modifiesRegister(OpR.
getReg(), HRI)) {
1425 GlueToNewValueJump =
true;
1434 for (
unsigned i = 0; i < SUJ->
Succs.size(); ++i) {
1435 if (FoundSequentialDependence)
1438 if (SUJ->
Succs[i].getSUnit() != SUI)
1457 unsigned DepReg = 0;
1460 DepReg = SUJ->
Succs[i].getReg();
1461 RC = HRI->getMinimalPhysRegClass(DepReg);
1464 if (
I.isCall() || HII->isJumpR(
I) ||
I.isReturn() || HII->isTailCall(
I)) {
1478 if (DepType ==
SDep::Data && HII->isDotCurInst(J)) {
1479 if (HII->isHVXVec(
I))
1487 PromotedToDotNew =
true;
1489 FoundSequentialDependence =
true;
1493 if (HII->isNewValueJump(
I))
1499 if (HII->isPredicated(
I) && HII->isPredicated(J) &&
1513 auto Itr =
find(IgnoreDepMIs, &J);
1514 if (Itr != IgnoreDepMIs.end()) {
1518 IgnoreDepMIs.push_back(&
I);
1530 if (
I.isConditionalBranch() && DepType !=
SDep::Data &&
1535 FoundSequentialDependence =
true;
1549 FoundSequentialDependence =
true;
1555 bool LoadI =
I.mayLoad(), StoreI =
I.mayStore();
1556 bool NVStoreJ = HII->isNewValueStore(J);
1557 bool NVStoreI = HII->isNewValueStore(
I);
1558 bool IsVecJ = HII->isHVXVec(J) || HII->isHLXVec(J);
1559 bool IsVecI = HII->isHVXVec(
I) || HII->isHLXVec(
I);
1563 if (LoadJ && LoadI && HII->isPureSlot0(J)) {
1564 FoundSequentialDependence =
true;
1569 ((LoadJ && StoreI && !NVStoreI) ||
1570 (StoreJ && LoadI && !NVStoreJ)) &&
1571 (J.
getOpcode() != Hexagon::S2_allocframe &&
1572 I.getOpcode() != Hexagon::S2_allocframe) &&
1573 (J.
getOpcode() != Hexagon::L2_deallocframe &&
1574 I.getOpcode() != Hexagon::L2_deallocframe) &&
1575 (!HII->isMemOp(J) && !HII->isMemOp(
I)) && (!IsVecJ && !IsVecI))
1578 if (StoreJ && LoadI &&
alias(J,
I)) {
1579 FoundSequentialDependence =
true;
1584 if (!LoadJ || (!LoadI && !StoreI)) {
1587 FoundSequentialDependence =
true;
1602 unsigned Opc =
I.getOpcode();
1604 case Hexagon::S2_storerd_io:
1605 case Hexagon::S2_storeri_io:
1606 case Hexagon::S2_storerh_io:
1607 case Hexagon::S2_storerb_io:
1608 if (
I.getOperand(0).getReg() == HRI->getStackRegister()) {
1614 if (GlueAllocframeStore)
1634 if (
Op.isReg() &&
Op.isDef()) {
1638 }
else if (!
Op.isRegMask()) {
1642 FoundSequentialDependence =
true;
1656 if (DepType !=
SDep::Anti ||
I.getOpcode() == Hexagon::LX_L16b_pseudo) {
1657 FoundSequentialDependence =
true;
1662 if (FoundSequentialDependence) {
1677 if (Coexist && !Dependence)
1682 if (PromotedToDotNew)
1689 if (GlueAllocframeStore) {
1691 GlueAllocframeStore =
false;
1697 if (GlueToNewValueJump) {
1700 GlueToNewValueJump =
false;
1708 FoundSequentialDependence =
false;
1718 bool FoundLoad =
false;
1719 bool FoundStore =
false;
1722 unsigned Opc = MJ->getOpcode();
1723 if (
Opc == Hexagon::S2_allocframe ||
Opc == Hexagon::L2_deallocframe)
1725 if (HII->isMemOp(*MJ))
1729 if (MJ->mayStore() && !HII->isNewValueStore(*MJ))
1732 return FoundLoad && FoundStore;
1742 PacketStalls =
false;
1743 PacketStallCycles = 0;
1746 PacketStallCycles = std::max(PacketStallCycles,
calcStall(
MI));
1748 if (
MI.isImplicitDef()) {
1756 bool ExtMI = HII->isExtended(
MI) || HII->isConstExtended(
MI);
1759 if (GlueToNewValueJump) {
1769 bool ExtNvjMI = HII->isExtended(NvjMI) || HII->isConstExtended(NvjMI);
1776 if (Good && ExtNvjMI)
1802 if (PromotedToDotNew)
1804 if (GlueAllocframeStore) {
1806 GlueAllocframeStore =
false;
1821 dbgs() <<
"Finalizing packet:\n";
1837 OldPacketMIs.clear();
1840 for (
auto &
I :
make_range(HII->expandVGatherPseudo(*
MI), NextMI))
1841 OldPacketMIs.push_back(&
I);
1845 if (OldPacketMIs.size() > 1) {
1849 auto BundleMII = std::prev(FirstMI);
1850 if (memShufDisabled)
1851 HII->setBundleNoShuf(BundleMII);
1856 PacketHasDuplex =
false;
1857 PacketHasSLOT0OnlyInsn =
false;
1883 PacketHasSLOT0OnlyInsn |= HII->isPureSlot0(*MJ);
1885 int Opcode = HII->getDuplexOpcode(
MI,
false);
1889 if (HII->isDuplexPair(
MI, *MJ) && !PacketHasSLOT0OnlyInsn) {
1890 PacketHasDuplex =
true;
1897 MIRef.
setDesc(HII->get(Opcode));
1908 return HII->isTmpLoadPseudo(
I) || HII->isNewStorePseudo(
I);
1910 bool HasConstExt = HII->isConstExtended(
MI);
1911 bool HasPseudo = IsHLXLdStPseudo(
MI);
1913 HasConstExt |= HII->isConstExtended(*MJ);
1914 HasPseudo |= IsHLXLdStPseudo(*MJ);
1916 if (HasConstExt && HasPseudo)
1932 if (!OldPacketMIs.empty()) {
1933 auto *OldBB = OldPacketMIs.front()->getParent();
1934 auto *ThisBB =
I.getParent();
1935 if (
MLI->getLoopFor(OldBB) !=
MLI->getLoopFor(ThisBB))
1966 for (
auto &Pred : SUI->
Preds)
1967 if (Pred.getSUnit() == SUJ)
1968 if ((Pred.getLatency() == 0 && Pred.isAssignedRegDep()) ||
1969 HII->isNewValueJump(
I) || HII->isToBeScheduledASAP(*J,
I))
1975 for (
auto *J : OldPacketMIs) {
1977 for (
auto &Pred : SUI->
Preds)
1978 if (Pred.getSUnit() == SUJ && Pred.getLatency() > 1)
1979 return Pred.getLatency();
1991 return Latency > PacketStallCycles;
2000 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)
Remove Loads Into Fake Uses
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 isHLXVec(const MachineInstr &MI) const
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
const HexagonRegisterInfo & getRegisterInfo() 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...
filtered_mop_range all_defs()
Returns an iterator range over all operands that are (explicit or implicit) register defs.
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...
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
FunctionPass * createHexagonPacketizer(bool Minimal)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
DWARFExpression::Operation Op
@ End
Run the machine verifier once, at the end of the pipeline.
MCRegisterClass TargetRegisterClass