41#define GEN_CHECK_COMPRESS_INSTR
42#include "RISCVGenCompressInstEmitter.inc"
44#define GET_INSTRINFO_CTOR_DTOR
45#include "RISCVGenInstrInfo.inc"
47#define DEBUG_TYPE "riscv-instr-info"
49 "Number of registers within vector register groups spilled");
51 "Number of registers within vector register groups reloaded");
57#define GET_RISCVVPseudosTable_IMPL
58#include "RISCVGenSearchableTables.inc"
64#define GET_RISCVMaskedPseudosTable_IMPL
65#include "RISCVGenSearchableTables.inc"
71 RISCV::ADJCALLSTACKUP),
74#define GET_INSTRINFO_HELPERS
75#include "RISCVGenInstrInfo.inc"
78 if (
STI.hasStdExtZca())
87 int &FrameIndex)
const {
98 case RISCV::VL1RE16_V:
99 case RISCV::VL1RE32_V:
100 case RISCV::VL1RE64_V:
103 case RISCV::VL2RE8_V:
104 case RISCV::VL2RE16_V:
105 case RISCV::VL2RE32_V:
106 case RISCV::VL2RE64_V:
109 case RISCV::VL4RE8_V:
110 case RISCV::VL4RE16_V:
111 case RISCV::VL4RE32_V:
112 case RISCV::VL4RE64_V:
115 case RISCV::VL8RE8_V:
116 case RISCV::VL8RE16_V:
117 case RISCV::VL8RE32_V:
118 case RISCV::VL8RE64_V:
126 switch (
MI.getOpcode()) {
150 case RISCV::VL1RE8_V:
151 case RISCV::VL2RE8_V:
152 case RISCV::VL4RE8_V:
153 case RISCV::VL8RE8_V:
154 if (!
MI.getOperand(1).isFI())
156 FrameIndex =
MI.getOperand(1).getIndex();
159 return MI.getOperand(0).getReg();
162 if (
MI.getOperand(1).isFI() &&
MI.getOperand(2).isImm() &&
163 MI.getOperand(2).getImm() == 0) {
164 FrameIndex =
MI.getOperand(1).getIndex();
165 return MI.getOperand(0).getReg();
172 int &FrameIndex)
const {
180 switch (
MI.getOpcode()) {
205 if (!
MI.getOperand(1).isFI())
207 FrameIndex =
MI.getOperand(1).getIndex();
210 return MI.getOperand(0).getReg();
213 if (
MI.getOperand(1).isFI() &&
MI.getOperand(2).isImm() &&
214 MI.getOperand(2).getImm() == 0) {
215 FrameIndex =
MI.getOperand(1).getIndex();
216 return MI.getOperand(0).getReg();
226 case RISCV::VFMV_V_F:
229 case RISCV::VFMV_S_F:
231 return MI.getOperand(1).isUndef();
239 return DstReg > SrcReg && (DstReg - SrcReg) < NumRegs;
247 if (STI.
getCLOpts().prefer_whole_register_move)
250 assert(
MBBI->getOpcode() == TargetOpcode::COPY &&
251 "Unexpected COPY instruction.");
255 bool FoundDef =
false;
256 bool FirstVSetVLI =
false;
257 unsigned FirstSEW = 0;
260 if (
MBBI->isMetaInstruction())
263 if (RISCVInstrInfo::isVectorConfigInstr(*
MBBI)) {
273 unsigned FirstVType =
MBBI->getOperand(2).getImm();
278 if (FirstLMul != LMul)
283 if (!RISCVInstrInfo::isVLPreservingConfig(*
MBBI))
289 unsigned VType =
MBBI->getOperand(2).getImm();
307 }
else if (
MBBI->isInlineAsm() ||
MBBI->isCall()) {
309 }
else if (
MBBI->getNumDefs()) {
312 if (
MBBI->modifiesRegister(RISCV::VL,
nullptr))
318 if (!MO.isReg() || !MO.isDef())
320 if (!FoundDef &&
TRI->regsOverlap(MO.getReg(), SrcReg)) {
335 if (MO.getReg() != SrcReg)
376 uint16_t SrcEncoding =
TRI->getEncodingValue(SrcReg);
377 uint16_t DstEncoding =
TRI->getEncodingValue(DstReg);
379 assert(!Fractional &&
"It is impossible be fractional lmul here.");
380 unsigned NumRegs = NF * LMulVal;
386 SrcEncoding += NumRegs - 1;
387 DstEncoding += NumRegs - 1;
391 auto GetCopyInfo = [&](uint16_t SrcEncoding, uint16_t DstEncoding)
393 unsigned,
unsigned> {
401 uint16_t Diff = DstEncoding - SrcEncoding;
402 if (
I + 8 <= NumRegs && Diff >= 8 && SrcEncoding % 8 == 7 &&
403 DstEncoding % 8 == 7)
405 RISCV::PseudoVMV_V_V_M8, RISCV::PseudoVMV_V_I_M8};
406 if (
I + 4 <= NumRegs && Diff >= 4 && SrcEncoding % 4 == 3 &&
407 DstEncoding % 4 == 3)
409 RISCV::PseudoVMV_V_V_M4, RISCV::PseudoVMV_V_I_M4};
410 if (
I + 2 <= NumRegs && Diff >= 2 && SrcEncoding % 2 == 1 &&
411 DstEncoding % 2 == 1)
413 RISCV::PseudoVMV_V_V_M2, RISCV::PseudoVMV_V_I_M2};
416 RISCV::PseudoVMV_V_V_M1, RISCV::PseudoVMV_V_I_M1};
421 if (
I + 8 <= NumRegs && SrcEncoding % 8 == 0 && DstEncoding % 8 == 0)
423 RISCV::PseudoVMV_V_V_M8, RISCV::PseudoVMV_V_I_M8};
424 if (
I + 4 <= NumRegs && SrcEncoding % 4 == 0 && DstEncoding % 4 == 0)
426 RISCV::PseudoVMV_V_V_M4, RISCV::PseudoVMV_V_I_M4};
427 if (
I + 2 <= NumRegs && SrcEncoding % 2 == 0 && DstEncoding % 2 == 0)
429 RISCV::PseudoVMV_V_V_M2, RISCV::PseudoVMV_V_I_M2};
432 RISCV::PseudoVMV_V_V_M1, RISCV::PseudoVMV_V_I_M1};
435 while (
I != NumRegs) {
440 auto [LMulCopied, RegClass,
Opc, VVOpc, VIOpc] =
441 GetCopyInfo(SrcEncoding, DstEncoding);
445 if (LMul == LMulCopied &&
448 if (DefMBBI->getOpcode() == VIOpc)
455 RegClass, ReversedCopy ? (SrcEncoding - NumCopied + 1) : SrcEncoding);
457 RegClass, ReversedCopy ? (DstEncoding - NumCopied + 1) : DstEncoding);
465 MIB = MIB.add(DefMBBI->getOperand(2));
473 MIB.addImm(Log2SEW ? Log2SEW : 3);
485 SrcEncoding += (ReversedCopy ? -NumCopied : NumCopied);
486 DstEncoding += (ReversedCopy ? -NumCopied : NumCopied);
495 bool RenamableDest,
bool RenamableSrc)
const {
499 if (RISCV::GPRRegClass.
contains(DstReg, SrcReg)) {
506 if (RISCV::GPRF16RegClass.
contains(DstReg, SrcReg)) {
512 if (RISCV::GPRF32RegClass.
contains(DstReg, SrcReg)) {
518 if (RISCV::GPRPairRegClass.
contains(DstReg, SrcReg)) {
519 if (!
STI.is64Bit()) {
520 if (
STI.hasStdExtZdinx()) {
529 if (
STI.hasStdExtP()) {
538 auto [EvenReg, OddReg] =
TRI->getGPRPairSubRegs(SrcReg);
539 assert(DstReg != RISCV::X0_Pair &&
"Cannot write to X0_Pair");
543 TRI->getSubReg(DstReg, RISCV::sub_gpr_even))
544 .
addReg(EvenReg, KillFlag)
547 TRI->getSubReg(DstReg, RISCV::sub_gpr_odd))
554 if (RISCV::VCSRRegClass.
contains(SrcReg) &&
555 RISCV::GPRRegClass.
contains(DstReg)) {
557 .
addImm(RISCVSysReg::lookupSysRegByName(
TRI->getName(SrcReg))->Encoding)
562 if (RISCV::FPR16RegClass.
contains(DstReg, SrcReg)) {
564 if (
STI.hasStdExtZfh()) {
565 Opc = RISCV::FSGNJ_H;
568 (
STI.hasStdExtZfhmin() ||
STI.hasStdExtZfbfmin()) &&
569 "Unexpected extensions");
571 DstReg =
TRI->getMatchingSuperReg(DstReg, RISCV::sub_16,
572 &RISCV::FPR32RegClass);
573 SrcReg =
TRI->getMatchingSuperReg(SrcReg, RISCV::sub_16,
574 &RISCV::FPR32RegClass);
575 Opc = RISCV::FSGNJ_S;
579 .
addReg(SrcReg, KillFlag);
583 if (RISCV::FPR32RegClass.
contains(DstReg, SrcReg)) {
586 .
addReg(SrcReg, KillFlag);
590 if (RISCV::FPR64RegClass.
contains(DstReg, SrcReg)) {
593 .
addReg(SrcReg, KillFlag);
597 if (RISCV::FPR16RegClass.
contains(DstReg) &&
598 RISCV::GPRRegClass.
contains(SrcReg)) {
599 assert(
STI.hasHalfFPLoadStoreMove() &&
"Unexpected extensions");
601 .
addReg(SrcReg, KillFlag);
605 if (RISCV::GPRRegClass.
contains(DstReg) &&
606 RISCV::FPR16RegClass.
contains(SrcReg)) {
607 assert(
STI.hasHalfFPLoadStoreMove() &&
"Unexpected extensions");
609 .
addReg(SrcReg, KillFlag);
613 if (RISCV::FPR32RegClass.
contains(DstReg) &&
614 RISCV::GPRRegClass.
contains(SrcReg)) {
616 .
addReg(SrcReg, KillFlag);
620 if (RISCV::GPRRegClass.
contains(DstReg) &&
621 RISCV::FPR32RegClass.
contains(SrcReg)) {
623 .
addReg(SrcReg, KillFlag);
627 if (RISCV::FPR64RegClass.
contains(DstReg) &&
628 RISCV::GPRRegClass.
contains(SrcReg)) {
629 assert(
STI.getXLen() == 64 &&
"Unexpected GPR size");
631 .
addReg(SrcReg, KillFlag);
635 if (RISCV::GPRRegClass.
contains(DstReg) &&
636 RISCV::FPR64RegClass.
contains(SrcReg)) {
637 assert(
STI.getXLen() == 64 &&
"Unexpected GPR size");
639 .
addReg(SrcReg, KillFlag);
645 TRI->getCommonMinimalPhysRegClass(SrcReg, DstReg);
656 Register SrcReg,
bool IsKill,
int FI,
665 if (RISCV::GPRRegClass.hasSubClassEq(RC)) {
666 Opcode = RegInfo.getRegSizeInBits(RISCV::GPRRegClass) == 32 ? RISCV::SW
668 }
else if (RISCV::GPRF16RegClass.hasSubClassEq(RC)) {
669 Opcode = RISCV::SH_INX;
670 }
else if (RISCV::GPRF32RegClass.hasSubClassEq(RC)) {
671 Opcode = RISCV::SW_INX;
672 }
else if (RISCV::GPRPairRegClass.hasSubClassEq(RC)) {
673 if (!
STI.is64Bit() &&
STI.hasStdExtZilsd() &&
674 Alignment >=
STI.getZilsdAlign()) {
675 Opcode = RISCV::SD_RV32;
677 Opcode = RISCV::PseudoRV32ZdinxSD;
679 }
else if (RISCV::FPR16RegClass.hasSubClassEq(RC)) {
681 }
else if (RISCV::FPR32RegClass.hasSubClassEq(RC)) {
683 }
else if (RISCV::FPR64RegClass.hasSubClassEq(RC)) {
685 }
else if (RISCV::VRRegClass.hasSubClassEq(RC)) {
686 Opcode = RISCV::VS1R_V;
687 }
else if (RISCV::VRM2RegClass.hasSubClassEq(RC)) {
688 Opcode = RISCV::VS2R_V;
689 }
else if (RISCV::VRM4RegClass.hasSubClassEq(RC)) {
690 Opcode = RISCV::VS4R_V;
691 }
else if (RISCV::VRM8RegClass.hasSubClassEq(RC)) {
692 Opcode = RISCV::VS8R_V;
693 }
else if (RISCV::VRN2M1RegClass.hasSubClassEq(RC))
694 Opcode = RISCV::PseudoVSPILL2_M1;
695 else if (RISCV::VRN2M2RegClass.hasSubClassEq(RC))
696 Opcode = RISCV::PseudoVSPILL2_M2;
697 else if (RISCV::VRN2M4RegClass.hasSubClassEq(RC))
698 Opcode = RISCV::PseudoVSPILL2_M4;
699 else if (RISCV::VRN3M1RegClass.hasSubClassEq(RC))
700 Opcode = RISCV::PseudoVSPILL3_M1;
701 else if (RISCV::VRN3M2RegClass.hasSubClassEq(RC))
702 Opcode = RISCV::PseudoVSPILL3_M2;
703 else if (RISCV::VRN4M1RegClass.hasSubClassEq(RC))
704 Opcode = RISCV::PseudoVSPILL4_M1;
705 else if (RISCV::VRN4M2RegClass.hasSubClassEq(RC))
706 Opcode = RISCV::PseudoVSPILL4_M2;
707 else if (RISCV::VRN5M1RegClass.hasSubClassEq(RC))
708 Opcode = RISCV::PseudoVSPILL5_M1;
709 else if (RISCV::VRN6M1RegClass.hasSubClassEq(RC))
710 Opcode = RISCV::PseudoVSPILL6_M1;
711 else if (RISCV::VRN7M1RegClass.hasSubClassEq(RC))
712 Opcode = RISCV::PseudoVSPILL7_M1;
713 else if (RISCV::VRN8M1RegClass.hasSubClassEq(RC))
714 Opcode = RISCV::PseudoVSPILL8_M1;
757 if (RISCV::GPRRegClass.hasSubClassEq(RC)) {
758 Opcode = RegInfo.getRegSizeInBits(RISCV::GPRRegClass) == 32 ? RISCV::LW
760 }
else if (RISCV::GPRF16RegClass.hasSubClassEq(RC)) {
761 Opcode = RISCV::LH_INX;
762 }
else if (RISCV::GPRF32RegClass.hasSubClassEq(RC)) {
763 Opcode = RISCV::LW_INX;
764 }
else if (RISCV::GPRPairRegClass.hasSubClassEq(RC)) {
765 if (!
STI.is64Bit() &&
STI.hasStdExtZilsd() &&
766 Alignment >=
STI.getZilsdAlign()) {
767 Opcode = RISCV::LD_RV32;
769 Opcode = RISCV::PseudoRV32ZdinxLD;
771 }
else if (RISCV::FPR16RegClass.hasSubClassEq(RC)) {
773 }
else if (RISCV::FPR32RegClass.hasSubClassEq(RC)) {
775 }
else if (RISCV::FPR64RegClass.hasSubClassEq(RC)) {
777 }
else if (RISCV::VRRegClass.hasSubClassEq(RC)) {
778 Opcode = RISCV::VL1RE8_V;
779 }
else if (RISCV::VRM2RegClass.hasSubClassEq(RC)) {
780 Opcode = RISCV::VL2RE8_V;
781 }
else if (RISCV::VRM4RegClass.hasSubClassEq(RC)) {
782 Opcode = RISCV::VL4RE8_V;
783 }
else if (RISCV::VRM8RegClass.hasSubClassEq(RC)) {
784 Opcode = RISCV::VL8RE8_V;
785 }
else if (RISCV::VRN2M1RegClass.hasSubClassEq(RC))
786 Opcode = RISCV::PseudoVRELOAD2_M1;
787 else if (RISCV::VRN2M2RegClass.hasSubClassEq(RC))
788 Opcode = RISCV::PseudoVRELOAD2_M2;
789 else if (RISCV::VRN2M4RegClass.hasSubClassEq(RC))
790 Opcode = RISCV::PseudoVRELOAD2_M4;
791 else if (RISCV::VRN3M1RegClass.hasSubClassEq(RC))
792 Opcode = RISCV::PseudoVRELOAD3_M1;
793 else if (RISCV::VRN3M2RegClass.hasSubClassEq(RC))
794 Opcode = RISCV::PseudoVRELOAD3_M2;
795 else if (RISCV::VRN4M1RegClass.hasSubClassEq(RC))
796 Opcode = RISCV::PseudoVRELOAD4_M1;
797 else if (RISCV::VRN4M2RegClass.hasSubClassEq(RC))
798 Opcode = RISCV::PseudoVRELOAD4_M2;
799 else if (RISCV::VRN5M1RegClass.hasSubClassEq(RC))
800 Opcode = RISCV::PseudoVRELOAD5_M1;
801 else if (RISCV::VRN6M1RegClass.hasSubClassEq(RC))
802 Opcode = RISCV::PseudoVRELOAD6_M1;
803 else if (RISCV::VRN7M1RegClass.hasSubClassEq(RC))
804 Opcode = RISCV::PseudoVRELOAD7_M1;
805 else if (RISCV::VRN8M1RegClass.hasSubClassEq(RC))
806 Opcode = RISCV::PseudoVRELOAD8_M1;
844 if (
Ops.size() != 1 ||
Ops[0] != 1)
847 switch (
MI.getOpcode()) {
849 if (RISCVInstrInfo::isSEXT_W(
MI))
851 if (RISCVInstrInfo::isZEXT_W(
MI))
853 if (RISCVInstrInfo::isZEXT_B(
MI))
860 case RISCV::ZEXT_H_RV32:
861 case RISCV::ZEXT_H_RV64:
868 case RISCV::VMV_X_S: {
871 if (ST.getXLen() < (1U << Log2SEW))
886 case RISCV::VFMV_F_S: {
914 return BuildMI(*
MI.getParent(), InsertPt,
MI.getDebugLoc(),
get(*LoadOpc),
923 return RISCV::PseudoCCLB;
925 return RISCV::PseudoCCLBU;
927 return RISCV::PseudoCCLH;
929 return RISCV::PseudoCCLHU;
931 return RISCV::PseudoCCLW;
933 return RISCV::PseudoCCLWU;
935 return RISCV::PseudoCCLD;
937 return RISCV::PseudoCCQC_E_LB;
938 case RISCV::QC_E_LBU:
939 return RISCV::PseudoCCQC_E_LBU;
941 return RISCV::PseudoCCQC_E_LH;
942 case RISCV::QC_E_LHU:
943 return RISCV::PseudoCCQC_E_LHU;
945 return RISCV::PseudoCCQC_E_LW;
957 if (
MI.getOpcode() != RISCV::PseudoCCMOVGPR)
962 if (!
STI.hasShortForwardBranchILoad() || !PredOpc)
966 if (
Ops.size() != 1 || (
Ops[0] != 1 &&
Ops[0] != 2))
969 bool Invert =
Ops[0] == 2;
978 MI.getDebugLoc(),
get(PredOpc), DestReg);
989 unsigned BCC =
MI.getOperand(
MI.getNumExplicitOperands() - 3).getImm();
995 NewMI.
add({
MI.getOperand(
MI.getNumExplicitOperands() - 2),
996 MI.getOperand(
MI.getNumExplicitOperands() - 1)});
1005 bool DstIsDead)
const {
1021 bool SrcRenamable =
false;
1025 bool LastItem = ++Num == Seq.
size();
1030 switch (Inst.getOpndKind()) {
1033 .
addDef(DstReg, DstRegState)
1039 .
addDef(DstReg, DstRegState)
1040 .
addReg(SrcReg, SrcRegState)
1046 .
addDef(DstReg, DstRegState)
1047 .
addReg(SrcReg, SrcRegState)
1048 .
addReg(SrcReg, SrcRegState)
1053 .
addDef(DstReg, DstRegState)
1054 .
addReg(SrcReg, SrcRegState)
1062 SrcRenamable = DstRenamable;
1072 case RISCV::CV_BEQIMM:
1073 case RISCV::QC_BEQI:
1074 case RISCV::QC_E_BEQI:
1075 case RISCV::NDS_BBC:
1076 case RISCV::NDS_BEQC:
1080 case RISCV::QC_BNEI:
1081 case RISCV::QC_E_BNEI:
1082 case RISCV::CV_BNEIMM:
1083 case RISCV::NDS_BBS:
1084 case RISCV::NDS_BNEC:
1087 case RISCV::QC_BLTI:
1088 case RISCV::QC_E_BLTI:
1091 case RISCV::QC_BGEI:
1092 case RISCV::QC_E_BGEI:
1095 case RISCV::QC_BLTUI:
1096 case RISCV::QC_E_BLTUI:
1099 case RISCV::QC_BGEUI:
1100 case RISCV::QC_E_BGEUI:
1119 return (uint64_t)C0 < (uint64_t)C1;
1121 return (uint64_t)C0 >= (uint64_t)C1;
1132 "Unknown conditional branch");
1143 case RISCV::QC_MVEQ:
1144 return RISCV::QC_MVNE;
1145 case RISCV::QC_MVNE:
1146 return RISCV::QC_MVEQ;
1147 case RISCV::QC_MVLT:
1148 return RISCV::QC_MVGE;
1149 case RISCV::QC_MVGE:
1150 return RISCV::QC_MVLT;
1151 case RISCV::QC_MVLTU:
1152 return RISCV::QC_MVGEU;
1153 case RISCV::QC_MVGEU:
1154 return RISCV::QC_MVLTU;
1155 case RISCV::QC_MVEQI:
1156 return RISCV::QC_MVNEI;
1157 case RISCV::QC_MVNEI:
1158 return RISCV::QC_MVEQI;
1159 case RISCV::QC_MVLTI:
1160 return RISCV::QC_MVGEI;
1161 case RISCV::QC_MVGEI:
1162 return RISCV::QC_MVLTI;
1163 case RISCV::QC_MVLTUI:
1164 return RISCV::QC_MVGEUI;
1165 case RISCV::QC_MVGEUI:
1166 return RISCV::QC_MVLTUI;
1171 switch (SelectOpc) {
1190 case RISCV::Select_GPR_Using_CC_Imm5_Zibi:
1200 case RISCV::Select_GPR_Using_CC_SImm5_CV:
1205 return RISCV::CV_BEQIMM;
1207 return RISCV::CV_BNEIMM;
1210 case RISCV::Select_GPRNoX0_Using_CC_SImm5NonZero_QC:
1215 return RISCV::QC_BEQI;
1217 return RISCV::QC_BNEI;
1219 return RISCV::QC_BLTI;
1221 return RISCV::QC_BGEI;
1224 case RISCV::Select_GPRNoX0_Using_CC_UImm5NonZero_QC:
1229 return RISCV::QC_BLTUI;
1231 return RISCV::QC_BGEUI;
1234 case RISCV::Select_GPRNoX0_Using_CC_SImm16NonZero_QC:
1239 return RISCV::QC_E_BEQI;
1241 return RISCV::QC_E_BNEI;
1243 return RISCV::QC_E_BLTI;
1245 return RISCV::QC_E_BGEI;
1248 case RISCV::Select_GPRNoX0_Using_CC_UImm16NonZero_QC:
1253 return RISCV::QC_E_BLTUI;
1255 return RISCV::QC_E_BGEUI;
1258 case RISCV::Select_GPR_Using_CC_UImmLog2XLen_NDS:
1263 return RISCV::NDS_BBC;
1265 return RISCV::NDS_BBS;
1268 case RISCV::Select_GPR_Using_CC_UImm7_NDS:
1273 return RISCV::NDS_BEQC;
1275 return RISCV::NDS_BNEC;
1321 case RISCV::CV_BEQIMM:
1322 return RISCV::CV_BNEIMM;
1323 case RISCV::CV_BNEIMM:
1324 return RISCV::CV_BEQIMM;
1325 case RISCV::QC_BEQI:
1326 return RISCV::QC_BNEI;
1327 case RISCV::QC_BNEI:
1328 return RISCV::QC_BEQI;
1329 case RISCV::QC_BLTI:
1330 return RISCV::QC_BGEI;
1331 case RISCV::QC_BGEI:
1332 return RISCV::QC_BLTI;
1333 case RISCV::QC_BLTUI:
1334 return RISCV::QC_BGEUI;
1335 case RISCV::QC_BGEUI:
1336 return RISCV::QC_BLTUI;
1337 case RISCV::QC_E_BEQI:
1338 return RISCV::QC_E_BNEI;
1339 case RISCV::QC_E_BNEI:
1340 return RISCV::QC_E_BEQI;
1341 case RISCV::QC_E_BLTI:
1342 return RISCV::QC_E_BGEI;
1343 case RISCV::QC_E_BGEI:
1344 return RISCV::QC_E_BLTI;
1345 case RISCV::QC_E_BLTUI:
1346 return RISCV::QC_E_BGEUI;
1347 case RISCV::QC_E_BGEUI:
1348 return RISCV::QC_E_BLTUI;
1349 case RISCV::NDS_BBC:
1350 return RISCV::NDS_BBS;
1351 case RISCV::NDS_BBS:
1352 return RISCV::NDS_BBC;
1353 case RISCV::NDS_BEQC:
1354 return RISCV::NDS_BNEC;
1355 case RISCV::NDS_BNEC:
1356 return RISCV::NDS_BEQC;
1364 bool AllowModify)
const {
1365 TBB = FBB =
nullptr;
1370 if (
I ==
MBB.end() || !isUnpredicatedTerminator(*
I))
1376 int NumTerminators = 0;
1377 for (
auto J =
I.getReverse(); J !=
MBB.rend() && isUnpredicatedTerminator(*J);
1380 if (J->getDesc().isUnconditionalBranch() ||
1381 J->getDesc().isIndirectBranch()) {
1388 if (AllowModify && FirstUncondOrIndirectBr !=
MBB.end()) {
1389 while (std::next(FirstUncondOrIndirectBr) !=
MBB.end()) {
1390 std::next(FirstUncondOrIndirectBr)->eraseFromParent();
1393 I = FirstUncondOrIndirectBr;
1397 if (
I->getDesc().isIndirectBranch())
1401 if (
I->isPreISelOpcode())
1405 if (NumTerminators > 2)
1409 if (NumTerminators == 1 &&
I->getDesc().isUnconditionalBranch()) {
1415 if (NumTerminators == 1 &&
I->getDesc().isConditionalBranch()) {
1421 if (NumTerminators == 2 && std::prev(
I)->getDesc().isConditionalBranch() &&
1422 I->getDesc().isUnconditionalBranch()) {
1433 int *BytesRemoved)
const {
1440 if (!
I->getDesc().isUnconditionalBranch() &&
1441 !
I->getDesc().isConditionalBranch())
1447 I->eraseFromParent();
1451 if (
I ==
MBB.begin())
1454 if (!
I->getDesc().isConditionalBranch())
1460 I->eraseFromParent();
1473 assert(
TBB &&
"insertBranch must not be told to insert a fallthrough");
1475 "RISC-V branch conditions have two components!");
1509 assert(RS &&
"RegScavenger required for long branching");
1511 "new block should be inserted for expanding unconditional branch");
1514 "restore block should be inserted for restoring clobbered registers");
1523 "Branch offsets outside of the signed 32-bit range not supported");
1529 auto II =
MBB.end();
1535 RS->enterBasicBlockEnd(
MBB);
1542 RC = &RISCV::GPRX7RegClass;
1544 RS->scavengeRegisterBackwards(*RC,
MI.getIterator(),
1548 RS->setRegUsed(TmpGPR);
1553 TmpGPR =
STI.hasStdExtE() ? RISCV::X9 : RISCV::X27;
1559 if (FrameIndex == -1)
1564 TRI->eliminateFrameIndex(std::prev(
MI.getIterator()),
1567 MI.getOperand(1).setMBB(&RestoreBB);
1571 TRI->eliminateFrameIndex(RestoreBB.
back(),
1581 assert((
Cond.size() == 3) &&
"Invalid branch condition!");
1591 if (
MI->getOpcode() == RISCV::ADDI &&
MI->getOperand(1).isReg() &&
1592 MI->getOperand(1).getReg() == RISCV::X0) {
1593 Imm =
MI->getOperand(2).getImm();
1598 if (
MI->getOpcode() == RISCV::BSETI &&
MI->getOperand(1).isReg() &&
1599 MI->getOperand(1).getReg() == RISCV::X0 &&
1600 MI->getOperand(2).getImm() == 11) {
1614 if (Reg == RISCV::X0) {
1619 if (!Reg.isVirtual())
1627 bool IsSigned =
false;
1628 bool IsEquality =
false;
1629 switch (
MI.getOpcode()) {
1665 MI.eraseFromParent();
1691 auto searchConst = [&](int64_t C1) ->
Register {
1693 auto DefC1 = std::find_if(++
II, E, [&](
const MachineInstr &
I) ->
bool {
1696 I.getOperand(0).getReg().isVirtual();
1699 return DefC1->getOperand(0).getReg();
1711 if (
isFromLoadImm(MRI, LHS, C0) && C0 != 0 && LHS.getReg().isVirtual() &&
1712 MRI.
hasOneUse(LHS.getReg()) && (IsSigned || C0 != -1)) {
1714 if (
Register RegZ = searchConst(C0 + 1)) {
1722 MI.eraseFromParent();
1732 if (
isFromLoadImm(MRI, RHS, C0) && C0 != 0 && RHS.getReg().isVirtual() &&
1735 if (
Register RegZ = searchConst(C0 - 1)) {
1743 MI.eraseFromParent();
1753 assert(
MI.getDesc().isBranch() &&
"Unexpected opcode!");
1755 int NumOp =
MI.getNumExplicitOperands();
1756 return MI.getOperand(NumOp - 1).getMBB();
1760 int64_t BrOffset)
const {
1761 unsigned XLen =
STI.getXLen();
1768 case RISCV::NDS_BBC:
1769 case RISCV::NDS_BBS:
1770 case RISCV::NDS_BEQC:
1771 case RISCV::NDS_BNEC:
1781 case RISCV::CV_BEQIMM:
1782 case RISCV::CV_BNEIMM:
1783 case RISCV::QC_BEQI:
1784 case RISCV::QC_BNEI:
1785 case RISCV::QC_BGEI:
1786 case RISCV::QC_BLTI:
1787 case RISCV::QC_BLTUI:
1788 case RISCV::QC_BGEUI:
1789 case RISCV::QC_E_BEQI:
1790 case RISCV::QC_E_BNEI:
1791 case RISCV::QC_E_BGEI:
1792 case RISCV::QC_E_BLTI:
1793 case RISCV::QC_E_BLTUI:
1794 case RISCV::QC_E_BGEUI:
1797 case RISCV::PseudoBR:
1799 case RISCV::PseudoJump:
1806 const PseudoSourceValue *PSV = MMO->getPseudoValue();
1807 return PSV && PSV->isJumpTable();
1815 if (!
Reg.isVirtual())
1823 return MO.getIndex();
1832 if (!
Reg.isVirtual())
1839 switch (
MI->getOpcode()) {
1875 if (
MI.getOpcode() != RISCV::PseudoBRIND &&
1876 MI.getOpcode() != RISCV::PseudoBRINDX7)
1880 if (!Reg.isVirtual())
1891 switch (Def->getOpcode()) {
1932 case RISCV::ADD:
return RISCV::PseudoCCADD;
1933 case RISCV::SUB:
return RISCV::PseudoCCSUB;
1934 case RISCV::SLL:
return RISCV::PseudoCCSLL;
1935 case RISCV::SRL:
return RISCV::PseudoCCSRL;
1936 case RISCV::SRA:
return RISCV::PseudoCCSRA;
1937 case RISCV::AND:
return RISCV::PseudoCCAND;
1938 case RISCV::OR:
return RISCV::PseudoCCOR;
1939 case RISCV::XOR:
return RISCV::PseudoCCXOR;
1940 case RISCV::MAX:
return RISCV::PseudoCCMAX;
1941 case RISCV::MAXU:
return RISCV::PseudoCCMAXU;
1942 case RISCV::MIN:
return RISCV::PseudoCCMIN;
1943 case RISCV::MINU:
return RISCV::PseudoCCMINU;
1944 case RISCV::MUL:
return RISCV::PseudoCCMUL;
1945 case RISCV::LUI:
return RISCV::PseudoCCLUI;
1946 case RISCV::QC_LI:
return RISCV::PseudoCCQC_LI;
1947 case RISCV::QC_E_LI:
return RISCV::PseudoCCQC_E_LI;
1949 case RISCV::ADDI:
return RISCV::PseudoCCADDI;
1950 case RISCV::SLLI:
return RISCV::PseudoCCSLLI;
1951 case RISCV::SRLI:
return RISCV::PseudoCCSRLI;
1952 case RISCV::SRAI:
return RISCV::PseudoCCSRAI;
1953 case RISCV::ANDI:
return RISCV::PseudoCCANDI;
1954 case RISCV::ORI:
return RISCV::PseudoCCORI;
1955 case RISCV::XORI:
return RISCV::PseudoCCXORI;
1957 case RISCV::ADDW:
return RISCV::PseudoCCADDW;
1958 case RISCV::SUBW:
return RISCV::PseudoCCSUBW;
1959 case RISCV::SLLW:
return RISCV::PseudoCCSLLW;
1960 case RISCV::SRLW:
return RISCV::PseudoCCSRLW;
1961 case RISCV::SRAW:
return RISCV::PseudoCCSRAW;
1963 case RISCV::ADDIW:
return RISCV::PseudoCCADDIW;
1964 case RISCV::SLLIW:
return RISCV::PseudoCCSLLIW;
1965 case RISCV::SRLIW:
return RISCV::PseudoCCSRLIW;
1966 case RISCV::SRAIW:
return RISCV::PseudoCCSRAIW;
1968 case RISCV::ANDN:
return RISCV::PseudoCCANDN;
1969 case RISCV::ORN:
return RISCV::PseudoCCORN;
1970 case RISCV::XNOR:
return RISCV::PseudoCCXNOR;
1972 case RISCV::NDS_BFOS:
return RISCV::PseudoCCNDS_BFOS;
1973 case RISCV::NDS_BFOZ:
return RISCV::PseudoCCNDS_BFOZ;
1977 return RISCV::INSTRUCTION_LIST_END;
1986 if (!
Reg.isVirtual())
1994 if (!STI.hasShortForwardBranchIMinMax() &&
1995 (
MI->getOpcode() == RISCV::MAX ||
MI->getOpcode() == RISCV::MIN ||
1996 MI->getOpcode() == RISCV::MINU ||
MI->getOpcode() == RISCV::MAXU))
1999 if (!STI.hasShortForwardBranchIMul() &&
MI->getOpcode() == RISCV::MUL)
2006 if (
MI->getOpcode() == RISCV::ADDI &&
MI->getOperand(1).isReg() &&
2007 MI->getOperand(1).getReg() == RISCV::X0)
2012 if (MO.isFI() || MO.isCPI() || MO.isJTI())
2025 bool DontMoveAcrossStores =
true;
2026 if (!
MI->isSafeToMove(DontMoveAcrossStores))
2034 bool PreferFalse)
const {
2035 assert(
MI.getOpcode() == RISCV::PseudoCCMOVGPR &&
2036 "Unknown select instruction");
2037 if (!
STI.hasShortForwardBranchIALU())
2043 bool Invert = !
DefMI;
2051 Register DestReg =
MI.getOperand(0).getReg();
2057 assert(PredOpc != RISCV::INSTRUCTION_LIST_END &&
"Unexpected opcode!");
2064 NewMI.
add(FalseReg);
2072 unsigned BCCOpcode =
MI.getOperand(
MI.getNumExplicitOperands() - 3).getImm();
2078 NewMI.
add(
MI.getOperand(
MI.getNumExplicitOperands() - 2));
2079 NewMI.
add(
MI.getOperand(
MI.getNumExplicitOperands() - 1));
2089 if (
DefMI->getParent() !=
MI.getParent())
2093 DefMI->eraseFromParent();
2098 if (
MI.isMetaInstruction())
2101 unsigned Opcode =
MI.getOpcode();
2103 if (Opcode == TargetOpcode::INLINEASM ||
2104 Opcode == TargetOpcode::INLINEASM_BR) {
2106 return getInlineAsmLength(
MI.getOperand(0).getSymbolName(),
2111 if (
STI.hasStdExtZca()) {
2112 if (
unsigned Size = getCompressedSize(
MI,
STI))
2119 if (Opcode == TargetOpcode::BUNDLE)
2120 return getInstBundleSize(
MI);
2122 if (
MI.getParent() &&
MI.getParent()->getParent()) {
2123 if (
unsigned Size = getCompressedSize(
MI,
STI))
2128 case RISCV::PseudoMV_FPR16INX:
2129 case RISCV::PseudoMV_FPR32INX:
2130 case RISCV::PseudoClearGPR:
2132 return STI.hasStdExtZca() ? 2 : 4;
2134 case RISCV::PseudoCCMOVGPRNoX0:
2135 return get(
MI.getOperand(
MI.getNumExplicitOperands() - 3).getImm())
2138 case RISCV::PseudoCCMOVGPR:
2139 case RISCV::PseudoCCADD:
2140 case RISCV::PseudoCCSUB:
2141 case RISCV::PseudoCCSLL:
2142 case RISCV::PseudoCCSRL:
2143 case RISCV::PseudoCCSRA:
2144 case RISCV::PseudoCCAND:
2145 case RISCV::PseudoCCOR:
2146 case RISCV::PseudoCCXOR:
2147 case RISCV::PseudoCCADDI:
2148 case RISCV::PseudoCCANDI:
2149 case RISCV::PseudoCCORI:
2150 case RISCV::PseudoCCXORI:
2151 case RISCV::PseudoCCLUI:
2152 case RISCV::PseudoCCSLLI:
2153 case RISCV::PseudoCCSRLI:
2154 case RISCV::PseudoCCSRAI:
2155 case RISCV::PseudoCCADDW:
2156 case RISCV::PseudoCCSUBW:
2157 case RISCV::PseudoCCSLLW:
2158 case RISCV::PseudoCCSRLW:
2159 case RISCV::PseudoCCSRAW:
2160 case RISCV::PseudoCCADDIW:
2161 case RISCV::PseudoCCSLLIW:
2162 case RISCV::PseudoCCSRLIW:
2163 case RISCV::PseudoCCSRAIW:
2164 case RISCV::PseudoCCANDN:
2165 case RISCV::PseudoCCORN:
2166 case RISCV::PseudoCCXNOR:
2167 case RISCV::PseudoCCMAX:
2168 case RISCV::PseudoCCMIN:
2169 case RISCV::PseudoCCMAXU:
2170 case RISCV::PseudoCCMINU:
2171 case RISCV::PseudoCCMUL:
2172 case RISCV::PseudoCCLB:
2173 case RISCV::PseudoCCLH:
2174 case RISCV::PseudoCCLW:
2175 case RISCV::PseudoCCLHU:
2176 case RISCV::PseudoCCLBU:
2177 case RISCV::PseudoCCLWU:
2178 case RISCV::PseudoCCLD:
2179 case RISCV::PseudoCCQC_LI:
2180 return get(
MI.getOperand(
MI.getNumExplicitOperands() - 3).getImm())
2183 case RISCV::PseudoCCQC_E_LI:
2184 case RISCV::PseudoCCQC_E_LB:
2185 case RISCV::PseudoCCQC_E_LH:
2186 case RISCV::PseudoCCQC_E_LW:
2187 case RISCV::PseudoCCQC_E_LHU:
2188 case RISCV::PseudoCCQC_E_LBU:
2189 return get(
MI.getOperand(
MI.getNumExplicitOperands() - 3).getImm())
2192 case TargetOpcode::STACKMAP:
2195 case TargetOpcode::PATCHPOINT:
2198 case TargetOpcode::STATEPOINT: {
2202 return std::max(NumBytes, 8U);
2204 case TargetOpcode::PATCHABLE_FUNCTION_ENTER:
2205 case TargetOpcode::PATCHABLE_FUNCTION_EXIT:
2206 case TargetOpcode::PATCHABLE_TAIL_CALL: {
2209 if (Opcode == TargetOpcode::PATCHABLE_FUNCTION_ENTER &&
2210 F.hasFnAttribute(
"patchable-function-entry")) {
2212 F.getFnAttributeAsParsedInteger(
"patchable-function-entry");
2214 return (
STI.hasStdExtZca() ? 2 : 4) * Num;
2218 return STI.is64Bit() ? 68 : 44;
2221 return get(Opcode).getSize();
2226 const unsigned Opcode =
MI.getOpcode();
2230 case RISCV::FSGNJ_D:
2231 case RISCV::FSGNJ_S:
2232 case RISCV::FSGNJ_H:
2233 case RISCV::FSGNJ_D_INX:
2234 case RISCV::FSGNJ_D_IN32X:
2235 case RISCV::FSGNJ_S_INX:
2236 case RISCV::FSGNJ_H_INX:
2238 return MI.getOperand(1).isReg() &&
MI.getOperand(2).isReg() &&
2239 MI.getOperand(1).getReg() ==
MI.getOperand(2).getReg();
2243 return (
MI.getOperand(1).isReg() &&
2244 MI.getOperand(1).getReg() == RISCV::X0) ||
2245 (
MI.getOperand(2).isImm() &&
MI.getOperand(2).getImm() == 0);
2247 return MI.isAsCheapAsAMove();
2250std::optional<DestSourcePair>
2254 switch (
MI.getOpcode()) {
2260 if (
MI.getOperand(1).isReg() &&
MI.getOperand(1).getReg() == RISCV::X0 &&
2261 MI.getOperand(2).isReg())
2263 if (
MI.getOperand(2).isReg() &&
MI.getOperand(2).getReg() == RISCV::X0 &&
2264 MI.getOperand(1).isReg())
2269 if (
MI.getOperand(1).isReg() &&
MI.getOperand(2).isImm() &&
2270 MI.getOperand(2).getImm() == 0)
2274 if (
MI.getOperand(2).isReg() &&
MI.getOperand(2).getReg() == RISCV::X0 &&
2275 MI.getOperand(1).isReg())
2279 case RISCV::SH1ADD_UW:
2281 case RISCV::SH2ADD_UW:
2283 case RISCV::SH3ADD_UW:
2284 if (
MI.getOperand(1).isReg() &&
MI.getOperand(1).getReg() == RISCV::X0 &&
2285 MI.getOperand(2).isReg())
2288 case RISCV::FSGNJ_D:
2289 case RISCV::FSGNJ_S:
2290 case RISCV::FSGNJ_H:
2291 case RISCV::FSGNJ_D_INX:
2292 case RISCV::FSGNJ_D_IN32X:
2293 case RISCV::FSGNJ_S_INX:
2294 case RISCV::FSGNJ_H_INX:
2296 if (
MI.getOperand(1).isReg() &&
MI.getOperand(2).isReg() &&
2297 MI.getOperand(1).getReg() ==
MI.getOperand(2).getReg())
2301 return std::nullopt;
2305 std::optional<MachineTraceStrategy> Forced =
2306 STI.getCLOpts().force_machine_combiner_strategy;
2311 const auto &SchedModel =
STI.getSchedModel();
2312 return (!SchedModel.hasInstrSchedModel() || SchedModel.isOutOfOrder())
2324 RISCV::getNamedOperandIdx(Root.
getOpcode(), RISCV::OpName::frm);
2328 return RISCV::getNamedOperandIdx(
MI->getOpcode(),
2329 RISCV::OpName::frm) < 0;
2331 "New instructions require FRM whereas the old one does not have it");
2338 for (
auto *NewMI : InsInstrs) {
2340 if (
static_cast<unsigned>(RISCV::getNamedOperandIdx(
2341 NewMI->getOpcode(), RISCV::OpName::frm)) != NewMI->getNumOperands())
2383bool RISCVInstrInfo::isVectorAssociativeAndCommutative(
const MachineInstr &Inst,
2384 bool Invert)
const {
2385#define OPCODE_LMUL_CASE(OPC) \
2386 case RISCV::OPC##_M1: \
2387 case RISCV::OPC##_M2: \
2388 case RISCV::OPC##_M4: \
2389 case RISCV::OPC##_M8: \
2390 case RISCV::OPC##_MF2: \
2391 case RISCV::OPC##_MF4: \
2392 case RISCV::OPC##_MF8
2394#define OPCODE_LMUL_MASK_CASE(OPC) \
2395 case RISCV::OPC##_M1_MASK: \
2396 case RISCV::OPC##_M2_MASK: \
2397 case RISCV::OPC##_M4_MASK: \
2398 case RISCV::OPC##_M8_MASK: \
2399 case RISCV::OPC##_MF2_MASK: \
2400 case RISCV::OPC##_MF4_MASK: \
2401 case RISCV::OPC##_MF8_MASK
2406 Opcode = *InvOpcode;
2423#undef OPCODE_LMUL_MASK_CASE
2424#undef OPCODE_LMUL_CASE
2427bool RISCVInstrInfo::areRVVInstsReassociable(
const MachineInstr &Root,
2440 auto checkImmOperand = [&](
unsigned OpIdx) {
2444 auto checkRegOperand = [&](
unsigned OpIdx) {
2452 if (!checkRegOperand(1))
2467 bool SeenMI2 =
false;
2477 if (It->modifiesRegister(RISCV::V0,
TRI)) {
2478 Register SrcReg = It->getOperand(1).getReg();
2496 if (MI1VReg != SrcReg)
2505 assert(SeenMI2 &&
"Prev is expected to appear before Root");
2516 const MachineOperand &Op1 = Root.
getOperand(OpIdx);
2517 const MachineOperand &Op2 = Prev.
getOperand(OpIdx);
2545bool RISCVInstrInfo::hasReassociableVectorSibling(
const MachineInstr &Inst,
2546 bool &Commuted)
const {
2550 "Expect the present of passthrough operand.");
2556 Commuted = !areRVVInstsReassociable(Inst, *MI1) &&
2557 areRVVInstsReassociable(Inst, *MI2);
2561 return areRVVInstsReassociable(Inst, *MI1) &&
2562 (isVectorAssociativeAndCommutative(*MI1) ||
2563 isVectorAssociativeAndCommutative(*MI1,
true)) &&
2570 if (!isVectorAssociativeAndCommutative(Inst) &&
2571 !isVectorAssociativeAndCommutative(Inst,
true))
2597 for (
unsigned I = 0;
I < 5; ++
I)
2603 bool &Commuted)
const {
2604 if (isVectorAssociativeAndCommutative(Inst) ||
2605 isVectorAssociativeAndCommutative(Inst,
true))
2606 return hasReassociableVectorSibling(Inst, Commuted);
2612 unsigned OperandIdx = Commuted ? 2 : 1;
2616 int16_t InstFrmOpIdx =
2617 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::frm);
2618 int16_t SiblingFrmOpIdx =
2619 RISCV::getNamedOperandIdx(Sibling.
getOpcode(), RISCV::OpName::frm);
2621 return (InstFrmOpIdx < 0 && SiblingFrmOpIdx < 0) ||
2626 bool Invert)
const {
2627 if (isVectorAssociativeAndCommutative(Inst, Invert))
2635 Opc = *InverseOpcode;
2680std::optional<unsigned>
2682#define RVV_OPC_LMUL_CASE(OPC, INV) \
2683 case RISCV::OPC##_M1: \
2684 return RISCV::INV##_M1; \
2685 case RISCV::OPC##_M2: \
2686 return RISCV::INV##_M2; \
2687 case RISCV::OPC##_M4: \
2688 return RISCV::INV##_M4; \
2689 case RISCV::OPC##_M8: \
2690 return RISCV::INV##_M8; \
2691 case RISCV::OPC##_MF2: \
2692 return RISCV::INV##_MF2; \
2693 case RISCV::OPC##_MF4: \
2694 return RISCV::INV##_MF4; \
2695 case RISCV::OPC##_MF8: \
2696 return RISCV::INV##_MF8
2698#define RVV_OPC_LMUL_MASK_CASE(OPC, INV) \
2699 case RISCV::OPC##_M1_MASK: \
2700 return RISCV::INV##_M1_MASK; \
2701 case RISCV::OPC##_M2_MASK: \
2702 return RISCV::INV##_M2_MASK; \
2703 case RISCV::OPC##_M4_MASK: \
2704 return RISCV::INV##_M4_MASK; \
2705 case RISCV::OPC##_M8_MASK: \
2706 return RISCV::INV##_M8_MASK; \
2707 case RISCV::OPC##_MF2_MASK: \
2708 return RISCV::INV##_MF2_MASK; \
2709 case RISCV::OPC##_MF4_MASK: \
2710 return RISCV::INV##_MF4_MASK; \
2711 case RISCV::OPC##_MF8_MASK: \
2712 return RISCV::INV##_MF8_MASK
2716 return std::nullopt;
2718 return RISCV::FSUB_H;
2720 return RISCV::FSUB_S;
2722 return RISCV::FSUB_D;
2724 return RISCV::FADD_H;
2726 return RISCV::FADD_S;
2728 return RISCV::FADD_D;
2745#undef RVV_OPC_LMUL_MASK_CASE
2746#undef RVV_OPC_LMUL_CASE
2751 bool DoRegPressureReduce) {
2778 bool DoRegPressureReduce) {
2785 DoRegPressureReduce)) {
2791 DoRegPressureReduce)) {
2801 bool DoRegPressureReduce) {
2809 unsigned CombineOpc) {
2816 if (!
MI ||
MI->getParent() != &
MBB ||
MI->getOpcode() != CombineOpc)
2830 unsigned OuterShiftAmt) {
2836 if (InnerShiftAmt < OuterShiftAmt || (InnerShiftAmt - OuterShiftAmt) > 3)
2863 case RISCV::SH1ADD_UW:
2865 case RISCV::SH2ADD_UW:
2867 case RISCV::SH3ADD_UW:
2913 bool DoRegPressureReduce)
const {
2922 DoRegPressureReduce);
2930 return RISCV::FMADD_H;
2932 return RISCV::FMADD_S;
2934 return RISCV::FMADD_D;
3009 assert(OuterShiftAmt != 0 &&
"Unexpected opcode");
3016 assert(InnerShiftAmt >= OuterShiftAmt &&
"Unexpected shift amount");
3019 switch (InnerShiftAmt - OuterShiftAmt) {
3023 InnerOpc = RISCV::ADD;
3026 InnerOpc = RISCV::SH1ADD;
3029 InnerOpc = RISCV::SH2ADD;
3032 InnerOpc = RISCV::SH3ADD;
3050 InstrIdxForVirtReg.
insert(std::make_pair(NewVR, 0));
3067 DelInstrs, InstrIdxForVirtReg);
3094 for (
const auto &[Index, Operand] :
enumerate(
Desc.operands())) {
3096 unsigned OpType = Operand.OperandType;
3102 ErrInfo =
"Expected an immediate operand.";
3111#define CASE_OPERAND_UIMM(NUM) \
3112 case RISCVOp::OPERAND_UIMM##NUM: \
3113 Ok = isUInt<NUM>(Imm); \
3115#define CASE_OPERAND_UIMM_LSB_ZEROS(BITS, SUFFIX) \
3116 case RISCVOp::OPERAND_UIMM##BITS##_LSB##SUFFIX: { \
3117 constexpr size_t NumZeros = sizeof(#SUFFIX) - 1; \
3118 Ok = isShiftedUInt<BITS - NumZeros, NumZeros>(Imm); \
3121#define CASE_OPERAND_SIMM(NUM) \
3122 case RISCVOp::OPERAND_SIMM##NUM: \
3123 Ok = isInt<NUM>(Imm); \
3152 Ok =
Imm >= 1 &&
Imm <= 16;
3161 Ok =
Imm >= 1 &&
Imm <= 32;
3164 Ok =
Imm >= 1 &&
Imm <= 64;
3200 Ok =
Imm >= -15 &&
Imm <= 16;
3228 Ok = Ok &&
Imm != 0;
3234 Ok =
Imm >= 0 &&
Imm <= 10;
3237 Ok =
Imm >= 0 &&
Imm <= 7;
3240 Ok =
Imm >= 1 &&
Imm <= 10;
3243 Ok =
Imm >= 2 &&
Imm <= 14;
3252 Ok =
Imm >= 0 &&
Imm <= 48 &&
Imm % 16 == 0;
3297 ErrInfo =
"Invalid immediate";
3306 ErrInfo =
"Expected a non-register operand.";
3310 ErrInfo =
"Invalid immediate";
3319 ErrInfo =
"Expected a non-register operand.";
3323 ErrInfo =
"Invalid immediate";
3331 ErrInfo =
"Expected a non-register operand.";
3335 ErrInfo =
"Invalid immediate";
3344 ErrInfo =
"Invalid immediate";
3347 }
else if (!MO.
isReg()) {
3348 ErrInfo =
"Expected a register or immediate operand.";
3354 ErrInfo =
"Expected a register or immediate operand.";
3361 const uint64_t TSFlags =
Desc.TSFlags;
3364 if (!
Op.isImm() && !
Op.isReg()) {
3365 ErrInfo =
"Invalid operand type for VL operand";
3368 if (
Op.isReg() &&
Op.getReg().isValid()) {
3371 if (!RISCV::GPRNoX0RegClass.hasSubClassEq(RC)) {
3372 ErrInfo =
"Invalid register class for VL operand";
3377 ErrInfo =
"VL operand w/o SEW operand?";
3383 if (!
MI.getOperand(OpIdx).isImm()) {
3384 ErrInfo =
"SEW value expected to be an immediate";
3387 uint64_t Log2SEW =
MI.getOperand(OpIdx).getImm();
3389 ErrInfo =
"Unexpected SEW value";
3392 unsigned SEW = Log2SEW ? 1 << Log2SEW : 8;
3394 ErrInfo =
"Unexpected SEW value";
3400 if (!
MI.getOperand(OpIdx).isImm()) {
3401 ErrInfo =
"Policy operand expected to be an immediate";
3404 uint64_t Policy =
MI.getOperand(OpIdx).getImm();
3406 ErrInfo =
"Invalid Policy Value";
3410 ErrInfo =
"policy operand w/o VL operand?";
3418 if (!
MI.isRegTiedToUseOperand(0, &UseOpIdx)) {
3419 ErrInfo =
"policy operand w/o tied operand?";
3426 !
MI.readsRegister(RISCV::FRM,
nullptr)) {
3427 ErrInfo =
"dynamic rounding mode should read FRM";
3449 case RISCV::LD_RV32:
3459 case RISCV::SD_RV32:
3475 int64_t NewOffset = OldOffset + Disp;
3497 "Addressing mode not supported for folding");
3569 case RISCV::LD_RV32:
3572 case RISCV::SD_RV32:
3579 OffsetIsScalable =
false;
3595 if (BaseOps1.
front()->isIdenticalTo(*BaseOps2.
front()))
3603 if (MO1->getAddrSpace() != MO2->getAddrSpace())
3606 auto Base1 = MO1->getValue();
3607 auto Base2 = MO2->getValue();
3608 if (!Base1 || !Base2)
3616 return Base1 == Base2;
3622 int64_t Offset2,
bool OffsetIsScalable2,
unsigned ClusterSize,
3623 unsigned NumBytes)
const {
3626 if (!BaseOps1.
empty() && !BaseOps2.
empty()) {
3631 }
else if (!BaseOps1.
empty() || !BaseOps2.
empty()) {
3637 BaseOps1.
front()->getParent()->getMF()->getSubtarget().getCacheLineSize();
3643 return ClusterSize <= 4 && std::abs(Offset1 - Offset2) <
CacheLineSize;
3692 int64_t OffsetA = 0, OffsetB = 0;
3698 int LowOffset = std::min(OffsetA, OffsetB);
3699 int HighOffset = std::max(OffsetA, OffsetB);
3700 LocationSize LowWidth = (LowOffset == OffsetA) ? WidthA : WidthB;
3702 LowOffset + (
int)LowWidth.
getValue() <= HighOffset)
3709std::pair<unsigned, unsigned>
3712 return std::make_pair(TF & Mask, TF & ~Mask);
3718 static const std::pair<unsigned, const char *> TargetFlags[] = {
3719 {MO_CALL,
"riscv-call"},
3720 {MO_LO,
"riscv-lo"},
3721 {MO_HI,
"riscv-hi"},
3722 {MO_PCREL_LO,
"riscv-pcrel-lo"},
3723 {MO_PCREL_HI,
"riscv-pcrel-hi"},
3724 {MO_GOT_HI,
"riscv-got-hi"},
3725 {MO_TPREL_LO,
"riscv-tprel-lo"},
3726 {MO_TPREL_HI,
"riscv-tprel-hi"},
3727 {MO_TPREL_ADD,
"riscv-tprel-add"},
3728 {MO_TLS_GOT_HI,
"riscv-tls-got-hi"},
3729 {MO_TLS_GD_HI,
"riscv-tls-gd-hi"},
3730 {MO_TLSDESC_HI,
"riscv-tlsdesc-hi"},
3731 {MO_TLSDESC_LOAD_LO,
"riscv-tlsdesc-load-lo"},
3732 {MO_TLSDESC_ADD_LO,
"riscv-tlsdesc-add-lo"},
3733 {MO_TLSDESC_CALL,
"riscv-tlsdesc-call"},
3734 {MO_QC_ACCESS,
"riscv-qc-access"},
3740 unsigned &Flags)
const {
3760 return F.getFnAttribute(
"fentry-call").getValueAsBool() ||
3761 F.hasFnAttribute(
"patchable-function-entry");
3766 return MI.readsRegister(RegNo,
TRI) ||
3767 MI.getDesc().hasImplicitUseOfPhysReg(RegNo);
3772 return MI.modifiesRegister(RegNo,
TRI) ||
3773 MI.getDesc().hasImplicitDefOfPhysReg(RegNo);
3777 if (!
MBB.back().isReturn())
3823 if (
C.isAvailableAcrossAndOutOfSeq(
Reg,
TRI) &&
3824 C.isAvailableInsideSeq(
Reg,
TRI)) {
3842 if (
C.back().isReturn() &&
3843 !
C.isAvailableAcrossAndOutOfSeq(TailExpandUseReg, RegInfo)) {
3845 LLVM_DEBUG(
dbgs() <<
"Cannot be outlined between: " <<
C.front() <<
"and "
3847 LLVM_DEBUG(
dbgs() <<
"Because the tail-call register is live across "
3848 "the proposed outlined function call\n");
3854 if (
C.back().isReturn()) {
3856 "The candidate who uses return instruction must be outlined "
3863 if (!
C.isAvailableInsideSeq(RISCV::X5, RegInfo))
3867 if (
C.isAvailableAcrossAndOutOfSeq(RISCV::X5, RegInfo))
3877std::optional<std::unique_ptr<outliner::OutlinedFunction>>
3880 std::vector<outliner::Candidate> &RepeatedSequenceLocs,
3881 unsigned MinRepeats)
const {
3889 if (RepeatedSequenceLocs.size() < MinRepeats)
3890 return std::nullopt;
3894 unsigned InstrSizeCExt =
3896 unsigned CallOverhead = 0, FrameOverhead = 0;
3899 unsigned CFICount = 0;
3900 for (
auto &
I : Candidate) {
3901 if (
I.isCFIInstruction())
3912 std::vector<MCCFIInstruction> CFIInstructions =
3913 C.getMF()->getFrameInstructions();
3915 if (CFICount > 0 && CFICount != CFIInstructions.size())
3916 return std::nullopt;
3924 CallOverhead = 4 + InstrSizeCExt;
3931 FrameOverhead = InstrSizeCExt;
3937 return std::nullopt;
3941 for (
auto &
C : RepeatedSequenceLocs) {
3943 if (
C.isAvailableAcrossAndOutOfSeq(RISCV::X5, RegInfo)) {
3945 unsigned CandCallOverhead = 8;
3950 unsigned CandCallOverhead = InstrSizeCExt + 8 + InstrSizeCExt;
3955 for (
auto &
C : RepeatedSequenceLocs)
3956 C.setCallInfo(MOCI, CallOverhead);
3959 unsigned SequenceSize = 0;
3960 for (
auto &
MI : Candidate)
3963 return std::make_unique<outliner::OutlinedFunction>(
3964 RepeatedSequenceLocs, SequenceSize, FrameOverhead, MOCI);
3970 unsigned Flags)
const {
3974 MBB->getParent()->getSubtarget().getRegisterInfo();
3975 const auto &
F =
MI.getMF()->getFunction();
3980 if (
MI.isCFIInstruction())
3988 for (
const auto &MO :
MI.operands()) {
3993 (
MI.getMF()->getTarget().getFunctionSections() ||
F.hasComdat() ||
3994 F.hasSection() ||
F.getSectionPrefix()))
4011 MBB.addLiveIn(RISCV::X5);
4029 .addGlobalAddress(M.getNamedValue(MF.
getName()),
4036 assert(SaveReg &&
"Cannot find an available register to save/restore X5.");
4047 .addGlobalAddress(M.getNamedValue(MF.
getName()), 0,
4063 .addGlobalAddress(M.getNamedValue(MF.
getName()), 0,
4071 bool AllowSideEffects)
const {
4076 if (
TRI.isGeneralPurposeRegister(MF, Reg)) {
4078 }
else if (RISCV::FPR32RegClass.
contains(Reg)) {
4080 }
else if (RISCV::FPR64RegClass.
contains(Reg)) {
4082 }
else if (RISCV::FPR128RegClass.
contains(Reg)) {
4084 }
else if (RISCV::VRRegClass.
contains(Reg)) {
4088 "buildClearRegister is not implemented for " +
TRI.getRegAsmName(Reg));
4098 return std::nullopt;
4102 if (
MI.getOpcode() == RISCV::ADDI &&
MI.getOperand(1).isReg() &&
4103 MI.getOperand(2).isImm())
4104 return RegImmPair{
MI.getOperand(1).getReg(),
MI.getOperand(2).getImm()};
4106 return std::nullopt;
4112 unsigned OpIdx)
const {
4114 std::string GenericComment =
4116 if (!GenericComment.empty())
4117 return GenericComment;
4120 if (OpIdx >=
Desc.getNumOperands())
4121 return std::string();
4123 std::string Comment;
4130 switch (OpInfo.OperandType) {
4133 unsigned Imm =
Op.getImm();
4138 unsigned Imm =
Op.getImm();
4143 unsigned Imm =
Op.getImm();
4149 unsigned Log2SEW =
Op.getImm();
4150 unsigned SEW = Log2SEW ? 1 << Log2SEW : 8;
4156 unsigned Policy =
Op.getImm();
4158 "Invalid Policy Value");
4164 if (
Op.isImm() &&
Op.getImm() == -1)
4186#define CASE_RVV_OPCODE_UNMASK_LMUL(OP, LMUL) \
4187 RISCV::Pseudo##OP##_##LMUL
4189#define CASE_RVV_OPCODE_MASK_LMUL(OP, LMUL) \
4190 RISCV::Pseudo##OP##_##LMUL##_MASK
4192#define CASE_RVV_OPCODE_LMUL(OP, LMUL) \
4193 CASE_RVV_OPCODE_UNMASK_LMUL(OP, LMUL): \
4194 case CASE_RVV_OPCODE_MASK_LMUL(OP, LMUL)
4196#define CASE_RVV_OPCODE_UNMASK_WIDEN(OP) \
4197 CASE_RVV_OPCODE_UNMASK_LMUL(OP, MF8): \
4198 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, MF4): \
4199 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, MF2): \
4200 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, M1): \
4201 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, M2): \
4202 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, M4)
4204#define CASE_RVV_OPCODE_UNMASK(OP) \
4205 CASE_RVV_OPCODE_UNMASK_WIDEN(OP): \
4206 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, M8)
4208#define CASE_RVV_OPCODE_MASK_WIDEN(OP) \
4209 CASE_RVV_OPCODE_MASK_LMUL(OP, MF8): \
4210 case CASE_RVV_OPCODE_MASK_LMUL(OP, MF4): \
4211 case CASE_RVV_OPCODE_MASK_LMUL(OP, MF2): \
4212 case CASE_RVV_OPCODE_MASK_LMUL(OP, M1): \
4213 case CASE_RVV_OPCODE_MASK_LMUL(OP, M2): \
4214 case CASE_RVV_OPCODE_MASK_LMUL(OP, M4)
4216#define CASE_RVV_OPCODE_MASK(OP) \
4217 CASE_RVV_OPCODE_MASK_WIDEN(OP): \
4218 case CASE_RVV_OPCODE_MASK_LMUL(OP, M8)
4220#define CASE_RVV_OPCODE_WIDEN(OP) \
4221 CASE_RVV_OPCODE_UNMASK_WIDEN(OP): \
4222 case CASE_RVV_OPCODE_MASK_WIDEN(OP)
4224#define CASE_RVV_OPCODE(OP) \
4225 CASE_RVV_OPCODE_UNMASK(OP): \
4226 case CASE_RVV_OPCODE_MASK(OP)
4230#define CASE_VMA_OPCODE_COMMON(OP, TYPE, LMUL) \
4231 RISCV::PseudoV##OP##_##TYPE##_##LMUL
4233#define CASE_VMA_OPCODE_LMULS(OP, TYPE) \
4234 CASE_VMA_OPCODE_COMMON(OP, TYPE, MF8): \
4235 case CASE_VMA_OPCODE_COMMON(OP, TYPE, MF4): \
4236 case CASE_VMA_OPCODE_COMMON(OP, TYPE, MF2): \
4237 case CASE_VMA_OPCODE_COMMON(OP, TYPE, M1): \
4238 case CASE_VMA_OPCODE_COMMON(OP, TYPE, M2): \
4239 case CASE_VMA_OPCODE_COMMON(OP, TYPE, M4): \
4240 case CASE_VMA_OPCODE_COMMON(OP, TYPE, M8)
4243#define CASE_VFMA_OPCODE_COMMON(OP, TYPE, LMUL, SEW) \
4244 RISCV::PseudoV##OP##_##TYPE##_##LMUL##_##SEW
4246#define CASE_VFMA_OPCODE_LMULS_M1(OP, TYPE, SEW) \
4247 CASE_VFMA_OPCODE_COMMON(OP, TYPE, M1, SEW): \
4248 case CASE_VFMA_OPCODE_COMMON(OP, TYPE, M2, SEW): \
4249 case CASE_VFMA_OPCODE_COMMON(OP, TYPE, M4, SEW): \
4250 case CASE_VFMA_OPCODE_COMMON(OP, TYPE, M8, SEW)
4252#define CASE_VFMA_OPCODE_LMULS_MF2(OP, TYPE, SEW) \
4253 CASE_VFMA_OPCODE_COMMON(OP, TYPE, MF2, SEW): \
4254 case CASE_VFMA_OPCODE_LMULS_M1(OP, TYPE, SEW)
4256#define CASE_VFMA_OPCODE_LMULS_MF4(OP, TYPE, SEW) \
4257 CASE_VFMA_OPCODE_COMMON(OP, TYPE, MF4, SEW): \
4258 case CASE_VFMA_OPCODE_LMULS_MF2(OP, TYPE, SEW)
4260#define CASE_VFMA_OPCODE_VV(OP) \
4261 CASE_VFMA_OPCODE_LMULS_MF4(OP, VV, E16): \
4262 case CASE_VFMA_OPCODE_LMULS_MF4(OP##_ALT, VV, E16): \
4263 case CASE_VFMA_OPCODE_LMULS_MF2(OP, VV, E32): \
4264 case CASE_VFMA_OPCODE_LMULS_M1(OP, VV, E64)
4266#define CASE_VFMA_SPLATS(OP) \
4267 CASE_VFMA_OPCODE_LMULS_MF4(OP, VFPR16, E16): \
4268 case CASE_VFMA_OPCODE_LMULS_MF4(OP##_ALT, VFPR16, E16): \
4269 case CASE_VFMA_OPCODE_LMULS_MF2(OP, VFPR32, E32): \
4270 case CASE_VFMA_OPCODE_LMULS_M1(OP, VFPR64, E64)
4274 unsigned &SrcOpIdx1,
4275 unsigned &SrcOpIdx2)
const {
4277 if (!
Desc.isCommutable())
4280 switch (
MI.getOpcode()) {
4281 case RISCV::TH_MVEQZ:
4282 case RISCV::TH_MVNEZ:
4286 if (
MI.getOperand(2).getReg() == RISCV::X0)
4289 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 1, 2);
4290 case RISCV::QC_SELECTIEQ:
4291 case RISCV::QC_SELECTINE:
4292 case RISCV::QC_SELECTIIEQ:
4293 case RISCV::QC_SELECTIINE:
4294 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 1, 2);
4295 case RISCV::QC_MVEQ:
4296 case RISCV::QC_MVNE:
4297 case RISCV::QC_MVLT:
4298 case RISCV::QC_MVGE:
4299 case RISCV::QC_MVLTU:
4300 case RISCV::QC_MVGEU:
4301 case RISCV::QC_MVEQI:
4302 case RISCV::QC_MVNEI:
4303 case RISCV::QC_MVLTI:
4304 case RISCV::QC_MVGEI:
4305 case RISCV::QC_MVLTUI:
4306 case RISCV::QC_MVGEUI:
4307 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 1, 4);
4308 case RISCV::TH_MULA:
4309 case RISCV::TH_MULAW:
4310 case RISCV::TH_MULAH:
4311 case RISCV::TH_MULS:
4312 case RISCV::TH_MULSW:
4313 case RISCV::TH_MULSH:
4315 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 2, 3);
4316 case RISCV::PseudoCCMOVGPRNoX0:
4317 case RISCV::PseudoCCMOVGPR:
4319 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 1, 2);
4360 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 2, 3);
4387 unsigned CommutableOpIdx1 = 1;
4388 unsigned CommutableOpIdx2 = 3;
4389 if (!fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, CommutableOpIdx1,
4410 if (SrcOpIdx1 != CommuteAnyOperandIndex && SrcOpIdx1 > 3)
4412 if (SrcOpIdx2 != CommuteAnyOperandIndex && SrcOpIdx2 > 3)
4416 if (SrcOpIdx1 != CommuteAnyOperandIndex &&
4417 SrcOpIdx2 != CommuteAnyOperandIndex && SrcOpIdx1 != 1 && SrcOpIdx2 != 1)
4423 if (SrcOpIdx1 == CommuteAnyOperandIndex ||
4424 SrcOpIdx2 == CommuteAnyOperandIndex) {
4427 unsigned CommutableOpIdx1 = SrcOpIdx1;
4428 if (SrcOpIdx1 == SrcOpIdx2) {
4431 CommutableOpIdx1 = 1;
4432 }
else if (SrcOpIdx1 == CommuteAnyOperandIndex) {
4434 CommutableOpIdx1 = SrcOpIdx2;
4439 unsigned CommutableOpIdx2;
4440 if (CommutableOpIdx1 != 1) {
4442 CommutableOpIdx2 = 1;
4444 Register Op1Reg =
MI.getOperand(CommutableOpIdx1).getReg();
4449 if (Op1Reg !=
MI.getOperand(2).getReg())
4450 CommutableOpIdx2 = 2;
4452 CommutableOpIdx2 = 3;
4457 if (!fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, CommutableOpIdx1,
4470#define CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, LMUL) \
4471 case RISCV::PseudoV##OLDOP##_##TYPE##_##LMUL: \
4472 Opc = RISCV::PseudoV##NEWOP##_##TYPE##_##LMUL; \
4475#define CASE_VMA_CHANGE_OPCODE_LMULS(OLDOP, NEWOP, TYPE) \
4476 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF8) \
4477 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF4) \
4478 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF2) \
4479 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M1) \
4480 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M2) \
4481 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M4) \
4482 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M8)
4485#define CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, LMUL, SEW) \
4486 case RISCV::PseudoV##OLDOP##_##TYPE##_##LMUL##_##SEW: \
4487 Opc = RISCV::PseudoV##NEWOP##_##TYPE##_##LMUL##_##SEW; \
4490#define CASE_VFMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, TYPE, SEW) \
4491 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M1, SEW) \
4492 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M2, SEW) \
4493 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M4, SEW) \
4494 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M8, SEW)
4496#define CASE_VFMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, TYPE, SEW) \
4497 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF2, SEW) \
4498 CASE_VFMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, TYPE, SEW)
4500#define CASE_VFMA_CHANGE_OPCODE_LMULS_MF4(OLDOP, NEWOP, TYPE, SEW) \
4501 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF4, SEW) \
4502 CASE_VFMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, TYPE, SEW)
4504#define CASE_VFMA_CHANGE_OPCODE_VV(OLDOP, NEWOP) \
4505 CASE_VFMA_CHANGE_OPCODE_LMULS_MF4(OLDOP, NEWOP, VV, E16) \
4506 CASE_VFMA_CHANGE_OPCODE_LMULS_MF4(OLDOP##_ALT, NEWOP##_ALT, VV, E16) \
4507 CASE_VFMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, VV, E32) \
4508 CASE_VFMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, VV, E64)
4510#define CASE_VFMA_CHANGE_OPCODE_SPLATS(OLDOP, NEWOP) \
4511 CASE_VFMA_CHANGE_OPCODE_LMULS_MF4(OLDOP, NEWOP, VFPR16, E16) \
4512 CASE_VFMA_CHANGE_OPCODE_LMULS_MF4(OLDOP##_ALT, NEWOP##_ALT, VFPR16, E16) \
4513 CASE_VFMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, VFPR32, E32) \
4514 CASE_VFMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, VFPR64, E64)
4520 unsigned OpIdx2)
const {
4523 return *
MI.getParent()->getParent()->CloneMachineInstr(&
MI);
4527 switch (
MI.getOpcode()) {
4528 case RISCV::TH_MVEQZ:
4529 case RISCV::TH_MVNEZ: {
4530 auto &WorkingMI = cloneIfNew(
MI);
4531 WorkingMI.setDesc(
get(
MI.getOpcode() == RISCV::TH_MVEQZ ? RISCV::TH_MVNEZ
4532 : RISCV::TH_MVEQZ));
4536 case RISCV::QC_SELECTIEQ:
4537 case RISCV::QC_SELECTINE:
4538 case RISCV::QC_SELECTIIEQ:
4539 case RISCV::QC_SELECTIINE:
4541 case RISCV::QC_MVEQ:
4542 case RISCV::QC_MVNE:
4543 case RISCV::QC_MVLT:
4544 case RISCV::QC_MVGE:
4545 case RISCV::QC_MVLTU:
4546 case RISCV::QC_MVGEU:
4547 case RISCV::QC_MVEQI:
4548 case RISCV::QC_MVNEI:
4549 case RISCV::QC_MVLTI:
4550 case RISCV::QC_MVGEI:
4551 case RISCV::QC_MVLTUI:
4552 case RISCV::QC_MVGEUI: {
4553 auto &WorkingMI = cloneIfNew(
MI);
4558 case RISCV::PseudoCCMOVGPRNoX0:
4559 case RISCV::PseudoCCMOVGPR: {
4561 unsigned BCC =
MI.getOperand(
MI.getNumExplicitOperands() - 3).getImm();
4563 auto &WorkingMI = cloneIfNew(
MI);
4564 WorkingMI.getOperand(
MI.getNumExplicitOperands() - 3).setImm(BCC);
4588 assert((OpIdx1 == 1 || OpIdx2 == 1) &&
"Unexpected opcode index");
4589 assert((OpIdx1 == 3 || OpIdx2 == 3) &&
"Unexpected opcode index");
4591 switch (
MI.getOpcode()) {
4614 auto &WorkingMI = cloneIfNew(
MI);
4615 WorkingMI.setDesc(
get(
Opc));
4625 assert((OpIdx1 == 1 || OpIdx2 == 1) &&
"Unexpected opcode index");
4628 if (OpIdx1 == 3 || OpIdx2 == 3) {
4630 switch (
MI.getOpcode()) {
4641 auto &WorkingMI = cloneIfNew(
MI);
4642 WorkingMI.setDesc(
get(
Opc));
4654#undef CASE_VMA_CHANGE_OPCODE_COMMON
4655#undef CASE_VMA_CHANGE_OPCODE_LMULS
4656#undef CASE_VFMA_CHANGE_OPCODE_COMMON
4657#undef CASE_VFMA_CHANGE_OPCODE_LMULS_M1
4658#undef CASE_VFMA_CHANGE_OPCODE_LMULS_MF2
4659#undef CASE_VFMA_CHANGE_OPCODE_LMULS_MF4
4660#undef CASE_VFMA_CHANGE_OPCODE_VV
4661#undef CASE_VFMA_CHANGE_OPCODE_SPLATS
4663#undef CASE_RVV_OPCODE_UNMASK_LMUL
4664#undef CASE_RVV_OPCODE_MASK_LMUL
4665#undef CASE_RVV_OPCODE_LMUL
4666#undef CASE_RVV_OPCODE_UNMASK_WIDEN
4667#undef CASE_RVV_OPCODE_UNMASK
4668#undef CASE_RVV_OPCODE_MASK_WIDEN
4669#undef CASE_RVV_OPCODE_MASK
4670#undef CASE_RVV_OPCODE_WIDEN
4671#undef CASE_RVV_OPCODE
4673#undef CASE_VMA_OPCODE_COMMON
4674#undef CASE_VMA_OPCODE_LMULS
4675#undef CASE_VFMA_OPCODE_COMMON
4676#undef CASE_VFMA_OPCODE_LMULS_M1
4677#undef CASE_VFMA_OPCODE_LMULS_MF2
4678#undef CASE_VFMA_OPCODE_LMULS_MF4
4679#undef CASE_VFMA_OPCODE_VV
4680#undef CASE_VFMA_SPLATS
4683 switch (
MI.getOpcode()) {
4691 if (
MI.getOperand(1).getReg() == RISCV::X0)
4692 commuteInstruction(
MI);
4694 if (
MI.getOperand(2).getReg() == RISCV::X0) {
4695 MI.getOperand(2).ChangeToImmediate(0);
4696 MI.setDesc(
get(RISCV::ADDI));
4700 if (
MI.getOpcode() == RISCV::XOR &&
4701 MI.getOperand(1).getReg() ==
MI.getOperand(2).getReg()) {
4702 MI.getOperand(1).setReg(RISCV::X0);
4703 MI.getOperand(2).ChangeToImmediate(0);
4704 MI.setDesc(
get(RISCV::ADDI));
4711 if (
MI.getOperand(1).getReg() == RISCV::X0) {
4712 MI.setDesc(
get(RISCV::ADDI));
4718 if (
MI.getOperand(2).getReg() == RISCV::X0) {
4719 MI.getOperand(2).ChangeToImmediate(0);
4720 MI.setDesc(
get(RISCV::ADDI));
4726 if (
MI.getOperand(2).getReg() == RISCV::X0) {
4727 MI.getOperand(2).ChangeToImmediate(0);
4728 MI.setDesc(
get(RISCV::ADDIW));
4735 if (
MI.getOperand(1).getReg() == RISCV::X0)
4736 commuteInstruction(
MI);
4738 if (
MI.getOperand(2).getReg() == RISCV::X0) {
4739 MI.getOperand(2).ChangeToImmediate(0);
4740 MI.setDesc(
get(RISCV::ADDIW));
4745 case RISCV::SH1ADD_UW:
4747 case RISCV::SH2ADD_UW:
4749 case RISCV::SH3ADD_UW:
4751 if (
MI.getOperand(1).getReg() == RISCV::X0) {
4752 MI.removeOperand(1);
4754 MI.setDesc(
get(RISCV::ADDI));
4758 if (
MI.getOperand(2).getReg() == RISCV::X0) {
4759 MI.removeOperand(2);
4760 unsigned Opc =
MI.getOpcode();
4761 if (
Opc == RISCV::SH1ADD_UW ||
Opc == RISCV::SH2ADD_UW ||
4762 Opc == RISCV::SH3ADD_UW) {
4764 MI.setDesc(
get(RISCV::SLLI_UW));
4768 MI.setDesc(
get(RISCV::SLLI));
4782 if (
MI.getOperand(1).getReg() == RISCV::X0 ||
4783 MI.getOperand(2).getReg() == RISCV::X0) {
4784 MI.getOperand(1).setReg(RISCV::X0);
4785 MI.getOperand(2).ChangeToImmediate(0);
4786 MI.setDesc(
get(RISCV::ADDI));
4792 if (
MI.getOperand(1).getReg() == RISCV::X0) {
4793 MI.getOperand(2).setImm(0);
4794 MI.setDesc(
get(RISCV::ADDI));
4802 if (
MI.getOperand(1).getReg() == RISCV::X0) {
4803 MI.getOperand(2).ChangeToImmediate(0);
4804 MI.setDesc(
get(RISCV::ADDI));
4808 if (
MI.getOperand(2).getReg() == RISCV::X0) {
4809 MI.getOperand(2).ChangeToImmediate(0);
4810 MI.setDesc(
get(RISCV::ADDI));
4818 if (
MI.getOperand(1).getReg() == RISCV::X0) {
4819 MI.getOperand(2).ChangeToImmediate(0);
4820 MI.setDesc(
get(RISCV::ADDI));
4830 case RISCV::SLLI_UW:
4832 if (
MI.getOperand(1).getReg() == RISCV::X0) {
4833 MI.getOperand(2).setImm(0);
4834 MI.setDesc(
get(RISCV::ADDI));
4842 if (
MI.getOperand(1).getReg() == RISCV::X0 &&
4843 MI.getOperand(2).getReg() == RISCV::X0) {
4844 MI.getOperand(2).ChangeToImmediate(0);
4845 MI.setDesc(
get(RISCV::ADDI));
4849 if (
MI.getOpcode() == RISCV::ADD_UW &&
4850 MI.getOperand(1).getReg() == RISCV::X0) {
4851 MI.removeOperand(1);
4853 MI.setDesc(
get(RISCV::ADDI));
4859 if (
MI.getOperand(1).getReg() == RISCV::X0) {
4860 MI.getOperand(2).setImm(
MI.getOperand(2).getImm() != 0);
4861 MI.setDesc(
get(RISCV::ADDI));
4867 case RISCV::ZEXT_H_RV32:
4868 case RISCV::ZEXT_H_RV64:
4871 if (
MI.getOperand(1).getReg() == RISCV::X0) {
4873 MI.setDesc(
get(RISCV::ADDI));
4882 if (
MI.getOperand(1).getReg() ==
MI.getOperand(2).getReg()) {
4883 MI.getOperand(2).ChangeToImmediate(0);
4884 MI.setDesc(
get(RISCV::ADDI));
4891 if (
MI.getOperand(0).getReg() == RISCV::X0) {
4893 MI.removeOperand(0);
4894 MI.insert(
MI.operands_begin() + 1, {MO0});
4899 if (
MI.getOperand(0).getReg() == RISCV::X0) {
4901 MI.removeOperand(0);
4902 MI.insert(
MI.operands_begin() + 1, {MO0});
4903 MI.setDesc(
get(RISCV::BNE));
4908 if (
MI.getOperand(0).getReg() == RISCV::X0) {
4910 MI.removeOperand(0);
4911 MI.insert(
MI.operands_begin() + 1, {MO0});
4912 MI.setDesc(
get(RISCV::BEQ));
4920#define CASE_WIDEOP_OPCODE_COMMON(OP, LMUL) \
4921 RISCV::PseudoV##OP##_##LMUL##_TIED
4923#define CASE_WIDEOP_OPCODE_LMULS(OP) \
4924 CASE_WIDEOP_OPCODE_COMMON(OP, MF8): \
4925 case CASE_WIDEOP_OPCODE_COMMON(OP, MF4): \
4926 case CASE_WIDEOP_OPCODE_COMMON(OP, MF2): \
4927 case CASE_WIDEOP_OPCODE_COMMON(OP, M1): \
4928 case CASE_WIDEOP_OPCODE_COMMON(OP, M2): \
4929 case CASE_WIDEOP_OPCODE_COMMON(OP, M4)
4931#define CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, LMUL) \
4932 case RISCV::PseudoV##OP##_##LMUL##_TIED: \
4933 NewOpc = RISCV::PseudoV##OP##_##LMUL; \
4936#define CASE_WIDEOP_CHANGE_OPCODE_LMULS(OP) \
4937 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF8) \
4938 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF4) \
4939 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF2) \
4940 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, M1) \
4941 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, M2) \
4942 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, M4)
4945#define CASE_FP_WIDEOP_OPCODE_COMMON(OP, LMUL, SEW) \
4946 RISCV::PseudoV##OP##_##LMUL##_##SEW##_TIED
4948#define CASE_FP_WIDEOP_OPCODE_LMULS(OP) \
4949 CASE_FP_WIDEOP_OPCODE_COMMON(OP, MF4, E16): \
4950 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, MF2, E16): \
4951 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, MF2, E32): \
4952 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M1, E16): \
4953 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M1, E32): \
4954 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M2, E16): \
4955 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M2, E32): \
4956 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M4, E16): \
4957 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M4, E32) \
4959#define CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, LMUL, SEW) \
4960 case RISCV::PseudoV##OP##_##LMUL##_##SEW##_TIED: \
4961 NewOpc = RISCV::PseudoV##OP##_##LMUL##_##SEW; \
4964#define CASE_FP_WIDEOP_CHANGE_OPCODE_LMULS(OP) \
4965 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF4, E16) \
4966 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF2, E16) \
4967 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF2, E32) \
4968 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M1, E16) \
4969 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M1, E32) \
4970 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M2, E16) \
4971 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M2, E32) \
4972 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M4, E16) \
4973 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M4, E32) \
4975#define CASE_FP_WIDEOP_OPCODE_LMULS_ALT(OP) \
4976 CASE_FP_WIDEOP_OPCODE_COMMON(OP, MF4, E16): \
4977 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, MF2, E16): \
4978 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M1, E16): \
4979 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M2, E16): \
4980 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M4, E16)
4982#define CASE_FP_WIDEOP_CHANGE_OPCODE_LMULS_ALT(OP) \
4983 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF4, E16) \
4984 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF2, E16) \
4985 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M1, E16) \
4986 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M2, E16) \
4987 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M4, E16)
4993 switch (
MI.getOpcode()) {
5001 MI.getNumExplicitOperands() == 7 &&
5002 "Expect 7 explicit operands rd, rs2, rs1, rm, vl, sew, policy");
5009 switch (
MI.getOpcode()) {
5021 .
add(
MI.getOperand(0))
5023 .
add(
MI.getOperand(1))
5024 .
add(
MI.getOperand(2))
5025 .
add(
MI.getOperand(3))
5026 .
add(
MI.getOperand(4))
5027 .
add(
MI.getOperand(5))
5028 .
add(
MI.getOperand(6));
5037 MI.getNumExplicitOperands() == 6);
5044 switch (
MI.getOpcode()) {
5056 .
add(
MI.getOperand(0))
5058 .
add(
MI.getOperand(1))
5059 .
add(
MI.getOperand(2))
5060 .
add(
MI.getOperand(3))
5061 .
add(
MI.getOperand(4))
5062 .
add(
MI.getOperand(5));
5071 if (
MI.getOperand(0).isEarlyClobber()) {
5077 if (S->
end == Idx.getRegSlot(
true))
5078 S->
end = Idx.getRegSlot();
5085#undef CASE_WIDEOP_OPCODE_COMMON
5086#undef CASE_WIDEOP_OPCODE_LMULS
5087#undef CASE_WIDEOP_CHANGE_OPCODE_COMMON
5088#undef CASE_WIDEOP_CHANGE_OPCODE_LMULS
5089#undef CASE_FP_WIDEOP_OPCODE_COMMON
5090#undef CASE_FP_WIDEOP_OPCODE_LMULS
5091#undef CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON
5092#undef CASE_FP_WIDEOP_CHANGE_OPCODE_LMULS
5101 if (ShiftAmount == 0)
5107 }
else if (
int ShXAmount, ShiftAmount;
5109 (ShXAmount =
isShifted359(Amount, ShiftAmount)) != 0) {
5112 switch (ShXAmount) {
5114 Opc = RISCV::SH1ADD;
5117 Opc = RISCV::SH2ADD;
5120 Opc = RISCV::SH3ADD;
5156 }
else if (
STI.hasStdExtZmmul()) {
5166 for (
uint32_t ShiftAmount = 0; Amount >> ShiftAmount; ShiftAmount++) {
5167 if (Amount & (1U << ShiftAmount)) {
5171 .
addImm(ShiftAmount - PrevShiftAmount)
5173 if (Amount >> (ShiftAmount + 1)) {
5187 PrevShiftAmount = ShiftAmount;
5190 assert(Acc &&
"Expected valid accumulator");
5200 static const std::pair<MachineMemOperand::Flags, const char *> TargetFlags[] =
5208 ?
STI.getTailDupAggressiveThreshold()
5215 unsigned Opcode =
MI.getOpcode();
5216 if (!RISCVVPseudosTable::getPseudoInfo(Opcode) &&
5225 return MI.isCopy() &&
MI.getOperand(0).getReg().isPhysical() &&
5227 TRI->getMinimalPhysRegClass(
MI.getOperand(0).getReg()));
5230std::optional<std::pair<unsigned, unsigned>>
5234 return std::nullopt;
5235 case RISCV::PseudoVSPILL2_M1:
5236 case RISCV::PseudoVRELOAD2_M1:
5237 return std::make_pair(2u, 1u);
5238 case RISCV::PseudoVSPILL2_M2:
5239 case RISCV::PseudoVRELOAD2_M2:
5240 return std::make_pair(2u, 2u);
5241 case RISCV::PseudoVSPILL2_M4:
5242 case RISCV::PseudoVRELOAD2_M4:
5243 return std::make_pair(2u, 4u);
5244 case RISCV::PseudoVSPILL3_M1:
5245 case RISCV::PseudoVRELOAD3_M1:
5246 return std::make_pair(3u, 1u);
5247 case RISCV::PseudoVSPILL3_M2:
5248 case RISCV::PseudoVRELOAD3_M2:
5249 return std::make_pair(3u, 2u);
5250 case RISCV::PseudoVSPILL4_M1:
5251 case RISCV::PseudoVRELOAD4_M1:
5252 return std::make_pair(4u, 1u);
5253 case RISCV::PseudoVSPILL4_M2:
5254 case RISCV::PseudoVRELOAD4_M2:
5255 return std::make_pair(4u, 2u);
5256 case RISCV::PseudoVSPILL5_M1:
5257 case RISCV::PseudoVRELOAD5_M1:
5258 return std::make_pair(5u, 1u);
5259 case RISCV::PseudoVSPILL6_M1:
5260 case RISCV::PseudoVRELOAD6_M1:
5261 return std::make_pair(6u, 1u);
5262 case RISCV::PseudoVSPILL7_M1:
5263 case RISCV::PseudoVRELOAD7_M1:
5264 return std::make_pair(7u, 1u);
5265 case RISCV::PseudoVSPILL8_M1:
5266 case RISCV::PseudoVRELOAD8_M1:
5267 return std::make_pair(8u, 1u);
5272 int16_t MI1FrmOpIdx =
5273 RISCV::getNamedOperandIdx(MI1.
getOpcode(), RISCV::OpName::frm);
5274 int16_t MI2FrmOpIdx =
5275 RISCV::getNamedOperandIdx(MI2.
getOpcode(), RISCV::OpName::frm);
5276 if (MI1FrmOpIdx < 0 || MI2FrmOpIdx < 0)
5283std::optional<unsigned>
5287 return std::nullopt;
5290 case RISCV::VSLL_VX:
5291 case RISCV::VSRL_VX:
5292 case RISCV::VSRA_VX:
5294 case RISCV::VSSRL_VX:
5295 case RISCV::VSSRA_VX:
5297 case RISCV::VROL_VX:
5298 case RISCV::VROR_VX:
5303 case RISCV::VNSRL_WX:
5304 case RISCV::VNSRA_WX:
5306 case RISCV::VNCLIPU_WX:
5307 case RISCV::VNCLIP_WX:
5309 case RISCV::VWSLL_VX:
5314 case RISCV::VADD_VX:
5315 case RISCV::VSUB_VX:
5316 case RISCV::VRSUB_VX:
5318 case RISCV::VWADDU_VX:
5319 case RISCV::VWSUBU_VX:
5320 case RISCV::VWADD_VX:
5321 case RISCV::VWSUB_VX:
5322 case RISCV::VWADDU_WX:
5323 case RISCV::VWSUBU_WX:
5324 case RISCV::VWADD_WX:
5325 case RISCV::VWSUB_WX:
5327 case RISCV::VADC_VXM:
5328 case RISCV::VADC_VIM:
5329 case RISCV::VMADC_VXM:
5330 case RISCV::VMADC_VIM:
5331 case RISCV::VMADC_VX:
5332 case RISCV::VSBC_VXM:
5333 case RISCV::VMSBC_VXM:
5334 case RISCV::VMSBC_VX:
5336 case RISCV::VAND_VX:
5338 case RISCV::VXOR_VX:
5340 case RISCV::VMSEQ_VX:
5341 case RISCV::VMSNE_VX:
5342 case RISCV::VMSLTU_VX:
5343 case RISCV::VMSLT_VX:
5344 case RISCV::VMSLEU_VX:
5345 case RISCV::VMSLE_VX:
5346 case RISCV::VMSGTU_VX:
5347 case RISCV::VMSGT_VX:
5349 case RISCV::VMINU_VX:
5350 case RISCV::VMIN_VX:
5351 case RISCV::VMAXU_VX:
5352 case RISCV::VMAX_VX:
5354 case RISCV::VMUL_VX:
5355 case RISCV::VMULH_VX:
5356 case RISCV::VMULHU_VX:
5357 case RISCV::VMULHSU_VX:
5359 case RISCV::VDIVU_VX:
5360 case RISCV::VDIV_VX:
5361 case RISCV::VREMU_VX:
5362 case RISCV::VREM_VX:
5364 case RISCV::VWMUL_VX:
5365 case RISCV::VWMULU_VX:
5366 case RISCV::VWMULSU_VX:
5368 case RISCV::VMACC_VX:
5369 case RISCV::VNMSAC_VX:
5370 case RISCV::VMADD_VX:
5371 case RISCV::VNMSUB_VX:
5373 case RISCV::VWMACCU_VX:
5374 case RISCV::VWMACC_VX:
5375 case RISCV::VWMACCSU_VX:
5376 case RISCV::VWMACCUS_VX:
5378 case RISCV::VMERGE_VXM:
5380 case RISCV::VMV_V_X:
5382 case RISCV::VSADDU_VX:
5383 case RISCV::VSADD_VX:
5384 case RISCV::VSSUBU_VX:
5385 case RISCV::VSSUB_VX:
5387 case RISCV::VAADDU_VX:
5388 case RISCV::VAADD_VX:
5389 case RISCV::VASUBU_VX:
5390 case RISCV::VASUB_VX:
5392 case RISCV::VSMUL_VX:
5394 case RISCV::VMV_S_X:
5396 case RISCV::VANDN_VX:
5397 return 1U << Log2SEW;
5403 RISCVVPseudosTable::getPseudoInfo(RVVPseudoOpcode);
5406 return RVV->BaseInstr;
5416 unsigned Scaled = Log2SEW + (DestEEW - 1);
5430 return std::nullopt;
5437 if (LHS.isReg() && RHS.isReg() && LHS.getReg().isVirtual() &&
5438 LHS.getReg() == RHS.getReg())
5442 if (LHS.isImm() && LHS.getImm() == 0)
5448 if (!LHSImm || !RHSImm)
5450 return LHSImm <= RHSImm;
5462 : LHS(LHS), RHS(RHS),
Cond(
Cond.begin(),
Cond.end()) {}
5464 bool shouldIgnoreForPipelining(
const MachineInstr *
MI)
const override {
5474 std::optional<bool> createTripCountGreaterCondition(
5475 int TC, MachineBasicBlock &
MBB,
5476 SmallVectorImpl<MachineOperand> &CondParam)
override {
5484 void setPreheader(MachineBasicBlock *NewPreheader)
override {}
5486 void adjustTripCount(
int TripCountAdjust)
override {}
5490std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo>
5498 if (
TBB == LoopBB && FBB == LoopBB)
5505 assert((
TBB == LoopBB || FBB == LoopBB) &&
5506 "The Loop must be a single-basic-block loop");
5517 if (!Reg.isVirtual())
5524 if (LHS && LHS->isPHI())
5526 if (RHS && RHS->isPHI())
5529 return std::make_unique<RISCVPipelinerLoopInfo>(LHS, RHS,
Cond);
5535 Opc = RVVMCOpcode ? RVVMCOpcode :
Opc;
5552 case RISCV::FDIV_H_INX:
5553 case RISCV::FDIV_S_INX:
5554 case RISCV::FDIV_D_INX:
5555 case RISCV::FDIV_D_IN32X:
5556 case RISCV::FSQRT_H:
5557 case RISCV::FSQRT_S:
5558 case RISCV::FSQRT_D:
5559 case RISCV::FSQRT_H_INX:
5560 case RISCV::FSQRT_S_INX:
5561 case RISCV::FSQRT_D_INX:
5562 case RISCV::FSQRT_D_IN32X:
5564 case RISCV::VDIV_VV:
5565 case RISCV::VDIV_VX:
5566 case RISCV::VDIVU_VV:
5567 case RISCV::VDIVU_VX:
5568 case RISCV::VREM_VV:
5569 case RISCV::VREM_VX:
5570 case RISCV::VREMU_VV:
5571 case RISCV::VREMU_VX:
5573 case RISCV::VFDIV_VV:
5574 case RISCV::VFDIV_VF:
5575 case RISCV::VFRDIV_VF:
5576 case RISCV::VFSQRT_V:
5577 case RISCV::VFRSQRT7_V:
5583 if (
MI->getOpcode() != TargetOpcode::COPY)
5588 Register DstReg =
MI->getOperand(0).getReg();
5591 :
TRI->getMinimalPhysRegClass(DstReg);
5601 auto [RCLMul, RCFractional] =
5603 return (!RCFractional && LMul == RCLMul) || (RCFractional && LMul == 1);
5607 if (
MI.memoperands_empty())
5622 if (MO.getReg().isPhysical())
5625 if (MO.getReg().isPhysical())
5627 bool SawStore =
false;
5630 if (
II->definesRegister(PhysReg,
nullptr))
5633 if (
II->definesRegister(PhysReg,
nullptr) ||
5634 II->readsRegister(PhysReg,
nullptr))
5636 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!")
This file defines the StringMap class.
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...
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
This file declares the machine register scavenger class.
static bool memOpsHaveSameBasePtr(const MachineInstr &MI1, ArrayRef< const MachineOperand * > BaseOps1, const MachineInstr &MI2, ArrayRef< const MachineOperand * > BaseOps2)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static 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 TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
LLVM_ABI void clearKillFlags(Register Reg) const
clearKillFlags - Iterate over all the uses of the given register and clear the kill flag from the Mac...
LLVM_ABI LLVM_READONLY MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
bool isReserved(MCRegister PhysReg) const
isReserved - Returns true when PhysReg is a reserved register.
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
bool hasOneUse(Register RegNo) const
hasOneUse - Return true if there is exactly one instruction using the specified register.
LLVM_ABI void clearVirtRegs()
clearVirtRegs - Remove all virtual registers (after physreg assignment).
const TargetRegisterInfo * getTargetRegisterInfo() const
LLVM_ABI bool isConstantPhysReg(MCRegister PhysReg) const
Returns true if PhysReg is unallocatable and constant throughout the function.
LLVM_ABI const TargetRegisterClass * constrainRegClass(Register Reg, const TargetRegisterClass *RC, unsigned MinNumRegs=0)
constrainRegClass - Constrain the register class of the specified virtual register to be a common sub...
LLVM_ABI void replaceRegWith(Register FromReg, Register ToReg)
replaceRegWith - Replace all instances of FromReg with ToReg in the machine function.
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.