*** empty log message ***

From-SVN: r790
This commit is contained in:
Richard Kenner 1992-04-18 22:12:25 -04:00
parent c8332879d8
commit e5f6a288fb
2 changed files with 153 additions and 17 deletions

100
gcc/cse.c
View File

@ -453,7 +453,7 @@ struct table_elt
: (FIXED_REGNO_P (REGNO (X)) \
&& REGNO_REG_CLASS (REGNO (X)) != NO_REGS) ? 0 \
: 2) \
: rtx_cost (X) * 2) \
: rtx_cost (X, SET) * 2)
/* Determine if the quantity number for register X represents a valid index
into the `qty_...' variables. */
@ -569,8 +569,9 @@ static void cse_set_around_loop ();
#define COSTS_N_INSNS(N) ((N) * 4 - 2)
int
rtx_cost (x)
rtx_cost (x, outer_code)
rtx x;
enum rtx_code outer_code;
{
register int i, j;
register enum rtx_code code;
@ -627,9 +628,9 @@ rtx_cost (x)
+ GET_MODE_SIZE (GET_MODE (x)) / UNITS_PER_WORD);
return 2;
#ifdef RTX_COSTS
RTX_COSTS (x, code);
RTX_COSTS (x, code, outer_code);
#endif
CONST_COSTS (x, code);
CONST_COSTS (x, code, outer_code);
}
/* Sum the costs of the sub-rtx's, plus cost of this operation,
@ -638,10 +639,10 @@ rtx_cost (x)
fmt = GET_RTX_FORMAT (code);
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
if (fmt[i] == 'e')
total += rtx_cost (XEXP (x, i));
total += rtx_cost (XEXP (x, i), code);
else if (fmt[i] == 'E')
for (j = 0; j < XVECLEN (x, i); j++)
total += rtx_cost (XVECEXP (x, i, j));
total += rtx_cost (XVECEXP (x, i, j), code);
return total;
}
@ -815,7 +816,7 @@ mention_regs (x)
register int changed = 0;
if (x == 0)
return;
return 0;
code = GET_CODE (x);
if (code == REG)
@ -4157,6 +4158,11 @@ fold_rtx (x, insn)
&& (new = lookup_as_function (x, CONST_INT)) != 0)
return new;
/* If this is a paradoxical SUBREG, we can't do anything with
it because we have no idea what value the extra bits would have. */
if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
return x;
/* Fold SUBREG_REG. If it changed, see if we can simplify the SUBREG.
We might be able to if the SUBREG is extracting a single word in an
integral mode or extracting the low part. */
@ -4180,6 +4186,86 @@ fold_rtx (x, insn)
if (new)
return new;
}
/* If this is a narrowing SUBREG and our operand is a REG, see if
we can find an equivalence for REG that is a arithmetic operation
in a wider mode where both operands are paradoxical SUBREGs
from objects of our result mode. In that case, we couldn't report
an equivalent value for that operation, since we don't know what the
extra bits will be. But we can find an equivalence for this SUBREG
by folding that operation is the narrow mode. This allows us to
fold arithmetic in narrow modes when the machine only supports
word-sized arithmetic. */
if (GET_CODE (folded_arg0) == REG
&& GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (folded_arg0)))
{
struct table_elt *elt;
/* We can use HASH here since we know that canon_hash won't be
called. */
elt = lookup (folded_arg0,
HASH (folded_arg0, GET_MODE (folded_arg0)),
GET_MODE (folded_arg0));
if (elt)
elt = elt->first_same_value;
for (; elt; elt = elt->next_same_value)
{
/* Just check for unary and binary operations. */
if (GET_RTX_CLASS (GET_CODE (elt->exp)) == '1'
&& GET_CODE (elt->exp) != SIGN_EXTEND
&& GET_CODE (elt->exp) != ZERO_EXTEND
&& GET_CODE (XEXP (elt->exp, 0)) == SUBREG
&& GET_MODE (SUBREG_REG (XEXP (elt->exp, 0))) == mode)
{
rtx op0 = SUBREG_REG (XEXP (elt->exp, 0));
if (GET_CODE (op0) != REG && ! CONSTANT_P (op0))
op0 = fold_rtx (op0, 0);
op0 = equiv_constant (op0);
if (op0)
new = simplify_unary_operation (GET_CODE (elt->exp), mode,
op0, mode);
}
else if ((GET_RTX_CLASS (GET_CODE (elt->exp)) == '2'
|| GET_RTX_CLASS (GET_CODE (elt->exp)) == 'c')
&& ((GET_CODE (XEXP (elt->exp, 0)) == SUBREG
&& (GET_MODE (SUBREG_REG (XEXP (elt->exp, 0)))
== mode))
|| CONSTANT_P (XEXP (elt->exp, 0)))
&& ((GET_CODE (XEXP (elt->exp, 1)) == SUBREG
&& (GET_MODE (SUBREG_REG (XEXP (elt->exp, 1)))
== mode))
|| CONSTANT_P (XEXP (elt->exp, 1))))
{
rtx op0 = gen_lowpart_common (mode, XEXP (elt->exp, 0));
rtx op1 = gen_lowpart_common (mode, XEXP (elt->exp, 1));
if (op0 && GET_CODE (op0) != REG && ! CONSTANT_P (op0))
op0 = fold_rtx (op0, 0);
if (op0)
op0 = equiv_constant (op0);
if (op1 && GET_CODE (op1) != REG && ! CONSTANT_P (op1))
op1 = fold_rtx (op1, 0);
if (op1)
op1 = equiv_constant (op1);
if (op0 && op1)
new = simplify_binary_operation (GET_CODE (elt->exp), mode,
op0, op1);
}
if (new)
return new;
}
}
return x;
case NOT:

