summaryrefslogtreecommitdiff
path: root/gcc/reload.c
diff options
context:
space:
mode:
authordj <dj@138bc75d-0d04-0410-961f-82ee72b054a4>2004-12-07 01:14:40 +0000
committerdj <dj@138bc75d-0d04-0410-961f-82ee72b054a4>2004-12-07 01:14:40 +0000
commit8f3b70dd80454ab00aa443d4adcdf9b239c02b94 (patch)
tree861e9f14a0b81df68d28f56d761a5d92d63bc7bf /gcc/reload.c
parent64bdda86ce5b20136e03fb9321e37f090cf17254 (diff)
downloadgcc-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.c41
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),