From 08a692679fb8ff32f7d63932fd97a90b2aef4c0c Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Mon, 25 Oct 2004 17:23:15 +0000 Subject: [PATCH] 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 From-SVN: r89543 --- gcc/ChangeLog | 15 +++++++++++++++ gcc/cse.c | 38 +++++++++++++++++--------------------- 2 files changed, 32 insertions(+), 21 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cac846699dd..474fec2c466 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2004-10-25 Roger Sayle + John David Anglin + + * 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 * stmt.c (expand_case): Remove an obsolete comment. diff --git a/gcc/cse.c b/gcc/cse.c index 431ae708678..13133998ca6 100644 --- a/gcc/cse.c +++ b/gcc/cse.c @@ -84,11 +84,12 @@ Registers and "quantity numbers": `reg_qty' records what quantity a register is currently thought of as containing. - 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. + 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 - 1, which is always negative. - Quantity numbers below `max_reg' do not exist and none of the `qty_table' - entries should be referenced with an index below `max_reg'. + Quantity numbers below zero do not exist and none of the `qty_table' + entries should be referenced with a negative index. We also maintain a bidirectional chain of registers for each 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 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]; @@ -844,7 +845,7 @@ get_cse_reg_info (unsigned int regno) p->reg_tick = 1; p->reg_in_table = -1; p->subreg_ticked = -1; - p->reg_qty = regno; + p->reg_qty = -regno - 1; p->regno = regno; p->next = cse_reg_info_used_list; cse_reg_info_used_list = p; @@ -868,7 +869,7 @@ new_basic_block (void) { int i; - next_qty = max_reg; + next_qty = 0; /* Clear out hash table state for this pass. */ @@ -1012,7 +1013,7 @@ delete_reg_equiv (unsigned int reg) int p, n; /* If invalid, do nothing. */ - if (q == (int) reg) + if (! REGNO_QTY_VALID_P (reg)) return; ent = &qty_table[q]; @@ -1029,7 +1030,7 @@ delete_reg_equiv (unsigned int reg) else ent->first_reg = n; - REG_QTY (reg) = reg; + REG_QTY (reg) = -reg - 1; } /* 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)) { - need_rehash = (unsigned) REG_QTY (REGNO (exp)) != REGNO (exp); + need_rehash = REGNO_QTY_VALID_P (REGNO (exp)); delete_reg_equiv (REGNO (exp)); } @@ -6739,8 +6740,6 @@ cse_main (rtx f, int nregs, FILE *file) if (max_qty < 500) max_qty = 500; - max_qty += max_reg; - /* If this basic block is being extended by following certain jumps, (see `cse_end_of_basic_block'), we reprocess the code from the start. 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 no_conflict = 0; - /* This array is undefined before max_reg, so only allocate - the space actually needed and adjust the start. */ - - qty_table = xmalloc ((max_qty - max_reg) * sizeof (struct qty_table_elem)); - qty_table -= max_reg; + /* Allocate the space needed by qty_table. */ + qty_table = xmalloc (max_qty * sizeof (struct qty_table_elem)); new_basic_block (); @@ -6916,7 +6912,7 @@ cse_basic_block (rtx from, rtx to, struct branch_path *next_branch) { if (to == 0) { - free (qty_table + max_reg); + free (qty_table); 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 (insn == 0) { - free (qty_table + max_reg); + free (qty_table); return 0; } @@ -6960,7 +6956,7 @@ cse_basic_block (rtx from, rtx to, struct branch_path *next_branch) prev = prev_nonnote_insn (to); if (prev && BARRIER_P (prev)) { - free (qty_table + max_reg); + free (qty_table); return insn; } @@ -6995,7 +6991,7 @@ cse_basic_block (rtx from, rtx to, struct branch_path *next_branch) gcc_assert (next_qty <= max_qty); - free (qty_table + max_reg); + free (qty_table); return to ? NEXT_INSN (to) : 0; }