OSDN Git Service

* config/elfos.h, config/spu/spu.c, tree-ssa-operands.h,
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-dom.c
index 7656f36..73ddc0a 100644 (file)
@@ -101,7 +101,11 @@ static VEC(tree,heap) *avail_exprs_stack;
    expressions are removed from AVAIL_EXPRS.  Else we may change the
    hash code for an expression and be unable to find/remove it from
    AVAIL_EXPRS.  */
-static VEC(tree,heap) *stmts_to_rescan;
+typedef tree *tree_p;
+DEF_VEC_P(tree_p);
+DEF_VEC_ALLOC_P(tree_p,heap);
+
+static VEC(tree_p,heap) *stmts_to_rescan;
 
 /* Structure for entries in the expression hash table.
 
@@ -247,7 +251,7 @@ tree_ssa_dominator_optimize (void)
   avail_exprs = htab_create (1024, real_avail_expr_hash, avail_expr_eq, free);
   avail_exprs_stack = VEC_alloc (tree, heap, 20);
   const_and_copies_stack = VEC_alloc (tree, heap, 20);
-  stmts_to_rescan = VEC_alloc (tree, heap, 20);
+  stmts_to_rescan = VEC_alloc (tree_p, heap, 20);
   need_eh_cleanup = BITMAP_ALLOC (NULL);
 
   /* Setup callbacks for the generic dominator tree walker.  */
@@ -359,7 +363,7 @@ tree_ssa_dominator_optimize (void)
   
   VEC_free (tree, heap, avail_exprs_stack);
   VEC_free (tree, heap, const_and_copies_stack);
-  VEC_free (tree, heap, stmts_to_rescan);
+  VEC_free (tree_p, heap, stmts_to_rescan);
   return 0;
 }
 
@@ -701,16 +705,17 @@ dom_opt_finalize_block (struct dom_walk_data *walk_data, basic_block bb)
 
   /* If we queued any statements to rescan in this block, then
      go ahead and rescan them now.  */
-  while (VEC_length (tree, stmts_to_rescan) > 0)
+  while (VEC_length (tree_p, stmts_to_rescan) > 0)
     {
-      tree stmt = VEC_last (tree, stmts_to_rescan);
+      tree *stmt_p = VEC_last (tree_p, stmts_to_rescan);
+      tree stmt = *stmt_p;
       basic_block stmt_bb = bb_for_stmt (stmt);
 
       if (stmt_bb != bb)
        break;
 
-      VEC_pop (tree, stmts_to_rescan);
-      mark_new_vars_to_rename (stmt);
+      VEC_pop (tree_p, stmts_to_rescan);
+      pop_stmt_changes (stmt_p);
     }
 }
 
@@ -1481,7 +1486,7 @@ eliminate_redundant_computations (tree stmt)
   if (! def
       || TREE_CODE (def) != SSA_NAME
       || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (def)
-      || !ZERO_SSA_OPERANDS (stmt, SSA_OP_VMAYDEF)
+      || !ZERO_SSA_OPERANDS (stmt, SSA_OP_VDEF)
       /* Do not record equivalences for increments of ivs.  This would create
         overlapping live ranges for a very questionable gain.  */
       || simple_iv_increment_p (stmt))
@@ -1557,9 +1562,7 @@ eliminate_redundant_computations (tree stmt)
    Detect and record those equivalences.  */
 
 static void
