Commit 08a69267 by Roger Sayle Committed by Roger Sayle

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
parent 4cd26879
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.
......
...@@ -84,11 +84,12 @@ Registers and "quantity numbers": ...@@ -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 ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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;
} }
......
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