OSDN Git Service

2000-08-10 Alexandre Petit-Bianco <apbianco@cygnus.com>
[pf3gnuchains/gcc-fork.git] / gcc / gcse.c
index 996cde9..680eb4f 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;
@@ -489,13 +494,6 @@ static int copy_prop_count;
    Normally they'd be defined a bit later, but `rd_gen' needs to
    be declared sooner.  */
 
-/* A bitmap of all ones for implementing the algorithm for available
-   expressions and reaching definitions.  */
-/* ??? Available expression bitmaps have a different size than reaching
-   definition bitmaps.  This should be the larger of the two, however, it
-   is not currently used for reaching definitions.  */
-static sbitmap u_bitmap;
-
 /* Each block has a bitmap of each type.
    The length of each blocks bitmap is:
 
@@ -560,7 +558,7 @@ 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 **,
@@ -894,10 +892,10 @@ alloc_gcse_mem (f)
   bzero ((char *) uid_cuid, n);
   for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
     {
-      if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
-       INSN_CUID (insn) = i++;
+      if (INSN_P (insn))
+       uid_cuid[INSN_UID (insn)] = i++;
       else
-       INSN_CUID (insn) = i;
+       uid_cuid[INSN_UID (insn)] = i;
     }
 
   /* Create a table mapping cuids to insns.  */
@@ -907,7 +905,7 @@ alloc_gcse_mem (f)
   cuid_insn = (rtx *) gmalloc (n);
   bzero ((char *) cuid_insn, n);
   for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
-    if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
+    if (INSN_P (insn))
       CUID_INSN (i++) = insn;
 
   /* Allocate vars to track sets of regs.  */
@@ -1011,7 +1009,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.  */
@@ -1116,7 +1114,7 @@ record_one_set (regno, insn)
      rtx insn;
 {
   /* allocate a new reg_set element and link it onto the list */
-  struct reg_set *new_reg_info, *reg_info_ptr1, *reg_info_ptr2;
+  struct reg_set *new_reg_info;
 
   /* If the table isn't big enough, enlarge it.  */
   if (regno >= reg_set_table_size)
@@ -1135,21 +1133,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
@@ -1179,7 +1164,7 @@ compute_sets (f)
   rtx insn;
 
   for (insn = f; insn != 0; insn = NEXT_INSN (insn))
-    if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
+    if (INSN_P (insn))
       note_stores (PATTERN (insn), record_set_info, insn);
 }
 \f
@@ -1265,6 +1250,8 @@ oprs_unchanged_p (x, insn, avail_p)
     case PRE_INC:
     case POST_DEC:
     case POST_INC:
+    case PRE_MODIFY:
+    case POST_MODIFY:
       return 0;
 
     case PC:
@@ -2145,7 +2132,7 @@ compute_hash_table (set_p)
            }
 #endif
 
-         if (GET_RTX_CLASS (GET_CODE (insn)) != 'i')
+         if (! INSN_P (insn))
            continue;
 
          if (GET_CODE (insn) == CALL_INSN)
@@ -2179,7 +2166,7 @@ compute_hash_table (set_p)
       for (insn = BLOCK_HEAD (bb), in_libcall_block = 0;
           insn && insn != NEXT_INSN (BLOCK_END (bb));
           insn = NEXT_INSN (insn))
-       if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
+       if (INSN_P (insn))
          {
            if (find_reg_note (insn, REG_LIBCALL, NULL_RTX))
              in_libcall_block = 1;
@@ -2245,7 +2232,7 @@ compute_set_hash_table ()
 
 static void
 alloc_expr_hash_table (n_insns)
-     int n_insns;
+     unsigned int n_insns;
 {
   int n;
 
@@ -2671,9 +2658,6 @@ alloc_avail_expr_mem (n_blocks, n_exprs)
 
   ae_out = (sbitmap *) sbitmap_vector_alloc (n_blocks, n_exprs);
   sbitmap_vector_zero (ae_out, n_basic_blocks);
-
-  u_bitmap = (sbitmap) sbitmap_alloc (n_exprs);
-  sbitmap_ones (u_bitmap);
 }
 
 static void
@@ -2683,7 +2667,6 @@ free_avail_expr_mem ()
   free (ae_gen);
   free (ae_in);
   free (ae_out);
-  free (u_bitmap);
 }
 
 /* Compute the set of available expressions generated in each basic block.  */
@@ -2691,7 +2674,7 @@ free_avail_expr_mem ()
 static void
 compute_ae_gen ()
 {
-  int i;
+  unsigned int i;
   struct expr *expr;
   struct occr *occr;
 
@@ -2773,7 +2756,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++)
@@ -3242,7 +3226,7 @@ classic_gcse ()
 
          /* Keep track of everything modified by this insn.  */
          /* ??? Need to be careful w.r.t. mods done to INSN.  */
-         if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
+         if (INSN_P (insn))
            mark_oprs_set (insn);
        }
     }
