OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / gcse.c
index aaa2f6d..224dd6b 100644 (file)
@@ -365,7 +365,8 @@ struct occr
    Someday I'll perform the computation and figure it out.  */
 
 /* Total size of the expression hash table, in elements.  */
-static int expr_hash_table_size;
+static unsigned int expr_hash_table_size;
+
 /* The table itself.
    This is an array of `expr_hash_table_size' elements.  */
 static struct expr **expr_hash_table;
@@ -385,7 +386,11 @@ static int *uid_cuid;
 static int max_uid;
 
 /* Get the cuid of an insn.  */
+#ifdef ENABLE_CHECKING
+#define INSN_CUID(INSN) (INSN_UID (INSN) > max_uid ? (abort (), 0) : uid_cuid[INSN_UID (INSN)])
+#else
 #define INSN_CUID(INSN) (uid_cuid[INSN_UID (INSN)])
+#endif
 
 /* Number of cuids.  */
 static int max_cuid;
@@ -399,7 +404,7 @@ static rtx *cuid_insn;
 /* Maximum register number in function prior to doing gcse + 1.
    Registers created during this pass have regno >= max_gcse_regno.
    This is named with "gcse" to not collide with global of same name.  */
-static int max_gcse_regno;
+static unsigned int max_gcse_regno;
 
 /* Maximum number of cse-able expressions found.  */
 static int n_exprs;
@@ -519,9 +524,9 @@ struct null_pointer_info
   /* The basic block being processed.  */
   int current_block;
   /* The first register to be handled in this pass.  */
-  int min_reg;
+  unsigned int min_reg;
   /* One greater than the last register to be handled in this pass.  */
-  int max_reg;
+  unsigned int max_reg;
   sbitmap *nonnull_local;
   sbitmap *nonnull_killed;
 };
@@ -560,14 +565,14 @@ static void compute_hash_table    PARAMS ((int));
 static void alloc_set_hash_table PARAMS ((int));
 static void free_set_hash_table PARAMS ((void));
 static void compute_set_hash_table PARAMS ((void));
-static void alloc_expr_hash_table PARAMS ((int));
+static void alloc_expr_hash_table PARAMS ((unsigned int));
 static void free_expr_hash_table PARAMS ((void));
 static void compute_expr_hash_table PARAMS ((void));
 static void dump_hash_table    PARAMS ((FILE *, const char *, struct expr **,
                                         int, int));
 static struct expr *lookup_expr        PARAMS ((rtx));
-static struct expr *lookup_set PARAMS ((int, rtx));
-static struct expr *next_set   PARAMS ((int, struct expr *));
+static struct expr *lookup_set PARAMS ((unsigned int, rtx));
+static struct expr *next_set   PARAMS ((unsigned int, struct expr *));
 static void reset_opr_set_tables PARAMS ((void));
 static int oprs_not_set_p      PARAMS ((rtx, rtx));
 static void mark_call          PARAMS ((rtx));
@@ -628,7 +633,8 @@ static int handle_avail_expr        PARAMS ((rtx, struct expr *));
 static int classic_gcse                PARAMS ((void));
 static int one_classic_gcse_pass PARAMS ((int));
 static void invalidate_nonnull_info PARAMS ((rtx, rtx, void *));
