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;
100 return MO.isReg() && MO.getReg().isVirtual() &&
101 RISCVRegisterInfo::isRVVRegClass(MRI->getRegClass(MO.getReg()));
112 std::optional<std::pair<unsigned, bool>> EMUL;
119 OperandInfo(std::pair<unsigned, bool> EMUL,
unsigned Log2EEW)
120 : EMUL(EMUL), Log2EEW(Log2EEW) {}
122 OperandInfo(
unsigned Log2EEW) : Log2EEW(Log2EEW) {}
124 OperandInfo() =
delete;
128 static bool areCompatible(
const OperandInfo &Def,
const OperandInfo &
User) {
129 if (Def.Log2EEW !=
User.Log2EEW)
131 if (
User.EMUL && Def.EMUL !=
User.EMUL)
143 OS <<
"EMUL: none\n";
144 OS <<
", EEW: " << (1 << Log2EEW);
150char RISCVVLOptimizer::ID = 0;
156 return new RISCVVLOptimizer();
167 const std::optional<OperandInfo> &OI) {
177static std::pair<unsigned, bool>
189 unsigned MISEW = 1 << MILog2SEW;
191 unsigned EEW = 1 << Log2EEW;
194 unsigned Num = EEW, Denom = MISEW;
195 int GCD = MILMULIsFractional ? std::gcd(Num, Denom * MILMUL)
196 : std::gcd(Num * MILMUL, Denom);
197 Num = MILMULIsFractional ? Num / GCD : Num * MILMUL / GCD;
198 Denom = MILMULIsFractional ? Denom * MILMUL / GCD : Denom / GCD;
199 return std::make_pair(Num > Denom ? Num : Denom, Denom > Num);
213 unsigned MISEW = 1 << MILog2SEW;
214 unsigned EEW = MISEW / Factor;
215 unsigned Log2EEW =
Log2_32(EEW);
220#define VSEG_CASES(Prefix, EEW) \
221 RISCV::Prefix##SEG2E##EEW##_V: \
222 case RISCV::Prefix##SEG3E##EEW##_V: \
223 case RISCV::Prefix##SEG4E##EEW##_V: \
224 case RISCV::Prefix##SEG5E##EEW##_V: \
225 case RISCV::Prefix##SEG6E##EEW##_V: \
226 case RISCV::Prefix##SEG7E##EEW##_V: \
227 case RISCV::Prefix##SEG8E##EEW##_V
228#define VSSEG_CASES(EEW) VSEG_CASES(VS, EEW)
229#define VSSSEG_CASES(EEW) VSEG_CASES(VSS, EEW)
230#define VSUXSEG_CASES(EEW) VSEG_CASES(VSUX, I##EEW)
231#define VSOXSEG_CASES(EEW) VSEG_CASES(VSOX, I##EEW)
237 RISCVVPseudosTable::getPseudoInfo(
MI.getOpcode());
238 assert(
RVV &&
"Could not find MI in PseudoTable");
253 Info.RegClass == RISCV::VMV0RegClassID)
258 switch (
RVV->BaseInstr) {
262 case RISCV::VSETIVLI:
284 case RISCV::VLSE16_V:
285 case RISCV::VSSE16_V:
291 case RISCV::VLSE32_V:
292 case RISCV::VSSE32_V:
298 case RISCV::VLSE64_V:
299 case RISCV::VSSE64_V:
307 case RISCV::VLUXEI8_V:
308 case RISCV::VLOXEI8_V:
309 case RISCV::VSUXEI8_V:
310 case RISCV::VSOXEI8_V:
317 case RISCV::VLUXEI16_V:
318 case RISCV::VLOXEI16_V:
319 case RISCV::VSUXEI16_V:
320 case RISCV::VSOXEI16_V:
327 case RISCV::VLUXEI32_V:
328 case RISCV::VLOXEI32_V:
329 case RISCV::VSUXEI32_V:
330 case RISCV::VSOXEI32_V:
337 case RISCV::VLUXEI64_V:
338 case RISCV::VLOXEI64_V:
339 case RISCV::VSUXEI64_V:
340 case RISCV::VSOXEI64_V:
355 case RISCV::VRSUB_VI:
356 case RISCV::VRSUB_VX:
380 case RISCV::VMINU_VV:
381 case RISCV::VMINU_VX:
384 case RISCV::VMAXU_VV:
385 case RISCV::VMAXU_VX:
392 case RISCV::VMULH_VV:
393 case RISCV::VMULH_VX:
394 case RISCV::VMULHU_VV:
395 case RISCV::VMULHU_VX:
396 case RISCV::VMULHSU_VV:
397 case RISCV::VMULHSU_VX:
400 case RISCV::VDIVU_VV:
401 case RISCV::VDIVU_VX:
404 case RISCV::VREMU_VV:
405 case RISCV::VREMU_VX:
410 case RISCV::VMACC_VV:
411 case RISCV::VMACC_VX:
412 case RISCV::VNMSAC_VV:
413 case RISCV::VNMSAC_VX:
414 case RISCV::VMADD_VV:
415 case RISCV::VMADD_VX:
416 case RISCV::VNMSUB_VV:
417 case RISCV::VNMSUB_VX:
422 case RISCV::VMERGE_VIM:
423 case RISCV::VMERGE_VVM:
424 case RISCV::VMERGE_VXM:
425 case RISCV::VADC_VIM:
426 case RISCV::VADC_VVM:
427 case RISCV::VADC_VXM:
428 case RISCV::VSBC_VVM:
429 case RISCV::VSBC_VXM:
438 case RISCV::VSADDU_VI:
439 case RISCV::VSADDU_VV:
440 case RISCV::VSADDU_VX:
441 case RISCV::VSADD_VI:
442 case RISCV::VSADD_VV:
443 case RISCV::VSADD_VX:
444 case RISCV::VSSUBU_VV:
445 case RISCV::VSSUBU_VX:
446 case RISCV::VSSUB_VV:
447 case RISCV::VSSUB_VX:
448 case RISCV::VAADDU_VV:
449 case RISCV::VAADDU_VX:
450 case RISCV::VAADD_VV:
451 case RISCV::VAADD_VX:
452 case RISCV::VASUBU_VV:
453 case RISCV::VASUBU_VX:
454 case RISCV::VASUB_VV:
455 case RISCV::VASUB_VX:
459 case RISCV::VSMUL_VV:
460 case RISCV::VSMUL_VX:
463 case RISCV::VSSRL_VI:
464 case RISCV::VSSRL_VV:
465 case RISCV::VSSRL_VX:
466 case RISCV::VSSRA_VI:
467 case RISCV::VSSRA_VV:
468 case RISCV::VSSRA_VX:
475 case RISCV::VFMV_F_S:
476 case RISCV::VFMV_S_F:
479 case RISCV::VSLIDEUP_VI:
480 case RISCV::VSLIDEUP_VX:
481 case RISCV::VSLIDEDOWN_VI:
482 case RISCV::VSLIDEDOWN_VX:
483 case RISCV::VSLIDE1UP_VX:
484 case RISCV::VFSLIDE1UP_VF:
485 case RISCV::VSLIDE1DOWN_VX:
486 case RISCV::VFSLIDE1DOWN_VF:
489 case RISCV::VRGATHER_VI:
490 case RISCV::VRGATHER_VV:
491 case RISCV::VRGATHER_VX:
495 case RISCV::VFADD_VF:
496 case RISCV::VFADD_VV:
497 case RISCV::VFSUB_VF:
498 case RISCV::VFSUB_VV:
499 case RISCV::VFRSUB_VF:
501 case RISCV::VFMUL_VF:
502 case RISCV::VFMUL_VV:
503 case RISCV::VFDIV_VF:
504 case RISCV::VFDIV_VV:
505 case RISCV::VFRDIV_VF:
507 case RISCV::VFMACC_VV:
508 case RISCV::VFMACC_VF:
509 case RISCV::VFNMACC_VV:
510 case RISCV::VFNMACC_VF:
511 case RISCV::VFMSAC_VV:
512 case RISCV::VFMSAC_VF:
513 case RISCV::VFNMSAC_VV:
514 case RISCV::VFNMSAC_VF:
515 case RISCV::VFMADD_VV:
516 case RISCV::VFMADD_VF:
517 case RISCV::VFNMADD_VV:
518 case RISCV::VFNMADD_VF:
519 case RISCV::VFMSUB_VV:
520 case RISCV::VFMSUB_VF:
521 case RISCV::VFNMSUB_VV:
522 case RISCV::VFNMSUB_VF:
524 case RISCV::VFSQRT_V:
526 case RISCV::VFRSQRT7_V:
528 case RISCV::VFREC7_V:
530 case RISCV::VFMIN_VF:
531 case RISCV::VFMIN_VV:
532 case RISCV::VFMAX_VF:
533 case RISCV::VFMAX_VV:
535 case RISCV::VFSGNJ_VF:
536 case RISCV::VFSGNJ_VV:
537 case RISCV::VFSGNJN_VV:
538 case RISCV::VFSGNJN_VF:
539 case RISCV::VFSGNJX_VF:
540 case RISCV::VFSGNJX_VV:
542 case RISCV::VFCLASS_V:
544 case RISCV::VFMV_V_F:
546 case RISCV::VFCVT_XU_F_V:
547 case RISCV::VFCVT_X_F_V:
548 case RISCV::VFCVT_RTZ_XU_F_V:
549 case RISCV::VFCVT_RTZ_X_F_V:
550 case RISCV::VFCVT_F_XU_V:
551 case RISCV::VFCVT_F_X_V:
553 case RISCV::VFMERGE_VFM:
557 case RISCV::VFIRST_M:
560 case RISCV::VANDN_VV:
561 case RISCV::VANDN_VX:
565 case RISCV::VBREV8_V:
583 case RISCV::VCLMUL_VV:
584 case RISCV::VCLMUL_VX:
586 case RISCV::VCLMULH_VV:
587 case RISCV::VCLMULH_VX:
591 case RISCV::VWSLL_VI:
592 case RISCV::VWSLL_VX:
593 case RISCV::VWSLL_VV:
596 case RISCV::VWADDU_VV:
597 case RISCV::VWADDU_VX:
598 case RISCV::VWSUBU_VV:
599 case RISCV::VWSUBU_VX:
600 case RISCV::VWADD_VV:
601 case RISCV::VWADD_VX:
602 case RISCV::VWSUB_VV:
603 case RISCV::VWSUB_VX:
606 case RISCV::VWMUL_VV:
607 case RISCV::VWMUL_VX:
608 case RISCV::VWMULSU_VV:
609 case RISCV::VWMULSU_VX:
610 case RISCV::VWMULU_VV:
611 case RISCV::VWMULU_VX:
617 case RISCV::VWMACCU_VV:
618 case RISCV::VWMACCU_VX:
619 case RISCV::VWMACC_VV:
620 case RISCV::VWMACC_VX:
621 case RISCV::VWMACCSU_VV:
622 case RISCV::VWMACCSU_VX:
623 case RISCV::VWMACCUS_VX:
625 case RISCV::VFWMACC_VF:
626 case RISCV::VFWMACC_VV:
627 case RISCV::VFWNMACC_VF:
628 case RISCV::VFWNMACC_VV:
629 case RISCV::VFWMSAC_VF:
630 case RISCV::VFWMSAC_VV:
631 case RISCV::VFWNMSAC_VF:
632 case RISCV::VFWNMSAC_VV:
633 case RISCV::VFWMACCBF16_VV:
634 case RISCV::VFWMACCBF16_VF:
637 case RISCV::VFWADD_VV:
638 case RISCV::VFWADD_VF:
639 case RISCV::VFWSUB_VV:
640 case RISCV::VFWSUB_VF:
642 case RISCV::VFWMUL_VF:
643 case RISCV::VFWMUL_VV:
645 case RISCV::VFWCVT_XU_F_V:
646 case RISCV::VFWCVT_X_F_V:
647 case RISCV::VFWCVT_RTZ_XU_F_V:
648 case RISCV::VFWCVT_RTZ_X_F_V:
649 case RISCV::VFWCVT_F_XU_V:
650 case RISCV::VFWCVT_F_X_V:
651 case RISCV::VFWCVT_F_F_V:
652 case RISCV::VFWCVTBF16_F_F_V:
653 return IsMODef ? MILog2SEW + 1 : MILog2SEW;
656 case RISCV::VWADDU_WV:
657 case RISCV::VWADDU_WX:
658 case RISCV::VWSUBU_WV:
659 case RISCV::VWSUBU_WX:
660 case RISCV::VWADD_WV:
661 case RISCV::VWADD_WX:
662 case RISCV::VWSUB_WV:
663 case RISCV::VWSUB_WX:
665 case RISCV::VFWADD_WF:
666 case RISCV::VFWADD_WV:
667 case RISCV::VFWSUB_WF:
668 case RISCV::VFWSUB_WV: {
669 bool IsOp1 = (HasPassthru && !IsTied) ? MO.
getOperandNo() == 2
671 bool TwoTimes = IsMODef || IsOp1;
672 return TwoTimes ? MILog2SEW + 1 : MILog2SEW;
676 case RISCV::VZEXT_VF2:
677 case RISCV::VSEXT_VF2:
679 case RISCV::VZEXT_VF4:
680 case RISCV::VSEXT_VF4:
682 case RISCV::VZEXT_VF8:
683 case RISCV::VSEXT_VF8:
688 case RISCV::VNSRL_WX:
689 case RISCV::VNSRL_WI:
690 case RISCV::VNSRL_WV:
691 case RISCV::VNSRA_WI:
692 case RISCV::VNSRA_WV:
693 case RISCV::VNSRA_WX:
696 case RISCV::VNCLIPU_WI:
697 case RISCV::VNCLIPU_WV:
698 case RISCV::VNCLIPU_WX:
699 case RISCV::VNCLIP_WI:
700 case RISCV::VNCLIP_WV:
701 case RISCV::VNCLIP_WX:
703 case RISCV::VFNCVT_XU_F_W:
704 case RISCV::VFNCVT_X_F_W:
705 case RISCV::VFNCVT_RTZ_XU_F_W:
706 case RISCV::VFNCVT_RTZ_X_F_W:
707 case RISCV::VFNCVT_F_XU_W:
708 case RISCV::VFNCVT_F_X_W:
709 case RISCV::VFNCVT_F_F_W:
710 case RISCV::VFNCVT_ROD_F_F_W:
711 case RISCV::VFNCVTBF16_F_F_W: {
714 bool TwoTimes = IsOp1;
715 return TwoTimes ? MILog2SEW + 1 : MILog2SEW;
727 case RISCV::VMAND_MM:
728 case RISCV::VMNAND_MM:
729 case RISCV::VMANDN_MM:
730 case RISCV::VMXOR_MM:
732 case RISCV::VMNOR_MM:
733 case RISCV::VMORN_MM:
734 case RISCV::VMXNOR_MM:
737 case RISCV::VMSOF_M: {
744 case RISCV::VCOMPRESS_VM:
750 case RISCV::VIOTA_M: {
758 case RISCV::VMSEQ_VI:
759 case RISCV::VMSEQ_VV:
760 case RISCV::VMSEQ_VX:
761 case RISCV::VMSNE_VI:
762 case RISCV::VMSNE_VV:
763 case RISCV::VMSNE_VX:
764 case RISCV::VMSLTU_VV:
765 case RISCV::VMSLTU_VX:
766 case RISCV::VMSLT_VV:
767 case RISCV::VMSLT_VX:
768 case RISCV::VMSLEU_VV:
769 case RISCV::VMSLEU_VI:
770 case RISCV::VMSLEU_VX:
771 case RISCV::VMSLE_VV:
772 case RISCV::VMSLE_VI:
773 case RISCV::VMSLE_VX:
774 case RISCV::VMSGTU_VI:
775 case RISCV::VMSGTU_VX:
776 case RISCV::VMSGT_VI:
777 case RISCV::VMSGT_VX:
780 case RISCV::VMADC_VIM:
781 case RISCV::VMADC_VVM:
782 case RISCV::VMADC_VXM:
783 case RISCV::VMSBC_VVM:
784 case RISCV::VMSBC_VXM:
786 case RISCV::VMADC_VV:
787 case RISCV::VMADC_VI:
788 case RISCV::VMADC_VX:
789 case RISCV::VMSBC_VV:
790 case RISCV::VMSBC_VX:
793 case RISCV::VMFEQ_VF:
794 case RISCV::VMFEQ_VV:
795 case RISCV::VMFNE_VF:
796 case RISCV::VMFNE_VV:
797 case RISCV::VMFLT_VF:
798 case RISCV::VMFLT_VV:
799 case RISCV::VMFLE_VF:
800 case RISCV::VMFLE_VV:
801 case RISCV::VMFGT_VF:
802 case RISCV::VMFGE_VF: {
810 case RISCV::VREDAND_VS:
811 case RISCV::VREDMAX_VS:
812 case RISCV::VREDMAXU_VS:
813 case RISCV::VREDMIN_VS:
814 case RISCV::VREDMINU_VS:
815 case RISCV::VREDOR_VS:
816 case RISCV::VREDSUM_VS:
817 case RISCV::VREDXOR_VS:
819 case RISCV::VFREDMAX_VS:
820 case RISCV::VFREDMIN_VS:
821 case RISCV::VFREDOSUM_VS:
822 case RISCV::VFREDUSUM_VS: {
829 case RISCV::VWREDSUM_VS:
830 case RISCV::VWREDSUMU_VS:
832 case RISCV::VFWREDOSUM_VS:
833 case RISCV::VFWREDUSUM_VS: {
835 return TwoTimes ? MILog2SEW + 1 : MILog2SEW;
840 case RISCV::VRGATHEREI16_VV: {
854 RISCVVPseudosTable::getPseudoInfo(
MI.getOpcode());
855 assert(
RVV &&
"Could not find MI in PseudoTable");
861 switch (
RVV->BaseInstr) {
868 case RISCV::VREDAND_VS:
869 case RISCV::VREDMAX_VS:
870 case RISCV::VREDMAXU_VS:
871 case RISCV::VREDMIN_VS:
872 case RISCV::VREDMINU_VS:
873 case RISCV::VREDOR_VS:
874 case RISCV::VREDSUM_VS:
875 case RISCV::VREDXOR_VS:
876 case RISCV::VWREDSUM_VS:
877 case RISCV::VWREDSUMU_VS:
878 case RISCV::VFWREDOSUM_VS:
879 case RISCV::VFWREDUSUM_VS:
881 return OperandInfo(*Log2EEW);
899 RISCVVPseudosTable::getPseudoInfo(
MI.getOpcode());
904 switch (
RVV->BaseInstr) {
911 case RISCV::VLSE16_V:
913 case RISCV::VLSE32_V:
915 case RISCV::VLSE64_V:
917 case RISCV::VLUXEI8_V:
918 case RISCV::VLOXEI8_V:
919 case RISCV::VLUXEI16_V:
920 case RISCV::VLOXEI16_V:
921 case RISCV::VLUXEI32_V:
922 case RISCV::VLOXEI32_V:
923 case RISCV::VLUXEI64_V:
924 case RISCV::VLOXEI64_V:
931 case RISCV::VRSUB_VI:
932 case RISCV::VRSUB_VX:
954 case RISCV::VWADDU_VV:
955 case RISCV::VWADDU_VX:
956 case RISCV::VWSUBU_VV:
957 case RISCV::VWSUBU_VX:
958 case RISCV::VWADD_VV:
959 case RISCV::VWADD_VX:
960 case RISCV::VWSUB_VV:
961 case RISCV::VWSUB_VX:
962 case RISCV::VWADDU_WV:
963 case RISCV::VWADDU_WX:
964 case RISCV::VWSUBU_WV:
965 case RISCV::VWSUBU_WX:
966 case RISCV::VWADD_WV:
967 case RISCV::VWADD_WX:
968 case RISCV::VWSUB_WV:
969 case RISCV::VWSUB_WX:
971 case RISCV::VZEXT_VF2:
972 case RISCV::VSEXT_VF2:
973 case RISCV::VZEXT_VF4:
974 case RISCV::VSEXT_VF4:
975 case RISCV::VZEXT_VF8:
976 case RISCV::VSEXT_VF8:
978 case RISCV::VNSRL_WX:
979 case RISCV::VNSRL_WI:
980 case RISCV::VNSRL_WV:
981 case RISCV::VNSRA_WI:
982 case RISCV::VNSRA_WV:
983 case RISCV::VNSRA_WX:
985 case RISCV::VMSEQ_VI:
986 case RISCV::VMSEQ_VV:
987 case RISCV::VMSEQ_VX:
988 case RISCV::VMSNE_VI:
989 case RISCV::VMSNE_VV:
990 case RISCV::VMSNE_VX:
991 case RISCV::VMSLTU_VV:
992 case RISCV::VMSLTU_VX:
993 case RISCV::VMSLT_VV:
994 case RISCV::VMSLT_VX:
995 case RISCV::VMSLEU_VV:
996 case RISCV::VMSLEU_VI:
997 case RISCV::VMSLEU_VX:
998 case RISCV::VMSLE_VV:
999 case RISCV::VMSLE_VI:
1000 case RISCV::VMSLE_VX:
1001 case RISCV::VMSGTU_VI:
1002 case RISCV::VMSGTU_VX:
1003 case RISCV::VMSGT_VI:
1004 case RISCV::VMSGT_VX:
1006 case RISCV::VMINU_VV:
1007 case RISCV::VMINU_VX:
1008 case RISCV::VMIN_VV:
1009 case RISCV::VMIN_VX:
1010 case RISCV::VMAXU_VV:
1011 case RISCV::VMAXU_VX:
1012 case RISCV::VMAX_VV:
1013 case RISCV::VMAX_VX:
1015 case RISCV::VMUL_VV:
1016 case RISCV::VMUL_VX:
1017 case RISCV::VMULH_VV:
1018 case RISCV::VMULH_VX:
1019 case RISCV::VMULHU_VV:
1020 case RISCV::VMULHU_VX:
1021 case RISCV::VMULHSU_VV:
1022 case RISCV::VMULHSU_VX:
1024 case RISCV::VDIVU_VV:
1025 case RISCV::VDIVU_VX:
1026 case RISCV::VDIV_VV:
1027 case RISCV::VDIV_VX:
1028 case RISCV::VREMU_VV:
1029 case RISCV::VREMU_VX:
1030 case RISCV::VREM_VV:
1031 case RISCV::VREM_VX:
1033 case RISCV::VWMUL_VV:
1034 case RISCV::VWMUL_VX:
1035 case RISCV::VWMULSU_VV:
1036 case RISCV::VWMULSU_VX:
1037 case RISCV::VWMULU_VV:
1038 case RISCV::VWMULU_VX:
1040 case RISCV::VMACC_VV:
1041 case RISCV::VMACC_VX:
1042 case RISCV::VNMSAC_VV:
1043 case RISCV::VNMSAC_VX:
1044 case RISCV::VMADD_VV:
1045 case RISCV::VMADD_VX:
1046 case RISCV::VNMSUB_VV:
1047 case RISCV::VNMSUB_VX:
1049 case RISCV::VMERGE_VIM:
1050 case RISCV::VMERGE_VVM:
1051 case RISCV::VMERGE_VXM:
1053 case RISCV::VADC_VIM:
1054 case RISCV::VADC_VVM:
1055 case RISCV::VADC_VXM:
1056 case RISCV::VMADC_VIM:
1057 case RISCV::VMADC_VVM:
1058 case RISCV::VMADC_VXM:
1059 case RISCV::VSBC_VVM:
1060 case RISCV::VSBC_VXM:
1061 case RISCV::VMSBC_VVM:
1062 case RISCV::VMSBC_VXM:
1063 case RISCV::VMADC_VV:
1064 case RISCV::VMADC_VI:
1065 case RISCV::VMADC_VX:
1066 case RISCV::VMSBC_VV:
1067 case RISCV::VMSBC_VX:
1069 case RISCV::VWMACCU_VV:
1070 case RISCV::VWMACCU_VX:
1071 case RISCV::VWMACC_VV:
1072 case RISCV::VWMACC_VX:
1073 case RISCV::VWMACCSU_VV:
1074 case RISCV::VWMACCSU_VX:
1075 case RISCV::VWMACCUS_VX:
1077 case RISCV::VMV_V_I:
1078 case RISCV::VMV_V_X:
1079 case RISCV::VMV_V_V:
1081 case RISCV::VSADDU_VV:
1082 case RISCV::VSADDU_VX:
1083 case RISCV::VSADDU_VI:
1084 case RISCV::VSADD_VV:
1085 case RISCV::VSADD_VX:
1086 case RISCV::VSADD_VI:
1087 case RISCV::VSSUBU_VV:
1088 case RISCV::VSSUBU_VX:
1089 case RISCV::VSSUB_VV:
1090 case RISCV::VSSUB_VX:
1092 case RISCV::VAADDU_VV:
1093 case RISCV::VAADDU_VX:
1094 case RISCV::VAADD_VV:
1095 case RISCV::VAADD_VX:
1096 case RISCV::VASUBU_VV:
1097 case RISCV::VASUBU_VX:
1098 case RISCV::VASUB_VV:
1099 case RISCV::VASUB_VX:
1101 case RISCV::VSMUL_VV:
1102 case RISCV::VSMUL_VX:
1104 case RISCV::VSSRL_VV:
1105 case RISCV::VSSRL_VX:
1106 case RISCV::VSSRL_VI:
1107 case RISCV::VSSRA_VV:
1108 case RISCV::VSSRA_VX:
1109 case RISCV::VSSRA_VI:
1111 case RISCV::VNCLIPU_WV:
1112 case RISCV::VNCLIPU_WX:
1113 case RISCV::VNCLIPU_WI:
1114 case RISCV::VNCLIP_WV:
1115 case RISCV::VNCLIP_WX:
1116 case RISCV::VNCLIP_WI:
1119 case RISCV::VANDN_VV:
1120 case RISCV::VANDN_VX:
1122 case RISCV::VBREV_V:
1124 case RISCV::VBREV8_V:
1126 case RISCV::VREV8_V:
1132 case RISCV::VCPOP_V:
1134 case RISCV::VROL_VV:
1135 case RISCV::VROL_VX:
1137 case RISCV::VROR_VI:
1138 case RISCV::VROR_VV:
1139 case RISCV::VROR_VX:
1141 case RISCV::VWSLL_VI:
1142 case RISCV::VWSLL_VX:
1143 case RISCV::VWSLL_VV:
1146 case RISCV::VCLMUL_VV:
1147 case RISCV::VCLMUL_VX:
1149 case RISCV::VCLMULH_VV:
1150 case RISCV::VCLMULH_VX:
1158 case RISCV::VMAND_MM:
1159 case RISCV::VMNAND_MM:
1160 case RISCV::VMANDN_MM:
1161 case RISCV::VMXOR_MM:
1162 case RISCV::VMOR_MM:
1163 case RISCV::VMNOR_MM:
1164 case RISCV::VMORN_MM:
1165 case RISCV::VMXNOR_MM:
1166 case RISCV::VMSBF_M:
1167 case RISCV::VMSIF_M:
1168 case RISCV::VMSOF_M:
1169 case RISCV::VIOTA_M:
1172 case RISCV::VSLIDEUP_VX:
1173 case RISCV::VSLIDEUP_VI:
1174 case RISCV::VSLIDEDOWN_VX:
1175 case RISCV::VSLIDEDOWN_VI:
1176 case RISCV::VSLIDE1UP_VX:
1177 case RISCV::VFSLIDE1UP_VF:
1179 case RISCV::VRGATHER_VI:
1180 case RISCV::VRGATHER_VV:
1181 case RISCV::VRGATHER_VX:
1182 case RISCV::VRGATHEREI16_VV:
1184 case RISCV::VFADD_VF:
1185 case RISCV::VFADD_VV:
1186 case RISCV::VFSUB_VF:
1187 case RISCV::VFSUB_VV:
1188 case RISCV::VFRSUB_VF:
1190 case RISCV::VFWADD_VV:
1191 case RISCV::VFWADD_VF:
1192 case RISCV::VFWSUB_VV:
1193 case RISCV::VFWSUB_VF:
1194 case RISCV::VFWADD_WF:
1195 case RISCV::VFWADD_WV:
1196 case RISCV::VFWSUB_WF:
1197 case RISCV::VFWSUB_WV:
1199 case RISCV::VFMUL_VF:
1200 case RISCV::VFMUL_VV:
1201 case RISCV::VFDIV_VF:
1202 case RISCV::VFDIV_VV:
1203 case RISCV::VFRDIV_VF:
1205 case RISCV::VFWMUL_VF:
1206 case RISCV::VFWMUL_VV:
1208 case RISCV::VFMACC_VV:
1209 case RISCV::VFMACC_VF:
1210 case RISCV::VFNMACC_VV:
1211 case RISCV::VFNMACC_VF:
1212 case RISCV::VFMSAC_VV:
1213 case RISCV::VFMSAC_VF:
1214 case RISCV::VFNMSAC_VV:
1215 case RISCV::VFNMSAC_VF:
1216 case RISCV::VFMADD_VV:
1217 case RISCV::VFMADD_VF:
1218 case RISCV::VFNMADD_VV:
1219 case RISCV::VFNMADD_VF:
1220 case RISCV::VFMSUB_VV:
1221 case RISCV::VFMSUB_VF:
1222 case RISCV::VFNMSUB_VV:
1223 case RISCV::VFNMSUB_VF:
1225 case RISCV::VFWMACC_VV:
1226 case RISCV::VFWMACC_VF:
1227 case RISCV::VFWNMACC_VV:
1228 case RISCV::VFWNMACC_VF:
1229 case RISCV::VFWMSAC_VV:
1230 case RISCV::VFWMSAC_VF:
1231 case RISCV::VFWNMSAC_VV:
1232 case RISCV::VFWNMSAC_VF:
1233 case RISCV::VFWMACCBF16_VV:
1234 case RISCV::VFWMACCBF16_VF:
1236 case RISCV::VFSQRT_V:
1238 case RISCV::VFRSQRT7_V:
1240 case RISCV::VFREC7_V:
1242 case RISCV::VFMIN_VF:
1243 case RISCV::VFMIN_VV:
1244 case RISCV::VFMAX_VF:
1245 case RISCV::VFMAX_VV:
1247 case RISCV::VFSGNJ_VF:
1248 case RISCV::VFSGNJ_VV:
1249 case RISCV::VFSGNJN_VV:
1250 case RISCV::VFSGNJN_VF:
1251 case RISCV::VFSGNJX_VF:
1252 case RISCV::VFSGNJX_VV:
1254 case RISCV::VMFEQ_VF:
1255 case RISCV::VMFEQ_VV:
1256 case RISCV::VMFNE_VF:
1257 case RISCV::VMFNE_VV:
1258 case RISCV::VMFLT_VF:
1259 case RISCV::VMFLT_VV:
1260 case RISCV::VMFLE_VF:
1261 case RISCV::VMFLE_VV:
1262 case RISCV::VMFGT_VF:
1263 case RISCV::VMFGE_VF:
1265 case RISCV::VFCLASS_V:
1267 case RISCV::VFMERGE_VFM:
1269 case RISCV::VFMV_V_F:
1271 case RISCV::VFCVT_XU_F_V:
1272 case RISCV::VFCVT_X_F_V:
1273 case RISCV::VFCVT_RTZ_XU_F_V:
1274 case RISCV::VFCVT_RTZ_X_F_V:
1275 case RISCV::VFCVT_F_XU_V:
1276 case RISCV::VFCVT_F_X_V:
1278 case RISCV::VFWCVT_XU_F_V:
1279 case RISCV::VFWCVT_X_F_V:
1280 case RISCV::VFWCVT_RTZ_XU_F_V:
1281 case RISCV::VFWCVT_RTZ_X_F_V:
1282 case RISCV::VFWCVT_F_XU_V:
1283 case RISCV::VFWCVT_F_X_V:
1284 case RISCV::VFWCVT_F_F_V:
1285 case RISCV::VFWCVTBF16_F_F_V:
1287 case RISCV::VFNCVT_XU_F_W:
1288 case RISCV::VFNCVT_X_F_W:
1289 case RISCV::VFNCVT_RTZ_XU_F_W:
1290 case RISCV::VFNCVT_RTZ_X_F_W:
1291 case RISCV::VFNCVT_F_XU_W:
1292 case RISCV::VFNCVT_F_X_W:
1293 case RISCV::VFNCVT_F_F_W:
1294 case RISCV::VFNCVT_ROD_F_F_W:
1295 case RISCV::VFNCVTBF16_F_F_W:
1306 RISCVVPseudosTable::getPseudoInfo(
MI->getOpcode());
1311 switch (
RVV->BaseInstr) {
1313 case RISCV::VREDAND_VS:
1314 case RISCV::VREDMAX_VS:
1315 case RISCV::VREDMAXU_VS:
1316 case RISCV::VREDMIN_VS:
1317 case RISCV::VREDMINU_VS:
1318 case RISCV::VREDOR_VS:
1319 case RISCV::VREDSUM_VS:
1320 case RISCV::VREDXOR_VS:
1321 case RISCV::VWREDSUM_VS:
1322 case RISCV::VWREDSUMU_VS:
1323 case RISCV::VFREDMAX_VS:
1324 case RISCV::VFREDMIN_VS:
1325 case RISCV::VFREDOSUM_VS:
1326 case RISCV::VFREDUSUM_VS:
1327 case RISCV::VFWREDOSUM_VS:
1328 case RISCV::VFWREDUSUM_VS:
1330 case RISCV::VMV_X_S:
1331 case RISCV::VFMV_F_S:
1338bool RISCVVLOptimizer::isCandidate(
const MachineInstr &
MI)
const {
1339 const MCInstrDesc &
Desc =
MI.getDesc();
1343 if (
MI.getNumExplicitDefs() != 1)
1348 if (!
MI.allImplicitDefsAreDead()) {
1349 LLVM_DEBUG(
dbgs() <<
"Not a candidate because has non-dead implicit def\n");
1353 if (
MI.mayRaiseFPException()) {
1354 LLVM_DEBUG(
dbgs() <<
"Not a candidate because may raise FP exception\n");
1358 for (
const MachineMemOperand *MMO :
MI.memoperands()) {
1359 if (MMO->isVolatile()) {
1360 LLVM_DEBUG(
dbgs() <<
"Not a candidate because contains volatile MMO\n");
1378 LLVM_DEBUG(
dbgs() <<
"Not a candidate due to unsupported instruction: "
1385 "Instruction shouldn't be supported if elements depend on VL");
1388 MRI->getRegClass(
MI.getOperand(0).getReg())->TSFlags) &&
1389 "All supported instructions produce a vector register result");
1391 LLVM_DEBUG(
dbgs() <<
"Found a candidate for VL reduction: " <<
MI <<
"\n");
1396RISCVVLOptimizer::getMinimumVLForUser(
const MachineOperand &UserOp)
const {
1397 const MachineInstr &UserMI = *UserOp.
getParent();
1401 return DemandedVLs.lookup(&UserMI);
1406 return DemandedVL::vlmax();
1411 LLVM_DEBUG(
dbgs() <<
" Abort because used by unsafe instruction\n");
1412 return DemandedVL::vlmax();
1416 const MachineOperand &VLOp = UserMI.
getOperand(VLOpNum);
1419 "Did not expect X0 VL");
1428 "instruction with demanded tail\n");
1429 return DemandedVL::vlmax();
1436 LLVM_DEBUG(
dbgs() <<
" Used this operand as a scalar operand\n");
1443 return DemandedVLs.lookup(&UserMI);
1452 if (!
MI.isInsertSubreg())
1466 unsigned SubRegIdx =
MI.getOperand(3).getImm();
1468 assert(!IsFractional &&
"unexpected LMUL for tuple register classes");
1496bool RISCVVLOptimizer::checkUsers(
const MachineInstr &
MI)
const {
1500 SmallSetVector<MachineOperand *, 8> OpWorklist;
1501 SmallPtrSet<const MachineInstr *, 4> PHISeen;
1502 for (
auto &UserOp :
MRI->use_operands(
MI.getOperand(0).getReg()))
1503 OpWorklist.
insert(&UserOp);
1505 while (!OpWorklist.
empty()) {
1507 const MachineInstr &UserMI = *UserOp.
getParent();
1518 LLVM_DEBUG(
dbgs().indent(4) <<
"Peeking through uses of INSERT_SUBREG\n");
1519 for (MachineOperand &UseOp :
1521 const MachineInstr &CandidateMI = *UseOp.getParent();
1529 OpWorklist.
insert(&UseOp);
1534 if (UserMI.
isPHI()) {
1536 if (!PHISeen.
insert(&UserMI).second)
1549 std::optional<OperandInfo> ConsumerInfo =
getOperandInfo(UserOp);
1550 std::optional<OperandInfo> ProducerInfo =
getOperandInfo(
MI.getOperand(0));
1551 if (!ConsumerInfo || !ProducerInfo) {
1552 LLVM_DEBUG(
dbgs() <<
" Abort due to unknown operand information.\n");
1553 LLVM_DEBUG(
dbgs() <<
" ConsumerInfo is: " << ConsumerInfo <<
"\n");
1554 LLVM_DEBUG(
dbgs() <<
" ProducerInfo is: " << ProducerInfo <<
"\n");
1558 if (!OperandInfo::areCompatible(*ProducerInfo, *ConsumerInfo)) {
1561 <<
" Abort due to incompatible information for EMUL or EEW.\n");
1562 LLVM_DEBUG(
dbgs() <<
" ConsumerInfo is: " << ConsumerInfo <<
"\n");
1563 LLVM_DEBUG(
dbgs() <<
" ProducerInfo is: " << ProducerInfo <<
"\n");
1571bool RISCVVLOptimizer::tryReduceVL(MachineInstr &
MI)
const {
1575 MachineOperand &VLOp =
MI.getOperand(VLOpNum);
1580 LLVM_DEBUG(
dbgs() <<
" Abort due to VL == 1, no point in reducing.\n");
1584 auto *CommonVL = &DemandedVLs.at(&
MI).VL;
1586 assert((CommonVL->isImm() || CommonVL->getReg().isVirtual()) &&
1587 "Expected VL to be an Imm or virtual Reg");
1591 if (CommonVL->isReg()) {
1592 const MachineInstr *VLMI =
MRI->getVRegDef(CommonVL->getReg());
1593 if (RISCVInstrInfo::isFaultOnlyFirstLoad(*VLMI) &&
1603 if (CommonVL->isIdenticalTo(VLOp)) {
1605 dbgs() <<
" Abort due to CommonVL == VLOp, no point in reducing.\n");
1609 if (CommonVL->isImm()) {
1611 << CommonVL->getImm() <<
" for " <<
MI <<
"\n");
1615 const MachineInstr *VLMI =
MRI->getVRegDef(CommonVL->getReg());
1621 dbgs() <<
" Reduce VL from " << VLOp <<
" to "
1622 <<
printReg(CommonVL->getReg(),
MRI->getTargetRegisterInfo())
1623 <<
" for " <<
MI <<
"\n");
1635void RISCVVLOptimizer::transfer(
const MachineInstr &
MI) {
1637 DemandedVLs[&
MI] = DemandedVL::vlmax();
1639 for (
const MachineOperand &MO : virtual_vec_uses(
MI)) {
1640 const MachineInstr *
Def =
MRI->getVRegDef(MO.getReg());
1641 DemandedVL Prev = DemandedVLs[
Def];
1642 DemandedVLs[
Def] = DemandedVLs[
Def].max(getMinimumVLForUser(MO));
1643 if (DemandedVLs[Def] != Prev)
1644 Worklist.insert(Def);
1648bool RISCVVLOptimizer::runOnMachineFunction(MachineFunction &MF) {
1653 MDT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
1656 if (!
ST.hasVInstructions())
1659 TII =
ST.getInstrInfo();
1661 assert(DemandedVLs.empty());
1668 if (!
MI.isDebugInstr())
1669 Worklist.insert(&
MI);
1672 while (!Worklist.empty()) {
1673 const MachineInstr *
MI = Worklist.front();
1674 Worklist.remove(
MI);
1680 bool MadeChange =
false;
1681 for (MachineBasicBlock &
MBB : MF) {
1689 if (!tryReduceVL(
MI))
1695 DemandedVLs.clear();
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Analysis containing CSE Info
#define LLVM_ATTRIBUTE_UNUSED
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 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)
static bool isSupportedInstr(const MachineInstr &MI)
Return true if this optimization should consider MI for VL reduction.
#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.