OSDN Git Service

2004-11-01 Andrew Pinski <pinskia@physics.uc.edu>
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-pre.c
index bf332f4..7f70c84 100644 (file)
@@ -363,7 +363,7 @@ expr_pred_trans_eq (const void *p1, const void *p2)
     return false;
 
   /* If they are for the same basic block, determine if the
-     expressions are equal.   */  
+     expressions are equal.  */  
   if (expressions_equal_p (ve1->e, ve2->e))
     return true;
   
@@ -510,8 +510,10 @@ bitmap_insert_into_set (bitmap_set_t set, tree expr)
   
   gcc_assert (val);
   if (!is_gimple_min_invariant (val))
+  {
     bitmap_set_bit (set->values, VALUE_HANDLE_ID (val));
-  bitmap_set_bit (set->expressions, SSA_NAME_VERSION (expr));
+    bitmap_set_bit (set->expressions, SSA_NAME_VERSION (expr));
+  }
 }
 
 /* Insert EXPR into SET.  */
@@ -522,6 +524,9 @@ insert_into_set (value_set_t set, tree expr)
   value_set_node_t newnode = pool_alloc (value_set_node_pool);
   tree val = get_value_handle (expr);
   gcc_assert (val);
+  
+  if (is_gimple_min_invariant (val))
+    return;
 
   /* For indexed sets, insert the value into the set value bitmap.
      For all sets, add it to the linked list and increment the list
@@ -764,16 +769,18 @@ bitmap_print_value_set (FILE *outfile, bitmap_set_t set,
   if (set)
     {
       int i;
-      EXECUTE_IF_SET_IN_BITMAP (set->expressions, 0, i,
-      {
-       print_generic_expr (outfile, ssa_name (i), 0);
+      bitmap_iterator bi;
+
+      EXECUTE_IF_SET_IN_BITMAP (set->expressions, 0, i, bi)
+       {
+         print_generic_expr (outfile, ssa_name (i), 0);
        
-       fprintf (outfile, " (");
-       print_generic_expr (outfile, get_value_handle (ssa_name (i)), 0);
-       fprintf (outfile, ") ");
-       if (bitmap_last_set_bit (set->expressions) != i)
-         fprintf (outfile, ", ");
-      });
+         fprintf (outfile, " (");
+         print_generic_expr (outfile, get_value_handle (ssa_name (i)), 0);
+         fprintf (outfile, ") ");
+         if (bitmap_last_set_bit (set->expressions) != i)
+           fprintf (outfile, ", ");
+       }
     }
   fprintf (outfile, " }\n");
 }
@@ -848,15 +855,21 @@ phi_translate (tree expr, value_set_t set, basic_block pred,
   if (expr == NULL)
     return NULL;
 
-  /* Phi translations of a given expression don't change,  */
+  if (is_gimple_min_invariant (expr))
+    return expr;
+
+  /* Phi translations of a given expression don't change.  */
   phitrans = phi_trans_lookup (expr, pred);
   if (phitrans)
     return phitrans;
   
-  
   switch (TREE_CODE_CLASS (TREE_CODE (expr)))
     {
-    case '2':
+    case tcc_reference:
+      /* XXX: Until we have PRE of loads working, none will be ANTIC.  */
+      return NULL;
+
+    case tcc_binary:
       {
        tree oldop1 = TREE_OPERAND (expr, 0);
        tree oldop2 = TREE_OPERAND (expr, 1);
@@ -884,13 +897,9 @@ phi_translate (tree expr, value_set_t set, basic_block pred,
            phi_trans_add (oldexpr, newexpr, pred);         
          }
       }
-      break;
-      /* XXX: Until we have PRE of loads working, none will be ANTIC.
-       */
-    case 'r':
-      return NULL;
-      break;
-    case '1':
+      return expr;
+
+    case tcc_unary:
       {
        tree oldop1 = TREE_OPERAND (expr, 0);
        tree newop1;
@@ -911,10 +920,9 @@ phi_translate (tree expr, value_set_t set, basic_block pred,
            phi_trans_add (oldexpr, newexpr, pred);
          }
       }
-      break;
-    case 'd':
-      gcc_unreachable ();
-    case 'x':
+      return expr;
+
+    case tcc_exceptional:
       {
        tree phi = NULL;
        int i;
@@ -934,9 +942,11 @@ phi_translate (tree expr, value_set_t set, basic_block pred,
              return PHI_ARG_DEF (phi, i);
            }
       }
-      break;
+      return expr;
+
+    default:
+      gcc_unreachable ();
     }