-static void delete_null_pointer_checks_1 PARAMS ((int *, sbitmap *, sbitmap *,
+static void delete_null_pointer_checks_1 PARAMS ((unsigned int *, sbitmap *,
+                                                 sbitmap *,
                                                  struct null_pointer_info *));
 static rtx process_insert_insn PARAMS ((struct expr *));
 static int pre_edge_insert     PARAMS ((struct edge_list *, struct expr **));
@@ -668,18 +674,13 @@ gcse_main (f, file)
   /* Identify the basic block information for this function, including
      successors and predecessors.  */
   max_gcse_regno = max_reg_num ();
-  find_basic_blocks (f, max_gcse_regno, file);
-  cleanup_cfg (f);
 
   if (file)
     dump_flow_info (file);
 
   /* Return if there's nothing to do.  */
   if (n_basic_blocks <= 1)
-    {
-      free_basic_block_vars (0);
-      return 0;
-    }
+    return 0;
 
   /* Trying to perform global optimizations on flow graphs which have
      a high connectivity will take a long time and is unlikely to be
@@ -690,10 +691,7 @@ gcse_main (f, file)
      a couple switch statements.  So we require a relatively large number
      of basic blocks and the ratio of edges to blocks to be high.  */
   if (n_basic_blocks > 1000 && n_edges / n_basic_blocks >= 20)
-    {
-      free_basic_block_vars (0);
-      return 0;
-    }
+    return 0;
 
   /* See what modes support reg/reg copy operations.  */
   if (! can_copy_init_p)
@@ -806,7 +804,6 @@ gcse_main (f, file)
 
   obstack_free (&gcse_obstack, NULL_PTR);
   free_reg_set_mem ();
-  free_basic_block_vars (0);
   return run_jump_opt_after_gcse;
 }
 \f
@@ -903,9 +900,9 @@ alloc_gcse_mem (f)
   for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
     {
       if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
-       INSN_CUID (insn) = i++;
+       uid_cuid[INSN_UID (insn)] = i++;
       else
-       INSN_CUID (insn) = i;
+       uid_cuid[INSN_UID (insn)] = i;
     }
 
   /* Create a table mapping cuids to insns.  */
@@ -1019,7 +1016,7 @@ compute_local_properties (transp, comp, antloc, setp)
      sbitmap *antloc;
      int setp;
 {
-  int i, hash_table_size;
+  unsigned int i, hash_table_size;
   struct expr **hash_table;
   
   /* Initialize any bitmaps that were passed in.  */
@@ -1143,21 +1140,8 @@ record_one_set (regno, insn)
                                                   sizeof (struct reg_set));
   bytes_used += sizeof (struct reg_set);
   new_reg_info->insn = insn;
-  new_reg_info->next = NULL;
-  if (reg_set_table[regno] == NULL)
-    reg_set_table[regno] = new_reg_info;
-  else
-    {
-      reg_info_ptr1 = reg_info_ptr2 = reg_set_table[regno];
-      /* ??? One could keep a "last" pointer to speed this up.  */
-      while (reg_info_ptr1 != NULL)
-       {
-         reg_info_ptr2 = reg_info_ptr1;
-         reg_info_ptr1 = reg_info_ptr1->next;
-       }
-
-      reg_info_ptr2->next = new_reg_info;
-    }
+  new_reg_info->next = reg_set_table[regno];
+  reg_set_table[regno] = new_reg_info;
 }
 
 /* Called from compute_sets via note_stores to handle one SET or CLOBBER in
@@ -1416,7 +1400,7 @@ hash_expr_1 (x, mode, do_not_record_p)
           final assembler.  This also avoids differences in the dump files
           between various stages.  */
        unsigned int h = 0;
-       unsigned char *p = (unsigned char *) XSTR (x, 0);
+       const unsigned char *p = (const unsigned char *) XSTR (x, 0);
 
        while (*p)
          h += (h << 7) + *p++; /* ??? revisit */
