cse.c: Change encoding of quantity numbers to avoid undefined pointer arithmetic on...
* cse.c: Change encoding of quantity numbers to avoid undefined pointer arithmetic on qty_table. (REGNO_QTY_VALID_P): A quantity is now valid if it isn't negative. (get_cse_reg_info): Initialize reg_qty to a unique negative value. (new_basic_block): Assign "real" quantity numbers from zero. (delete_reg_equiv): Do nothing if quantity is invalid. Reset the REG_QTY to its unique negative value. (merge_equiv_classes): Calculate need_rehash if quantity is valid. (cse_main): Don't include max_reg when determining max_qty. (cse_basic_block): Avoid subtracting a large offset from qty_table, which causes undefined C99 behaviour. Only allocate needed memory. Co-Authored-By: John David Anglin <dave.anglin@nrc-cnrc.gc.ca> From-SVN: r89543
This commit is contained in:
parent
4cd26879f7
commit
08a692679f
2 changed files with 32 additions and 21 deletions
|
@ -1,3 +1,18 @@
|
||||||
|
2004-10-25 Roger Sayle <roger@eyesopen.com>
|
||||||
|
John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
|
||||||
|
|
||||||
|
* cse.c: Change encoding of quantity numbers to avoid undefined
|
||||||
|
pointer arithmetic on qty_table.
|
||||||
|
(REGNO_QTY_VALID_P): A quantity is now valid if it isn't negative.
|
||||||
|
(get_cse_reg_info): Initialize reg_qty to a unique negative value.
|
||||||
|
(new_basic_block): Assign "real" quantity numbers from zero.
|
||||||
|
(delete_reg_equiv): Do nothing if quantity is invalid. Reset the
|
||||||
|
REG_QTY to its unique negative value.
|
||||||
|
(merge_equiv_classes): Calculate need_rehash if quantity is valid.
|
||||||
|
(cse_main): Don't include max_reg when determining max_qty.
|
||||||
|
(cse_basic_block): Avoid subtracting a large offset from qty_table,
|
||||||
|
which causes undefined C99 behaviour. Only allocate needed memory.
|
||||||
|
|
||||||
2004-10-25 Kazu Hirata <kazu@cs.umass.edu>
|
2004-10-25 Kazu Hirata <kazu@cs.umass.edu>
|
||||||
|
|
||||||
* stmt.c (expand_case): Remove an obsolete comment.
|
* stmt.c (expand_case): Remove an obsolete comment.
|
||||||
|
|
38
gcc/cse.c
38
gcc/cse.c
|
@ -84,11 +84,12 @@ Registers and "quantity numbers":
|
||||||
`reg_qty' records what quantity a register is currently thought
|
`reg_qty' records what quantity a register is currently thought
|
||||||
of as containing.
|
of as containing.
|
||||||
|
|
||||||
All real quantity numbers are greater than or equal to `max_reg'.
|
All real quantity numbers are greater than or equal to zero.
|
||||||
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 - 1, which is always negative.
|
||||||
|
|
||||||
Quantity numbers below `max_reg' do not exist and none of the `qty_table'
|
Quantity numbers below zero do not exist and none of the `qty_table'
|
||||||
entries should be referenced with an index below `max_reg'.
|
entries should be referenced with a negative index.
|
||||||
|
|
||||||
We also maintain a bidirectional chain of registers for each
|
We also maintain a bidirectional chain of registers for each
|
||||||
quantity number. The `qty_table` members `first_reg' and `last_reg',
|
quantity number. The `qty_table` members `first_reg' and `last_reg',
|
||||||
|
@ -546,7 +547,7 @@ struct table_elt
|
||||||
/* 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_table. */
|
into the qty_table. */
|
||||||
|
|
||||||
#define REGNO_QTY_VALID_P(N) (REG_QTY (N) != (int) (N))
|
#define REGNO_QTY_VALID_P(N) (REG_QTY (N) >= 0)
|
||||||
|
|
||||||
static struct table_elt *table[HASH_SIZE];
|
static struct table_elt *table[HASH_SIZE];
|
||||||
|
|
||||||
|
@ -844,7 +845,7 @@ get_cse_reg_info (unsigned int regno)
|
||||||
p->reg_tick = 1;
|
p->reg_tick = 1;
|
||||||
p->reg_in_table = -1;
|
p->reg_in_table = -1;
|
||||||
p->subreg_ticked = -1;
|
p->subreg_ticked = -1;
|
||||||
p->reg_qty = regno;
|
p->reg_qty = -regno - 1;
|
||||||
p->regno = regno;
|
p->regno = regno;
|
||||||
p->next = cse_reg_info_used_list;
|
p->next = cse_reg_info_used_list;
|
||||||
cse_reg_info_used_list = p;
|
cse_reg_info_used_list = p;
|
||||||
|
@ -868,7 +869,7 @@ new_basic_block (void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
next_qty = max_reg;
|
next_qty = 0;
|
||||||
|
|
||||||
/* Clear out hash table state for this pass. */
|
/* Clear out hash table state for this pass. */
|
||||||
|
|
||||||
|
@ -1012,7 +1013,7 @@ delete_reg_equiv (unsigned int reg)
|
||||||
int p, n;
|
int p, n;
|
||||||
|
|
||||||
/* If invalid, do nothing. */
|
/* If invalid, do nothing. */
|
||||||
if (q == (int) reg)
|
if (! REGNO_QTY_VALID_P (reg))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ent = &qty_table[q];
|
ent = &qty_table[q];
|
||||||
|
@ -1029,7 +1030,7 @@ delete_reg_equiv (unsigned int reg)
|
||||||
else
|
else
|
||||||
ent->first_reg = n;
|
ent->first_reg = n;
|
||||||
|
|
||||||
REG_QTY (reg) = reg;
|
REG_QTY (reg) = -reg - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove any invalid expressions from the hash table
|
/* Remove any invalid expressions from the hash table
|
||||||
|
@ -1627,7 +1628,7 @@ merge_equiv_classes (struct table_elt *class1, struct table_elt *class2)
|
||||||
|
|
||||||
if (REG_P (exp))
|
if (REG_P (exp))
|
||||||
{
|
{
|
||||||
need_rehash = (unsigned) REG_QTY (REGNO (exp)) != REGNO (exp);
|
need_rehash = REGNO_QTY_VALID_P (REGNO (exp));
|
||||||
delete_reg_equiv (REGNO (exp));
|
delete_reg_equiv (REGNO (exp));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6739,8 +6740,6 @@ cse_main (rtx f, int nregs, FILE *file)
|
||||||
if (max_qty < 500)
|
if (max_qty < 500)
|
||||||
max_qty = 500;
|
max_qty = 500;
|
||||||
|
|
||||||
max_qty += max_reg;
|
|
||||||
|
|
||||||
/* If this basic block is being extended by following certain jumps,
|
/* If this basic block is being extended by following certain jumps,
|
||||||
(see `cse_end_of_basic_block'), we reprocess the code from the start.
|
(see `cse_end_of_basic_block'), we reprocess the code from the start.
|
||||||
Otherwise, we start after this basic block. */
|
Otherwise, we start after this basic block. */
|
||||||
|
@ -6801,11 +6800,8 @@ cse_basic_block (rtx from, rtx to, struct branch_path *next_branch)
|
||||||
int num_insns = 0;
|
int num_insns = 0;
|
||||||
int no_conflict = 0;
|
int no_conflict = 0;
|
||||||
|
|
||||||
/* This array is undefined before max_reg, so only allocate
|
/* Allocate the space needed by qty_table. */
|
||||||
the space actually needed and adjust the start. */
|
qty_table = xmalloc (max_qty * sizeof (struct qty_table_elem));
|
||||||
|
|
||||||
qty_table = xmalloc ((max_qty - max_reg) * sizeof (struct qty_table_elem));
|
|
||||||
qty_table -= max_reg;
|
|
||||||
|
|
||||||
new_basic_block ();
|
new_basic_block ();
|
||||||
|
|
||||||
|
@ -6916,7 +6912,7 @@ cse_basic_block (rtx from, rtx to, struct branch_path *next_branch)
|
||||||
{
|
{
|
||||||
if (to == 0)
|
if (to == 0)
|
||||||
{
|
{
|
||||||
free (qty_table + max_reg);
|
free (qty_table);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6951,7 +6947,7 @@ cse_basic_block (rtx from, rtx to, struct branch_path *next_branch)
|
||||||
/* If TO was the last insn in the function, we are done. */
|
/* If TO was the last insn in the function, we are done. */
|
||||||
if (insn == 0)
|
if (insn == 0)
|
||||||
{
|
{
|
||||||
free (qty_table + max_reg);
|
free (qty_table);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6960,7 +6956,7 @@ cse_basic_block (rtx from, rtx to, struct branch_path *next_branch)
|
||||||
prev = prev_nonnote_insn (to);
|
prev = prev_nonnote_insn (to);
|
||||||
if (prev && BARRIER_P (prev))
|
if (prev && BARRIER_P (prev))
|
||||||
{
|
{
|
||||||
free (qty_table + max_reg);
|
free (qty_table);
|
||||||
return insn;
|
return insn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6995,7 +6991,7 @@ cse_basic_block (rtx from, rtx to, struct branch_path *next_branch)
|
||||||
|
|
||||||
gcc_assert (next_qty <= max_qty);
|
gcc_assert (next_qty <= max_qty);
|
||||||
|
|
||||||
free (qty_table + max_reg);
|
free (qty_table);
|
||||||
|
|
||||||
return to ? NEXT_INSN (to) : 0;
|
return to ? NEXT_INSN (to) : 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue