Mercurial > hg > CbC > CbC_gcc
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 { |