@@ -1488,7 +1472,8 @@ hash_expr_1 (x, mode, do_not_record_p)
 
       else if (fmt[i] == 's')
        {
-         register unsigned char *p = (unsigned char *) XSTR (x, i);
+         register const unsigned char *p =
+           (const unsigned char *) XSTR (x, i);
 
          if (p)
            while (*p)
@@ -2123,9 +2108,9 @@ compute_hash_table (set_p)
   for (bb = 0; bb < n_basic_blocks; bb++)
     {
       rtx insn;
-      int regno;
+      unsigned int regno;
       int in_libcall_block;
-      int i;
+      unsigned int i;
 
       /* First pass over the instructions records information used to
         determine when registers and memory are first and last set.
@@ -2134,6 +2119,7 @@ compute_hash_table (set_p)
 
       for (i = 0; i < max_gcse_regno; i++)
        reg_first_set[i] = reg_last_set[i] = NEVER_SET;
+
       mem_first_set = NEVER_SET;
       mem_last_set = NEVER_SET;
 
@@ -2251,7 +2237,7 @@ compute_set_hash_table ()
 
 static void
 alloc_expr_hash_table (n_insns)
-     int n_insns;
+     unsigned int n_insns;
 {
   int n;
 
@@ -2320,7 +2306,7 @@ lookup_expr (pat)
 
 static struct expr *
 lookup_set (regno, pat)
-     int regno;
+     unsigned int regno;
      rtx pat;
 {
   unsigned int hash = hash_set (regno, set_hash_table_size);
@@ -2346,7 +2332,7 @@ lookup_set (regno, pat)
 
 static struct expr *
 next_set (regno, expr)
-     int regno;
+     unsigned int regno;
      struct expr *expr;
 {
   do
@@ -2697,7 +2683,7 @@ free_avail_expr_mem ()
 static void
 compute_ae_gen ()
 {
-  int i;
+  unsigned int i;
   struct expr *expr;
   struct occr *occr;
 
@@ -2779,7 +2765,8 @@ static void
 compute_ae_kill (ae_gen, ae_kill)
      sbitmap *ae_gen, *ae_kill;
 {
-  int bb, i;
+  int bb;
+  unsigned int i;
   struct expr *expr;
 
   for (bb = 0; bb < n_basic_blocks; bb++)
@@ -3073,7 +3060,7 @@ handle_avail_expr (insn, expr)
     {
       /* This is the case when the available expression that reaches
         here has already been handled as an available expression.  */
-      int regnum_for_replacing
+      unsigned int regnum_for_replacing
        = REGNO (SET_SRC (PATTERN (insn_computes_expr)));
 
       /* If the register was created by GCSE we can't use `reg_set_table',
@@ -3092,7 +3079,7 @@ handle_avail_expr (insn, expr)
 
   if (!found_setting)
     {
-      int regnum_for_replacing
+      unsigned int regnum_for_replacing
        = REGNO (SET_DEST (PATTERN (insn_computes_expr)));
 
       /* This shouldn't happen.  */
@@ -3835,7 +3822,7 @@ cprop_insn (insn, alter_jumps)
   for (reg_used = &reg_use_table[0]; reg_use_count > 0;
        reg_used++, reg_use_count--)
     {
-      int regno = REGNO (reg_used->reg_rtx);
+      unsigned int regno = REGNO (reg_used->reg_rtx);
       rtx pat, src;
       struct expr *set;
 
@@ -4122,10 +4109,24 @@ free_pre_mem ()
 static void
 compute_pre_data ()
 {
+  int i;
+
   compute_local_properties (transp, comp, antloc, 0);
   compute_transpout ();
   sbitmap_vector_zero (ae_kill, n_basic_blocks);
-  compute_ae_kill (comp, ae_kill);
+
+  /* Compute ae_kill for each basic block using:
+
+     ~(TRANSP | COMP)
+
+     This is significantly faster than compute_ae_kill.  */
+
+  for (i = 0; i < n_basic_blocks; i++)
+    {
+      sbitmap_a_or_b (ae_kill[i], transp[i], comp[i]);
+      sbitmap_not (ae_kill[i], ae_kill[i]);
+    }
+
   edge_list = pre_edge_lcm (gcse_file, n_exprs, transp, comp, antloc,
                            ae_kill, &pre_insert_map, &pre_delete_map);
 }
@@ -4350,10 +4351,9 @@ insert_insn_end_bb (expr, bb, pre)
         If we inserted before the CODE_LABEL, then we would be putting
         the insn in the wrong basic block.  In that case, put the insn
         after the CODE_LABEL.  Also, respect NOTE_INSN_BASIC_BLOCK.  */
-      if (GET_CODE (insn) == CODE_LABEL)
-       insn = NEXT_INSN (insn);
-      else if (GET_CODE (insn) == NOTE
-              && NOTE_LINE_NUMBER (insn) == NOTE_INSN_BASIC_BLOCK)
+      while (GET_CODE (insn) == CODE_LABEL
+            || (GET_CODE (insn) == NOTE
+                && NOTE_LINE_NUMBER (insn) == NOTE_INSN_BASIC_BLOCK))
        insn = NEXT_INSN (insn);
 
       new_insn = emit_block_insn_before (pat, insn, BASIC_BLOCK (bb));
@@ -4528,7 +4528,7 @@ pre_insert_copy_insn (expr, insn)
 static void
 pre_insert_copies ()
 {
-  int i;
+  unsigned int i;
   struct expr *expr;
   struct occr *occr;
   struct occr *avail;
@@ -4590,7 +4590,8 @@ pre_insert_copies ()
 static int
 pre_delete ()
 {
-  int i, bb, changed;
+  unsigned int i;
+  int bb, changed;
   struct expr *expr;
   struct occr *occr;
 
@@ -4681,8 +4682,8 @@ pre_delete ()
 static int
 pre_gcse ()
 {
-  int i, did_insert;
-  int changed;
+  unsigned int i;
+  int did_insert, changed;
   struct expr **index_map;
   struct expr *expr;
 
@@ -4824,7 +4825,7 @@ static void
 compute_transpout ()
 {
   int bb;
-  int i;
+  unsigned int i;
   struct expr *expr;
 
   sbitmap_vector_ones (transpout, n_basic_blocks);
@@ -4867,10 +4868,8 @@ invalidate_nonnull_info (x, setter, data)
      rtx setter ATTRIBUTE_UNUSED;
      void *data;
 {
-  int offset, regno;
-  struct null_pointer_info* npi = (struct null_pointer_info *) data;
-
-  offset = 0;
+  unsigned int regno;
+  struct null_pointer_info *npi = (struct null_pointer_info *) data;
 
   while (GET_CODE (x) == SUBREG)
     x = SUBREG_REG (x);
@@ -4893,7 +4892,7 @@ invalidate_nonnull_info (x, setter, data)
 
 static void
 delete_null_pointer_checks_1 (block_reg, nonnull_avin, nonnull_avout, npi)
-     int *block_reg;
+     unsigned int *block_reg;
      sbitmap *nonnull_avin;
      sbitmap *nonnull_avout;
      struct null_pointer_info *npi;
@@ -5059,27 +5058,19 @@ delete_null_pointer_checks_1 (block_reg, nonnull_avin, nonnull_avout, npi)
 
 void
 delete_null_pointer_checks (f)
-     rtx f;
+     rtx f ATTRIBUTE_UNUSED;
 {
   sbitmap *nonnull_avin, *nonnull_avout;
-  int *block_reg;
+  unsigned int *block_reg;
   int bb;
   int reg;
   int regs_per_pass;
   int max_reg;
   struct null_pointer_info npi;
 
-  /* First break the program into basic blocks.  */
-  find_basic_blocks (f, max_reg_num (), NULL);
-  cleanup_cfg (f);
-
   /* If we have only a single block, then there's nothing to do.  */
   if (n_basic_blocks <= 1)
-    {
-      /* Free storage allocated by find_basic_blocks.  */
-      free_basic_block_vars (0);
-      return;
-    }
+    return;
 
   /* Trying to perform global optimizations on flow graphs which have
      a high connectivity will take a long time and is unlikely to be
@@ -5090,11 +5081,7 @@ delete_null_pointer_checks (f)
      a couple switch statements.  So we require a relatively large number
      of basic blocks and the ratio of edges to blocks to be high.  */
   if (n_basic_blocks > 1000 && n_edges / n_basic_blocks >= 20)
-    {
-      /* Free storage allocated by find_basic_blocks.  */
-      free_basic_block_vars (0);
-      return;
-    }
+    return;
 
   /* We need four bitmaps, each with a bit for each register in each
      basic block.  */
@@ -5110,7 +5097,7 @@ delete_null_pointer_checks (f)
   /* Go through the basic blocks, seeing whether or not each block
      ends with a conditional branch whose condition is a comparison
      against zero.  Record the register compared in BLOCK_REG.  */
-  block_reg = (int *) xcalloc (n_basic_blocks, sizeof (int));
+  block_reg = (unsigned int *) xcalloc (n_basic_blocks, sizeof (int));
   for (bb = 0; bb < n_basic_blocks; bb++)
     {
       rtx last_insn = BLOCK_END (bb);
@@ -5118,8 +5105,8 @@ delete_null_pointer_checks (f)
 
       /* We only want conditional branches.  */
       if (GET_CODE (last_insn) != JUMP_INSN
-         || !condjump_p (last_insn)
-         || simplejump_p (last_insn))
+         || !any_condjump_p (last_insn)
+         || !onlyjump_p (last_insn))
        continue;
 
       /* LAST_INSN is a conditional jump.  Get its condition.  */
@@ -5151,9 +5138,6 @@ delete_null_pointer_checks (f)
                                    nonnull_avout, &npi);
     }
 
-  /* Free storage allocated by find_basic_blocks.  */
-  free_basic_block_vars (0);
-
   /* Free the table of registers compared at the end of every block.  */
   free (block_reg);
 
@@ -5334,7 +5318,8 @@ hoist_expr_reaches_here_p (expr_bb, expr_index, bb, visited)
 static void
 hoist_code ()
 {
-  int bb, dominated, i;
+  int bb, dominated;
+  unsigned int i;
   struct expr **index_map;
   struct expr *expr;