38#define DEBUG_TYPE "riscv-vl-optimizer"
39#define PASS_NAME "RISC-V VL Optimizer"
48 static DemandedVL vlmax() {
55 DemandedVL
max(
const DemandedVL &
X)
const {
60 return DemandedVL::vlmax();
85 DemandedVL getMinimumVLForUser(
const MachineOperand &UserOp)
const;
101 return MO.isReg() && MO.getReg().isVirtual() &&
102 RISCVRegisterInfo::isRVVRegClass(MRI->getRegClass(MO.getReg()));
113 std::optional<std::pair<unsigned, bool>> EMUL;
120 OperandInfo(std::pair<unsigned, bool> EMUL,
unsigned Log2EEW)
121 : EMUL(EMUL), Log2EEW(Log2EEW) {}
123 OperandInfo(
unsigned Log2EEW) : Log2EEW(Log2EEW) {}
125 OperandInfo() =
delete;
129 static bool areCompatible(
const OperandInfo &Def,
const OperandInfo &
User) {
130 if (Def.Log2EEW !=
User.Log2EEW)
132 if (
User.EMUL && Def.EMUL !=
User.EMUL)
144 OS <<
"EMUL: none\n";
145 OS <<
", EEW: " << (1 << Log2EEW);
151char RISCVVLOptimizer::ID = 0;
157 return new RISCVVLOptimizer();
168 const std::optional<OperandInfo> &OI) {
178static std::pair<unsigned, bool>
190 unsigned MISEW = 1 << MILog2SEW;
192 unsigned EEW = 1 << Log2EEW;
195 unsigned Num = EEW, Denom = MISEW;
196 int GCD = MILMULIsFractional ? std::gcd(Num, Denom * MILMUL)
197 : std::gcd(Num * MILMUL, Denom);
198 Num = MILMULIsFractional ? Num / GCD : Num * MILMUL / GCD;
199 Denom = MILMULIsFractional ? Denom * MILMUL / GCD : Denom / GCD;
200 return std::make_pair(Num > Denom ? Num : Denom, Denom > Num);
214 unsigned MISEW = 1 << MILog2SEW;
215 unsigned EEW = MISEW / Factor;
216 unsigned Log2EEW =
Log2_32(EEW);
221#define VSEG_CASES(Prefix, EEW) \
222 RISCV::Prefix##SEG2E##EEW##_V: \
223 case RISCV::Prefix##SEG3E##EEW##_V: \
224 case RISCV::Prefix##SEG4E##EEW##_V: \
225 case RISCV::Prefix##SEG5E##EEW##_V: \
226 case RISCV::Prefix##SEG6E##EEW##_V: \
227 case RISCV::Prefix##SEG7E##EEW##_V: \
228 case RISCV::Prefix##SEG8E##EEW##_V
229#define VSSEG_CASES(EEW) VSEG_CASES(VS, EEW)
230#define VSSSEG_CASES(EEW) VSEG_CASES(VSS, EEW)
231#define VSUXSEG_CASES(EEW) VSEG_CASES(VSUX, I##EEW)
232#define VSOXSEG_CASES(EEW) VSEG_CASES(VSOX, I##EEW)
238 RISCVVPseudosTable::getPseudoInfo(
MI.getOpcode());
239 assert(
RVV &&
"Could not find MI in PseudoTable");
254 Info.RegClass == RISCV::VMV0RegClassID)
259 switch (
RVV->BaseInstr) {
263 case RISCV::VSETIVLI:
285 case RISCV::VLSE16_V:
286 case RISCV::VSSE16_V:
292 case RISCV::VLSE32_V:
293 case RISCV::VSSE32_V:
299 case RISCV::VLSE64_V:
300 case RISCV::VSSE64_V:
308 case RISCV::VLUXEI8_V:
309 case RISCV::VLOXEI8_V:
310 case RISCV::VSUXEI8_V:
311 case RISCV::VSOXEI8_V:
318 case RISCV::VLUXEI16_V:
319 case RISCV::VLOXEI16_V:
320 case RISCV::VSUXEI16_V:
321 case RISCV::VSOXEI16_V:
328 case RISCV::VLUXEI32_V:
329 case RISCV::VLOXEI32_V:
330 case RISCV::VSUXEI32_V:
331 case RISCV::VSOXEI32_V:
338 case RISCV::VLUXEI64_V:
339 case RISCV::VLOXEI64_V:
340 case RISCV::VSUXEI64_V:
341 case RISCV::VSOXEI64_V:
356 case RISCV::VRSUB_VI:
357 case RISCV::VRSUB_VX:
381 case RISCV::VMINU_VV:
382 case RISCV::VMINU_VX:
385 case RISCV::VMAXU_VV:
386 case RISCV::VMAXU_VX:
393 case RISCV::VMULH_VV:
394 case RISCV::VMULH_VX:
395 case RISCV::VMULHU_VV:
396 case RISCV::VMULHU_VX:
397 case RISCV::VMULHSU_VV:
398 case RISCV::VMULHSU_VX:
401 case RISCV::VDIVU_VV:
402 case RISCV::VDIVU_VX:
405 case RISCV::VREMU_VV:
406 case RISCV::VREMU_VX:
411 case RISCV::VMACC_VV:
412 case RISCV::VMACC_VX:
413 case RISCV::VNMSAC_VV:
414 case RISCV::VNMSAC_VX:
415 case RISCV::VMADD_VV:
416 case RISCV::VMADD_VX:
417 case RISCV::VNMSUB_VV:
418 case RISCV::VNMSUB_VX:
423 case RISCV::VMERGE_VIM:
424 case RISCV::VMERGE_VVM:
425 case RISCV::VMERGE_VXM:
426 case RISCV::VADC_VIM:
427 case RISCV::VADC_VVM:
428 case RISCV::VADC_VXM:
429 case RISCV::VSBC_VVM:
430 case RISCV::VSBC_VXM:
439 case RISCV::VSADDU_VI:
440 case RISCV::VSADDU_VV:
441 case RISCV::VSADDU_VX:
442 case RISCV::VSADD_VI:
443 case RISCV::VSADD_VV:
444 case RISCV::VSADD_VX:
445 case RISCV::VSSUBU_VV:
446 case RISCV::VSSUBU_VX:
447 case RISCV::VSSUB_VV:
448 case RISCV::VSSUB_VX:
449 case RISCV::VAADDU_VV:
450 case RISCV::VAADDU_VX:
451 case RISCV::VAADD_VV:
452 case RISCV::VAADD_VX:
453 case RISCV::VASUBU_VV:
454 case RISCV::VASUBU_VX:
455 case RISCV::VASUB_VV:
456 case RISCV::VASUB_VX:
460 case RISCV::VSMUL_VV:
461 case RISCV::VSMUL_VX:
464 case RISCV::VSSRL_VI:
465 case RISCV::VSSRL_VV:
466 case RISCV::VSSRL_VX:
467 case RISCV::VSSRA_VI:
468 case RISCV::VSSRA_VV:
469 case RISCV::VSSRA_VX:
476 case RISCV::VFMV_F_S:
477 case RISCV::VFMV_S_F:
480 case RISCV::VSLIDEUP_VI:
481 case RISCV::VSLIDEUP_VX:
482 case RISCV::VSLIDEDOWN_VI:
483 case RISCV::VSLIDEDOWN_VX:
484 case RISCV::VSLIDE1UP_VX:
485 case RISCV::VFSLIDE1UP_VF:
486 case RISCV::VSLIDE1DOWN_VX:
487 case RISCV::VFSLIDE1DOWN_VF:
490 case RISCV::VRGATHER_VI:
491 case RISCV::VRGATHER_VV:
492 case RISCV::VRGATHER_VX:
496 case RISCV::VFADD_VF:
497 case RISCV::VFADD_VV:
498 case RISCV::VFSUB_VF:
499 case RISCV::VFSUB_VV:
500 case RISCV::VFRSUB_VF:
502 case RISCV::VFMUL_VF:
503 case RISCV::VFMUL_VV:
504 case RISCV::VFDIV_VF:
505 case RISCV::VFDIV_VV:
506 case RISCV::VFRDIV_VF:
508 case RISCV::VFMACC_VV:
509 case RISCV::VFMACC_VF:
510 case RISCV::VFNMACC_VV:
511 case RISCV::VFNMACC_VF:
512 case RISCV::VFMSAC_VV:
513 case RISCV::VFMSAC_VF:
514 case RISCV::VFNMSAC_VV:
515 case RISCV::VFNMSAC_VF:
516 case RISCV::VFMADD_VV:
517 case RISCV::VFMADD_VF:
518 case RISCV::VFNMADD_VV:
519 case RISCV::VFNMADD_VF:
520 case RISCV::VFMSUB_VV:
521 case RISCV::VFMSUB_VF:
522 case RISCV::VFNMSUB_VV:
523 case RISCV::VFNMSUB_VF:
525 case RISCV::VFSQRT_V:
527 case RISCV::VFRSQRT7_V:
529 case RISCV::VFREC7_V:
531 case RISCV::VFMIN_VF:
532 case RISCV::VFMIN_VV:
533 case RISCV::VFMAX_VF:
534 case RISCV::VFMAX_VV:
536 case RISCV::VFSGNJ_VF:
537 case RISCV::VFSGNJ_VV:
538 case RISCV::VFSGNJN_VV:
539 case RISCV::VFSGNJN_VF:
540 case RISCV::VFSGNJX_VF:
541 case RISCV::VFSGNJX_VV:
543 case RISCV::VFCLASS_V:
545 case RISCV::VFMV_V_F:
547 case RISCV::VFCVT_XU_F_V:
548 case RISCV::VFCVT_X_F_V:
549 case RISCV::VFCVT_RTZ_XU_F_V:
550 case RISCV::VFCVT_RTZ_X_F_V:
551 case RISCV::VFCVT_F_XU_V:
552 case RISCV::VFCVT_F_X_V:
554 case RISCV::VFMERGE_VFM:
558 case RISCV::VFIRST_M:
561 case RISCV::VANDN_VV:
562 case RISCV::VANDN_VX:
566 case RISCV::VBREV8_V:
584 case RISCV::VCLMUL_VV:
585 case RISCV::VCLMUL_VX:
587 case RISCV::VCLMULH_VV:
588 case RISCV::VCLMULH_VX:
592 case RISCV::VWSLL_VI:
593 case RISCV::VWSLL_VX:
594 case RISCV::VWSLL_VV:
597 case RISCV::VWADDU_VV:
598 case RISCV::VWADDU_VX:
599 case RISCV::VWSUBU_VV:
600 case RISCV::VWSUBU_VX:
601 case RISCV::VWADD_VV:
602 case RISCV::VWADD_VX:
603 case RISCV::VWSUB_VV:
604 case RISCV::VWSUB_VX:
607 case RISCV::VWMUL_VV:
608 case RISCV::VWMUL_VX:
609 case RISCV::VWMULSU_VV:
610 case RISCV::VWMULSU_VX:
611 case RISCV::VWMULU_VV:
612 case RISCV::VWMULU_VX:
618 case RISCV::VWMACCU_VV:
619 case RISCV::VWMACCU_VX:
620 case RISCV::VWMACC_VV:
621 case RISCV::VWMACC_VX:
622 case RISCV::VWMACCSU_VV:
623 case RISCV::VWMACCSU_VX:
624 case RISCV::VWMACCUS_VX:
626 case RISCV::VFWMACC_VF:
627 case RISCV::VFWMACC_VV:
628 case RISCV::VFWNMACC_VF:
629 case RISCV::VFWNMACC_VV:
630 case RISCV::VFWMSAC_VF:
631 case RISCV::VFWMSAC_VV:
632 case RISCV::VFWNMSAC_VF:
633 case RISCV::VFWNMSAC_VV:
634 case RISCV::VFWMACCBF16_VV:
635 case RISCV::VFWMACCBF16_VF:
638 case RISCV::VFWADD_VV:
639 case RISCV::VFWADD_VF:
640 case RISCV::VFWSUB_VV:
641 case RISCV::VFWSUB_VF:
643 case RISCV::VFWMUL_VF:
644 case RISCV::VFWMUL_VV:
646 case RISCV::VFWCVT_XU_F_V:
647 case RISCV::VFWCVT_X_F_V:
648 case RISCV::VFWCVT_RTZ_XU_F_V:
649 case RISCV::VFWCVT_RTZ_X_F_V:
650 case RISCV::VFWCVT_F_XU_V:
651 case RISCV::VFWCVT_F_X_V:
652 case RISCV::VFWCVT_F_F_V:
653 case RISCV::VFWCVTBF16_F_F_V:
654 return IsMODef ? MILog2SEW + 1 : MILog2SEW;
657 case RISCV::VWADDU_WV:
658 case RISCV::VWADDU_WX:
659 case RISCV::VWSUBU_WV:
660 case RISCV::VWSUBU_WX:
661 case RISCV::VWADD_WV:
662 case RISCV::VWADD_WX:
663 case RISCV::VWSUB_WV:
664 case RISCV::VWSUB_WX:
666 case RISCV::VFWADD_WF:
667 case RISCV::VFWADD_WV:
668 case RISCV::VFWSUB_WF:
669 case RISCV::VFWSUB_WV: {
670 bool IsOp1 = (HasPassthru && !IsTied) ? MO.
getOperandNo() == 2
672 bool TwoTimes = IsMODef || IsOp1;
673 return TwoTimes ? MILog2SEW + 1 : MILog2SEW;
677 case RISCV::VZEXT_VF2:
678 case RISCV::VSEXT_VF2:
680 case RISCV::VZEXT_VF4:
681 case RISCV::VSEXT_VF4:
683 case RISCV::VZEXT_VF8:
684 case RISCV::VSEXT_VF8:
689 case RISCV::VNSRL_WX:
690 case RISCV::VNSRL_WI:
691 case RISCV::VNSRL_WV:
692 case RISCV::VNSRA_WI:
693 case RISCV::VNSRA_WV:
694 case RISCV::VNSRA_WX:
697 case RISCV::VNCLIPU_WI:
698 case RISCV::VNCLIPU_WV:
699 case RISCV::VNCLIPU_WX:
700 case RISCV::VNCLIP_WI:
701 case RISCV::VNCLIP_WV:
702 case RISCV::VNCLIP_WX:
704 case RISCV::VFNCVT_XU_F_W:
705 case RISCV::VFNCVT_X_F_W:
706 case RISCV::VFNCVT_RTZ_XU_F_W:
707 case RISCV::VFNCVT_RTZ_X_F_W:
708 case RISCV::VFNCVT_F_XU_W:
709 case RISCV::VFNCVT_F_X_W:
710 case RISCV::VFNCVT_F_F_W:
711 case RISCV::VFNCVT_ROD_F_F_W:
712 case RISCV::VFNCVTBF16_F_F_W: {
715 bool TwoTimes = IsOp1;
716 return TwoTimes ? MILog2SEW + 1 : MILog2SEW;
728 case RISCV::VMAND_MM:
729 case RISCV::VMNAND_MM:
730 case RISCV::VMANDN_MM:
731 case RISCV::VMXOR_MM:
733 case RISCV::VMNOR_MM:
734 case RISCV::VMORN_MM:
735 case RISCV::VMXNOR_MM:
738 case RISCV::VMSOF_M: {
745 case RISCV::VCOMPRESS_VM:
751 case RISCV::VIOTA_M: {
759 case RISCV::VMSEQ_VI:
760 case RISCV::VMSEQ_VV:
761 case RISCV::VMSEQ_VX:
762 case RISCV::VMSNE_VI:
763 case RISCV::VMSNE_VV:
764 case RISCV::VMSNE_VX:
765 case RISCV::VMSLTU_VV:
766 case RISCV::VMSLTU_VX:
767 case RISCV::VMSLT_VV:
768 case RISCV::VMSLT_VX:
769 case RISCV::VMSLEU_VV:
770 case RISCV::VMSLEU_VI:
771 case RISCV::VMSLEU_VX:
772 case RISCV::VMSLE_VV:
773 case RISCV::VMSLE_VI:
774 case RISCV::VMSLE_VX:
775 case RISCV::VMSGTU_VI:
776 case RISCV::VMSGTU_VX:
777 case RISCV::VMSGT_VI:
778 case RISCV::VMSGT_VX:
781 case RISCV::VMADC_VIM:
782 case RISCV::VMADC_VVM:
783 case RISCV::VMADC_VXM:
784 case RISCV::VMSBC_VVM:
785 case RISCV::VMSBC_VXM:
787 case RISCV::VMADC_VV:
788 case RISCV::VMADC_VI:
789 case RISCV::VMADC_VX:
790 case RISCV::VMSBC_VV:
791 case RISCV::VMSBC_VX:
794 case RISCV::VMFEQ_VF:
795 case RISCV::VMFEQ_VV:
796 case RISCV::VMFNE_VF:
797 case RISCV::VMFNE_VV:
798 case RISCV::VMFLT_VF:
799 case RISCV::VMFLT_VV:
800 case RISCV::VMFLE_VF:
801 case RISCV::VMFLE_VV:
802 case RISCV::VMFGT_VF:
803 case RISCV::VMFGE_VF: {
811 case RISCV::VREDAND_VS:
812 case RISCV::VREDMAX_VS:
813 case RISCV::VREDMAXU_VS:
814 case RISCV::VREDMIN_VS:
815 case RISCV::VREDMINU_VS:
816 case RISCV::VREDOR_VS:
817 case RISCV::VREDSUM_VS:
818 case RISCV::VREDXOR_VS:
820 case RISCV::VFREDMAX_VS:
821 case RISCV::VFREDMIN_VS:
822 case RISCV::VFREDOSUM_VS:
823 case RISCV::VFREDUSUM_VS: {
830 case RISCV::VWREDSUM_VS:
831 case RISCV::VWREDSUMU_VS:
833 case RISCV::VFWREDOSUM_VS:
834 case RISCV::VFWREDUSUM_VS: {
836 return TwoTimes ? MILog2SEW + 1 : MILog2SEW;
841 case RISCV::VRGATHEREI16_VV: {
855 RISCVVPseudosTable::getPseudoInfo(
MI.getOpcode());
856 assert(
RVV &&
"Could not find MI in PseudoTable");
862 switch (
RVV->BaseInstr) {
869 case RISCV::VREDAND_VS:
870 case RISCV::VREDMAX_VS:
871 case RISCV::VREDMAXU_VS:
872 case RISCV::VREDMIN_VS:
873 case RISCV::VREDMINU_VS:
874 case RISCV::VREDOR_VS:
875 case RISCV::VREDSUM_VS:
876 case RISCV::VREDXOR_VS:
877 case RISCV::VWREDSUM_VS:
878 case RISCV::VWREDSUMU_VS:
879 case RISCV::VFWREDOSUM_VS:
880 case RISCV::VFWREDUSUM_VS:
882 return OperandInfo(*Log2EEW);
893bool RISCVVLOptimizer::isSupportedInstr(
const MachineInstr &
MI)
const {
901 assert(!(
MI.getNumExplicitDefs() == 0 && !
MI.mayStore() &&
903 "No defs but elements don't depend on VL?");
907 if (RVVOpc == RISCV::VMV_S_X || RVVOpc == RISCV::VFMV_S_F)
923 RISCVVPseudosTable::getPseudoInfo(
MI->getOpcode());
928 switch (
RVV->BaseInstr) {
930 case RISCV::VREDAND_VS:
931 case RISCV::VREDMAX_VS:
932 case RISCV::VREDMAXU_VS:
933 case RISCV::VREDMIN_VS:
934 case RISCV::VREDMINU_VS:
935 case RISCV::VREDOR_VS:
936 case RISCV::VREDSUM_VS:
937 case RISCV::VREDXOR_VS:
938 case RISCV::VWREDSUM_VS:
939 case RISCV::VWREDSUMU_VS:
940 case RISCV::VFREDMAX_VS:
941 case RISCV::VFREDMIN_VS:
942 case RISCV::VFREDOSUM_VS:
943 case RISCV::VFREDUSUM_VS:
944 case RISCV::VFWREDOSUM_VS:
945 case RISCV::VFWREDUSUM_VS:
948 case RISCV::VFMV_F_S:
955bool RISCVVLOptimizer::isCandidate(
const MachineInstr &
MI)
const {
956 const MCInstrDesc &
Desc =
MI.getDesc();
960 if (
MI.getNumExplicitDefs() != 1)
965 if (!
MI.allImplicitDefsAreDead()) {
966 LLVM_DEBUG(
dbgs() <<
"Not a candidate because has non-dead implicit def\n");
970 if (
MI.mayRaiseFPException()) {
971 LLVM_DEBUG(
dbgs() <<
"Not a candidate because may raise FP exception\n");
975 for (
const MachineMemOperand *MMO :
MI.memoperands()) {
976 if (MMO->isVolatile()) {
977 LLVM_DEBUG(
dbgs() <<
"Not a candidate because contains volatile MMO\n");
982 if (!isSupportedInstr(
MI)) {
983 LLVM_DEBUG(
dbgs() <<
"Not a candidate due to unsupported instruction: "
990 "Instruction shouldn't be supported if elements depend on VL");
993 MRI->getRegClass(
MI.getOperand(0).getReg())->TSFlags) &&
994 "All supported instructions produce a vector register result");
1011static std::optional<DemandedVL>
1016 return std::nullopt;
1019 return std::nullopt;
1023 return std::nullopt;
1027 return std::nullopt;
1029 if (SlideAmtDef->
getOpcode() != RISCV::ADDI ||
1032 return std::nullopt;
1037RISCVVLOptimizer::getMinimumVLForUser(
const MachineOperand &UserOp)
const {
1038 const MachineInstr &UserMI = *UserOp.
getParent();
1042 return DemandedVLs.lookup(&UserMI);
1047 return DemandedVL::vlmax();
1055 LLVM_DEBUG(
dbgs() <<
" Abort because used by unsafe instruction\n");
1056 return DemandedVL::vlmax();
1060 const MachineOperand &VLOp = UserMI.
getOperand(VLOpNum);
1063 "Did not expect X0 VL");
1072 "instruction with demanded tail\n");
1073 return DemandedVL::vlmax();
1080 LLVM_DEBUG(
dbgs() <<
" Used this operand as a scalar operand\n");
1087 return DemandedVLs.lookup(&UserMI);
1096 if (!
MI.isInsertSubreg())
1110 unsigned SubRegIdx =
MI.getOperand(3).getImm();
1112 assert(!IsFractional &&
"unexpected LMUL for tuple register classes");
1140bool RISCVVLOptimizer::checkUsers(
const MachineInstr &
MI)
const {
1144 SmallSetVector<MachineOperand *, 8> OpWorklist;
1145 SmallPtrSet<const MachineInstr *, 4> PHISeen;
1146 for (
auto &UserOp :
MRI->use_operands(
MI.getOperand(0).getReg()))
1147 OpWorklist.
insert(&UserOp);
1149 while (!OpWorklist.
empty()) {
1151 const MachineInstr &UserMI = *UserOp.
getParent();
1162 LLVM_DEBUG(
dbgs().indent(4) <<
"Peeking through uses of INSERT_SUBREG\n");
1163 for (MachineOperand &UseOp :
1165 const MachineInstr &CandidateMI = *UseOp.getParent();
1173 OpWorklist.
insert(&UseOp);
1178 if (UserMI.
isPHI()) {
1180 if (!PHISeen.
insert(&UserMI).second)
1193 std::optional<OperandInfo> ConsumerInfo =
getOperandInfo(UserOp);
1194 std::optional<OperandInfo> ProducerInfo =
getOperandInfo(
MI.getOperand(0));
1195 if (!ConsumerInfo || !ProducerInfo) {
1196 LLVM_DEBUG(
dbgs() <<
" Abort due to unknown operand information.\n");
1197 LLVM_DEBUG(
dbgs() <<
" ConsumerInfo is: " << ConsumerInfo <<
"\n");
1198 LLVM_DEBUG(
dbgs() <<
" ProducerInfo is: " << ProducerInfo <<
"\n");
1202 if (!OperandInfo::areCompatible(*ProducerInfo, *ConsumerInfo)) {
1205 <<
" Abort due to incompatible information for EMUL or EEW.\n");
1206 LLVM_DEBUG(
dbgs() <<
" ConsumerInfo is: " << ConsumerInfo <<
"\n");
1207 LLVM_DEBUG(
dbgs() <<
" ProducerInfo is: " << ProducerInfo <<
"\n");
1215bool RISCVVLOptimizer::tryReduceVL(MachineInstr &
MI,
1216 MachineOperand CommonVL)
const {
1220 MachineOperand &VLOp =
MI.getOperand(VLOpNum);
1225 LLVM_DEBUG(
dbgs() <<
" Abort due to VL == 1, no point in reducing.\n");
1230 "Expected VL to be an Imm or virtual Reg");
1234 if (CommonVL.
isReg()) {
1235 const MachineInstr *VLMI =
MRI->getVRegDef(CommonVL.
getReg());
1236 if (RISCVInstrInfo::isFaultOnlyFirstLoad(*VLMI) &&
1248 dbgs() <<
" Abort due to CommonVL == VLOp, no point in reducing.\n");
1252 if (CommonVL.
isImm()) {
1254 << CommonVL.
getImm() <<
" for " <<
MI <<
"\n");
1258 const MachineInstr *VLMI =
MRI->getVRegDef(CommonVL.
getReg());
1265 <<
" for " <<
MI <<
"\n");
1269 MRI->constrainRegClass(CommonVL.
getReg(), &RISCV::GPRNoX0RegClass);
1278void RISCVVLOptimizer::transfer(
const MachineInstr &
MI) {
1280 DemandedVLs[&
MI] = DemandedVL::vlmax();
1282 for (
const MachineOperand &MO : virtual_vec_uses(
MI)) {
1283 const MachineInstr *
Def =
MRI->getVRegDef(MO.getReg());
1284 DemandedVL Prev = DemandedVLs[
Def];
1285 DemandedVLs[
Def] = DemandedVLs[
Def].max(getMinimumVLForUser(MO));
1286 if (DemandedVLs[Def] != Prev)
1287 Worklist.insert(Def);
1291bool RISCVVLOptimizer::runOnMachineFunction(MachineFunction &MF) {
1296 MDT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
1299 if (!
ST.hasVInstructions())
1302 TII =
ST.getInstrInfo();
1304 assert(DemandedVLs.empty());
1311 if (!
MI.isDebugInstr())
1312 Worklist.insert(&
MI);
1315 while (!Worklist.empty()) {
1316 const MachineInstr *
MI = Worklist.front();
1317 Worklist.remove(
MI);
1323 bool MadeChange =
false;
1324 for (
auto &[
MI, VL] : DemandedVLs) {
1328 if (!tryReduceVL(*
const_cast<MachineInstr *
>(
MI), VL.VL))
1333 DemandedVLs.clear();
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
const HexagonInstrInfo * TII
static bool isCandidate(const MachineInstr *MI, Register &DefedReg, Register FrameReg)
Register const TargetRegisterInfo * TRI
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
static std::optional< DemandedVL > getMinimumVLForVSLIDEDOWN_VX(const MachineOperand &UserOp, const MachineRegisterInfo *MRI)
Given a vslidedown.vx like:
static unsigned getIntegerExtensionOperandEEW(unsigned Factor, const MachineInstr &MI, const MachineOperand &MO)
Dest has EEW=SEW.
static std::optional< OperandInfo > getOperandInfo(const MachineOperand &MO)
#define VSOXSEG_CASES(EEW)
static bool isSegmentedStoreInstr(const MachineInstr &MI)
static bool isVectorOpUsedAsScalarOp(const MachineOperand &MO)
Return true if MO is a vector operand but is used as a scalar operand.
static std::optional< unsigned > getOperandLog2EEW(const MachineOperand &MO)
static std::pair< unsigned, bool > getEMULEqualsEEWDivSEWTimesLMUL(unsigned Log2EEW, const MachineInstr &MI)
Return EMUL = (EEW / SEW) * LMUL where EEW comes from Log2EEW and LMUL and SEW are from the TSFlags o...
#define VSUXSEG_CASES(EEW)
static bool isPhysical(const MachineOperand &MO)
#define VSSSEG_CASES(EEW)
static bool isTupleInsertInstr(const MachineInstr &MI)
Return true if MI is an instruction used for assembling registers for segmented store instructions,...
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
bool isReachableFromEntry(const NodeT *A) const
isReachableFromEntry - Return true if A is dominated by the entry block of the function containing it...
FunctionPass class - This class is used to implement most global optimizations.
Describe properties that are true of each instruction in the target description file.
This holds information about one operand of a machine instruction, indicating the register class for ...
Analysis pass which computes a MachineDominatorTree.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
bool dominates(const MachineInstr *A, const MachineInstr *B) const
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
LLVM_ABI unsigned getNumExplicitDefs() const
Returns the number of non-implicit definitions.
const MachineOperand & getOperand(unsigned i) const
MachineOperand class - Representation of each machine instruction operand.
LLVM_ABI unsigned getOperandNo() const
Returns the index of this operand in the instruction that it belongs to.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
LLVM_ABI void ChangeToImmediate(int64_t ImmVal, unsigned TargetFlags=0)
ChangeToImmediate - Replace this operand with a new immediate operand of the specified value.
LLVM_ABI void ChangeToRegister(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isDebug=false)
ChangeToRegister - Replace this operand with a new register operand of the specified value.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
static MachineOperand CreateImm(int64_t Val)
Register getReg() const
getReg - Returns the register number.
LLVM_ABI bool isIdenticalTo(const MachineOperand &Other) const
Returns true if this operand is identical to the specified operand except for liveness related flags ...
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
A vector that has set insertion semantics.
void insert_range(Range &&R)
bool empty() const
Determine if the SetVector is empty or not.
bool insert(const value_type &X)
Insert a new element into the SetVector.
value_type pop_back_val()
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
StringRef - Represent a constant reference to a string, i.e.
TargetInstrInfo - Interface to description of machine instruction set.
const uint8_t TSFlags
Configurable target specific flags.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
static bool readsPastVL(uint64_t TSFlags)
static bool isTiedPseudo(uint64_t TSFlags)
static RISCVVType::VLMUL getLMul(uint64_t TSFlags)
static unsigned getVLOpNum(const MCInstrDesc &Desc)
static bool hasVLOp(uint64_t TSFlags)
static unsigned getSEWOpNum(const MCInstrDesc &Desc)
static bool elementsDependOnVL(uint64_t TSFlags)
static bool hasSEWOp(uint64_t TSFlags)
static bool isFirstDefTiedToFirstUse(const MCInstrDesc &Desc)
static unsigned getNF(uint8_t TSFlags)
static bool isVRegClass(uint8_t TSFlags)
static RISCVVType::VLMUL getLMul(uint8_t TSFlags)
LLVM_ABI std::pair< unsigned, bool > decodeVLMUL(VLMUL VLMul)
bool isVLKnownLE(const MachineOperand &LHS, const MachineOperand &RHS)
Given two VL operands, do we know that LHS <= RHS?
unsigned getRVVMCOpcode(unsigned RVVPseudoOpcode)
static constexpr unsigned RVVBitsPerBlock
static constexpr int64_t VLMaxSentinel
NodeAddr< DefNode * > Def
This is an optimization pass for GlobalISel generic memory operations.
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
bool operator!=(uint64_t V1, const APInt &V2)
FunctionPass * createRISCVVLOptimizerPass()
iterator_range< po_iterator< T > > post_order(const T &G)
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.
auto reverse(ContainerTy &&C)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
iterator_range< filter_iterator< detail::IterOfRange< RangeT >, PredicateT > > make_filter_range(RangeT &&Range, PredicateT Pred)
Convenience function that takes a range of elements and a predicate, and return a new filter_iterator...
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
iterator_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)
LLVM_ABI Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.