OSDN Git Service

* config/rs6000/darwin.h (SUBTARGET_OPTIONS): Move from here, to...
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-pre.c
index ba4be7b..1267a54 100644 (file)
@@ -307,6 +307,10 @@ static alloc_pool binary_node_pool;
 static alloc_pool unary_node_pool;
 static alloc_pool reference_node_pool;
 
+/* Set of blocks with statements that have had its EH information
+   cleaned up.  */
+static bitmap need_eh_cleanup;
+
 /* The phi_translate_table caches phi translations for a given
    expression and predecessor.  */
 
@@ -625,6 +629,10 @@ set_contains_value (value_set_t set, tree val)
 static bool
 bitmap_set_contains (bitmap_set_t set, tree expr)
 {
+  /* All constants are in every set.  */
+  if (is_gimple_min_invariant (get_value_handle (expr)))
+    return true;
+
   /* XXX: Bitmapped sets only contain SSA_NAME's for now.  */
   if (TREE_CODE (expr) != SSA_NAME)
     return false;
@@ -730,6 +738,7 @@ static void
 bitmap_value_insert_into_set (bitmap_set_t set, tree expr)
 {
   tree val = get_value_handle (expr);
+
   if (is_gimple_min_invariant (val))
     return;
   
@@ -1457,6 +1466,15 @@ insert_aux (basic_block block)
                        {
                          tree vprime;
                          tree edoubleprime;
+
+                         /* This can happen in the very weird case
+                            that our fake infinite loop edges have caused a
+                            critical edge to appear.  */
+                         if (EDGE_CRITICAL_P (pred))
+                           {
+                             cant_insert = true;
+                             break;
+                           }
                          bprime = pred->src;
                          eprime = phi_translate (node->expr,
                                                  ANTIC_IN (block),
@@ -1688,7 +1706,8 @@ create_value_expr_from (tree expr, basic_block block, vuse_optype vuses)
          tree val = vn_lookup_or_add (op, vuses);
          if (!is_undefined_value (op))
            value_insert_into_set (EXP_GEN (block), op);
-         TREE_TYPE (val) = TREE_TYPE (TREE_OPERAND (vexpr, i));
+         if (TREE_CODE (val) == VALUE_HANDLE)
+           TREE_TYPE (val) = TREE_TYPE (TREE_OPERAND (vexpr, i));
          TREE_OPERAND (vexpr, i) = val;
        }
     }
@@ -1882,6 +1901,16 @@ eliminate (void)
                  pre_stats.eliminations++;
                  propagate_tree_value (rhs_p, sprime);
                  modify_stmt (stmt);
+
+                 /* If we removed EH side effects from the statement, clean
+                    its EH information.  */
+                 if (maybe_clean_eh_stmt (stmt))
+                   {
+                     bitmap_set_bit (need_eh_cleanup,
+                                     bb_for_stmt (stmt)->index);
+                     if (dump_file && (dump_flags & TDF_DETAILS))
+                       fprintf (dump_file, "  Removed EH side effects.\n");
+                   }
                }
            }
         }
@@ -1900,6 +1929,18 @@ init_pre (void)
   connect_infinite_loops_to_exit ();
   vn_init ();
   memset (&pre_stats, 0, sizeof (pre_stats));
+
+  /* If block 0 has more than one predecessor, it means that its PHI
+     nodes will have arguments coming from block -1.  This creates
+     problems for several places in PRE that keep local arrays indexed
+     by block number.  To prevent this, we split the edge coming from
+     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);
+
   FOR_ALL_BB (bb)
     bb->aux = xcalloc (1, sizeof (struct bb_value_sets));
 
@@ -1917,7 +1958,8 @@ init_pre (void)
   binary_node_pool = create_alloc_pool ("Binary tree nodes", tsize, 30);
   tsize = tree_size (build1 (NEGATE_EXPR, void_type_node, NULL_TREE));
   unary_node_pool = create_alloc_pool ("Unary tree nodes", tsize, 30);
-  tsize = tree_size (build (COMPONENT_REF, void_type_node, NULL_TREE, NULL_TREE, NULL_TREE));
+  tsize = tree_size (build (COMPONENT_REF, void_type_node, NULL_TREE,
+                           NULL_TREE, NULL_TREE));
   reference_node_pool = create_alloc_pool ("Reference tree nodes", tsize, 30);
   FOR_ALL_BB (bb)
     {
@@ -1926,6 +1968,8 @@ init_pre (void)
       TMP_GEN (bb) = bitmap_set_new ();
       AVAIL_OUT (bb) = bitmap_set_new ();
     }
+
+  need_eh_cleanup = BITMAP_XMALLOC ();
 }
 
 
@@ -1953,6 +1997,14 @@ fini_pre (void)
 
   free_dominance_info (CDI_POST_DOMINATORS);
   vn_delete ();
+
+  if (bitmap_first_set_bit (need_eh_cleanup) >= 0)
+    {
+      tree_purge_all_dead_eh_edges (need_eh_cleanup);
+      cleanup_tree_cfg ();
+    }
+
+  BITMAP_XFREE (need_eh_cleanup);
 }
 
 
@@ -2030,7 +2082,8 @@ struct tree_opt_pass pass_pre =
   NULL,                                        /* next */
   0,                                   /* static_pass_number */
   TV_TREE_PRE,                         /* tv_id */
-  PROP_no_crit_edges | PROP_cfg | PROP_ssa,/* properties_required */
+  PROP_no_crit_edges | PROP_cfg
+    | PROP_ssa | PROP_alias,           /* properties_required */
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
@@ -2061,7 +2114,7 @@ struct tree_opt_pass pass_fre =
   NULL,                                        /* next */
   0,                                   /* static_pass_number */
   TV_TREE_FRE,                         /* tv_id */
-  PROP_no_crit_edges | PROP_cfg | PROP_ssa,/* properties_required */
+  PROP_cfg | PROP_ssa | PROP_alias,    /* properties_required */
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */