Move quantity tables and register equivalence chains into
per-qty and per-register structure arrays respectively. From-SVN: r30717
This commit is contained in:
parent
de96bf571d
commit
1bb98cecc6
@ -1,3 +1,20 @@
|
||||
1999-11-29 David S. Miller <davem@redhat.com>
|
||||
|
||||
Move quantity tables and register equivalence chains into
|
||||
per-qty and per-register structure arrays respectively.
|
||||
* cse.c (qty_first_reg, qty_last_reg, qty_mode, qty_const,
|
||||
qty_const_insn, qty_comparison_code, qty_comparison_const,
|
||||
qty_comparison_qty): Delete, replace with...
|
||||
(qty_table): this structure table.
|
||||
(reg_next_eqv, reg_prev_eqv): Delete, replace with...
|
||||
(reg_eqv_table): this structure table.
|
||||
(make_new_qty): Add argument MODE. Caller updated.
|
||||
Update to use qty_table and reg_eqv_table.
|
||||
(make_regs_eqv, delete_reg_equiv, insert_regs,
|
||||
insert, exp_equiv_p, cse_rtx_varies_p, canon_reg,
|
||||
fold_rtx, equiv_constant, record_jump_cond, cse_insn,
|
||||
cse_process_notes, cse_main, cse_basic_block): Likewise.
|
||||
|
||||
Mon Nov 29 16:56:42 1999 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
|
||||
|
||||
* fold-const.c (extract_muldiv, case {MIN,MAX}_EXPR): Reverse
|
||||
|
636
gcc/cse.c
636
gcc/cse.c
@ -55,8 +55,8 @@ Boston, MA 02111-1307, USA. */
|
||||
optimizer after CSE to delete the unreachable code.
|
||||
|
||||
We use two data structures to record the equivalent expressions:
|
||||
a hash table for most expressions, and several vectors together
|
||||
with "quantity numbers" to record equivalent (pseudo) registers.
|
||||
a hash table for most expressions, and a vector of "quantity
|
||||
numbers" to record equivalent (pseudo) registers.
|
||||
|
||||
The use of the special data structure for registers is desirable
|
||||
because it is faster. It is possible because registers references
|
||||
@ -81,19 +81,19 @@ Registers and "quantity numbers":
|
||||
All real quantity numbers are greater than or equal to `max_reg'.
|
||||
If register N has not been assigned a quantity, reg_qty[N] will equal N.
|
||||
|
||||
Quantity numbers below `max_reg' do not exist and none of the `qty_...'
|
||||
variables should be referenced with an index below `max_reg'.
|
||||
Quantity numbers below `max_reg' do not exist and none of the `qty_table'
|
||||
entries should be referenced with an index below `max_reg'.
|
||||
|
||||
We also maintain a bidirectional chain of registers for each
|
||||
quantity number. `qty_first_reg', `qty_last_reg',
|
||||
`reg_next_eqv' and `reg_prev_eqv' hold these chains.
|
||||
quantity number. The `qty_table` members `first_reg' and `last_reg',
|
||||
and `reg_eqv_table' members `next' and `prev' hold these chains.
|
||||
|
||||
The first register in a chain is the one whose lifespan is least local.
|
||||
Among equals, it is the one that was seen first.
|
||||
We replace any equivalent register with that one.
|
||||
|
||||
If two registers have the same quantity number, it must be true that
|
||||
REG expressions with `qty_mode' must be in the hash table for both
|
||||
REG expressions with qty_table `mode' must be in the hash table for both
|
||||
registers and must be in the same class.
|
||||
|
||||
The converse is not true. Since hard registers may be referenced in
|
||||
@ -104,7 +104,7 @@ Registers and "quantity numbers":
|
||||
Constants and quantity numbers
|
||||
|
||||
When a quantity has a known constant value, that value is stored
|
||||
in the appropriate element of qty_const. This is in addition to
|
||||
in the appropriate qty_table `const_rtx'. This is in addition to
|
||||
putting the constant in the hash table as is usual for non-regs.
|
||||
|
||||
Whether a reg or a constant is preferred is determined by the configuration
|
||||
@ -112,8 +112,8 @@ Constants and quantity numbers
|
||||
event, expressions containing constants can be simplified, by fold_rtx.
|
||||
|
||||
When a quantity has a known nearly constant value (such as an address
|
||||
of a stack slot), that value is stored in the appropriate element
|
||||
of qty_const.
|
||||
of a stack slot), that value is stored in the appropriate qty_table
|
||||
`const_rtx'.
|
||||
|
||||
Integer constants don't have a machine mode. However, cse
|
||||
determines the intended machine mode from the destination
|
||||
@ -133,7 +133,7 @@ Other expressions:
|
||||
currently have equivalent values.
|
||||
|
||||
Register references in an expression are canonicalized before hashing
|
||||
the expression. This is done using `reg_qty' and `qty_first_reg'.
|
||||
the expression. This is done using `reg_qty' and qty_table `first_reg'.
|
||||
The hash code of a register reference is computed using the quantity
|
||||
number, not the register number.
|
||||
|
||||
@ -205,8 +205,8 @@ static int max_reg;
|
||||
|
||||
static int max_insn_uid;
|
||||
|
||||
/* Length of vectors indexed by quantity number.
|
||||
We know in advance we will not need a quantity number this big. */
|
||||
/* Length of qty_table vector. We know in advance we will not need
|
||||
a quantity number this big. */
|
||||
|
||||
static int max_qty;
|
||||
|
||||
@ -215,48 +215,44 @@ static int max_qty;
|
||||
|
||||
static int next_qty;
|
||||
|
||||
/* Indexed by quantity number, gives the first (or last) register
|
||||
in the chain of registers that currently contain this quantity. */
|
||||
/* Per-qty information tracking.
|
||||
|
||||
static int *qty_first_reg;
|
||||
static int *qty_last_reg;
|
||||
`first_reg' and `last_reg' track the head and tail of the
|
||||
chain of registers which currently contain this quantity.
|
||||
|
||||
/* Index by quantity number, gives the mode of the quantity. */
|
||||
`mode' contains the machine mode of this quantity.
|
||||
|
||||
static enum machine_mode *qty_mode;
|
||||
`const_rtx' holds the rtx of the constant value of this
|
||||
quantity, if known. A summations of the frame/arg pointer
|
||||
and a constant can also be entered here. When this holds
|
||||
a known value, `const_insn' is the insn which stored the
|
||||
constant value.
|
||||
|
||||
/* Indexed by quantity number, gives the rtx of the constant value of the
|
||||
quantity, or zero if it does not have a known value.
|
||||
A sum of the frame pointer (or arg pointer) plus a constant
|
||||
can also be entered here. */
|
||||
`comparison_{code,const,qty}' are used to track when a
|
||||
comparison between a quantity and some constant or register has
|
||||
been passed. In such a case, we know the results of the comparison
|
||||
in case we see it again. These members record a comparison that
|
||||
is known to be true. `comparison_code' holds the rtx code of such
|
||||
a comparison, else it is set to UNKNOWN and the other two
|
||||
comparison members are undefined. `comparison_const' holds
|
||||
the constant being compared against, or zero if the comparison
|
||||
is not against a constant. `comparison_qty' holds the quantity
|
||||
being compared against when the result is known. If the comparison
|
||||
is not with a register, `comparison_qty' is -1. */
|
||||
|
||||
static rtx *qty_const;
|
||||
struct qty_table_elem
|
||||
{
|
||||
rtx const_rtx;
|
||||
rtx const_insn;
|
||||
rtx comparison_const;
|
||||
int comparison_qty;
|
||||
int first_reg, last_reg;
|
||||
enum machine_mode mode;
|
||||
enum rtx_code comparison_code;
|
||||
};
|
||||
|
||||
/* Indexed by qty number, gives the insn that stored the constant value
|
||||
recorded in `qty_const'. */
|
||||
|
||||
static rtx *qty_const_insn;
|
||||
|
||||
/* The next three variables are used to track when a comparison between a
|
||||
quantity and some constant or register has been passed. In that case, we
|
||||
know the results of the comparison in case we see it again. These variables
|
||||
record a comparison that is known to be true. */
|
||||
|
||||
/* Indexed by qty number, gives the rtx code of a comparison with a known
|
||||
result involving this quantity. If none, it is UNKNOWN. */
|
||||
static enum rtx_code *qty_comparison_code;
|
||||
|
||||
/* Indexed by qty number, gives the constant being compared against in a
|
||||
comparison of known result. If no such comparison, it is undefined.
|
||||
If the comparison is not with a constant, it is zero. */
|
||||
|
||||
static rtx *qty_comparison_const;
|
||||
|
||||
/* Indexed by qty number, gives the quantity being compared against in a
|
||||
comparison of known result. If no such comparison, if it undefined.
|
||||
If the comparison is not with a register, it is -1. */
|
||||
|
||||
static int *qty_comparison_qty;
|
||||
/* The table of all qtys, indexed by qty number. */
|
||||
static struct qty_table_elem *qty_table;
|
||||
|
||||
#ifdef HAVE_cc0
|
||||
/* For machines that have a CC0, we do not record its value in the hash
|
||||
@ -286,10 +282,16 @@ static rtx this_insn;
|
||||
|
||||
Or -1 if this register is at the end of the chain.
|
||||
|
||||
If reg_qty[N] == N, reg_next_eqv[N] is undefined. */
|
||||
If reg_qty[N] == N, reg_eqv_table[N].next is undefined. */
|
||||
|
||||
static int *reg_next_eqv;
|
||||
static int *reg_prev_eqv;
|
||||
/* Per-register equivalence chain. */
|
||||
struct reg_eqv_elem
|
||||
{
|
||||
int next, prev;
|
||||
};
|
||||
|
||||
/* The table of all register equivalence chains. */
|
||||
static struct reg_eqv_elem *reg_eqv_table;
|
||||
|
||||
struct cse_reg_info
|
||||
{
|
||||
@ -519,7 +521,7 @@ struct table_elt
|
||||
#define REG_QTY(N) ((GET_CSE_REG_INFO (N))->reg_qty)
|
||||
|
||||
/* Determine if the quantity number for register X represents a valid index
|
||||
into the `qty_...' variables. */
|
||||
into the qty_table. */
|
||||
|
||||
#define REGNO_QTY_VALID_P(N) (REG_QTY (N) != (N))
|
||||
|
||||
@ -643,7 +645,7 @@ struct cse_basic_block_data
|
||||
|
||||
static int notreg_cost PROTO((rtx));
|
||||
static void new_basic_block PROTO((void));
|
||||
static void make_new_qty PROTO((int));
|
||||
static void make_new_qty PROTO((int, enum machine_mode));
|
||||
static void make_regs_eqv PROTO((int, int));
|
||||
static void delete_reg_equiv PROTO((int));
|
||||
static int mention_regs PROTO((rtx));
|
||||
@ -950,25 +952,31 @@ new_basic_block ()
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Say that register REG contains a quantity not in any register before
|
||||
and initialize that quantity. */
|
||||
/* Say that register REG contains a quantity in mode MODE not in any
|
||||
register before and initialize that quantity. */
|
||||
|
||||
static void
|
||||
make_new_qty (reg)
|
||||
make_new_qty (reg, mode)
|
||||
register int reg;
|
||||
register enum machine_mode mode;
|
||||
{
|
||||
register int q;
|
||||
register struct qty_table_elem *ent;
|
||||
register struct reg_eqv_elem *eqv;
|
||||
|
||||
if (next_qty >= max_qty)
|
||||
abort ();
|
||||
|
||||
q = REG_QTY (reg) = next_qty++;
|
||||
qty_first_reg[q] = reg;
|
||||
qty_last_reg[q] = reg;
|
||||
qty_const[q] = qty_const_insn[q] = 0;
|
||||
qty_comparison_code[q] = UNKNOWN;
|
||||
ent = &qty_table[q];
|
||||
ent->first_reg = reg;
|
||||
ent->last_reg = reg;
|
||||
ent->mode = mode;
|
||||
ent->const_rtx = ent->const_insn = NULL_RTX;
|
||||
ent->comparison_code = UNKNOWN;
|
||||
|
||||
reg_next_eqv[reg] = reg_prev_eqv[reg] = -1;
|
||||
eqv = ®_eqv_table[reg];
|
||||
eqv->next = eqv->prev = -1;
|
||||
}
|
||||
|
||||
/* Make reg NEW equivalent to reg OLD.
|
||||
@ -980,14 +988,17 @@ make_regs_eqv (new, old)
|
||||
{
|
||||
register int lastr, firstr;
|
||||
register int q = REG_QTY (old);
|
||||
register struct qty_table_elem *ent;
|
||||
|
||||
ent = &qty_table[q];
|
||||
|
||||
/* Nothing should become eqv until it has a "non-invalid" qty number. */
|
||||
if (! REGNO_QTY_VALID_P (old))
|
||||
abort ();
|
||||
|
||||
REG_QTY (new) = q;
|
||||
firstr = qty_first_reg[q];
|
||||
lastr = qty_last_reg[q];
|
||||
firstr = ent->first_reg;
|
||||
lastr = ent->last_reg;
|
||||
|
||||
/* Prefer fixed hard registers to anything. Prefer pseudo regs to other
|
||||
hard regs. Among pseudos, if NEW will live longer than any other reg
|
||||
@ -1008,10 +1019,10 @@ make_regs_eqv (new, old)
|
||||
&& (uid_cuid[REGNO_LAST_UID (new)]
|
||||
> uid_cuid[REGNO_LAST_UID (firstr)]))))))
|
||||
{
|
||||
reg_prev_eqv[firstr] = new;
|
||||
reg_next_eqv[new] = firstr;
|
||||
reg_prev_eqv[new] = -1;
|
||||
qty_first_reg[q] = new;
|
||||
reg_eqv_table[firstr].prev = new;
|
||||
reg_eqv_table[new].next = firstr;
|
||||
reg_eqv_table[new].prev = -1;
|
||||
ent->first_reg = new;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1019,17 +1030,17 @@ make_regs_eqv (new, old)
|
||||
Otherwise, insert before any non-fixed hard regs that are at the
|
||||
end. Registers of class NO_REGS cannot be used as an
|
||||
equivalent for anything. */
|
||||
while (lastr < FIRST_PSEUDO_REGISTER && reg_prev_eqv[lastr] >= 0
|
||||
while (lastr < FIRST_PSEUDO_REGISTER && reg_eqv_table[lastr].prev >= 0
|
||||
&& (REGNO_REG_CLASS (lastr) == NO_REGS || ! FIXED_REGNO_P (lastr))
|
||||
&& new >= FIRST_PSEUDO_REGISTER)
|
||||
lastr = reg_prev_eqv[lastr];
|
||||
reg_next_eqv[new] = reg_next_eqv[lastr];
|
||||
if (reg_next_eqv[lastr] >= 0)
|
||||
reg_prev_eqv[reg_next_eqv[lastr]] = new;
|
||||
lastr = reg_eqv_table[lastr].prev;
|
||||
reg_eqv_table[new].next = reg_eqv_table[lastr].next;
|
||||
if (reg_eqv_table[lastr].next >= 0)
|
||||
reg_eqv_table[reg_eqv_table[lastr].next].prev = new;
|
||||
else
|
||||
qty_last_reg[q] = new;
|
||||
reg_next_eqv[lastr] = new;
|
||||
reg_prev_eqv[new] = lastr;
|
||||
qty_table[q].last_reg = new;
|
||||
reg_eqv_table[lastr].next = new;
|
||||
reg_eqv_table[new].prev = lastr;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1039,6 +1050,7 @@ static void
|
||||
delete_reg_equiv (reg)
|
||||
register int reg;
|
||||
{
|
||||
register struct qty_table_elem *ent;
|
||||
register int q = REG_QTY (reg);
|
||||
register int p, n;
|
||||
|
||||
@ -1046,17 +1058,19 @@ delete_reg_equiv (reg)
|
||||
if (q == reg)
|
||||
return;
|
||||
|
||||
p = reg_prev_eqv[reg];
|
||||
n = reg_next_eqv[reg];
|
||||
ent = &qty_table[q];
|
||||
|
||||
p = reg_eqv_table[reg].prev;
|
||||
n = reg_eqv_table[reg].next;
|
||||
|
||||
if (n != -1)
|
||||
reg_prev_eqv[n] = p;
|
||||
reg_eqv_table[n].prev = p;
|
||||
else
|
||||
qty_last_reg[q] = p;
|
||||
ent->last_reg = p;
|
||||
if (p != -1)
|
||||
reg_next_eqv[p] = n;
|
||||
reg_eqv_table[p].next = n;
|
||||
else
|
||||
qty_first_reg[q] = n;
|
||||
ent->first_reg = n;
|
||||
|
||||
REG_QTY (reg) = reg;
|
||||
}
|
||||
@ -1188,15 +1202,21 @@ insert_regs (x, classp, modified)
|
||||
if (GET_CODE (x) == REG)
|
||||
{
|
||||
register int regno = REGNO (x);
|
||||
register int qty_valid;
|
||||
|
||||
/* If REGNO is in the equivalence table already but is of the
|
||||
wrong mode for that equivalence, don't do anything here. */
|
||||
|
||||
if (REGNO_QTY_VALID_P (regno)
|
||||
&& qty_mode[REG_QTY (regno)] != GET_MODE (x))
|
||||
return 0;
|
||||
qty_valid = REGNO_QTY_VALID_P (regno);
|
||||
if (qty_valid)
|
||||
{
|
||||
struct qty_table_elem *ent = &qty_table[REG_QTY (regno)];
|
||||
|
||||
if (modified || ! REGNO_QTY_VALID_P (regno))
|
||||
if (ent->mode != GET_MODE (x))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (modified || ! qty_valid)
|
||||
{
|
||||
if (classp)
|
||||
for (classp = classp->first_same_value;
|
||||
@ -1209,8 +1229,7 @@ insert_regs (x, classp, modified)
|
||||
return 1;
|
||||
}
|
||||
|
||||
make_new_qty (regno);
|
||||
qty_mode[REG_QTY (regno)] = GET_MODE (x);
|
||||
make_new_qty (regno, GET_MODE (x));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1566,18 +1585,22 @@ insert (x, classp, hash, mode)
|
||||
constant, we must check the entire class.
|
||||
|
||||
If this is a register that is already known equivalent to an insn,
|
||||
update `qty_const_insn' to show that `this_insn' is the latest
|
||||
update the qtys `const_insn' to show that `this_insn' is the latest
|
||||
insn making that quantity equivalent to the constant. */
|
||||
|
||||
if (elt->is_const && classp && GET_CODE (classp->exp) == REG
|
||||
&& GET_CODE (x) != REG)
|
||||
{
|
||||
qty_const[REG_QTY (REGNO (classp->exp))]
|
||||
= gen_lowpart_if_possible (qty_mode[REG_QTY (REGNO (classp->exp))], x);
|
||||
qty_const_insn[REG_QTY (REGNO (classp->exp))] = this_insn;
|
||||
int exp_q = REG_QTY (REGNO (classp->exp));
|
||||
struct qty_table_elem *exp_ent = &qty_table[exp_q];
|
||||
|
||||
exp_ent->const_rtx = gen_lowpart_if_possible (exp_ent->mode, x);
|
||||
exp_ent->const_insn = this_insn;
|
||||
}
|
||||
|
||||
else if (GET_CODE (x) == REG && classp && ! qty_const[REG_QTY (REGNO (x))]
|
||||
else if (GET_CODE (x) == REG
|
||||
&& classp
|
||||
&& ! qty_table[REG_QTY (REGNO (x))].const_rtx
|
||||
&& ! elt->is_const)
|
||||
{
|
||||
register struct table_elt *p;
|
||||
@ -1586,17 +1609,20 @@ insert (x, classp, hash, mode)
|
||||
{
|
||||
if (p->is_const && GET_CODE (p->exp) != REG)
|
||||
{
|
||||
qty_const[REG_QTY (REGNO (x))]
|
||||
= gen_lowpart_if_possible (GET_MODE (x), p->exp);
|
||||
qty_const_insn[REG_QTY (REGNO (x))] = this_insn;
|
||||
int x_q = REG_QTY (REGNO (x));
|
||||
struct qty_table_elem *x_ent = &qty_table[x_q];
|
||||
|
||||
x_ent->const_rtx = gen_lowpart_if_possible (GET_MODE (x), p->exp);
|
||||
x_ent->const_insn = this_insn;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if (GET_CODE (x) == REG && qty_const[REG_QTY (REGNO (x))]
|
||||
&& GET_MODE (x) == qty_mode[REG_QTY (REGNO (x))])
|
||||
qty_const_insn[REG_QTY (REGNO (x))] = this_insn;
|
||||
else if (GET_CODE (x) == REG
|
||||
&& qty_table[REG_QTY (REGNO (x))].const_rtx
|
||||
&& GET_MODE (x) == qty_table[REG_QTY (REGNO (x))].mode)
|
||||
qty_table[REG_QTY (REGNO (x))].const_insn = this_insn;
|
||||
|
||||
/* If this is a constant with symbolic value,
|
||||
and it has a term with an explicit integer value,
|
||||
@ -2321,17 +2347,27 @@ exp_equiv_p (x, y, validate, equal_values)
|
||||
/* If X is a constant and Y is a register or vice versa, they may be
|
||||
equivalent. We only have to validate if Y is a register. */
|
||||
if (CONSTANT_P (x) && GET_CODE (y) == REG
|
||||
&& REGNO_QTY_VALID_P (REGNO (y))
|
||||
&& GET_MODE (y) == qty_mode[REG_QTY (REGNO (y))]
|
||||
&& rtx_equal_p (x, qty_const[REG_QTY (REGNO (y))])
|
||||
&& (! validate || REG_IN_TABLE (REGNO (y)) == REG_TICK (REGNO (y))))
|
||||
return 1;
|
||||
&& REGNO_QTY_VALID_P (REGNO (y)))
|
||||
{
|
||||
int y_q = REG_QTY (REGNO (y));
|
||||
struct qty_table_elem *y_ent = &qty_table[y_q];
|
||||
|
||||
if (GET_MODE (y) == y_ent->mode
|
||||
&& rtx_equal_p (x, y_ent->const_rtx)
|
||||
&& (! validate || REG_IN_TABLE (REGNO (y)) == REG_TICK (REGNO (y))))
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (CONSTANT_P (y) && code == REG
|
||||
&& REGNO_QTY_VALID_P (REGNO (x))
|
||||
&& GET_MODE (x) == qty_mode[REG_QTY (REGNO (x))]
|
||||
&& rtx_equal_p (y, qty_const[REG_QTY (REGNO (x))]))
|
||||
return 1;
|
||||
&& REGNO_QTY_VALID_P (REGNO (x)))
|
||||
{
|
||||
int x_q = REG_QTY (REGNO (x));
|
||||
struct qty_table_elem *x_ent = &qty_table[x_q];
|
||||
|
||||
if (GET_MODE (x) == x_ent->mode
|
||||
&& rtx_equal_p (y, x_ent->const_rtx))
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -2462,19 +2498,28 @@ cse_rtx_varies_p (x)
|
||||
doesn't vary in any mode. */
|
||||
|
||||
if (GET_CODE (x) == REG
|
||||
&& REGNO_QTY_VALID_P (REGNO (x))
|
||||
&& GET_MODE (x) == qty_mode[REG_QTY (REGNO (x))]
|
||||
&& qty_const[REG_QTY (REGNO (x))] != 0)
|
||||
return 0;
|
||||
&& REGNO_QTY_VALID_P (REGNO (x)))
|
||||
{
|
||||
int x_q = REG_QTY (REGNO (x));
|
||||
struct qty_table_elem *x_ent = &qty_table[x_q];
|
||||
|
||||
if (GET_MODE (x) == x_ent->mode
|
||||
&& x_ent->const_rtx != NULL_RTX)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (GET_CODE (x) == PLUS
|
||||
&& GET_CODE (XEXP (x, 1)) == CONST_INT
|
||||
&& GET_CODE (XEXP (x, 0)) == REG
|
||||
&& REGNO_QTY_VALID_P (REGNO (XEXP (x, 0)))
|
||||
&& (GET_MODE (XEXP (x, 0))
|
||||
== qty_mode[REG_QTY (REGNO (XEXP (x, 0)))])
|
||||
&& qty_const[REG_QTY (REGNO (XEXP (x, 0)))])
|
||||
return 0;
|
||||
&& REGNO_QTY_VALID_P (REGNO (XEXP (x, 0))))
|
||||
{
|
||||
int x0_q = REG_QTY (REGNO (XEXP (x, 0)));
|
||||
struct qty_table_elem *x0_ent = &qty_table[x0_q];
|
||||
|
||||
if ((GET_MODE (XEXP (x, 0)) == x0_ent->mode)
|
||||
&& x0_ent->const_rtx != NULL_RTX)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This can happen as the result of virtual register instantiation, if
|
||||
the initial constant is too large to be a valid address. This gives
|
||||
@ -2485,14 +2530,19 @@ cse_rtx_varies_p (x)
|
||||
&& GET_CODE (XEXP (x, 0)) == REG
|
||||
&& GET_CODE (XEXP (x, 1)) == REG
|
||||
&& REGNO_QTY_VALID_P (REGNO (XEXP (x, 0)))
|
||||
&& (GET_MODE (XEXP (x, 0))
|
||||
== qty_mode[REG_QTY (REGNO (XEXP (x, 0)))])
|
||||
&& qty_const[REG_QTY (REGNO (XEXP (x, 0)))]
|
||||
&& REGNO_QTY_VALID_P (REGNO (XEXP (x, 1)))
|
||||
&& (GET_MODE (XEXP (x, 1))
|
||||
== qty_mode[REG_QTY (REGNO (XEXP (x, 1)))])
|
||||
&& qty_const[REG_QTY (REGNO (XEXP (x, 1)))])
|
||||
return 0;
|
||||
&& REGNO_QTY_VALID_P (REGNO (XEXP (x, 1))))
|
||||
{
|
||||
int x0_q = REG_QTY (REGNO (XEXP (x, 0)));
|
||||
int x1_q = REG_QTY (REGNO (XEXP (x, 1)));
|
||||
struct qty_table_elem *x0_ent = &qty_table[x0_q];
|
||||
struct qty_table_elem *x1_ent = &qty_table[x1_q];
|
||||
|
||||
if ((GET_MODE (XEXP (x, 0)) == x0_ent->mode)
|
||||
&& x0_ent->const_rtx != NULL_RTX
|
||||
&& (GET_MODE (XEXP (x, 1)) == x1_ent->mode)
|
||||
&& x1_ent->const_rtx != NULL_RTX)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return rtx_varies_p (x);
|
||||
}
|
||||
@ -2537,6 +2587,8 @@ canon_reg (x, insn)
|
||||
case REG:
|
||||
{
|
||||
register int first;
|
||||
register int q;
|
||||
register struct qty_table_elem *ent;
|
||||
|
||||
/* Never replace a hard reg, because hard regs can appear
|
||||
in more than one machine mode, and we must preserve the mode
|
||||
@ -2547,10 +2599,12 @@ canon_reg (x, insn)
|
||||
|| ! REGNO_QTY_VALID_P (REGNO (x)))
|
||||
return x;
|
||||
|
||||
first = qty_first_reg[REG_QTY (REGNO (x))];
|
||||
q = REG_QTY (REGNO(x));
|
||||
ent = &qty_table[q];
|
||||
first = ent->first_reg;
|
||||
return (first >= FIRST_PSEUDO_REGISTER ? regno_reg_rtx[first]
|
||||
: REGNO_REG_CLASS (first) == NO_REGS ? x
|
||||
: gen_rtx_REG (qty_mode[REG_QTY (REGNO (x))], first));
|
||||
: gen_rtx_REG (ent->mode, first));
|
||||
}
|
||||
|
||||
default:
|
||||
@ -3105,7 +3159,7 @@ fold_rtx (x, insn)
|
||||
&& GET_MODE (SUBREG_REG (elt->exp)) == mode
|
||||
&& exp_equiv_p (elt->exp, elt->exp, 1, 0))
|
||||
return copy_rtx (SUBREG_REG (elt->exp));
|
||||
}
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
@ -3279,10 +3333,15 @@ fold_rtx (x, insn)
|
||||
HOST_WIDE_INT offset = 0;
|
||||
|
||||
if (GET_CODE (addr) == REG
|
||||
&& REGNO_QTY_VALID_P (REGNO (addr))
|
||||
&& GET_MODE (addr) == qty_mode[REG_QTY (REGNO (addr))]
|
||||
&& qty_const[REG_QTY (REGNO (addr))] != 0)
|
||||
addr = qty_const[REG_QTY (REGNO (addr))];
|
||||
&& REGNO_QTY_VALID_P (REGNO (addr)))
|
||||
{
|
||||
int addr_q = REG_QTY (REGNO (addr));
|
||||
struct qty_table_elem *addr_ent = &qty_table[addr_q];
|
||||
|
||||
if (GET_MODE (addr) == addr_ent->mode
|
||||
&& addr_ent->const_rtx != NULL_RTX)
|
||||
addr = addr_ent->const_rtx;
|
||||
}
|
||||
|
||||
/* If address is constant, split it into a base and integer offset. */
|
||||
if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == LABEL_REF)
|
||||
@ -3423,13 +3482,18 @@ fold_rtx (x, insn)
|
||||
case REG:
|
||||
/* This is the same as calling equiv_constant; it is duplicated
|
||||
here for speed. */
|
||||
if (REGNO_QTY_VALID_P (REGNO (arg))
|
||||
&& qty_const[REG_QTY (REGNO (arg))] != 0
|
||||
&& GET_CODE (qty_const[REG_QTY (REGNO (arg))]) != REG
|
||||
&& GET_CODE (qty_const[REG_QTY (REGNO (arg))]) != PLUS)
|
||||
const_arg
|
||||
= gen_lowpart_if_possible (GET_MODE (arg),
|
||||
qty_const[REG_QTY (REGNO (arg))]);
|
||||
if (REGNO_QTY_VALID_P (REGNO (arg)))
|
||||
{
|
||||
int arg_q = REG_QTY (REGNO (arg));
|
||||
struct qty_table_elem *arg_ent = &qty_table[arg_q];
|
||||
|
||||
if (arg_ent->const_rtx != NULL_RTX
|
||||
&& GET_CODE (arg_ent->const_rtx) != REG
|
||||
&& GET_CODE (arg_ent->const_rtx) != PLUS)
|
||||
const_arg
|
||||
= gen_lowpart_if_possible (GET_MODE (arg),
|
||||
arg_ent->const_rtx);
|
||||
}
|
||||
break;
|
||||
|
||||
case CONST:
|
||||
@ -3672,21 +3736,23 @@ fold_rtx (x, insn)
|
||||
{
|
||||
int qty = REG_QTY (REGNO (folded_arg0));
|
||||
|
||||
if (REGNO_QTY_VALID_P (REGNO (folded_arg0))
|
||||
&& (comparison_dominates_p (qty_comparison_code[qty], code)
|
||||
|| (comparison_dominates_p (qty_comparison_code[qty],
|
||||
reverse_condition (code))
|
||||
&& ! FLOAT_MODE_P (mode_arg0)))
|
||||
&& (rtx_equal_p (qty_comparison_const[qty], folded_arg1)
|
||||
|| (const_arg1
|
||||
&& rtx_equal_p (qty_comparison_const[qty],
|
||||
const_arg1))
|
||||
|| (GET_CODE (folded_arg1) == REG
|
||||
&& (REG_QTY (REGNO (folded_arg1))
|
||||
== qty_comparison_qty[qty]))))
|
||||
return (comparison_dominates_p (qty_comparison_code[qty],
|
||||
code)
|
||||
? true : false);
|
||||
if (REGNO_QTY_VALID_P (REGNO (folded_arg0)))
|
||||
{
|
||||
struct qty_table_elem *ent = &qty_table[qty];
|
||||
|
||||
if ((comparison_dominates_p (ent->comparison_code, code)
|
||||
|| (comparison_dominates_p (ent->comparison_code,
|
||||
reverse_condition (code))
|
||||
&& ! FLOAT_MODE_P (mode_arg0)))
|
||||
&& (rtx_equal_p (ent->comparison_const, folded_arg1)
|
||||
|| (const_arg1
|
||||
&& rtx_equal_p (ent->comparison_const,
|
||||
const_arg1))
|
||||
|| (GET_CODE (folded_arg1) == REG
|
||||
&& (REG_QTY (REGNO (folded_arg1)) == ent->comparison_qty))))
|
||||
return (comparison_dominates_p (ent->comparison_code, code)
|
||||
? true : false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3984,9 +4050,14 @@ equiv_constant (x)
|
||||
rtx x;
|
||||
{
|
||||
if (GET_CODE (x) == REG
|
||||
&& REGNO_QTY_VALID_P (REGNO (x))
|
||||
&& qty_const[REG_QTY (REGNO (x))])
|
||||
x = gen_lowpart_if_possible (GET_MODE (x), qty_const[REG_QTY (REGNO (x))]);
|
||||
&& REGNO_QTY_VALID_P (REGNO (x)))
|
||||
{
|
||||
int x_q = REG_QTY (REGNO (x));
|
||||
struct qty_table_elem *x_ent = &qty_table[x_q];
|
||||
|
||||
if (x_ent->const_rtx)
|
||||
x = gen_lowpart_if_possible (GET_MODE (x), x_ent->const_rtx);
|
||||
}
|
||||
|
||||
if (x == 0 || CONSTANT_P (x))
|
||||
return x;
|
||||
@ -4229,6 +4300,9 @@ record_jump_cond (code, mode, op0, op1, reversed_nonequality)
|
||||
|
||||
if (code != EQ || FLOAT_MODE_P (GET_MODE (op0)))
|
||||
{
|
||||
struct qty_table_elem *ent;
|
||||
int qty;
|
||||
|
||||
/* If we reversed a floating-point comparison, if OP0 is not a
|
||||
register, or if OP1 is neither a register or constant, we can't
|
||||
do anything. */
|
||||
@ -4260,7 +4334,10 @@ record_jump_cond (code, mode, op0, op1, reversed_nonequality)
|
||||
op0_elt->in_memory = op0_in_memory;
|
||||
}
|
||||
|
||||
qty_comparison_code[REG_QTY (REGNO (op0))] = code;
|
||||
qty = REG_QTY (REGNO (op0));
|
||||
ent = &qty_table[qty];
|
||||
|
||||
ent->comparison_code = code;
|
||||
if (GET_CODE (op1) == REG)
|
||||
{
|
||||
/* Look it up again--in case op0 and op1 are the same. */
|
||||
@ -4279,13 +4356,13 @@ record_jump_cond (code, mode, op0, op1, reversed_nonequality)
|
||||
op1_elt->in_memory = op1_in_memory;
|
||||
}
|
||||
|
||||
qty_comparison_qty[REG_QTY (REGNO (op0))] = REG_QTY (REGNO (op1));
|
||||
qty_comparison_const[REG_QTY (REGNO (op0))] = 0;
|
||||
ent->comparison_const = NULL_RTX;
|
||||
ent->comparison_qty = REG_QTY (REGNO (op1));
|
||||
}
|
||||
else
|
||||
{
|
||||
qty_comparison_qty[REG_QTY (REGNO (op0))] = -1;
|
||||
qty_comparison_const[REG_QTY (REGNO (op0))] = op1;
|
||||
ent->comparison_const = op1;
|
||||
ent->comparison_qty = -1;
|
||||
}
|
||||
|
||||
return;
|
||||
@ -5198,36 +5275,43 @@ cse_insn (insn, libcall_insn)
|
||||
both registers live over a portion of the basic block. This way,
|
||||
their lifetimes will likely abut instead of overlapping. */
|
||||
if (GET_CODE (dest) == REG
|
||||
&& REGNO_QTY_VALID_P (REGNO (dest))
|
||||
&& qty_mode[REG_QTY (REGNO (dest))] == GET_MODE (dest)
|
||||
&& qty_first_reg[REG_QTY (REGNO (dest))] != REGNO (dest)
|
||||
&& GET_CODE (src) == REG && REGNO (src) == REGNO (dest)
|
||||
/* Don't do this if the original insn had a hard reg as
|
||||
SET_SRC or SET_DEST. */
|
||||
&& (GET_CODE (sets[i].src) != REG
|
||||
|| REGNO (sets[i].src) >= FIRST_PSEUDO_REGISTER)
|
||||
&& (GET_CODE (dest) != REG || REGNO (dest) >= FIRST_PSEUDO_REGISTER))
|
||||
/* We can't call canon_reg here because it won't do anything if
|
||||
SRC is a hard register. */
|
||||
&& REGNO_QTY_VALID_P (REGNO (dest)))
|
||||
{
|
||||
int first = qty_first_reg[REG_QTY (REGNO (src))];
|
||||
rtx new_src
|
||||
= (first >= FIRST_PSEUDO_REGISTER
|
||||
? regno_reg_rtx[first] : gen_rtx_REG (GET_MODE (src), first));
|
||||
int dest_q = REG_QTY (REGNO (dest));
|
||||
struct qty_table_elem *dest_ent = &qty_table[dest_q];
|
||||
|
||||
/* We must use validate-change even for this, because this
|
||||
might be a special no-op instruction, suitable only to
|
||||
tag notes onto. */
|
||||
if (validate_change (insn, &SET_SRC (sets[i].rtl), new_src, 0))
|
||||
if (dest_ent->mode == GET_MODE (dest)
|
||||
&& dest_ent->first_reg != REGNO (dest)
|
||||
&& GET_CODE (src) == REG && REGNO (src) == REGNO (dest)
|
||||
/* Don't do this if the original insn had a hard reg as
|
||||
SET_SRC or SET_DEST. */
|
||||
&& (GET_CODE (sets[i].src) != REG
|
||||
|| REGNO (sets[i].src) >= FIRST_PSEUDO_REGISTER)
|
||||
&& (GET_CODE (dest) != REG || REGNO (dest) >= FIRST_PSEUDO_REGISTER))
|
||||
/* We can't call canon_reg here because it won't do anything if
|
||||
SRC is a hard register. */
|
||||
{
|
||||
src = new_src;
|
||||
/* If we had a constant that is cheaper than what we are now
|
||||
setting SRC to, use that constant. We ignored it when we
|
||||
thought we could make this into a no-op. */
|
||||
if (src_const && COST (src_const) < COST (src)
|
||||
&& validate_change (insn, &SET_SRC (sets[i].rtl), src_const,
|
||||
0))
|
||||
src = src_const;
|
||||
int src_q = REG_QTY (REGNO (src));
|
||||
struct qty_table_elem *src_ent = &qty_table[src_q];
|
||||
int first = src_ent->first_reg;
|
||||
rtx new_src
|
||||
= (first >= FIRST_PSEUDO_REGISTER
|
||||
? regno_reg_rtx[first] : gen_rtx_REG (GET_MODE (src), first));
|
||||
|
||||
/* We must use validate-change even for this, because this
|
||||
might be a special no-op instruction, suitable only to
|
||||
tag notes onto. */
|
||||
if (validate_change (insn, &SET_SRC (sets[i].rtl), new_src, 0))
|
||||
{
|
||||
src = new_src;
|
||||
/* If we had a constant that is cheaper than what we are now
|
||||
setting SRC to, use that constant. We ignored it when we
|
||||
thought we could make this into a no-op. */
|
||||
if (src_const && COST (src_const) < COST (src)
|
||||
&& validate_change (insn, &SET_SRC (sets[i].rtl), src_const,
|
||||
0))
|
||||
src = src_const;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -5284,22 +5368,27 @@ cse_insn (insn, libcall_insn)
|
||||
Rather than track each register individually, we just see if
|
||||
the last set for this quantity was for this register. */
|
||||
|
||||
if (REGNO_QTY_VALID_P (REGNO (dest))
|
||||
&& qty_const[REG_QTY (REGNO (dest))] == const0_rtx)
|
||||
if (REGNO_QTY_VALID_P (REGNO (dest)))
|
||||
{
|
||||
/* See if we previously had a REG_WAS_0 note. */
|
||||
rtx note = find_reg_note (insn, REG_WAS_0, NULL_RTX);
|
||||
rtx const_insn = qty_const_insn[REG_QTY (REGNO (dest))];
|
||||
int dest_q = REG_QTY (REGNO (dest));
|
||||
struct qty_table_elem *dest_ent = &qty_table[dest_q];
|
||||
|
||||
if ((tem = single_set (const_insn)) != 0
|
||||
&& rtx_equal_p (SET_DEST (tem), dest))
|
||||
if (dest_ent->const_rtx == const0_rtx)
|
||||
{
|
||||
if (note)
|
||||
XEXP (note, 0) = const_insn;
|
||||
else
|
||||
REG_NOTES (insn)
|
||||
= gen_rtx_INSN_LIST (REG_WAS_0, const_insn,
|
||||
REG_NOTES (insn));
|
||||
/* See if we previously had a REG_WAS_0 note. */
|
||||
rtx note = find_reg_note (insn, REG_WAS_0, NULL_RTX);
|
||||
rtx const_insn = dest_ent->const_insn;
|
||||
|
||||
if ((tem = single_set (const_insn)) != 0
|
||||
&& rtx_equal_p (SET_DEST (tem), dest))
|
||||
{
|
||||
if (note)
|
||||
XEXP (note, 0) = const_insn;
|
||||
else
|
||||
REG_NOTES (insn)
|
||||
= gen_rtx_INSN_LIST (REG_WAS_0, const_insn,
|
||||
REG_NOTES (insn));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5828,50 +5917,54 @@ cse_insn (insn, libcall_insn)
|
||||
&& NEXT_INSN (PREV_INSN (insn)) == insn
|
||||
&& GET_CODE (SET_SRC (sets[0].rtl)) == REG
|
||||
&& REGNO (SET_SRC (sets[0].rtl)) >= FIRST_PSEUDO_REGISTER
|
||||
&& REGNO_QTY_VALID_P (REGNO (SET_SRC (sets[0].rtl)))
|
||||
&& (qty_first_reg[REG_QTY (REGNO (SET_SRC (sets[0].rtl)))]
|
||||
== REGNO (SET_DEST (sets[0].rtl)))
|
||||
&& ! find_reg_note (insn, REG_RETVAL, NULL_RTX))
|
||||
&& REGNO_QTY_VALID_P (REGNO (SET_SRC (sets[0].rtl))))
|
||||
{
|
||||
rtx prev = PREV_INSN (insn);
|
||||
while (prev && GET_CODE (prev) == NOTE)
|
||||
prev = PREV_INSN (prev);
|
||||
int src_q = REG_QTY (REGNO (SET_SRC (sets[0].rtl)));
|
||||
struct qty_table_elem *src_ent = &qty_table[src_q];
|
||||
|
||||
if (prev && GET_CODE (prev) == INSN && GET_CODE (PATTERN (prev)) == SET
|
||||
&& SET_DEST (PATTERN (prev)) == SET_SRC (sets[0].rtl))
|
||||
if ((src_ent->first_reg == REGNO (SET_DEST (sets[0].rtl)))
|
||||
&& ! find_reg_note (insn, REG_RETVAL, NULL_RTX))
|
||||
{
|
||||
rtx dest = SET_DEST (sets[0].rtl);
|
||||
rtx note = find_reg_note (prev, REG_EQUIV, NULL_RTX);
|
||||
rtx prev = PREV_INSN (insn);
|
||||
while (prev && GET_CODE (prev) == NOTE)
|
||||
prev = PREV_INSN (prev);
|
||||
|
||||
validate_change (prev, & SET_DEST (PATTERN (prev)), dest, 1);
|
||||
validate_change (insn, & SET_DEST (sets[0].rtl),
|
||||
SET_SRC (sets[0].rtl), 1);
|
||||
validate_change (insn, & SET_SRC (sets[0].rtl), dest, 1);
|
||||
apply_change_group ();
|
||||
|
||||
/* If REG1 was equivalent to a constant, REG0 is not. */
|
||||
if (note)
|
||||
PUT_REG_NOTE_KIND (note, REG_EQUAL);
|
||||
|
||||
/* If there was a REG_WAS_0 note on PREV, remove it. Move
|
||||
any REG_WAS_0 note on INSN to PREV. */
|
||||
note = find_reg_note (prev, REG_WAS_0, NULL_RTX);
|
||||
if (note)
|
||||
remove_note (prev, note);
|
||||
|
||||
note = find_reg_note (insn, REG_WAS_0, NULL_RTX);
|
||||
if (note)
|
||||
if (prev && GET_CODE (prev) == INSN && GET_CODE (PATTERN (prev)) == SET
|
||||
&& SET_DEST (PATTERN (prev)) == SET_SRC (sets[0].rtl))
|
||||
{
|
||||
remove_note (insn, note);
|
||||
XEXP (note, 1) = REG_NOTES (prev);
|
||||
REG_NOTES (prev) = note;
|
||||
}
|
||||
rtx dest = SET_DEST (sets[0].rtl);
|
||||
rtx note = find_reg_note (prev, REG_EQUIV, NULL_RTX);
|
||||
|
||||
/* If INSN has a REG_EQUAL note, and this note mentions REG0,
|
||||
then we must delete it, because the value in REG0 has changed. */
|
||||
note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
|
||||
if (note && reg_mentioned_p (dest, XEXP (note, 0)))
|
||||
remove_note (insn, note);
|
||||
validate_change (prev, & SET_DEST (PATTERN (prev)), dest, 1);
|
||||
validate_change (insn, & SET_DEST (sets[0].rtl),
|
||||
SET_SRC (sets[0].rtl), 1);
|
||||
validate_change (insn, & SET_SRC (sets[0].rtl), dest, 1);
|
||||
apply_change_group ();
|
||||
|
||||
/* If REG1 was equivalent to a constant, REG0 is not. */
|
||||
if (note)
|
||||
PUT_REG_NOTE_KIND (note, REG_EQUAL);
|
||||
|
||||
/* If there was a REG_WAS_0 note on PREV, remove it. Move
|
||||
any REG_WAS_0 note on INSN to PREV. */
|
||||
note = find_reg_note (prev, REG_WAS_0, NULL_RTX);
|
||||
if (note)
|
||||
remove_note (prev, note);
|
||||
|
||||
note = find_reg_note (insn, REG_WAS_0, NULL_RTX);
|
||||
if (note)
|
||||
{
|
||||
remove_note (insn, note);
|
||||
XEXP (note, 1) = REG_NOTES (prev);
|
||||
REG_NOTES (prev) = note;
|
||||
}
|
||||
|
||||
/* If INSN has a REG_EQUAL note, and this note mentions REG0,
|
||||
then we must delete it, because the value in REG0 has changed. */
|
||||
note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
|
||||
if (note && reg_mentioned_p (dest, XEXP (note, 0)))
|
||||
remove_note (insn, note);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -6049,14 +6142,18 @@ cse_process_notes (x, object)
|
||||
i = REG_QTY (REGNO (x));
|
||||
|
||||
/* Return a constant or a constant register. */
|
||||
if (REGNO_QTY_VALID_P (REGNO (x))
|
||||
&& qty_const[i] != 0
|
||||
&& (CONSTANT_P (qty_const[i])
|
||||
|| GET_CODE (qty_const[i]) == REG))
|
||||
if (REGNO_QTY_VALID_P (REGNO (x)))
|
||||
{
|
||||
rtx new = gen_lowpart_if_possible (GET_MODE (x), qty_const[i]);
|
||||
if (new)
|
||||
return new;
|
||||
struct qty_table_elem *ent = &qty_table[i];
|
||||
|
||||
if (ent->const_rtx != NULL_RTX
|
||||
&& (CONSTANT_P (ent->const_rtx)
|
||||
|| GET_CODE (ent->const_rtx) == REG))
|
||||
{
|
||||
rtx new = gen_lowpart_if_possible (GET_MODE (x), ent->const_rtx);
|
||||
if (new)
|
||||
return new;
|
||||
}
|
||||
}
|
||||
|
||||
/* Otherwise, canonicalize this register. */
|
||||
@ -6615,8 +6712,8 @@ cse_main (f, nregs, after_loop, file)
|
||||
|
||||
max_insn_uid = get_max_uid ();
|
||||
|
||||
reg_next_eqv = (int *) xmalloc (nregs * sizeof (int));
|
||||
reg_prev_eqv = (int *) xmalloc (nregs * sizeof (int));
|
||||
reg_eqv_table = (struct reg_eqv_elem *)
|
||||
xmalloc(nregs * sizeof(struct reg_eqv_elem));
|
||||
|
||||
#ifdef LOAD_EXTEND_OP
|
||||
|
||||
@ -6753,17 +6850,13 @@ cse_main (f, nregs, after_loop, file)
|
||||
if (ggc_p)
|
||||
ggc_pop_context ();
|
||||
|
||||
/* Tell refers_to_mem_p that qty_const info is not available. */
|
||||
qty_const = 0;
|
||||
|
||||
if (max_elements_made < n_elements_made)
|
||||
max_elements_made = n_elements_made;
|
||||
|
||||
/* Clean up. */
|
||||
end_alias_analysis ();
|
||||
free (uid_cuid);
|
||||
free (reg_next_eqv);
|
||||
free (reg_prev_eqv);
|
||||
free (reg_eqv_table);
|
||||
|
||||
return cse_jumps_altered || recorded_label_ref;
|
||||
}
|
||||
@ -6787,28 +6880,12 @@ cse_basic_block (from, to, next_branch, around_loop)
|
||||
rtx libcall_insn = NULL_RTX;
|
||||
int num_insns = 0;
|
||||
|
||||
/* Each of these arrays is undefined before max_reg, so only allocate
|
||||
the space actually needed and adjust the start below. */
|
||||
/* This array is undefined before max_reg, so only allocate
|
||||
the space actually needed and adjust the start. */
|
||||
|
||||
qty_first_reg = (int *) xmalloc ((max_qty - max_reg) * sizeof (int));
|
||||
qty_last_reg = (int *) xmalloc ((max_qty - max_reg) * sizeof (int));
|
||||
qty_mode = (enum machine_mode *) xmalloc ((max_qty - max_reg)
|
||||
* sizeof (enum machine_mode));
|
||||
qty_const = (rtx *) xmalloc ((max_qty - max_reg) * sizeof (rtx));
|
||||
qty_const_insn = (rtx *) xmalloc ((max_qty - max_reg) * sizeof (rtx));
|
||||
qty_comparison_code
|
||||
= (enum rtx_code *) xmalloc ((max_qty - max_reg) * sizeof (enum rtx_code));
|
||||
qty_comparison_qty = (int *) xmalloc ((max_qty - max_reg) * sizeof (int));
|
||||
qty_comparison_const = (rtx *) xmalloc ((max_qty - max_reg) * sizeof (rtx));
|
||||
|
||||
qty_first_reg -= max_reg;
|
||||
qty_last_reg -= max_reg;
|
||||
qty_mode -= max_reg;
|
||||
qty_const -= max_reg;
|
||||
qty_const_insn -= max_reg;
|
||||
qty_comparison_code -= max_reg;
|
||||
qty_comparison_qty -= max_reg;
|
||||
qty_comparison_const -= max_reg;
|
||||
qty_table = (struct qty_table_elem *) xmalloc ((max_qty - max_reg)
|
||||
* sizeof(struct qty_table_elem));
|
||||
qty_table -= max_reg;
|
||||
|
||||
new_basic_block ();
|
||||
|
||||
@ -6976,14 +7053,7 @@ cse_basic_block (from, to, next_branch, around_loop)
|
||||
&& LABEL_NUSES (JUMP_LABEL (PREV_INSN (to))) == 1)
|
||||
cse_around_loop (JUMP_LABEL (PREV_INSN (to)));
|
||||
|
||||
free (qty_first_reg + max_reg);
|
||||
free (qty_last_reg + max_reg);
|
||||
free (qty_mode + max_reg);
|
||||
free (qty_const + max_reg);
|
||||
free (qty_const_insn + max_reg);
|
||||
free (qty_comparison_code + max_reg);
|
||||
free (qty_comparison_qty + max_reg);
|
||||
free (qty_comparison_const + max_reg);
|
||||
free (qty_table + max_reg);
|
||||
|
||||
return to ? NEXT_INSN (to) : 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user