OSDN Git Service

* cse.c: Change encoding of quantity numbers to avoid undefined
authorsayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 25 Oct 2004 17:23:15 +0000 (17:23 +0000)
committersayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 25 Oct 2004 17:23:15 +0000 (17:23 +0000)
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@89543 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/cse.c

index cac8466..474fec2 100644 (file)
@@ -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>
 
        * stmt.c (expand_case): Remove an obsolete comment.
index 431ae70..1313399 100644 (file)
--- 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;
 }