comparison gcc/ree.c @ 132:d34655255c78

update gcc-8.2
author mir3636
date Thu, 25 Oct 2018 10:21:07 +0900
parents 84e7813d76e9
children 1830386684a0
comparison
equal deleted inserted replaced
130:e108057fa461 132:d34655255c78
1 /* Redundant Extension Elimination pass for the GNU compiler. 1 /* Redundant Extension Elimination pass for the GNU compiler.
2 Copyright (C) 2010-2017 Free Software Foundation, Inc. 2 Copyright (C) 2010-2018 Free Software Foundation, Inc.
3 Contributed by Ilya Enkovich (ilya.enkovich@intel.com) 3 Contributed by Ilya Enkovich (ilya.enkovich@intel.com)
4 4
5 Based on the Redundant Zero-extension elimination pass contributed by 5 Based on the Redundant Zero-extension elimination pass contributed by
6 Sriraman Tallam (tmsriram@google.com) and Silvius Rus (rus@google.com). 6 Sriraman Tallam (tmsriram@google.com) and Silvius Rus (rus@google.com).
7 7
859 859
860 /* On RISC machines we must make sure that changing the mode of SRC_REG 860 /* On RISC machines we must make sure that changing the mode of SRC_REG
861 as destination register will not affect its reaching uses, which may 861 as destination register will not affect its reaching uses, which may
862 read its value in a larger mode because DEF_INSN implicitly sets it 862 read its value in a larger mode because DEF_INSN implicitly sets it
863 in word mode. */ 863 in word mode. */
864 const unsigned int prec 864 poly_int64 prec
865 = GET_MODE_PRECISION (GET_MODE (SET_DEST (*dest_sub_rtx))); 865 = GET_MODE_PRECISION (GET_MODE (SET_DEST (*dest_sub_rtx)));
866 if (WORD_REGISTER_OPERATIONS && prec < BITS_PER_WORD) 866 if (WORD_REGISTER_OPERATIONS && known_lt (prec, BITS_PER_WORD))
867 { 867 {
868 struct df_link *uses = get_uses (def_insn, src_reg); 868 struct df_link *uses = get_uses (def_insn, src_reg);
869 if (!uses) 869 if (!uses)
870 return false; 870 return false;
871 871
899 REGNO (get_extended_src_reg (SET_SRC (pat)))); 899 REGNO (get_extended_src_reg (SET_SRC (pat))));
900 rtx new_src = gen_rtx_REG (GET_MODE (SET_DEST (pat)), 900 rtx new_src = gen_rtx_REG (GET_MODE (SET_DEST (pat)),
901 REGNO (SET_DEST (pat))); 901 REGNO (SET_DEST (pat)));
902 emit_move_insn (new_dst, new_src); 902 emit_move_insn (new_dst, new_src);
903 903
904 rtx_insn *insn = get_insns(); 904 rtx_insn *insn = get_insns ();
905 end_sequence (); 905 end_sequence ();
906 if (NEXT_INSN (insn)) 906 if (NEXT_INSN (insn))
907 return false; 907 return false;
908 if (recog_memoized (insn) == -1) 908 if (recog_memoized (insn) == -1)
909 return false; 909 return false;
910 extract_insn (insn); 910 extract_insn (insn);
911 if (!constrain_operands (1, get_preferred_alternatives (insn, bb))) 911 if (!constrain_operands (1, get_preferred_alternatives (insn, bb)))
912 return false; 912 return false;
913 } 913
914 914 while (REG_P (SET_SRC (*dest_sub_rtx))
915 && (REGNO (SET_SRC (*dest_sub_rtx)) == REGNO (SET_DEST (pat))))
916 {
917 /* Considering transformation of
918 (set (reg2) (expression))
919 ...
920 (set (reg1) (reg2))
921 ...
922 (set (reg2) (any_extend (reg1)))
923
924 into
925
926 (set (reg2) (any_extend (expression)))
927 (set (reg1) (reg2))
928 ... */
929 struct df_link *defs
930 = get_defs (def_insn, SET_SRC (*dest_sub_rtx), NULL);
931 if (defs == NULL || defs->next)
932 break;
933
934 /* There is only one reaching def. */
935 rtx_insn *def_insn2 = DF_REF_INSN (defs->ref);
936
937 /* The defining statement must not have been modified either. */
938 if (state->modified[INSN_UID (def_insn2)].kind != EXT_MODIFIED_NONE)
939 break;
940
941 /* The def_insn2 and candidate insn must be in the same
942 block and def_insn follows def_insn2. */
943 if (bb != BLOCK_FOR_INSN (def_insn2)
944 || DF_INSN_LUID (def_insn2) > DF_INSN_LUID (def_insn))
945 break;
946
947 rtx *dest_sub_rtx2 = get_sub_rtx (def_insn2);
948 if (dest_sub_rtx2 == NULL
949 || !REG_P (SET_DEST (*dest_sub_rtx2)))
950 break;
951
952 /* On RISC machines we must make sure that changing the mode of
953 SRC_REG as destination register will not affect its reaching
954 uses, which may read its value in a larger mode because DEF_INSN
955 implicitly sets it in word mode. */
956 if (WORD_REGISTER_OPERATIONS && known_lt (prec, BITS_PER_WORD))
957 {
958 struct df_link *uses = get_uses (def_insn2, SET_DEST (pat));
959 if (!uses)
960 break;
961
962 df_link *use;
963 rtx dest2 = SET_DEST (*dest_sub_rtx2);
964 for (use = uses; use; use = use->next)
965 if (paradoxical_subreg_p (GET_MODE (*DF_REF_LOC (use->ref)),
966 GET_MODE (dest2)))
967 break;
968 if (use)
969 break;
970 }
971
972 /* The destination register of the extension insn must not be
973 used or set between the def_insn2 and def_insn exclusive.
974 Likewise for the other reg, i.e. check both reg1 and reg2
975 in the above comment. */
976 if (reg_used_between_p (SET_DEST (PATTERN (cand->insn)),
977 def_insn2, def_insn)
978 || reg_set_between_p (SET_DEST (PATTERN (cand->insn)),
979 def_insn2, def_insn)
980 || reg_used_between_p (src_reg, def_insn2, def_insn)
981 || reg_set_between_p (src_reg, def_insn2, def_insn))
982 break;
983
984 state->defs_list[0] = def_insn2;
985 break;
986 }
987 }
915 988
916 /* If cand->insn has been already modified, update cand->mode to a wider 989 /* If cand->insn has been already modified, update cand->mode to a wider
917 mode if possible, or punt. */ 990 mode if possible, or punt. */
918 if (state->modified[INSN_UID (cand->insn)].kind != EXT_MODIFIED_NONE) 991 if (state->modified[INSN_UID (cand->insn)].kind != EXT_MODIFIED_NONE)
919 { 992 {