28#define DEBUG_TYPE "riscv-vl-optimizer"
29#define PASS_NAME "RISC-V VL Optimizer"
53 std::optional<MachineOperand> getMinimumVLForUser(
MachineOperand &UserOp);
63char RISCVVLOptimizer::ID = 0;
69 return new RISCVVLOptimizer();
75 return RISCV::VRRegClass.contains(R);
85 std::optional<std::pair<unsigned, bool>>
EMUL;
100 return A.Log2EEW ==
B.Log2EEW &&
A.EMUL->first ==
B.EMUL->first &&
101 A.EMUL->second ==
B.EMUL->second;
105 return A.Log2EEW ==
B.Log2EEW;
115 OS <<
"EMUL: unknown\n";
128 const std::optional<OperandInfo> &OI) {
137namespace RISCVVType {
140static std::pair<unsigned, bool>
152 unsigned MISEW = 1 << MILog2SEW;
154 unsigned EEW = 1 << Log2EEW;
157 unsigned Num = EEW, Denom = MISEW;
158 int GCD = MILMULIsFractional ? std::gcd(Num, Denom * MILMUL)
159 : std::gcd(Num * MILMUL, Denom);
160 Num = MILMULIsFractional ? Num / GCD : Num * MILMUL / GCD;
161 Denom = MILMULIsFractional ? Denom * MILMUL / GCD : Denom / GCD;
162 return std::make_pair(Num > Denom ? Num : Denom, Denom > Num);
178 unsigned MISEW = 1 << MILog2SEW;
179 unsigned EEW = MISEW / Factor;
180 unsigned Log2EEW =
Log2_32(EEW);
193 return Desc.operands()[MO.
getOperandNo()].RegClass == RISCV::VMV0RegClassID;
196static std::optional<unsigned>
200 RISCVVPseudosTable::getPseudoInfo(
MI.getOpcode());
201 assert(
RVV &&
"Could not find MI in PseudoTable");
213 if (HasPassthru && MO.
getOperandNo() ==
MI.getNumExplicitDefs() &&
214 (MO.
getReg() != RISCV::NoRegister))
225 switch (
RVV->BaseInstr) {
229 case RISCV::VSETIVLI:
249 case RISCV::VLSE16_V:
250 case RISCV::VSSE16_V:
254 case RISCV::VLSE32_V:
255 case RISCV::VSSE32_V:
259 case RISCV::VLSE64_V:
260 case RISCV::VSSE64_V:
266 case RISCV::VLUXEI8_V:
267 case RISCV::VLOXEI8_V:
268 case RISCV::VSUXEI8_V:
269 case RISCV::VSOXEI8_V: {
274 case RISCV::VLUXEI16_V:
275 case RISCV::VLOXEI16_V:
276 case RISCV::VSUXEI16_V:
277 case RISCV::VSOXEI16_V: {
282 case RISCV::VLUXEI32_V:
283 case RISCV::VLOXEI32_V:
284 case RISCV::VSUXEI32_V:
285 case RISCV::VSOXEI32_V: {
290 case RISCV::VLUXEI64_V:
291 case RISCV::VLOXEI64_V:
292 case RISCV::VSUXEI64_V:
293 case RISCV::VSOXEI64_V: {
306 case RISCV::VRSUB_VI:
307 case RISCV::VRSUB_VX:
331 case RISCV::VMINU_VV:
332 case RISCV::VMINU_VX:
335 case RISCV::VMAXU_VV:
336 case RISCV::VMAXU_VX:
343 case RISCV::VMULH_VV:
344 case RISCV::VMULH_VX:
345 case RISCV::VMULHU_VV:
346 case RISCV::VMULHU_VX:
347 case RISCV::VMULHSU_VV:
348 case RISCV::VMULHSU_VX:
351 case RISCV::VDIVU_VV:
352 case RISCV::VDIVU_VX:
355 case RISCV::VREMU_VV:
356 case RISCV::VREMU_VX:
361 case RISCV::VMACC_VV:
362 case RISCV::VMACC_VX:
363 case RISCV::VNMSAC_VV:
364 case RISCV::VNMSAC_VX:
365 case RISCV::VMADD_VV:
366 case RISCV::VMADD_VX:
367 case RISCV::VNMSUB_VV:
368 case RISCV::VNMSUB_VX:
373 case RISCV::VMERGE_VIM:
374 case RISCV::VMERGE_VVM:
375 case RISCV::VMERGE_VXM:
376 case RISCV::VADC_VIM:
377 case RISCV::VADC_VVM:
378 case RISCV::VADC_VXM:
379 case RISCV::VSBC_VVM:
380 case RISCV::VSBC_VXM:
389 case RISCV::VSADDU_VI:
390 case RISCV::VSADDU_VV:
391 case RISCV::VSADDU_VX:
392 case RISCV::VSADD_VI:
393 case RISCV::VSADD_VV:
394 case RISCV::VSADD_VX:
395 case RISCV::VSSUBU_VV:
396 case RISCV::VSSUBU_VX:
397 case RISCV::VSSUB_VV:
398 case RISCV::VSSUB_VX:
399 case RISCV::VAADDU_VV:
400 case RISCV::VAADDU_VX:
401 case RISCV::VAADD_VV:
402 case RISCV::VAADD_VX:
403 case RISCV::VASUBU_VV:
404 case RISCV::VASUBU_VX:
405 case RISCV::VASUB_VV:
406 case RISCV::VASUB_VX:
410 case RISCV::VSMUL_VV:
411 case RISCV::VSMUL_VX:
414 case RISCV::VSSRL_VI:
415 case RISCV::VSSRL_VV:
416 case RISCV::VSSRL_VX:
417 case RISCV::VSSRA_VI:
418 case RISCV::VSSRA_VV:
419 case RISCV::VSSRA_VX:
426 case RISCV::VFMV_F_S:
427 case RISCV::VFMV_S_F:
430 case RISCV::VSLIDEUP_VI:
431 case RISCV::VSLIDEUP_VX:
432 case RISCV::VSLIDEDOWN_VI:
433 case RISCV::VSLIDEDOWN_VX:
434 case RISCV::VSLIDE1UP_VX:
435 case RISCV::VFSLIDE1UP_VF:
436 case RISCV::VSLIDE1DOWN_VX:
437 case RISCV::VFSLIDE1DOWN_VF:
440 case RISCV::VRGATHER_VI:
441 case RISCV::VRGATHER_VV:
442 case RISCV::VRGATHER_VX:
445 case RISCV::VCOMPRESS_VM:
449 case RISCV::VFADD_VF:
450 case RISCV::VFADD_VV:
451 case RISCV::VFSUB_VF:
452 case RISCV::VFSUB_VV:
453 case RISCV::VFRSUB_VF:
455 case RISCV::VFMUL_VF:
456 case RISCV::VFMUL_VV:
457 case RISCV::VFDIV_VF:
458 case RISCV::VFDIV_VV:
459 case RISCV::VFRDIV_VF:
461 case RISCV::VFSQRT_V:
463 case RISCV::VFRSQRT7_V:
465 case RISCV::VFREC7_V:
467 case RISCV::VFMIN_VF:
468 case RISCV::VFMIN_VV:
469 case RISCV::VFMAX_VF:
470 case RISCV::VFMAX_VV:
472 case RISCV::VFSGNJ_VF:
473 case RISCV::VFSGNJ_VV:
474 case RISCV::VFSGNJN_VV:
475 case RISCV::VFSGNJN_VF:
476 case RISCV::VFSGNJX_VF:
477 case RISCV::VFSGNJX_VV:
479 case RISCV::VFCLASS_V:
481 case RISCV::VFMV_V_F:
483 case RISCV::VFCVT_XU_F_V:
484 case RISCV::VFCVT_X_F_V:
485 case RISCV::VFCVT_RTZ_XU_F_V:
486 case RISCV::VFCVT_RTZ_X_F_V:
487 case RISCV::VFCVT_F_XU_V:
488 case RISCV::VFCVT_F_X_V:
490 case RISCV::VFMERGE_VFM:
494 case RISCV::VFIRST_M:
499 case RISCV::VWADDU_VV:
500 case RISCV::VWADDU_VX:
501 case RISCV::VWSUBU_VV:
502 case RISCV::VWSUBU_VX:
503 case RISCV::VWADD_VV:
504 case RISCV::VWADD_VX:
505 case RISCV::VWSUB_VV:
506 case RISCV::VWSUB_VX:
507 case RISCV::VWSLL_VI:
510 case RISCV::VWMUL_VV:
511 case RISCV::VWMUL_VX:
512 case RISCV::VWMULSU_VV:
513 case RISCV::VWMULSU_VX:
514 case RISCV::VWMULU_VV:
515 case RISCV::VWMULU_VX:
521 case RISCV::VWMACCU_VV:
522 case RISCV::VWMACCU_VX:
523 case RISCV::VWMACC_VV:
524 case RISCV::VWMACC_VX:
525 case RISCV::VWMACCSU_VV:
526 case RISCV::VWMACCSU_VX:
527 case RISCV::VWMACCUS_VX:
529 case RISCV::VFWMACC_VF:
530 case RISCV::VFWMACC_VV:
531 case RISCV::VFWNMACC_VF:
532 case RISCV::VFWNMACC_VV:
533 case RISCV::VFWMSAC_VF:
534 case RISCV::VFWMSAC_VV:
535 case RISCV::VFWNMSAC_VF:
536 case RISCV::VFWNMSAC_VV:
539 case RISCV::VFWADD_VV:
540 case RISCV::VFWADD_VF:
541 case RISCV::VFWSUB_VV:
542 case RISCV::VFWSUB_VF:
544 case RISCV::VFWMUL_VF:
545 case RISCV::VFWMUL_VV:
547 case RISCV::VFWCVT_XU_F_V:
548 case RISCV::VFWCVT_X_F_V:
549 case RISCV::VFWCVT_RTZ_XU_F_V:
550 case RISCV::VFWCVT_RTZ_X_F_V:
551 case RISCV::VFWCVT_F_XU_V:
552 case RISCV::VFWCVT_F_X_V:
553 case RISCV::VFWCVT_F_F_V:
554 case RISCV::VFWCVTBF16_F_F_V:
555 return IsMODef ? MILog2SEW + 1 : MILog2SEW;
558 case RISCV::VWADDU_WV:
559 case RISCV::VWADDU_WX:
560 case RISCV::VWSUBU_WV:
561 case RISCV::VWSUBU_WX:
562 case RISCV::VWADD_WV:
563 case RISCV::VWADD_WX:
564 case RISCV::VWSUB_WV:
565 case RISCV::VWSUB_WX:
567 case RISCV::VFWADD_WF:
568 case RISCV::VFWADD_WV:
569 case RISCV::VFWSUB_WF:
570 case RISCV::VFWSUB_WV: {
572 bool TwoTimes = IsMODef || IsOp1;
573 return TwoTimes ? MILog2SEW + 1 : MILog2SEW;
577 case RISCV::VZEXT_VF2:
578 case RISCV::VSEXT_VF2:
580 case RISCV::VZEXT_VF4:
581 case RISCV::VSEXT_VF4:
583 case RISCV::VZEXT_VF8:
584 case RISCV::VSEXT_VF8:
589 case RISCV::VNSRL_WX:
590 case RISCV::VNSRL_WI:
591 case RISCV::VNSRL_WV:
592 case RISCV::VNSRA_WI:
593 case RISCV::VNSRA_WV:
594 case RISCV::VNSRA_WX:
597 case RISCV::VNCLIPU_WI:
598 case RISCV::VNCLIPU_WV:
599 case RISCV::VNCLIPU_WX:
600 case RISCV::VNCLIP_WI:
601 case RISCV::VNCLIP_WV:
602 case RISCV::VNCLIP_WX:
604 case RISCV::VFNCVT_XU_F_W:
605 case RISCV::VFNCVT_X_F_W:
606 case RISCV::VFNCVT_RTZ_XU_F_W:
607 case RISCV::VFNCVT_RTZ_X_F_W:
608 case RISCV::VFNCVT_F_XU_W:
609 case RISCV::VFNCVT_F_X_W:
610 case RISCV::VFNCVT_F_F_W:
611 case RISCV::VFNCVT_ROD_F_F_W:
612 case RISCV::VFNCVTBF16_F_F_W: {
614 bool TwoTimes = IsOp1;
615 return TwoTimes ? MILog2SEW + 1 : MILog2SEW;
627 case RISCV::VMAND_MM:
628 case RISCV::VMNAND_MM:
629 case RISCV::VMANDN_MM:
630 case RISCV::VMXOR_MM:
632 case RISCV::VMNOR_MM:
633 case RISCV::VMORN_MM:
634 case RISCV::VMXNOR_MM:
637 case RISCV::VMSOF_M: {
644 case RISCV::VIOTA_M: {
652 case RISCV::VMSEQ_VI:
653 case RISCV::VMSEQ_VV:
654 case RISCV::VMSEQ_VX:
655 case RISCV::VMSNE_VI:
656 case RISCV::VMSNE_VV:
657 case RISCV::VMSNE_VX:
658 case RISCV::VMSLTU_VV:
659 case RISCV::VMSLTU_VX:
660 case RISCV::VMSLT_VV:
661 case RISCV::VMSLT_VX:
662 case RISCV::VMSLEU_VV:
663 case RISCV::VMSLEU_VI:
664 case RISCV::VMSLEU_VX:
665 case RISCV::VMSLE_VV:
666 case RISCV::VMSLE_VI:
667 case RISCV::VMSLE_VX:
668 case RISCV::VMSGTU_VI:
669 case RISCV::VMSGTU_VX:
670 case RISCV::VMSGT_VI:
671 case RISCV::VMSGT_VX:
674 case RISCV::VMADC_VIM:
675 case RISCV::VMADC_VVM:
676 case RISCV::VMADC_VXM:
677 case RISCV::VMSBC_VVM:
678 case RISCV::VMSBC_VXM:
680 case RISCV::VMADC_VV:
681 case RISCV::VMADC_VI:
682 case RISCV::VMADC_VX:
683 case RISCV::VMSBC_VV:
684 case RISCV::VMSBC_VX:
687 case RISCV::VMFEQ_VF:
688 case RISCV::VMFEQ_VV:
689 case RISCV::VMFNE_VF:
690 case RISCV::VMFNE_VV:
691 case RISCV::VMFLT_VF:
692 case RISCV::VMFLT_VV:
693 case RISCV::VMFLE_VF:
694 case RISCV::VMFLE_VV:
695 case RISCV::VMFGT_VF:
696 case RISCV::VMFGE_VF: {
704 case RISCV::VREDAND_VS:
705 case RISCV::VREDMAX_VS:
706 case RISCV::VREDMAXU_VS:
707 case RISCV::VREDMIN_VS:
708 case RISCV::VREDMINU_VS:
709 case RISCV::VREDOR_VS:
710 case RISCV::VREDSUM_VS:
711 case RISCV::VREDXOR_VS:
713 case RISCV::VFREDMAX_VS:
714 case RISCV::VFREDMIN_VS:
715 case RISCV::VFREDOSUM_VS:
716 case RISCV::VFREDUSUM_VS: {
723 case RISCV::VWREDSUM_VS:
724 case RISCV::VWREDSUMU_VS:
726 case RISCV::VFWREDOSUM_VS:
727 case RISCV::VFWREDUSUM_VS: {
729 return TwoTimes ? MILog2SEW + 1 : MILog2SEW;
737static std::optional<OperandInfo>
741 RISCVVPseudosTable::getPseudoInfo(
MI.getOpcode());
742 assert(
RVV &&
"Could not find MI in PseudoTable");
748 switch (
RVV->BaseInstr) {
755 case RISCV::VREDAND_VS:
756 case RISCV::VREDMAX_VS:
757 case RISCV::VREDMAXU_VS:
758 case RISCV::VREDMIN_VS:
759 case RISCV::VREDMINU_VS:
760 case RISCV::VREDOR_VS:
761 case RISCV::VREDSUM_VS:
762 case RISCV::VREDXOR_VS:
763 case RISCV::VWREDSUM_VS:
764 case RISCV::VWREDSUMU_VS:
765 case RISCV::VFWREDOSUM_VS:
766 case RISCV::VFWREDUSUM_VS:
782 RISCVVPseudosTable::getPseudoInfo(
MI.getOpcode());
787 switch (
RVV->BaseInstr) {
794 case RISCV::VLSE16_V:
796 case RISCV::VLSE32_V:
798 case RISCV::VLSE64_V:
800 case RISCV::VLUXEI8_V:
801 case RISCV::VLOXEI8_V:
802 case RISCV::VLUXEI16_V:
803 case RISCV::VLOXEI16_V:
804 case RISCV::VLUXEI32_V:
805 case RISCV::VLOXEI32_V:
806 case RISCV::VLUXEI64_V:
807 case RISCV::VLOXEI64_V: {
809 if (MMO->isVolatile())
820 case RISCV::VRSUB_VI:
821 case RISCV::VRSUB_VX:
843 case RISCV::VWADDU_VV:
844 case RISCV::VWADDU_VX:
845 case RISCV::VWSUBU_VV:
846 case RISCV::VWSUBU_VX:
847 case RISCV::VWADD_VV:
848 case RISCV::VWADD_VX:
849 case RISCV::VWSUB_VV:
850 case RISCV::VWSUB_VX:
851 case RISCV::VWADDU_WV:
852 case RISCV::VWADDU_WX:
853 case RISCV::VWSUBU_WV:
854 case RISCV::VWSUBU_WX:
855 case RISCV::VWADD_WV:
856 case RISCV::VWADD_WX:
857 case RISCV::VWSUB_WV:
858 case RISCV::VWSUB_WX:
860 case RISCV::VZEXT_VF2:
861 case RISCV::VSEXT_VF2:
862 case RISCV::VZEXT_VF4:
863 case RISCV::VSEXT_VF4:
864 case RISCV::VZEXT_VF8:
865 case RISCV::VSEXT_VF8:
868 case RISCV::VMADC_VV:
869 case RISCV::VMADC_VI:
870 case RISCV::VMADC_VX:
871 case RISCV::VMSBC_VV:
872 case RISCV::VMSBC_VX:
874 case RISCV::VNSRL_WX:
875 case RISCV::VNSRL_WI:
876 case RISCV::VNSRL_WV:
877 case RISCV::VNSRA_WI:
878 case RISCV::VNSRA_WV:
879 case RISCV::VNSRA_WX:
881 case RISCV::VMSEQ_VI:
882 case RISCV::VMSEQ_VV:
883 case RISCV::VMSEQ_VX:
884 case RISCV::VMSNE_VI:
885 case RISCV::VMSNE_VV:
886 case RISCV::VMSNE_VX:
887 case RISCV::VMSLTU_VV:
888 case RISCV::VMSLTU_VX:
889 case RISCV::VMSLT_VV:
890 case RISCV::VMSLT_VX:
891 case RISCV::VMSLEU_VV:
892 case RISCV::VMSLEU_VI:
893 case RISCV::VMSLEU_VX:
894 case RISCV::VMSLE_VV:
895 case RISCV::VMSLE_VI:
896 case RISCV::VMSLE_VX:
897 case RISCV::VMSGTU_VI:
898 case RISCV::VMSGTU_VX:
899 case RISCV::VMSGT_VI:
900 case RISCV::VMSGT_VX:
902 case RISCV::VMINU_VV:
903 case RISCV::VMINU_VX:
906 case RISCV::VMAXU_VV:
907 case RISCV::VMAXU_VX:
913 case RISCV::VMULH_VV:
914 case RISCV::VMULH_VX:
915 case RISCV::VMULHU_VV:
916 case RISCV::VMULHU_VX:
917 case RISCV::VMULHSU_VV:
918 case RISCV::VMULHSU_VX:
920 case RISCV::VDIVU_VV:
921 case RISCV::VDIVU_VX:
924 case RISCV::VREMU_VV:
925 case RISCV::VREMU_VX:
929 case RISCV::VWMUL_VV:
930 case RISCV::VWMUL_VX:
931 case RISCV::VWMULSU_VV:
932 case RISCV::VWMULSU_VX:
933 case RISCV::VWMULU_VV:
934 case RISCV::VWMULU_VX:
936 case RISCV::VMACC_VV:
937 case RISCV::VMACC_VX:
938 case RISCV::VNMSAC_VV:
939 case RISCV::VNMSAC_VX:
940 case RISCV::VMADD_VV:
941 case RISCV::VMADD_VX:
942 case RISCV::VNMSUB_VV:
943 case RISCV::VNMSUB_VX:
945 case RISCV::VMERGE_VIM:
946 case RISCV::VMERGE_VVM:
947 case RISCV::VMERGE_VXM:
949 case RISCV::VADC_VIM:
950 case RISCV::VADC_VVM:
951 case RISCV::VADC_VXM:
953 case RISCV::VWMACCU_VV:
954 case RISCV::VWMACCU_VX:
955 case RISCV::VWMACC_VV:
956 case RISCV::VWMACC_VX:
957 case RISCV::VWMACCSU_VV:
958 case RISCV::VWMACCSU_VX:
959 case RISCV::VWMACCUS_VX:
968 case RISCV::VAADDU_VV:
969 case RISCV::VAADDU_VX:
970 case RISCV::VAADD_VV:
971 case RISCV::VAADD_VX:
972 case RISCV::VASUBU_VV:
973 case RISCV::VASUBU_VX:
974 case RISCV::VASUB_VV:
975 case RISCV::VASUB_VX:
978 case RISCV::VWSLL_VI:
987 case RISCV::VMAND_MM:
988 case RISCV::VMNAND_MM:
989 case RISCV::VMANDN_MM:
990 case RISCV::VMXOR_MM:
992 case RISCV::VMNOR_MM:
993 case RISCV::VMORN_MM:
994 case RISCV::VMXNOR_MM:
1001 case RISCV::VFADD_VF:
1002 case RISCV::VFADD_VV:
1003 case RISCV::VFSUB_VF:
1004 case RISCV::VFSUB_VV:
1005 case RISCV::VFRSUB_VF:
1007 case RISCV::VFWADD_VV:
1008 case RISCV::VFWADD_VF:
1009 case RISCV::VFWSUB_VV:
1010 case RISCV::VFWSUB_VF:
1011 case RISCV::VFWADD_WF:
1012 case RISCV::VFWADD_WV:
1013 case RISCV::VFWSUB_WF:
1014 case RISCV::VFWSUB_WV:
1016 case RISCV::VFMUL_VF:
1017 case RISCV::VFMUL_VV:
1018 case RISCV::VFDIV_VF:
1019 case RISCV::VFDIV_VV:
1020 case RISCV::VFRDIV_VF:
1022 case RISCV::VFWMUL_VF:
1023 case RISCV::VFWMUL_VV:
1025 case RISCV::VMFEQ_VF:
1026 case RISCV::VMFEQ_VV:
1027 case RISCV::VMFNE_VF:
1028 case RISCV::VMFNE_VV:
1029 case RISCV::VMFLT_VF:
1030 case RISCV::VMFLT_VV:
1031 case RISCV::VMFLE_VF:
1032 case RISCV::VMFLE_VV:
1033 case RISCV::VMFGT_VF:
1034 case RISCV::VMFGE_VF:
1036 case RISCV::VFCVT_XU_F_V:
1037 case RISCV::VFCVT_X_F_V:
1038 case RISCV::VFCVT_RTZ_XU_F_V:
1039 case RISCV::VFCVT_RTZ_X_F_V:
1040 case RISCV::VFCVT_F_XU_V:
1041 case RISCV::VFCVT_F_X_V:
1043 case RISCV::VFWCVT_XU_F_V:
1044 case RISCV::VFWCVT_X_F_V:
1045 case RISCV::VFWCVT_RTZ_XU_F_V:
1046 case RISCV::VFWCVT_RTZ_X_F_V:
1047 case RISCV::VFWCVT_F_XU_V:
1048 case RISCV::VFWCVT_F_X_V:
1049 case RISCV::VFWCVT_F_F_V:
1050 case RISCV::VFWCVTBF16_F_F_V:
1052 case RISCV::VFNCVT_XU_F_W:
1053 case RISCV::VFNCVT_X_F_W:
1054 case RISCV::VFNCVT_RTZ_XU_F_W:
1055 case RISCV::VFNCVT_RTZ_X_F_W:
1056 case RISCV::VFNCVT_F_XU_W:
1057 case RISCV::VFNCVT_F_X_W:
1058 case RISCV::VFNCVT_F_F_W:
1059 case RISCV::VFNCVT_ROD_F_F_W:
1060 case RISCV::VFNCVTBF16_F_F_W:
1071 RISCVVPseudosTable::getPseudoInfo(
MI->getOpcode());
1076 switch (
RVV->BaseInstr) {
1078 case RISCV::VREDAND_VS:
1079 case RISCV::VREDMAX_VS:
1080 case RISCV::VREDMAXU_VS:
1081 case RISCV::VREDMIN_VS:
1082 case RISCV::VREDMINU_VS:
1083 case RISCV::VREDOR_VS:
1084 case RISCV::VREDSUM_VS:
1085 case RISCV::VREDXOR_VS:
1086 case RISCV::VWREDSUM_VS:
1087 case RISCV::VWREDSUMU_VS:
1088 case RISCV::VFREDMAX_VS:
1089 case RISCV::VFREDMIN_VS:
1090 case RISCV::VFREDOSUM_VS:
1091 case RISCV::VFREDUSUM_VS:
1092 case RISCV::VFWREDOSUM_VS:
1093 case RISCV::VFWREDUSUM_VS:
1095 case RISCV::VMV_X_S:
1096 case RISCV::VFMV_F_S:
1106 RISCVVPseudosTable::getPseudoInfo(
MI.getOpcode());
1110 switch (
RVV->BaseInstr) {
1113 case RISCV::VSLIDEDOWN_VI:
1114 case RISCV::VSLIDEDOWN_VX:
1115 case RISCV::VSLIDE1DOWN_VX:
1116 case RISCV::VFSLIDE1DOWN_VF:
1120 case RISCV::VRGATHER_VI:
1121 case RISCV::VRGATHER_VV:
1122 case RISCV::VRGATHER_VX:
1123 case RISCV::VRGATHEREI16_VV:
1131bool RISCVVLOptimizer::isCandidate(
const MachineInstr &
MI)
const {
1135 if (
MI.getNumDefs() != 1)
1150 unsigned PassthruOpIdx =
MI.getNumExplicitDefs();
1152 MI.getOperand(PassthruOpIdx).getReg() != RISCV::NoRegister) {
1154 dbgs() <<
" Not a candidate because it uses non-undef passthru"
1155 " with non-VLMAX VL\n");
1163 LLVM_DEBUG(
dbgs() <<
" Not a candidate because VL is already 1\n");
1167 if (
MI.mayRaiseFPException()) {
1168 LLVM_DEBUG(
dbgs() <<
"Not a candidate because may raise FP exception\n");
1185 LLVM_DEBUG(
dbgs() <<
"Not a candidate due to unsupported instruction\n");
1189 LLVM_DEBUG(
dbgs() <<
"Found a candidate for VL reduction: " <<
MI <<
"\n");
1193std::optional<MachineOperand>
1201 return std::nullopt;
1209 assert(RISCV::VRRegClass.hasSubClassEq(RC) &&
1210 "Expect LMUL 1 register class for vector as scalar operands!");
1211 LLVM_DEBUG(
dbgs() <<
" Used this operand as a scalar operand\n");
1220 "Did not expect X0 VL");
1224std::optional<MachineOperand> RISCVVLOptimizer::checkUsers(
MachineInstr &
MI) {
1229 std::optional<MachineOperand> CommonVL;
1230 for (
auto &UserOp :
MRI->use_operands(
MI.getOperand(0).getReg())) {
1234 LLVM_DEBUG(
dbgs() <<
" Abort because used by unsafe instruction\n");
1235 return std::nullopt;
1240 LLVM_DEBUG(
dbgs() <<
" Abort because user used as tied operand\n");
1241 return std::nullopt;
1244 auto VLOp = getMinimumVLForUser(UserOp);
1246 return std::nullopt;
1254 LLVM_DEBUG(
dbgs() <<
" Abort because cannot determine a common VL\n");
1255 return std::nullopt;
1260 return std::nullopt;
1264 std::optional<OperandInfo> ProducerInfo =
1266 if (!ConsumerInfo || !ProducerInfo) {
1267 LLVM_DEBUG(
dbgs() <<
" Abort due to unknown operand information.\n");
1268 LLVM_DEBUG(
dbgs() <<
" ConsumerInfo is: " << ConsumerInfo <<
"\n");
1269 LLVM_DEBUG(
dbgs() <<
" ProducerInfo is: " << ProducerInfo <<
"\n");
1270 return std::nullopt;
1276 if ((IsVectorOpUsedAsScalarOp &&
1278 (!IsVectorOpUsedAsScalarOp &&
1282 <<
" Abort due to incompatible information for EMUL or EEW.\n");
1283 LLVM_DEBUG(
dbgs() <<
" ConsumerInfo is: " << ConsumerInfo <<
"\n");
1284 LLVM_DEBUG(
dbgs() <<
" ProducerInfo is: " << ProducerInfo <<
"\n");
1285 return std::nullopt;
1292bool RISCVVLOptimizer::tryReduceVL(
MachineInstr &OrigMI) {
1294 Worklist.
insert(&OrigMI);
1296 bool MadeChange =
false;
1297 while (!Worklist.
empty()) {
1304 auto CommonVL = checkUsers(
MI);
1308 assert((CommonVL->isImm() || CommonVL->getReg().isVirtual()) &&
1309 "Expected VL to be an Imm or virtual Reg");
1319 if (CommonVL->isImm()) {
1321 << CommonVL->getImm() <<
" for " <<
MI <<
"\n");
1325 if (!MDT->dominates(VLMI, &
MI))
1328 dbgs() <<
" Reduce VL from " << VLOp <<
" to "
1329 <<
printReg(CommonVL->getReg(),
MRI->getTargetRegisterInfo())
1330 <<
" for " <<
MI <<
"\n");
1339 for (
auto &
Op :
MI.operands()) {
1340 if (!
Op.isReg() || !
Op.isUse() || !
Op.getReg().isVirtual())
1363 MDT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
1366 if (!
ST.hasVInstructions())
1369 bool MadeChange =
false;
1376 MadeChange |= tryReduceVL(
MI);
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder MachineInstrBuilder & DefMI
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
#define LLVM_ATTRIBUTE_UNUSED
static bool isCandidate(const MachineInstr *MI, Register &DefedReg, Register FrameReg)
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
static bool mayReadPastVL(const MachineInstr &MI)
Return true if MI may read elements past VL.
static LLVM_ATTRIBUTE_UNUSED raw_ostream & operator<<(raw_ostream &OS, const OperandInfo &OI)
static unsigned getIntegerExtensionOperandEEW(unsigned Factor, const MachineInstr &MI, const MachineOperand &MO)
Dest has EEW=SEW.
static bool isVectorOpUsedAsScalarOp(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, const MachineRegisterInfo *MRI)
static bool isVectorRegClass(Register R, const MachineRegisterInfo *MRI)
Return true if R is a physical or virtual vector register, false otherwise.
static bool isSupportedInstr(const MachineInstr &MI)
Return true if this optimization should consider MI for VL reduction.
static bool isMaskOperand(const MachineInstr &MI, const MachineOperand &MO, const MachineRegisterInfo *MRI)
Check whether MO is a mask operand of MI.
static std::optional< OperandInfo > getOperandInfo(const MachineOperand &MO, const MachineRegisterInfo *MRI)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file implements a set that has insertion order iteration characteristics.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
void setPreservesCFG()
This function should be called by the pass, iff they do not:
This class represents an Operation in the Expression.
FunctionPass class - This class is used to implement most global optimizations.
Describe properties that are true of each instruction in the target description file.
reverse_iterator rbegin()
Analysis pass which computes a MachineDominatorTree.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
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.
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
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.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
A description of a memory reference used in the backend.
MachineOperand class - Representation of each machine instruction operand.
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.
void ChangeToImmediate(int64_t ImmVal, unsigned TargetFlags=0)
ChangeToImmediate - Replace this operand with a new immediate operand of the specified value.
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.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Wrapper class representing virtual and physical registers.
A vector that has set insertion semantics.
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()
StringRef - Represent a constant reference to a string, i.e.
const uint8_t TSFlags
Configurable target specific flags.
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 unsigned getVLOpNum(const MCInstrDesc &Desc)
static VLMUL getLMul(uint64_t TSFlags)
static bool hasVLOp(uint64_t TSFlags)
static unsigned getSEWOpNum(const MCInstrDesc &Desc)
static bool hasSEWOp(uint64_t TSFlags)
static bool isFirstDefTiedToFirstUse(const MCInstrDesc &Desc)
static bool isVRegClass(uint64_t TSFlags)
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...
std::pair< unsigned, bool > decodeVLMUL(RISCVII::VLMUL VLMUL)
bool isVLKnownLE(const MachineOperand &LHS, const MachineOperand &RHS)
Given two VL operands, do we know that LHS <= RHS?
static constexpr int64_t VLMaxSentinel
This is an optimization pass for GlobalISel generic memory operations.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
FunctionPass * createRISCVVLOptimizerPass()
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
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.
Represents the EMUL and EEW of a MachineOperand.
static bool EEWAreEqual(const OperandInfo &A, const OperandInfo &B)
OperandInfo(std::pair< unsigned, bool > EMUL, unsigned Log2EEW)
OperandInfo(unsigned Log2EEW)
void print(raw_ostream &OS) const
static bool EMULAndEEWAreEqual(const OperandInfo &A, const OperandInfo &B)
OperandInfo(RISCVII::VLMUL EMUL, unsigned Log2EEW)
std::optional< std::pair< unsigned, bool > > EMUL
Description of the encoding of one expression Op.