39#define GEN_CHECK_COMPRESS_INSTR
40#include "RISCVGenCompressInstEmitter.inc"
42#define GET_INSTRINFO_CTOR_DTOR
43#define GET_INSTRINFO_NAMED_OPS
44#include "RISCVGenInstrInfo.inc"
48 cl::desc(
"Prefer whole register move for vector registers."));
51 "riscv-force-machine-combiner-strategy",
cl::Hidden,
52 cl::desc(
"Force machine combiner to use a specific strategy for machine "
53 "trace metrics evaluation."),
54 cl::init(MachineTraceStrategy::TS_NumStrategies),
57 clEnumValN(MachineTraceStrategy::TS_MinInstrCount,
"min-instr",
58 "MinInstrCount strategy.")));
64#define GET_RISCVVPseudosTable_IMPL
65#include "RISCVGenSearchableTables.inc"
71#define GET_RISCVMaskedPseudosTable_IMPL
72#include "RISCVGenSearchableTables.inc"
90 int &FrameIndex)
const {
97 unsigned &MemBytes)
const {
98 switch (
MI.getOpcode()) {
121 if (
MI.getOperand(1).isFI() &&
MI.getOperand(2).isImm() &&
122 MI.getOperand(2).getImm() == 0) {
123 FrameIndex =
MI.getOperand(1).getIndex();
124 return MI.getOperand(0).getReg();
131 int &FrameIndex)
const {
138 unsigned &MemBytes)
const {
139 switch (
MI.getOpcode()) {
159 if (
MI.getOperand(1).isFI() &&
MI.getOperand(2).isImm() &&
160 MI.getOperand(2).getImm() == 0) {
161 FrameIndex =
MI.getOperand(1).getIndex();
162 return MI.getOperand(0).getReg();
170 return DstReg > SrcReg && (DstReg - SrcReg) < NumRegs;
181 assert(
MBBI->getOpcode() == TargetOpcode::COPY &&
182 "Unexpected COPY instruction.");
186 bool FoundDef =
false;
187 bool FirstVSetVLI =
false;
188 unsigned FirstSEW = 0;
191 if (
MBBI->isMetaInstruction())
194 if (
MBBI->getOpcode() == RISCV::PseudoVSETVLI ||
195 MBBI->getOpcode() == RISCV::PseudoVSETVLIX0 ||
196 MBBI->getOpcode() == RISCV::PseudoVSETIVLI) {
206 unsigned FirstVType =
MBBI->getOperand(2).getImm();
211 if (FirstLMul != LMul)
216 if (
MBBI->getOperand(0).getReg() != RISCV::X0)
218 if (
MBBI->getOperand(1).isImm())
220 if (
MBBI->getOperand(1).getReg() != RISCV::X0)
226 unsigned VType =
MBBI->getOperand(2).getImm();
244 }
else if (
MBBI->isInlineAsm() ||
MBBI->isCall()) {
246 }
else if (
MBBI->getNumDefs()) {
249 if (
MBBI->modifiesRegister(RISCV::VL,
nullptr))
255 if (!MO.isReg() || !MO.isDef())
257 if (!FoundDef &&
TRI->regsOverlap(MO.getReg(), SrcReg)) {
272 if (MO.getReg() != SrcReg)
313 uint16_t SrcEncoding =
TRI->getEncodingValue(SrcReg);
314 uint16_t DstEncoding =
TRI->getEncodingValue(DstReg);
316 assert(!Fractional &&
"It is impossible be fractional lmul here.");
317 unsigned NumRegs = NF * LMulVal;
323 SrcEncoding += NumRegs - 1;
324 DstEncoding += NumRegs - 1;
330 unsigned,
unsigned> {
338 uint16_t Diff = DstEncoding - SrcEncoding;
339 if (
I + 8 <= NumRegs && Diff >= 8 && SrcEncoding % 8 == 7 &&
340 DstEncoding % 8 == 7)
342 RISCV::PseudoVMV_V_V_M8, RISCV::PseudoVMV_V_I_M8};
343 if (
I + 4 <= NumRegs && Diff >= 4 && SrcEncoding % 4 == 3 &&
344 DstEncoding % 4 == 3)
346 RISCV::PseudoVMV_V_V_M4, RISCV::PseudoVMV_V_I_M4};
347 if (
I + 2 <= NumRegs && Diff >= 2 && SrcEncoding % 2 == 1 &&
348 DstEncoding % 2 == 1)
350 RISCV::PseudoVMV_V_V_M2, RISCV::PseudoVMV_V_I_M2};
353 RISCV::PseudoVMV_V_V_M1, RISCV::PseudoVMV_V_I_M1};
358 if (
I + 8 <= NumRegs && SrcEncoding % 8 == 0 && DstEncoding % 8 == 0)
360 RISCV::PseudoVMV_V_V_M8, RISCV::PseudoVMV_V_I_M8};
361 if (
I + 4 <= NumRegs && SrcEncoding % 4 == 0 && DstEncoding % 4 == 0)
363 RISCV::PseudoVMV_V_V_M4, RISCV::PseudoVMV_V_I_M4};
364 if (
I + 2 <= NumRegs && SrcEncoding % 2 == 0 && DstEncoding % 2 == 0)
366 RISCV::PseudoVMV_V_V_M2, RISCV::PseudoVMV_V_I_M2};
369 RISCV::PseudoVMV_V_V_M1, RISCV::PseudoVMV_V_I_M1};
374 if (&RegClass == &RISCV::VRRegClass)
376 return TRI->getMatchingSuperReg(Reg, RISCV::sub_vrm1_0, &RegClass);
378 while (
I != NumRegs) {
383 auto [LMulCopied, RegClass, Opc, VVOpc, VIOpc] =
384 GetCopyInfo(SrcEncoding, DstEncoding);
388 if (LMul == LMulCopied &&
391 if (DefMBBI->getOpcode() == VIOpc)
397 MCRegister ActualSrcReg = FindRegWithEncoding(
398 RegClass, ReversedCopy ? (SrcEncoding - NumCopied + 1) : SrcEncoding);
399 MCRegister ActualDstReg = FindRegWithEncoding(
400 RegClass, ReversedCopy ? (DstEncoding - NumCopied + 1) : DstEncoding);
408 MIB = MIB.add(DefMBBI->getOperand(2));
421 SrcEncoding += (ReversedCopy ? -NumCopied : NumCopied);
422 DstEncoding += (ReversedCopy ? -NumCopied : NumCopied);
433 if (RISCV::GPRRegClass.
contains(DstReg, SrcReg)) {
440 if (RISCV::GPRPairRegClass.
contains(DstReg, SrcReg)) {
443 TRI->getSubReg(DstReg, RISCV::sub_gpr_even))
444 .
addReg(
TRI->getSubReg(SrcReg, RISCV::sub_gpr_even),
448 TRI->getSubReg(DstReg, RISCV::sub_gpr_odd))
449 .
addReg(
TRI->getSubReg(SrcReg, RISCV::sub_gpr_odd),
456 if (RISCV::VCSRRegClass.
contains(SrcReg) &&
457 RISCV::GPRRegClass.
contains(DstReg)) {
459 .
addImm(RISCVSysReg::lookupSysRegByName(
TRI->getName(SrcReg))->Encoding)
464 if (RISCV::FPR16RegClass.
contains(DstReg, SrcReg)) {
466 if (
STI.hasStdExtZfh()) {
467 Opc = RISCV::FSGNJ_H;
470 (
STI.hasStdExtZfhmin() ||
STI.hasStdExtZfbfmin()) &&
471 "Unexpected extensions");
473 DstReg =
TRI->getMatchingSuperReg(DstReg, RISCV::sub_16,
474 &RISCV::FPR32RegClass);
475 SrcReg =
TRI->getMatchingSuperReg(SrcReg, RISCV::sub_16,
476 &RISCV::FPR32RegClass);
477 Opc = RISCV::FSGNJ_S;
485 if (RISCV::FPR32RegClass.
contains(DstReg, SrcReg)) {
492 if (RISCV::FPR64RegClass.
contains(DstReg, SrcReg)) {
499 if (RISCV::FPR32RegClass.
contains(DstReg) &&
500 RISCV::GPRRegClass.
contains(SrcReg)) {
506 if (RISCV::GPRRegClass.
contains(DstReg) &&
507 RISCV::FPR32RegClass.
contains(SrcReg)) {
513 if (RISCV::FPR64RegClass.
contains(DstReg) &&
514 RISCV::GPRRegClass.
contains(SrcReg)) {
521 if (RISCV::GPRRegClass.
contains(DstReg) &&
522 RISCV::FPR64RegClass.
contains(SrcReg)) {
531 &RISCV::VRRegClass, &RISCV::VRM2RegClass, &RISCV::VRM4RegClass,
532 &RISCV::VRM8RegClass, &RISCV::VRN2M1RegClass, &RISCV::VRN2M2RegClass,
533 &RISCV::VRN2M4RegClass, &RISCV::VRN3M1RegClass, &RISCV::VRN3M2RegClass,
534 &RISCV::VRN4M1RegClass, &RISCV::VRN4M2RegClass, &RISCV::VRN5M1RegClass,
535 &RISCV::VRN6M1RegClass, &RISCV::VRN7M1RegClass, &RISCV::VRN8M1RegClass};
536 for (
const auto &RegClass : RVVRegClasses) {
537 if (RegClass->contains(DstReg, SrcReg)) {
548 Register SrcReg,
bool IsKill,
int FI,
556 bool IsScalableVector =
true;
557 if (RISCV::GPRRegClass.hasSubClassEq(RC)) {
558 Opcode =
TRI->getRegSizeInBits(RISCV::GPRRegClass) == 32 ?
559 RISCV::SW : RISCV::SD;
560 IsScalableVector =
false;
561 }
else if (RISCV::GPRPairRegClass.hasSubClassEq(RC)) {
562 Opcode = RISCV::PseudoRV32ZdinxSD;
563 IsScalableVector =
false;
564 }
else if (RISCV::FPR16RegClass.hasSubClassEq(RC)) {
566 IsScalableVector =
false;
567 }
else if (RISCV::FPR32RegClass.hasSubClassEq(RC)) {
569 IsScalableVector =
false;
570 }
else if (RISCV::FPR64RegClass.hasSubClassEq(RC)) {
572 IsScalableVector =
false;
573 }
else if (RISCV::VRRegClass.hasSubClassEq(RC)) {
574 Opcode = RISCV::VS1R_V;
575 }
else if (RISCV::VRM2RegClass.hasSubClassEq(RC)) {
576 Opcode = RISCV::VS2R_V;
577 }
else if (RISCV::VRM4RegClass.hasSubClassEq(RC)) {
578 Opcode = RISCV::VS4R_V;
579 }
else if (RISCV::VRM8RegClass.hasSubClassEq(RC)) {
580 Opcode = RISCV::VS8R_V;
581 }
else if (RISCV::VRN2M1RegClass.hasSubClassEq(RC))
582 Opcode = RISCV::PseudoVSPILL2_M1;
583 else if (RISCV::VRN2M2RegClass.hasSubClassEq(RC))
584 Opcode = RISCV::PseudoVSPILL2_M2;
585 else if (RISCV::VRN2M4RegClass.hasSubClassEq(RC))
586 Opcode = RISCV::PseudoVSPILL2_M4;
587 else if (RISCV::VRN3M1RegClass.hasSubClassEq(RC))
588 Opcode = RISCV::PseudoVSPILL3_M1;
589 else if (RISCV::VRN3M2RegClass.hasSubClassEq(RC))
590 Opcode = RISCV::PseudoVSPILL3_M2;
591 else if (RISCV::VRN4M1RegClass.hasSubClassEq(RC))
592 Opcode = RISCV::PseudoVSPILL4_M1;
593 else if (RISCV::VRN4M2RegClass.hasSubClassEq(RC))
594 Opcode = RISCV::PseudoVSPILL4_M2;
595 else if (RISCV::VRN5M1RegClass.hasSubClassEq(RC))
596 Opcode = RISCV::PseudoVSPILL5_M1;
597 else if (RISCV::VRN6M1RegClass.hasSubClassEq(RC))
598 Opcode = RISCV::PseudoVSPILL6_M1;
599 else if (RISCV::VRN7M1RegClass.hasSubClassEq(RC))
600 Opcode = RISCV::PseudoVSPILL7_M1;
601 else if (RISCV::VRN8M1RegClass.hasSubClassEq(RC))
602 Opcode = RISCV::PseudoVSPILL8_M1;
606 if (IsScalableVector) {
639 bool IsScalableVector =
true;
640 if (RISCV::GPRRegClass.hasSubClassEq(RC)) {
641 Opcode =
TRI->getRegSizeInBits(RISCV::GPRRegClass) == 32 ?
642 RISCV::LW : RISCV::LD;
643 IsScalableVector =
false;
644 }
else if (RISCV::GPRPairRegClass.hasSubClassEq(RC)) {
645 Opcode = RISCV::PseudoRV32ZdinxLD;
646 IsScalableVector =
false;
647 }
else if (RISCV::FPR16RegClass.hasSubClassEq(RC)) {
649 IsScalableVector =
false;
650 }
else if (RISCV::FPR32RegClass.hasSubClassEq(RC)) {
652 IsScalableVector =
false;
653 }
else if (RISCV::FPR64RegClass.hasSubClassEq(RC)) {
655 IsScalableVector =
false;
656 }
else if (RISCV::VRRegClass.hasSubClassEq(RC)) {
657 Opcode = RISCV::VL1RE8_V;
658 }
else if (RISCV::VRM2RegClass.hasSubClassEq(RC)) {
659 Opcode = RISCV::VL2RE8_V;
660 }
else if (RISCV::VRM4RegClass.hasSubClassEq(RC)) {
661 Opcode = RISCV::VL4RE8_V;
662 }
else if (RISCV::VRM8RegClass.hasSubClassEq(RC)) {
663 Opcode = RISCV::VL8RE8_V;
664 }
else if (RISCV::VRN2M1RegClass.hasSubClassEq(RC))
665 Opcode = RISCV::PseudoVRELOAD2_M1;
666 else if (RISCV::VRN2M2RegClass.hasSubClassEq(RC))
667 Opcode = RISCV::PseudoVRELOAD2_M2;
668 else if (RISCV::VRN2M4RegClass.hasSubClassEq(RC))
669 Opcode = RISCV::PseudoVRELOAD2_M4;
670 else if (RISCV::VRN3M1RegClass.hasSubClassEq(RC))
671 Opcode = RISCV::PseudoVRELOAD3_M1;
672 else if (RISCV::VRN3M2RegClass.hasSubClassEq(RC))
673 Opcode = RISCV::PseudoVRELOAD3_M2;
674 else if (RISCV::VRN4M1RegClass.hasSubClassEq(RC))
675 Opcode = RISCV::PseudoVRELOAD4_M1;
676 else if (RISCV::VRN4M2RegClass.hasSubClassEq(RC))
677 Opcode = RISCV::PseudoVRELOAD4_M2;
678 else if (RISCV::VRN5M1RegClass.hasSubClassEq(RC))
679 Opcode = RISCV::PseudoVRELOAD5_M1;
680 else if (RISCV::VRN6M1RegClass.hasSubClassEq(RC))
681 Opcode = RISCV::PseudoVRELOAD6_M1;
682 else if (RISCV::VRN7M1RegClass.hasSubClassEq(RC))
683 Opcode = RISCV::PseudoVRELOAD7_M1;
684 else if (RISCV::VRN8M1RegClass.hasSubClassEq(RC))
685 Opcode = RISCV::PseudoVRELOAD8_M1;
689 if (IsScalableVector) {
723 if (Ops.
size() != 1 || Ops[0] != 1)
727 switch (
MI.getOpcode()) {
734 LoadOpc = RISCV::LWU;
738 LoadOpc = RISCV::LBU;
748 case RISCV::ZEXT_H_RV32:
749 case RISCV::ZEXT_H_RV64:
750 LoadOpc = RISCV::LHU;
760 return BuildMI(*
MI.getParent(), InsertPt,
MI.getDebugLoc(),
get(LoadOpc),
771 bool DstIsDead)
const {
777 if (!isUInt<32>(Val))
781 Val = SignExtend64<32>(Val);
787 bool SrcRenamable =
false;
791 bool LastItem = ++Num == Seq.
size();
796 switch (Inst.getOpndKind()) {
806 .
addReg(SrcReg, SrcRegState)
813 .
addReg(SrcReg, SrcRegState)
814 .
addReg(SrcReg, SrcRegState)
820 .
addReg(SrcReg, SrcRegState)
828 SrcRenamable = DstRenamable;
858 "Unknown conditional branch");
912 bool AllowModify)
const {
918 if (
I ==
MBB.
end() || !isUnpredicatedTerminator(*
I))
924 int NumTerminators = 0;
925 for (
auto J =
I.getReverse(); J !=
MBB.
rend() && isUnpredicatedTerminator(*J);
928 if (J->getDesc().isUnconditionalBranch() ||
929 J->getDesc().isIndirectBranch()) {
936 if (AllowModify && FirstUncondOrIndirectBr !=
MBB.
end()) {
937 while (std::next(FirstUncondOrIndirectBr) !=
MBB.
end()) {
938 std::next(FirstUncondOrIndirectBr)->eraseFromParent();
941 I = FirstUncondOrIndirectBr;
945 if (
I->getDesc().isIndirectBranch())
949 if (
I->isPreISelOpcode())
953 if (NumTerminators > 2)
957 if (NumTerminators == 1 &&
I->getDesc().isUnconditionalBranch()) {
963 if (NumTerminators == 1 &&
I->getDesc().isConditionalBranch()) {
969 if (NumTerminators == 2 && std::prev(
I)->getDesc().isConditionalBranch() &&
970 I->getDesc().isUnconditionalBranch()) {
981 int *BytesRemoved)
const {
988 if (!
I->getDesc().isUnconditionalBranch() &&
989 !
I->getDesc().isConditionalBranch())
995 I->eraseFromParent();
1002 if (!
I->getDesc().isConditionalBranch())
1008 I->eraseFromParent();
1021 assert(
TBB &&
"insertBranch must not be told to insert a fallthrough");
1023 "RISC-V branch conditions have two components!");
1056 assert(RS &&
"RegScavenger required for long branching");
1058 "new block should be inserted for expanding unconditional branch");
1061 "restore block should be inserted for restoring clobbered registers");
1068 if (!isInt<32>(BrOffset))
1070 "Branch offsets outside of the signed 32-bit range not supported");
1075 Register ScratchReg =
MRI.createVirtualRegister(&RISCV::GPRJALRRegClass);
1087 if (TmpGPR != RISCV::NoRegister)
1093 TmpGPR = RISCV::X27;
1096 if (FrameIndex == -1)
1101 TRI->eliminateFrameIndex(std::prev(
MI.getIterator()),
1104 MI.getOperand(1).setMBB(&RestoreBB);
1108 TRI->eliminateFrameIndex(RestoreBB.
back(),
1112 MRI.replaceRegWith(ScratchReg, TmpGPR);
1113 MRI.clearVirtRegs();
1118 assert((
Cond.size() == 3) &&
"Invalid branch condition!");
1158 auto isLoadImm = [](
const MachineInstr *
MI, int64_t &Imm) ->
bool {
1159 if (
MI->getOpcode() == RISCV::ADDI &&
MI->getOperand(1).isReg() &&
1160 MI->getOperand(1).getReg() == RISCV::X0) {
1161 Imm =
MI->getOperand(2).getImm();
1171 return Reg.isVirtual() && isLoadImm(
MRI.getVRegDef(Reg), Imm);
1178 auto searchConst = [&](int64_t C1) ->
Register {
1180 auto DefC1 = std::find_if(++II, E, [&](
const MachineInstr &
I) ->
bool {
1182 return isLoadImm(&
I, Imm) && Imm == C1 &&
1183 I.getOperand(0).getReg().isVirtual();
1186 return DefC1->getOperand(0).getReg();
1191 bool Modify =
false;
1193 if (isFromLoadImm(
LHS, C0) &&
MRI.hasOneUse(
LHS.getReg())) {
1198 if (
Register RegZ = searchConst(C0 + 1)) {
1204 MRI.clearKillFlags(RegZ);
1207 }
else if (isFromLoadImm(
RHS, C0) &&
MRI.hasOneUse(
RHS.getReg())) {
1212 if (
Register RegZ = searchConst(C0 - 1)) {
1218 MRI.clearKillFlags(RegZ);
1232 MI.eraseFromParent();
1239 assert(
MI.getDesc().isBranch() &&
"Unexpected opcode!");
1241 int NumOp =
MI.getNumExplicitOperands();
1242 return MI.getOperand(NumOp - 1).getMBB();
1246 int64_t BrOffset)
const {
1260 return isIntN(13, BrOffset);
1262 case RISCV::PseudoBR:
1263 return isIntN(21, BrOffset);
1264 case RISCV::PseudoJump:
1274 case RISCV::ADD:
return RISCV::PseudoCCADD;
break;
1275 case RISCV::SUB:
return RISCV::PseudoCCSUB;
break;
1276 case RISCV::SLL:
return RISCV::PseudoCCSLL;
break;
1277 case RISCV::SRL:
return RISCV::PseudoCCSRL;
break;
1278 case RISCV::SRA:
return RISCV::PseudoCCSRA;
break;
1279 case RISCV::AND:
return RISCV::PseudoCCAND;
break;
1280 case RISCV::OR:
return RISCV::PseudoCCOR;
break;
1281 case RISCV::XOR:
return RISCV::PseudoCCXOR;
break;
1283 case RISCV::ADDI:
return RISCV::PseudoCCADDI;
break;
1284 case RISCV::SLLI:
return RISCV::PseudoCCSLLI;
break;
1285 case RISCV::SRLI:
return RISCV::PseudoCCSRLI;
break;
1286 case RISCV::SRAI:
return RISCV::PseudoCCSRAI;
break;
1287 case RISCV::ANDI:
return RISCV::PseudoCCANDI;
break;
1288 case RISCV::ORI:
return RISCV::PseudoCCORI;
break;
1289 case RISCV::XORI:
return RISCV::PseudoCCXORI;
break;
1291 case RISCV::ADDW:
return RISCV::PseudoCCADDW;
break;
1292 case RISCV::SUBW:
return RISCV::PseudoCCSUBW;
break;
1293 case RISCV::SLLW:
return RISCV::PseudoCCSLLW;
break;
1294 case RISCV::SRLW:
return RISCV::PseudoCCSRLW;
break;
1295 case RISCV::SRAW:
return RISCV::PseudoCCSRAW;
break;
1297 case RISCV::ADDIW:
return RISCV::PseudoCCADDIW;
break;
1298 case RISCV::SLLIW:
return RISCV::PseudoCCSLLIW;
break;
1299 case RISCV::SRLIW:
return RISCV::PseudoCCSRLIW;
break;
1300 case RISCV::SRAIW:
return RISCV::PseudoCCSRAIW;
break;
1302 case RISCV::ANDN:
return RISCV::PseudoCCANDN;
break;
1303 case RISCV::ORN:
return RISCV::PseudoCCORN;
break;
1304 case RISCV::XNOR:
return RISCV::PseudoCCXNOR;
break;
1307 return RISCV::INSTRUCTION_LIST_END;
1315 if (!Reg.isVirtual())
1317 if (!
MRI.hasOneNonDBGUse(Reg))
1326 if (
MI->getOpcode() == RISCV::ADDI &&
MI->getOperand(1).isReg() &&
1327 MI->getOperand(1).getReg() == RISCV::X0)
1332 if (MO.isFI() || MO.isCPI() || MO.isJTI())
1342 if (MO.getReg().isPhysical() && !
MRI.isConstantPhysReg(MO.getReg()))
1345 bool DontMoveAcrossStores =
true;
1346 if (!
MI->isSafeToMove(
nullptr, DontMoveAcrossStores))
1353 unsigned &TrueOp,
unsigned &FalseOp,
1354 bool &Optimizable)
const {
1355 assert(
MI.getOpcode() == RISCV::PseudoCCMOVGPR &&
1356 "Unknown select instruction");
1366 Cond.push_back(
MI.getOperand(1));
1367 Cond.push_back(
MI.getOperand(2));
1368 Cond.push_back(
MI.getOperand(3));
1370 Optimizable =
STI.hasShortForwardBranchOpt();
1377 bool PreferFalse)
const {
1378 assert(
MI.getOpcode() == RISCV::PseudoCCMOVGPR &&
1379 "Unknown select instruction");
1380 if (!
STI.hasShortForwardBranchOpt())
1386 bool Invert = !
DefMI;
1394 Register DestReg =
MI.getOperand(0).getReg();
1396 if (!
MRI.constrainRegClass(DestReg, PreviousClass))
1400 assert(PredOpc != RISCV::INSTRUCTION_LIST_END &&
"Unexpected opcode!");
1407 NewMI.
add(
MI.getOperand(1));
1408 NewMI.
add(
MI.getOperand(2));
1417 NewMI.
add(FalseReg);
1441 if (
MI.isMetaInstruction())
1444 unsigned Opcode =
MI.getOpcode();
1446 if (Opcode == TargetOpcode::INLINEASM ||
1447 Opcode == TargetOpcode::INLINEASM_BR) {
1450 return getInlineAsmLength(
MI.getOperand(0).getSymbolName(),
1451 *
TM.getMCAsmInfo());
1454 if (!
MI.memoperands_empty()) {
1459 if (ST.hasStdExtCOrZca() && ST.enableRVCHintInstrs()) {
1460 if (isCompressibleInst(
MI,
STI))
1468 if (Opcode == TargetOpcode::BUNDLE)
1469 return getInstBundleLength(
MI);
1471 if (
MI.getParent() &&
MI.getParent()->getParent()) {
1472 if (isCompressibleInst(
MI,
STI))
1477 case TargetOpcode::STACKMAP:
1480 case TargetOpcode::PATCHPOINT:
1483 case TargetOpcode::STATEPOINT: {
1487 return std::max(NumBytes, 8U);
1490 return get(Opcode).getSize();
1494unsigned RISCVInstrInfo::getInstBundleLength(
const MachineInstr &
MI)
const {
1498 while (++
I != E &&
I->isInsideBundle()) {
1499 assert(!
I->isBundle() &&
"No nested bundle!");
1506 const unsigned Opcode =
MI.getOpcode();
1510 case RISCV::FSGNJ_D:
1511 case RISCV::FSGNJ_S:
1512 case RISCV::FSGNJ_H:
1513 case RISCV::FSGNJ_D_INX:
1514 case RISCV::FSGNJ_D_IN32X:
1515 case RISCV::FSGNJ_S_INX:
1516 case RISCV::FSGNJ_H_INX:
1518 return MI.getOperand(1).isReg() &&
MI.getOperand(2).isReg() &&
1519 MI.getOperand(1).getReg() ==
MI.getOperand(2).getReg();
1523 return (
MI.getOperand(1).isReg() &&
1524 MI.getOperand(1).getReg() == RISCV::X0) ||
1525 (
MI.getOperand(2).isImm() &&
MI.getOperand(2).getImm() == 0);
1527 return MI.isAsCheapAsAMove();
1530std::optional<DestSourcePair>
1534 switch (
MI.getOpcode()) {
1539 if (
MI.getOperand(1).isReg() &&
MI.getOperand(2).isImm() &&
1540 MI.getOperand(2).getImm() == 0)
1543 case RISCV::FSGNJ_D:
1544 case RISCV::FSGNJ_S:
1545 case RISCV::FSGNJ_H:
1546 case RISCV::FSGNJ_D_INX:
1547 case RISCV::FSGNJ_D_IN32X:
1548 case RISCV::FSGNJ_S_INX:
1549 case RISCV::FSGNJ_H_INX:
1551 if (
MI.getOperand(1).isReg() &&
MI.getOperand(2).isReg() &&
1552 MI.getOperand(1).getReg() ==
MI.getOperand(2).getReg())
1556 return std::nullopt;
1564 const auto &SchedModel =
STI.getSchedModel();
1565 return (!SchedModel.hasInstrSchedModel() || SchedModel.isOutOfOrder())
1582 RISCV::OpName::frm) < 0;
1584 "New instructions require FRM whereas the old one does not have it");
1591 for (
auto *NewMI : InsInstrs) {
1594 NewMI->getOpcode(), RISCV::OpName::frm)) != NewMI->getNumOperands())
1637 bool &Commuted)
const {
1642 unsigned OperandIdx = Commuted ? 2 : 1;
1646 int16_t InstFrmOpIdx =
1648 int16_t SiblingFrmOpIdx =
1651 return (InstFrmOpIdx < 0 && SiblingFrmOpIdx < 0) ||
1656 bool Invert)
const {
1662 Opc = *InverseOpcode;
1707std::optional<unsigned>
1711 return std::nullopt;
1713 return RISCV::FSUB_H;
1715 return RISCV::FSUB_S;
1717 return RISCV::FSUB_D;
1719 return RISCV::FADD_H;
1721 return RISCV::FADD_S;
1723 return RISCV::FADD_D;
1737 bool DoRegPressureReduce) {
1753 if (DoRegPressureReduce && !
MRI.hasOneNonDBGUse(
MI->getOperand(0).getReg()))
1764 bool DoRegPressureReduce) {
1766 bool IsFAdd =
isFADD(Opc);
1767 if (!IsFAdd && !
isFSUB(Opc))
1771 DoRegPressureReduce)) {
1777 DoRegPressureReduce)) {
1787 bool DoRegPressureReduce) {
1795 unsigned CombineOpc) {
1802 if (!
MI ||
MI->getParent() != &
MBB ||
MI->getOpcode() != CombineOpc)
1805 if (!
MRI.hasOneNonDBGUse(
MI->getOperand(0).getReg()))
1816 unsigned OuterShiftAmt) {
1822 if (InnerShiftAmt < OuterShiftAmt || (InnerShiftAmt - OuterShiftAmt) > 3)
1884 bool DoRegPressureReduce)
const {
1893 DoRegPressureReduce);
1901 return RISCV::FMADD_H;
1903 return RISCV::FMADD_S;
1905 return RISCV::FMADD_D;
1950 bool Mul1IsKill = Mul1.
isKill();
1951 bool Mul2IsKill = Mul2.
isKill();
1952 bool AddendIsKill = Addend.
isKill();
1961 BuildMI(*MF, MergedLoc,
TII->get(FusedOpc), DstReg)
1986 assert(OuterShiftAmt != 0 &&
"Unexpected opcode");
1993 assert(InnerShiftAmt >= OuterShiftAmt &&
"Unexpected shift amount");
1996 switch (InnerShiftAmt - OuterShiftAmt) {
2000 InnerOpc = RISCV::ADD;
2003 InnerOpc = RISCV::SH1ADD;
2006 InnerOpc = RISCV::SH2ADD;
2009 InnerOpc = RISCV::SH3ADD;
2017 Register NewVR =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
2027 InstrIdxForVirtReg.
insert(std::make_pair(NewVR, 0));
2044 DelInstrs, InstrIdxForVirtReg);
2072 unsigned OpType = Operand.OperandType;
2077 int64_t Imm = MO.
getImm();
2084#define CASE_OPERAND_UIMM(NUM) \
2085 case RISCVOp::OPERAND_UIMM##NUM: \
2086 Ok = isUInt<NUM>(Imm); \
2100 Ok = isShiftedUInt<1, 1>(Imm);
2103 Ok = isShiftedUInt<5, 2>(Imm);
2106 Ok = isShiftedUInt<6, 2>(Imm);
2109 Ok = isShiftedUInt<5, 3>(Imm);
2112 Ok = isUInt<8>(Imm) && Imm >= 32;
2115 Ok = isShiftedUInt<6, 3>(Imm);
2118 Ok = isShiftedInt<6, 4>(Imm) && (Imm != 0);
2121 Ok = isShiftedUInt<8, 2>(Imm) && (Imm != 0);
2130 Ok = (isInt<5>(Imm) && Imm != -16) || Imm == 16;
2136 Ok = Imm != 0 && isInt<6>(Imm);
2139 Ok = isUInt<10>(Imm);
2142 Ok = isUInt<11>(Imm);
2145 Ok = isInt<12>(Imm);
2148 Ok = isShiftedInt<7, 5>(Imm);
2151 Ok =
STI.
is64Bit() ? isUInt<6>(Imm) : isUInt<5>(Imm);
2154 Ok =
STI.
is64Bit() ? isUInt<6>(Imm) : isUInt<5>(Imm);
2155 Ok = Ok && Imm != 0;
2158 Ok = (isUInt<5>(Imm) && Imm != 0) ||
2159 (Imm >= 0xfffe0 && Imm <= 0xfffff);
2162 Ok = Imm >= 0 && Imm <= 10;
2165 Ok = Imm >= 0 && Imm <= 7;
2168 Ok = Imm >= 1 && Imm <= 10;
2171 Ok = Imm >= 2 && Imm <= 14;
2174 Ok = (Imm & 0xf) == 0;
2178 ErrInfo =
"Invalid immediate";
2188 if (!
Op.isImm() && !
Op.isReg()) {
2189 ErrInfo =
"Invalid operand type for VL operand";
2192 if (
Op.isReg() &&
Op.getReg() != RISCV::NoRegister) {
2194 auto *RC =
MRI.getRegClass(
Op.getReg());
2195 if (!RISCV::GPRRegClass.hasSubClassEq(RC)) {
2196 ErrInfo =
"Invalid register class for VL operand";
2201 ErrInfo =
"VL operand w/o SEW operand?";
2207 if (!
MI.getOperand(OpIdx).isImm()) {
2208 ErrInfo =
"SEW value expected to be an immediate";
2211 uint64_t Log2SEW =
MI.getOperand(OpIdx).getImm();
2213 ErrInfo =
"Unexpected SEW value";
2216 unsigned SEW = Log2SEW ? 1 << Log2SEW : 8;
2218 ErrInfo =
"Unexpected SEW value";
2224 if (!
MI.getOperand(OpIdx).isImm()) {
2225 ErrInfo =
"Policy operand expected to be an immediate";
2228 uint64_t Policy =
MI.getOperand(OpIdx).getImm();
2230 ErrInfo =
"Invalid Policy Value";
2234 ErrInfo =
"policy operand w/o VL operand?";
2242 if (!
MI.isRegTiedToUseOperand(0, &UseOpIdx)) {
2243 ErrInfo =
"policy operand w/o tied operand?";
2286 int64_t NewOffset = OldOffset + Disp;
2288 NewOffset = SignExtend64<32>(NewOffset);
2290 if (!isInt<12>(NewOffset))
2308 "Addressing mode not supported for folding");
2350 OffsetIsScalable =
false;
2366 if (BaseOps1.
front()->isIdenticalTo(*BaseOps2.
front()))
2374 if (MO1->getAddrSpace() != MO2->getAddrSpace())
2377 auto Base1 = MO1->getValue();
2378 auto Base2 = MO2->getValue();
2379 if (!Base1 || !Base2)
2384 if (isa<UndefValue>(Base1) || isa<UndefValue>(Base2))
2387 return Base1 == Base2;
2393 int64_t Offset2,
bool OffsetIsScalable2,
unsigned ClusterSize,
2394 unsigned NumBytes)
const {
2397 if (!BaseOps1.
empty() && !BaseOps2.
empty()) {
2402 }
else if (!BaseOps1.
empty() || !BaseOps2.
empty()) {
2408 BaseOps1.
front()->getParent()->getMF()->getSubtarget().getCacheLineSize();
2414 return ClusterSize <= 4 && std::abs(Offset1 - Offset2) <
CacheLineSize;
2464 int64_t OffsetA = 0, OffsetB = 0;
2469 int LowOffset = std::min(OffsetA, OffsetB);
2470 int HighOffset = std::max(OffsetA, OffsetB);
2471 LocationSize LowWidth = (LowOffset == OffsetA) ? WidthA : WidthB;
2473 LowOffset + (int)LowWidth.
getValue() <= HighOffset)
2480std::pair<unsigned, unsigned>
2483 return std::make_pair(TF & Mask, TF & ~Mask);
2488 using namespace RISCVII;
2489 static const std::pair<unsigned, const char *> TargetFlags[] = {
2490 {MO_CALL,
"riscv-call"},
2491 {MO_LO,
"riscv-lo"},
2492 {MO_HI,
"riscv-hi"},
2493 {MO_PCREL_LO,
"riscv-pcrel-lo"},
2494 {MO_PCREL_HI,
"riscv-pcrel-hi"},
2495 {MO_GOT_HI,
"riscv-got-hi"},
2496 {MO_TPREL_LO,
"riscv-tprel-lo"},
2497 {MO_TPREL_HI,
"riscv-tprel-hi"},
2498 {MO_TPREL_ADD,
"riscv-tprel-add"},
2499 {MO_TLS_GOT_HI,
"riscv-tls-got-hi"},
2500 {MO_TLS_GD_HI,
"riscv-tls-gd-hi"},
2501 {MO_TLSDESC_HI,
"riscv-tlsdesc-hi"},
2502 {MO_TLSDESC_LOAD_LO,
"riscv-tlsdesc-load-lo"},
2503 {MO_TLSDESC_ADD_LO,
"riscv-tlsdesc-add-lo"},
2504 {MO_TLSDESC_CALL,
"riscv-tlsdesc-call"}};
2512 if (!OutlineFromLinkOnceODRs &&
F.hasLinkOnceODRLinkage())
2525 unsigned &Flags)
const {
2540std::optional<outliner::OutlinedFunction>
2542 std::vector<outliner::Candidate> &RepeatedSequenceLocs)
const {
2548 return !
C.isAvailableAcrossAndOutOfSeq(RISCV::X5, *
TRI);
2554 if (RepeatedSequenceLocs.size() < 2)
2555 return std::nullopt;
2557 unsigned SequenceSize = 0;
2559 for (
auto &
MI : RepeatedSequenceLocs[0])
2563 unsigned CallOverhead = 8;
2564 for (
auto &
C : RepeatedSequenceLocs)
2568 unsigned FrameOverhead = 4;
2569 if (RepeatedSequenceLocs[0]
2571 ->getSubtarget<RISCVSubtarget>()
2581 unsigned Flags)
const {
2586 const auto &
F =
MI.getMF()->getFunction();
2589 if (
MI.isCFIInstruction())
2603 if (
MI.modifiesRegister(RISCV::X5,
TRI) ||
2604 MI.getDesc().hasImplicitDefOfPhysReg(RISCV::X5))
2608 for (
const auto &MO :
MI.operands()) {
2613 (
MI.getMF()->getTarget().getFunctionSections() ||
F.hasComdat() ||
2626 bool Changed =
true;
2631 for (;
I != E; ++
I) {
2632 if (
I->isCFIInstruction()) {
2633 I->removeFromParent();
2656 .addGlobalAddress(M.getNamedValue(MF.
getName()), 0,
2667 return std::nullopt;
2671 if (
MI.getOpcode() == RISCV::ADDI &&
MI.getOperand(1).isReg() &&
2672 MI.getOperand(2).isImm())
2673 return RegImmPair{
MI.getOperand(1).getReg(),
MI.getOperand(2).getImm()};
2675 return std::nullopt;
2683 std::string GenericComment =
2685 if (!GenericComment.empty())
2686 return GenericComment;
2690 return std::string();
2692 std::string Comment;
2699 if ((
MI.getOpcode() == RISCV::VSETVLI ||
MI.getOpcode() == RISCV::VSETIVLI ||
2700 MI.getOpcode() == RISCV::PseudoVSETVLI ||
2701 MI.getOpcode() == RISCV::PseudoVSETIVLI ||
2702 MI.getOpcode() == RISCV::PseudoVSETVLIX0) &&
2704 unsigned Imm =
MI.getOperand(OpIdx).getImm();
2708 unsigned Log2SEW =
MI.getOperand(OpIdx).getImm();
2709 unsigned SEW = Log2SEW ? 1 << Log2SEW : 8;
2714 unsigned Policy =
MI.getOperand(OpIdx).getImm();
2716 "Invalid Policy Value");
2726#define CASE_RVV_OPCODE_UNMASK_LMUL(OP, LMUL) \
2727 RISCV::Pseudo##OP##_##LMUL
2729#define CASE_RVV_OPCODE_MASK_LMUL(OP, LMUL) \
2730 RISCV::Pseudo##OP##_##LMUL##_MASK
2732#define CASE_RVV_OPCODE_LMUL(OP, LMUL) \
2733 CASE_RVV_OPCODE_UNMASK_LMUL(OP, LMUL): \
2734 case CASE_RVV_OPCODE_MASK_LMUL(OP, LMUL)
2736#define CASE_RVV_OPCODE_UNMASK_WIDEN(OP) \
2737 CASE_RVV_OPCODE_UNMASK_LMUL(OP, MF8): \
2738 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, MF4): \
2739 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, MF2): \
2740 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, M1): \
2741 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, M2): \
2742 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, M4)
2744#define CASE_RVV_OPCODE_UNMASK(OP) \
2745 CASE_RVV_OPCODE_UNMASK_WIDEN(OP): \
2746 case CASE_RVV_OPCODE_UNMASK_LMUL(OP, M8)
2748#define CASE_RVV_OPCODE_MASK_WIDEN(OP) \
2749 CASE_RVV_OPCODE_MASK_LMUL(OP, MF8): \
2750 case CASE_RVV_OPCODE_MASK_LMUL(OP, MF4): \
2751 case CASE_RVV_OPCODE_MASK_LMUL(OP, MF2): \
2752 case CASE_RVV_OPCODE_MASK_LMUL(OP, M1): \
2753 case CASE_RVV_OPCODE_MASK_LMUL(OP, M2): \
2754 case CASE_RVV_OPCODE_MASK_LMUL(OP, M4)
2756#define CASE_RVV_OPCODE_MASK(OP) \
2757 CASE_RVV_OPCODE_MASK_WIDEN(OP): \
2758 case CASE_RVV_OPCODE_MASK_LMUL(OP, M8)
2760#define CASE_RVV_OPCODE_WIDEN(OP) \
2761 CASE_RVV_OPCODE_UNMASK_WIDEN(OP): \
2762 case CASE_RVV_OPCODE_MASK_WIDEN(OP)
2764#define CASE_RVV_OPCODE(OP) \
2765 CASE_RVV_OPCODE_UNMASK(OP): \
2766 case CASE_RVV_OPCODE_MASK(OP)
2770#define CASE_VMA_OPCODE_COMMON(OP, TYPE, LMUL) \
2771 RISCV::PseudoV##OP##_##TYPE##_##LMUL
2773#define CASE_VMA_OPCODE_LMULS_M1(OP, TYPE) \
2774 CASE_VMA_OPCODE_COMMON(OP, TYPE, M1): \
2775 case CASE_VMA_OPCODE_COMMON(OP, TYPE, M2): \
2776 case CASE_VMA_OPCODE_COMMON(OP, TYPE, M4): \
2777 case CASE_VMA_OPCODE_COMMON(OP, TYPE, M8)
2779#define CASE_VMA_OPCODE_LMULS_MF2(OP, TYPE) \
2780 CASE_VMA_OPCODE_COMMON(OP, TYPE, MF2): \
2781 case CASE_VMA_OPCODE_LMULS_M1(OP, TYPE)
2783#define CASE_VMA_OPCODE_LMULS_MF4(OP, TYPE) \
2784 CASE_VMA_OPCODE_COMMON(OP, TYPE, MF4): \
2785 case CASE_VMA_OPCODE_LMULS_MF2(OP, TYPE)
2787#define CASE_VMA_OPCODE_LMULS(OP, TYPE) \
2788 CASE_VMA_OPCODE_COMMON(OP, TYPE, MF8): \
2789 case CASE_VMA_OPCODE_LMULS_MF4(OP, TYPE)
2792#define CASE_VFMA_OPCODE_COMMON(OP, TYPE, LMUL, SEW) \
2793 RISCV::PseudoV##OP##_##TYPE##_##LMUL##_##SEW
2795#define CASE_VFMA_OPCODE_LMULS_M1(OP, TYPE, SEW) \
2796 CASE_VFMA_OPCODE_COMMON(OP, TYPE, M1, SEW): \
2797 case CASE_VFMA_OPCODE_COMMON(OP, TYPE, M2, SEW): \
2798 case CASE_VFMA_OPCODE_COMMON(OP, TYPE, M4, SEW): \
2799 case CASE_VFMA_OPCODE_COMMON(OP, TYPE, M8, SEW)
2801#define CASE_VFMA_OPCODE_LMULS_MF2(OP, TYPE, SEW) \
2802 CASE_VFMA_OPCODE_COMMON(OP, TYPE, MF2, SEW): \
2803 case CASE_VFMA_OPCODE_LMULS_M1(OP, TYPE, SEW)
2805#define CASE_VFMA_OPCODE_LMULS_MF4(OP, TYPE, SEW) \
2806 CASE_VFMA_OPCODE_COMMON(OP, TYPE, MF4, SEW): \
2807 case CASE_VFMA_OPCODE_LMULS_MF2(OP, TYPE, SEW)
2809#define CASE_VFMA_OPCODE_VV(OP) \
2810 CASE_VFMA_OPCODE_LMULS_MF4(OP, VV, E16): \
2811 case CASE_VFMA_OPCODE_LMULS_MF2(OP, VV, E32): \
2812 case CASE_VFMA_OPCODE_LMULS_M1(OP, VV, E64)
2814#define CASE_VFMA_SPLATS(OP) \
2815 CASE_VFMA_OPCODE_LMULS_MF4(OP, VFPR16, E16): \
2816 case CASE_VFMA_OPCODE_LMULS_MF2(OP, VFPR32, E32): \
2817 case CASE_VFMA_OPCODE_LMULS_M1(OP, VFPR64, E64)
2821 unsigned &SrcOpIdx1,
2822 unsigned &SrcOpIdx2)
const {
2824 if (!
Desc.isCommutable())
2827 switch (
MI.getOpcode()) {
2828 case RISCV::TH_MVEQZ:
2829 case RISCV::TH_MVNEZ:
2833 if (
MI.getOperand(2).getReg() == RISCV::X0)
2836 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 1, 2);
2837 case RISCV::TH_MULA:
2838 case RISCV::TH_MULAW:
2839 case RISCV::TH_MULAH:
2840 case RISCV::TH_MULS:
2841 case RISCV::TH_MULSW:
2842 case RISCV::TH_MULSH:
2844 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 2, 3);
2845 case RISCV::PseudoCCMOVGPRNoX0:
2846 case RISCV::PseudoCCMOVGPR:
2848 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 4, 5);
2870 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 2, 3);
2891 if ((
MI.getOperand(
MI.getNumExplicitOperands() - 1).getImm() & 1) == 0)
2896 unsigned CommutableOpIdx1 = 1;
2897 unsigned CommutableOpIdx2 = 3;
2898 if (!fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, CommutableOpIdx1,
2911 if ((
MI.getOperand(
MI.getNumExplicitOperands() - 1).getImm() & 1) == 0)
2918 if (SrcOpIdx1 != CommuteAnyOperandIndex && SrcOpIdx1 > 3)
2920 if (SrcOpIdx2 != CommuteAnyOperandIndex && SrcOpIdx2 > 3)
2924 if (SrcOpIdx1 != CommuteAnyOperandIndex &&
2925 SrcOpIdx2 != CommuteAnyOperandIndex && SrcOpIdx1 != 1 && SrcOpIdx2 != 1)
2931 if (SrcOpIdx1 == CommuteAnyOperandIndex ||
2932 SrcOpIdx2 == CommuteAnyOperandIndex) {
2935 unsigned CommutableOpIdx1 = SrcOpIdx1;
2936 if (SrcOpIdx1 == SrcOpIdx2) {
2939 CommutableOpIdx1 = 1;
2940 }
else if (SrcOpIdx1 == CommuteAnyOperandIndex) {
2942 CommutableOpIdx1 = SrcOpIdx2;
2947 unsigned CommutableOpIdx2;
2948 if (CommutableOpIdx1 != 1) {
2950 CommutableOpIdx2 = 1;
2952 Register Op1Reg =
MI.getOperand(CommutableOpIdx1).getReg();
2957 if (Op1Reg !=
MI.getOperand(2).getReg())
2958 CommutableOpIdx2 = 2;
2960 CommutableOpIdx2 = 3;
2965 if (!fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, CommutableOpIdx1,
2978#define CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, LMUL) \
2979 case RISCV::PseudoV##OLDOP##_##TYPE##_##LMUL: \
2980 Opc = RISCV::PseudoV##NEWOP##_##TYPE##_##LMUL; \
2983#define CASE_VMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, TYPE) \
2984 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M1) \
2985 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M2) \
2986 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M4) \
2987 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M8)
2989#define CASE_VMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, TYPE) \
2990 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF2) \
2991 CASE_VMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, TYPE)
2993#define CASE_VMA_CHANGE_OPCODE_LMULS_MF4(OLDOP, NEWOP, TYPE) \
2994 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF4) \
2995 CASE_VMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, TYPE)
2997#define CASE_VMA_CHANGE_OPCODE_LMULS(OLDOP, NEWOP, TYPE) \
2998 CASE_VMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF8) \
2999 CASE_VMA_CHANGE_OPCODE_LMULS_MF4(OLDOP, NEWOP, TYPE)
3001#define CASE_VMA_CHANGE_OPCODE_SPLATS(OLDOP, NEWOP) \
3002 CASE_VMA_CHANGE_OPCODE_LMULS_MF4(OLDOP, NEWOP, VFPR16) \
3003 CASE_VMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, VFPR32) \
3004 CASE_VMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, VFPR64)
3007#define CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, LMUL, SEW) \
3008 case RISCV::PseudoV##OLDOP##_##TYPE##_##LMUL##_##SEW: \
3009 Opc = RISCV::PseudoV##NEWOP##_##TYPE##_##LMUL##_##SEW; \
3012#define CASE_VFMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, TYPE, SEW) \
3013 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M1, SEW) \
3014 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M2, SEW) \
3015 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M4, SEW) \
3016 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, M8, SEW)
3018#define CASE_VFMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, TYPE, SEW) \
3019 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF2, SEW) \
3020 CASE_VFMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, TYPE, SEW)
3022#define CASE_VFMA_CHANGE_OPCODE_VV(OLDOP, NEWOP) \
3023 CASE_VFMA_CHANGE_OPCODE_LMULS_MF4(OLDOP, NEWOP, VV, E16) \
3024 CASE_VFMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, VV, E32) \
3025 CASE_VFMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, VV, E64)
3027#define CASE_VFMA_CHANGE_OPCODE_LMULS_MF4(OLDOP, NEWOP, TYPE, SEW) \
3028 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF4, SEW) \
3029 CASE_VFMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, TYPE, SEW)
3031#define CASE_VFMA_CHANGE_OPCODE_LMULS(OLDOP, NEWOP, TYPE, SEW) \
3032 CASE_VFMA_CHANGE_OPCODE_COMMON(OLDOP, NEWOP, TYPE, MF8, SEW) \
3033 CASE_VFMA_CHANGE_OPCODE_LMULS_MF4(OLDOP, NEWOP, TYPE, SEW)
3035#define CASE_VFMA_CHANGE_OPCODE_SPLATS(OLDOP, NEWOP) \
3036 CASE_VFMA_CHANGE_OPCODE_LMULS_MF4(OLDOP, NEWOP, VFPR16, E16) \
3037 CASE_VFMA_CHANGE_OPCODE_LMULS_MF2(OLDOP, NEWOP, VFPR32, E32) \
3038 CASE_VFMA_CHANGE_OPCODE_LMULS_M1(OLDOP, NEWOP, VFPR64, E64)
3043 unsigned OpIdx2)
const {
3046 return *
MI.getParent()->getParent()->CloneMachineInstr(&
MI);
3050 switch (
MI.getOpcode()) {
3051 case RISCV::TH_MVEQZ:
3052 case RISCV::TH_MVNEZ: {
3053 auto &WorkingMI = cloneIfNew(
MI);
3054 WorkingMI.setDesc(
get(
MI.getOpcode() == RISCV::TH_MVEQZ ? RISCV::TH_MVNEZ
3055 : RISCV::TH_MVEQZ));
3059 case RISCV::PseudoCCMOVGPRNoX0:
3060 case RISCV::PseudoCCMOVGPR: {
3064 auto &WorkingMI = cloneIfNew(
MI);
3065 WorkingMI.getOperand(3).setImm(
CC);
3089 assert((OpIdx1 == 1 || OpIdx2 == 1) &&
"Unexpected opcode index");
3090 assert((OpIdx1 == 3 || OpIdx2 == 3) &&
"Unexpected opcode index");
3092 switch (
MI.getOpcode()) {
3115 auto &WorkingMI = cloneIfNew(
MI);
3116 WorkingMI.setDesc(
get(Opc));
3126 assert((OpIdx1 == 1 || OpIdx2 == 1) &&
"Unexpected opcode index");
3129 if (OpIdx1 == 3 || OpIdx2 == 3) {
3131 switch (
MI.getOpcode()) {
3142 auto &WorkingMI = cloneIfNew(
MI);
3143 WorkingMI.setDesc(
get(Opc));
3155#undef CASE_VMA_OPCODE_COMMON
3156#undef CASE_VMA_OPCODE_LMULS_M1
3157#undef CASE_VMA_OPCODE_LMULS_MF2
3158#undef CASE_VMA_OPCODE_LMULS_MF4
3159#undef CASE_VMA_OPCODE_LMULS
3160#undef CASE_VFMA_OPCODE_COMMON
3161#undef CASE_VFMA_OPCODE_LMULS_M1
3162#undef CASE_VFMA_OPCODE_LMULS_MF2
3163#undef CASE_VFMA_OPCODE_LMULS_MF4
3164#undef CASE_VFMA_OPCODE_VV
3165#undef CASE_VFMA_SPLATS
3168#define CASE_WIDEOP_OPCODE_COMMON(OP, LMUL) \
3169 RISCV::PseudoV##OP##_##LMUL##_TIED
3171#define CASE_WIDEOP_OPCODE_LMULS_MF4(OP) \
3172 CASE_WIDEOP_OPCODE_COMMON(OP, MF4): \
3173 case CASE_WIDEOP_OPCODE_COMMON(OP, MF2): \
3174 case CASE_WIDEOP_OPCODE_COMMON(OP, M1): \
3175 case CASE_WIDEOP_OPCODE_COMMON(OP, M2): \
3176 case CASE_WIDEOP_OPCODE_COMMON(OP, M4)
3178#define CASE_WIDEOP_OPCODE_LMULS(OP) \
3179 CASE_WIDEOP_OPCODE_COMMON(OP, MF8): \
3180 case CASE_WIDEOP_OPCODE_LMULS_MF4(OP)
3182#define CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, LMUL) \
3183 case RISCV::PseudoV##OP##_##LMUL##_TIED: \
3184 NewOpc = RISCV::PseudoV##OP##_##LMUL; \
3187#define CASE_WIDEOP_CHANGE_OPCODE_LMULS_MF4(OP) \
3188 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF4) \
3189 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF2) \
3190 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, M1) \
3191 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, M2) \
3192 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, M4)
3194#define CASE_WIDEOP_CHANGE_OPCODE_LMULS(OP) \
3195 CASE_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF8) \
3196 CASE_WIDEOP_CHANGE_OPCODE_LMULS_MF4(OP)
3199#define CASE_FP_WIDEOP_OPCODE_COMMON(OP, LMUL, SEW) \
3200 RISCV::PseudoV##OP##_##LMUL##_##SEW##_TIED
3202#define CASE_FP_WIDEOP_OPCODE_LMULS_MF4(OP) \
3203 CASE_FP_WIDEOP_OPCODE_COMMON(OP, MF4, E16): \
3204 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, MF2, E16): \
3205 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, MF2, E32): \
3206 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M1, E16): \
3207 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M1, E32): \
3208 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M2, E16): \
3209 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M2, E32): \
3210 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M4, E16): \
3211 case CASE_FP_WIDEOP_OPCODE_COMMON(OP, M4, E32) \
3213#define CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, LMUL, SEW) \
3214 case RISCV::PseudoV##OP##_##LMUL##_##SEW##_TIED: \
3215 NewOpc = RISCV::PseudoV##OP##_##LMUL##_##SEW; \
3218#define CASE_FP_WIDEOP_CHANGE_OPCODE_LMULS_MF4(OP) \
3219 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF4, E16) \
3220 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF2, E16) \
3221 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, MF2, E32) \
3222 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M1, E16) \
3223 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M1, E32) \
3224 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M2, E16) \
3225 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M2, E32) \
3226 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M4, E16) \
3227 CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON(OP, M4, E32) \
3229#define CASE_FP_WIDEOP_CHANGE_OPCODE_LMULS(OP) \
3230 CASE_FP_WIDEOP_CHANGE_OPCODE_LMULS_MF4(OP)
3237 switch (
MI.getOpcode()) {
3243 MI.getNumExplicitOperands() == 7 &&
3244 "Expect 7 explicit operands rd, rs2, rs1, rm, vl, sew, policy");
3251 switch (
MI.getOpcode()) {
3261 .
add(
MI.getOperand(0))
3263 .
add(
MI.getOperand(1))
3264 .
add(
MI.getOperand(2))
3265 .
add(
MI.getOperand(3))
3266 .
add(
MI.getOperand(4))
3267 .
add(
MI.getOperand(5))
3268 .
add(
MI.getOperand(6));
3277 MI.getNumExplicitOperands() == 6);
3278 if ((
MI.getOperand(5).getImm() & 1) == 0)
3283 switch (
MI.getOpcode()) {
3295 .
add(
MI.getOperand(0))
3297 .
add(
MI.getOperand(1))
3298 .
add(
MI.getOperand(2))
3299 .
add(
MI.getOperand(3))
3300 .
add(
MI.getOperand(4))
3301 .
add(
MI.getOperand(5));
3308 unsigned NumOps =
MI.getNumOperands();
3309 for (
unsigned I = 1;
I < NumOps; ++
I) {
3311 if (
Op.isReg() &&
Op.isKill())
3319 if (
MI.getOperand(0).isEarlyClobber()) {
3325 if (S->
end ==
Idx.getRegSlot(
true))
3326 S->
end =
Idx.getRegSlot();
3333#undef CASE_WIDEOP_OPCODE_COMMON
3334#undef CASE_WIDEOP_OPCODE_LMULS_MF4
3335#undef CASE_WIDEOP_OPCODE_LMULS
3336#undef CASE_WIDEOP_CHANGE_OPCODE_COMMON
3337#undef CASE_WIDEOP_CHANGE_OPCODE_LMULS_MF4
3338#undef CASE_WIDEOP_CHANGE_OPCODE_LMULS
3339#undef CASE_FP_WIDEOP_OPCODE_COMMON
3340#undef CASE_FP_WIDEOP_OPCODE_LMULS_MF4
3341#undef CASE_FP_WIDEOP_CHANGE_OPCODE_COMMON
3342#undef CASE_FP_WIDEOP_CHANGE_OPCODE_LMULS_MF4
3343#undef CASE_FP_WIDEOP_CHANGE_OPCODE_LMULS
3350 if (llvm::has_single_bit<uint32_t>(Amount)) {
3352 if (ShiftAmount == 0)
3358 }
else if (
STI.hasStdExtZba() &&
3365 if (Amount % 9 == 0) {
3366 Opc = RISCV::SH3ADD;
3367 ShiftAmount =
Log2_64(Amount / 9);
3368 }
else if (Amount % 5 == 0) {
3369 Opc = RISCV::SH2ADD;
3370 ShiftAmount =
Log2_64(Amount / 5);
3371 }
else if (Amount % 3 == 0) {
3372 Opc = RISCV::SH1ADD;
3373 ShiftAmount =
Log2_64(Amount / 3);
3386 }
else if (llvm::has_single_bit<uint32_t>(Amount - 1)) {
3387 Register ScaledRegister =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
3397 }
else if (llvm::has_single_bit<uint32_t>(Amount + 1)) {
3398 Register ScaledRegister =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
3408 }
else if (
STI.hasStdExtM() ||
STI.hasStdExtZmmul()) {
3409 Register N =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
3418 for (
uint32_t ShiftAmount = 0; Amount >> ShiftAmount; ShiftAmount++) {
3419 if (Amount & (1U << ShiftAmount)) {
3423 .
addImm(ShiftAmount - PrevShiftAmount)
3425 if (Amount >> (ShiftAmount + 1)) {
3428 Acc =
MRI.createVirtualRegister(&RISCV::GPRRegClass);
3439 PrevShiftAmount = ShiftAmount;
3442 assert(Acc &&
"Expected valid accumulator");
3452 static const std::pair<MachineMemOperand::Flags, const char *> TargetFlags[] =
3460 return MI.getOpcode() == RISCV::ADDIW &&
MI.getOperand(1).isReg() &&
3461 MI.getOperand(2).isImm() &&
MI.getOperand(2).getImm() == 0;
3466 return MI.getOpcode() == RISCV::ADD_UW &&
MI.getOperand(1).isReg() &&
3467 MI.getOperand(2).isReg() &&
MI.getOperand(2).getReg() == RISCV::X0;
3472 return MI.getOpcode() == RISCV::ANDI &&
MI.getOperand(1).isReg() &&
3473 MI.getOperand(2).isImm() &&
MI.getOperand(2).getImm() == 255;
3484 case RISCV::VL1RE8_V:
3485 case RISCV::VL2RE8_V:
3486 case RISCV::VL4RE8_V:
3487 case RISCV::VL8RE8_V:
3488 case RISCV::VL1RE16_V:
3489 case RISCV::VL2RE16_V:
3490 case RISCV::VL4RE16_V:
3491 case RISCV::VL8RE16_V:
3492 case RISCV::VL1RE32_V:
3493 case RISCV::VL2RE32_V:
3494 case RISCV::VL4RE32_V:
3495 case RISCV::VL8RE32_V:
3496 case RISCV::VL1RE64_V:
3497 case RISCV::VL2RE64_V:
3498 case RISCV::VL4RE64_V:
3499 case RISCV::VL8RE64_V:
3507 unsigned Opcode =
MI.getOpcode();
3508 if (!RISCVVPseudosTable::getPseudoInfo(Opcode) &&
3514std::optional<std::pair<unsigned, unsigned>>
3518 return std::nullopt;
3519 case RISCV::PseudoVSPILL2_M1:
3520 case RISCV::PseudoVRELOAD2_M1:
3521 return std::make_pair(2u, 1u);
3522 case RISCV::PseudoVSPILL2_M2:
3523 case RISCV::PseudoVRELOAD2_M2:
3524 return std::make_pair(2u, 2u);
3525 case RISCV::PseudoVSPILL2_M4:
3526 case RISCV::PseudoVRELOAD2_M4:
3527 return std::make_pair(2u, 4u);
3528 case RISCV::PseudoVSPILL3_M1:
3529 case RISCV::PseudoVRELOAD3_M1:
3530 return std::make_pair(3u, 1u);
3531 case RISCV::PseudoVSPILL3_M2:
3532 case RISCV::PseudoVRELOAD3_M2:
3533 return std::make_pair(3u, 2u);
3534 case RISCV::PseudoVSPILL4_M1:
3535 case RISCV::PseudoVRELOAD4_M1:
3536 return std::make_pair(4u, 1u);
3537 case RISCV::PseudoVSPILL4_M2:
3538 case RISCV::PseudoVRELOAD4_M2:
3539 return std::make_pair(4u, 2u);
3540 case RISCV::PseudoVSPILL5_M1:
3541 case RISCV::PseudoVRELOAD5_M1:
3542 return std::make_pair(5u, 1u);
3543 case RISCV::PseudoVSPILL6_M1:
3544 case RISCV::PseudoVRELOAD6_M1:
3545 return std::make_pair(6u, 1u);
3546 case RISCV::PseudoVSPILL7_M1:
3547 case RISCV::PseudoVRELOAD7_M1:
3548 return std::make_pair(7u, 1u);
3549 case RISCV::PseudoVSPILL8_M1:
3550 case RISCV::PseudoVRELOAD8_M1:
3551 return std::make_pair(8u, 1u);
3556 return MI.getNumExplicitDefs() == 2 &&
3557 MI.modifiesRegister(RISCV::VL,
nullptr) && !
MI.isInlineAsm();
3561 int16_t MI1FrmOpIdx =
3563 int16_t MI2FrmOpIdx =
3565 if (MI1FrmOpIdx < 0 || MI2FrmOpIdx < 0)
3572std::optional<unsigned>
3577 return std::nullopt;
3580 case RISCV::VSLL_VX:
3581 case RISCV::VSRL_VX:
3582 case RISCV::VSRA_VX:
3584 case RISCV::VSSRL_VX:
3585 case RISCV::VSSRA_VX:
3590 case RISCV::VNSRL_WX:
3591 case RISCV::VNSRA_WX:
3593 case RISCV::VNCLIPU_WX:
3594 case RISCV::VNCLIP_WX:
3599 case RISCV::VADD_VX:
3600 case RISCV::VSUB_VX:
3601 case RISCV::VRSUB_VX:
3603 case RISCV::VWADDU_VX:
3604 case RISCV::VWSUBU_VX:
3605 case RISCV::VWADD_VX:
3606 case RISCV::VWSUB_VX:
3607 case RISCV::VWADDU_WX:
3608 case RISCV::VWSUBU_WX:
3609 case RISCV::VWADD_WX:
3610 case RISCV::VWSUB_WX:
3612 case RISCV::VADC_VXM:
3613 case RISCV::VADC_VIM:
3614 case RISCV::VMADC_VXM:
3615 case RISCV::VMADC_VIM:
3616 case RISCV::VMADC_VX:
3617 case RISCV::VSBC_VXM:
3618 case RISCV::VMSBC_VXM:
3619 case RISCV::VMSBC_VX:
3621 case RISCV::VAND_VX:
3623 case RISCV::VXOR_VX:
3625 case RISCV::VMSEQ_VX:
3626 case RISCV::VMSNE_VX:
3627 case RISCV::VMSLTU_VX:
3628 case RISCV::VMSLT_VX:
3629 case RISCV::VMSLEU_VX:
3630 case RISCV::VMSLE_VX:
3631 case RISCV::VMSGTU_VX:
3632 case RISCV::VMSGT_VX:
3634 case RISCV::VMINU_VX:
3635 case RISCV::VMIN_VX:
3636 case RISCV::VMAXU_VX:
3637 case RISCV::VMAX_VX:
3639 case RISCV::VMUL_VX:
3640 case RISCV::VMULH_VX:
3641 case RISCV::VMULHU_VX:
3642 case RISCV::VMULHSU_VX:
3644 case RISCV::VDIVU_VX:
3645 case RISCV::VDIV_VX:
3646 case RISCV::VREMU_VX:
3647 case RISCV::VREM_VX:
3649 case RISCV::VWMUL_VX:
3650 case RISCV::VWMULU_VX:
3651 case RISCV::VWMULSU_VX:
3653 case RISCV::VMACC_VX:
3654 case RISCV::VNMSAC_VX:
3655 case RISCV::VMADD_VX:
3656 case RISCV::VNMSUB_VX:
3658 case RISCV::VWMACCU_VX:
3659 case RISCV::VWMACC_VX:
3660 case RISCV::VWMACCSU_VX:
3661 case RISCV::VWMACCUS_VX:
3663 case RISCV::VMERGE_VXM:
3665 case RISCV::VMV_V_X:
3667 case RISCV::VSADDU_VX:
3668 case RISCV::VSADD_VX:
3669 case RISCV::VSSUBU_VX:
3670 case RISCV::VSSUB_VX:
3672 case RISCV::VAADDU_VX:
3673 case RISCV::VAADD_VX:
3674 case RISCV::VASUBU_VX:
3675 case RISCV::VASUB_VX:
3677 case RISCV::VSMUL_VX:
3679 case RISCV::VMV_S_X:
3680 return 1U << Log2SEW;
3686 RISCVVPseudosTable::getPseudoInfo(RVVPseudoOpcode);
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder MachineInstrBuilder & DefMI
static bool forwardCopyWillClobberTuple(unsigned DestReg, unsigned SrcReg, unsigned NumRegs)
static bool canCombine(MachineBasicBlock &MBB, MachineOperand &MO, unsigned CombineOpc, unsigned ZeroReg=0, bool CheckZeroReg=false)
static void parseCondBranch(MachineInstr *LastInst, MachineBasicBlock *&Target, SmallVectorImpl< MachineOperand > &Cond)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
static ARCCC::CondCode getOppositeBranchCondition(ARCCC::CondCode CC)
Return the inverse of passed condition, i.e. turning COND_E to COND_NE.
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
const HexagonInstrInfo * TII
static M68k::CondCode getCondFromBranchOpc(unsigned BrOpc)
unsigned const TargetRegisterInfo * TRI
This file provides utility analysis objects describing memory locations.
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
const char LLVMTargetMachineRef TM
#define CASE_VFMA_CHANGE_OPCODE_SPLATS(OLDOP, NEWOP)
static bool isRVVWholeLoadStore(unsigned Opcode)
#define CASE_VFMA_CHANGE_OPCODE_VV(OLDOP, NEWOP)
static unsigned getFPFusedMultiplyOpcode(unsigned RootOpc, unsigned Pattern)
static void combineFPFusedMultiply(MachineInstr &Root, MachineInstr &Prev, unsigned Pattern, SmallVectorImpl< MachineInstr * > &InsInstrs, SmallVectorImpl< MachineInstr * > &DelInstrs)
static unsigned getAddendOperandIdx(unsigned Pattern)
#define CASE_RVV_OPCODE_UNMASK(OP)
#define CASE_WIDEOP_CHANGE_OPCODE_LMULS(OP)
static cl::opt< bool > PreferWholeRegisterMove("riscv-prefer-whole-register-move", cl::init(false), cl::Hidden, cl::desc("Prefer whole register move for vector registers."))
#define CASE_VFMA_SPLATS(OP)
unsigned getPredicatedOpcode(unsigned Opcode)
static void genShXAddAddShift(MachineInstr &Root, unsigned AddOpIdx, SmallVectorImpl< MachineInstr * > &InsInstrs, SmallVectorImpl< MachineInstr * > &DelInstrs, DenseMap< unsigned, unsigned > &InstrIdxForVirtReg)
#define CASE_WIDEOP_OPCODE_LMULS(OP)
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)
#define CASE_VMA_OPCODE_LMULS(OP, TYPE)
static bool isFMUL(unsigned Opc)
static bool getFPPatterns(MachineInstr &Root, SmallVectorImpl< unsigned > &Patterns, bool DoRegPressureReduce)
#define CASE_OPERAND_UIMM(NUM)
static bool canCombineShiftIntoShXAdd(const MachineBasicBlock &MBB, const MachineOperand &MO, unsigned OuterShiftAmt)
Utility routine that checks if.
static bool isFADD(unsigned Opc)
#define CASE_FP_WIDEOP_OPCODE_LMULS_MF4(OP)
static bool isConvertibleToVMV_V_V(const RISCVSubtarget &STI, const MachineBasicBlock &MBB, MachineBasicBlock::const_iterator MBBI, MachineBasicBlock::const_iterator &DefMBBI, RISCVII::VLMUL LMul)
static MachineInstr * canFoldAsPredicatedOp(Register Reg, const MachineRegisterInfo &MRI, const TargetInstrInfo *TII)
Identify instructions that can be folded into a CCMOV instruction, and return the defining instructio...
static bool canCombineFPFusedMultiply(const MachineInstr &Root, const MachineOperand &MO, bool DoRegPressureReduce)
static bool getSHXADDPatterns(const MachineInstr &Root, SmallVectorImpl< unsigned > &Patterns)
static bool getFPFusedMultiplyPatterns(MachineInstr &Root, SmallVectorImpl< unsigned > &Patterns, bool DoRegPressureReduce)
static cl::opt< MachineTraceStrategy > ForceMachineCombinerStrategy("riscv-force-machine-combiner-strategy", cl::Hidden, cl::desc("Force machine combiner to use a specific strategy for machine " "trace metrics evaluation."), cl::init(MachineTraceStrategy::TS_NumStrategies), cl::values(clEnumValN(MachineTraceStrategy::TS_Local, "local", "Local strategy."), clEnumValN(MachineTraceStrategy::TS_MinInstrCount, "min-instr", "MinInstrCount strategy.")))
static unsigned getSHXADDShiftAmount(unsigned Opc)
#define CASE_RVV_OPCODE_MASK(OP)
#define CASE_FP_WIDEOP_CHANGE_OPCODE_LMULS_MF4(OP)
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)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
static unsigned getSize(unsigned Kind)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
const T & front() const
front - Get the first element.
size_t size() const
size - Get the array size.
bool empty() const
empty - Check if the array is empty.
static DILocation * getMergedLocation(DILocation *LocA, DILocation *LocB)
When two instructions are combined into a single instruction we also need to combine the original loc...
This class represents an Operation in the Expression.
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.
void replaceKillInstruction(Register Reg, MachineInstr &OldMI, MachineInstr &NewMI)
replaceKillInstruction - Update register kill info by replacing a kill instruction with a new one.
static constexpr LocationSize beforeOrAfterPointer()
Any location before or after the base pointer (but still within the underlying object).
TypeSize getValue() const
MCInstBuilder & addReg(unsigned 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...
Wrapper class representing physical registers. Should be passed by value.
unsigned pred_size() const
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
iterator getLastNonDebugInstr(bool SkipPseudoOp=true)
Returns an iterator to the last non-debug instruction in the basic block, or end().
Instructions::const_iterator const_instr_iterator
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
void setStackID(int ObjectIdx, uint8_t ID)
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Function & getFunction()
Return the LLVM function that this machine code represents.
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineInstrBuilder & setMemRefs(ArrayRef< MachineMemOperand * > MMOs) const
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
const MachineInstrBuilder & copyImplicitOps(const MachineInstr &OtherMI) const
Copy all the implicit operands from OtherMI onto this one.
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
reverse_iterator getReverse() const
Get a reverse iterator to the same node.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
bool mayLoadOrStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read or modify memory.
const MachineBasicBlock * getParent() const
bool getFlag(MIFlag Flag) const
Return whether an MI flag is set.
unsigned getNumExplicitOperands() const
Returns the number of non-implicit operands.
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.
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.
bool hasOrderedMemoryRef() const
Return true if this instruction may have an ordered or volatile memory reference, or if the informati...
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.
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
const MachineOperand & getOperand(unsigned i) const
uint32_t getFlags() const
Return the MI flags bitvector.
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.
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)
Register getReg() const
getReg - Returns the register number.
bool isFI() const
isFI - Tests if this is a MO_FrameIndex operand.
bool isIdenticalTo(const MachineOperand &Other) const
Returns true if this operand is identical to the specified operand except for liveness related flags ...
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
A Module instance is used to store all the information related to an LLVM module.
MI-level patchpoint operands.
uint32_t getNumPatchBytes() const
Return the number of patchable bytes the given patchpoint should emit.
MachineInstr * convertToThreeAddress(MachineInstr &MI, LiveVariables *LV, LiveIntervals *LIS) const override
Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
std::optional< outliner::OutlinedFunction > getOutliningCandidateInfo(std::vector< outliner::Candidate > &RepeatedSequenceLocs) 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...
const MCInstrDesc & getBrCond(RISCVCC::CondCode CC) const
bool isFunctionSafeToOutlineFrom(MachineFunction &MF, bool OutlineFromLinkOnceODRs) 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
RISCVInstrInfo(RISCVSubtarget &STI)
void copyPhysRegVector(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, MCRegister DstReg, MCRegister SrcReg, bool KillSrc, const TargetRegisterClass *RegClass) const
void genAlternativeCodeSequence(MachineInstr &Root, unsigned Pattern, SmallVectorImpl< MachineInstr * > &InsInstrs, SmallVectorImpl< MachineInstr * > &DelInstrs, DenseMap< unsigned, unsigned > &InstrIdxForVirtReg) const override
MachineInstr * optimizeSelect(MachineInstr &MI, SmallPtrSetImpl< MachineInstr * > &SeenMIs, bool) const override
bool canFoldIntoAddrMode(const MachineInstr &MemI, Register Reg, const MachineInstr &AddrI, ExtAddrMode &AM) const override
void insertIndirectBranch(MachineBasicBlock &MBB, MachineBasicBlock &NewDestBB, MachineBasicBlock &RestoreBB, const DebugLoc &DL, int64_t BrOffset, RegScavenger *RS) const override
bool isAsCheapAsAMove(const MachineInstr &MI) const override
bool verifyInstruction(const MachineInstr &MI, StringRef &ErrInfo) const override
bool getMemOperandWithOffsetWidth(const MachineInstr &LdSt, const MachineOperand *&BaseOp, int64_t &Offset, LocationSize &Width, const TargetRegisterInfo *TRI) const
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, MCRegister DstReg, MCRegister SrcReg, bool KillSrc) const override
const RISCVSubtarget & STI
Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
std::optional< unsigned > getInverseOpcode(unsigned Opcode) const override
ArrayRef< std::pair< unsigned, const char * > > getSerializableDirectMachineOperandTargetFlags() const override
MachineTraceStrategy getMachineCombinerTraceStrategy() const override
unsigned getInstSizeInBytes(const MachineInstr &MI) const override
virtual outliner::InstrType getOutliningTypeImpl(MachineBasicBlock::iterator &MBBI, unsigned Flags) const override
std::optional< RegImmPair > isAddImmediate(const MachineInstr &MI, Register Reg) const override
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
ArrayRef< std::pair< MachineMemOperand::Flags, const char * > > getSerializableMachineMemOperandTargetFlags() const override
MCInst getNop() const override
MachineInstr * foldMemoryOperandImpl(MachineFunction &MF, MachineInstr &MI, ArrayRef< unsigned > Ops, MachineBasicBlock::iterator InsertPt, int FrameIndex, LiveIntervals *LIS=nullptr, VirtRegMap *VRM=nullptr) const override
bool isMBBSafeToOutlineFrom(MachineBasicBlock &MBB, unsigned &Flags) const override
bool getMemOperandsWithOffsetWidth(const MachineInstr &MI, SmallVectorImpl< const MachineOperand * > &BaseOps, int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width, const TargetRegisterInfo *TRI) const override
void buildOutlinedFrame(MachineBasicBlock &MBB, MachineFunction &MF, const outliner::OutlinedFunction &OF) const override
void finalizeInsInstrs(MachineInstr &Root, unsigned &Pattern, SmallVectorImpl< MachineInstr * > &InsInstrs) const override
std::pair< unsigned, unsigned > decomposeMachineOperandsTargetFlags(unsigned TF) const override
MachineInstr * commuteInstructionImpl(MachineInstr &MI, bool NewMI, unsigned OpIdx1, unsigned OpIdx2) const override
MachineBasicBlock * getBranchDestBlock(const MachineInstr &MI) const override
std::string createMIROperandComment(const MachineInstr &MI, const MachineOperand &Op, unsigned OpIdx, const TargetRegisterInfo *TRI) const override
bool shouldOutlineFromFunctionByDefault(MachineFunction &MF) const override
bool findCommutedOpIndices(const MachineInstr &MI, unsigned &SrcOpIdx1, unsigned &SrcOpIdx2) const override
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
MachineBasicBlock::iterator insertOutlinedCall(Module &M, MachineBasicBlock &MBB, MachineBasicBlock::iterator &It, MachineFunction &MF, outliner::Candidate &C) const override
bool isBranchOffsetInRange(unsigned BranchOpc, int64_t BrOffset) const override
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DstReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg) const override
bool isAssociativeAndCommutative(const MachineInstr &Inst, bool Invert) const override
CombinerObjective getCombinerObjective(unsigned Pattern) const override
bool getMachineCombinerPatterns(MachineInstr &Root, SmallVectorImpl< unsigned > &Patterns, bool DoRegPressureReduce) const override
bool optimizeCondBranch(MachineInstr &MI) const override
std::optional< DestSourcePair > isCopyInstrImpl(const MachineInstr &MI) const override
bool analyzeSelect(const MachineInstr &MI, SmallVectorImpl< MachineOperand > &Cond, unsigned &TrueOp, unsigned &FalseOp, bool &Optimizable) const override
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
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool IsKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg) const override
RISCVMachineFunctionInfo - This class is derived from MachineFunctionInfo and contains private RISCV-...
int getBranchRelaxationScratchFrameIndex() const
bool hasStdExtCOrZca() const
const RISCVRegisterInfo * getRegisterInfo() const override
void enterBasicBlockEnd(MachineBasicBlock &MBB)
Start tracking liveness from the end of basic block MBB.
void setRegUsed(Register Reg, LaneBitmask LaneMask=LaneBitmask::getAll())
Tell the scavenger a register is used.
Register scavengeRegisterBackwards(const TargetRegisterClass &RC, MachineBasicBlock::iterator To, bool RestoreAfter, int SPAdj, bool AllowSpill=true)
Make a register of the specific register class available from the current position backwards to the p...
Wrapper class representing virtual and physical registers.
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)
erase - If the set contains the specified pointer, remove it and return true, otherwise return false.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
MI-level stackmap operands.
uint32_t getNumPatchBytes() const
Return the number of patchable bytes the given stackmap should emit.
MI-level Statepoint operands.
uint32_t getNumPatchBytes() const
Return the number of patchable bytes the given statepoint should emit.
StringRef - Represent a constant reference to a string, i.e.
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 void genAlternativeCodeSequence(MachineInstr &Root, unsigned Pattern, SmallVectorImpl< MachineInstr * > &InsInstrs, SmallVectorImpl< MachineInstr * > &DelInstrs, DenseMap< unsigned, 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 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 CombinerObjective getCombinerObjective(unsigned Pattern) const
Return the objective of a combiner pattern.
virtual MachineInstr * commuteInstructionImpl(MachineInstr &MI, bool NewMI, unsigned OpIdx1, unsigned OpIdx2) const
This method commutes the operands of the given machine instruction MI.
virtual bool hasReassociableSibling(const MachineInstr &Inst, bool &Commuted) const
Return true when \P Inst has reassociable sibling.
virtual std::string createMIROperandComment(const MachineInstr &MI, const MachineOperand &Op, unsigned OpIdx, const TargetRegisterInfo *TRI) const
const uint8_t TSFlags
Configurable target specific flags.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
virtual const TargetInstrInfo * getInstrInfo() const
Target - Wrapper for Target specific information.
A raw_ostream that writes to an std::string.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
CondCode getOppositeBranchCondition(CondCode)
unsigned getBrCond(CondCode CC)
static unsigned getVecPolicyOpNum(const MCInstrDesc &Desc)
static unsigned getVLOpNum(const MCInstrDesc &Desc)
static bool hasVLOp(uint64_t TSFlags)
static bool hasVecPolicyOp(uint64_t TSFlags)
static bool isRVVWideningReduction(uint64_t TSFlags)
static unsigned getSEWOpNum(const MCInstrDesc &Desc)
static bool hasSEWOp(uint64_t TSFlags)
InstSeq generateInstSeq(int64_t Val, const MCSubtargetInfo &STI)
@ OPERAND_UIMMLOG2XLEN_NONZERO
@ OPERAND_SIMM12_LSB00000
@ OPERAND_FIRST_RISCV_IMM
@ OPERAND_UIMM10_LSB00_NONZERO
@ OPERAND_SIMM10_LSB0000_NONZERO
static RISCVII::VLMUL getLMul(uint64_t TSFlags)
static unsigned getNF(uint64_t TSFlags)
static bool isTailAgnostic(unsigned VType)
static RISCVII::VLMUL getVLMUL(unsigned VType)
std::pair< unsigned, bool > decodeVLMUL(RISCVII::VLMUL VLMUL)
static bool isValidSEW(unsigned SEW)
void printVType(unsigned VType, raw_ostream &OS)
static unsigned getSEW(unsigned VType)
bool hasEqualFRM(const MachineInstr &MI1, const MachineInstr &MI2)
std::optional< unsigned > getVectorLowDemandedScalarBits(uint16_t Opcode, unsigned Log2SEW)
int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIndex)
unsigned getRVVMCOpcode(unsigned RVVPseudoOpcode)
bool isSEXT_W(const MachineInstr &MI)
bool isFaultFirstLoad(const MachineInstr &MI)
std::optional< std::pair< unsigned, unsigned > > isRVVSpillForZvlsseg(unsigned Opcode)
bool isZEXT_B(const MachineInstr &MI)
bool isRVVSpill(const MachineInstr &MI)
bool isZEXT_W(const MachineInstr &MI)
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Define
Register definition.
@ Kill
The last use of a register.
@ Undef
Value of the register doesn't matter.
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
initializer< Ty > init(const Ty &Val)
InstrType
Represents how an instruction should be mapped by the outliner.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
MachineTraceStrategy
Strategies for selecting traces.
@ TS_MinInstrCount
Select the trace through a block that has the fewest instructions.
@ TS_Local
Select the trace that contains only the current basic block.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
static const MachineMemOperand::Flags MONontemporalBit1
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are are tuples (A,...
static const MachineMemOperand::Flags MONontemporalBit0
const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=6)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
unsigned getDeadRegState(bool B)
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
CombinerObjective
The combiner's goal may differ based on which pattern it is attempting to optimize.
unsigned getKillRegState(bool B)
bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
unsigned getRenamableRegState(bool B)
DWARFExpression::Operation Op
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.
Description of the encoding of one expression Op.
Used to describe addressing mode similar to ExtAddrMode in CodeGenPrepare.
This represents a simple continuous liveness interval for a value.
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
Used to describe a register and immediate addition.
An individual sequence of instructions to be replaced with a call to an outlined function.
The information necessary to create an outlined function for some class of candidate.