Commit a2d353e5 by Richard Kenner

(find_reloads): Don't restrict class of multiword operand to preferred class.

(find_reloads_address_1): Rework to use `switch'.
Reload a SUBREG of a hard reg as a unit.

From-SVN: r6622
parent 8bffcaf6
...@@ -2971,18 +2971,16 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p) ...@@ -2971,18 +2971,16 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
Don't bother with this if this alternative will accept this Don't bother with this if this alternative will accept this
operand. operand.
Don't do this for a multiword operand, if Don't do this for a multiword operand, since it is only a
we have to worry about small classes, because making reg groups small win and has the risk of requiring more spill registers,
harder to allocate is asking for trouble. which could cause a large loss.
Don't do this if the preferred class has only one register Don't do this if the preferred class has only one register
because we might otherwise exhaust the class. */ because we might otherwise exhaust the class. */
if (! win && this_alternative[i] != (int) NO_REGS if (! win && this_alternative[i] != (int) NO_REGS
#ifdef SMALL_REGISTER_CLASSES
&& GET_MODE_SIZE (operand_mode[i]) <= UNITS_PER_WORD && GET_MODE_SIZE (operand_mode[i]) <= UNITS_PER_WORD
#endif
&& reg_class_size[(int) preferred_class[i]] > 1) && reg_class_size[(int) preferred_class[i]] > 1)
{ {
if (! reg_class_subset_p (this_alternative[i], if (! reg_class_subset_p (this_alternative[i],
...@@ -4408,7 +4406,9 @@ find_reloads_address_1 (x, context, loc, opnum, type, ind_levels) ...@@ -4408,7 +4406,9 @@ find_reloads_address_1 (x, context, loc, opnum, type, ind_levels)
{ {
register RTX_CODE code = GET_CODE (x); register RTX_CODE code = GET_CODE (x);
if (code == PLUS) switch (code)
{
case PLUS:
{ {
register rtx orig_op0 = XEXP (x, 0); register rtx orig_op0 = XEXP (x, 0);
register rtx orig_op1 = XEXP (x, 1); register rtx orig_op1 = XEXP (x, 1);
...@@ -4422,6 +4422,7 @@ find_reloads_address_1 (x, context, loc, opnum, type, ind_levels) ...@@ -4422,6 +4422,7 @@ find_reloads_address_1 (x, context, loc, opnum, type, ind_levels)
op0 = SUBREG_REG (op0); op0 = SUBREG_REG (op0);
code0 = GET_CODE (op0); code0 = GET_CODE (op0);
} }
if (GET_CODE (op1) == SUBREG) if (GET_CODE (op1) == SUBREG)
{ {
op1 = SUBREG_REG (op1); op1 = SUBREG_REG (op1);
...@@ -4435,6 +4436,7 @@ find_reloads_address_1 (x, context, loc, opnum, type, ind_levels) ...@@ -4435,6 +4436,7 @@ find_reloads_address_1 (x, context, loc, opnum, type, ind_levels)
find_reloads_address_1 (orig_op1, 0, &XEXP (x, 1), opnum, type, find_reloads_address_1 (orig_op1, 0, &XEXP (x, 1), opnum, type,
ind_levels); ind_levels);
} }
else if (code1 == MULT || code1 == SIGN_EXTEND || code0 == MEM) else if (code1 == MULT || code1 == SIGN_EXTEND || code0 == MEM)
{ {
find_reloads_address_1 (orig_op0, 0, &XEXP (x, 0), opnum, type, find_reloads_address_1 (orig_op0, 0, &XEXP (x, 0), opnum, type,
...@@ -4442,12 +4444,17 @@ find_reloads_address_1 (x, context, loc, opnum, type, ind_levels) ...@@ -4442,12 +4444,17 @@ find_reloads_address_1 (x, context, loc, opnum, type, ind_levels)
find_reloads_address_1 (orig_op1, 1, &XEXP (x, 1), opnum, type, find_reloads_address_1 (orig_op1, 1, &XEXP (x, 1), opnum, type,
ind_levels); ind_levels);
} }
else if (code0 == CONST_INT || code0 == CONST else if (code0 == CONST_INT || code0 == CONST
|| code0 == SYMBOL_REF || code0 == LABEL_REF) || code0 == SYMBOL_REF || code0 == LABEL_REF)
find_reloads_address_1 (orig_op1, 0, &XEXP (x, 1), opnum, type, ind_levels); find_reloads_address_1 (orig_op1, 0, &XEXP (x, 1), opnum, type,
ind_levels);
else if (code1 == CONST_INT || code1 == CONST else if (code1 == CONST_INT || code1 == CONST
|| code1 == SYMBOL_REF || code1 == LABEL_REF) || code1 == SYMBOL_REF || code1 == LABEL_REF)
find_reloads_address_1 (orig_op0, 0, &XEXP (x, 0), opnum, type, ind_levels); find_reloads_address_1 (orig_op0, 0, &XEXP (x, 0), opnum, type,
ind_levels);
else if (code0 == REG && code1 == REG) else if (code0 == REG && code1 == REG)
{ {
if (REG_OK_FOR_INDEX_P (op0) if (REG_OK_FOR_INDEX_P (op0)
...@@ -4476,6 +4483,7 @@ find_reloads_address_1 (x, context, loc, opnum, type, ind_levels) ...@@ -4476,6 +4483,7 @@ find_reloads_address_1 (x, context, loc, opnum, type, ind_levels)
ind_levels); ind_levels);
} }
} }
else if (code0 == REG) else if (code0 == REG)
{ {
find_reloads_address_1 (orig_op0, 1, &XEXP (x, 0), opnum, type, find_reloads_address_1 (orig_op0, 1, &XEXP (x, 0), opnum, type,
...@@ -4483,6 +4491,7 @@ find_reloads_address_1 (x, context, loc, opnum, type, ind_levels) ...@@ -4483,6 +4491,7 @@ find_reloads_address_1 (x, context, loc, opnum, type, ind_levels)
find_reloads_address_1 (orig_op1, 0, &XEXP (x, 1), opnum, type, find_reloads_address_1 (orig_op1, 0, &XEXP (x, 1), opnum, type,
ind_levels); ind_levels);
} }
else if (code1 == REG) else if (code1 == REG)
{ {
find_reloads_address_1 (orig_op1, 1, &XEXP (x, 1), opnum, type, find_reloads_address_1 (orig_op1, 1, &XEXP (x, 1), opnum, type,
...@@ -4491,9 +4500,13 @@ find_reloads_address_1 (x, context, loc, opnum, type, ind_levels) ...@@ -4491,9 +4500,13 @@ find_reloads_address_1 (x, context, loc, opnum, type, ind_levels)
ind_levels); ind_levels);
} }
} }
else if (code == POST_INC || code == POST_DEC
|| code == PRE_INC || code == PRE_DEC) return 0;
{
case POST_INC:
case POST_DEC:
case PRE_INC:
case PRE_DEC:
if (GET_CODE (XEXP (x, 0)) == REG) if (GET_CODE (XEXP (x, 0)) == REG)
{ {
register int regno = REGNO (XEXP (x, 0)); register int regno = REGNO (XEXP (x, 0));
...@@ -4559,6 +4572,7 @@ find_reloads_address_1 (x, context, loc, opnum, type, ind_levels) ...@@ -4559,6 +4572,7 @@ find_reloads_address_1 (x, context, loc, opnum, type, ind_levels)
} }
return value; return value;
} }
else if (GET_CODE (XEXP (x, 0)) == MEM) else if (GET_CODE (XEXP (x, 0)) == MEM)
{ {
/* This is probably the result of a substitution, by eliminate_regs, /* This is probably the result of a substitution, by eliminate_regs,
...@@ -4591,16 +4605,16 @@ find_reloads_address_1 (x, context, loc, opnum, type, ind_levels) ...@@ -4591,16 +4605,16 @@ find_reloads_address_1 (x, context, loc, opnum, type, ind_levels)
return 1; return 1;
} }
} return 0;
else if (code == MEM)
{
/* This is probably the result of a substitution, by eliminate_regs,
of an equivalent address for a pseudo that was not allocated to a
hard register. Verify that the specified address is valid and reload
it into a register.
Since we know we are going to reload this item, don't decrement case MEM:
for the indirection level. /* This is probably the result of a substitution, by eliminate_regs, of
an equivalent address for a pseudo that was not allocated to a hard
register. Verify that the specified address is valid and reload it
into a register.
Since we know we are going to reload this item, don't decrement for
the indirection level.
Note that this is actually conservative: it would be slightly more Note that this is actually conservative: it would be slightly more
efficient to use the value of SPILL_INDIRECT_LEVELS from efficient to use the value of SPILL_INDIRECT_LEVELS from
...@@ -4608,13 +4622,12 @@ find_reloads_address_1 (x, context, loc, opnum, type, ind_levels) ...@@ -4608,13 +4622,12 @@ find_reloads_address_1 (x, context, loc, opnum, type, ind_levels)
find_reloads_address (GET_MODE (x), loc, XEXP (x, 0), &XEXP (x, 0), find_reloads_address (GET_MODE (x), loc, XEXP (x, 0), &XEXP (x, 0),
opnum, type, ind_levels); opnum, type, ind_levels);
push_reload (*loc, NULL_RTX, loc, NULL_PTR, push_reload (*loc, NULL_RTX, loc, NULL_PTR,
context ? INDEX_REG_CLASS : BASE_REG_CLASS, context ? INDEX_REG_CLASS : BASE_REG_CLASS,
GET_MODE (x), VOIDmode, 0, 0, opnum, type); GET_MODE (x), VOIDmode, 0, 0, opnum, type);
return 1; return 1;
}
else if (code == REG) case REG:
{ {
register int regno = REGNO (x); register int regno = REGNO (x);
...@@ -4637,6 +4650,7 @@ find_reloads_address_1 (x, context, loc, opnum, type, ind_levels) ...@@ -4637,6 +4650,7 @@ find_reloads_address_1 (x, context, loc, opnum, type, ind_levels)
return 1; return 1;
} }
#endif #endif
if (reg_equiv_address[regno] != 0) if (reg_equiv_address[regno] != 0)
{ {
x = make_memloc (x, regno); x = make_memloc (x, regno);
...@@ -4646,6 +4660,7 @@ find_reloads_address_1 (x, context, loc, opnum, type, ind_levels) ...@@ -4646,6 +4660,7 @@ find_reloads_address_1 (x, context, loc, opnum, type, ind_levels)
if (reg_renumber[regno] >= 0) if (reg_renumber[regno] >= 0)
regno = reg_renumber[regno]; regno = reg_renumber[regno];
if ((regno >= FIRST_PSEUDO_REGISTER if ((regno >= FIRST_PSEUDO_REGISTER
|| !(context ? REGNO_OK_FOR_INDEX_P (regno) || !(context ? REGNO_OK_FOR_INDEX_P (regno)
: REGNO_OK_FOR_BASE_P (regno)))) : REGNO_OK_FOR_BASE_P (regno))))
...@@ -4668,10 +4683,33 @@ find_reloads_address_1 (x, context, loc, opnum, type, ind_levels) ...@@ -4668,10 +4683,33 @@ find_reloads_address_1 (x, context, loc, opnum, type, ind_levels)
return 1; return 1;
} }
} }
else return 0;
case SUBREG:
/* If this is a SUBREG of a hard register and the resulting register is
of the wrong class, reload the whole SUBREG. This avoids needless
copies if SUBREG_REG is multi-word. */
if (GET_CODE (SUBREG_REG (x)) == REG
&& REGNO (SUBREG_REG (x)) < FIRST_PSEUDO_REGISTER)
{
int regno = REGNO (SUBREG_REG (x)) + SUBREG_WORD (x);
if (! (context ? REGNO_OK_FOR_INDEX_P (regno)
: REGNO_OK_FOR_BASE_P (regno)))
{
push_reload (x, NULL_RTX, loc, NULL_PTR,
context ? INDEX_REG_CLASS : BASE_REG_CLASS,
GET_MODE (x), VOIDmode, 0, 0, opnum, type);
return 1;
}
}
break;
}
{ {
register char *fmt = GET_RTX_FORMAT (code); register char *fmt = GET_RTX_FORMAT (code);
register int i; register int i;
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
{ {
if (fmt[i] == 'e') if (fmt[i] == 'e')
......
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