Mercurial > hg > CbC > CbC_gcc
comparison gcc/reginfo.c @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | 1830386684a0 |
comparison
equal
deleted
inserted
replaced
111:04ced10e8804 | 131:84e7813d76e9 |
---|---|
1 /* Compute different info about registers. | 1 /* Compute different info about registers. |
2 Copyright (C) 1987-2017 Free Software Foundation, Inc. | 2 Copyright (C) 1987-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 under | 6 GCC is free software; you can redistribute it and/or modify it under |
7 the terms of the GNU General Public License as published by the Free | 7 the terms of the GNU General Public License as published by the Free |
629 unsigned int /* machine_mode */ m; | 629 unsigned int /* machine_mode */ m; |
630 machine_mode found_mode = VOIDmode, mode; | 630 machine_mode found_mode = VOIDmode, mode; |
631 | 631 |
632 /* We first look for the largest integer mode that can be validly | 632 /* We first look for the largest integer mode that can be validly |
633 held in REGNO. If none, we look for the largest floating-point mode. | 633 held in REGNO. If none, we look for the largest floating-point mode. |
634 If we still didn't find a valid mode, try CCmode. */ | 634 If we still didn't find a valid mode, try CCmode. |
635 | 635 |
636 The tests use maybe_gt rather than known_gt because we want (for example) | |
637 N V4SFs to win over plain V4SF even though N might be 1. */ | |
636 FOR_EACH_MODE_IN_CLASS (mode, MODE_INT) | 638 FOR_EACH_MODE_IN_CLASS (mode, MODE_INT) |
637 if (hard_regno_nregs (regno, mode) == nregs | 639 if (hard_regno_nregs (regno, mode) == nregs |
638 && targetm.hard_regno_mode_ok (regno, mode) | 640 && targetm.hard_regno_mode_ok (regno, mode) |
639 && (!call_saved | 641 && (!call_saved |
640 || !targetm.hard_regno_call_part_clobbered (regno, mode)) | 642 || !targetm.hard_regno_call_part_clobbered (regno, mode)) |
641 && GET_MODE_SIZE (mode) > GET_MODE_SIZE (found_mode)) | 643 && maybe_gt (GET_MODE_SIZE (mode), GET_MODE_SIZE (found_mode))) |
642 found_mode = mode; | 644 found_mode = mode; |
643 | 645 |
644 FOR_EACH_MODE_IN_CLASS (mode, MODE_FLOAT) | 646 FOR_EACH_MODE_IN_CLASS (mode, MODE_FLOAT) |
645 if (hard_regno_nregs (regno, mode) == nregs | 647 if (hard_regno_nregs (regno, mode) == nregs |
646 && targetm.hard_regno_mode_ok (regno, mode) | 648 && targetm.hard_regno_mode_ok (regno, mode) |
647 && (!call_saved | 649 && (!call_saved |
648 || !targetm.hard_regno_call_part_clobbered (regno, mode)) | 650 || !targetm.hard_regno_call_part_clobbered (regno, mode)) |
649 && GET_MODE_SIZE (mode) > GET_MODE_SIZE (found_mode)) | 651 && maybe_gt (GET_MODE_SIZE (mode), GET_MODE_SIZE (found_mode))) |
650 found_mode = mode; | 652 found_mode = mode; |
651 | 653 |
652 FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_FLOAT) | 654 FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_FLOAT) |
653 if (hard_regno_nregs (regno, mode) == nregs | 655 if (hard_regno_nregs (regno, mode) == nregs |
654 && targetm.hard_regno_mode_ok (regno, mode) | 656 && targetm.hard_regno_mode_ok (regno, mode) |
655 && (!call_saved | 657 && (!call_saved |
656 || !targetm.hard_regno_call_part_clobbered (regno, mode)) | 658 || !targetm.hard_regno_call_part_clobbered (regno, mode)) |
657 && GET_MODE_SIZE (mode) > GET_MODE_SIZE (found_mode)) | 659 && maybe_gt (GET_MODE_SIZE (mode), GET_MODE_SIZE (found_mode))) |
658 found_mode = mode; | 660 found_mode = mode; |
659 | 661 |
660 FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_INT) | 662 FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_INT) |
661 if (hard_regno_nregs (regno, mode) == nregs | 663 if (hard_regno_nregs (regno, mode) == nregs |
662 && targetm.hard_regno_mode_ok (regno, mode) | 664 && targetm.hard_regno_mode_ok (regno, mode) |
663 && (!call_saved | 665 && (!call_saved |
664 || !targetm.hard_regno_call_part_clobbered (regno, mode)) | 666 || !targetm.hard_regno_call_part_clobbered (regno, mode)) |
665 && GET_MODE_SIZE (mode) > GET_MODE_SIZE (found_mode)) | 667 && maybe_gt (GET_MODE_SIZE (mode), GET_MODE_SIZE (found_mode))) |
666 found_mode = mode; | 668 found_mode = mode; |
667 | 669 |
668 if (found_mode != VOIDmode) | 670 if (found_mode != VOIDmode) |
669 return found_mode; | 671 return found_mode; |
670 | 672 |
778 if (fixed_regs[i] == 0 && no_global_reg_vars) | 780 if (fixed_regs[i] == 0 && no_global_reg_vars) |
779 error_at (loc, "global register variable follows a function definition"); | 781 error_at (loc, "global register variable follows a function definition"); |
780 | 782 |
781 if (global_regs[i]) | 783 if (global_regs[i]) |
782 { | 784 { |
785 auto_diagnostic_group d; | |
783 warning_at (loc, 0, | 786 warning_at (loc, 0, |
784 "register of %qD used for multiple global register variables", | 787 "register of %qD used for multiple global register variables", |
785 decl); | 788 decl); |
786 inform (DECL_SOURCE_LOCATION (global_regs_decl[i]), | 789 inform (DECL_SOURCE_LOCATION (global_regs_decl[i]), |
787 "conflicts with %qD", global_regs_decl[i]); | 790 "conflicts with %qD", global_regs_decl[i]); |
1094 break; | 1097 break; |
1095 | 1098 |
1096 case CLOBBER: | 1099 case CLOBBER: |
1097 if (MEM_P (XEXP (x, 0))) | 1100 if (MEM_P (XEXP (x, 0))) |
1098 reg_scan_mark_refs (XEXP (XEXP (x, 0), 0), insn); | 1101 reg_scan_mark_refs (XEXP (XEXP (x, 0), 0), insn); |
1102 break; | |
1103 | |
1104 case CLOBBER_HIGH: | |
1105 gcc_assert (!(MEM_P (XEXP (x, 0)))); | |
1099 break; | 1106 break; |
1100 | 1107 |
1101 case SET: | 1108 case SET: |
1102 /* Count a set of the destination if it is a register. */ | 1109 /* Count a set of the destination if it is a register. */ |
1103 for (dest = SET_DEST (x); | 1110 for (dest = SET_DEST (x); |
1204 | 1211 |
1205 | 1212 |
1206 inline hashval_t | 1213 inline hashval_t |
1207 simplifiable_subregs_hasher::hash (const simplifiable_subreg *value) | 1214 simplifiable_subregs_hasher::hash (const simplifiable_subreg *value) |
1208 { | 1215 { |
1209 return value->shape.unique_id (); | 1216 inchash::hash h; |
1217 h.add_hwi (value->shape.unique_id ()); | |
1218 return h.end (); | |
1210 } | 1219 } |
1211 | 1220 |
1212 inline bool | 1221 inline bool |
1213 simplifiable_subregs_hasher::equal (const simplifiable_subreg *value, | 1222 simplifiable_subregs_hasher::equal (const simplifiable_subreg *value, |
1214 const subreg_shape *compare) | 1223 const subreg_shape *compare) |
1229 simplifiable_subregs (const subreg_shape &shape) | 1238 simplifiable_subregs (const subreg_shape &shape) |
1230 { | 1239 { |
1231 if (!this_target_hard_regs->x_simplifiable_subregs) | 1240 if (!this_target_hard_regs->x_simplifiable_subregs) |
1232 this_target_hard_regs->x_simplifiable_subregs | 1241 this_target_hard_regs->x_simplifiable_subregs |
1233 = new hash_table <simplifiable_subregs_hasher> (30); | 1242 = new hash_table <simplifiable_subregs_hasher> (30); |
1243 inchash::hash h; | |
1244 h.add_hwi (shape.unique_id ()); | |
1234 simplifiable_subreg **slot | 1245 simplifiable_subreg **slot |
1235 = (this_target_hard_regs->x_simplifiable_subregs | 1246 = (this_target_hard_regs->x_simplifiable_subregs |
1236 ->find_slot_with_hash (&shape, shape.unique_id (), INSERT)); | 1247 ->find_slot_with_hash (&shape, h.end (), INSERT)); |
1237 | 1248 |
1238 if (!*slot) | 1249 if (!*slot) |
1239 { | 1250 { |
1240 simplifiable_subreg *info = new simplifiable_subreg (shape); | 1251 simplifiable_subreg *info = new simplifiable_subreg (shape); |
1241 for (unsigned int i = 0; i < FIRST_PSEUDO_REGISTER; ++i) | 1252 for (unsigned int i = 0; i < FIRST_PSEUDO_REGISTER; ++i) |
1288 If the underlying registers are small enough, both subregs will | 1299 If the underlying registers are small enough, both subregs will |
1289 be valid. If the underlying registers are too large, one of the | 1300 be valid. If the underlying registers are too large, one of the |
1290 subregs will be invalid. | 1301 subregs will be invalid. |
1291 | 1302 |
1292 This relies on the fact that we've already been passed | 1303 This relies on the fact that we've already been passed |
1293 SUBREG with PARTIAL_DEF set to false. */ | 1304 SUBREG with PARTIAL_DEF set to false. |
1294 unsigned int size = MAX (REGMODE_NATURAL_SIZE (shape.inner_mode), | 1305 |
1295 GET_MODE_SIZE (shape.outer_mode)); | 1306 The size of the outer mode must ordered wrt the size of the |
1296 gcc_checking_assert (size < GET_MODE_SIZE (shape.inner_mode)); | 1307 inner mode's registers, since otherwise we wouldn't know at |
1297 if (shape.offset >= size) | 1308 compile time how many registers the outer mode occupies. */ |
1309 poly_uint64 size = ordered_max (REGMODE_NATURAL_SIZE (shape.inner_mode), | |
1310 GET_MODE_SIZE (shape.outer_mode)); | |
1311 gcc_checking_assert (known_lt (size, GET_MODE_SIZE (shape.inner_mode))); | |
1312 if (known_ge (shape.offset, size)) | |
1298 shape.offset -= size; | 1313 shape.offset -= size; |
1299 else | 1314 else |
1300 shape.offset += size; | 1315 shape.offset += size; |
1301 } | 1316 } |
1302 | 1317 |