diff options
author | dj <dj@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-12-07 01:14:40 +0000 |
---|---|---|
committer | dj <dj@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-12-07 01:14:40 +0000 |
commit | 8f3b70dd80454ab00aa443d4adcdf9b239c02b94 (patch) | |
tree | 861e9f14a0b81df68d28f56d761a5d92d63bc7bf /gcc/reload.c | |
parent | 64bdda86ce5b20136e03fb9321e37f090cf17254 (diff) | |
download | gcc-8f3b70dd80454ab00aa443d4adcdf9b239c02b94.tar.gz |
* reload.c (find_valid_class): Fix logic to test inner mode as well.
(push_reload): Pass inner mode.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@91802 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/reload.c')
-rw-r--r-- | gcc/reload.c | 41 |
1 files changed, 26 insertions, 15 deletions
diff --git a/gcc/reload.c b/gcc/reload.c index 9e219a0978c..eec1b0fcf52 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), |