aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorDJ Delorie <dj@redhat.com>2004-12-06 20:14:40 -0500
committerDJ Delorie <dj@gcc.gnu.org>2004-12-06 20:14:40 -0500
commite11ab33b76c14a58124dbd71991c0adeea736d9b (patch)
tree861e9f14a0b81df68d28f56d761a5d92d63bc7bf /gcc
parente09ec16630ef1ec3dc7d6b512d3eb019e40d0424 (diff)
downloadgcc-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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/reload.c41
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),