-  return expr;
 }
 
 static void
@@ -1046,34 +1056,31 @@ valid_in_set (value_set_t set, tree expr)
 {
   switch (TREE_CODE_CLASS (TREE_CODE (expr)))
     {
-    case '2':
+    case tcc_binary:
       {
        tree op1 = TREE_OPERAND (expr, 0);
        tree op2 = TREE_OPERAND (expr, 1);
        return set_contains_value (set, op1) && set_contains_value (set, op2);
       }
-      break;
-    case '1':
+
+    case tcc_unary:
       {
        tree op1 = TREE_OPERAND (expr, 0);
        return set_contains_value (set, op1);
       }
-      break;
-      /* XXX: Until PRE of loads works, no reference nodes are ANTIC.
-       */
-    case 'r':
-      {
-       return false;
-      }
-    case 'x':
-      {
-       gcc_assert (TREE_CODE (expr) == SSA_NAME);
-       return true;
-      }
-    case 'c':
-      gcc_unreachable ();
-    }
-  return false;
+
+    case tcc_reference:
+      /* XXX: Until PRE of loads works, no reference nodes are ANTIC.  */
+      return false;
+
+    case tcc_exceptional:
+      gcc_assert (TREE_CODE (expr) == SSA_NAME);
+      return true;
+
+    default:
+      /* No other cases should be encountered.  */
+      gcc_unreachable (); 
+   }
 }
 
 /* Clean the set of expressions that are no longer valid in SET.  This
@@ -1095,6 +1102,8 @@ clean (value_set_t set)
     }
 }
 
+DEF_VEC_MALLOC_P (basic_block);
+
 /* Compute the ANTIC set for BLOCK.
 
 ANTIC_OUT[BLOCK] = intersection of ANTIC_IN[b] for all succ(BLOCK), if
@@ -1128,12 +1137,13 @@ compute_antic_aux (basic_block block)
      setting the BB_VISITED flag.  */
   if (! (block->flags & BB_VISITED))
     {
-      for (e = block->pred; e; e = e->pred_next)
-       if (e->flags & EDGE_ABNORMAL)
-         {
-           block->flags |= BB_VISITED;
-           break;
-         }
+      edge_iterator ei;
+      FOR_EACH_EDGE (e, ei, block->preds)
+       if (e->flags & EDGE_ABNORMAL)
+         {
+           block->flags |= BB_VISITED;
+           break;
+         }
     }
   if (block->flags & BB_VISITED)
     {
@@ -1148,37 +1158,33 @@ compute_antic_aux (basic_block block)
 
   /* If the block has no successors, ANTIC_OUT is empty, because it is
      the exit block.  */
-  if (block->succ == NULL);
+  if (EDGE_COUNT (block->succs) == 0);
 
   /* If we have one successor, we could have some phi nodes to
      translate through.  */
-  else if (block->succ->succ_next == NULL)
+  else if (EDGE_COUNT (block->succs) == 1)
     {
-      phi_translate_set (ANTIC_OUT, ANTIC_IN(block->succ->dest),
-                        block, block->succ->dest);
+      phi_translate_set (ANTIC_OUT, ANTIC_IN(EDGE_SUCC (block, 0)->dest),
+                        block, EDGE_SUCC (block, 0)->dest);
     }
   /* If we have multiple successors, we take the intersection of all of
      them.  */
   else
     {
-      varray_type worklist;
+      VEC (basic_block) * worklist;
       edge e;
       size_t i;
       basic_block bprime, first;
+      edge_iterator ei;
 
-      VARRAY_BB_INIT (worklist, 1, "succ");
-      e = block->succ;
-      while (e)
-       {
-         VARRAY_PUSH_BB (worklist, e->dest);
-         e = e->succ_next;
-       }
-      first = VARRAY_BB (worklist, 0);
+      worklist = VEC_alloc (basic_block, 2);
+      FOR_EACH_EDGE (e, ei, block->succs)
+       VEC_safe_push (basic_block, worklist, e->dest);
+      first = VEC_index (basic_block, worklist, 0);
       set_copy (ANTIC_OUT, ANTIC_IN (first));
 
-      for (i = 1; i < VARRAY_ACTIVE_SIZE (worklist); i++)
+      for (i = 1; VEC_iterate (basic_block, worklist, i, bprime); i++)
        {
-         bprime = VARRAY_BB (worklist, i);
          node = ANTIC_OUT->head;
          while (node)
            {
@@ -1190,10 +1196,10 @@ compute_antic_aux (basic_block block)
              node = next;
            }
        }
-      VARRAY_CLEAR (worklist);
+      VEC_free (basic_block, worklist);
     }
 
-  /* Generate ANTIC_OUT - TMP_GEN */
+  /* Generate ANTIC_OUT - TMP_GEN */
   S = bitmap_set_subtract_from_value_set (ANTIC_OUT, TMP_GEN (block), false);
 
   /* Start ANTIC_IN with EXP_GEN - TMP_GEN */
@@ -1291,9 +1297,9 @@ find_or_generate_expression (basic_block block, tree expr, tree stmts)
   if (genop == NULL)
     {
       genop = VALUE_HANDLE_EXPR_SET (expr)->head->expr;
-      gcc_assert (TREE_CODE_CLASS (TREE_CODE (genop)) == '1'
-                 || TREE_CODE_CLASS (TREE_CODE (genop)) == '2'
-                 || TREE_CODE_CLASS (TREE_CODE (genop)) == 'r');
+      gcc_assert (UNARY_CLASS_P (genop)
+                 || BINARY_CLASS_P (genop)
+                 || REFERENCE_CLASS_P (genop));
       genop = create_expression_by_pieces (block, genop, stmts);
     }
   return genop;
@@ -1323,7 +1329,7 @@ create_expression_by_pieces (basic_block block, tree expr, tree stmts)
   
   switch (TREE_CODE_CLASS (TREE_CODE (expr)))
     {
-    case '2':
+    case tcc_binary:
       {
        tree_stmt_iterator tsi;
        tree genop1, genop2;
@@ -1345,7 +1351,7 @@ create_expression_by_pieces (basic_block block, tree expr, tree stmts)
        pre_stats.insertions++;
        break;
       }
-    case '1':
+    case tcc_unary:
       {
        tree_stmt_iterator tsi;
        tree genop1;
@@ -1410,21 +1416,23 @@ insert_aux (basic_block block)
       if (dom)
        {
          int i;
+         bitmap_iterator bi;
+
          bitmap_set_t newset = NEW_SETS (dom);
-         EXECUTE_IF_SET_IN_BITMAP (newset->expressions, 0, i,
-          {
-           bitmap_insert_into_set (NEW_SETS (block), ssa_name (i));
-           bitmap_value_replace_in_set (AVAIL_OUT (block), ssa_name (i));
-         });
-         if (block->pred->pred_next)
+         EXECUTE_IF_SET_IN_BITMAP (newset->expressions, 0, i, bi)
+           {
+             bitmap_insert_into_set (NEW_SETS (block), ssa_name (i));
+             bitmap_value_replace_in_set (AVAIL_OUT (block), ssa_name (i));
+           }
+         if (EDGE_COUNT (block->preds) > 1)
            {
              value_set_node_t node;
              for (node = ANTIC_IN (block)->head;
                   node;
                   node = node->next)
                {
-                 if (TREE_CODE_CLASS (TREE_CODE (node->expr)) == '2'
-                     || TREE_CODE_CLASS (TREE_CODE (node->expr)) == '1')
+                 if (BINARY_CLASS_P (node->expr)
+                     || UNARY_CLASS_P (node->expr))
                    {
                      tree *avail;
                      tree val;
@@ -1435,6 +1443,7 @@ insert_aux (basic_block block)
                      edge pred;
                      basic_block bprime;
                      tree eprime;
+                     edge_iterator ei;
 
                      val = get_value_handle (node->expr);
                      if (bitmap_set_contains_value (PHI_GEN (block), val))
@@ -1445,11 +1454,9 @@ insert_aux (basic_block block)
                            fprintf (dump_file, "Found fully redundant value\n");
                          continue;
                        }
-                                   
+                                             
                      avail = xcalloc (last_basic_block, sizeof (tree));
-                     for (pred = block->pred;
-                          pred;
-                          pred = pred->pred_next)
+                     FOR_EACH_EDGE (pred, ei, block->preds)
                        {
                          tree vprime;
                          tree edoubleprime;
@@ -1510,7 +1517,7 @@ insert_aux (basic_block block)
                         partially redundant.  */
                      if (!cant_insert && !all_same && by_some)
                        {
-                         tree type = TREE_TYPE (avail[block->pred->src->index]);
+                         tree type = TREE_TYPE (avail[EDGE_PRED (block, 0)->src->index]);
                          tree temp;
                          if (dump_file && (dump_flags & TDF_DETAILS))
                            {
@@ -1520,25 +1527,22 @@ insert_aux (basic_block block)
                            }
 
                          /* Make the necessary insertions.  */
-                         for (pred = block->pred;
-                              pred;
-                              pred = pred->pred_next)
+                         FOR_EACH_EDGE (pred, ei, block->preds)
                            {
                              tree stmts = alloc_stmt_list ();
                              tree builtexpr;
                              bprime = pred->src;
                              eprime = avail[bprime->index];
-                             if (TREE_CODE_CLASS (TREE_CODE (eprime)) == '2'
-                                 || TREE_CODE_CLASS (TREE_CODE (eprime)) == '1')
+                             if (BINARY_CLASS_P (eprime)
+                                 || UNARY_CLASS_P (eprime))
                                {
                                  builtexpr = create_expression_by_pieces (bprime,
                                                                           eprime,
                                                                           stmts);
                                  bsi_insert_on_edge (pred, stmts);
-                                 bsi_commit_edge_inserts (NULL);
                                  avail[bprime->index] = builtexpr;
                                }                             
-                           } 
+                           }
                          /* Now build a phi for the new variable.  */
                          temp = create_tmp_var (type, "prephitmp");
                          add_referenced_tmp_var (temp);
@@ -1553,9 +1557,7 @@ insert_aux (basic_block block)
 #endif
                            bitmap_value_replace_in_set (AVAIL_OUT (block), 
                                                         PHI_RESULT (temp));
-                         for (pred = block->pred;
-                              pred;
-                              pred = pred->pred_next)
+                         FOR_EACH_EDGE (pred, ei, block->preds)
                            {
                              add_phi_arg (&temp, avail[pred->src->index],
                                           pred);
@@ -1622,8 +1624,7 @@ is_undefined_value (tree expr)
   return (TREE_CODE (expr) == SSA_NAME
           && IS_EMPTY_STMT (SSA_NAME_DEF_STMT (expr))
          /* PARM_DECLs and hard registers are always defined.  */
-         && TREE_CODE (SSA_NAME_VAR (expr)) != PARM_DECL
-         && !DECL_HARD_REGISTER (SSA_NAME_VAR (expr)));
+         && TREE_CODE (SSA_NAME_VAR (expr)) != PARM_DECL);
 }
 
 
@@ -1668,13 +1669,13 @@ create_value_expr_from (tree expr, basic_block block, vuse_optype vuses)
   enum tree_code code = TREE_CODE (expr);
   tree vexpr;
 
-  gcc_assert (TREE_CODE_CLASS (code) == '1'
-             || TREE_CODE_CLASS (code) == '2'
-             || TREE_CODE_CLASS (code) == 'r');
+  gcc_assert (TREE_CODE_CLASS (code) == tcc_unary
+             || TREE_CODE_CLASS (code) == tcc_binary
+             || TREE_CODE_CLASS (code) == tcc_reference);
 
-  if (TREE_CODE_CLASS (code) == '1')
+  if (TREE_CODE_CLASS (code) == tcc_unary)
     vexpr = pool_alloc (unary_node_pool);
-  else if (TREE_CODE_CLASS (code) == 'r')
+  else if (TREE_CODE_CLASS (code) == tcc_reference)
     vexpr = pool_alloc (reference_node_pool);
   else
     vexpr = pool_alloc (binary_node_pool);
@@ -1791,8 +1792,7 @@ compute_avail (basic_block block)
                    value_insert_into_set (EXP_GEN (block), rhs);
                  continue;
                }          
-             else if (TREE_CODE_CLASS (TREE_CODE (rhs)) == '1'
-                      || TREE_CODE_CLASS (TREE_CODE (rhs)) == '2'
+             else if (UNARY_CLASS_P (rhs) || BINARY_CLASS_P (rhs)
                       || TREE_CODE (rhs) == INDIRECT_REF)
                {
                  /* For binary, unary, and reference expressions,
@@ -1918,9 +1918,9 @@ init_pre (void)
      ENTRY_BLOCK_PTR (FIXME, if ENTRY_BLOCK_PTR had an index number
      different than -1 we wouldn't have to hack this.  tree-ssa-dce.c
      needs a similar change).  */
-  if (ENTRY_BLOCK_PTR->succ->dest->pred->pred_next)
-    if (!(ENTRY_BLOCK_PTR->succ->flags & EDGE_ABNORMAL))
-      split_edge (ENTRY_BLOCK_PTR->succ);
+  if (EDGE_COUNT (EDGE_SUCC (ENTRY_BLOCK_PTR, 0)->dest->preds) > 1)
+    if (!(EDGE_SUCC (ENTRY_BLOCK_PTR, 0)->flags & EDGE_ABNORMAL))
+      split_edge (EDGE_SUCC (ENTRY_BLOCK_PTR, 0));
 
   FOR_ALL_BB (bb)
     bb->aux = xcalloc (1, sizeof (struct bb_value_sets));
@@ -1941,7 +1941,7 @@ init_pre (void)
   unary_node_pool = create_alloc_pool ("Unary tree nodes",
                                       tree_code_size (NEGATE_EXPR), 30);
   reference_node_pool = create_alloc_pool ("Reference tree nodes",
-                                          tree_code_size (COMPONENT_REF), 30);
+                                          tree_code_size (ARRAY_REF), 30);
   FOR_ALL_BB (bb)
     {
       EXP_GEN (bb) = set_new (true);
@@ -1960,6 +1960,9 @@ static void
 fini_pre (void)
 {
   basic_block bb;
+  unsigned int i;
+
+  bsi_commit_edge_inserts (NULL);
 
   obstack_free (&grand_bitmap_obstack, NULL);
   free_alloc_pool (value_set_pool);
@@ -1980,13 +1983,27 @@ fini_pre (void)
   free_dominance_info (CDI_POST_DOMINATORS);
   vn_delete ();
 
-  if (bitmap_first_set_bit (need_eh_cleanup) >= 0)
+  if (!bitmap_empty_p (need_eh_cleanup))
     {
       tree_purge_all_dead_eh_edges (need_eh_cleanup);
       cleanup_tree_cfg ();
     }
 
   BITMAP_XFREE (need_eh_cleanup);
+
+  /* Wipe out pointers to VALUE_HANDLEs.  In the not terribly distant
+     future we will want them to be persistent though.  */
+  for (i = 0; i < num_ssa_names; i++)
+    {
+      tree name = ssa_name (i);
+
+      if (!name)
+       continue;
+
+      if (SSA_NAME_VALUE (name)
+         && TREE_CODE (SSA_NAME_VALUE (name)) == VALUE_HANDLE)
+       SSA_NAME_VALUE (name) = NULL;
+    }
 }