Mercurial > hg > CbC > CbC_gcc
comparison gcc/regcprop.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 /* Copy propagation on hard registers for the GNU compiler. | 1 /* Copy propagation on hard registers for the GNU compiler. |
2 Copyright (C) 2000-2017 Free Software Foundation, Inc. | 2 Copyright (C) 2000-2018 Free Software Foundation, Inc. |
3 | 3 |
4 This file is part of GCC. | 4 This file is part of GCC. |
5 | 5 |
6 GCC is free software; you can redistribute it and/or modify it | 6 GCC is free software; you can redistribute it and/or modify it |
7 under the terms of the GNU General Public License as published by | 7 under the terms of the GNU General Public License as published by |
235 | 235 |
236 static void | 236 static void |
237 kill_clobbered_value (rtx x, const_rtx set, void *data) | 237 kill_clobbered_value (rtx x, const_rtx set, void *data) |
238 { | 238 { |
239 struct value_data *const vd = (struct value_data *) data; | 239 struct value_data *const vd = (struct value_data *) data; |
240 if (GET_CODE (set) == CLOBBER) | 240 gcc_assert (GET_CODE (set) != CLOBBER_HIGH || REG_P (x)); |
241 | |
242 if (GET_CODE (set) == CLOBBER | |
243 || (GET_CODE (set) == CLOBBER_HIGH | |
244 && reg_is_clobbered_by_clobber_high (x, XEXP (set, 0)))) | |
241 kill_value (x, vd); | 245 kill_value (x, vd); |
242 } | 246 } |
243 | 247 |
244 /* A structure passed as data to kill_set_value through note_stores. */ | 248 /* A structure passed as data to kill_set_value through note_stores. */ |
245 struct kill_set_value_data | 249 struct kill_set_value_data |
255 kill_set_value (rtx x, const_rtx set, void *data) | 259 kill_set_value (rtx x, const_rtx set, void *data) |
256 { | 260 { |
257 struct kill_set_value_data *ksvd = (struct kill_set_value_data *) data; | 261 struct kill_set_value_data *ksvd = (struct kill_set_value_data *) data; |
258 if (rtx_equal_p (x, ksvd->ignore_set_reg)) | 262 if (rtx_equal_p (x, ksvd->ignore_set_reg)) |
259 return; | 263 return; |
260 if (GET_CODE (set) != CLOBBER) | 264 |
265 gcc_assert (GET_CODE (set) != CLOBBER_HIGH || REG_P (x)); | |
266 if (GET_CODE (set) != CLOBBER && GET_CODE (set) != CLOBBER_HIGH) | |
261 { | 267 { |
262 kill_value (x, ksvd->vd); | 268 kill_value (x, ksvd->vd); |
263 if (REG_P (x)) | 269 if (REG_P (x)) |
264 set_value_regno (REGNO (x), GET_MODE (x), ksvd->vd); | 270 set_value_regno (REGNO (x), GET_MODE (x), ksvd->vd); |
265 } | 271 } |
343 loads the high part of (reg:DI fr0) into fr2. | 349 loads the high part of (reg:DI fr0) into fr2. |
344 | 350 |
345 We can't properly represent the latter case in our tables, so don't | 351 We can't properly represent the latter case in our tables, so don't |
346 record anything then. */ | 352 record anything then. */ |
347 else if (sn < hard_regno_nregs (sr, vd->e[sr].mode) | 353 else if (sn < hard_regno_nregs (sr, vd->e[sr].mode) |
348 && subreg_lowpart_offset (GET_MODE (dest), vd->e[sr].mode) != 0) | 354 && maybe_ne (subreg_lowpart_offset (GET_MODE (dest), |
355 vd->e[sr].mode), 0U)) | |
349 return; | 356 return; |
350 | 357 |
351 /* If SRC had been assigned a mode narrower than the copy, we can't | 358 /* If SRC had been assigned a mode narrower than the copy, we can't |
352 link DEST into the chain, because not all of the pieces of the | 359 link DEST into the chain, because not all of the pieces of the |
353 copy came from oldest_regno. */ | 360 copy came from oldest_regno. */ |
403 return gen_raw_REG (new_mode, regno); | 410 return gen_raw_REG (new_mode, regno); |
404 else if (mode_change_ok (orig_mode, new_mode, regno)) | 411 else if (mode_change_ok (orig_mode, new_mode, regno)) |
405 { | 412 { |
406 int copy_nregs = hard_regno_nregs (copy_regno, copy_mode); | 413 int copy_nregs = hard_regno_nregs (copy_regno, copy_mode); |
407 int use_nregs = hard_regno_nregs (copy_regno, new_mode); | 414 int use_nregs = hard_regno_nregs (copy_regno, new_mode); |
408 int copy_offset | 415 poly_uint64 bytes_per_reg; |
409 = GET_MODE_SIZE (copy_mode) / copy_nregs * (copy_nregs - use_nregs); | 416 if (!can_div_trunc_p (GET_MODE_SIZE (copy_mode), |
410 unsigned int offset | 417 copy_nregs, &bytes_per_reg)) |
418 return NULL_RTX; | |
419 poly_uint64 copy_offset = bytes_per_reg * (copy_nregs - use_nregs); | |
420 poly_uint64 offset | |
411 = subreg_size_lowpart_offset (GET_MODE_SIZE (new_mode) + copy_offset, | 421 = subreg_size_lowpart_offset (GET_MODE_SIZE (new_mode) + copy_offset, |
412 GET_MODE_SIZE (orig_mode)); | 422 GET_MODE_SIZE (orig_mode)); |
413 regno += subreg_regno_offset (regno, orig_mode, offset, new_mode); | 423 regno += subreg_regno_offset (regno, orig_mode, offset, new_mode); |
414 if (targetm.hard_regno_mode_ok (regno, new_mode)) | 424 if (targetm.hard_regno_mode_ok (regno, new_mode)) |
415 return gen_raw_REG (new_mode, regno); | 425 return gen_raw_REG (new_mode, regno); |
425 find_oldest_value_reg (enum reg_class cl, rtx reg, struct value_data *vd) | 435 find_oldest_value_reg (enum reg_class cl, rtx reg, struct value_data *vd) |
426 { | 436 { |
427 unsigned int regno = REGNO (reg); | 437 unsigned int regno = REGNO (reg); |
428 machine_mode mode = GET_MODE (reg); | 438 machine_mode mode = GET_MODE (reg); |
429 unsigned int i; | 439 unsigned int i; |
440 | |
441 gcc_assert (regno < FIRST_PSEUDO_REGISTER); | |
430 | 442 |
431 /* If we are accessing REG in some mode other that what we set it in, | 443 /* If we are accessing REG in some mode other that what we set it in, |
432 make sure that the replacement is valid. In particular, consider | 444 make sure that the replacement is valid. In particular, consider |
433 (set (reg:DI r11) (...)) | 445 (set (reg:DI r11) (...)) |
434 (set (reg:SI r9) (reg:SI r11)) | 446 (set (reg:SI r9) (reg:SI r11)) |
743 { | 755 { |
744 int n_ops, i, predicated; | 756 int n_ops, i, predicated; |
745 bool is_asm, any_replacements; | 757 bool is_asm, any_replacements; |
746 rtx set; | 758 rtx set; |
747 rtx link; | 759 rtx link; |
748 bool replaced[MAX_RECOG_OPERANDS]; | |
749 bool changed = false; | 760 bool changed = false; |
750 struct kill_set_value_data ksvd; | 761 struct kill_set_value_data ksvd; |
751 | 762 |
752 next = NEXT_INSN (insn); | 763 next = NEXT_INSN (insn); |
753 if (!NONDEBUG_INSN_P (insn)) | 764 if (!NONDEBUG_INSN_P (insn)) |
754 { | 765 { |
755 if (DEBUG_INSN_P (insn)) | 766 if (DEBUG_BIND_INSN_P (insn)) |
756 { | 767 { |
757 rtx loc = INSN_VAR_LOCATION_LOC (insn); | 768 rtx loc = INSN_VAR_LOCATION_LOC (insn); |
758 if (!VAR_LOC_UNKNOWN_P (loc)) | 769 if (!VAR_LOC_UNKNOWN_P (loc)) |
759 replace_oldest_value_addr (&INSN_VAR_LOCATION_LOC (insn), | 770 replace_oldest_value_addr (&INSN_VAR_LOCATION_LOC (insn), |
760 ALL_REGS, GET_MODE (loc), | 771 ALL_REGS, GET_MODE (loc), |
841 special case below. */ | 852 special case below. */ |
842 if (set | 853 if (set |
843 && reg_overlap_mentioned_p (XEXP (link, 0), SET_SRC (set))) | 854 && reg_overlap_mentioned_p (XEXP (link, 0), SET_SRC (set))) |
844 set = NULL; | 855 set = NULL; |
845 } | 856 } |
857 | |
858 /* We need to keep CFI info correct, and the same on all paths, | |
859 so we cannot normally replace the registers REG_CFA_REGISTER | |
860 refers to. Bail. */ | |
861 if (REG_NOTE_KIND (link) == REG_CFA_REGISTER) | |
862 goto did_replacement; | |
846 } | 863 } |
847 | 864 |
848 /* Special-case plain move instructions, since we may well | 865 /* Special-case plain move instructions, since we may well |
849 be able to do the move from a different register class. */ | 866 be able to do the move from a different register class. */ |
850 if (set && REG_P (SET_SRC (set))) | 867 if (set && REG_P (SET_SRC (set))) |
864 goto no_move_special_case; | 881 goto no_move_special_case; |
865 | 882 |
866 /* And likewise, if we are narrowing on big endian the transformation | 883 /* And likewise, if we are narrowing on big endian the transformation |
867 is also invalid. */ | 884 is also invalid. */ |
868 if (REG_NREGS (src) < hard_regno_nregs (regno, vd->e[regno].mode) | 885 if (REG_NREGS (src) < hard_regno_nregs (regno, vd->e[regno].mode) |
869 && subreg_lowpart_offset (mode, vd->e[regno].mode) != 0) | 886 && maybe_ne (subreg_lowpart_offset (mode, |
887 vd->e[regno].mode), 0U)) | |
870 goto no_move_special_case; | 888 goto no_move_special_case; |
871 } | 889 } |
872 | 890 |
873 /* If the destination is also a register, try to find a source | 891 /* If the destination is also a register, try to find a source |
874 register in the same class. */ | 892 register in the same class. */ |
925 | 943 |
926 /* For each input operand, replace a hard register with the | 944 /* For each input operand, replace a hard register with the |
927 eldest live copy that's in an appropriate register class. */ | 945 eldest live copy that's in an appropriate register class. */ |
928 for (i = 0; i < n_ops; i++) | 946 for (i = 0; i < n_ops; i++) |
929 { | 947 { |
930 replaced[i] = false; | 948 bool replaced = false; |
931 | 949 |
932 /* Don't scan match_operand here, since we've no reg class | 950 /* Don't scan match_operand here, since we've no reg class |
933 information to pass down. Any operands that we could | 951 information to pass down. Any operands that we could |
934 substitute in will be represented elsewhere. */ | 952 substitute in will be represented elsewhere. */ |
935 if (recog_data.constraints[i][0] == '\0') | 953 if (recog_data.constraints[i][0] == '\0') |
942 continue; | 960 continue; |
943 | 961 |
944 if (recog_data.operand_type[i] == OP_IN) | 962 if (recog_data.operand_type[i] == OP_IN) |
945 { | 963 { |
946 if (op_alt[i].is_address) | 964 if (op_alt[i].is_address) |
947 replaced[i] | 965 replaced |
948 = replace_oldest_value_addr (recog_data.operand_loc[i], | 966 = replace_oldest_value_addr (recog_data.operand_loc[i], |
949 alternative_class (op_alt, i), | 967 alternative_class (op_alt, i), |
950 VOIDmode, ADDR_SPACE_GENERIC, | 968 VOIDmode, ADDR_SPACE_GENERIC, |
951 insn, vd); | 969 insn, vd); |
952 else if (REG_P (recog_data.operand[i])) | 970 else if (REG_P (recog_data.operand[i])) |
953 replaced[i] | 971 replaced |
954 = replace_oldest_value_reg (recog_data.operand_loc[i], | 972 = replace_oldest_value_reg (recog_data.operand_loc[i], |
955 alternative_class (op_alt, i), | 973 alternative_class (op_alt, i), |
956 insn, vd); | 974 insn, vd); |
957 else if (MEM_P (recog_data.operand[i])) | 975 else if (MEM_P (recog_data.operand[i])) |
958 replaced[i] = replace_oldest_value_mem (recog_data.operand[i], | 976 replaced = replace_oldest_value_mem (recog_data.operand[i], |
959 insn, vd); | 977 insn, vd); |
960 } | 978 } |
961 else if (MEM_P (recog_data.operand[i])) | 979 else if (MEM_P (recog_data.operand[i])) |
962 replaced[i] = replace_oldest_value_mem (recog_data.operand[i], | 980 replaced = replace_oldest_value_mem (recog_data.operand[i], |
963 insn, vd); | 981 insn, vd); |
964 | 982 |
965 /* If we performed any replacement, update match_dups. */ | 983 /* If we performed any replacement, update match_dups. */ |
966 if (replaced[i]) | 984 if (replaced) |
967 { | 985 { |
968 int j; | 986 int j; |
969 rtx new_rtx; | 987 rtx new_rtx; |
970 | 988 |
971 new_rtx = *recog_data.operand_loc[i]; | 989 new_rtx = *recog_data.operand_loc[i]; |
980 | 998 |
981 if (any_replacements) | 999 if (any_replacements) |
982 { | 1000 { |
983 if (! apply_change_group ()) | 1001 if (! apply_change_group ()) |
984 { | 1002 { |
985 for (i = 0; i < n_ops; i++) | |
986 if (replaced[i]) | |
987 { | |
988 rtx old = *recog_data.operand_loc[i]; | |
989 recog_data.operand[i] = old; | |
990 } | |
991 | |
992 if (dump_file) | 1003 if (dump_file) |
993 fprintf (dump_file, | 1004 fprintf (dump_file, |
994 "insn %u: reg replacements not verified\n", | 1005 "insn %u: reg replacements not verified\n", |
995 INSN_UID (insn)); | 1006 INSN_UID (insn)); |
996 } | 1007 } |
1294 init_value_data (all_vd + bb->index); | 1305 init_value_data (all_vd + bb->index); |
1295 | 1306 |
1296 copyprop_hardreg_forward_1 (bb, all_vd + bb->index); | 1307 copyprop_hardreg_forward_1 (bb, all_vd + bb->index); |
1297 } | 1308 } |
1298 | 1309 |
1299 if (MAY_HAVE_DEBUG_INSNS) | 1310 if (MAY_HAVE_DEBUG_BIND_INSNS) |
1300 { | 1311 { |
1301 FOR_EACH_BB_FN (bb, fun) | 1312 FOR_EACH_BB_FN (bb, fun) |
1302 if (bitmap_bit_p (visited, bb->index) | 1313 if (bitmap_bit_p (visited, bb->index) |
1303 && all_vd[bb->index].n_debug_insn_changes) | 1314 && all_vd[bb->index].n_debug_insn_changes) |
1304 { | 1315 { |