Commit 78adc5a0 by Richard Henderson Committed by Richard Henderson

reload1.c (reload_cse_simplify_set): Respect LOAD_EXTEND_OP when replacing a…

reload1.c (reload_cse_simplify_set): Respect LOAD_EXTEND_OP when replacing a memory load with a register.

        * reload1.c (reload_cse_simplify_set): Respect LOAD_EXTEND_OP
        when replacing a memory load with a register.

From-SVN: r39805
parent e2373f95
2001-02-17 Richard Henderson <rth@redhat.com>
* reload1.c (reload_cse_simplify_set): Respect LOAD_EXTEND_OP
when replacing a memory load with a register.
Sat Feb 17 14:48:30 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu> Sat Feb 17 14:48:30 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
Jan Hubicka <jh@suse.cz> Jan Hubicka <jh@suse.cz>
......
...@@ -6665,7 +6665,7 @@ emit_output_reload_insns (chain, rl, j) ...@@ -6665,7 +6665,7 @@ emit_output_reload_insns (chain, rl, j)
/* Copy primary reload reg to secondary reload reg. /* Copy primary reload reg to secondary reload reg.
(Note that these have been swapped above, then (Note that these have been swapped above, then
secondary reload reg to OLD using our insn. */ secondary reload reg to OLD using our insn.) */
/* If REAL_OLD is a paradoxical SUBREG, remove it /* If REAL_OLD is a paradoxical SUBREG, remove it
and try to put the opposite SUBREG on and try to put the opposite SUBREG on
...@@ -8172,6 +8172,9 @@ reload_cse_simplify_set (set, insn) ...@@ -8172,6 +8172,9 @@ reload_cse_simplify_set (set, insn)
int old_cost; int old_cost;
cselib_val *val; cselib_val *val;
struct elt_loc_list *l; struct elt_loc_list *l;
#ifdef LOAD_EXTEND_OP
enum rtx_code extend_op = NIL;
#endif
dreg = true_regnum (SET_DEST (set)); dreg = true_regnum (SET_DEST (set));
if (dreg < 0) if (dreg < 0)
...@@ -8183,6 +8186,18 @@ reload_cse_simplify_set (set, insn) ...@@ -8183,6 +8186,18 @@ reload_cse_simplify_set (set, insn)
dclass = REGNO_REG_CLASS (dreg); dclass = REGNO_REG_CLASS (dreg);
#ifdef LOAD_EXTEND_OP
/* When replacing a memory with a register, we need to honor assumptions
that combine made wrt the contents of sign bits. We'll do this by
generating an extend instruction instead of a reg->reg copy. Thus
the destination must be a register that we can widen. */
if (GET_CODE (src) == MEM
&& GET_MODE_BITSIZE (GET_MODE (src)) < BITS_PER_WORD
&& (extend_op = LOAD_EXTEND_OP (GET_MODE (src))) != NIL
&& GET_CODE (SET_DEST (set)) != REG)
return 0;
#endif
/* If memory loads are cheaper than register copies, don't change them. */ /* If memory loads are cheaper than register copies, don't change them. */
if (GET_CODE (src) == MEM) if (GET_CODE (src) == MEM)
old_cost = MEMORY_MOVE_COST (GET_MODE (src), dclass, 1); old_cost = MEMORY_MOVE_COST (GET_MODE (src), dclass, 1);
...@@ -8200,23 +8215,72 @@ reload_cse_simplify_set (set, insn) ...@@ -8200,23 +8215,72 @@ reload_cse_simplify_set (set, insn)
return 0; return 0;
for (l = val->locs; l; l = l->next) for (l = val->locs; l; l = l->next)
{ {
rtx this_rtx = l->loc;
int this_cost; int this_cost;
if (CONSTANT_P (l->loc) && ! references_value_p (l->loc, 0))
this_cost = rtx_cost (l->loc, SET); if (CONSTANT_P (this_rtx) && ! references_value_p (this_rtx, 0))
else if (GET_CODE (l->loc) == REG) {
this_cost = REGISTER_MOVE_COST (GET_MODE (l->loc), #ifdef LOAD_EXTEND_OP
REGNO_REG_CLASS (REGNO (l->loc)), if (extend_op != NIL)
dclass); {
HOST_WIDE_INT this_val;
/* ??? I'm lazy and don't wish to handle CONST_DOUBLE. Other
constants, such as SYMBOL_REF, cannot be extended. */
if (GET_CODE (this_rtx) != CONST_INT)
continue;
this_val = INTVAL (this_rtx);
switch (extend_op)
{
case ZERO_EXTEND:
this_val &= GET_MODE_MASK (GET_MODE (src));
break;
case SIGN_EXTEND:
/* ??? In theory we're already extended. */
if (this_val == trunc_int_for_mode (this_val, GET_MODE (src)))
break;
default:
abort ();
}
this_val = GEN_INT (this_val);
}
#endif
this_cost = rtx_cost (this_rtx, SET);
}
else if (GET_CODE (this_rtx) == REG)
{
#ifdef LOAD_EXTEND_OP
if (extend_op != NIL)
{
this_rtx = gen_rtx_fmt_e (extend_op, word_mode, this_rtx);
this_cost = rtx_cost (this_rtx, SET);
}
else
#endif
this_cost = REGISTER_MOVE_COST (GET_MODE (this_rtx),
REGNO_REG_CLASS (REGNO (this_rtx)),
dclass);
}
else else
continue; continue;
/* If equal costs, prefer registers over anything else. That tends to
lead to smaller instructions on some machines. */ /* If equal costs, prefer registers over anything else. That
if ((this_cost < old_cost tends to lead to smaller instructions on some machines. */
|| (this_cost == old_cost if (this_cost < old_cost
&& GET_CODE (l->loc) == REG || (this_cost == old_cost
&& GET_CODE (SET_SRC (set)) != REG)) && GET_CODE (this_rtx) == REG
&& validate_change (insn, &SET_SRC (set), copy_rtx (l->loc), 1)) && GET_CODE (SET_SRC (set)) != REG))
old_cost = this_cost, did_change = 1; {
#ifdef LOAD_EXTEND_OP
rtx wide_dest = gen_rtx_REG (word_mode, REGNO (SET_DEST (set)));
ORIGINAL_REGNO (wide_dest) = ORIGINAL_REGNO (SET_DEST (set));
validate_change (insn, &SET_DEST (set), wide_dest, 1);
#endif
validate_change (insn, &SET_SRC (set), copy_rtx (this_rtx), 1);
old_cost = this_cost, did_change = 1;
}
} }
return did_change; return did_change;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment