OSDN Git Service

PR target/11327
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-dom.c
index def20d6..67446b1 100644 (file)
@@ -550,6 +550,16 @@ thread_across_edge (struct dom_walk_data *walk_data, edge e)
     {
       tree src = PHI_ARG_DEF_FROM_EDGE (phi, e);
       tree dst = PHI_RESULT (phi);
+
+      /* If the desired argument is not the same as this PHI's result 
+        and it is set by a PHI in this block, then we can not thread
+        through this block.  */
+      if (src != dst
+         && TREE_CODE (src) == SSA_NAME
+         && TREE_CODE (SSA_NAME_DEF_STMT (src)) == PHI_NODE
+         && bb_for_stmt (SSA_NAME_DEF_STMT (src)) == e->dest)
+       return;
+
       record_const_or_copy (dst, src);
       register_new_def (dst, &block_defs_stack);
     }
@@ -676,22 +686,6 @@ thread_across_edge (struct dom_walk_data *walk_data, edge e)
          || TREE_CODE (stmt) == SWITCH_EXPR))
     {
       tree cond, cached_lhs;
-      edge e1;
-      edge_iterator ei;
-
-      /* Do not forward entry edges into the loop.  In the case loop
-        has multiple entry edges we may end up in constructing irreducible
-        region.  
-        ??? We may consider forwarding the edges in the case all incoming
-        edges forward to the same destination block.  */
-      if (!e->flags & EDGE_DFS_BACK)
-       {
-         FOR_EACH_EDGE (e1, ei, e->dest->preds)
-           if (e1->flags & EDGE_DFS_BACK)
-             break;
-         if (e1)
-           return;
-       }
 
       /* Now temporarily cprop the operands and try to find the resulting
         expression in the hash tables.  */
@@ -1177,7 +1171,9 @@ record_equivalences_from_phis (basic_block bb)
        {
          tree t = PHI_ARG_DEF (phi, i);
 
-         /* Ignore alternatives which are the same as our LHS.  */
+         /* Ignore alternatives which are the same as our LHS.  Since
+            LHS is a PHI_RESULT, it is known to be a SSA_NAME, so we
+            can simply compare pointers.  */
          if (lhs == t)
            continue;
 
@@ -2451,9 +2447,9 @@ record_edge_info (basic_block bb)
                    }
                }
 
-             if (is_gimple_min_invariant (op0)
-                 && (TREE_CODE (op1) == SSA_NAME
-                      || is_gimple_min_invariant (op1)))
+             else if (is_gimple_min_invariant (op0)
+                      && (TREE_CODE (op1) == SSA_NAME
+                          || is_gimple_min_invariant (op1)))
                {
                  tree inverted = invert_truthvalue (cond);
                  struct edge_info *edge_info;
@@ -2477,9 +2473,9 @@ record_edge_info (basic_block bb)
                    }
                }
 
-             if (TREE_CODE (op0) == SSA_NAME
-                 && (is_gimple_min_invariant (op1)
-                     || TREE_CODE (op1) == SSA_NAME))
+             else if (TREE_CODE (op0) == SSA_NAME
+                      && (is_gimple_min_invariant (op1)
+                          || TREE_CODE (op1) == SSA_NAME))
                {
                  tree inverted = invert_truthvalue (cond);
                  struct edge_info *edge_info;