View File

@ -47,12 +47,20 @@ static int insn_index_number;
struct clobber_pat
{
int code_number; /* Counts only insns. */
struct clobber_ent *insns;
rtx pattern;
int first_clobber;
struct clobber_pat *next;
} *clobber_list;
/* Records one insn that uses the clobber list. */
struct clobber_ent
{
int code_number; /* Counts only insns. */
struct clobber_ent *next;
};
static void
max_operand_1 (x)
rtx x;
@ -271,14 +279,54 @@ gen_insn (insn)
if (i != XVECLEN (insn, 1) - 1)
{
register struct clobber_pat *new
= (struct clobber_pat *) xmalloc (sizeof (struct clobber_pat));
register struct clobber_pat *p;
register struct clobber_ent *link
= (struct clobber_ent *) xmalloc (sizeof (struct clobber_ent));
register int j;
link->code_number = insn_code_number;
/* See if any previous CLOBBER_LIST entry is the same as this
one. */
for (p = clobber_list; p; p = p->next)
{
if (p->first_clobber != i + 1
|| XVECLEN (p->pattern, 1) != XVECLEN (insn, 1))
continue;
for (j = i + 1; j < XVECLEN (insn, 1); j++)
{
rtx old = XEXP (XVECEXP (p->pattern, 1, j), 0);
rtx new = XEXP (XVECEXP (insn, 1, j), 0);
/* OLD and NEW are the same if both are to be a SCRATCH
or if both are registers of the same mode and number. */
if (! ((GET_CODE (old) == MATCH_SCRATCH
&& GET_CODE (new) == MATCH_SCRATCH)
|| (GET_CODE (old) == REG && GET_CODE (new) == REG
&& GET_MODE (old) == GET_MODE (new)
&& REGNO (old) == REGNO (new))))
break;
}
if (j == XVECLEN (insn, 1))
break;
}
if (p == 0)
{
p = (struct clobber_pat *) xmalloc (sizeof (struct clobber_pat));
new->code_number = insn_code_number;
new->pattern = insn;
new->first_clobber = i + 1;
new->next = clobber_list;
clobber_list = new;
p->insns = 0;
p->pattern = insn;
p->first_clobber = i + 1;
p->next = clobber_list;
clobber_list = p;
}
link->next = p->insns;
p->insns = link;
}
}
@ -547,6 +595,7 @@ static void
output_add_clobbers ()
{
struct clobber_pat *clobber;
struct clobber_ent *ent;
int i;
printf ("\n\nvoid\nadd_clobbers (pattern, insn_code_number)\n");
@ -558,7 +607,8 @@ output_add_clobbers ()
for (clobber = clobber_list; clobber; clobber = clobber->next)
{
printf (" case %d:\n", clobber->code_number);
for (ent = clobber->insns; ent; ent = ent->next)
printf (" case %d:\n", ent->code_number);
for (i = clobber->first_clobber; i < XVECLEN (clobber->pattern, 1); i++)
{
@ -567,7 +617,7 @@ output_add_clobbers ()
printf (";\n");
}
printf (" break;\n");
printf (" break;\n\n");
}
printf (" default:\n");