40#define GEN_CHECK_COMPRESS_INSTR
41#include "RISCVGenCompressInstEmitter.inc"
43#define GET_INSTRINFO_CTOR_DTOR
44#define GET_INSTRINFO_NAMED_OPS
45#include "RISCVGenInstrInfo.inc"
47#define DEBUG_TYPE "riscv-instr-info"
49 "Number of registers within vector register groups spilled");
51 "Number of registers within vector register groups reloaded");
55 cl::desc(
"Prefer whole register move for vector registers."));
58 "riscv-force-machine-combiner-strategy",
cl::Hidden,
59 cl::desc(
"Force machine combiner to use a specific strategy for machine "
60 "trace metrics evaluation."),
65 "MinInstrCount strategy.")));
71#define GET_RISCVVPseudosTable_IMPL
72#include "RISCVGenSearchableTables.inc"
78#define GET_RISCVMaskedPseudosTable_IMPL
79#include "RISCVGenSearchableTables.inc"
87#define GET_INSTRINFO_HELPERS
88#include "RISCVGenInstrInfo.inc"
91 if (
STI.hasStdExtZca())
100 int &FrameIndex)
const {
110 case RISCV::VL1RE8_V:
111 case RISCV::VL1RE16_V:
112 case RISCV::VL1RE32_V:
113 case RISCV::VL1RE64_V:
116 case RISCV::VL2RE8_V:
117 case RISCV::VL2RE16_V:
118 case RISCV::VL2RE32_V:
119 case RISCV::VL2RE64_V:
122 case RISCV::VL4RE8_V:
123 case RISCV::VL4RE16_V:
124 case RISCV::VL4RE32_V:
125 case RISCV::VL4RE64_V:
128 case RISCV::VL8RE8_V:
129 case RISCV::VL8RE16_V:
130 case RISCV::VL8RE32_V:
131 case RISCV::VL8RE64_V:
139 switch (
MI.getOpcode()) {
163 case RISCV::VL1RE8_V:
164 case RISCV::VL2RE8_V:
165 case RISCV::VL4RE8_V:
166 case RISCV::VL8RE8_V:
167 if (!
MI.getOperand(1).isFI())
169 FrameIndex =
MI.getOperand(1).getIndex();
172 return MI.getOperand(0).getReg();
175 if (
MI.getOperand(1).isFI() &&
MI.getOperand(2).isImm() &&
176 MI.getOperand(2).getImm() == 0) {
177 FrameIndex =
MI.getOperand(1).getIndex();
178 return MI.getOperand(0).getReg();
185 int &FrameIndex)
const {
193 switch (
MI.getOpcode()) {
218 if (!
MI.getOperand(1).isFI())
220 FrameIndex =
MI.getOperand(1).getIndex();
223 return MI.getOperand(0).getReg();
226 if (
MI.getOperand(1).isFI() &&
MI.getOperand(2).isImm() &&
227 MI.getOperand(2).getImm() == 0) {
228 FrameIndex =
MI.getOperand(1).getIndex();
229 return MI.getOperand(0).getReg();
239 case RISCV::VFMV_V_F:
242 case RISCV::VFMV_S_F:
244 return MI.getOperand(1).isUndef();
252 return DstReg > SrcReg && (DstReg - SrcReg) < NumRegs;
263 assert(
MBBI->getOpcode() == TargetOpcode::COPY &&
264 "Unexpected COPY instruction.");
268 bool FoundDef =
false;
269 bool FirstVSetVLI =
false;
270 unsigned FirstSEW = 0;
273 if (
MBBI->isMetaInstruction())
276 if (RISCVInstrInfo::isVectorConfigInstr(*
MBBI)) {
286 unsigned FirstVType =
MBBI->getOperand(2).getImm();
291 if (FirstLMul != LMul)
296 if (!RISCVInstrInfo::isVLPreservingConfig(*
MBBI))
302 unsigned VType =
MBBI->getOperand(2).getImm();
320 }
else if (
MBBI->isInlineAsm() ||
MBBI->isCall()) {
322 }
else if (
MBBI->getNumDefs()) {
325 if (
MBBI->modifiesRegister(RISCV::VL,
nullptr))
331 if (!MO.isReg() || !MO.isDef())
333 if (!FoundDef &&
TRI->regsOverlap(MO.getReg(), SrcReg)) {
348 if (MO.getReg() != SrcReg)
389 uint16_t SrcEncoding =
TRI->getEncodingValue(SrcReg);
390 uint16_t DstEncoding =
TRI->getEncodingValue(DstReg);
392 assert(!Fractional &&
"It is impossible be fractional lmul here.");
393 unsigned NumRegs = NF * LMulVal;
399 SrcEncoding += NumRegs - 1;
400 DstEncoding += NumRegs - 1;
406 unsigned,
unsigned> {
414 uint16_t Diff = DstEncoding - SrcEncoding;
415 if (
I + 8 <= NumRegs && Diff >= 8 && SrcEncoding % 8 == 7 &&
416 DstEncoding % 8 == 7)
418 RISCV::PseudoVMV_V_V_M8, RISCV::PseudoVMV_V_I_M8};
419 if (
I + 4 <= NumRegs && Diff >= 4 && SrcEncoding % 4 == 3 &&
420 DstEncoding % 4 == 3)
422 RISCV::PseudoVMV_V_V_M4, RISCV::PseudoVMV_V_I_M4};
423 if (
I + 2 <= NumRegs && Diff >= 2 && SrcEncoding % 2 == 1 &&
424 DstEncoding % 2 == 1)
426 RISCV::PseudoVMV_V_V_M2, RISCV::PseudoVMV_V_I_M2};
429 RISCV::PseudoVMV_V_V_M1, RISCV::PseudoVMV_V_I_M1};
434 if (
I + 8 <= NumRegs && SrcEncoding % 8 == 0 && DstEncoding % 8 == 0)
436 RISCV::PseudoVMV_V_V_M8, RISCV::PseudoVMV_V_I_M8};
437 if (
I + 4 <= NumRegs && SrcEncoding % 4 == 0 && DstEncoding % 4 == 0)
439 RISCV::PseudoVMV_V_V_M4, RISCV::PseudoVMV_V_I_M4};
440 if (
I + 2 <= NumRegs && SrcEncoding % 2 == 0 && DstEncoding % 2 == 0)
442 RISCV::PseudoVMV_V_V_M2, RISCV::PseudoVMV_V_I_M2};
445 RISCV::PseudoVMV_V_V_M1, RISCV::PseudoVMV_V_I_M1};
448 while (
I != NumRegs) {
453 auto [LMulCopied, RegClass,
Opc, VVOpc, VIOpc] =
454 GetCopyInfo(SrcEncoding, DstEncoding);
458 if (LMul == LMulCopied &&
461 if (DefMBBI->getOpcode() == VIOpc)
468 RegClass, ReversedCopy ? (SrcEncoding - NumCopied + 1) : SrcEncoding);
470 RegClass, ReversedCopy ? (DstEncoding - NumCopied + 1) : DstEncoding);
478 MIB = MIB.add(DefMBBI->getOperand(2));
486 MIB.addImm(Log2SEW ? Log2SEW : 3);
498 SrcEncoding += (ReversedCopy ? -NumCopied : NumCopied);
499 DstEncoding += (ReversedCopy ? -NumCopied : NumCopied);
508 bool RenamableDest,
bool RenamableSrc)
const {
512 if (RISCV::GPRRegClass.
contains(DstReg, SrcReg)) {
519 if (RISCV::GPRF16RegClass.
contains(DstReg, SrcReg)) {
525 if (RISCV::GPRF32RegClass.
contains(DstReg, SrcReg)) {
531 if (RISCV::GPRPairRegClass.
contains(DstReg, SrcReg)) {
532 MCRegister EvenReg =
TRI->getSubReg(SrcReg, RISCV::sub_gpr_even);
533 MCRegister OddReg =
TRI->getSubReg(SrcReg, RISCV::sub_gpr_odd);
535 if (OddReg == RISCV::DUMMY_REG_PAIR_WITH_X0)
537 assert(DstReg != RISCV::X0_Pair &&
"Cannot write to X0_Pair");
541 TRI->getSubReg(DstReg, RISCV::sub_gpr_even))
542 .
addReg(EvenReg, KillFlag)
545 TRI->getSubReg(DstReg, RISCV::sub_gpr_odd))
552 if (RISCV::VCSRRegClass.
contains(SrcReg) &&
553 RISCV::GPRRegClass.
contains(DstReg)) {
555 .
addImm(RISCVSysReg::lookupSysRegByName(
TRI->getName(SrcReg))->Encoding)
560 if (RISCV::FPR16RegClass.
contains(DstReg, SrcReg)) {
562 if (
STI.hasStdExtZfh()) {
563 Opc = RISCV::FSGNJ_H;
566 (
STI.hasStdExtZfhmin() ||
STI.hasStdExtZfbfmin()) &&
567 "Unexpected extensions");
569 DstReg =
TRI->getMatchingSuperReg(DstReg, RISCV::sub_16,
570 &RISCV::FPR32RegClass);
571 SrcReg =
TRI->getMatchingSuperReg(SrcReg, RISCV::sub_16,
572 &RISCV::FPR32RegClass);
573 Opc = RISCV::FSGNJ_S;
577 .
addReg(SrcReg, KillFlag);
581 if (RISCV::FPR32RegClass.
contains(DstReg, SrcReg)) {
584 .
addReg(SrcReg, KillFlag);
588 if (RISCV::FPR64RegClass.
contains(DstReg, SrcReg)) {
591 .
addReg(SrcReg, KillFlag);
595 if (RISCV::FPR32RegClass.
contains(DstReg) &&
596 RISCV::GPRRegClass.
contains(SrcReg)) {
598 .
addReg(SrcReg, KillFlag);
602 if (RISCV::GPRRegClass.
contains(DstReg) &&
603 RISCV::FPR32RegClass.
contains(SrcReg)) {
605 .
addReg(SrcReg, KillFlag);
609 if (RISCV::FPR64RegClass.
contains(DstReg) &&
610 RISCV::GPRRegClass.
contains(SrcReg)) {
611 assert(
STI.getXLen() == 64 &&
"Unexpected GPR size");
613 .
addReg(SrcReg, KillFlag);
617 if (RISCV::GPRRegClass.
contains(DstReg) &&
618 RISCV::FPR64RegClass.
contains(SrcReg)) {
619 assert(
STI.getXLen() == 64 &&
"Unexpected GPR size");
621 .
addReg(SrcReg, KillFlag);
627 TRI->getCommonMinimalPhysRegClass(SrcReg, DstReg);
638 Register SrcReg,
bool IsKill,
int FI,
647 if (RISCV::GPRRegClass.hasSubClassEq(RC)) {
648 Opcode =
TRI->getRegSizeInBits(RISCV::GPRRegClass) == 32 ?
649 RISCV::SW : RISCV::SD;
650 }
else if (RISCV::GPRF16RegClass.hasSubClassEq(RC)) {
651 Opcode = RISCV::SH_INX;
652 }
else if (RISCV::GPRF32RegClass.hasSubClassEq(RC)) {
653 Opcode = RISCV::SW_INX;
654 }
else if (RISCV::GPRPairRegClass.hasSubClassEq(RC)) {
655 Opcode = RISCV::PseudoRV32ZdinxSD;
656 }
else if (RISCV::FPR16RegClass.hasSubClassEq(RC)) {
658 }
else if (RISCV::FPR32RegClass.hasSubClassEq(RC)) {
660 }
else if (RISCV::FPR64RegClass.hasSubClassEq(RC)) {
662 }
else if (RISCV::VRRegClass.hasSubClassEq(RC)) {
663 Opcode = RISCV::VS1R_V;
664 }
else if (RISCV::VRM2RegClass.hasSubClassEq(RC)) {
665 Opcode = RISCV::VS2R_V;
666 }
else if (RISCV::VRM4RegClass.hasSubClassEq(RC)) {
667 Opcode = RISCV::VS4R_V;
668 }
else if (RISCV::VRM8RegClass.hasSubClassEq(RC)) {
669 Opcode = RISCV::VS8R_V;
670 }
else if (RISCV::VRN2M1RegClass.hasSubClassEq(RC))
671 Opcode = RISCV::PseudoVSPILL2_M1;
672 else if (RISCV::VRN2M2RegClass.hasSubClassEq(RC))
673 Opcode = RISCV::PseudoVSPILL2_M2;
674 else if (RISCV::VRN2M4RegClass.hasSubClassEq(RC))
675 Opcode = RISCV::PseudoVSPILL2_M4;
676 else if (RISCV::VRN3M1RegClass.hasSubClassEq(RC))
677 Opcode = RISCV::PseudoVSPILL3_M1;
678 else if (RISCV::VRN3M2RegClass.hasSubClassEq(RC))
679 Opcode = RISCV::PseudoVSPILL3_M2;
680 else if (RISCV::VRN4M1RegClass.hasSubClassEq(RC))
681 Opcode = RISCV::PseudoVSPILL4_M1;
682 else if (RISCV::VRN4M2RegClass.hasSubClassEq(RC))
683 Opcode = RISCV::PseudoVSPILL4_M2;
684 else if (RISCV::VRN5M1RegClass.hasSubClassEq(RC))
685 Opcode = RISCV::PseudoVSPILL5_M1;
686 else if (RISCV::VRN6M1RegClass.hasSubClassEq(RC))
687 Opcode = RISCV::PseudoVSPILL6_M1;
688 else if (RISCV::VRN7M1RegClass.hasSubClassEq(RC))
689 Opcode = RISCV::PseudoVSPILL7_M1;
690 else if (RISCV::VRN8M1RegClass.hasSubClassEq(RC))
691 Opcode = RISCV::PseudoVSPILL8_M1;
731 if (RISCV::GPRRegClass.hasSubClassEq(RC)) {
732 Opcode =
TRI->getRegSizeInBits(RISCV::GPRRegClass) == 32 ?
733 RISCV::LW : RISCV::LD;
734 }
else if (RISCV::GPRF16RegClass.hasSubClassEq(RC)) {
735 Opcode = RISCV::LH_INX;
736 }
else if (RISCV::GPRF32RegClass.hasSubClassEq(RC)) {
737 Opcode = RISCV::LW_INX;
738 }
else if (RISCV::GPRPairRegClass.hasSubClassEq(RC)) {
739 Opcode = RISCV::PseudoRV32ZdinxLD;
740 }
else if (RISCV::FPR16RegClass.hasSubClassEq(RC)) {
742 }
else if (RISCV::FPR32RegClass.hasSubClassEq(RC)) {
744 }
else if (RISCV::FPR64RegClass.hasSubClassEq(RC)) {
746 }
else if (RISCV::VRRegClass.hasSubClassEq(RC)) {
747 Opcode = RISCV::VL1RE8_V;
748 }
else if (RISCV::VRM2RegClass.hasSubClassEq(RC)) {
749 Opcode = RISCV::VL2RE8_V;
750 }
else if (RISCV::VRM4RegClass.hasSubClassEq(RC)) {
751 Opcode = RISCV::VL4RE8_V;
752 }
else if (RISCV::VRM8RegClass.hasSubClassEq(RC)) {
753 Opcode = RISCV::VL8RE8_V;
754 }
else if (RISCV::VRN2M1RegClass.hasSubClassEq(RC))
755 Opcode = RISCV::PseudoVRELOAD2_M1;
756 else if (RISCV::VRN2M2RegClass.hasSubClassEq(RC))
757 Opcode = RISCV::PseudoVRELOAD2_M2;
758 else if (RISCV::VRN2M4RegClass.hasSubClassEq(RC))
759 Opcode = RISCV::PseudoVRELOAD2_M4;
760 else if (RISCV::VRN3M1RegClass.hasSubClassEq(RC))
761 Opcode = RISCV::PseudoVRELOAD3_M1;
762 else if (RISCV::VRN3M2RegClass.hasSubClassEq(RC))
763 Opcode = RISCV::PseudoVRELOAD3_M2;
764 else if (RISCV::VRN4M1RegClass.hasSubClassEq(RC))
765 Opcode = RISCV::PseudoVRELOAD4_M1;
766 else if (RISCV::VRN4M2RegClass.hasSubClassEq(RC))
767 Opcode = RISCV::PseudoVRELOAD4_M2;
768 else if (RISCV::VRN5M1RegClass.hasSubClassEq(RC))
769 Opcode = RISCV::PseudoVRELOAD5_M1;
770 else if (RISCV::VRN6M1RegClass.hasSubClassEq(RC))
771 Opcode = RISCV::PseudoVRELOAD6_M1;
772 else if (RISCV::VRN7M1RegClass.hasSubClassEq(RC))
773 Opcode = RISCV::PseudoVRELOAD7_M1;
774 else if (RISCV::VRN8M1RegClass.hasSubClassEq(RC))
775 Opcode = RISCV::PseudoVRELOAD8_M1;
813 if (
Ops.size() != 1 ||
Ops[0] != 1)
816 switch (
MI.getOpcode()) {
818 if (RISCVInstrInfo::isSEXT_W(
MI))
820 if (RISCVInstrInfo::isZEXT_W(
MI))
822 if (RISCVInstrInfo::isZEXT_B(
MI))
829 case RISCV::ZEXT_H_RV32:
830 case RISCV::ZEXT_H_RV64:
837 case RISCV::VMV_X_S: {
840 if (ST.getXLen() < (1U << Log2SEW))
855 case RISCV::VFMV_F_S: {
882 return BuildMI(*
MI.getParent(), InsertPt,
MI.getDebugLoc(),
get(*LoadOpc),
892 bool DstIsDead)
const {
908 bool SrcRenamable =
false;
912 bool LastItem = ++Num == Seq.
size();
917 switch (Inst.getOpndKind()) {
927 .
addReg(SrcReg, SrcRegState)
934 .
addReg(SrcReg, SrcRegState)
935 .
addReg(SrcReg, SrcRegState)
941 .
addReg(SrcReg, SrcRegState)
949 SrcRenamable = DstRenamable;
959 case RISCV::CV_BEQIMM:
961 case RISCV::QC_E_BEQI:
963 case RISCV::NDS_BEQC:
968 case RISCV::QC_E_BNEI:
969 case RISCV::CV_BNEIMM:
971 case RISCV::NDS_BNEC:
975 case RISCV::QC_E_BLTI:
979 case RISCV::QC_E_BGEI:
982 case RISCV::QC_BLTUI:
983 case RISCV::QC_E_BLTUI:
986 case RISCV::QC_BGEUI:
987 case RISCV::QC_E_BGEUI:
1019 "Unknown conditional branch");
1030 case RISCV::QC_MVEQ:
1031 return RISCV::QC_MVNE;
1032 case RISCV::QC_MVNE:
1033 return RISCV::QC_MVEQ;
1034 case RISCV::QC_MVLT:
1035 return RISCV::QC_MVGE;
1036 case RISCV::QC_MVGE:
1037 return RISCV::QC_MVLT;
1038 case RISCV::QC_MVLTU:
1039 return RISCV::QC_MVGEU;
1040 case RISCV::QC_MVGEU:
1041 return RISCV::QC_MVLTU;
1042 case RISCV::QC_MVEQI:
1043 return RISCV::QC_MVNEI;
1044 case RISCV::QC_MVNEI:
1045 return RISCV::QC_MVEQI;
1046 case RISCV::QC_MVLTI:
1047 return RISCV::QC_MVGEI;
1048 case RISCV::QC_MVGEI:
1049 return RISCV::QC_MVLTI;
1050 case RISCV::QC_MVLTUI:
1051 return RISCV::QC_MVGEUI;
1052 case RISCV::QC_MVGEUI:
1053 return RISCV::QC_MVLTUI;
1058 switch (SelectOpc) {
1077 case RISCV::Select_GPR_Using_CC_Imm5_Zibi:
1087 case RISCV::Select_GPR_Using_CC_SImm5_CV:
1092 return RISCV::CV_BEQIMM;
1094 return RISCV::CV_BNEIMM;
1097 case RISCV::Select_GPRNoX0_Using_CC_SImm5NonZero_QC:
1102 return RISCV::QC_BEQI;
1104 return RISCV::QC_BNEI;
1106 return RISCV::QC_BLTI;
1108 return RISCV::QC_BGEI;
1111 case RISCV::Select_GPRNoX0_Using_CC_UImm5NonZero_QC:
1116 return RISCV::QC_BLTUI;
1118 return RISCV::QC_BGEUI;
1121 case RISCV::Select_GPRNoX0_Using_CC_SImm16NonZero_QC:
1126 return RISCV::QC_E_BEQI;
1128 return RISCV::QC_E_BNEI;
1130 return RISCV::QC_E_BLTI;
1132 return RISCV::QC_E_BGEI;
1135 case RISCV::Select_GPRNoX0_Using_CC_UImm16NonZero_QC:
1140 return RISCV::QC_E_BLTUI;
1142 return RISCV::QC_E_BGEUI;
1145 case RISCV::Select_GPR_Using_CC_UImmLog2XLen_NDS:
1150 return RISCV::NDS_BBC;
1152 return RISCV::NDS_BBS;
1155 case RISCV::Select_GPR_Using_CC_UImm7_NDS:
1160 return RISCV::NDS_BEQC;
1162 return RISCV::NDS_BNEC;
1191 bool AllowModify)
const {
1192 TBB = FBB =
nullptr;
1197 if (
I ==
MBB.end() || !isUnpredicatedTerminator(*
I))
1203 int NumTerminators = 0;
1204 for (
auto J =
I.getReverse(); J !=
MBB.rend() && isUnpredicatedTerminator(*J);
1207 if (J->getDesc().isUnconditionalBranch() ||
1208 J->getDesc().isIndirectBranch()) {
1215 if (AllowModify && FirstUncondOrIndirectBr !=
MBB.end()) {
1216 while (std::next(FirstUncondOrIndirectBr) !=
MBB.end()) {
1217 std::next(FirstUncondOrIndirectBr)->eraseFromParent();
1220 I = FirstUncondOrIndirectBr;
1224 if (
I->getDesc().isIndirectBranch())
1228 if (
I->isPreISelOpcode())
1232 if (NumTerminators > 2)
1236 if (NumTerminators == 1 &&
I->getDesc().isUnconditionalBranch()) {
1242 if (NumTerminators == 1 &&
I->getDesc().isConditionalBranch()) {
1248 if (NumTerminators == 2 && std::prev(
I)->getDesc().isConditionalBranch() &&
1249 I->getDesc().isUnconditionalBranch()) {
1260 int *BytesRemoved)
const {
1267 if (!
I->getDesc().isUnconditionalBranch() &&
1268 !
I->getDesc().isConditionalBranch())
1274 I->eraseFromParent();
1278 if (
I ==
MBB.begin())
1281 if (!
I->getDesc().isConditionalBranch())
1287 I->eraseFromParent();
1300 assert(
TBB &&
"insertBranch must not be told to insert a fallthrough");
1302 "RISC-V branch conditions have two components!");
1336 assert(RS &&
"RegScavenger required for long branching");
1338 "new block should be inserted for expanding unconditional branch");
1341 "restore block should be inserted for restoring clobbered registers");
1350 "Branch offsets outside of the signed 32-bit range not supported");
1355 Register ScratchReg =
MRI.createVirtualRegister(&RISCV::GPRJALRRegClass);
1356 auto II =
MBB.end();
1362 RS->enterBasicBlockEnd(
MBB);
1364 RS->scavengeRegisterBackwards(RISCV::GPRRegClass,
MI.getIterator(),
1368 RS->setRegUsed(TmpGPR);
1373 TmpGPR =
STI.hasStdExtE() ? RISCV::X9 : RISCV::X27;
1376 if (FrameIndex == -1)
1381 TRI->eliminateFrameIndex(std::prev(
MI.getIterator()),
1384 MI.getOperand(1).setMBB(&RestoreBB);
1388 TRI->eliminateFrameIndex(RestoreBB.
back(),
1392 MRI.replaceRegWith(ScratchReg, TmpGPR);
1393 MRI.clearVirtRegs();
1398 assert((
Cond.size() == 3) &&
"Invalid branch condition!");
1403 Cond[0].setImm(RISCV::BNE);
1406 Cond[0].setImm(RISCV::BNEI);
1409 Cond[0].setImm(RISCV::BEQ);
1412 Cond[0].setImm(RISCV::BEQI);
1415 Cond[0].setImm(RISCV::BGE);
1418 Cond[0].setImm(RISCV::BLT);
1421 Cond[0].setImm(RISCV::BGEU);
1424 Cond[0].setImm(RISCV::BLTU);
1426 case RISCV::CV_BEQIMM:
1427 Cond[0].setImm(RISCV::CV_BNEIMM);
1429 case RISCV::CV_BNEIMM:
1430 Cond[0].setImm(RISCV::CV_BEQIMM);
1432 case RISCV::QC_BEQI:
1433 Cond[0].setImm(RISCV::QC_BNEI);
1435 case RISCV::QC_BNEI:
1436 Cond[0].setImm(RISCV::QC_BEQI);
1438 case RISCV::QC_BGEI:
1439 Cond[0].setImm(RISCV::QC_BLTI);
1441 case RISCV::QC_BLTI:
1442 Cond[0].setImm(RISCV::QC_BGEI);
1444 case RISCV::QC_BGEUI:
1445 Cond[0].setImm(RISCV::QC_BLTUI);
1447 case RISCV::QC_BLTUI:
1448 Cond[0].setImm(RISCV::QC_BGEUI);
1450 case RISCV::QC_E_BEQI:
1451 Cond[0].setImm(RISCV::QC_E_BNEI);
1453 case RISCV::QC_E_BNEI:
1454 Cond[0].setImm(RISCV::QC_E_BEQI);
1456 case RISCV::QC_E_BGEI:
1457 Cond[0].setImm(RISCV::QC_E_BLTI);
1459 case RISCV::QC_E_BLTI:
1460 Cond[0].setImm(RISCV::QC_E_BGEI);
1462 case RISCV::QC_E_BGEUI:
1463 Cond[0].setImm(RISCV::QC_E_BLTUI);
1465 case RISCV::QC_E_BLTUI:
1466 Cond[0].setImm(RISCV::QC_E_BGEUI);
1468 case RISCV::NDS_BBC:
1469 Cond[0].setImm(RISCV::NDS_BBS);
1471 case RISCV::NDS_BBS:
1472 Cond[0].setImm(RISCV::NDS_BBC);
1474 case RISCV::NDS_BEQC:
1475 Cond[0].setImm(RISCV::NDS_BNEC);
1477 case RISCV::NDS_BNEC:
1478 Cond[0].setImm(RISCV::NDS_BEQC);
1488 if (
MI->getOpcode() == RISCV::ADDI &&
MI->getOperand(1).isReg() &&
1489 MI->getOperand(1).getReg() == RISCV::X0) {
1490 Imm =
MI->getOperand(2).getImm();
1503 if (Reg == RISCV::X0) {
1507 return Reg.isVirtual() &&
isLoadImm(
MRI.getVRegDef(Reg), Imm);
1511 bool IsSigned =
false;
1512 bool IsEquality =
false;
1513 switch (
MI.getOpcode()) {
1549 MI.eraseFromParent();
1575 auto searchConst = [&](int64_t C1) ->
Register {
1577 auto DefC1 = std::find_if(++
II, E, [&](
const MachineInstr &
I) ->
bool {
1580 I.getOperand(0).getReg().isVirtual();
1583 return DefC1->getOperand(0).getReg();
1596 MRI.hasOneUse(LHS.getReg()) && (IsSigned || C0 != -1)) {
1598 if (
Register RegZ = searchConst(C0 + 1)) {
1605 MRI.clearKillFlags(RegZ);
1606 MI.eraseFromParent();
1617 MRI.hasOneUse(RHS.getReg())) {
1619 if (
Register RegZ = searchConst(C0 - 1)) {
1626 MRI.clearKillFlags(RegZ);
1627 MI.eraseFromParent();
1637 assert(
MI.getDesc().isBranch() &&
"Unexpected opcode!");
1639 int NumOp =
MI.getNumExplicitOperands();
1640 return MI.getOperand(NumOp - 1).getMBB();
1644 int64_t BrOffset)
const {
1645 unsigned XLen =
STI.getXLen();
1652 case RISCV::NDS_BBC:
1653 case RISCV::NDS_BBS:
1654 case RISCV::NDS_BEQC:
1655 case RISCV::NDS_BNEC:
1665 case RISCV::CV_BEQIMM:
1666 case RISCV::CV_BNEIMM:
1667 case RISCV::QC_BEQI:
1668 case RISCV::QC_BNEI:
1669 case RISCV::QC_BGEI:
1670 case RISCV::QC_BLTI:
1671 case RISCV::QC_BLTUI:
1672 case RISCV::QC_BGEUI:
1673 case RISCV::QC_E_BEQI:
1674 case RISCV::QC_E_BNEI:
1675 case RISCV::QC_E_BGEI:
1676 case RISCV::QC_E_BLTI:
1677 case RISCV::QC_E_BLTUI:
1678 case RISCV::QC_E_BGEUI:
1681 case RISCV::PseudoBR:
1683 case RISCV::PseudoJump:
1694 case RISCV::ADD:
return RISCV::PseudoCCADD;
1695 case RISCV::SUB:
return RISCV::PseudoCCSUB;
1696 case RISCV::SLL:
return RISCV::PseudoCCSLL;
1697 case RISCV::SRL:
return RISCV::PseudoCCSRL;
1698 case RISCV::SRA:
return RISCV::PseudoCCSRA;
1699 case RISCV::AND:
return RISCV::PseudoCCAND;
1700 case RISCV::OR:
return RISCV::PseudoCCOR;
1701 case RISCV::XOR:
return RISCV::PseudoCCXOR;
1702 case RISCV::MAX:
return RISCV::PseudoCCMAX;
1703 case RISCV::MAXU:
return RISCV::PseudoCCMAXU;
1704 case RISCV::MIN:
return RISCV::PseudoCCMIN;
1705 case RISCV::MINU:
return RISCV::PseudoCCMINU;
1706 case RISCV::MUL:
return RISCV::PseudoCCMUL;
1708 case RISCV::ADDI:
return RISCV::PseudoCCADDI;
1709 case RISCV::SLLI:
return RISCV::PseudoCCSLLI;
1710 case RISCV::SRLI:
return RISCV::PseudoCCSRLI;
1711 case RISCV::SRAI:
return RISCV::PseudoCCSRAI;
1712 case RISCV::ANDI:
return RISCV::PseudoCCANDI;
1713 case RISCV::ORI:
return RISCV::PseudoCCORI;
1714 case RISCV::XORI:
return RISCV::PseudoCCXORI;
1716 case RISCV::ADDW:
return RISCV::PseudoCCADDW;
1717 case RISCV::SUBW:
return RISCV::PseudoCCSUBW;
1718 case RISCV::SLLW:
return RISCV::PseudoCCSLLW;
1719 case RISCV::SRLW:
return RISCV::PseudoCCSRLW;
1720 case RISCV::SRAW:
return RISCV::PseudoCCSRAW;
1722 case RISCV::ADDIW:
return RISCV::PseudoCCADDIW;
1723 case RISCV::SLLIW:
return RISCV::PseudoCCSLLIW;
1724 case RISCV::SRLIW:
return RISCV::PseudoCCSRLIW;
1725 case RISCV::SRAIW:
return RISCV::PseudoCCSRAIW;
1727 case RISCV::ANDN:
return RISCV::PseudoCCANDN;
1728 case RISCV::ORN:
return RISCV::PseudoCCORN;
1729 case RISCV::XNOR:
return RISCV::PseudoCCXNOR;
1731 case RISCV::NDS_BFOS:
return RISCV::PseudoCCNDS_BFOS;
1732 case RISCV::NDS_BFOZ:
return RISCV::PseudoCCNDS_BFOZ;
1736 return RISCV::INSTRUCTION_LIST_END;
1745 if (!
Reg.isVirtual())
1747 if (!
MRI.hasOneNonDBGUse(
Reg))
1753 if (!STI.hasShortForwardBranchIMinMax() &&
1754 (
MI->getOpcode() == RISCV::MAX ||
MI->getOpcode() == RISCV::MIN ||
1755 MI->getOpcode() == RISCV::MINU ||
MI->getOpcode() == RISCV::MAXU))
1758 if (!STI.hasShortForwardBranchIMul() &&
MI->getOpcode() == RISCV::MUL)
1765 if (
MI->getOpcode() == RISCV::ADDI &&
MI->getOperand(1).isReg() &&
1766 MI->getOperand(1).getReg() == RISCV::X0)
1771 if (MO.isFI() || MO.isCPI() || MO.isJTI())
1781 if (MO.getReg().isPhysical() && !
MRI.isConstantPhysReg(MO.getReg()))
1784 bool DontMoveAcrossStores =
true;
1785 if (!
MI->isSafeToMove(DontMoveAcrossStores))
1792 unsigned &TrueOp,
unsigned &FalseOp,
1793 bool &Optimizable)
const {
1794 assert(
MI.getOpcode() == RISCV::PseudoCCMOVGPR &&
1795 "Unknown select instruction");
1805 Cond.push_back(
MI.getOperand(1));
1806 Cond.push_back(
MI.getOperand(2));
1807 Cond.push_back(
MI.getOperand(3));
1809 Optimizable =
STI.hasShortForwardBranchOpt();
1816 bool PreferFalse)
const {
1817 assert(
MI.getOpcode() == RISCV::PseudoCCMOVGPR &&
1818 "Unknown select instruction");
1819 if (!
STI.hasShortForwardBranchOpt())
1825 bool Invert = !
DefMI;
1833 Register DestReg =
MI.getOperand(0).getReg();
1835 if (!
MRI.constrainRegClass(DestReg, PreviousClass))
1839 assert(PredOpc != RISCV::INSTRUCTION_LIST_END &&
"Unexpected opcode!");
1846 NewMI.
add(
MI.getOperand(1));
1847 NewMI.
add(
MI.getOperand(2));
1856 NewMI.
add(FalseReg);
1871 if (
DefMI->getParent() !=
MI.getParent())
1875 DefMI->eraseFromParent();
1880 if (
MI.isMetaInstruction())
1883 unsigned Opcode =
MI.getOpcode();
1885 if (Opcode == TargetOpcode::INLINEASM ||
1886 Opcode == TargetOpcode::INLINEASM_BR) {
1888 return getInlineAsmLength(
MI.getOperand(0).getSymbolName(),
1892 if (!
MI.memoperands_empty()) {
1895 if (
STI.hasStdExtZca()) {
1896 if (isCompressibleInst(
MI,
STI))
1904 if (Opcode == TargetOpcode::BUNDLE)
1905 return getInstBundleLength(
MI);
1907 if (
MI.getParent() &&
MI.getParent()->getParent()) {
1908 if (isCompressibleInst(
MI,
STI))
1913 case RISCV::PseudoMV_FPR16INX:
1914 case RISCV::PseudoMV_FPR32INX:
1916 return STI.hasStdExtZca() ? 2 : 4;
1917 case TargetOpcode::STACKMAP:
1920 case TargetOpcode::PATCHPOINT:
1923 case TargetOpcode::STATEPOINT: {
1927 return std::max(NumBytes, 8U);
1929 case TargetOpcode::PATCHABLE_FUNCTION_ENTER:
1930 case TargetOpcode::PATCHABLE_FUNCTION_EXIT:
1931 case TargetOpcode::PATCHABLE_TAIL_CALL: {
1934 if (Opcode == TargetOpcode::PATCHABLE_FUNCTION_ENTER &&
1935 F.hasFnAttribute(
"patchable-function-entry")) {
1937 if (
F.getFnAttribute(
"patchable-function-entry")
1939 .getAsInteger(10, Num))
1940 return get(Opcode).getSize();
1943 return (
STI.hasStdExtZca() ? 2 : 4) * Num;
1947 return STI.is64Bit() ? 68 : 44;
1950 return get(Opcode).getSize();
1954unsigned RISCVInstrInfo::getInstBundleLength(
const MachineInstr &
MI)
const {
1958 while (++
I != E &&
I->isInsideBundle()) {
1959 assert(!
I->isBundle() &&
"No nested bundle!");
1966 const unsigned Opcode =
MI.getOpcode();
1970 case RISCV::FSGNJ_D:
1971 case RISCV::FSGNJ_S:
1972 case RISCV::FSGNJ_H:
1973 case RISCV::FSGNJ_D_INX:
1974 case RISCV::FSGNJ_D_IN32X:
1975 case RISCV::FSGNJ_S_INX:
1976 case RISCV::FSGNJ_H_INX:
1978 return MI.getOperand(1).isReg() &&
MI.getOperand(2).isReg() &&
1979 MI.getOperand(1).getReg() ==
MI.getOperand(2).getReg();
1983 return (
MI.getOperand(1).isReg() &&
1984 MI.getOperand(1).getReg() == RISCV::X0) ||
1985 (
MI.getOperand(2).isImm() &&
MI.getOperand(2).getImm() == 0);
1987 return MI.isAsCheapAsAMove();
1990std::optional<DestSourcePair>
1994 switch (
MI.getOpcode()) {
2000 if (
MI.getOperand(1).isReg() &&
MI.getOperand(1).getReg() == RISCV::X0 &&
2001 MI.getOperand(2).isReg())
2003 if (
MI.getOperand(2).isReg() &&
MI.getOperand(2).getReg() == RISCV::X0 &&
2004 MI.getOperand(1).isReg())
2009 if (
MI.getOperand(1).isReg() &&
MI.getOperand(2).isImm() &&
2010 MI.getOperand(2).getImm() == 0)
2014 if (
MI.getOperand(2).isReg() &&
MI.getOperand(2).getReg() == RISCV::X0 &&
2015 MI.getOperand(1).isReg())
2019 case RISCV::SH1ADD_UW:
2021 case RISCV::SH2ADD_UW:
2023 case RISCV::SH3ADD_UW:
2024 if (
MI.getOperand(1).isReg() &&
MI.getOperand(1).getReg() == RISCV::X0 &&
2025 MI.getOperand(2).isReg())
2028 case RISCV::FSGNJ_D:
2029 case RISCV::FSGNJ_S:
2030 case RISCV::FSGNJ_H:
2031 case RISCV::FSGNJ_D_INX:
2032 case RISCV::FSGNJ_D_IN32X:
2033 case RISCV::FSGNJ_S_INX:
2034 case RISCV::FSGNJ_H_INX:
2036 if (
MI.getOperand(1).isReg() &&
MI.getOperand(2).isReg() &&
2037 MI.getOperand(1).getReg() ==
MI.getOperand(2).getReg())
2041 return std::nullopt;
2049 const auto &SchedModel =
STI.getSchedModel();
2050 return (!SchedModel.hasInstrSchedModel() || SchedModel.isOutOfOrder())
2062 RISCV::getNamedOperandIdx(Root.
getOpcode(), RISCV::OpName::frm);
2066 return RISCV::getNamedOperandIdx(
MI->getOpcode(),
2067 RISCV::OpName::frm) < 0;
2069 "New instructions require FRM whereas the old one does not have it");
2076 for (
auto *NewMI : InsInstrs) {
2078 if (
static_cast<unsigned>(RISCV::getNamedOperandIdx(
2079 NewMI->getOpcode(), RISCV::OpName::frm)) != NewMI->getNumOperands())
2121bool RISCVInstrInfo::isVectorAssociativeAndCommutative(
const MachineInstr &Inst,
2122 bool Invert)
const {
2123#define OPCODE_LMUL_CASE(OPC) \
2124 case RISCV::OPC##_M1: \
2125 case RISCV::OPC##_M2: \
2126 case RISCV::OPC##_M4: \
2127 case RISCV::OPC##_M8: \
2128 case RISCV::OPC##_MF2: \
2129 case RISCV::OPC##_MF4: \
2130 case RISCV::OPC##_MF8
2132#define OPCODE_LMUL_MASK_CASE(OPC) \
2133 case RISCV::OPC##_M1_MASK: \
2134 case RISCV::OPC##_M2_MASK: \
2135 case RISCV::OPC##_M4_MASK: \
2136 case RISCV::OPC##_M8_MASK: \
2137 case RISCV::OPC##_MF2_MASK: \
2138 case RISCV::OPC##_MF4_MASK: \
2139 case RISCV::OPC##_MF8_MASK
2144 Opcode = *InvOpcode;
2161#undef OPCODE_LMUL_MASK_CASE
2162#undef OPCODE_LMUL_CASE
2165bool RISCVInstrInfo::areRVVInstsReassociable(
const MachineInstr &Root,
2172 const TargetRegisterInfo *
TRI =
MRI->getTargetRegisterInfo();
2176 const uint64_t TSFlags =
Desc.TSFlags;
2178 auto checkImmOperand = [&](
unsigned OpIdx) {
2182 auto checkRegOperand = [&](
unsigned OpIdx) {
2190 if (!checkRegOperand(1))
2205 bool SeenMI2 =
false;
2206 for (
auto End =
MBB->
rend(), It = It1; It != End; ++It) {
2215 if (It->modifiesRegister(RISCV::V0,
TRI)) {
2216 Register SrcReg = It->getOperand(1).getReg();
2234 if (MI1VReg != SrcReg)
2243 assert(SeenMI2 &&
"Prev is expected to appear before Root");
2282bool RISCVInstrInfo::hasReassociableVectorSibling(
const MachineInstr &Inst,
2283 bool &Commuted)
const {
2287 "Expect the present of passthrough operand.");
2293 Commuted = !areRVVInstsReassociable(Inst, *MI1) &&
2294 areRVVInstsReassociable(Inst, *MI2);
2298 return areRVVInstsReassociable(Inst, *MI1) &&
2299 (isVectorAssociativeAndCommutative(*MI1) ||
2300 isVectorAssociativeAndCommutative(*MI1,
true)) &&
2307 if (!isVectorAssociativeAndCommutative(Inst) &&
2308 !isVectorAssociativeAndCommutative(Inst,
true))
2320 MI1 =
MRI.getUniqueVRegDef(Op1.
getReg());
2322 MI2 =
MRI.getUniqueVRegDef(Op2.
getReg());
2334 for (
unsigned I = 0;
I < 5; ++
I)
2340 bool &Commuted)
const {
2341 if (isVectorAssociativeAndCommutative(Inst) ||
2342 isVectorAssociativeAndCommutative(Inst,
true))
2343 return hasReassociableVectorSibling(Inst, Commuted);
2349 unsigned OperandIdx = Commuted ? 2 : 1;
2353 int16_t InstFrmOpIdx =
2354 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::frm);
2355 int16_t SiblingFrmOpIdx =
2356 RISCV::getNamedOperandIdx(Sibling.
getOpcode(), RISCV::OpName::frm);
2358 return (InstFrmOpIdx < 0 && SiblingFrmOpIdx < 0) ||
2363 bool Invert)
const {
2364 if (isVectorAssociativeAndCommutative(Inst, Invert))
2372 Opc = *InverseOpcode;
2417std::optional<unsigned>
2419#define RVV_OPC_LMUL_CASE(OPC, INV) \
2420 case RISCV::OPC##_M1: \
2421 return RISCV::INV##_M1; \
2422 case RISCV::OPC##_M2: \
2423 return RISCV::INV##_M2; \
2424 case RISCV::OPC##_M4: \
2425 return RISCV::INV##_M4; \
2426 case RISCV::OPC##_M8: \
2427 return RISCV::INV##_M8; \
2428 case RISCV::OPC##_MF2: \
2429 return RISCV::INV##_MF2; \
2430 case RISCV::OPC##_MF4: \
2431 return RISCV::INV##_MF4; \
2432 case RISCV::OPC##_MF8: \
2433 return RISCV::INV##_MF8
2435#define RVV_OPC_LMUL_MASK_CASE(OPC, INV) \
2436 case RISCV::OPC##_M1_MASK: \
2437 return RISCV::INV##_M1_MASK; \
2438 case RISCV::OPC##_M2_MASK: \
2439 return RISCV::INV##_M2_MASK; \
2440 case RISCV::OPC##_M4_MASK: \
2441 return RISCV::INV##_M4_MASK; \
2442 case RISCV::OPC##_M8_MASK: \
2443 return RISCV::INV##_M8_MASK; \
2444 case RISCV::OPC##_MF2_MASK: \
2445 return RISCV::INV##_MF2_MASK; \
2446 case RISCV::OPC##_MF4_MASK: \
2447 return RISCV::INV##_MF4_MASK; \
2448 case RISCV::OPC##_MF8_MASK: \
2449 return RISCV::INV##_MF8_MASK
2453 return std::nullopt;
2455 return RISCV::FSUB_H;
2457 return RISCV::FSUB_S;
2459 return RISCV::FSUB_D;
2461 return RISCV::FADD_H;
2463 return RISCV::FADD_S;
2465 return RISCV::FADD_D;
2482#undef RVV_OPC_LMUL_MASK_CASE
2483#undef RVV_OPC_LMUL_CASE
2488 bool DoRegPressureReduce) {
2504 if (DoRegPressureReduce && !
MRI.hasOneNonDBGUse(
MI->getOperand(0).getReg()))
2515 bool DoRegPressureReduce) {
2522 DoRegPressureReduce)) {
2528 DoRegPressureReduce)) {
2538 bool DoRegPressureReduce) {
2546 unsigned CombineOpc) {
2553 if (!
MI ||
MI->getParent() != &
MBB ||
MI->getOpcode() != CombineOpc)
2556 if (!
MRI.hasOneNonDBGUse(
MI->getOperand(0).getReg()))
2567 unsigned OuterShiftAmt) {
2573 if (InnerShiftAmt < OuterShiftAmt || (InnerShiftAmt - OuterShiftAmt) > 3)
2600 case RISCV::SH1ADD_UW:
2602 case RISCV::SH2ADD_UW:
2604 case RISCV::SH3ADD_UW:
2650 bool DoRegPressureReduce)
const {
2659 DoRegPressureReduce);
2667 return RISCV::FMADD_H;
2669 return RISCV::FMADD_S;
2671 return RISCV::FMADD_D;
2716 bool Mul1IsKill = Mul1.
isKill();
2717 bool Mul2IsKill = Mul2.
isKill();
2718 bool AddendIsKill = Addend.
isKill();
2727 BuildMI(*MF, MergedLoc,
TII->get(FusedOpc), DstReg)
2752 assert(OuterShiftAmt != 0 &&
"Unexpected opcode");
2759 assert(InnerShiftAmt >= OuterShiftAmt &&
"Unexpected shift amount");
2762 switch (InnerShiftAmt - OuterShiftAmt) {
2766 InnerOpc = RISCV::ADD;
2769 InnerOpc = RISCV::SH1ADD;
2772 InnerOpc = RISCV::SH2ADD;
2775 InnerOpc = RISCV::SH3ADD;
2783 Register NewVR =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
2793 InstrIdxForVirtReg.
insert(std::make_pair(NewVR, 0));
2810 DelInstrs, InstrIdxForVirtReg);
2837 for (
const auto &[Index, Operand] :
enumerate(
Desc.operands())) {
2838 unsigned OpType = Operand.OperandType;
2843 ErrInfo =
"Expected a non-register operand.";
2847 int64_t Imm = MO.
getImm();
2854#define CASE_OPERAND_UIMM(NUM) \
2855 case RISCVOp::OPERAND_UIMM##NUM: \
2856 Ok = isUInt<NUM>(Imm); \
2858#define CASE_OPERAND_SIMM(NUM) \
2859 case RISCVOp::OPERAND_SIMM##NUM: \
2860 Ok = isInt<NUM>(Imm); \
2892 Ok = (
isUInt<5>(Imm) && (Imm != 0)) || (Imm == 32);
2931 Ok = (
isUInt<5>(Imm) && Imm != 0) || Imm == -1;
2941 Ok = (
isInt<5>(Imm) && Imm != -16) || Imm == 16;
2972 Ok = Ok && Imm != 0;
2976 (Imm >= 0xfffe0 && Imm <= 0xfffff);
2979 Ok = Imm >= 0 && Imm <= 10;
2982 Ok = Imm >= 0 && Imm <= 7;
2985 Ok = Imm >= 1 && Imm <= 10;
2988 Ok = Imm >= 2 && Imm <= 14;
2997 Ok = Imm >= 0 && Imm <= 48 && Imm % 16 == 0;
3030 ErrInfo =
"Invalid immediate";
3040 if (!
Op.isImm() && !
Op.isReg()) {
3041 ErrInfo =
"Invalid operand type for VL operand";
3044 if (
Op.isReg() &&
Op.getReg().isValid()) {
3046 auto *RC =
MRI.getRegClass(
Op.getReg());
3047 if (!RISCV::GPRRegClass.hasSubClassEq(RC)) {
3048 ErrInfo =
"Invalid register class for VL operand";
3053 ErrInfo =
"VL operand w/o SEW operand?";
3059 if (!
MI.getOperand(
OpIdx).isImm()) {
3060 ErrInfo =
"SEW value expected to be an immediate";
3065 ErrInfo =
"Unexpected SEW value";
3068 unsigned SEW = Log2SEW ? 1 << Log2SEW : 8;
3070 ErrInfo =
"Unexpected SEW value";
3076 if (!
MI.getOperand(
OpIdx).isImm()) {
3077 ErrInfo =
"Policy operand expected to be an immediate";
3082 ErrInfo =
"Invalid Policy Value";
3086 ErrInfo =
"policy operand w/o VL operand?";
3094 if (!
MI.isRegTiedToUseOperand(0, &UseOpIdx)) {
3095 ErrInfo =
"policy operand w/o tied operand?";
3102 !
MI.readsRegister(RISCV::FRM,
nullptr)) {
3103 ErrInfo =
"dynamic rounding mode should read FRM";
3125 case RISCV::LD_RV32:
3135 case RISCV::SD_RV32:
3151 int64_t NewOffset = OldOffset + Disp;
3173 "Addressing mode not supported for folding");
3247 case RISCV::LD_RV32:
3250 case RISCV::SD_RV32:
3257 OffsetIsScalable =
false;
3273 if (BaseOps1.
front()->isIdenticalTo(*BaseOps2.
front()))
3281 if (MO1->getAddrSpace() != MO2->getAddrSpace())
3284 auto Base1 = MO1->getValue();
3285 auto Base2 = MO2->getValue();
3286 if (!Base1 || !Base2)
3294 return Base1 == Base2;
3300 int64_t Offset2,
bool OffsetIsScalable2,
unsigned ClusterSize,
3301 unsigned NumBytes)
const {
3304 if (!BaseOps1.
empty() && !BaseOps2.
empty()) {
3309 }
else if (!BaseOps1.
empty() || !BaseOps2.
empty()) {
3315 BaseOps1.
front()->getParent()->getMF()->getSubtarget().getCacheLineSize();
3321 return ClusterSize <= 4 && std::abs(Offset1 - Offset2) <
CacheLineSize;
3371 int64_t OffsetA = 0, OffsetB = 0;
3377 int LowOffset = std::min(OffsetA, OffsetB);
3378 int HighOffset = std::max(OffsetA, OffsetB);
3379 LocationSize LowWidth = (LowOffset == OffsetA) ? WidthA : WidthB;
3381 LowOffset + (
int)LowWidth.
getValue() <= HighOffset)
3388std::pair<unsigned, unsigned>
3391 return std::make_pair(TF & Mask, TF & ~Mask);
3397 static const std::pair<unsigned, const char *> TargetFlags[] = {
3398 {MO_CALL,
"riscv-call"},
3399 {MO_LO,
"riscv-lo"},
3400 {MO_HI,
"riscv-hi"},
3401 {MO_PCREL_LO,
"riscv-pcrel-lo"},
3402 {MO_PCREL_HI,
"riscv-pcrel-hi"},
3403 {MO_GOT_HI,
"riscv-got-hi"},
3404 {MO_TPREL_LO,
"riscv-tprel-lo"},
3405 {MO_TPREL_HI,
"riscv-tprel-hi"},
3406 {MO_TPREL_ADD,
"riscv-tprel-add"},
3407 {MO_TLS_GOT_HI,
"riscv-tls-got-hi"},
3408 {MO_TLS_GD_HI,
"riscv-tls-gd-hi"},
3409 {MO_TLSDESC_HI,
"riscv-tlsdesc-hi"},
3410 {MO_TLSDESC_LOAD_LO,
"riscv-tlsdesc-load-lo"},
3411 {MO_TLSDESC_ADD_LO,
"riscv-tlsdesc-add-lo"},
3412 {MO_TLSDESC_CALL,
"riscv-tlsdesc-call"}};
3420 if (!OutlineFromLinkOnceODRs &&
F.hasLinkOnceODRLinkage())
3433 unsigned &Flags)
const {
3452 return F.getFnAttribute(
"fentry-call").getValueAsBool() ||
3453 F.hasFnAttribute(
"patchable-function-entry");
3458 return MI.readsRegister(RegNo,
TRI) ||
3459 MI.getDesc().hasImplicitUseOfPhysReg(RegNo);
3464 return MI.modifiesRegister(RegNo,
TRI) ||
3465 MI.getDesc().hasImplicitDefOfPhysReg(RegNo);
3469 if (!
MBB.back().isReturn())
3492 if (
C.back().isReturn()) {
3494 "The candidate who uses return instruction must be outlined "
3507 return !
C.isAvailableAcrossAndOutOfSeq(RISCV::X5, *
TRI);
3510std::optional<std::unique_ptr<outliner::OutlinedFunction>>
3513 std::vector<outliner::Candidate> &RepeatedSequenceLocs,
3514 unsigned MinRepeats)
const {
3520 if (RepeatedSequenceLocs.size() < MinRepeats)
3521 return std::nullopt;
3525 unsigned InstrSizeCExt =
3527 unsigned CallOverhead = 0, FrameOverhead = 0;
3534 CallOverhead = 4 + InstrSizeCExt;
3541 FrameOverhead = InstrSizeCExt;
3544 for (
auto &
C : RepeatedSequenceLocs)
3545 C.setCallInfo(MOCI, CallOverhead);
3547 unsigned SequenceSize = 0;
3548 for (
auto &
MI : Candidate)
3551 return std::make_unique<outliner::OutlinedFunction>(
3552 RepeatedSequenceLocs, SequenceSize, FrameOverhead, MOCI);
3558 unsigned Flags)
const {
3562 MBB->getParent()->getSubtarget().getRegisterInfo();
3563 const auto &
F =
MI.getMF()->getFunction();
3566 if (
MI.isCFIInstruction())
3578 for (
const auto &MO :
MI.operands()) {
3583 (
MI.getMF()->getTarget().getFunctionSections() ||
F.hasComdat() ||
3584 F.hasSection() ||
F.getSectionPrefix()))
3602 auto I =
MBB.begin();
3604 for (;
I != E; ++
I) {
3605 if (
I->isCFIInstruction()) {
3606 I->removeFromParent();
3616 MBB.addLiveIn(RISCV::X5);
3631 .addGlobalAddress(M.getNamedValue(MF.
getName()),
3639 .addGlobalAddress(M.getNamedValue(MF.
getName()), 0,
3650 return std::nullopt;
3654 if (
MI.getOpcode() == RISCV::ADDI &&
MI.getOperand(1).isReg() &&
3655 MI.getOperand(2).isImm())
3656 return RegImmPair{
MI.getOperand(1).getReg(),
MI.getOperand(2).getImm()};
3658 return std::nullopt;
3666 std::string GenericComment =
3668 if (!GenericComment.empty())
3669 return GenericComment;
3673 return std::string();
3677 return std::string();
3679 std::string Comment;
3686 switch (OpInfo.OperandType) {
3689 unsigned Imm =
Op.getImm();
3694 unsigned Imm =
Op.getImm();
3700 unsigned Log2SEW =
Op.getImm();
3701 unsigned SEW = Log2SEW ? 1 << Log2SEW : 8;
3707 unsigned Policy =
Op.getImm();
3709 "Invalid Policy Value");
3719#define CASE_RVV_OPCODE_UNMASK_LMUL(OP, LMUL) \
3720 RISCV::Pseudo##OP##_##LMUL
3722#define CASE_RVV_OPCODE_MASK_LMUL(OP, LMUL) \
3723 RISCV::Pseudo##OP##_##LMUL##_MASK
3725#define CASE_RVV_OPCODE_LMUL(OP, LMUL) \
3726 CASE_RVV_OPCODE_UNMASK_LMUL(OP, LMUL): \
3727 case CASE_RVV_OPCODE_MASK_LMUL(OP, LMUL)
3729#define CASE_RVV_OPCODE_UNMASK_WIDEN(OP) \
3730 CASE_RVV_OPCODE_UNMASK_LMUL(OP, MF8): \
3731 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, MF4): \
3732 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, MF2): \
3733 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, M1): \
3734 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, M2): \
3735 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, M4)
3737#define CASE_RVV_OPCODE_UNMASK(OP) \
3738 CASE_RVV_OPCODE_UNMASK_WIDEN(OP): \
3739 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, M8)
3741#define CASE_RVV_OPCODE_MASK_WIDEN(OP) \
3742 CASE_RVV_OPCODE_MASK_LMUL(OP, MF8): \
3743 case CASE_RVV_OPCODE_MASK_LMUL(OP, MF4): \
3744 case CASE_RVV_OPCODE_MASK_LMUL(OP, MF2): \
3745 case CASE_RVV_OPCODE_MASK_LMUL(OP, M1): \
3746 case CASE_RVV_OPCODE_MASK_LMUL(OP, M2): \
3747 case CASE_RVV_OPCODE_MASK_LMUL(OP, M4)
3749#define CASE_RVV_OPCODE_MASK(OP) \
3750 CASE_RVV_OPCODE_MASK_WIDEN(OP): \
3751 case CASE_RVV_OPCODE_MASK_LMUL(OP, M8)
3753#define CASE_RVV_OPCODE_WIDEN(OP) \
3754 CASE_RVV_OPCODE_UNMASK_WIDEN(OP): \
3755 case CASE_RVV_OPCODE_MASK_WIDEN(OP)
3757#define CASE_RVV_OPCODE(OP) \
3758 CASE_RVV_OPCODE_UNMASK(OP): \
3759 case CASE_RVV_OPCODE_MASK(OP)
3763#define CASE_VMA_OPCODE_COMMON(OP, TYPE, LMUL) \
3764 RISCV::PseudoV##OP##_##TYPE##_##LMUL
3766#define CASE_VMA_OPCODE_LMULS(OP, TYPE) \
3767 CASE_VMA_OPCODE_COMMON(OP, TYPE, MF8): \
3768 case CASE_VMA_OPCODE_COMMON(OP, TYPE, MF4): \
3769 case CASE_VMA_OPCODE_COMMON(OP, TYPE, MF2): \
3770 case CASE_VMA_OPCODE_COMMON(OP, TYPE, M1): \
3771 case CASE_VMA_OPCODE_COMMON(OP, TYPE, M2): \
3772 case CASE_VMA_OPCODE_COMMON(OP, TYPE, M4): \
3773 case CASE_VMA_OPCODE_COMMON(OP, TYPE, M8)
3776#define CASE_VFMA_OPCODE_COMMON(OP, TYPE, LMUL, SEW) \
3777 RISCV::PseudoV##OP##_##TYPE##_##LMUL##_##SEW
3779#define CASE_VFMA_OPCODE_LMULS_M1(OP, TYPE, SEW) \
3780 CASE_VFMA_OPCODE_COMMON(OP, TYPE, M1, SEW): \
3781 case CASE_VFMA_OPCODE_COMMON(OP, TYPE, M2, SEW): \
3782 case CASE_VFMA_OPCODE_COMMON(OP, TYPE, M4, SEW): \
3783 case CASE_VFMA_OPCODE_COMMON(OP, TYPE, M8, SEW)
3785#define CASE_VFMA_OPCODE_LMULS_MF2(OP, TYPE, SEW) \
3786 CASE_VFMA_OPCODE_COMMON(OP, TYPE, MF2, SEW): \
3787 case CASE_VFMA_OPCODE_LMULS_M1(OP, TYPE, SEW)
3789#define CASE_VFMA_OPCODE_LMULS_MF4(OP, TYPE, SEW) \
3790 CASE_VFMA_OPCODE_COMMON(OP, TYPE, MF4, SEW): \
3791 case CASE_VFMA_OPCODE_LMULS_MF2(OP, TYPE, SEW)
3793#define CASE_VFMA_OPCODE_VV(OP) \
3794 CASE_VFMA_OPCODE_LMULS_MF4(OP, VV, E16): \
3795 case CASE_VFMA_OPCODE_LMULS_MF4(OP##_ALT, VV, E16): \
3796 case CASE_VFMA_OPCODE_LMULS_MF2(OP, VV, E32): \
3797 case CASE_VFMA_OPCODE_LMULS_M1(OP, VV, E64)
3799#define CASE_VFMA_SPLATS(OP) \
3800 CASE_VFMA_OPCODE_LMULS_MF4(OP, VFPR16, E16): \
3801 case CASE_VFMA_OPCODE_LMULS_MF4(OP##_ALT, VFPR16, E16): \
3802 case CASE_VFMA_OPCODE_LMULS_MF2(OP, VFPR32, E32): \
3803 case CASE_VFMA_OPCODE_LMULS_M1(OP, VFPR64, E64)
3807 unsigned &SrcOpIdx1,
3808 unsigned &SrcOpIdx2)
const {
3810 if (!
Desc.isCommutable())
3813 switch (
MI.getOpcode()) {
3814 case RISCV::TH_MVEQZ:
3815 case RISCV::TH_MVNEZ:
3819 if (
MI.getOperand(2).getReg() == RISCV::X0)
3822 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 1, 2);
3823 case RISCV::QC_SELECTIEQ:
3824 case RISCV::QC_SELECTINE:
3825 case RISCV::QC_SELECTIIEQ:
3826 case RISCV::QC_SELECTIINE:
3827 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 1, 2);
3828 case RISCV::QC_MVEQ:
3829 case RISCV::QC_MVNE:
3830 case RISCV::QC_MVLT:
3831 case RISCV::QC_MVGE:
3832 case RISCV::QC_MVLTU:
3833 case RISCV::QC_MVGEU:
3834 case RISCV::QC_MVEQI:
3835 case RISCV::QC_MVNEI:
3836 case RISCV::QC_MVLTI:
3837 case RISCV::QC_MVGEI:
3838 case RISCV::QC_MVLTUI:
3839 case RISCV::QC_MVGEUI:
3840 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 1, 4);
3841 case RISCV::TH_MULA:
3842 case RISCV::TH_MULAW:
3843 case RISCV::TH_MULAH:
3844 case RISCV::TH_MULS:
3845 case RISCV::TH_MULSW:
3846 case RISCV::TH_MULSH:
3848 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 2, 3);
3849 case RISCV::PseudoCCMOVGPRNoX0:
3850 case RISCV::PseudoCCMOVGPR:
3852 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 4, 5);
3879 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 2, 3);
3906 unsigned CommutableOpIdx1 = 1;
3907 unsigned CommutableOpIdx2 = 3;
3908 if (!fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, CommutableOpIdx1,
3929 if (SrcOpIdx1 != CommuteAnyOperandIndex && SrcOpIdx1 > 3)
3931 if (SrcOpIdx2 != CommuteAnyOperandIndex && SrcOpIdx2 > 3)
3935 if (SrcOpIdx1 != CommuteAnyOperandIndex &&
3936 SrcOpIdx2 != CommuteAnyOperandIndex && SrcOpIdx1 != 1 && SrcOpIdx2 != 1)
3942 if (SrcOpIdx1 == CommuteAnyOperandIndex ||
3943 SrcOpIdx2 == CommuteAnyOperandIndex) {
3946 unsigned CommutableOpIdx1 = SrcOpIdx1;
3947 if (SrcOpIdx1 == SrcOpIdx2) {
3950 CommutableOpIdx1 = 1;
3951 }
else if (SrcOpIdx1 == CommuteAnyOperandIndex) {
3953 CommutableOpIdx1 = SrcOpIdx2;
3958 unsigned CommutableOpIdx2;
3959 if (CommutableOpIdx1 != 1) {
3961 CommutableOpIdx2 = 1;
3963 Register Op1Reg =
MI.getOperand(CommutableOpIdx1).getReg();
3968 if (Op1Reg !=
MI.getOperand(2).getReg())
3969 CommutableOpIdx2 = 2;
3971 CommutableOpIdx2 = 3;
3976 if (!fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, CommutableOpIdx1,
3989#define CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, LMUL) \
3990 case RISCV::PseudoV##OLDOP##_##TYPE##_##LMUL: \
3991 Opc = RISCV::PseudoV##NEWOP##_##TYPE##_##LMUL; \
3994#define CASE_VMA_CHANGE_OPCODE_LMULS(OLDOP, NEWOP, TYPE) \
3995 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF8) \
3996 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF4) \
3997 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF2) \
3998 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M1) \
3999 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M2) \
4000 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M4) \
4001 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M8)
4004#define CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, LMUL, SEW) \
4005 case RISCV::PseudoV##OLDOP##_##TYPE##_##LMUL##_##SEW: \
4006 Opc = RISCV::PseudoV##NEWOP##_##TYPE##_##LMUL##_##SEW; \
4009#define CASE_VFMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, TYPE, SEW) \
4010 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M1, SEW) \
4011 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M2, SEW) \
4012 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M4, SEW) \
4013 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M8, SEW)
4015#define CASE_VFMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, TYPE, SEW) \
4016 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF2, SEW) \
4017 CASE_VFMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, TYPE, SEW)
4019#define CASE_VFMA_CHANGE_OPCODE_LMULS_MF4(OLDOP, NEWOP, TYPE, SEW) \
4020 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF4, SEW) \
4021 CASE_VFMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, TYPE, SEW)
4023#define CASE_VFMA_CHANGE_OPCODE_VV(OLDOP, NEWOP) \
4024 CASE_VFMA_CHANGE_OPCODE_LMULS_MF4(OLDOP, NEWOP, VV, E16) \
4025 CASE_VFMA_CHANGE_OPCODE_LMULS_MF4(OLDOP##_ALT, NEWOP##_ALT, VV, E16) \
4026 CASE_VFMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, VV, E32) \
4027 CASE_VFMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, VV, E64)
4029#define CASE_VFMA_CHANGE_OPCODE_SPLATS(OLDOP, NEWOP) \
4030 CASE_VFMA_CHANGE_OPCODE_LMULS_MF4(OLDOP, NEWOP, VFPR16, E16) \
4031 CASE_VFMA_CHANGE_OPCODE_LMULS_MF4(OLDOP##_ALT, NEWOP##_ALT, VFPR16, E16) \
4032 CASE_VFMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, VFPR32, E32) \
4033 CASE_VFMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, VFPR64, E64)
4039 unsigned OpIdx2)
const {
4042 return *
MI.getParent()->getParent()->CloneMachineInstr(&
MI);
4046 switch (
MI.getOpcode()) {
4047 case RISCV::TH_MVEQZ:
4048 case RISCV::TH_MVNEZ: {
4049 auto &WorkingMI = cloneIfNew(
MI);
4050 WorkingMI.setDesc(
get(
MI.getOpcode() == RISCV::TH_MVEQZ ? RISCV::TH_MVNEZ
4051 : RISCV::TH_MVEQZ));
4055 case RISCV::QC_SELECTIEQ:
4056 case RISCV::QC_SELECTINE:
4057 case RISCV::QC_SELECTIIEQ:
4058 case RISCV::QC_SELECTIINE:
4060 case RISCV::QC_MVEQ:
4061 case RISCV::QC_MVNE:
4062 case RISCV::QC_MVLT:
4063 case RISCV::QC_MVGE:
4064 case RISCV::QC_MVLTU:
4065 case RISCV::QC_MVGEU:
4066 case RISCV::QC_MVEQI:
4067 case RISCV::QC_MVNEI:
4068 case RISCV::QC_MVLTI:
4069 case RISCV::QC_MVGEI:
4070 case RISCV::QC_MVLTUI:
4071 case RISCV::QC_MVGEUI: {
4072 auto &WorkingMI = cloneIfNew(
MI);
4077 case RISCV::PseudoCCMOVGPRNoX0:
4078 case RISCV::PseudoCCMOVGPR: {
4082 auto &WorkingMI = cloneIfNew(
MI);
4083 WorkingMI.getOperand(3).setImm(CC);
4107 assert((OpIdx1 == 1 || OpIdx2 == 1) &&
"Unexpected opcode index");
4108 assert((OpIdx1 == 3 || OpIdx2 == 3) &&
"Unexpected opcode index");
4110 switch (
MI.getOpcode()) {
4133 auto &WorkingMI = cloneIfNew(
MI);
4134 WorkingMI.setDesc(
get(
Opc));
4144 assert((OpIdx1 == 1 || OpIdx2 == 1) &&
"Unexpected opcode index");
4147 if (OpIdx1 == 3 || OpIdx2 == 3) {
4149 switch (
MI.getOpcode()) {
4160 auto &WorkingMI = cloneIfNew(
MI);
4161 WorkingMI.setDesc(
get(
Opc));
4173#undef CASE_VMA_CHANGE_OPCODE_COMMON
4174#undef CASE_VMA_CHANGE_OPCODE_LMULS
4175#undef CASE_VFMA_CHANGE_OPCODE_COMMON
4176#undef CASE_VFMA_CHANGE_OPCODE_LMULS_M1
4177#undef CASE_VFMA_CHANGE_OPCODE_LMULS_MF2
4178#undef CASE_VFMA_CHANGE_OPCODE_LMULS_MF4
4179#undef CASE_VFMA_CHANGE_OPCODE_VV
4180#undef CASE_VFMA_CHANGE_OPCODE_SPLATS
4182#undef CASE_RVV_OPCODE_UNMASK_LMUL
4183#undef CASE_RVV_OPCODE_MASK_LMUL
4184#undef CASE_RVV_OPCODE_LMUL
4185#undef CASE_RVV_OPCODE_UNMASK_WIDEN
4186#undef CASE_RVV_OPCODE_UNMASK
4187#undef CASE_RVV_OPCODE_MASK_WIDEN
4188#undef CASE_RVV_OPCODE_MASK
4189#undef CASE_RVV_OPCODE_WIDEN
4190#undef CASE_RVV_OPCODE
4192#undef CASE_VMA_OPCODE_COMMON
4193#undef CASE_VMA_OPCODE_LMULS
4194#undef CASE_VFMA_OPCODE_COMMON
4195#undef CASE_VFMA_OPCODE_LMULS_M1
4196#undef CASE_VFMA_OPCODE_LMULS_MF2
4197#undef CASE_VFMA_OPCODE_LMULS_MF4
4198#undef CASE_VFMA_OPCODE_VV
4199#undef CASE_VFMA_SPLATS
4202 switch (
MI.getOpcode()) {
4210 if (
MI.getOperand(1).getReg() == RISCV::X0)
4211 commuteInstruction(
MI);
4213 if (
MI.getOperand(2).getReg() == RISCV::X0) {
4214 MI.getOperand(2).ChangeToImmediate(0);
4215 MI.setDesc(
get(RISCV::ADDI));
4219 if (
MI.getOpcode() == RISCV::XOR &&
4220 MI.getOperand(1).getReg() ==
MI.getOperand(2).getReg()) {
4221 MI.getOperand(1).setReg(RISCV::X0);
4222 MI.getOperand(2).ChangeToImmediate(0);
4223 MI.setDesc(
get(RISCV::ADDI));
4230 if (
MI.getOperand(1).getReg() == RISCV::X0) {
4231 MI.setDesc(
get(RISCV::ADDI));
4237 if (
MI.getOperand(2).getReg() == RISCV::X0) {
4238 MI.getOperand(2).ChangeToImmediate(0);
4239 MI.setDesc(
get(RISCV::ADDI));
4245 if (
MI.getOperand(2).getReg() == RISCV::X0) {
4246 MI.getOperand(2).ChangeToImmediate(0);
4247 MI.setDesc(
get(RISCV::ADDIW));
4254 if (
MI.getOperand(1).getReg() == RISCV::X0)
4255 commuteInstruction(
MI);
4257 if (
MI.getOperand(2).getReg() == RISCV::X0) {
4258 MI.getOperand(2).ChangeToImmediate(0);
4259 MI.setDesc(
get(RISCV::ADDIW));
4264 case RISCV::SH1ADD_UW:
4266 case RISCV::SH2ADD_UW:
4268 case RISCV::SH3ADD_UW:
4270 if (
MI.getOperand(1).getReg() == RISCV::X0) {
4271 MI.removeOperand(1);
4273 MI.setDesc(
get(RISCV::ADDI));
4277 if (
MI.getOperand(2).getReg() == RISCV::X0) {
4278 MI.removeOperand(2);
4279 unsigned Opc =
MI.getOpcode();
4280 if (
Opc == RISCV::SH1ADD_UW ||
Opc == RISCV::SH2ADD_UW ||
4281 Opc == RISCV::SH3ADD_UW) {
4283 MI.setDesc(
get(RISCV::SLLI_UW));
4287 MI.setDesc(
get(RISCV::SLLI));
4301 if (
MI.getOperand(1).getReg() == RISCV::X0 ||
4302 MI.getOperand(2).getReg() == RISCV::X0) {
4303 MI.getOperand(1).setReg(RISCV::X0);
4304 MI.getOperand(2).ChangeToImmediate(0);
4305 MI.setDesc(
get(RISCV::ADDI));
4311 if (
MI.getOperand(1).getReg() == RISCV::X0) {
4312 MI.getOperand(2).setImm(0);
4313 MI.setDesc(
get(RISCV::ADDI));
4321 if (
MI.getOperand(1).getReg() == RISCV::X0) {
4322 MI.getOperand(2).ChangeToImmediate(0);
4323 MI.setDesc(
get(RISCV::ADDI));
4327 if (
MI.getOperand(2).getReg() == RISCV::X0) {
4328 MI.getOperand(2).ChangeToImmediate(0);
4329 MI.setDesc(
get(RISCV::ADDI));
4337 if (
MI.getOperand(1).getReg() == RISCV::X0) {
4338 MI.getOperand(2).ChangeToImmediate(0);
4339 MI.setDesc(
get(RISCV::ADDI));
4349 case RISCV::SLLI_UW:
4351 if (
MI.getOperand(1).getReg() == RISCV::X0) {
4352 MI.getOperand(2).setImm(0);
4353 MI.setDesc(
get(RISCV::ADDI));
4361 if (
MI.getOperand(1).getReg() == RISCV::X0 &&
4362 MI.getOperand(2).getReg() == RISCV::X0) {
4363 MI.getOperand(2).ChangeToImmediate(0);
4364 MI.setDesc(
get(RISCV::ADDI));
4368 if (
MI.getOpcode() == RISCV::ADD_UW &&
4369 MI.getOperand(1).getReg() == RISCV::X0) {
4370 MI.removeOperand(1);
4372 MI.setDesc(
get(RISCV::ADDI));
4378 if (
MI.getOperand(1).getReg() == RISCV::X0) {
4379 MI.getOperand(2).setImm(
MI.getOperand(2).getImm() != 0);
4380 MI.setDesc(
get(RISCV::ADDI));
4386 case RISCV::ZEXT_H_RV32:
4387 case RISCV::ZEXT_H_RV64:
4390 if (
MI.getOperand(1).getReg() == RISCV::X0) {
4392 MI.setDesc(
get(RISCV::ADDI));
4401 if (
MI.getOperand(1).getReg() ==
MI.getOperand(2).getReg()) {
4402 MI.getOperand(2).ChangeToImmediate(0);
4403 MI.setDesc(
get(RISCV::ADDI));
4410 if (
MI.getOperand(0).getReg() == RISCV::X0) {
4412 MI.removeOperand(0);
4413 MI.insert(
MI.operands_begin() + 1, {MO0});
4418 if (
MI.getOperand(0).getReg() == RISCV::X0) {
4420 MI.removeOperand(0);
4421 MI.insert(
MI.operands_begin() + 1, {MO0});
4422 MI.setDesc(
get(RISCV::BNE));
4427 if (
MI.getOperand(0).getReg() == RISCV::X0) {
4429 MI.removeOperand(0);
4430 MI.insert(
MI.operands_begin() + 1, {MO0});
4431 MI.setDesc(
get(RISCV::BEQ));
4439#define CASE_WIDEOP_OPCODE_COMMON(OP, LMUL) \
4440 RISCV::PseudoV##OP##_##LMUL##_TIED
4442#define CASE_WIDEOP_OPCODE_LMULS(OP) \
4443 CASE_WIDEOP_OPCODE_COMMON(OP, MF8): \
4444 case CASE_WIDEOP_OPCODE_COMMON(OP, MF4): \
4445 case CASE_WIDEOP_OPCODE_COMMON(OP, MF2): \
4446 case CASE_WIDEOP_OPCODE_COMMON(OP, M1): \
4447 case CASE_WIDEOP_OPCODE_COMMON(OP, M2): \
4448 case CASE_WIDEOP_OPCODE_COMMON(OP, M4)
4450#define CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, LMUL) \
4451 case RISCV::PseudoV##OP##_##LMUL##_TIED: \
4452 NewOpc = RISCV::PseudoV##OP##_##LMUL; \
4455#define CASE_WIDEOP_CHANGE_OPCODE_LMULS(OP) \
4456 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF8) \
4457 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF4) \
4458 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF2) \
4459 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, M1) \
4460 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, M2) \
4461 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, M4)
4464#define CASE_FP_WIDEOP_OPCODE_COMMON(OP, LMUL, SEW) \
4465 RISCV::PseudoV##OP##_##LMUL##_##SEW##_TIED
4467#define CASE_FP_WIDEOP_OPCODE_LMULS(OP) \
4468 CASE_FP_WIDEOP_OPCODE_COMMON(OP, MF4, E16): \
4469 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, MF2, E16): \
4470 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, MF2, E32): \
4471 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M1, E16): \
4472 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M1, E32): \
4473 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M2, E16): \
4474 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M2, E32): \
4475 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M4, E16): \
4476 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M4, E32) \
4478#define CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, LMUL, SEW) \
4479 case RISCV::PseudoV##OP##_##LMUL##_##SEW##_TIED: \
4480 NewOpc = RISCV::PseudoV##OP##_##LMUL##_##SEW; \
4483#define CASE_FP_WIDEOP_CHANGE_OPCODE_LMULS(OP) \
4484 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF4, E16) \
4485 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF2, E16) \
4486 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF2, E32) \
4487 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M1, E16) \
4488 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M1, E32) \
4489 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M2, E16) \
4490 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M2, E32) \
4491 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M4, E16) \
4492 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M4, E32) \
4494#define CASE_FP_WIDEOP_OPCODE_LMULS_ALT(OP) \
4495 CASE_FP_WIDEOP_OPCODE_COMMON(OP, MF4, E16): \
4496 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, MF2, E16): \
4497 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M1, E16): \
4498 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M2, E16): \
4499 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M4, E16)
4501#define CASE_FP_WIDEOP_CHANGE_OPCODE_LMULS_ALT(OP) \
4502 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF4, E16) \
4503 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF2, E16) \
4504 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M1, E16) \
4505 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M2, E16) \
4506 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M4, E16)
4513 switch (
MI.getOpcode()) {
4521 MI.getNumExplicitOperands() == 7 &&
4522 "Expect 7 explicit operands rd, rs2, rs1, rm, vl, sew, policy");
4529 switch (
MI.getOpcode()) {
4541 .
add(
MI.getOperand(0))
4543 .
add(
MI.getOperand(1))
4544 .
add(
MI.getOperand(2))
4545 .
add(
MI.getOperand(3))
4546 .
add(
MI.getOperand(4))
4547 .
add(
MI.getOperand(5))
4548 .
add(
MI.getOperand(6));
4557 MI.getNumExplicitOperands() == 6);
4564 switch (
MI.getOpcode()) {
4576 .
add(
MI.getOperand(0))
4578 .
add(
MI.getOperand(1))
4579 .
add(
MI.getOperand(2))
4580 .
add(
MI.getOperand(3))
4581 .
add(
MI.getOperand(4))
4582 .
add(
MI.getOperand(5));
4589 unsigned NumOps =
MI.getNumOperands();
4592 if (
Op.isReg() &&
Op.isKill())
4600 if (
MI.getOperand(0).isEarlyClobber()) {
4614#undef CASE_WIDEOP_OPCODE_COMMON
4615#undef CASE_WIDEOP_OPCODE_LMULS
4616#undef CASE_WIDEOP_CHANGE_OPCODE_COMMON
4617#undef CASE_WIDEOP_CHANGE_OPCODE_LMULS
4618#undef CASE_FP_WIDEOP_OPCODE_COMMON
4619#undef CASE_FP_WIDEOP_OPCODE_LMULS
4620#undef CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON
4621#undef CASE_FP_WIDEOP_CHANGE_OPCODE_LMULS
4630 if (ShiftAmount == 0)
4636 }
else if (
int ShXAmount, ShiftAmount;
4638 (ShXAmount =
isShifted359(Amount, ShiftAmount)) != 0) {
4641 switch (ShXAmount) {
4643 Opc = RISCV::SH1ADD;
4646 Opc = RISCV::SH2ADD;
4649 Opc = RISCV::SH3ADD;
4664 Register ScaledRegister =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
4675 Register ScaledRegister =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
4685 }
else if (
STI.hasStdExtZmmul()) {
4686 Register N =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
4695 for (
uint32_t ShiftAmount = 0; Amount >> ShiftAmount; ShiftAmount++) {
4696 if (Amount & (1U << ShiftAmount)) {
4700 .
addImm(ShiftAmount - PrevShiftAmount)
4702 if (Amount >> (ShiftAmount + 1)) {
4705 Acc =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
4716 PrevShiftAmount = ShiftAmount;
4719 assert(Acc &&
"Expected valid accumulator");
4729 static const std::pair<MachineMemOperand::Flags, const char *> TargetFlags[] =
4737 ?
STI.getTailDupAggressiveThreshold()
4744 unsigned Opcode =
MI.getOpcode();
4745 if (!RISCVVPseudosTable::getPseudoInfo(Opcode) &&
4751std::optional<std::pair<unsigned, unsigned>>
4755 return std::nullopt;
4756 case RISCV::PseudoVSPILL2_M1:
4757 case RISCV::PseudoVRELOAD2_M1:
4758 return std::make_pair(2u, 1u);
4759 case RISCV::PseudoVSPILL2_M2:
4760 case RISCV::PseudoVRELOAD2_M2:
4761 return std::make_pair(2u, 2u);
4762 case RISCV::PseudoVSPILL2_M4:
4763 case RISCV::PseudoVRELOAD2_M4:
4764 return std::make_pair(2u, 4u);
4765 case RISCV::PseudoVSPILL3_M1:
4766 case RISCV::PseudoVRELOAD3_M1:
4767 return std::make_pair(3u, 1u);
4768 case RISCV::PseudoVSPILL3_M2:
4769 case RISCV::PseudoVRELOAD3_M2:
4770 return std::make_pair(3u, 2u);
4771 case RISCV::PseudoVSPILL4_M1:
4772 case RISCV::PseudoVRELOAD4_M1:
4773 return std::make_pair(4u, 1u);
4774 case RISCV::PseudoVSPILL4_M2:
4775 case RISCV::PseudoVRELOAD4_M2:
4776 return std::make_pair(4u, 2u);
4777 case RISCV::PseudoVSPILL5_M1:
4778 case RISCV::PseudoVRELOAD5_M1:
4779 return std::make_pair(5u, 1u);
4780 case RISCV::PseudoVSPILL6_M1:
4781 case RISCV::PseudoVRELOAD6_M1:
4782 return std::make_pair(6u, 1u);
4783 case RISCV::PseudoVSPILL7_M1:
4784 case RISCV::PseudoVRELOAD7_M1:
4785 return std::make_pair(7u, 1u);
4786 case RISCV::PseudoVSPILL8_M1:
4787 case RISCV::PseudoVRELOAD8_M1:
4788 return std::make_pair(8u, 1u);
4793 int16_t MI1FrmOpIdx =
4794 RISCV::getNamedOperandIdx(MI1.
getOpcode(), RISCV::OpName::frm);
4795 int16_t MI2FrmOpIdx =
4796 RISCV::getNamedOperandIdx(MI2.
getOpcode(), RISCV::OpName::frm);
4797 if (MI1FrmOpIdx < 0 || MI2FrmOpIdx < 0)
4804std::optional<unsigned>
4808 return std::nullopt;
4811 case RISCV::VSLL_VX:
4812 case RISCV::VSRL_VX:
4813 case RISCV::VSRA_VX:
4815 case RISCV::VSSRL_VX:
4816 case RISCV::VSSRA_VX:
4818 case RISCV::VROL_VX:
4819 case RISCV::VROR_VX:
4824 case RISCV::VNSRL_WX:
4825 case RISCV::VNSRA_WX:
4827 case RISCV::VNCLIPU_WX:
4828 case RISCV::VNCLIP_WX:
4830 case RISCV::VWSLL_VX:
4835 case RISCV::VADD_VX:
4836 case RISCV::VSUB_VX:
4837 case RISCV::VRSUB_VX:
4839 case RISCV::VWADDU_VX:
4840 case RISCV::VWSUBU_VX:
4841 case RISCV::VWADD_VX:
4842 case RISCV::VWSUB_VX:
4843 case RISCV::VWADDU_WX:
4844 case RISCV::VWSUBU_WX:
4845 case RISCV::VWADD_WX:
4846 case RISCV::VWSUB_WX:
4848 case RISCV::VADC_VXM:
4849 case RISCV::VADC_VIM:
4850 case RISCV::VMADC_VXM:
4851 case RISCV::VMADC_VIM:
4852 case RISCV::VMADC_VX:
4853 case RISCV::VSBC_VXM:
4854 case RISCV::VMSBC_VXM:
4855 case RISCV::VMSBC_VX:
4857 case RISCV::VAND_VX:
4859 case RISCV::VXOR_VX:
4861 case RISCV::VMSEQ_VX:
4862 case RISCV::VMSNE_VX:
4863 case RISCV::VMSLTU_VX:
4864 case RISCV::VMSLT_VX:
4865 case RISCV::VMSLEU_VX:
4866 case RISCV::VMSLE_VX:
4867 case RISCV::VMSGTU_VX:
4868 case RISCV::VMSGT_VX:
4870 case RISCV::VMINU_VX:
4871 case RISCV::VMIN_VX:
4872 case RISCV::VMAXU_VX:
4873 case RISCV::VMAX_VX:
4875 case RISCV::VMUL_VX:
4876 case RISCV::VMULH_VX:
4877 case RISCV::VMULHU_VX:
4878 case RISCV::VMULHSU_VX:
4880 case RISCV::VDIVU_VX:
4881 case RISCV::VDIV_VX:
4882 case RISCV::VREMU_VX:
4883 case RISCV::VREM_VX:
4885 case RISCV::VWMUL_VX:
4886 case RISCV::VWMULU_VX:
4887 case RISCV::VWMULSU_VX:
4889 case RISCV::VMACC_VX:
4890 case RISCV::VNMSAC_VX:
4891 case RISCV::VMADD_VX:
4892 case RISCV::VNMSUB_VX:
4894 case RISCV::VWMACCU_VX:
4895 case RISCV::VWMACC_VX:
4896 case RISCV::VWMACCSU_VX:
4897 case RISCV::VWMACCUS_VX:
4899 case RISCV::VMERGE_VXM:
4901 case RISCV::VMV_V_X:
4903 case RISCV::VSADDU_VX:
4904 case RISCV::VSADD_VX:
4905 case RISCV::VSSUBU_VX:
4906 case RISCV::VSSUB_VX:
4908 case RISCV::VAADDU_VX:
4909 case RISCV::VAADD_VX:
4910 case RISCV::VASUBU_VX:
4911 case RISCV::VASUB_VX:
4913 case RISCV::VSMUL_VX:
4915 case RISCV::VMV_S_X:
4917 case RISCV::VANDN_VX:
4918 return 1U << Log2SEW;
4924 RISCVVPseudosTable::getPseudoInfo(RVVPseudoOpcode);
4927 return RVV->BaseInstr;
4937 unsigned Scaled = Log2SEW + (DestEEW - 1);
4951 return std::nullopt;
4956 assert((LHS.isImm() || LHS.getParent()->getMF()->getRegInfo().isSSA()) &&
4957 (RHS.isImm() || RHS.getParent()->getMF()->getRegInfo().isSSA()));
4958 if (LHS.isReg() && RHS.isReg() && LHS.getReg().isVirtual() &&
4959 LHS.getReg() == RHS.getReg())
4963 if (LHS.isImm() && LHS.getImm() == 0)
4969 if (!LHSImm || !RHSImm)
4971 return LHSImm <= RHSImm;
4983 : LHS(LHS), RHS(RHS),
Cond(
Cond.begin(),
Cond.end()) {}
4985 bool shouldIgnoreForPipelining(
const MachineInstr *
MI)
const override {
4995 std::optional<bool> createTripCountGreaterCondition(
4996 int TC, MachineBasicBlock &
MBB,
4997 SmallVectorImpl<MachineOperand> &CondParam)
override {
5005 void setPreheader(MachineBasicBlock *NewPreheader)
override {}
5007 void adjustTripCount(
int TripCountAdjust)
override {}
5011std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo>
5019 if (
TBB == LoopBB && FBB == LoopBB)
5026 assert((
TBB == LoopBB || FBB == LoopBB) &&
5027 "The Loop must be a single-basic-block loop");
5038 if (!Reg.isVirtual())
5040 return MRI.getVRegDef(Reg);
5045 if (LHS && LHS->isPHI())
5047 if (RHS && RHS->isPHI())
5050 return std::make_unique<RISCVPipelinerLoopInfo>(LHS, RHS,
Cond);
5056 Opc = RVVMCOpcode ? RVVMCOpcode :
Opc;
5073 case RISCV::FDIV_H_INX:
5074 case RISCV::FDIV_S_INX:
5075 case RISCV::FDIV_D_INX:
5076 case RISCV::FDIV_D_IN32X:
5077 case RISCV::FSQRT_H:
5078 case RISCV::FSQRT_S:
5079 case RISCV::FSQRT_D:
5080 case RISCV::FSQRT_H_INX:
5081 case RISCV::FSQRT_S_INX:
5082 case RISCV::FSQRT_D_INX:
5083 case RISCV::FSQRT_D_IN32X:
5085 case RISCV::VDIV_VV:
5086 case RISCV::VDIV_VX:
5087 case RISCV::VDIVU_VV:
5088 case RISCV::VDIVU_VX:
5089 case RISCV::VREM_VV:
5090 case RISCV::VREM_VX:
5091 case RISCV::VREMU_VV:
5092 case RISCV::VREMU_VX:
5094 case RISCV::VFDIV_VV:
5095 case RISCV::VFDIV_VF:
5096 case RISCV::VFRDIV_VF:
5097 case RISCV::VFSQRT_V:
5098 case RISCV::VFRSQRT7_V:
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder MachineInstrBuilder & DefMI
static bool forwardCopyWillClobberTuple(unsigned DestReg, unsigned SrcReg, unsigned NumRegs)
static void parseCondBranch(MachineInstr *LastInst, MachineBasicBlock *&Target, SmallVectorImpl< MachineOperand > &Cond)
@ MachineOutlinerTailCall
Emit a save, restore, call, and return.
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
SmallVector< int16_t, MAX_SRC_OPERANDS_NUM > OperandIndices
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
const HexagonInstrInfo * TII
Module.h This file contains the declarations for the Module class.
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
Register const TargetRegisterInfo * TRI
Promote Memory to Register
This file provides utility analysis objects describing memory locations.
MachineInstr unsigned OpIdx
uint64_t IntrinsicInst * II
static bool cannotInsertTailCall(const MachineBasicBlock &MBB)
#define CASE_VFMA_CHANGE_OPCODE_SPLATS(OLDOP, NEWOP)
#define CASE_FP_WIDEOP_CHANGE_OPCODE_LMULS_ALT(OP)
#define CASE_FP_WIDEOP_OPCODE_LMULS(OP)
#define CASE_OPERAND_SIMM(NUM)
static std::optional< unsigned > getLMULForRVVWholeLoadStore(unsigned Opcode)
#define CASE_VFMA_CHANGE_OPCODE_VV(OLDOP, NEWOP)
static bool analyzeCandidate(outliner::Candidate &C)
static unsigned getFPFusedMultiplyOpcode(unsigned RootOpc, unsigned Pattern)
std::optional< unsigned > getFoldedOpcode(MachineFunction &MF, MachineInstr &MI, ArrayRef< unsigned > Ops, const RISCVSubtarget &ST)
#define RVV_OPC_LMUL_CASE(OPC, INV)
#define CASE_FP_WIDEOP_CHANGE_OPCODE_LMULS(OP)
static void combineFPFusedMultiply(MachineInstr &Root, MachineInstr &Prev, unsigned Pattern, SmallVectorImpl< MachineInstr * > &InsInstrs, SmallVectorImpl< MachineInstr * > &DelInstrs)
static unsigned getAddendOperandIdx(unsigned Pattern)
#define CASE_RVV_OPCODE_UNMASK(OP)
#define CASE_WIDEOP_CHANGE_OPCODE_LMULS(OP)
static cl::opt< bool > PreferWholeRegisterMove("riscv-prefer-whole-register-move", cl::init(false), cl::Hidden, cl::desc("Prefer whole register move for vector registers."))
#define CASE_VFMA_SPLATS(OP)
unsigned getPredicatedOpcode(unsigned Opcode)
#define CASE_FP_WIDEOP_OPCODE_LMULS_ALT(OP)
#define CASE_WIDEOP_OPCODE_LMULS(OP)
static bool isMIReadsReg(const MachineInstr &MI, const TargetRegisterInfo *TRI, MCRegister RegNo)
#define OPCODE_LMUL_MASK_CASE(OPC)
static bool isFSUB(unsigned Opc)
#define CASE_VMA_CHANGE_OPCODE_LMULS(OLDOP, NEWOP, TYPE)
#define CASE_RVV_OPCODE(OP)
static std::optional< int64_t > getEffectiveImm(const MachineOperand &MO)
#define CASE_VFMA_OPCODE_VV(OP)
MachineOutlinerConstructionID
#define CASE_RVV_OPCODE_WIDEN(OP)
static unsigned getSHXADDUWShiftAmount(unsigned Opc)
#define CASE_VMA_OPCODE_LMULS(OP, TYPE)
static bool isConvertibleToVMV_V_V(const RISCVSubtarget &STI, const MachineBasicBlock &MBB, MachineBasicBlock::const_iterator MBBI, MachineBasicBlock::const_iterator &DefMBBI, RISCVVType::VLMUL LMul)
static bool isFMUL(unsigned Opc)
static unsigned getInverseXqcicmOpcode(unsigned Opcode)
static bool getFPPatterns(MachineInstr &Root, SmallVectorImpl< unsigned > &Patterns, bool DoRegPressureReduce)
#define OPCODE_LMUL_CASE(OPC)
#define CASE_OPERAND_UIMM(NUM)
static bool canCombineShiftIntoShXAdd(const MachineBasicBlock &MBB, const MachineOperand &MO, unsigned OuterShiftAmt)
Utility routine that checks if.
static bool isCandidatePatchable(const MachineBasicBlock &MBB)
static bool isFADD(unsigned Opc)
static void genShXAddAddShift(MachineInstr &Root, unsigned AddOpIdx, SmallVectorImpl< MachineInstr * > &InsInstrs, SmallVectorImpl< MachineInstr * > &DelInstrs, DenseMap< Register, unsigned > &InstrIdxForVirtReg)
static bool isLoadImm(const MachineInstr *MI, int64_t &Imm)
static bool isMIModifiesReg(const MachineInstr &MI, const TargetRegisterInfo *TRI, MCRegister RegNo)
static bool canCombineFPFusedMultiply(const MachineInstr &Root, const MachineOperand &MO, bool DoRegPressureReduce)
static bool getSHXADDPatterns(const MachineInstr &Root, SmallVectorImpl< unsigned > &Patterns)
static bool getFPFusedMultiplyPatterns(MachineInstr &Root, SmallVectorImpl< unsigned > &Patterns, bool DoRegPressureReduce)
static cl::opt< MachineTraceStrategy > ForceMachineCombinerStrategy("riscv-force-machine-combiner-strategy", cl::Hidden, cl::desc("Force machine combiner to use a specific strategy for machine " "trace metrics evaluation."), cl::init(MachineTraceStrategy::TS_NumStrategies), cl::values(clEnumValN(MachineTraceStrategy::TS_Local, "local", "Local strategy."), clEnumValN(MachineTraceStrategy::TS_MinInstrCount, "min-instr", "MinInstrCount strategy.")))
static unsigned getSHXADDShiftAmount(unsigned Opc)
#define CASE_RVV_OPCODE_MASK(OP)
#define RVV_OPC_LMUL_MASK_CASE(OPC, INV)
static MachineInstr * canFoldAsPredicatedOp(Register Reg, const MachineRegisterInfo &MRI, const TargetInstrInfo *TII, const RISCVSubtarget &STI)
Identify instructions that can be folded into a CCMOV instruction, and return the defining instructio...
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
This file declares the machine register scavenger class.
static bool memOpsHaveSameBasePtr(const MachineInstr &MI1, ArrayRef< const MachineOperand * > BaseOps1, const MachineInstr &MI2, ArrayRef< const MachineOperand * > BaseOps2)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
static bool canCombine(MachineBasicBlock &MBB, MachineOperand &MO, unsigned CombineOpc=0)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
const T & front() const
front - Get the first element.
bool empty() const
empty - Check if the array is empty.
static LLVM_ABI DILocation * getMergedLocation(DILocation *LocA, DILocation *LocB)
Attempts to merge LocA and LocB into a single location; see DebugLoc::getMergedLocation for more deta...
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
LiveInterval - This class represents the liveness of a register, or stack slot.
LiveInterval & getInterval(Register Reg)
SlotIndex ReplaceMachineInstrInMaps(MachineInstr &MI, MachineInstr &NewMI)
const Segment * getSegmentContaining(SlotIndex Idx) const
Return the segment that contains the specified index, or null if there is none.
LLVM_ABI void replaceKillInstruction(Register Reg, MachineInstr &OldMI, MachineInstr &NewMI)
replaceKillInstruction - Update register kill info by replacing a kill instruction with a new one.
static LocationSize precise(uint64_t Value)
TypeSize getValue() const
MCInstBuilder & addReg(MCRegister Reg)
Add a new register operand.
MCInstBuilder & addImm(int64_t Val)
Add a new integer immediate operand.
Instances of this class represent a single low-level machine instruction.
Describe properties that are true of each instruction in the target description file.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
bool isConditionalBranch() const
Return true if this is a branch which may fall through to the next instruction or may transfer contro...
This holds information about one operand of a machine instruction, indicating the register class for ...
Wrapper class representing physical registers. Should be passed by value.
const FeatureBitset & getFeatureBits() const
MachineInstrBundleIterator< const MachineInstr > const_iterator
MachineInstrBundleIterator< MachineInstr, true > reverse_iterator
Instructions::const_iterator const_instr_iterator
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
MachineInstrBundleIterator< MachineInstr > iterator
MachineInstrBundleIterator< const MachineInstr, true > const_reverse_iterator
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
void setStackID(int ObjectIdx, uint8_t ID)
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineInstrBuilder & setMemRefs(ArrayRef< MachineMemOperand * > MMOs) const
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
const MachineInstrBuilder & copyImplicitOps(const MachineInstr &OtherMI) const
Copy all the implicit operands from OtherMI onto this one.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
reverse_iterator getReverse() const
Get a reverse iterator to the same node.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
bool isReturn(QueryType Type=AnyInBundle) const
bool mayLoadOrStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read or modify memory.
const MachineBasicBlock * getParent() const
bool getFlag(MIFlag Flag) const
Return whether an MI flag is set.
LLVM_ABI unsigned getNumExplicitOperands() const
Returns the number of non-implicit operands.
bool modifiesRegister(Register Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr modifies (fully define or partially define) the specified register.
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 bool hasUnmodeledSideEffects() const
Return true if this instruction has side effects that are not modeled by mayLoad / mayStore,...
bool hasOneMemOperand() const
Return true if this instruction has exactly one MachineMemOperand.
mmo_iterator memoperands_begin() const
Access to memory operands of the instruction.
LLVM_ABI bool hasOrderedMemoryRef() const
Return true if this instruction may have an ordered or volatile memory reference, or if the informati...
LLVM_ABI const MachineFunction * getMF() const
Return the function that contains the basic block that this instruction belongs to.
ArrayRef< MachineMemOperand * > memoperands() const
Access to memory operands of the instruction.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
uint32_t getFlags() const
Return the MI flags bitvector.
LLVM_ABI void clearKillInfo()
Clears kill flags on all operands.
A description of a memory reference used in the backend.
bool isNonTemporal() const
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
This class contains meta information specific to a module.
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineBasicBlock * getMBB() const
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
static MachineOperand CreateImm(int64_t Val)
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
Register getReg() const
getReg - Returns the register number.
bool isFI() const
isFI - Tests if this is a MO_FrameIndex operand.
LLVM_ABI bool isIdenticalTo(const MachineOperand &Other) const
Returns true if this operand is identical to the specified operand except for liveness related flags ...
@ MO_Immediate
Immediate operand.
@ MO_Register
Register operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
A Module instance is used to store all the information related to an LLVM module.
MI-level patchpoint operands.
uint32_t getNumPatchBytes() const
Return the number of patchable bytes the given patchpoint should emit.
MachineInstr * convertToThreeAddress(MachineInstr &MI, LiveVariables *LV, LiveIntervals *LIS) const override
Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
std::optional< std::unique_ptr< outliner::OutlinedFunction > > getOutliningCandidateInfo(const MachineModuleInfo &MMI, std::vector< outliner::Candidate > &RepeatedSequenceLocs, unsigned MinRepeats) const override
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
void genAlternativeCodeSequence(MachineInstr &Root, unsigned Pattern, SmallVectorImpl< MachineInstr * > &InsInstrs, SmallVectorImpl< MachineInstr * > &DelInstrs, DenseMap< Register, unsigned > &InstrIdxForVirtReg) const override
void movImm(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, Register DstReg, uint64_t Val, MachineInstr::MIFlag Flag=MachineInstr::NoFlags, bool DstRenamable=false, bool DstIsDead=false) const
MachineInstr * emitLdStWithAddr(MachineInstr &MemI, const ExtAddrMode &AM) const override
void mulImm(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator II, const DebugLoc &DL, Register DestReg, uint32_t Amt, MachineInstr::MIFlag Flag) const
Generate code to multiply the value in DestReg by Amt - handles all the common optimizations for this...
static bool isPairableLdStInstOpc(unsigned Opc)
Return true if pairing the given load or store may be paired with another.
RISCVInstrInfo(const RISCVSubtarget &STI)
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool IsKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
bool isFunctionSafeToOutlineFrom(MachineFunction &MF, bool OutlineFromLinkOnceODRs) const override
std::unique_ptr< TargetInstrInfo::PipelinerLoopInfo > analyzeLoopForPipelining(MachineBasicBlock *LoopBB) const override
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &dl, int *BytesAdded=nullptr) const override
bool hasReassociableSibling(const MachineInstr &Inst, bool &Commuted) const override
static bool isLdStSafeToPair(const MachineInstr &LdSt, const TargetRegisterInfo *TRI)
void copyPhysRegVector(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, MCRegister DstReg, MCRegister SrcReg, bool KillSrc, const TargetRegisterClass *RegClass) const
bool isReMaterializableImpl(const MachineInstr &MI) const override
MachineInstr * optimizeSelect(MachineInstr &MI, SmallPtrSetImpl< MachineInstr * > &SeenMIs, bool) const override
bool canFoldIntoAddrMode(const MachineInstr &MemI, Register Reg, const MachineInstr &AddrI, ExtAddrMode &AM) const override
void insertIndirectBranch(MachineBasicBlock &MBB, MachineBasicBlock &NewDestBB, MachineBasicBlock &RestoreBB, const DebugLoc &DL, int64_t BrOffset, RegScavenger *RS) const override
bool isAsCheapAsAMove(const MachineInstr &MI) const override
bool verifyInstruction(const MachineInstr &MI, StringRef &ErrInfo) const override
bool getMemOperandWithOffsetWidth(const MachineInstr &LdSt, const MachineOperand *&BaseOp, int64_t &Offset, LocationSize &Width, const TargetRegisterInfo *TRI) const
unsigned getTailDuplicateSize(CodeGenOptLevel OptLevel) const override
void getReassociateOperandIndices(const MachineInstr &Root, unsigned Pattern, std::array< unsigned, 5 > &OperandIndices) const override
const RISCVSubtarget & STI
Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
std::optional< unsigned > getInverseOpcode(unsigned Opcode) const override
bool simplifyInstruction(MachineInstr &MI) const override
ArrayRef< std::pair< unsigned, const char * > > getSerializableDirectMachineOperandTargetFlags() const override
outliner::InstrType getOutliningTypeImpl(const MachineModuleInfo &MMI, MachineBasicBlock::iterator &MBBI, unsigned Flags) const override
MachineTraceStrategy getMachineCombinerTraceStrategy() const override
unsigned getInstSizeInBytes(const MachineInstr &MI) const override
std::optional< RegImmPair > isAddImmediate(const MachineInstr &MI, Register Reg) const override
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
ArrayRef< std::pair< MachineMemOperand::Flags, const char * > > getSerializableMachineMemOperandTargetFlags() const override
MCInst getNop() const override
MachineInstr * foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI, ArrayRef< unsigned > Ops, MachineBasicBlock::iterator InsertPt, int FrameIndex, LiveIntervals *LIS=nullptr, VirtRegMap *VRM=nullptr) const override
bool isMBBSafeToOutlineFrom(MachineBasicBlock &MBB, unsigned &Flags) const override
bool getMemOperandsWithOffsetWidth(const MachineInstr &MI, SmallVectorImpl< const MachineOperand * > &BaseOps, int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width, const TargetRegisterInfo *TRI) const override
void buildOutlinedFrame(MachineBasicBlock &MBB, MachineFunction &MF, const outliner::OutlinedFunction &OF) const override
void finalizeInsInstrs(MachineInstr &Root, unsigned &Pattern, SmallVectorImpl< MachineInstr * > &InsInstrs) const override
std::pair< unsigned, unsigned > decomposeMachineOperandsTargetFlags(unsigned TF) const override
MachineInstr * commuteInstructionImpl(MachineInstr &MI, bool NewMI, unsigned OpIdx1, unsigned OpIdx2) const override
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DstReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
bool hasReassociableOperands(const MachineInstr &Inst, const MachineBasicBlock *MBB) const override
MachineBasicBlock * getBranchDestBlock(const MachineInstr &MI) const override
std::string createMIROperandComment(const MachineInstr &MI, const MachineOperand &Op, unsigned OpIdx, const TargetRegisterInfo *TRI) const override
bool shouldOutlineFromFunctionByDefault(MachineFunction &MF) const override
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, Register DstReg, Register SrcReg, bool KillSrc, bool RenamableDest=false, bool RenamableSrc=false) const override
bool findCommutedOpIndices(const MachineInstr &MI, unsigned &SrcOpIdx1, unsigned &SrcOpIdx2) const override
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
MachineBasicBlock::iterator insertOutlinedCall(Module &M, MachineBasicBlock &MBB, MachineBasicBlock::iterator &It, MachineFunction &MF, outliner::Candidate &C) const override
bool isBranchOffsetInRange(unsigned BranchOpc, int64_t BrOffset) const override
static RISCVCC::CondCode getCondFromBranchOpc(unsigned Opc)
bool isAssociativeAndCommutative(const MachineInstr &Inst, bool Invert) const override
CombinerObjective getCombinerObjective(unsigned Pattern) const override
bool isHighLatencyDef(int Opc) const override
static bool evaluateCondBranch(RISCVCC::CondCode CC, int64_t C0, int64_t C1)
Return the result of the evaluation of C0 CC C1, where CC is a RISCVCC::CondCode.
bool getMachineCombinerPatterns(MachineInstr &Root, SmallVectorImpl< unsigned > &Patterns, bool DoRegPressureReduce) const override
bool optimizeCondBranch(MachineInstr &MI) const override
std::optional< DestSourcePair > isCopyInstrImpl(const MachineInstr &MI) const override
bool analyzeSelect(const MachineInstr &MI, SmallVectorImpl< MachineOperand > &Cond, unsigned &TrueOp, unsigned &FalseOp, bool &Optimizable) const override
static bool isFromLoadImm(const MachineRegisterInfo &MRI, const MachineOperand &Op, int64_t &Imm)
Return true if the operand is a load immediate instruction and sets Imm to the immediate value.
bool shouldClusterMemOps(ArrayRef< const MachineOperand * > BaseOps1, int64_t Offset1, bool OffsetIsScalable1, ArrayRef< const MachineOperand * > BaseOps2, int64_t Offset2, bool OffsetIsScalable2, unsigned ClusterSize, unsigned NumBytes) const override
bool areMemAccessesTriviallyDisjoint(const MachineInstr &MIa, const MachineInstr &MIb) const override
RISCVMachineFunctionInfo - This class is derived from MachineFunctionInfo and contains private RISCV-...
int getBranchRelaxationScratchFrameIndex() const
const RISCVRegisterInfo * getRegisterInfo() const override
Wrapper class representing virtual and physical registers.
constexpr bool isValid() const
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
SlotIndex - An opaque wrapper around machine indexes.
SlotIndex getRegSlot(bool EC=false) const
Returns the register use/def slot in the current instruction for a normal or early-clobber def.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
bool erase(PtrType Ptr)
Remove pointer from the set.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
MI-level stackmap operands.
uint32_t getNumPatchBytes() const
Return the number of patchable bytes the given stackmap should emit.
MI-level Statepoint operands.
uint32_t getNumPatchBytes() const
Return the number of patchable bytes the given statepoint should emit.
StringRef - Represent a constant reference to a string, i.e.
Object returned by analyzeLoopForPipelining.
TargetInstrInfo - Interface to description of machine instruction set.
virtual bool findCommutedOpIndices(const MachineInstr &MI, unsigned &SrcOpIdx1, unsigned &SrcOpIdx2) const
Returns true iff the routine could find two commutable operands in the given machine instruction.
virtual bool hasReassociableOperands(const MachineInstr &Inst, const MachineBasicBlock *MBB) const
Return true when \P Inst has reassociable operands in the same \P MBB.
virtual void genAlternativeCodeSequence(MachineInstr &Root, unsigned Pattern, SmallVectorImpl< MachineInstr * > &InsInstrs, SmallVectorImpl< MachineInstr * > &DelInstrs, DenseMap< Register, unsigned > &InstIdxForVirtReg) const
When getMachineCombinerPatterns() finds patterns, this function generates the instructions that could...
virtual bool getMachineCombinerPatterns(MachineInstr &Root, SmallVectorImpl< unsigned > &Patterns, bool DoRegPressureReduce) const
Return true when there is potentially a faster code sequence for an instruction chain ending in Root.
virtual bool isReMaterializableImpl(const MachineInstr &MI) const
For instructions with opcodes for which the M_REMATERIALIZABLE flag is set, this hook lets the target...
virtual bool isMBBSafeToOutlineFrom(MachineBasicBlock &MBB, unsigned &Flags) const
Optional target hook that returns true if MBB is safe to outline from, and returns any target-specifi...
virtual void getReassociateOperandIndices(const MachineInstr &Root, unsigned Pattern, std::array< unsigned, 5 > &OperandIndices) const
The returned array encodes the operand index for each parameter because the operands may be commuted;...
virtual CombinerObjective getCombinerObjective(unsigned Pattern) const
Return the objective of a combiner pattern.
virtual MachineInstr * commuteInstructionImpl(MachineInstr &MI, bool NewMI, unsigned OpIdx1, unsigned OpIdx2) const
This method commutes the operands of the given machine instruction MI.
virtual bool hasReassociableSibling(const MachineInstr &Inst, bool &Commuted) const
Return true when \P Inst has reassociable sibling.
virtual std::string createMIROperandComment(const MachineInstr &MI, const MachineOperand &Op, unsigned OpIdx, const TargetRegisterInfo *TRI) const
const MCAsmInfo * getMCAsmInfo() const
Return target specific asm information.
const uint8_t TSFlags
Configurable target specific flags.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
TargetSubtargetInfo - Generic base class for all target subtargets.
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
Target - Wrapper for Target specific information.
static constexpr TypeSize getFixed(ScalarTy ExactSize)
static constexpr TypeSize getZero()
static constexpr TypeSize getScalable(ScalarTy MinimumSize)
A raw_ostream that writes to an std::string.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
CondCode getInverseBranchCondition(CondCode)
unsigned getBrCond(CondCode CC, unsigned SelectOpc=0)
static bool isValidRoundingMode(unsigned Mode)
static unsigned getVecPolicyOpNum(const MCInstrDesc &Desc)
static bool usesMaskPolicy(uint64_t TSFlags)
static bool hasRoundModeOp(uint64_t TSFlags)
static unsigned getVLOpNum(const MCInstrDesc &Desc)
static bool hasVLOp(uint64_t TSFlags)
static MCRegister getTailExpandUseRegNo(const FeatureBitset &FeatureBits)
static int getFRMOpNum(const MCInstrDesc &Desc)
static bool hasVecPolicyOp(uint64_t TSFlags)
static bool usesVXRM(uint64_t TSFlags)
static bool isRVVWideningReduction(uint64_t TSFlags)
static unsigned getSEWOpNum(const MCInstrDesc &Desc)
static bool hasSEWOp(uint64_t TSFlags)
static bool isFirstDefTiedToFirstUse(const MCInstrDesc &Desc)
InstSeq generateInstSeq(int64_t Val, const MCSubtargetInfo &STI)
SmallVector< Inst, 8 > InstSeq
@ OPERAND_UIMMLOG2XLEN_NONZERO
@ OPERAND_SIMM12_LSB00000
@ OPERAND_FIRST_RISCV_IMM
@ OPERAND_UIMM10_LSB00_NONZERO
@ OPERAND_SIMM10_LSB0000_NONZERO
static unsigned getNF(uint8_t TSFlags)
static RISCVVType::VLMUL getLMul(uint8_t TSFlags)
static bool isTailAgnostic(unsigned VType)
LLVM_ABI void printXSfmmVType(unsigned VType, raw_ostream &OS)
LLVM_ABI std::pair< unsigned, bool > decodeVLMUL(VLMUL VLMul)
static bool isValidSEW(unsigned SEW)
LLVM_ABI void printVType(unsigned VType, raw_ostream &OS)
static bool isValidXSfmmVType(unsigned VTypeI)
static unsigned getSEW(unsigned VType)
static VLMUL getVLMUL(unsigned VType)
bool hasEqualFRM(const MachineInstr &MI1, const MachineInstr &MI2)
bool isVLKnownLE(const MachineOperand &LHS, const MachineOperand &RHS)
Given two VL operands, do we know that LHS <= RHS?
unsigned getRVVMCOpcode(unsigned RVVPseudoOpcode)
unsigned getDestLog2EEW(const MCInstrDesc &Desc, unsigned Log2SEW)
std::optional< unsigned > getVectorLowDemandedScalarBits(unsigned Opcode, unsigned Log2SEW)
std::optional< std::pair< unsigned, unsigned > > isRVVSpillForZvlsseg(unsigned Opcode)
static constexpr unsigned RVVBitsPerBlock
bool isRVVSpill(const MachineInstr &MI)
static constexpr unsigned RVVBytesPerBlock
static constexpr int64_t VLMaxSentinel
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Define
Register definition.
@ Kill
The last use of a register.
@ Undef
Value of the register doesn't matter.
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
initializer< Ty > init(const Ty &Val)
InstrType
Represents how an instruction should be mapped by the outliner.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
MachineTraceStrategy
Strategies for selecting traces.
@ TS_MinInstrCount
Select the trace through a block that has the fewest instructions.
@ TS_Local
Select the trace that contains only the current basic block.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
static const MachineMemOperand::Flags MONontemporalBit1
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
static const MachineMemOperand::Flags MONontemporalBit0
unsigned getDeadRegState(bool B)
constexpr bool has_single_bit(T Value) noexcept
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
CombinerObjective
The combiner's goal may differ based on which pattern it is attempting to optimize.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
CodeGenOptLevel
Code generation optimization level.
int isShifted359(T Value, int &Shift)
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
unsigned getKillRegState(bool B)
unsigned getRenamableRegState(bool B)
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
constexpr bool isShiftedInt(int64_t x)
Checks if a signed integer is an N bit number shifted left by S.
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
constexpr bool isShiftedUInt(uint64_t x)
Checks if a unsigned integer is an N bit number shifted left by S.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Used to describe addressing mode similar to ExtAddrMode in CodeGenPrepare.
This represents a simple continuous liveness interval for a value.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
static bool isRVVRegClass(const TargetRegisterClass *RC)
Used to describe a register and immediate addition.
An individual sequence of instructions to be replaced with a call to an outlined function.
MachineFunction * getMF() const
The information necessary to create an outlined function for some class of candidate.