@@ -3594,8 +3578,10 @@ try_replace_reg (from, to, insn)
     {
       rtx simplified;
 
+      if (!validate_replace_rtx_subexp (from, to, insn, &XEXP (note, 0)))
+       abort();
+
       src = XEXP (note, 0);
-      replace_rtx (src, from, to);
 
       /* Try to simplify resulting note. */
       simplified = simplify_rtx (src);
@@ -3953,7 +3939,7 @@ cprop (alter_jumps)
           insn != NULL && insn != NEXT_INSN (BLOCK_END (bb));
           insn = NEXT_INSN (insn))
        {
-         if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
+         if (INSN_P (insn))
            {
              changed |= cprop_insn (insn, alter_jumps);
 
@@ -4045,8 +4031,6 @@ static sbitmap *pre_delete_map;
 /* Contains the edge_list returned by pre_edge_lcm.  */
 static struct edge_list *edge_list;
 
-static sbitmap *temp_bitmap;
-
 /* Redundant insns.  */
 static sbitmap pre_redundant_insns;
 
@@ -4059,7 +4043,6 @@ alloc_pre_mem (n_blocks, n_exprs)
   transp = sbitmap_vector_alloc (n_blocks, n_exprs);
   comp = sbitmap_vector_alloc (n_blocks, n_exprs);
   antloc = sbitmap_vector_alloc (n_blocks, n_exprs);
-  temp_bitmap = sbitmap_vector_alloc (n_blocks, n_exprs);
 
   pre_optimal = NULL;
   pre_redundant = NULL;
@@ -4067,8 +4050,6 @@ alloc_pre_mem (n_blocks, n_exprs)
   pre_delete_map = NULL;
   ae_in = NULL;
   ae_out = NULL;
-  u_bitmap = NULL;
-  transpout = sbitmap_vector_alloc (n_blocks, n_exprs);
   ae_kill = sbitmap_vector_alloc (n_blocks, n_exprs);
 
   /* pre_insert and pre_delete are allocated later.  */
@@ -4081,8 +4062,8 @@ free_pre_mem ()
 {
   free (transp);
   free (comp);
-  free (antloc);
-  free (temp_bitmap);
+
+  /* ANTLOC and AE_KILL are freed just after pre_lcm finishes.  */
 
   if (pre_optimal)
     free (pre_optimal);
@@ -4092,23 +4073,15 @@ free_pre_mem ()
     free (pre_insert_map);
   if (pre_delete_map)
     free (pre_delete_map);
-  if (transpout)
-    free (transpout);
 
   if (ae_in)
     free (ae_in);
   if (ae_out)
     free (ae_out);
-  if (ae_kill)
-    free (ae_kill);
-  if (u_bitmap)
-    free (u_bitmap);
 
-  transp = comp = antloc = NULL;
+  transp = comp = NULL;
   pre_optimal = pre_redundant = pre_insert_map = pre_delete_map = NULL;
-  transpout = ae_in = ae_out = ae_kill = NULL;
-  u_bitmap = NULL;
-
+  ae_in = ae_out = NULL;
 }
 
 /* Top level routine to do the dataflow analysis needed by PRE.  */
@@ -4116,12 +4089,29 @@ 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);
+  free (antloc);
+  antloc = NULL;
+  free (ae_kill);
+  ae_kill = NULL; 
 }
 \f
 /* PRE utilities */
@@ -4275,7 +4265,7 @@ insert_insn_end_bb (expr, bb, pre)
        {
          rtx maybe_cc0_setter = prev_nonnote_insn (insn);
          if (maybe_cc0_setter
-             && GET_RTX_CLASS (GET_CODE (maybe_cc0_setter)) == 'i'
+             && INSN_P (maybe_cc0_setter)
              && sets_cc0_p (PATTERN (maybe_cc0_setter)))
            insn = maybe_cc0_setter;
        }
@@ -4344,10 +4334,8 @@ 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
+            || NOTE_INSN_BASIC_BLOCK_P (insn))
        insn = NEXT_INSN (insn);
 
       new_insn = emit_block_insn_before (pat, insn, BASIC_BLOCK (bb));
@@ -4368,7 +4356,7 @@ insert_insn_end_bb (expr, bb, pre)
          rtx insn = XVECEXP (pat, 0, i);
 
          set_block_num (insn, bb);
-         if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
+         if (INSN_P (insn))
            add_label_notes (PATTERN (insn), new_insn);
 
          note_stores (PATTERN (insn), record_set_info, insn);
@@ -4522,7 +4510,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;
@@ -4584,15 +4572,11 @@ pre_insert_copies ()
 static int
 pre_delete ()
 {
-  int i, bb, changed;
+  unsigned int i;
+  int changed;
   struct expr *expr;
   struct occr *occr;
 
-  /* Compute the expressions which are redundant and need to be replaced by
-     copies from the reaching reg to the target reg.  */
-  for (bb = 0; bb < n_basic_blocks; bb++)
-    sbitmap_copy (temp_bitmap[bb], pre_delete_map[bb]);
-
   changed = 0;
   for (i = 0; i < expr_hash_table_size; i++)
     for (expr = expr_hash_table[i]; expr != NULL; expr = expr->next_same_hash)
@@ -4608,7 +4592,7 @@ pre_delete ()
            rtx set;
            int bb = BLOCK_NUM (insn);
 
-           if (TEST_BIT (temp_bitmap[bb], indx))
+           if (TEST_BIT (pre_delete_map[bb], indx))
              {
                set = single_set (insn);
                if (! set)
@@ -4675,8 +4659,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;
 
@@ -4818,7 +4802,7 @@ static void
 compute_transpout ()
 {
   int bb;
-  int i;
+  unsigned int i;
   struct expr *expr;
 
   sbitmap_vector_ones (transpout, n_basic_blocks);
@@ -4924,7 +4908,7 @@ delete_null_pointer_checks_1 (block_reg, nonnull_avin, nonnull_avout, npi)
          rtx reg;
 
          /* Ignore anything that is not a normal insn.  */
-         if (GET_RTX_CLASS (GET_CODE (insn)) != 'i')
+         if (! INSN_P (insn))
            continue;
 
          /* Basically ignore anything that is not a simple SET.  We do have
@@ -5051,7 +5035,7 @@ 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;
   unsigned int *block_reg;
@@ -5090,7 +5074,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);
@@ -5098,8 +5082,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.  */
@@ -5311,7 +5295,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;