Commit 1bb98cec by David S. Miller Committed by David S. Miller

Move quantity tables and register equivalence chains into

	per-qty and per-register structure arrays respectively.

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