diff options
author | DJ Delorie <dj@redhat.com> | 2004-12-06 20:14:40 -0500 |
---|---|---|
committer | DJ Delorie <dj@gcc.gnu.org> | 2004-12-06 20:14:40 -0500 |
commit | e11ab33b76c14a58124dbd71991c0adeea736d9b (patch) | |
tree | 861e9f14a0b81df68d28f56d761a5d92d63bc7bf | |
parent | e09ec16630ef1ec3dc7d6b512d3eb019e40d0424 (diff) | |
download | gcc-e11ab33b76c14a58124dbd71991c0adeea736d9b.zip gcc-e11ab33b76c14a58124dbd71991c0adeea736d9b.tar.gz gcc-e11ab33b76c14a58124dbd71991c0adeea736d9b.tar.bz2 |
reload.c (find_valid_class): Fix logic to test inner mode as well.
* reload.c (find_valid_class): Fix logic to test inner mode as well.
(push_reload): Pass inner mode.
From-SVN: r91802
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/reload.c | 41 |
2 files changed, 31 insertions, 15 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2562640..ebc7bae 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2004-12-06 DJ Delorie <dj@redhat.com> + + * reload.c (find_valid_class): Fix logic to test inner mode as well. + (push_reload): Pass inner mode. + 2004-12-06 Eric Christopher <echristo@redhat.com> * doc/tm.texi (TARGET_VALID_POINTER_MODE): Document. diff --git a/gcc/reload.c b/gcc/reload.c index 9e219a0..eec1b0fc 100644 --- a/gcc/reload.c +++ b/gcc/reload.c @@ -240,7 +240,8 @@ static int push_secondary_reload (int, rtx, int, int, enum reg_class, enum machine_mode, enum reload_type, enum insn_code *); #endif -static enum reg_class find_valid_class (enum machine_mode, int, unsigned int); +static enum reg_class find_valid_class (enum machine_mode, enum machine_mode, + int, unsigned int); static int reload_inner_reg_of_subreg (rtx, enum machine_mode, int); static void push_replacement (rtx *, int, enum machine_mode); static void dup_replacements (rtx *, rtx *); @@ -659,12 +660,15 @@ clear_secondary_mem (void) } #endif /* SECONDARY_MEMORY_NEEDED */ -/* Find the largest class for which every register number plus N is valid in - M1 (if in range) and is cheap to move into REGNO. - Abort if no such class exists. */ + +/* Find the largest class which has at least one register valid in + mode INNER, and which for every such register, that register number + plus N is also valid in OUTER (if in range) and is cheap to move + into REGNO. Abort if no such class exists. */ static enum reg_class -find_valid_class (enum machine_mode m1 ATTRIBUTE_UNUSED, int n, +find_valid_class (enum machine_mode outer ATTRIBUTE_UNUSED, + enum machine_mode inner ATTRIBUTE_UNUSED, int n, unsigned int dest_regno ATTRIBUTE_UNUSED) { int best_cost = -1; @@ -678,15 +682,22 @@ find_valid_class (enum machine_mode m1 ATTRIBUTE_UNUSED, int n, for (class = 1; class < N_REG_CLASSES; class++) { int bad = 0; - for (regno = 0; regno < FIRST_PSEUDO_REGISTER && ! bad; regno++) - if (TEST_HARD_REG_BIT (reg_class_contents[class], regno) - && TEST_HARD_REG_BIT (reg_class_contents[class], regno + n) - && ! HARD_REGNO_MODE_OK (regno + n, m1)) - bad = 1; + int good = 0; + for (regno = 0; regno < FIRST_PSEUDO_REGISTER - n && ! bad; regno++) + if (TEST_HARD_REG_BIT (reg_class_contents[class], regno)) + { + if (HARD_REGNO_MODE_OK (regno, inner)) + { + good = 1; + if (! TEST_HARD_REG_BIT (reg_class_contents[class], regno + n) + || ! HARD_REGNO_MODE_OK (regno + n, outer)) + bad = 1; + } + } - if (bad) + if (bad || !good) continue; - cost = REGISTER_MOVE_COST (m1, class, dest_class); + cost = REGISTER_MOVE_COST (outer, class, dest_class); if ((reg_class_size[class] > best_size && (best_cost < 0 || best_cost >= cost)) @@ -694,7 +705,7 @@ find_valid_class (enum machine_mode m1 ATTRIBUTE_UNUSED, int n, { best_class = class; best_size = reg_class_size[class]; - best_cost = REGISTER_MOVE_COST (m1, class, dest_class); + best_cost = REGISTER_MOVE_COST (outer, class, dest_class); } } @@ -1083,7 +1094,7 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc, if (REG_P (SUBREG_REG (in))) in_class - = find_valid_class (inmode, + = find_valid_class (inmode, GET_MODE (SUBREG_REG (in)), subreg_regno_offset (REGNO (SUBREG_REG (in)), GET_MODE (SUBREG_REG (in)), SUBREG_BYTE (in), @@ -1180,7 +1191,7 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc, dont_remove_subreg = 1; push_reload (SUBREG_REG (out), SUBREG_REG (out), &SUBREG_REG (out), &SUBREG_REG (out), - find_valid_class (outmode, + find_valid_class (outmode, GET_MODE (SUBREG_REG (out)), subreg_regno_offset (REGNO (SUBREG_REG (out)), GET_MODE (SUBREG_REG (out)), SUBREG_BYTE (out), |