-record_equivalences_from_stmt (tree stmt,
-                              int may_optimize_p,
-                              stmt_ann_t ann)
+record_equivalences_from_stmt (tree stmt, int may_optimize_p, stmt_ann_t ann)
 {
   tree lhs = GIMPLE_STMT_OPERAND (stmt, 0);
   enum tree_code lhs_code = TREE_CODE (lhs);
@@ -1588,6 +1591,7 @@ record_equivalences_from_stmt (tree stmt,
      vops and recording the result in the available expression table,
      we may be able to expose more redundant loads.  */
   if (!ann->has_volatile_ops
+      && stmt_references_memory_p (stmt)
       && (TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == SSA_NAME
          || is_gimple_min_invariant (GIMPLE_STMT_OPERAND (stmt, 1)))
       && !is_gimple_reg (lhs))
@@ -1621,7 +1625,7 @@ record_equivalences_from_stmt (tree stmt,
          /* Build a new statement with the RHS and LHS exchanged.  */
          new = build2_gimple (GIMPLE_MODIFY_STMT, rhs, lhs);
 
-         create_ssa_artficial_load_stmt (new, stmt);
+         create_ssa_artificial_load_stmt (new, stmt);
 
          /* Finally enter the statement into the available expression
             table.  */
@@ -1741,7 +1745,7 @@ cprop_operand (tree stmt, use_operand_p op_p)
    known value for that SSA_NAME (or NULL if no value is known).  
 
    Propagate values from CONST_AND_COPIES into the uses, vuses and
-   v_may_def_ops of STMT.  */
+   vdef_ops of STMT.  */
 
 static bool
 cprop_into_stmt (tree stmt)
@@ -1793,6 +1797,7 @@ optimize_stmt (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
   ann = stmt_ann (stmt);
   opt_stats.num_stmts++;
   may_have_exposed_new_symbols = false;
+  push_stmt_changes (bsi_stmt_ptr (si));
 
   if (dump_file && (dump_flags & TDF_DETAILS))
     {
@@ -1800,7 +1805,7 @@ optimize_stmt (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
       print_generic_stmt (dump_file, stmt, TDF_SLIM);
     }
 
-  /* Const/copy propagate into USES, VUSES and the RHS of V_MAY_DEFs.  */
+  /* Const/copy propagate into USES, VUSES and the RHS of VDEFs.  */
   may_have_exposed_new_symbols = cprop_into_stmt (stmt);
 
   /* If the statement has been modified with constant replacements,
@@ -1856,9 +1861,7 @@ optimize_stmt (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
 
   /* Record any additional equivalences created by this statement.  */
   if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
-    record_equivalences_from_stmt (stmt,
-                                  may_optimize_p,
-                                  ann);
+    record_equivalences_from_stmt (stmt, may_optimize_p, ann);
 
   /* If STMT is a COND_EXPR and it was modified, then we may know
      where it goes.  If that is the case, then mark the CFG as altered.
@@ -1885,7 +1888,6 @@ optimize_stmt (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
 
      Ultimately I suspect we're going to need to change the interface
      into the SSA_NAME manager.  */
-
   if (ann->modified)
     {
       tree val = NULL;
@@ -1909,7 +1911,20 @@ optimize_stmt (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
     }
 
   if (may_have_exposed_new_symbols)
-    VEC_safe_push (tree, heap, stmts_to_rescan, bsi_stmt (si));
+    {
+      /* Queue the statement to be re-scanned after all the
+        AVAIL_EXPRS have been processed.  The change buffer stack for
+        all the pushed statements will be processed when this queue
+        is emptied.  */
+      VEC_safe_push (tree_p, heap, stmts_to_rescan, bsi_stmt_ptr (si));
+    }
+  else
+    {
+      /* Otherwise, just discard the recently pushed change buffer.  If
+        not, the STMTS_TO_RESCAN queue will get out of synch with the
+        change buffer stack.  */
+      discard_stmt_changes (bsi_stmt_ptr (si));
+    }
 }
 
 /* Search for an existing instance of STMT in the AVAIL_EXPRS table.  If
@@ -2089,7 +2104,7 @@ static void
 remove_stmt_or_phi (tree t)
 {
   if (TREE_CODE (t) == PHI_NODE)
-    remove_phi_node (t, NULL);
+    remove_phi_node (t, NULL, true);
   else
     {
       block_stmt_iterator bsi = bsi_for_stmt (t);
@@ -2185,6 +2200,8 @@ propagate_rhs_into_lhs (tree stmt, tree lhs, tree rhs, bitmap interesting_names)
              fprintf (dump_file, "\n");
            }
 
+         push_stmt_changes (&use_stmt);
+
          /* Propagate the RHS into this use of the LHS.  */
          FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
            propagate_value (use_p, rhs);
@@ -2219,6 +2236,8 @@ propagate_rhs_into_lhs (tree stmt, tree lhs, tree rhs, bitmap interesting_names)
                  tree result = get_lhs_or_phi_result (use_stmt);
                  bitmap_set_bit (interesting_names, SSA_NAME_VERSION (result));
                }
+
+             discard_stmt_changes (&use_stmt);
              continue;
            }
 
@@ -2231,7 +2250,7 @@ propagate_rhs_into_lhs (tree stmt, tree lhs, tree rhs, bitmap interesting_names)
          /* Sometimes propagation can expose new operands to the
             renamer.  Note this will call update_stmt at the 
             appropriate time.  */
-         mark_new_vars_to_rename (use_stmt);
+         pop_stmt_changes (&use_stmt);
 
          /* Dump details.  */
          if (dump_file && (dump_flags & TDF_DETAILS))
@@ -2447,6 +2466,7 @@ static unsigned int
 eliminate_degenerate_phis (void)
 {
   bitmap interesting_names;
+  bitmap interesting_names1;
 
   /* Bitmap of blocks which need EH information updated.  We can not
      update it on-the-fly as doing so invalidates the dominator tree.  */
@@ -2463,6 +2483,7 @@ eliminate_degenerate_phis (void)
      Experiments have show we generally get better compilation
      time behavior with bitmaps rather than sbitmaps.  */
   interesting_names = BITMAP_ALLOC (NULL);
+  interesting_names1 = BITMAP_ALLOC (NULL);
 
   /* First phase.  Eliminate degenerate PHIs via a dominator
      walk of the CFG.
@@ -2484,7 +2505,12 @@ eliminate_degenerate_phis (void)
       unsigned int i;
       bitmap_iterator bi;
 
-      EXECUTE_IF_SET_IN_BITMAP (interesting_names, 0, i, bi)
+      /* EXECUTE_IF_SET_IN_BITMAP does not like its bitmap
+        changed during the loop.  Copy it to another bitmap and
+        use that.  */
+      bitmap_copy (interesting_names1, interesting_names);
+
+      EXECUTE_IF_SET_IN_BITMAP (interesting_names1, 0, i, bi)
        {
          tree name = ssa_name (i);
 
@@ -2505,6 +2531,7 @@ eliminate_degenerate_phis (void)
     }
 
   BITMAP_FREE (interesting_names);
+  BITMAP_FREE (interesting_names1);
   if (cfg_altered)
     free_dominance_info (CDI_DOMINATORS);
   return 0;