40#define GEN_CHECK_COMPRESS_INSTR
41#include "RISCVGenCompressInstEmitter.inc"
43#define GET_INSTRINFO_CTOR_DTOR
44#include "RISCVGenInstrInfo.inc"
46#define DEBUG_TYPE "riscv-instr-info"
48 "Number of registers within vector register groups spilled");
50 "Number of registers within vector register groups reloaded");
56#define GET_RISCVVPseudosTable_IMPL
57#include "RISCVGenSearchableTables.inc"
63#define GET_RISCVMaskedPseudosTable_IMPL
64#include "RISCVGenSearchableTables.inc"
70 RISCV::ADJCALLSTACKUP),
71 RegInfo(
STI.getHwMode(),
STI.getUserReservedXRegs()),
STI(
STI) {}
73#define GET_INSTRINFO_HELPERS
74#include "RISCVGenInstrInfo.inc"
77 if (
STI.hasStdExtZca())
86 int &FrameIndex)
const {
97 case RISCV::VL1RE16_V:
98 case RISCV::VL1RE32_V:
99 case RISCV::VL1RE64_V:
102 case RISCV::VL2RE8_V:
103 case RISCV::VL2RE16_V:
104 case RISCV::VL2RE32_V:
105 case RISCV::VL2RE64_V:
108 case RISCV::VL4RE8_V:
109 case RISCV::VL4RE16_V:
110 case RISCV::VL4RE32_V:
111 case RISCV::VL4RE64_V:
114 case RISCV::VL8RE8_V:
115 case RISCV::VL8RE16_V:
116 case RISCV::VL8RE32_V:
117 case RISCV::VL8RE64_V:
125 switch (
MI.getOpcode()) {
149 case RISCV::VL1RE8_V:
150 case RISCV::VL2RE8_V:
151 case RISCV::VL4RE8_V:
152 case RISCV::VL8RE8_V:
153 if (!
MI.getOperand(1).isFI())
155 FrameIndex =
MI.getOperand(1).getIndex();
158 return MI.getOperand(0).getReg();
161 if (
MI.getOperand(1).isFI() &&
MI.getOperand(2).isImm() &&
162 MI.getOperand(2).getImm() == 0) {
163 FrameIndex =
MI.getOperand(1).getIndex();
164 return MI.getOperand(0).getReg();
171 int &FrameIndex)
const {
179 switch (
MI.getOpcode()) {
204 if (!
MI.getOperand(1).isFI())
206 FrameIndex =
MI.getOperand(1).getIndex();
209 return MI.getOperand(0).getReg();
212 if (
MI.getOperand(1).isFI() &&
MI.getOperand(2).isImm() &&
213 MI.getOperand(2).getImm() == 0) {
214 FrameIndex =
MI.getOperand(1).getIndex();
215 return MI.getOperand(0).getReg();
225 case RISCV::VFMV_V_F:
228 case RISCV::VFMV_S_F:
230 return MI.getOperand(1).isUndef();
238 return DstReg > SrcReg && (DstReg - SrcReg) < NumRegs;
246 if (STI.
getCLOpts().prefer_whole_register_move)
249 assert(
MBBI->getOpcode() == TargetOpcode::COPY &&
250 "Unexpected COPY instruction.");
254 bool FoundDef =
false;
255 bool FirstVSetVLI =
false;
256 unsigned FirstSEW = 0;
259 if (
MBBI->isMetaInstruction())
262 if (RISCVInstrInfo::isVectorConfigInstr(*
MBBI)) {
272 unsigned FirstVType =
MBBI->getOperand(2).getImm();
277 if (FirstLMul != LMul)
282 if (!RISCVInstrInfo::isVLPreservingConfig(*
MBBI))
288 unsigned VType =
MBBI->getOperand(2).getImm();
306 }
else if (
MBBI->isInlineAsm() ||
MBBI->isCall()) {
308 }
else if (
MBBI->getNumDefs()) {
311 if (
MBBI->modifiesRegister(RISCV::VL,
nullptr))
317 if (!MO.isReg() || !MO.isDef())
319 if (!FoundDef &&
TRI->regsOverlap(MO.getReg(), SrcReg)) {
334 if (MO.getReg() != SrcReg)
375 uint16_t SrcEncoding =
TRI->getEncodingValue(SrcReg);
376 uint16_t DstEncoding =
TRI->getEncodingValue(DstReg);
378 assert(!Fractional &&
"It is impossible be fractional lmul here.");
379 unsigned NumRegs = NF * LMulVal;
385 SrcEncoding += NumRegs - 1;
386 DstEncoding += NumRegs - 1;
390 auto GetCopyInfo = [&](uint16_t SrcEncoding, uint16_t DstEncoding)
392 unsigned,
unsigned> {
400 uint16_t Diff = DstEncoding - SrcEncoding;
401 if (
I + 8 <= NumRegs && Diff >= 8 && SrcEncoding % 8 == 7 &&
402 DstEncoding % 8 == 7)
404 RISCV::PseudoVMV_V_V_M8, RISCV::PseudoVMV_V_I_M8};
405 if (
I + 4 <= NumRegs && Diff >= 4 && SrcEncoding % 4 == 3 &&
406 DstEncoding % 4 == 3)
408 RISCV::PseudoVMV_V_V_M4, RISCV::PseudoVMV_V_I_M4};
409 if (
I + 2 <= NumRegs && Diff >= 2 && SrcEncoding % 2 == 1 &&
410 DstEncoding % 2 == 1)
412 RISCV::PseudoVMV_V_V_M2, RISCV::PseudoVMV_V_I_M2};
415 RISCV::PseudoVMV_V_V_M1, RISCV::PseudoVMV_V_I_M1};
420 if (
I + 8 <= NumRegs && SrcEncoding % 8 == 0 && DstEncoding % 8 == 0)
422 RISCV::PseudoVMV_V_V_M8, RISCV::PseudoVMV_V_I_M8};
423 if (
I + 4 <= NumRegs && SrcEncoding % 4 == 0 && DstEncoding % 4 == 0)
425 RISCV::PseudoVMV_V_V_M4, RISCV::PseudoVMV_V_I_M4};
426 if (
I + 2 <= NumRegs && SrcEncoding % 2 == 0 && DstEncoding % 2 == 0)
428 RISCV::PseudoVMV_V_V_M2, RISCV::PseudoVMV_V_I_M2};
431 RISCV::PseudoVMV_V_V_M1, RISCV::PseudoVMV_V_I_M1};
434 while (
I != NumRegs) {
439 auto [LMulCopied, RegClass,
Opc, VVOpc, VIOpc] =
440 GetCopyInfo(SrcEncoding, DstEncoding);
444 if (LMul == LMulCopied &&
447 if (DefMBBI->getOpcode() == VIOpc)
454 RegClass, ReversedCopy ? (SrcEncoding - NumCopied + 1) : SrcEncoding);
456 RegClass, ReversedCopy ? (DstEncoding - NumCopied + 1) : DstEncoding);
464 MIB = MIB.add(DefMBBI->getOperand(2));
472 MIB.addImm(Log2SEW ? Log2SEW : 3);
484 SrcEncoding += (ReversedCopy ? -NumCopied : NumCopied);
485 DstEncoding += (ReversedCopy ? -NumCopied : NumCopied);
494 bool RenamableDest,
bool RenamableSrc)
const {
498 if (RISCV::GPRRegClass.
contains(DstReg, SrcReg)) {
505 if (RISCV::GPRF16RegClass.
contains(DstReg, SrcReg)) {
511 if (RISCV::GPRF32RegClass.
contains(DstReg, SrcReg)) {
517 if (RISCV::GPRPairRegClass.
contains(DstReg, SrcReg)) {
518 if (!
STI.is64Bit()) {
519 if (
STI.hasStdExtZdinx()) {
528 if (
STI.hasStdExtP()) {
537 auto [EvenReg, OddReg] =
TRI->getGPRPairSubRegs(SrcReg);
538 assert(DstReg != RISCV::X0_Pair &&
"Cannot write to X0_Pair");
542 TRI->getSubReg(DstReg, RISCV::sub_gpr_even))
543 .
addReg(EvenReg, KillFlag)
546 TRI->getSubReg(DstReg, RISCV::sub_gpr_odd))
553 if (RISCV::VCSRRegClass.
contains(SrcReg) &&
554 RISCV::GPRRegClass.
contains(DstReg)) {
556 .
addImm(RISCVSysReg::lookupSysRegByName(
TRI->getName(SrcReg))->Encoding)
561 if (RISCV::FPR16RegClass.
contains(DstReg, SrcReg)) {
563 if (
STI.hasStdExtZfh()) {
564 Opc = RISCV::FSGNJ_H;
567 (
STI.hasStdExtZfhmin() ||
STI.hasStdExtZfbfmin()) &&
568 "Unexpected extensions");
570 DstReg =
TRI->getMatchingSuperReg(DstReg, RISCV::sub_16,
571 &RISCV::FPR32RegClass);
572 SrcReg =
TRI->getMatchingSuperReg(SrcReg, RISCV::sub_16,
573 &RISCV::FPR32RegClass);
574 Opc = RISCV::FSGNJ_S;
578 .
addReg(SrcReg, KillFlag);
582 if (RISCV::FPR32RegClass.
contains(DstReg, SrcReg)) {
585 .
addReg(SrcReg, KillFlag);
589 if (RISCV::FPR64RegClass.
contains(DstReg, SrcReg)) {
592 .
addReg(SrcReg, KillFlag);
596 if (RISCV::FPR16RegClass.
contains(DstReg) &&
597 RISCV::GPRRegClass.
contains(SrcReg)) {
598 assert(
STI.hasHalfFPLoadStoreMove() &&
"Unexpected extensions");
600 .
addReg(SrcReg, KillFlag);
604 if (RISCV::GPRRegClass.
contains(DstReg) &&
605 RISCV::FPR16RegClass.
contains(SrcReg)) {
606 assert(
STI.hasHalfFPLoadStoreMove() &&
"Unexpected extensions");
608 .
addReg(SrcReg, KillFlag);
612 if (RISCV::FPR32RegClass.
contains(DstReg) &&
613 RISCV::GPRRegClass.
contains(SrcReg)) {
615 .
addReg(SrcReg, KillFlag);
619 if (RISCV::GPRRegClass.
contains(DstReg) &&
620 RISCV::FPR32RegClass.
contains(SrcReg)) {
622 .
addReg(SrcReg, KillFlag);
626 if (RISCV::FPR64RegClass.
contains(DstReg) &&
627 RISCV::GPRRegClass.
contains(SrcReg)) {
628 assert(
STI.getXLen() == 64 &&
"Unexpected GPR size");
630 .
addReg(SrcReg, KillFlag);
634 if (RISCV::GPRRegClass.
contains(DstReg) &&
635 RISCV::FPR64RegClass.
contains(SrcReg)) {
636 assert(
STI.getXLen() == 64 &&
"Unexpected GPR size");
638 .
addReg(SrcReg, KillFlag);
644 TRI->getCommonMinimalPhysRegClass(SrcReg, DstReg);
655 Register SrcReg,
bool IsKill,
int FI,
664 if (RISCV::GPRRegClass.hasSubClassEq(RC)) {
665 Opcode = RegInfo.getRegSizeInBits(RISCV::GPRRegClass) == 32 ? RISCV::SW
667 }
else if (RISCV::GPRF16RegClass.hasSubClassEq(RC)) {
668 Opcode = RISCV::SH_INX;
669 }
else if (RISCV::GPRF32RegClass.hasSubClassEq(RC)) {
670 Opcode = RISCV::SW_INX;
671 }
else if (RISCV::GPRPairRegClass.hasSubClassEq(RC)) {
672 if (!
STI.is64Bit() &&
STI.hasStdExtZilsd() &&
673 Alignment >=
STI.getZilsdAlign()) {
674 Opcode = RISCV::SD_RV32;
676 Opcode = RISCV::PseudoRV32ZdinxSD;
678 }
else if (RISCV::FPR16RegClass.hasSubClassEq(RC)) {
680 }
else if (RISCV::FPR32RegClass.hasSubClassEq(RC)) {
682 }
else if (RISCV::FPR64RegClass.hasSubClassEq(RC)) {
684 }
else if (RISCV::VRRegClass.hasSubClassEq(RC)) {
685 Opcode = RISCV::VS1R_V;
686 }
else if (RISCV::VRM2RegClass.hasSubClassEq(RC)) {
687 Opcode = RISCV::VS2R_V;
688 }
else if (RISCV::VRM4RegClass.hasSubClassEq(RC)) {
689 Opcode = RISCV::VS4R_V;
690 }
else if (RISCV::VRM8RegClass.hasSubClassEq(RC)) {
691 Opcode = RISCV::VS8R_V;
692 }
else if (RISCV::VRN2M1RegClass.hasSubClassEq(RC))
693 Opcode = RISCV::PseudoVSPILL2_M1;
694 else if (RISCV::VRN2M2RegClass.hasSubClassEq(RC))
695 Opcode = RISCV::PseudoVSPILL2_M2;
696 else if (RISCV::VRN2M4RegClass.hasSubClassEq(RC))
697 Opcode = RISCV::PseudoVSPILL2_M4;
698 else if (RISCV::VRN3M1RegClass.hasSubClassEq(RC))
699 Opcode = RISCV::PseudoVSPILL3_M1;
700 else if (RISCV::VRN3M2RegClass.hasSubClassEq(RC))
701 Opcode = RISCV::PseudoVSPILL3_M2;
702 else if (RISCV::VRN4M1RegClass.hasSubClassEq(RC))
703 Opcode = RISCV::PseudoVSPILL4_M1;
704 else if (RISCV::VRN4M2RegClass.hasSubClassEq(RC))
705 Opcode = RISCV::PseudoVSPILL4_M2;
706 else if (RISCV::VRN5M1RegClass.hasSubClassEq(RC))
707 Opcode = RISCV::PseudoVSPILL5_M1;
708 else if (RISCV::VRN6M1RegClass.hasSubClassEq(RC))
709 Opcode = RISCV::PseudoVSPILL6_M1;
710 else if (RISCV::VRN7M1RegClass.hasSubClassEq(RC))
711 Opcode = RISCV::PseudoVSPILL7_M1;
712 else if (RISCV::VRN8M1RegClass.hasSubClassEq(RC))
713 Opcode = RISCV::PseudoVSPILL8_M1;
756 if (RISCV::GPRRegClass.hasSubClassEq(RC)) {
757 Opcode = RegInfo.getRegSizeInBits(RISCV::GPRRegClass) == 32 ? RISCV::LW
759 }
else if (RISCV::GPRF16RegClass.hasSubClassEq(RC)) {
760 Opcode = RISCV::LH_INX;
761 }
else if (RISCV::GPRF32RegClass.hasSubClassEq(RC)) {
762 Opcode = RISCV::LW_INX;
763 }
else if (RISCV::GPRPairRegClass.hasSubClassEq(RC)) {
764 if (!
STI.is64Bit() &&
STI.hasStdExtZilsd() &&
765 Alignment >=
STI.getZilsdAlign()) {
766 Opcode = RISCV::LD_RV32;
768 Opcode = RISCV::PseudoRV32ZdinxLD;
770 }
else if (RISCV::FPR16RegClass.hasSubClassEq(RC)) {
772 }
else if (RISCV::FPR32RegClass.hasSubClassEq(RC)) {
774 }
else if (RISCV::FPR64RegClass.hasSubClassEq(RC)) {
776 }
else if (RISCV::VRRegClass.hasSubClassEq(RC)) {
777 Opcode = RISCV::VL1RE8_V;
778 }
else if (RISCV::VRM2RegClass.hasSubClassEq(RC)) {
779 Opcode = RISCV::VL2RE8_V;
780 }
else if (RISCV::VRM4RegClass.hasSubClassEq(RC)) {
781 Opcode = RISCV::VL4RE8_V;
782 }
else if (RISCV::VRM8RegClass.hasSubClassEq(RC)) {
783 Opcode = RISCV::VL8RE8_V;
784 }
else if (RISCV::VRN2M1RegClass.hasSubClassEq(RC))
785 Opcode = RISCV::PseudoVRELOAD2_M1;
786 else if (RISCV::VRN2M2RegClass.hasSubClassEq(RC))
787 Opcode = RISCV::PseudoVRELOAD2_M2;
788 else if (RISCV::VRN2M4RegClass.hasSubClassEq(RC))
789 Opcode = RISCV::PseudoVRELOAD2_M4;
790 else if (RISCV::VRN3M1RegClass.hasSubClassEq(RC))
791 Opcode = RISCV::PseudoVRELOAD3_M1;
792 else if (RISCV::VRN3M2RegClass.hasSubClassEq(RC))
793 Opcode = RISCV::PseudoVRELOAD3_M2;
794 else if (RISCV::VRN4M1RegClass.hasSubClassEq(RC))
795 Opcode = RISCV::PseudoVRELOAD4_M1;
796 else if (RISCV::VRN4M2RegClass.hasSubClassEq(RC))
797 Opcode = RISCV::PseudoVRELOAD4_M2;
798 else if (RISCV::VRN5M1RegClass.hasSubClassEq(RC))
799 Opcode = RISCV::PseudoVRELOAD5_M1;
800 else if (RISCV::VRN6M1RegClass.hasSubClassEq(RC))
801 Opcode = RISCV::PseudoVRELOAD6_M1;
802 else if (RISCV::VRN7M1RegClass.hasSubClassEq(RC))
803 Opcode = RISCV::PseudoVRELOAD7_M1;
804 else if (RISCV::VRN8M1RegClass.hasSubClassEq(RC))
805 Opcode = RISCV::PseudoVRELOAD8_M1;
843 if (
Ops.size() != 1 ||
Ops[0] != 1)
846 switch (
MI.getOpcode()) {
848 if (RISCVInstrInfo::isSEXT_W(
MI))
850 if (RISCVInstrInfo::isZEXT_W(
MI))
852 if (RISCVInstrInfo::isZEXT_B(
MI))
859 case RISCV::ZEXT_H_RV32:
860 case RISCV::ZEXT_H_RV64:
867 case RISCV::VMV_X_S: {
870 if (ST.getXLen() < (1U << Log2SEW))
885 case RISCV::VFMV_F_S: {
913 return BuildMI(*
MI.getParent(), InsertPt,
MI.getDebugLoc(),
get(*LoadOpc),
922 return RISCV::PseudoCCLB;
924 return RISCV::PseudoCCLBU;
926 return RISCV::PseudoCCLH;
928 return RISCV::PseudoCCLHU;
930 return RISCV::PseudoCCLW;
932 return RISCV::PseudoCCLWU;
934 return RISCV::PseudoCCLD;
936 return RISCV::PseudoCCQC_E_LB;
937 case RISCV::QC_E_LBU:
938 return RISCV::PseudoCCQC_E_LBU;
940 return RISCV::PseudoCCQC_E_LH;
941 case RISCV::QC_E_LHU:
942 return RISCV::PseudoCCQC_E_LHU;
944 return RISCV::PseudoCCQC_E_LW;
956 if (
MI.getOpcode() != RISCV::PseudoCCMOVGPR)
961 if (!
STI.hasShortForwardBranchILoad() || !PredOpc)
965 if (
Ops.size() != 1 || (
Ops[0] != 1 &&
Ops[0] != 2))
968 bool Invert =
Ops[0] == 2;
972 if (!
MRI.constrainRegClass(DestReg, PreviousClass))
977 MI.getDebugLoc(),
get(PredOpc), DestReg);
988 unsigned BCC =
MI.getOperand(
MI.getNumExplicitOperands() - 3).getImm();
994 NewMI.
add({
MI.getOperand(
MI.getNumExplicitOperands() - 2),
995 MI.getOperand(
MI.getNumExplicitOperands() - 1)});
1004 bool DstIsDead)
const {
1020 bool SrcRenamable =
false;
1024 bool LastItem = ++Num == Seq.
size();
1029 switch (Inst.getOpndKind()) {
1032 .
addDef(DstReg, DstRegState)
1038 .
addDef(DstReg, DstRegState)
1039 .
addReg(SrcReg, SrcRegState)
1045 .
addDef(DstReg, DstRegState)
1046 .
addReg(SrcReg, SrcRegState)
1047 .
addReg(SrcReg, SrcRegState)
1052 .
addDef(DstReg, DstRegState)
1053 .
addReg(SrcReg, SrcRegState)
1061 SrcRenamable = DstRenamable;
1071 case RISCV::CV_BEQIMM:
1072 case RISCV::QC_BEQI:
1073 case RISCV::QC_E_BEQI:
1074 case RISCV::NDS_BBC:
1075 case RISCV::NDS_BEQC:
1079 case RISCV::QC_BNEI:
1080 case RISCV::QC_E_BNEI:
1081 case RISCV::CV_BNEIMM:
1082 case RISCV::NDS_BBS:
1083 case RISCV::NDS_BNEC:
1086 case RISCV::QC_BLTI:
1087 case RISCV::QC_E_BLTI:
1090 case RISCV::QC_BGEI:
1091 case RISCV::QC_E_BGEI:
1094 case RISCV::QC_BLTUI:
1095 case RISCV::QC_E_BLTUI:
1098 case RISCV::QC_BGEUI:
1099 case RISCV::QC_E_BGEUI:
1118 return (uint64_t)
C0 < (uint64_t)
C1;
1120 return (uint64_t)
C0 >= (uint64_t)
C1;
1131 "Unknown conditional branch");
1142 case RISCV::QC_MVEQ:
1143 return RISCV::QC_MVNE;
1144 case RISCV::QC_MVNE:
1145 return RISCV::QC_MVEQ;
1146 case RISCV::QC_MVLT:
1147 return RISCV::QC_MVGE;
1148 case RISCV::QC_MVGE:
1149 return RISCV::QC_MVLT;
1150 case RISCV::QC_MVLTU:
1151 return RISCV::QC_MVGEU;
1152 case RISCV::QC_MVGEU:
1153 return RISCV::QC_MVLTU;
1154 case RISCV::QC_MVEQI:
1155 return RISCV::QC_MVNEI;
1156 case RISCV::QC_MVNEI:
1157 return RISCV::QC_MVEQI;
1158 case RISCV::QC_MVLTI:
1159 return RISCV::QC_MVGEI;
1160 case RISCV::QC_MVGEI:
1161 return RISCV::QC_MVLTI;
1162 case RISCV::QC_MVLTUI:
1163 return RISCV::QC_MVGEUI;
1164 case RISCV::QC_MVGEUI:
1165 return RISCV::QC_MVLTUI;
1170 switch (SelectOpc) {
1189 case RISCV::Select_GPR_Using_CC_Imm5_Zibi:
1199 case RISCV::Select_GPR_Using_CC_SImm5_CV:
1204 return RISCV::CV_BEQIMM;
1206 return RISCV::CV_BNEIMM;
1209 case RISCV::Select_GPRNoX0_Using_CC_SImm5NonZero_QC:
1214 return RISCV::QC_BEQI;
1216 return RISCV::QC_BNEI;
1218 return RISCV::QC_BLTI;
1220 return RISCV::QC_BGEI;
1223 case RISCV::Select_GPRNoX0_Using_CC_UImm5NonZero_QC:
1228 return RISCV::QC_BLTUI;
1230 return RISCV::QC_BGEUI;
1233 case RISCV::Select_GPRNoX0_Using_CC_SImm16NonZero_QC:
1238 return RISCV::QC_E_BEQI;
1240 return RISCV::QC_E_BNEI;
1242 return RISCV::QC_E_BLTI;
1244 return RISCV::QC_E_BGEI;
1247 case RISCV::Select_GPRNoX0_Using_CC_UImm16NonZero_QC:
1252 return RISCV::QC_E_BLTUI;
1254 return RISCV::QC_E_BGEUI;
1257 case RISCV::Select_GPR_Using_CC_UImmLog2XLen_NDS:
1262 return RISCV::NDS_BBC;
1264 return RISCV::NDS_BBS;
1267 case RISCV::Select_GPR_Using_CC_UImm7_NDS:
1272 return RISCV::NDS_BEQC;
1274 return RISCV::NDS_BNEC;
1320 case RISCV::CV_BEQIMM:
1321 return RISCV::CV_BNEIMM;
1322 case RISCV::CV_BNEIMM:
1323 return RISCV::CV_BEQIMM;
1324 case RISCV::QC_BEQI:
1325 return RISCV::QC_BNEI;
1326 case RISCV::QC_BNEI:
1327 return RISCV::QC_BEQI;
1328 case RISCV::QC_BLTI:
1329 return RISCV::QC_BGEI;
1330 case RISCV::QC_BGEI:
1331 return RISCV::QC_BLTI;
1332 case RISCV::QC_BLTUI:
1333 return RISCV::QC_BGEUI;
1334 case RISCV::QC_BGEUI:
1335 return RISCV::QC_BLTUI;
1336 case RISCV::QC_E_BEQI:
1337 return RISCV::QC_E_BNEI;
1338 case RISCV::QC_E_BNEI:
1339 return RISCV::QC_E_BEQI;
1340 case RISCV::QC_E_BLTI:
1341 return RISCV::QC_E_BGEI;
1342 case RISCV::QC_E_BGEI:
1343 return RISCV::QC_E_BLTI;
1344 case RISCV::QC_E_BLTUI:
1345 return RISCV::QC_E_BGEUI;
1346 case RISCV::QC_E_BGEUI:
1347 return RISCV::QC_E_BLTUI;
1348 case RISCV::NDS_BBC:
1349 return RISCV::NDS_BBS;
1350 case RISCV::NDS_BBS:
1351 return RISCV::NDS_BBC;
1352 case RISCV::NDS_BEQC:
1353 return RISCV::NDS_BNEC;
1354 case RISCV::NDS_BNEC:
1355 return RISCV::NDS_BEQC;
1363 bool AllowModify)
const {
1364 TBB = FBB =
nullptr;
1369 if (
I ==
MBB.end() || !isUnpredicatedTerminator(*
I))
1375 int NumTerminators = 0;
1376 for (
auto J =
I.getReverse(); J !=
MBB.rend() && isUnpredicatedTerminator(*J);
1379 if (J->getDesc().isUnconditionalBranch() ||
1380 J->getDesc().isIndirectBranch()) {
1387 if (AllowModify && FirstUncondOrIndirectBr !=
MBB.end()) {
1388 while (std::next(FirstUncondOrIndirectBr) !=
MBB.end()) {
1389 std::next(FirstUncondOrIndirectBr)->eraseFromParent();
1392 I = FirstUncondOrIndirectBr;
1396 if (
I->getDesc().isIndirectBranch())
1400 if (
I->isPreISelOpcode())
1404 if (NumTerminators > 2)
1408 if (NumTerminators == 1 &&
I->getDesc().isUnconditionalBranch()) {
1414 if (NumTerminators == 1 &&
I->getDesc().isConditionalBranch()) {
1420 if (NumTerminators == 2 && std::prev(
I)->getDesc().isConditionalBranch() &&
1421 I->getDesc().isUnconditionalBranch()) {
1432 int *BytesRemoved)
const {
1439 if (!
I->getDesc().isUnconditionalBranch() &&
1440 !
I->getDesc().isConditionalBranch())
1446 I->eraseFromParent();
1450 if (
I ==
MBB.begin())
1453 if (!
I->getDesc().isConditionalBranch())
1459 I->eraseFromParent();
1472 assert(
TBB &&
"insertBranch must not be told to insert a fallthrough");
1474 "RISC-V branch conditions have two components!");
1508 assert(RS &&
"RegScavenger required for long branching");
1510 "new block should be inserted for expanding unconditional branch");
1513 "restore block should be inserted for restoring clobbered registers");
1522 "Branch offsets outside of the signed 32-bit range not supported");
1527 Register ScratchReg =
MRI.createVirtualRegister(&RISCV::GPRJALRRegClass);
1528 auto II =
MBB.end();
1534 RS->enterBasicBlockEnd(
MBB);
1541 RC = &RISCV::GPRX7RegClass;
1543 RS->scavengeRegisterBackwards(*RC,
MI.getIterator(),
1547 RS->setRegUsed(TmpGPR);
1552 TmpGPR =
STI.hasStdExtE() ? RISCV::X9 : RISCV::X27;
1558 if (FrameIndex == -1)
1563 TRI->eliminateFrameIndex(std::prev(
MI.getIterator()),
1566 MI.getOperand(1).setMBB(&RestoreBB);
1570 TRI->eliminateFrameIndex(RestoreBB.
back(),
1574 MRI.replaceRegWith(ScratchReg, TmpGPR);
1575 MRI.clearVirtRegs();
1580 assert((
Cond.size() == 3) &&
"Invalid branch condition!");
1590 if (
MI->getOpcode() == RISCV::ADDI &&
MI->getOperand(1).isReg() &&
1591 MI->getOperand(1).getReg() == RISCV::X0) {
1592 Imm =
MI->getOperand(2).getImm();
1597 if (
MI->getOpcode() == RISCV::BSETI &&
MI->getOperand(1).isReg() &&
1598 MI->getOperand(1).getReg() == RISCV::X0 &&
1599 MI->getOperand(2).getImm() == 11) {
1613 if (Reg == RISCV::X0) {
1618 if (!Reg.isVirtual())
1626 bool IsSigned =
false;
1627 bool IsEquality =
false;
1628 switch (
MI.getOpcode()) {
1664 MI.eraseFromParent();
1690 auto searchConst = [&](int64_t
C1) ->
Register {
1692 auto DefC1 = std::find_if(++
II, E, [&](
const MachineInstr &
I) ->
bool {
1695 I.getOperand(0).getReg().isVirtual();
1698 return DefC1->getOperand(0).getReg();
1711 MRI.hasOneUse(LHS.getReg()) && (IsSigned ||
C0 != -1)) {
1718 MI.eraseFromParent();
1729 MRI.hasOneUse(RHS.getReg())) {
1736 MI.eraseFromParent();
1746 assert(
MI.getDesc().isBranch() &&
"Unexpected opcode!");
1748 int NumOp =
MI.getNumExplicitOperands();
1749 return MI.getOperand(NumOp - 1).getMBB();
1753 int64_t BrOffset)
const {
1754 unsigned XLen =
STI.getXLen();
1761 case RISCV::NDS_BBC:
1762 case RISCV::NDS_BBS:
1763 case RISCV::NDS_BEQC:
1764 case RISCV::NDS_BNEC:
1774 case RISCV::CV_BEQIMM:
1775 case RISCV::CV_BNEIMM:
1776 case RISCV::QC_BEQI:
1777 case RISCV::QC_BNEI:
1778 case RISCV::QC_BGEI:
1779 case RISCV::QC_BLTI:
1780 case RISCV::QC_BLTUI:
1781 case RISCV::QC_BGEUI:
1782 case RISCV::QC_E_BEQI:
1783 case RISCV::QC_E_BNEI:
1784 case RISCV::QC_E_BGEI:
1785 case RISCV::QC_E_BLTI:
1786 case RISCV::QC_E_BLTUI:
1787 case RISCV::QC_E_BGEUI:
1790 case RISCV::PseudoBR:
1792 case RISCV::PseudoJump:
1799 const PseudoSourceValue *PSV = MMO->getPseudoValue();
1800 return PSV && PSV->isJumpTable();
1808 if (!
Reg.isVirtual())
1816 return MO.getIndex();
1825 if (!
Reg.isVirtual())
1832 switch (
MI->getOpcode()) {
1868 if (
MI.getOpcode() != RISCV::PseudoBRIND &&
1869 MI.getOpcode() != RISCV::PseudoBRINDX7)
1873 if (!Reg.isVirtual())
1884 switch (Def->getOpcode()) {
1925 case RISCV::ADD:
return RISCV::PseudoCCADD;
1926 case RISCV::SUB:
return RISCV::PseudoCCSUB;
1927 case RISCV::SLL:
return RISCV::PseudoCCSLL;
1928 case RISCV::SRL:
return RISCV::PseudoCCSRL;
1929 case RISCV::SRA:
return RISCV::PseudoCCSRA;
1930 case RISCV::AND:
return RISCV::PseudoCCAND;
1931 case RISCV::OR:
return RISCV::PseudoCCOR;
1932 case RISCV::XOR:
return RISCV::PseudoCCXOR;
1933 case RISCV::MAX:
return RISCV::PseudoCCMAX;
1934 case RISCV::MAXU:
return RISCV::PseudoCCMAXU;
1935 case RISCV::MIN:
return RISCV::PseudoCCMIN;
1936 case RISCV::MINU:
return RISCV::PseudoCCMINU;
1937 case RISCV::MUL:
return RISCV::PseudoCCMUL;
1938 case RISCV::LUI:
return RISCV::PseudoCCLUI;
1939 case RISCV::QC_LI:
return RISCV::PseudoCCQC_LI;
1940 case RISCV::QC_E_LI:
return RISCV::PseudoCCQC_E_LI;
1942 case RISCV::ADDI:
return RISCV::PseudoCCADDI;
1943 case RISCV::SLLI:
return RISCV::PseudoCCSLLI;
1944 case RISCV::SRLI:
return RISCV::PseudoCCSRLI;
1945 case RISCV::SRAI:
return RISCV::PseudoCCSRAI;
1946 case RISCV::ANDI:
return RISCV::PseudoCCANDI;
1947 case RISCV::ORI:
return RISCV::PseudoCCORI;
1948 case RISCV::XORI:
return RISCV::PseudoCCXORI;
1950 case RISCV::ADDW:
return RISCV::PseudoCCADDW;
1951 case RISCV::SUBW:
return RISCV::PseudoCCSUBW;
1952 case RISCV::SLLW:
return RISCV::PseudoCCSLLW;
1953 case RISCV::SRLW:
return RISCV::PseudoCCSRLW;
1954 case RISCV::SRAW:
return RISCV::PseudoCCSRAW;
1956 case RISCV::ADDIW:
return RISCV::PseudoCCADDIW;
1957 case RISCV::SLLIW:
return RISCV::PseudoCCSLLIW;
1958 case RISCV::SRLIW:
return RISCV::PseudoCCSRLIW;
1959 case RISCV::SRAIW:
return RISCV::PseudoCCSRAIW;
1961 case RISCV::ANDN:
return RISCV::PseudoCCANDN;
1962 case RISCV::ORN:
return RISCV::PseudoCCORN;
1963 case RISCV::XNOR:
return RISCV::PseudoCCXNOR;
1965 case RISCV::NDS_BFOS:
return RISCV::PseudoCCNDS_BFOS;
1966 case RISCV::NDS_BFOZ:
return RISCV::PseudoCCNDS_BFOZ;
1970 return RISCV::INSTRUCTION_LIST_END;
1979 if (!
Reg.isVirtual())
1981 if (!
MRI.hasOneNonDBGUse(
Reg))
1987 if (!STI.hasShortForwardBranchIMinMax() &&
1988 (
MI->getOpcode() == RISCV::MAX ||
MI->getOpcode() == RISCV::MIN ||
1989 MI->getOpcode() == RISCV::MINU ||
MI->getOpcode() == RISCV::MAXU))
1992 if (!STI.hasShortForwardBranchIMul() &&
MI->getOpcode() == RISCV::MUL)
1999 if (
MI->getOpcode() == RISCV::ADDI &&
MI->getOperand(1).isReg() &&
2000 MI->getOperand(1).getReg() == RISCV::X0)
2005 if (MO.isFI() || MO.isCPI() || MO.isJTI())
2015 if (MO.getReg().isPhysical() && !
MRI.isConstantPhysReg(MO.getReg()))
2018 bool DontMoveAcrossStores =
true;
2019 if (!
MI->isSafeToMove(DontMoveAcrossStores))
2027 bool PreferFalse)
const {
2028 assert(
MI.getOpcode() == RISCV::PseudoCCMOVGPR &&
2029 "Unknown select instruction");
2030 if (!
STI.hasShortForwardBranchIALU())
2036 bool Invert = !
DefMI;
2044 Register DestReg =
MI.getOperand(0).getReg();
2046 if (!
MRI.constrainRegClass(DestReg, PreviousClass))
2050 assert(PredOpc != RISCV::INSTRUCTION_LIST_END &&
"Unexpected opcode!");
2057 NewMI.
add(FalseReg);
2065 unsigned BCCOpcode =
MI.getOperand(
MI.getNumExplicitOperands() - 3).getImm();
2071 NewMI.
add(
MI.getOperand(
MI.getNumExplicitOperands() - 2));
2072 NewMI.
add(
MI.getOperand(
MI.getNumExplicitOperands() - 1));
2082 if (
DefMI->getParent() !=
MI.getParent())
2086 DefMI->eraseFromParent();
2091 if (
MI.isMetaInstruction())
2094 unsigned Opcode =
MI.getOpcode();
2096 if (Opcode == TargetOpcode::INLINEASM ||
2097 Opcode == TargetOpcode::INLINEASM_BR) {
2099 return getInlineAsmLength(
MI.getOperand(0).getSymbolName(),
2104 if (
STI.hasStdExtZca()) {
2105 if (
unsigned Size = getCompressedSize(
MI,
STI))
2112 if (Opcode == TargetOpcode::BUNDLE)
2113 return getInstBundleSize(
MI);
2115 if (
MI.getParent() &&
MI.getParent()->getParent()) {
2116 if (
unsigned Size = getCompressedSize(
MI,
STI))
2121 case RISCV::PseudoMV_FPR16INX:
2122 case RISCV::PseudoMV_FPR32INX:
2123 case RISCV::PseudoClearGPR:
2125 return STI.hasStdExtZca() ? 2 : 4;
2127 case RISCV::PseudoCCMOVGPRNoX0:
2128 return get(
MI.getOperand(
MI.getNumExplicitOperands() - 3).getImm())
2131 case RISCV::PseudoCCMOVGPR:
2132 case RISCV::PseudoCCADD:
2133 case RISCV::PseudoCCSUB:
2134 case RISCV::PseudoCCSLL:
2135 case RISCV::PseudoCCSRL:
2136 case RISCV::PseudoCCSRA:
2137 case RISCV::PseudoCCAND:
2138 case RISCV::PseudoCCOR:
2139 case RISCV::PseudoCCXOR:
2140 case RISCV::PseudoCCADDI:
2141 case RISCV::PseudoCCANDI:
2142 case RISCV::PseudoCCORI:
2143 case RISCV::PseudoCCXORI:
2144 case RISCV::PseudoCCLUI:
2145 case RISCV::PseudoCCSLLI:
2146 case RISCV::PseudoCCSRLI:
2147 case RISCV::PseudoCCSRAI:
2148 case RISCV::PseudoCCADDW:
2149 case RISCV::PseudoCCSUBW:
2150 case RISCV::PseudoCCSLLW:
2151 case RISCV::PseudoCCSRLW:
2152 case RISCV::PseudoCCSRAW:
2153 case RISCV::PseudoCCADDIW:
2154 case RISCV::PseudoCCSLLIW:
2155 case RISCV::PseudoCCSRLIW:
2156 case RISCV::PseudoCCSRAIW:
2157 case RISCV::PseudoCCANDN:
2158 case RISCV::PseudoCCORN:
2159 case RISCV::PseudoCCXNOR:
2160 case RISCV::PseudoCCMAX:
2161 case RISCV::PseudoCCMIN:
2162 case RISCV::PseudoCCMAXU:
2163 case RISCV::PseudoCCMINU:
2164 case RISCV::PseudoCCMUL:
2165 case RISCV::PseudoCCLB:
2166 case RISCV::PseudoCCLH:
2167 case RISCV::PseudoCCLW:
2168 case RISCV::PseudoCCLHU:
2169 case RISCV::PseudoCCLBU:
2170 case RISCV::PseudoCCLWU:
2171 case RISCV::PseudoCCLD:
2172 case RISCV::PseudoCCQC_LI:
2173 return get(
MI.getOperand(
MI.getNumExplicitOperands() - 3).getImm())
2176 case RISCV::PseudoCCQC_E_LI:
2177 case RISCV::PseudoCCQC_E_LB:
2178 case RISCV::PseudoCCQC_E_LH:
2179 case RISCV::PseudoCCQC_E_LW:
2180 case RISCV::PseudoCCQC_E_LHU:
2181 case RISCV::PseudoCCQC_E_LBU:
2182 return get(
MI.getOperand(
MI.getNumExplicitOperands() - 3).getImm())
2185 case TargetOpcode::STACKMAP:
2188 case TargetOpcode::PATCHPOINT:
2191 case TargetOpcode::STATEPOINT: {
2195 return std::max(NumBytes, 8U);
2197 case TargetOpcode::PATCHABLE_FUNCTION_ENTER:
2198 case TargetOpcode::PATCHABLE_FUNCTION_EXIT:
2199 case TargetOpcode::PATCHABLE_TAIL_CALL: {
2202 if (Opcode == TargetOpcode::PATCHABLE_FUNCTION_ENTER &&
2203 F.hasFnAttribute(
"patchable-function-entry")) {
2205 F.getFnAttributeAsParsedInteger(
"patchable-function-entry");
2207 return (
STI.hasStdExtZca() ? 2 : 4) * Num;
2211 return STI.is64Bit() ? 68 : 44;
2214 return get(Opcode).getSize();
2219 const unsigned Opcode =
MI.getOpcode();
2223 case RISCV::FSGNJ_D:
2224 case RISCV::FSGNJ_S:
2225 case RISCV::FSGNJ_H:
2226 case RISCV::FSGNJ_D_INX:
2227 case RISCV::FSGNJ_D_IN32X:
2228 case RISCV::FSGNJ_S_INX:
2229 case RISCV::FSGNJ_H_INX:
2231 return MI.getOperand(1).isReg() &&
MI.getOperand(2).isReg() &&
2232 MI.getOperand(1).getReg() ==
MI.getOperand(2).getReg();
2236 return (
MI.getOperand(1).isReg() &&
2237 MI.getOperand(1).getReg() == RISCV::X0) ||
2238 (
MI.getOperand(2).isImm() &&
MI.getOperand(2).getImm() == 0);
2240 return MI.isAsCheapAsAMove();
2243std::optional<DestSourcePair>
2247 switch (
MI.getOpcode()) {
2253 if (
MI.getOperand(1).isReg() &&
MI.getOperand(1).getReg() == RISCV::X0 &&
2254 MI.getOperand(2).isReg())
2256 if (
MI.getOperand(2).isReg() &&
MI.getOperand(2).getReg() == RISCV::X0 &&
2257 MI.getOperand(1).isReg())
2262 if (
MI.getOperand(1).isReg() &&
MI.getOperand(2).isImm() &&
2263 MI.getOperand(2).getImm() == 0)
2267 if (
MI.getOperand(2).isReg() &&
MI.getOperand(2).getReg() == RISCV::X0 &&
2268 MI.getOperand(1).isReg())
2272 case RISCV::SH1ADD_UW:
2274 case RISCV::SH2ADD_UW:
2276 case RISCV::SH3ADD_UW:
2277 if (
MI.getOperand(1).isReg() &&
MI.getOperand(1).getReg() == RISCV::X0 &&
2278 MI.getOperand(2).isReg())
2281 case RISCV::FSGNJ_D:
2282 case RISCV::FSGNJ_S:
2283 case RISCV::FSGNJ_H:
2284 case RISCV::FSGNJ_D_INX:
2285 case RISCV::FSGNJ_D_IN32X:
2286 case RISCV::FSGNJ_S_INX:
2287 case RISCV::FSGNJ_H_INX:
2289 if (
MI.getOperand(1).isReg() &&
MI.getOperand(2).isReg() &&
2290 MI.getOperand(1).getReg() ==
MI.getOperand(2).getReg())
2294 return std::nullopt;
2298 std::optional<MachineTraceStrategy> Forced =
2299 STI.getCLOpts().force_machine_combiner_strategy;
2304 const auto &SchedModel =
STI.getSchedModel();
2305 return (!SchedModel.hasInstrSchedModel() || SchedModel.isOutOfOrder())
2317 RISCV::getNamedOperandIdx(Root.
getOpcode(), RISCV::OpName::frm);
2321 return RISCV::getNamedOperandIdx(
MI->getOpcode(),
2322 RISCV::OpName::frm) < 0;
2324 "New instructions require FRM whereas the old one does not have it");
2331 for (
auto *NewMI : InsInstrs) {
2333 if (
static_cast<unsigned>(RISCV::getNamedOperandIdx(
2334 NewMI->getOpcode(), RISCV::OpName::frm)) != NewMI->getNumOperands())
2376bool RISCVInstrInfo::isVectorAssociativeAndCommutative(
const MachineInstr &Inst,
2377 bool Invert)
const {
2378#define OPCODE_LMUL_CASE(OPC) \
2379 case RISCV::OPC##_M1: \
2380 case RISCV::OPC##_M2: \
2381 case RISCV::OPC##_M4: \
2382 case RISCV::OPC##_M8: \
2383 case RISCV::OPC##_MF2: \
2384 case RISCV::OPC##_MF4: \
2385 case RISCV::OPC##_MF8
2387#define OPCODE_LMUL_MASK_CASE(OPC) \
2388 case RISCV::OPC##_M1_MASK: \
2389 case RISCV::OPC##_M2_MASK: \
2390 case RISCV::OPC##_M4_MASK: \
2391 case RISCV::OPC##_M8_MASK: \
2392 case RISCV::OPC##_MF2_MASK: \
2393 case RISCV::OPC##_MF4_MASK: \
2394 case RISCV::OPC##_MF8_MASK
2399 Opcode = *InvOpcode;
2416#undef OPCODE_LMUL_MASK_CASE
2417#undef OPCODE_LMUL_CASE
2420bool RISCVInstrInfo::areRVVInstsReassociable(
const MachineInstr &Root,
2433 auto checkImmOperand = [&](
unsigned OpIdx) {
2437 auto checkRegOperand = [&](
unsigned OpIdx) {
2445 if (!checkRegOperand(1))
2460 bool SeenMI2 =
false;
2470 if (It->modifiesRegister(RISCV::V0,
TRI)) {
2471 Register SrcReg = It->getOperand(1).getReg();
2489 if (MI1VReg != SrcReg)
2498 assert(SeenMI2 &&
"Prev is expected to appear before Root");
2509 const MachineOperand &Op1 = Root.
getOperand(OpIdx);
2510 const MachineOperand &Op2 = Prev.
getOperand(OpIdx);
2538bool RISCVInstrInfo::hasReassociableVectorSibling(
const MachineInstr &Inst,
2539 bool &Commuted)
const {
2543 "Expect the present of passthrough operand.");
2549 Commuted = !areRVVInstsReassociable(Inst, *MI1) &&
2550 areRVVInstsReassociable(Inst, *MI2);
2554 return areRVVInstsReassociable(Inst, *MI1) &&
2555 (isVectorAssociativeAndCommutative(*MI1) ||
2556 isVectorAssociativeAndCommutative(*MI1,
true)) &&
2563 if (!isVectorAssociativeAndCommutative(Inst) &&
2564 !isVectorAssociativeAndCommutative(Inst,
true))
2576 MI1 =
MRI.getUniqueVRegDef(Op1.
getReg());
2578 MI2 =
MRI.getUniqueVRegDef(Op2.
getReg());
2590 for (
unsigned I = 0;
I < 5; ++
I)
2596 bool &Commuted)
const {
2597 if (isVectorAssociativeAndCommutative(Inst) ||
2598 isVectorAssociativeAndCommutative(Inst,
true))
2599 return hasReassociableVectorSibling(Inst, Commuted);
2605 unsigned OperandIdx = Commuted ? 2 : 1;
2609 int16_t InstFrmOpIdx =
2610 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::frm);
2611 int16_t SiblingFrmOpIdx =
2612 RISCV::getNamedOperandIdx(Sibling.
getOpcode(), RISCV::OpName::frm);
2614 return (InstFrmOpIdx < 0 && SiblingFrmOpIdx < 0) ||
2619 bool Invert)
const {
2620 if (isVectorAssociativeAndCommutative(Inst, Invert))
2628 Opc = *InverseOpcode;
2673std::optional<unsigned>
2675#define RVV_OPC_LMUL_CASE(OPC, INV) \
2676 case RISCV::OPC##_M1: \
2677 return RISCV::INV##_M1; \
2678 case RISCV::OPC##_M2: \
2679 return RISCV::INV##_M2; \
2680 case RISCV::OPC##_M4: \
2681 return RISCV::INV##_M4; \
2682 case RISCV::OPC##_M8: \
2683 return RISCV::INV##_M8; \
2684 case RISCV::OPC##_MF2: \
2685 return RISCV::INV##_MF2; \
2686 case RISCV::OPC##_MF4: \
2687 return RISCV::INV##_MF4; \
2688 case RISCV::OPC##_MF8: \
2689 return RISCV::INV##_MF8
2691#define RVV_OPC_LMUL_MASK_CASE(OPC, INV) \
2692 case RISCV::OPC##_M1_MASK: \
2693 return RISCV::INV##_M1_MASK; \
2694 case RISCV::OPC##_M2_MASK: \
2695 return RISCV::INV##_M2_MASK; \
2696 case RISCV::OPC##_M4_MASK: \
2697 return RISCV::INV##_M4_MASK; \
2698 case RISCV::OPC##_M8_MASK: \
2699 return RISCV::INV##_M8_MASK; \
2700 case RISCV::OPC##_MF2_MASK: \
2701 return RISCV::INV##_MF2_MASK; \
2702 case RISCV::OPC##_MF4_MASK: \
2703 return RISCV::INV##_MF4_MASK; \
2704 case RISCV::OPC##_MF8_MASK: \
2705 return RISCV::INV##_MF8_MASK
2709 return std::nullopt;
2711 return RISCV::FSUB_H;
2713 return RISCV::FSUB_S;
2715 return RISCV::FSUB_D;
2717 return RISCV::FADD_H;
2719 return RISCV::FADD_S;
2721 return RISCV::FADD_D;
2738#undef RVV_OPC_LMUL_MASK_CASE
2739#undef RVV_OPC_LMUL_CASE
2744 bool DoRegPressureReduce) {
2760 if (DoRegPressureReduce && !
MRI.hasOneNonDBGUse(
MI->getOperand(0).getReg()))
2771 bool DoRegPressureReduce) {
2778 DoRegPressureReduce)) {
2784 DoRegPressureReduce)) {
2794 bool DoRegPressureReduce) {
2802 unsigned CombineOpc) {
2809 if (!
MI ||
MI->getParent() != &
MBB ||
MI->getOpcode() != CombineOpc)
2812 if (!
MRI.hasOneNonDBGUse(
MI->getOperand(0).getReg()))
2823 unsigned OuterShiftAmt) {
2829 if (InnerShiftAmt < OuterShiftAmt || (InnerShiftAmt - OuterShiftAmt) > 3)
2856 case RISCV::SH1ADD_UW:
2858 case RISCV::SH2ADD_UW:
2860 case RISCV::SH3ADD_UW:
2906 bool DoRegPressureReduce)
const {
2915 DoRegPressureReduce);
2923 return RISCV::FMADD_H;
2925 return RISCV::FMADD_S;
2927 return RISCV::FMADD_D;
2997 assert(OuterShiftAmt != 0 &&
"Unexpected opcode");
3004 assert(InnerShiftAmt >= OuterShiftAmt &&
"Unexpected shift amount");
3007 switch (InnerShiftAmt - OuterShiftAmt) {
3011 InnerOpc = RISCV::ADD;
3014 InnerOpc = RISCV::SH1ADD;
3017 InnerOpc = RISCV::SH2ADD;
3020 InnerOpc = RISCV::SH3ADD;
3028 Register NewVR =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
3038 InstrIdxForVirtReg.
insert(std::make_pair(NewVR, 0));
3055 DelInstrs, InstrIdxForVirtReg);
3082 for (
const auto &[Index, Operand] :
enumerate(
Desc.operands())) {
3084 unsigned OpType = Operand.OperandType;
3090 ErrInfo =
"Expected an immediate operand.";
3099#define CASE_OPERAND_UIMM(NUM) \
3100 case RISCVOp::OPERAND_UIMM##NUM: \
3101 Ok = isUInt<NUM>(Imm); \
3103#define CASE_OPERAND_UIMM_LSB_ZEROS(BITS, SUFFIX) \
3104 case RISCVOp::OPERAND_UIMM##BITS##_LSB##SUFFIX: { \
3105 constexpr size_t NumZeros = sizeof(#SUFFIX) - 1; \
3106 Ok = isShiftedUInt<BITS - NumZeros, NumZeros>(Imm); \
3109#define CASE_OPERAND_SIMM(NUM) \
3110 case RISCVOp::OPERAND_SIMM##NUM: \
3111 Ok = isInt<NUM>(Imm); \
3140 Ok =
Imm >= 1 &&
Imm <= 16;
3149 Ok =
Imm >= 1 &&
Imm <= 32;
3152 Ok =
Imm >= 1 &&
Imm <= 64;
3188 Ok =
Imm >= -15 &&
Imm <= 16;
3216 Ok = Ok &&
Imm != 0;
3222 Ok =
Imm >= 0 &&
Imm <= 10;
3225 Ok =
Imm >= 0 &&
Imm <= 7;
3228 Ok =
Imm >= 1 &&
Imm <= 10;
3231 Ok =
Imm >= 2 &&
Imm <= 14;
3240 Ok =
Imm >= 0 &&
Imm <= 48 &&
Imm % 16 == 0;
3285 ErrInfo =
"Invalid immediate";
3294 ErrInfo =
"Expected a non-register operand.";
3298 ErrInfo =
"Invalid immediate";
3307 ErrInfo =
"Expected a non-register operand.";
3311 ErrInfo =
"Invalid immediate";
3319 ErrInfo =
"Expected a non-register operand.";
3323 ErrInfo =
"Invalid immediate";
3332 ErrInfo =
"Invalid immediate";
3335 }
else if (!MO.
isReg()) {
3336 ErrInfo =
"Expected a register or immediate operand.";
3342 ErrInfo =
"Expected a register or immediate operand.";
3349 const uint64_t TSFlags =
Desc.TSFlags;
3352 if (!
Op.isImm() && !
Op.isReg()) {
3353 ErrInfo =
"Invalid operand type for VL operand";
3356 if (
Op.isReg() &&
Op.getReg().isValid()) {
3358 auto *RC =
MRI.getRegClass(
Op.getReg());
3359 if (!RISCV::GPRNoX0RegClass.hasSubClassEq(RC)) {
3360 ErrInfo =
"Invalid register class for VL operand";
3365 ErrInfo =
"VL operand w/o SEW operand?";
3371 if (!
MI.getOperand(OpIdx).isImm()) {
3372 ErrInfo =
"SEW value expected to be an immediate";
3375 uint64_t Log2SEW =
MI.getOperand(OpIdx).getImm();
3377 ErrInfo =
"Unexpected SEW value";
3380 unsigned SEW = Log2SEW ? 1 << Log2SEW : 8;
3382 ErrInfo =
"Unexpected SEW value";
3388 if (!
MI.getOperand(OpIdx).isImm()) {
3389 ErrInfo =
"Policy operand expected to be an immediate";
3392 uint64_t Policy =
MI.getOperand(OpIdx).getImm();
3394 ErrInfo =
"Invalid Policy Value";
3398 ErrInfo =
"policy operand w/o VL operand?";
3406 if (!
MI.isRegTiedToUseOperand(0, &UseOpIdx)) {
3407 ErrInfo =
"policy operand w/o tied operand?";
3414 !
MI.readsRegister(RISCV::FRM,
nullptr)) {
3415 ErrInfo =
"dynamic rounding mode should read FRM";
3437 case RISCV::LD_RV32:
3447 case RISCV::SD_RV32:
3463 int64_t NewOffset = OldOffset + Disp;
3485 "Addressing mode not supported for folding");
3557 case RISCV::LD_RV32:
3560 case RISCV::SD_RV32:
3567 OffsetIsScalable =
false;
3583 if (BaseOps1.
front()->isIdenticalTo(*BaseOps2.
front()))
3591 if (MO1->getAddrSpace() != MO2->getAddrSpace())
3594 auto Base1 = MO1->getValue();
3595 auto Base2 = MO2->getValue();
3596 if (!Base1 || !Base2)
3604 return Base1 == Base2;
3610 int64_t Offset2,
bool OffsetIsScalable2,
unsigned ClusterSize,
3611 unsigned NumBytes)
const {
3614 if (!BaseOps1.
empty() && !BaseOps2.
empty()) {
3619 }
else if (!BaseOps1.
empty() || !BaseOps2.
empty()) {
3625 BaseOps1.
front()->getParent()->getMF()->getSubtarget().getCacheLineSize();
3631 return ClusterSize <= 4 && std::abs(Offset1 - Offset2) <
CacheLineSize;
3680 int64_t OffsetA = 0, OffsetB = 0;
3686 int LowOffset = std::min(OffsetA, OffsetB);
3687 int HighOffset = std::max(OffsetA, OffsetB);
3688 LocationSize LowWidth = (LowOffset == OffsetA) ? WidthA : WidthB;
3690 LowOffset + (
int)LowWidth.
getValue() <= HighOffset)
3697std::pair<unsigned, unsigned>
3700 return std::make_pair(TF & Mask, TF & ~Mask);
3706 static const std::pair<unsigned, const char *> TargetFlags[] = {
3707 {MO_CALL,
"riscv-call"},
3708 {MO_LO,
"riscv-lo"},
3709 {MO_HI,
"riscv-hi"},
3710 {MO_PCREL_LO,
"riscv-pcrel-lo"},
3711 {MO_PCREL_HI,
"riscv-pcrel-hi"},
3712 {MO_GOT_HI,
"riscv-got-hi"},
3713 {MO_TPREL_LO,
"riscv-tprel-lo"},
3714 {MO_TPREL_HI,
"riscv-tprel-hi"},
3715 {MO_TPREL_ADD,
"riscv-tprel-add"},
3716 {MO_TLS_GOT_HI,
"riscv-tls-got-hi"},
3717 {MO_TLS_GD_HI,
"riscv-tls-gd-hi"},
3718 {MO_TLSDESC_HI,
"riscv-tlsdesc-hi"},
3719 {MO_TLSDESC_LOAD_LO,
"riscv-tlsdesc-load-lo"},
3720 {MO_TLSDESC_ADD_LO,
"riscv-tlsdesc-add-lo"},
3721 {MO_TLSDESC_CALL,
"riscv-tlsdesc-call"},
3722 {MO_QC_ACCESS,
"riscv-qc-access"},
3728 unsigned &Flags)
const {
3748 return F.getFnAttribute(
"fentry-call").getValueAsBool() ||
3749 F.hasFnAttribute(
"patchable-function-entry");
3754 return MI.readsRegister(RegNo,
TRI) ||
3755 MI.getDesc().hasImplicitUseOfPhysReg(RegNo);
3760 return MI.modifiesRegister(RegNo,
TRI) ||
3761 MI.getDesc().hasImplicitDefOfPhysReg(RegNo);
3765 if (!
MBB.back().isReturn())
3811 if (
C.isAvailableAcrossAndOutOfSeq(
Reg,
TRI) &&
3812 C.isAvailableInsideSeq(
Reg,
TRI)) {
3830 if (
C.back().isReturn() &&
3831 !
C.isAvailableAcrossAndOutOfSeq(TailExpandUseReg, RegInfo)) {
3833 LLVM_DEBUG(
dbgs() <<
"Cannot be outlined between: " <<
C.front() <<
"and "
3835 LLVM_DEBUG(
dbgs() <<
"Because the tail-call register is live across "
3836 "the proposed outlined function call\n");
3842 if (
C.back().isReturn()) {
3844 "The candidate who uses return instruction must be outlined "
3851 if (!
C.isAvailableInsideSeq(RISCV::X5, RegInfo))
3855 if (
C.isAvailableAcrossAndOutOfSeq(RISCV::X5, RegInfo))
3865std::optional<std::unique_ptr<outliner::OutlinedFunction>>
3868 std::vector<outliner::Candidate> &RepeatedSequenceLocs,
3869 unsigned MinRepeats)
const {
3877 if (RepeatedSequenceLocs.size() < MinRepeats)
3878 return std::nullopt;
3882 unsigned InstrSizeCExt =
3884 unsigned CallOverhead = 0, FrameOverhead = 0;
3887 unsigned CFICount = 0;
3888 for (
auto &
I : Candidate) {
3889 if (
I.isCFIInstruction())
3900 std::vector<MCCFIInstruction> CFIInstructions =
3901 C.getMF()->getFrameInstructions();
3903 if (CFICount > 0 && CFICount != CFIInstructions.size())
3904 return std::nullopt;
3912 CallOverhead = 4 + InstrSizeCExt;
3919 FrameOverhead = InstrSizeCExt;
3925 return std::nullopt;
3929 for (
auto &
C : RepeatedSequenceLocs) {
3931 if (
C.isAvailableAcrossAndOutOfSeq(RISCV::X5, RegInfo)) {
3933 unsigned CandCallOverhead = 8;
3938 unsigned CandCallOverhead = InstrSizeCExt + 8 + InstrSizeCExt;
3943 for (
auto &
C : RepeatedSequenceLocs)
3944 C.setCallInfo(MOCI, CallOverhead);
3947 unsigned SequenceSize = 0;
3948 for (
auto &
MI : Candidate)
3951 return std::make_unique<outliner::OutlinedFunction>(
3952 RepeatedSequenceLocs, SequenceSize, FrameOverhead, MOCI);
3958 unsigned Flags)
const {
3962 MBB->getParent()->getSubtarget().getRegisterInfo();
3963 const auto &
F =
MI.getMF()->getFunction();
3968 if (
MI.isCFIInstruction())
3976 for (
const auto &MO :
MI.operands()) {
3981 (
MI.getMF()->getTarget().getFunctionSections() ||
F.hasComdat() ||
3982 F.hasSection() ||
F.getSectionPrefix()))
3999 MBB.addLiveIn(RISCV::X5);
4017 .addGlobalAddress(M.getNamedValue(MF.
getName()),
4024 assert(SaveReg &&
"Cannot find an available register to save/restore X5.");
4035 .addGlobalAddress(M.getNamedValue(MF.
getName()), 0,
4051 .addGlobalAddress(M.getNamedValue(MF.
getName()), 0,
4059 bool AllowSideEffects)
const {
4064 if (
TRI.isGeneralPurposeRegister(MF, Reg)) {
4066 }
else if (RISCV::FPR32RegClass.
contains(Reg)) {
4068 }
else if (RISCV::FPR64RegClass.
contains(Reg)) {
4070 }
else if (RISCV::FPR128RegClass.
contains(Reg)) {
4072 }
else if (RISCV::VRRegClass.
contains(Reg)) {
4076 "buildClearRegister is not implemented for " +
TRI.getRegAsmName(Reg));
4086 return std::nullopt;
4090 if (
MI.getOpcode() == RISCV::ADDI &&
MI.getOperand(1).isReg() &&
4091 MI.getOperand(2).isImm())
4092 return RegImmPair{
MI.getOperand(1).getReg(),
MI.getOperand(2).getImm()};
4094 return std::nullopt;
4100 unsigned OpIdx)
const {
4102 std::string GenericComment =
4104 if (!GenericComment.empty())
4105 return GenericComment;
4108 if (OpIdx >=
Desc.getNumOperands())
4109 return std::string();
4111 std::string Comment;
4118 switch (OpInfo.OperandType) {
4121 unsigned Imm =
Op.getImm();
4126 unsigned Imm =
Op.getImm();
4131 unsigned Imm =
Op.getImm();
4137 unsigned Log2SEW =
Op.getImm();
4138 unsigned SEW = Log2SEW ? 1 << Log2SEW : 8;
4144 unsigned Policy =
Op.getImm();
4146 "Invalid Policy Value");
4152 if (
Op.isImm() &&
Op.getImm() == -1)
4174#define CASE_RVV_OPCODE_UNMASK_LMUL(OP, LMUL) \
4175 RISCV::Pseudo##OP##_##LMUL
4177#define CASE_RVV_OPCODE_MASK_LMUL(OP, LMUL) \
4178 RISCV::Pseudo##OP##_##LMUL##_MASK
4180#define CASE_RVV_OPCODE_LMUL(OP, LMUL) \
4181 CASE_RVV_OPCODE_UNMASK_LMUL(OP, LMUL): \
4182 case CASE_RVV_OPCODE_MASK_LMUL(OP, LMUL)
4184#define CASE_RVV_OPCODE_UNMASK_WIDEN(OP) \
4185 CASE_RVV_OPCODE_UNMASK_LMUL(OP, MF8): \
4186 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, MF4): \
4187 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, MF2): \
4188 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, M1): \
4189 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, M2): \
4190 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, M4)
4192#define CASE_RVV_OPCODE_UNMASK(OP) \
4193 CASE_RVV_OPCODE_UNMASK_WIDEN(OP): \
4194 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, M8)
4196#define CASE_RVV_OPCODE_MASK_WIDEN(OP) \
4197 CASE_RVV_OPCODE_MASK_LMUL(OP, MF8): \
4198 case CASE_RVV_OPCODE_MASK_LMUL(OP, MF4): \
4199 case CASE_RVV_OPCODE_MASK_LMUL(OP, MF2): \
4200 case CASE_RVV_OPCODE_MASK_LMUL(OP, M1): \
4201 case CASE_RVV_OPCODE_MASK_LMUL(OP, M2): \
4202 case CASE_RVV_OPCODE_MASK_LMUL(OP, M4)
4204#define CASE_RVV_OPCODE_MASK(OP) \
4205 CASE_RVV_OPCODE_MASK_WIDEN(OP): \
4206 case CASE_RVV_OPCODE_MASK_LMUL(OP, M8)
4208#define CASE_RVV_OPCODE_WIDEN(OP) \
4209 CASE_RVV_OPCODE_UNMASK_WIDEN(OP): \
4210 case CASE_RVV_OPCODE_MASK_WIDEN(OP)
4212#define CASE_RVV_OPCODE(OP) \
4213 CASE_RVV_OPCODE_UNMASK(OP): \
4214 case CASE_RVV_OPCODE_MASK(OP)
4218#define CASE_VMA_OPCODE_COMMON(OP, TYPE, LMUL) \
4219 RISCV::PseudoV##OP##_##TYPE##_##LMUL
4221#define CASE_VMA_OPCODE_LMULS(OP, TYPE) \
4222 CASE_VMA_OPCODE_COMMON(OP, TYPE, MF8): \
4223 case CASE_VMA_OPCODE_COMMON(OP, TYPE, MF4): \
4224 case CASE_VMA_OPCODE_COMMON(OP, TYPE, MF2): \
4225 case CASE_VMA_OPCODE_COMMON(OP, TYPE, M1): \
4226 case CASE_VMA_OPCODE_COMMON(OP, TYPE, M2): \
4227 case CASE_VMA_OPCODE_COMMON(OP, TYPE, M4): \
4228 case CASE_VMA_OPCODE_COMMON(OP, TYPE, M8)
4231#define CASE_VFMA_OPCODE_COMMON(OP, TYPE, LMUL, SEW) \
4232 RISCV::PseudoV##OP##_##TYPE##_##LMUL##_##SEW
4234#define CASE_VFMA_OPCODE_LMULS_M1(OP, TYPE, SEW) \
4235 CASE_VFMA_OPCODE_COMMON(OP, TYPE, M1, SEW): \
4236 case CASE_VFMA_OPCODE_COMMON(OP, TYPE, M2, SEW): \
4237 case CASE_VFMA_OPCODE_COMMON(OP, TYPE, M4, SEW): \
4238 case CASE_VFMA_OPCODE_COMMON(OP, TYPE, M8, SEW)
4240#define CASE_VFMA_OPCODE_LMULS_MF2(OP, TYPE, SEW) \
4241 CASE_VFMA_OPCODE_COMMON(OP, TYPE, MF2, SEW): \
4242 case CASE_VFMA_OPCODE_LMULS_M1(OP, TYPE, SEW)
4244#define CASE_VFMA_OPCODE_LMULS_MF4(OP, TYPE, SEW) \
4245 CASE_VFMA_OPCODE_COMMON(OP, TYPE, MF4, SEW): \
4246 case CASE_VFMA_OPCODE_LMULS_MF2(OP, TYPE, SEW)
4248#define CASE_VFMA_OPCODE_VV(OP) \
4249 CASE_VFMA_OPCODE_LMULS_MF4(OP, VV, E16): \
4250 case CASE_VFMA_OPCODE_LMULS_MF4(OP##_ALT, VV, E16): \
4251 case CASE_VFMA_OPCODE_LMULS_MF2(OP, VV, E32): \
4252 case CASE_VFMA_OPCODE_LMULS_M1(OP, VV, E64)
4254#define CASE_VFMA_SPLATS(OP) \
4255 CASE_VFMA_OPCODE_LMULS_MF4(OP, VFPR16, E16): \
4256 case CASE_VFMA_OPCODE_LMULS_MF4(OP##_ALT, VFPR16, E16): \
4257 case CASE_VFMA_OPCODE_LMULS_MF2(OP, VFPR32, E32): \
4258 case CASE_VFMA_OPCODE_LMULS_M1(OP, VFPR64, E64)
4262 unsigned &SrcOpIdx1,
4263 unsigned &SrcOpIdx2)
const {
4265 if (!
Desc.isCommutable())
4268 switch (
MI.getOpcode()) {
4269 case RISCV::TH_MVEQZ:
4270 case RISCV::TH_MVNEZ:
4274 if (
MI.getOperand(2).getReg() == RISCV::X0)
4277 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 1, 2);
4278 case RISCV::QC_SELECTIEQ:
4279 case RISCV::QC_SELECTINE:
4280 case RISCV::QC_SELECTIIEQ:
4281 case RISCV::QC_SELECTIINE:
4282 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 1, 2);
4283 case RISCV::QC_MVEQ:
4284 case RISCV::QC_MVNE:
4285 case RISCV::QC_MVLT:
4286 case RISCV::QC_MVGE:
4287 case RISCV::QC_MVLTU:
4288 case RISCV::QC_MVGEU:
4289 case RISCV::QC_MVEQI:
4290 case RISCV::QC_MVNEI:
4291 case RISCV::QC_MVLTI:
4292 case RISCV::QC_MVGEI:
4293 case RISCV::QC_MVLTUI:
4294 case RISCV::QC_MVGEUI:
4295 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 1, 4);
4296 case RISCV::TH_MULA:
4297 case RISCV::TH_MULAW:
4298 case RISCV::TH_MULAH:
4299 case RISCV::TH_MULS:
4300 case RISCV::TH_MULSW:
4301 case RISCV::TH_MULSH:
4303 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 2, 3);
4304 case RISCV::PseudoCCMOVGPRNoX0:
4305 case RISCV::PseudoCCMOVGPR:
4307 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 1, 2);
4348 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 2, 3);
4375 unsigned CommutableOpIdx1 = 1;
4376 unsigned CommutableOpIdx2 = 3;
4377 if (!fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, CommutableOpIdx1,
4398 if (SrcOpIdx1 != CommuteAnyOperandIndex && SrcOpIdx1 > 3)
4400 if (SrcOpIdx2 != CommuteAnyOperandIndex && SrcOpIdx2 > 3)
4404 if (SrcOpIdx1 != CommuteAnyOperandIndex &&
4405 SrcOpIdx2 != CommuteAnyOperandIndex && SrcOpIdx1 != 1 && SrcOpIdx2 != 1)
4411 if (SrcOpIdx1 == CommuteAnyOperandIndex ||
4412 SrcOpIdx2 == CommuteAnyOperandIndex) {
4415 unsigned CommutableOpIdx1 = SrcOpIdx1;
4416 if (SrcOpIdx1 == SrcOpIdx2) {
4419 CommutableOpIdx1 = 1;
4420 }
else if (SrcOpIdx1 == CommuteAnyOperandIndex) {
4422 CommutableOpIdx1 = SrcOpIdx2;
4427 unsigned CommutableOpIdx2;
4428 if (CommutableOpIdx1 != 1) {
4430 CommutableOpIdx2 = 1;
4432 Register Op1Reg =
MI.getOperand(CommutableOpIdx1).getReg();
4437 if (Op1Reg !=
MI.getOperand(2).getReg())
4438 CommutableOpIdx2 = 2;
4440 CommutableOpIdx2 = 3;
4445 if (!fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, CommutableOpIdx1,
4458#define CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, LMUL) \
4459 case RISCV::PseudoV##OLDOP##_##TYPE##_##LMUL: \
4460 Opc = RISCV::PseudoV##NEWOP##_##TYPE##_##LMUL; \
4463#define CASE_VMA_CHANGE_OPCODE_LMULS(OLDOP, NEWOP, TYPE) \
4464 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF8) \
4465 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF4) \
4466 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF2) \
4467 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M1) \
4468 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M2) \
4469 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M4) \
4470 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M8)
4473#define CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, LMUL, SEW) \
4474 case RISCV::PseudoV##OLDOP##_##TYPE##_##LMUL##_##SEW: \
4475 Opc = RISCV::PseudoV##NEWOP##_##TYPE##_##LMUL##_##SEW; \
4478#define CASE_VFMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, TYPE, SEW) \
4479 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M1, SEW) \
4480 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M2, SEW) \
4481 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M4, SEW) \
4482 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M8, SEW)
4484#define CASE_VFMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, TYPE, SEW) \
4485 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF2, SEW) \
4486 CASE_VFMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, TYPE, SEW)
4488#define CASE_VFMA_CHANGE_OPCODE_LMULS_MF4(OLDOP, NEWOP, TYPE, SEW) \
4489 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF4, SEW) \
4490 CASE_VFMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, TYPE, SEW)
4492#define CASE_VFMA_CHANGE_OPCODE_VV(OLDOP, NEWOP) \
4493 CASE_VFMA_CHANGE_OPCODE_LMULS_MF4(OLDOP, NEWOP, VV, E16) \
4494 CASE_VFMA_CHANGE_OPCODE_LMULS_MF4(OLDOP##_ALT, NEWOP##_ALT, VV, E16) \
4495 CASE_VFMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, VV, E32) \
4496 CASE_VFMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, VV, E64)
4498#define CASE_VFMA_CHANGE_OPCODE_SPLATS(OLDOP, NEWOP) \
4499 CASE_VFMA_CHANGE_OPCODE_LMULS_MF4(OLDOP, NEWOP, VFPR16, E16) \
4500 CASE_VFMA_CHANGE_OPCODE_LMULS_MF4(OLDOP##_ALT, NEWOP##_ALT, VFPR16, E16) \
4501 CASE_VFMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, VFPR32, E32) \
4502 CASE_VFMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, VFPR64, E64)
4508 unsigned OpIdx2)
const {
4511 return *
MI.getParent()->getParent()->CloneMachineInstr(&
MI);
4515 switch (
MI.getOpcode()) {
4516 case RISCV::TH_MVEQZ:
4517 case RISCV::TH_MVNEZ: {
4518 auto &WorkingMI = cloneIfNew(
MI);
4519 WorkingMI.setDesc(
get(
MI.getOpcode() == RISCV::TH_MVEQZ ? RISCV::TH_MVNEZ
4520 : RISCV::TH_MVEQZ));
4524 case RISCV::QC_SELECTIEQ:
4525 case RISCV::QC_SELECTINE:
4526 case RISCV::QC_SELECTIIEQ:
4527 case RISCV::QC_SELECTIINE:
4529 case RISCV::QC_MVEQ:
4530 case RISCV::QC_MVNE:
4531 case RISCV::QC_MVLT:
4532 case RISCV::QC_MVGE:
4533 case RISCV::QC_MVLTU:
4534 case RISCV::QC_MVGEU:
4535 case RISCV::QC_MVEQI:
4536 case RISCV::QC_MVNEI:
4537 case RISCV::QC_MVLTI:
4538 case RISCV::QC_MVGEI:
4539 case RISCV::QC_MVLTUI:
4540 case RISCV::QC_MVGEUI: {
4541 auto &WorkingMI = cloneIfNew(
MI);
4546 case RISCV::PseudoCCMOVGPRNoX0:
4547 case RISCV::PseudoCCMOVGPR: {
4549 unsigned BCC =
MI.getOperand(
MI.getNumExplicitOperands() - 3).getImm();
4551 auto &WorkingMI = cloneIfNew(
MI);
4552 WorkingMI.getOperand(
MI.getNumExplicitOperands() - 3).setImm(BCC);
4576 assert((OpIdx1 == 1 || OpIdx2 == 1) &&
"Unexpected opcode index");
4577 assert((OpIdx1 == 3 || OpIdx2 == 3) &&
"Unexpected opcode index");
4579 switch (
MI.getOpcode()) {
4602 auto &WorkingMI = cloneIfNew(
MI);
4603 WorkingMI.setDesc(
get(
Opc));
4613 assert((OpIdx1 == 1 || OpIdx2 == 1) &&
"Unexpected opcode index");
4616 if (OpIdx1 == 3 || OpIdx2 == 3) {
4618 switch (
MI.getOpcode()) {
4629 auto &WorkingMI = cloneIfNew(
MI);
4630 WorkingMI.setDesc(
get(
Opc));
4642#undef CASE_VMA_CHANGE_OPCODE_COMMON
4643#undef CASE_VMA_CHANGE_OPCODE_LMULS
4644#undef CASE_VFMA_CHANGE_OPCODE_COMMON
4645#undef CASE_VFMA_CHANGE_OPCODE_LMULS_M1
4646#undef CASE_VFMA_CHANGE_OPCODE_LMULS_MF2
4647#undef CASE_VFMA_CHANGE_OPCODE_LMULS_MF4
4648#undef CASE_VFMA_CHANGE_OPCODE_VV
4649#undef CASE_VFMA_CHANGE_OPCODE_SPLATS
4651#undef CASE_RVV_OPCODE_UNMASK_LMUL
4652#undef CASE_RVV_OPCODE_MASK_LMUL
4653#undef CASE_RVV_OPCODE_LMUL
4654#undef CASE_RVV_OPCODE_UNMASK_WIDEN
4655#undef CASE_RVV_OPCODE_UNMASK
4656#undef CASE_RVV_OPCODE_MASK_WIDEN
4657#undef CASE_RVV_OPCODE_MASK
4658#undef CASE_RVV_OPCODE_WIDEN
4659#undef CASE_RVV_OPCODE
4661#undef CASE_VMA_OPCODE_COMMON
4662#undef CASE_VMA_OPCODE_LMULS
4663#undef CASE_VFMA_OPCODE_COMMON
4664#undef CASE_VFMA_OPCODE_LMULS_M1
4665#undef CASE_VFMA_OPCODE_LMULS_MF2
4666#undef CASE_VFMA_OPCODE_LMULS_MF4
4667#undef CASE_VFMA_OPCODE_VV
4668#undef CASE_VFMA_SPLATS
4671 switch (
MI.getOpcode()) {
4679 if (
MI.getOperand(1).getReg() == RISCV::X0)
4680 commuteInstruction(
MI);
4682 if (
MI.getOperand(2).getReg() == RISCV::X0) {
4683 MI.getOperand(2).ChangeToImmediate(0);
4684 MI.setDesc(
get(RISCV::ADDI));
4688 if (
MI.getOpcode() == RISCV::XOR &&
4689 MI.getOperand(1).getReg() ==
MI.getOperand(2).getReg()) {
4690 MI.getOperand(1).setReg(RISCV::X0);
4691 MI.getOperand(2).ChangeToImmediate(0);
4692 MI.setDesc(
get(RISCV::ADDI));
4699 if (
MI.getOperand(1).getReg() == RISCV::X0) {
4700 MI.setDesc(
get(RISCV::ADDI));
4706 if (
MI.getOperand(2).getReg() == RISCV::X0) {
4707 MI.getOperand(2).ChangeToImmediate(0);
4708 MI.setDesc(
get(RISCV::ADDI));
4714 if (
MI.getOperand(2).getReg() == RISCV::X0) {
4715 MI.getOperand(2).ChangeToImmediate(0);
4716 MI.setDesc(
get(RISCV::ADDIW));
4723 if (
MI.getOperand(1).getReg() == RISCV::X0)
4724 commuteInstruction(
MI);
4726 if (
MI.getOperand(2).getReg() == RISCV::X0) {
4727 MI.getOperand(2).ChangeToImmediate(0);
4728 MI.setDesc(
get(RISCV::ADDIW));
4733 case RISCV::SH1ADD_UW:
4735 case RISCV::SH2ADD_UW:
4737 case RISCV::SH3ADD_UW:
4739 if (
MI.getOperand(1).getReg() == RISCV::X0) {
4740 MI.removeOperand(1);
4742 MI.setDesc(
get(RISCV::ADDI));
4746 if (
MI.getOperand(2).getReg() == RISCV::X0) {
4747 MI.removeOperand(2);
4748 unsigned Opc =
MI.getOpcode();
4749 if (
Opc == RISCV::SH1ADD_UW ||
Opc == RISCV::SH2ADD_UW ||
4750 Opc == RISCV::SH3ADD_UW) {
4752 MI.setDesc(
get(RISCV::SLLI_UW));
4756 MI.setDesc(
get(RISCV::SLLI));
4770 if (
MI.getOperand(1).getReg() == RISCV::X0 ||
4771 MI.getOperand(2).getReg() == RISCV::X0) {
4772 MI.getOperand(1).setReg(RISCV::X0);
4773 MI.getOperand(2).ChangeToImmediate(0);
4774 MI.setDesc(
get(RISCV::ADDI));
4780 if (
MI.getOperand(1).getReg() == RISCV::X0) {
4781 MI.getOperand(2).setImm(0);
4782 MI.setDesc(
get(RISCV::ADDI));
4790 if (
MI.getOperand(1).getReg() == RISCV::X0) {
4791 MI.getOperand(2).ChangeToImmediate(0);
4792 MI.setDesc(
get(RISCV::ADDI));
4796 if (
MI.getOperand(2).getReg() == RISCV::X0) {
4797 MI.getOperand(2).ChangeToImmediate(0);
4798 MI.setDesc(
get(RISCV::ADDI));
4806 if (
MI.getOperand(1).getReg() == RISCV::X0) {
4807 MI.getOperand(2).ChangeToImmediate(0);
4808 MI.setDesc(
get(RISCV::ADDI));
4818 case RISCV::SLLI_UW:
4820 if (
MI.getOperand(1).getReg() == RISCV::X0) {
4821 MI.getOperand(2).setImm(0);
4822 MI.setDesc(
get(RISCV::ADDI));
4830 if (
MI.getOperand(1).getReg() == RISCV::X0 &&
4831 MI.getOperand(2).getReg() == RISCV::X0) {
4832 MI.getOperand(2).ChangeToImmediate(0);
4833 MI.setDesc(
get(RISCV::ADDI));
4837 if (
MI.getOpcode() == RISCV::ADD_UW &&
4838 MI.getOperand(1).getReg() == RISCV::X0) {
4839 MI.removeOperand(1);
4841 MI.setDesc(
get(RISCV::ADDI));
4847 if (
MI.getOperand(1).getReg() == RISCV::X0) {
4848 MI.getOperand(2).setImm(
MI.getOperand(2).getImm() != 0);
4849 MI.setDesc(
get(RISCV::ADDI));
4855 case RISCV::ZEXT_H_RV32:
4856 case RISCV::ZEXT_H_RV64:
4859 if (
MI.getOperand(1).getReg() == RISCV::X0) {
4861 MI.setDesc(
get(RISCV::ADDI));
4870 if (
MI.getOperand(1).getReg() ==
MI.getOperand(2).getReg()) {
4871 MI.getOperand(2).ChangeToImmediate(0);
4872 MI.setDesc(
get(RISCV::ADDI));
4879 if (
MI.getOperand(0).getReg() == RISCV::X0) {
4881 MI.removeOperand(0);
4882 MI.insert(
MI.operands_begin() + 1, {MO0});
4887 if (
MI.getOperand(0).getReg() == RISCV::X0) {
4889 MI.removeOperand(0);
4890 MI.insert(
MI.operands_begin() + 1, {MO0});
4891 MI.setDesc(
get(RISCV::BNE));
4896 if (
MI.getOperand(0).getReg() == RISCV::X0) {
4898 MI.removeOperand(0);
4899 MI.insert(
MI.operands_begin() + 1, {MO0});
4900 MI.setDesc(
get(RISCV::BEQ));
4908#define CASE_WIDEOP_OPCODE_COMMON(OP, LMUL) \
4909 RISCV::PseudoV##OP##_##LMUL##_TIED
4911#define CASE_WIDEOP_OPCODE_LMULS(OP) \
4912 CASE_WIDEOP_OPCODE_COMMON(OP, MF8): \
4913 case CASE_WIDEOP_OPCODE_COMMON(OP, MF4): \
4914 case CASE_WIDEOP_OPCODE_COMMON(OP, MF2): \
4915 case CASE_WIDEOP_OPCODE_COMMON(OP, M1): \
4916 case CASE_WIDEOP_OPCODE_COMMON(OP, M2): \
4917 case CASE_WIDEOP_OPCODE_COMMON(OP, M4)
4919#define CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, LMUL) \
4920 case RISCV::PseudoV##OP##_##LMUL##_TIED: \
4921 NewOpc = RISCV::PseudoV##OP##_##LMUL; \
4924#define CASE_WIDEOP_CHANGE_OPCODE_LMULS(OP) \
4925 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF8) \
4926 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF4) \
4927 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF2) \
4928 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, M1) \
4929 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, M2) \
4930 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, M4)
4933#define CASE_FP_WIDEOP_OPCODE_COMMON(OP, LMUL, SEW) \
4934 RISCV::PseudoV##OP##_##LMUL##_##SEW##_TIED
4936#define CASE_FP_WIDEOP_OPCODE_LMULS(OP) \
4937 CASE_FP_WIDEOP_OPCODE_COMMON(OP, MF4, E16): \
4938 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, MF2, E16): \
4939 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, MF2, E32): \
4940 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M1, E16): \
4941 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M1, E32): \
4942 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M2, E16): \
4943 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M2, E32): \
4944 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M4, E16): \
4945 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M4, E32) \
4947#define CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, LMUL, SEW) \
4948 case RISCV::PseudoV##OP##_##LMUL##_##SEW##_TIED: \
4949 NewOpc = RISCV::PseudoV##OP##_##LMUL##_##SEW; \
4952#define CASE_FP_WIDEOP_CHANGE_OPCODE_LMULS(OP) \
4953 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF4, E16) \
4954 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF2, E16) \
4955 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF2, E32) \
4956 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M1, E16) \
4957 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M1, E32) \
4958 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M2, E16) \
4959 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M2, E32) \
4960 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M4, E16) \
4961 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M4, E32) \
4963#define CASE_FP_WIDEOP_OPCODE_LMULS_ALT(OP) \
4964 CASE_FP_WIDEOP_OPCODE_COMMON(OP, MF4, E16): \
4965 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, MF2, E16): \
4966 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M1, E16): \
4967 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M2, E16): \
4968 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M4, E16)
4970#define CASE_FP_WIDEOP_CHANGE_OPCODE_LMULS_ALT(OP) \
4971 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF4, E16) \
4972 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF2, E16) \
4973 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M1, E16) \
4974 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M2, E16) \
4975 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M4, E16)
4981 switch (
MI.getOpcode()) {
4989 MI.getNumExplicitOperands() == 7 &&
4990 "Expect 7 explicit operands rd, rs2, rs1, rm, vl, sew, policy");
4997 switch (
MI.getOpcode()) {
5009 .
add(
MI.getOperand(0))
5011 .
add(
MI.getOperand(1))
5012 .
add(
MI.getOperand(2))
5013 .
add(
MI.getOperand(3))
5014 .
add(
MI.getOperand(4))
5015 .
add(
MI.getOperand(5))
5016 .
add(
MI.getOperand(6));
5025 MI.getNumExplicitOperands() == 6);
5032 switch (
MI.getOpcode()) {
5044 .
add(
MI.getOperand(0))
5046 .
add(
MI.getOperand(1))
5047 .
add(
MI.getOperand(2))
5048 .
add(
MI.getOperand(3))
5049 .
add(
MI.getOperand(4))
5050 .
add(
MI.getOperand(5));
5059 if (
MI.getOperand(0).isEarlyClobber()) {
5065 if (S->
end == Idx.getRegSlot(
true))
5066 S->
end = Idx.getRegSlot();
5073#undef CASE_WIDEOP_OPCODE_COMMON
5074#undef CASE_WIDEOP_OPCODE_LMULS
5075#undef CASE_WIDEOP_CHANGE_OPCODE_COMMON
5076#undef CASE_WIDEOP_CHANGE_OPCODE_LMULS
5077#undef CASE_FP_WIDEOP_OPCODE_COMMON
5078#undef CASE_FP_WIDEOP_OPCODE_LMULS
5079#undef CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON
5080#undef CASE_FP_WIDEOP_CHANGE_OPCODE_LMULS
5089 if (ShiftAmount == 0)
5095 }
else if (
int ShXAmount, ShiftAmount;
5096 STI.hasStdExtZba() &&
5097 (ShXAmount =
isShifted359(Amount, ShiftAmount)) != 0) {
5100 switch (ShXAmount) {
5102 Opc = RISCV::SH1ADD;
5105 Opc = RISCV::SH2ADD;
5108 Opc = RISCV::SH3ADD;
5123 Register ScaledRegister =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
5134 Register ScaledRegister =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
5144 }
else if (
STI.hasStdExtZmmul()) {
5145 Register N =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
5154 for (
uint32_t ShiftAmount = 0; Amount >> ShiftAmount; ShiftAmount++) {
5155 if (Amount & (1U << ShiftAmount)) {
5159 .
addImm(ShiftAmount - PrevShiftAmount)
5161 if (Amount >> (ShiftAmount + 1)) {
5164 Acc =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
5175 PrevShiftAmount = ShiftAmount;
5178 assert(Acc &&
"Expected valid accumulator");
5188 static const std::pair<MachineMemOperand::Flags, const char *> TargetFlags[] =
5196 ?
STI.getTailDupAggressiveThreshold()
5203 unsigned Opcode =
MI.getOpcode();
5204 if (!RISCVVPseudosTable::getPseudoInfo(Opcode) &&
5213 return MI.isCopy() &&
MI.getOperand(0).getReg().isPhysical() &&
5215 TRI->getMinimalPhysRegClass(
MI.getOperand(0).getReg()));
5218std::optional<std::pair<unsigned, unsigned>>
5222 return std::nullopt;
5223 case RISCV::PseudoVSPILL2_M1:
5224 case RISCV::PseudoVRELOAD2_M1:
5225 return std::make_pair(2u, 1u);
5226 case RISCV::PseudoVSPILL2_M2:
5227 case RISCV::PseudoVRELOAD2_M2:
5228 return std::make_pair(2u, 2u);
5229 case RISCV::PseudoVSPILL2_M4:
5230 case RISCV::PseudoVRELOAD2_M4:
5231 return std::make_pair(2u, 4u);
5232 case RISCV::PseudoVSPILL3_M1:
5233 case RISCV::PseudoVRELOAD3_M1:
5234 return std::make_pair(3u, 1u);
5235 case RISCV::PseudoVSPILL3_M2:
5236 case RISCV::PseudoVRELOAD3_M2:
5237 return std::make_pair(3u, 2u);
5238 case RISCV::PseudoVSPILL4_M1:
5239 case RISCV::PseudoVRELOAD4_M1:
5240 return std::make_pair(4u, 1u);
5241 case RISCV::PseudoVSPILL4_M2:
5242 case RISCV::PseudoVRELOAD4_M2:
5243 return std::make_pair(4u, 2u);
5244 case RISCV::PseudoVSPILL5_M1:
5245 case RISCV::PseudoVRELOAD5_M1:
5246 return std::make_pair(5u, 1u);
5247 case RISCV::PseudoVSPILL6_M1:
5248 case RISCV::PseudoVRELOAD6_M1:
5249 return std::make_pair(6u, 1u);
5250 case RISCV::PseudoVSPILL7_M1:
5251 case RISCV::PseudoVRELOAD7_M1:
5252 return std::make_pair(7u, 1u);
5253 case RISCV::PseudoVSPILL8_M1:
5254 case RISCV::PseudoVRELOAD8_M1:
5255 return std::make_pair(8u, 1u);
5260 int16_t MI1FrmOpIdx =
5261 RISCV::getNamedOperandIdx(MI1.
getOpcode(), RISCV::OpName::frm);
5262 int16_t MI2FrmOpIdx =
5263 RISCV::getNamedOperandIdx(MI2.
getOpcode(), RISCV::OpName::frm);
5264 if (MI1FrmOpIdx < 0 || MI2FrmOpIdx < 0)
5271std::optional<unsigned>
5275 return std::nullopt;
5278 case RISCV::VSLL_VX:
5279 case RISCV::VSRL_VX:
5280 case RISCV::VSRA_VX:
5282 case RISCV::VSSRL_VX:
5283 case RISCV::VSSRA_VX:
5285 case RISCV::VROL_VX:
5286 case RISCV::VROR_VX:
5291 case RISCV::VNSRL_WX:
5292 case RISCV::VNSRA_WX:
5294 case RISCV::VNCLIPU_WX:
5295 case RISCV::VNCLIP_WX:
5297 case RISCV::VWSLL_VX:
5302 case RISCV::VADD_VX:
5303 case RISCV::VSUB_VX:
5304 case RISCV::VRSUB_VX:
5306 case RISCV::VWADDU_VX:
5307 case RISCV::VWSUBU_VX:
5308 case RISCV::VWADD_VX:
5309 case RISCV::VWSUB_VX:
5310 case RISCV::VWADDU_WX:
5311 case RISCV::VWSUBU_WX:
5312 case RISCV::VWADD_WX:
5313 case RISCV::VWSUB_WX:
5315 case RISCV::VADC_VXM:
5316 case RISCV::VADC_VIM:
5317 case RISCV::VMADC_VXM:
5318 case RISCV::VMADC_VIM:
5319 case RISCV::VMADC_VX:
5320 case RISCV::VSBC_VXM:
5321 case RISCV::VMSBC_VXM:
5322 case RISCV::VMSBC_VX:
5324 case RISCV::VAND_VX:
5326 case RISCV::VXOR_VX:
5328 case RISCV::VMSEQ_VX:
5329 case RISCV::VMSNE_VX:
5330 case RISCV::VMSLTU_VX:
5331 case RISCV::VMSLT_VX:
5332 case RISCV::VMSLEU_VX:
5333 case RISCV::VMSLE_VX:
5334 case RISCV::VMSGTU_VX:
5335 case RISCV::VMSGT_VX:
5337 case RISCV::VMINU_VX:
5338 case RISCV::VMIN_VX:
5339 case RISCV::VMAXU_VX:
5340 case RISCV::VMAX_VX:
5342 case RISCV::VMUL_VX:
5343 case RISCV::VMULH_VX:
5344 case RISCV::VMULHU_VX:
5345 case RISCV::VMULHSU_VX:
5347 case RISCV::VDIVU_VX:
5348 case RISCV::VDIV_VX:
5349 case RISCV::VREMU_VX:
5350 case RISCV::VREM_VX:
5352 case RISCV::VWMUL_VX:
5353 case RISCV::VWMULU_VX:
5354 case RISCV::VWMULSU_VX:
5356 case RISCV::VMACC_VX:
5357 case RISCV::VNMSAC_VX:
5358 case RISCV::VMADD_VX:
5359 case RISCV::VNMSUB_VX:
5361 case RISCV::VWMACCU_VX:
5362 case RISCV::VWMACC_VX:
5363 case RISCV::VWMACCSU_VX:
5364 case RISCV::VWMACCUS_VX:
5366 case RISCV::VMERGE_VXM:
5368 case RISCV::VMV_V_X:
5370 case RISCV::VSADDU_VX:
5371 case RISCV::VSADD_VX:
5372 case RISCV::VSSUBU_VX:
5373 case RISCV::VSSUB_VX:
5375 case RISCV::VAADDU_VX:
5376 case RISCV::VAADD_VX:
5377 case RISCV::VASUBU_VX:
5378 case RISCV::VASUB_VX:
5380 case RISCV::VSMUL_VX:
5382 case RISCV::VMV_S_X:
5384 case RISCV::VANDN_VX:
5385 return 1U << Log2SEW;
5391 RISCVVPseudosTable::getPseudoInfo(RVVPseudoOpcode);
5394 return RVV->BaseInstr;
5404 unsigned Scaled = Log2SEW + (DestEEW - 1);
5418 return std::nullopt;
5424 assert((LHS.isImm() ||
MRI.isSSA()) && (RHS.isImm() ||
MRI.isSSA()));
5425 if (LHS.isReg() && RHS.isReg() && LHS.getReg().isVirtual() &&
5426 LHS.getReg() == RHS.getReg())
5430 if (LHS.isImm() && LHS.getImm() == 0)
5436 if (!LHSImm || !RHSImm)
5438 return LHSImm <= RHSImm;
5450 : LHS(LHS), RHS(RHS),
Cond(
Cond.begin(),
Cond.end()) {}
5452 bool shouldIgnoreForPipelining(
const MachineInstr *
MI)
const override {
5462 std::optional<bool> createTripCountGreaterCondition(
5463 int TC, MachineBasicBlock &
MBB,
5464 SmallVectorImpl<MachineOperand> &CondParam)
override {
5472 void setPreheader(MachineBasicBlock *NewPreheader)
override {}
5474 void adjustTripCount(
int TripCountAdjust)
override {}
5478std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo>
5486 if (
TBB == LoopBB && FBB == LoopBB)
5493 assert((
TBB == LoopBB || FBB == LoopBB) &&
5494 "The Loop must be a single-basic-block loop");
5505 if (!Reg.isVirtual())
5507 return MRI.getVRegDef(Reg);
5512 if (LHS && LHS->isPHI())
5514 if (RHS && RHS->isPHI())
5517 return std::make_unique<RISCVPipelinerLoopInfo>(LHS, RHS,
Cond);
5523 Opc = RVVMCOpcode ? RVVMCOpcode :
Opc;
5540 case RISCV::FDIV_H_INX:
5541 case RISCV::FDIV_S_INX:
5542 case RISCV::FDIV_D_INX:
5543 case RISCV::FDIV_D_IN32X:
5544 case RISCV::FSQRT_H:
5545 case RISCV::FSQRT_S:
5546 case RISCV::FSQRT_D:
5547 case RISCV::FSQRT_H_INX:
5548 case RISCV::FSQRT_S_INX:
5549 case RISCV::FSQRT_D_INX:
5550 case RISCV::FSQRT_D_IN32X:
5552 case RISCV::VDIV_VV:
5553 case RISCV::VDIV_VX:
5554 case RISCV::VDIVU_VV:
5555 case RISCV::VDIVU_VX:
5556 case RISCV::VREM_VV:
5557 case RISCV::VREM_VX:
5558 case RISCV::VREMU_VV:
5559 case RISCV::VREMU_VX:
5561 case RISCV::VFDIV_VV:
5562 case RISCV::VFDIV_VF:
5563 case RISCV::VFRDIV_VF:
5564 case RISCV::VFSQRT_V:
5565 case RISCV::VFRSQRT7_V:
5571 if (
MI->getOpcode() != TargetOpcode::COPY)
5576 Register DstReg =
MI->getOperand(0).getReg();
5578 ?
MRI.getRegClass(DstReg)
5579 :
TRI->getMinimalPhysRegClass(DstReg);
5589 auto [RCLMul, RCFractional] =
5591 return (!RCFractional && LMul == RCLMul) || (RCFractional && LMul == 1);
5595 if (
MI.memoperands_empty())
5610 if (MO.getReg().isPhysical())
5613 if (MO.getReg().isPhysical())
5615 bool SawStore =
false;
5618 if (
II->definesRegister(PhysReg,
nullptr))
5621 if (
II->definesRegister(PhysReg,
nullptr) ||
5622 II->readsRegister(PhysReg,
nullptr))
5624 II->isSafeToMove(SawStore);
MachineInstrBuilder MachineInstrBuilder & DefMI
static void parseCondBranch(MachineInstr *LastInst, MachineBasicBlock *&Target, SmallVectorImpl< MachineOperand > &Cond)
@ MachineOutlinerTailCall
Emit a save, restore, call, and return.
@ MachineOutlinerRegSave
Emit a call and tail-call.
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
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
const HexagonInstrInfo * TII
Module.h This file contains the declarations for the Module class.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static int getJumpTableIndexFromLoadAddr(const MachineRegisterInfo &MRI, Register Reg)
static bool isJumpTableLoad(const MachineInstr &MI)
Register const TargetRegisterInfo * TRI
Promote Memory to Register
This file provides utility analysis objects describing memory locations.
uint64_t IntrinsicInst * II
static std::optional< int64_t > getEffectiveImm(const MachineRegisterInfo &MRI, const MachineOperand &MO)
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 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 bool forwardCopyWillClobberTuple(unsigned DstReg, unsigned SrcReg, unsigned NumRegs)
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)
#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)
#define CASE_OPERAND_UIMM_LSB_ZEROS(BITS, SUFFIX)
static bool isFSUB(unsigned Opc)
#define CASE_VMA_CHANGE_OPCODE_LMULS(OLDOP, NEWOP, TYPE)
#define CASE_RVV_OPCODE(OP)
#define CASE_VFMA_OPCODE_VV(OP)
MachineOutlinerConstructionID
#define CASE_RVV_OPCODE_WIDEN(OP)
static unsigned getLoadPredicatedOpcode(unsigned Opcode)
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 Register findRegisterToSaveX5To(outliner::Candidate &C, const TargetRegisterInfo &TRI)
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)
#define CASE_RVV_OPCODE_LMUL(OP, LMUL)
static int getJumpTableIndexFromBase(const MachineRegisterInfo &MRI, Register Reg)
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 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...
SmallVector< MachineOperand, 4 > Cond
MachineRegisterInfo & MRI
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
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 bool canCombine(MachineBasicBlock &MBB, MachineOperand &MO, unsigned CombineOpc=0)
Represent a constant reference to an array (0 or more elements consecutively in memory),...
const T & front() const
Get the first element.
bool empty() const
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.
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 ...
const uint8_t TSFlags
Configurable target specific flags.
Wrapper class representing physical registers. Should be passed by value.
const FeatureBitset & getFeatureBits() const
MachineInstrBundleIterator< const MachineInstr > const_iterator
MachineInstrBundleIterator< MachineInstr, true > reverse_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.
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...
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags F, LLT MemTy, Align BaseAlignment, const MMOMetadata &Metadata=MMOMetadata(), SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineInstrBuilder & setMemRefs(ArrayRef< MachineMemOperand * > MMOs) const
const MachineInstrBuilder & addUse(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
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 & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
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
filtered_mop_range all_defs()
Returns an iterator range over all operands that are (explicit or implicit) register defs.
bool getFlag(MIFlag Flag) const
Return whether an MI flag is set.
LLVM_ABI bool isSafeToMove(bool &SawStore) const
Return true if it is safe to move this instruction.
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.
filtered_mop_range all_uses()
Returns an iterator range over all operands that are (explicit or implicit) register uses.
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.
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 bool hasOneNonDBGUse(Register RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug use of the specified register.
const TargetRegisterInfo * getTargetRegisterInfo() const
LLVM_ABI LLVM_READONLY MachineInstr * getUniqueVRegDef(Register Reg) const
getUniqueVRegDef - Return the unique machine instr that defines the specified virtual register or nul...
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.
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool IsKill, int FrameIndex, const TargetRegisterClass *RC, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
static bool isSafeToMove(const MachineInstr &From, const MachineBasicBlock::iterator &To)
Return true if moving From down to To won't cause any physical register reads or writes to be clobber...
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.
MachineInstr * convertToThreeAddress(MachineInstr &MI, LiveIntervals *LIS) const override
RISCVInstrInfo(const RISCVSubtarget &STI)
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DstReg, int FrameIndex, const TargetRegisterClass *RC, Register VReg, unsigned SubReg=0, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) 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 isVRegCopy(const MachineInstr *MI, unsigned LMul=0) const
Return true if MI is a COPY to a vector register of a specific LMul, or any kind of vector registers ...
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
unsigned getTailDuplicateSize(CodeGenOptLevel OptLevel) const override
void getReassociateOperandIndices(const MachineInstr &Root, unsigned Pattern, std::array< unsigned, 5 > &OperandIndices) const override
bool getMemOperandsWithOffsetWidth(const MachineInstr &MI, SmallVectorImpl< const MachineOperand * > &BaseOps, int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width) 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
bool analyzeCandidate(outliner::Candidate &C) const
bool isMBBSafeToOutlineFrom(MachineBasicBlock &MBB, unsigned &Flags) const override
bool getMemOperandWithOffsetWidth(const MachineInstr &LdSt, const MachineOperand *&BaseOp, int64_t &Offset, LocationSize &Width) const
void buildOutlinedFrame(MachineBasicBlock &MBB, MachineFunction &MF, const outliner::OutlinedFunction &OF) const override
bool requiresNTLHint(const MachineInstr &MI) const
Return true if the instruction requires an NTL hint to be emitted.
std::string createMIROperandComment(const MachineInstr &MI, const MachineOperand &Op, unsigned OpIdx) 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
int getJumpTableIndex(const MachineInstr &MI) const override
bool hasReassociableOperands(const MachineInstr &Inst, const MachineBasicBlock *MBB) const override
MachineBasicBlock * getBranchDestBlock(const MachineInstr &MI) 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
MachineInstr * foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI, ArrayRef< unsigned > Ops, int FrameIndex, MachineInstr *&CopyMI, LiveIntervals *LIS=nullptr, VirtRegMap *VRM=nullptr) const override
bool isBranchOffsetInRange(unsigned BranchOpc, int64_t BrOffset) const override
static RISCVCC::CondCode getCondFromBranchOpc(unsigned Opc)
void buildClearRegister(Register Reg, MachineBasicBlock &MBB, MachineBasicBlock::iterator Iter, DebugLoc &DL, bool AllowSideEffects=true) const override
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
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
bool hasCFProtectionBranch() const
const RISCVOptions & getCLOpts() 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.
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.
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 std::string createMIROperandComment(const MachineInstr &MI, const MachineOperand &Op, unsigned OpIdx) const
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.
const MCAsmInfo & getMCAsmInfo() const
Return target specific asm information.
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)
self_iterator getIterator()
A raw_ostream that writes to an std::string.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
CondCode getInverseBranchCondition(CondCode)
unsigned getInverseBranchOpcode(unsigned BCC)
unsigned getBrCond(CondCode CC, unsigned SelectOpc=0)
static bool isValidRoundingMode(unsigned Mode)
static StringRef roundingModeToString(RoundingMode RndMode)
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 int getVXRMOpNum(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
@ OPERAND_ATOMIC_ORDERING
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)
static bool isValidVType(unsigned VType)
LLVM_ABI void printVType(unsigned VType, raw_ostream &OS)
static bool isValidXSfmmVType(unsigned VTypeI)
static unsigned getSEW(unsigned VType)
static VLMUL getVLMUL(unsigned VType)
static bool isValidRoundingMode(unsigned Mode)
static StringRef roundingModeToString(RoundingMode RndMode)
bool hasEqualFRM(const MachineInstr &MI1, const MachineInstr &MI2)
bool isValidYBNDSWImm(int64_t Imm)
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
bool isVLKnownLE(const MachineRegisterInfo &MRI, const MachineOperand &LHS, const MachineOperand &RHS)
Given two VL operands, do we know that LHS <= RHS?
bool isVectorCopy(const TargetRegisterInfo *TRI, const MachineInstr &MI)
Return true if MI is a copy that will be lowered to one or more vmvNr.vs.
static bool isValidSMTVTypeMode(unsigned Mode)
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.
RegState
Flags to represent properties of register accesses.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Kill
The last use of a register.
@ Undef
Value of the register doesn't matter.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
bool isValidAtomicOrdering(Int I)
constexpr RegState getKillRegState(bool B)
static const MachineMemOperand::Flags MONontemporalBit0
constexpr RegState getDeadRegState(bool B)
LLVM_ABI void reportFatalInternalError(Error Err)
Report a fatal error that indicates a bug in LLVM.
unsigned M1(unsigned Val)
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)
constexpr RegState getRenamableRegState(bool B)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
constexpr RegState getDefRegState(bool B)
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)
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth, bool MustPreserveProvenance=false)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
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...
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
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.
@ End
Run the machine verifier once, at the end of the pipeline.
constexpr bool isShiftedUInt(uint64_t x)
Checks if a unsigned integer is an N bit number shifted left by S.
MCRegisterClass TargetRegisterClass
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
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.