OSDN Git Service

PR tree-optimization/52255
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 16 Feb 2012 10:20:26 +0000 (10:20 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 16 Feb 2012 10:20:26 +0000 (10:20 +0000)
* tree-vect-loop-manip.c (slpeel_tree_peel_loop_to_edge): If
loop->header has virtual PHI, but exit_e->dest doesn't, add
virtual PHI to exit_e->dest and adjust all uses after the loop.

* gcc.c-torture/compile/pr52255.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@184306 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/pr52255.c [new file with mode: 0644]
gcc/tree-vect-loop-manip.c

index 82139ff..e8b5efa 100644 (file)
@@ -1,5 +1,10 @@
 2012-02-16  Jakub Jelinek  <jakub@redhat.com>
 
+       PR tree-optimization/52255
+       * tree-vect-loop-manip.c (slpeel_tree_peel_loop_to_edge): If
+       loop->header has virtual PHI, but exit_e->dest doesn't, add
+       virtual PHI to exit_e->dest and adjust all uses after the loop.
+
        PR debug/52260
        * dwarf2out.c (copy_decls_walk): Fill in *slot before traversing
        children with clone_tree_hash, not after it.
index ae98f1e..76f2bb6 100644 (file)
@@ -1,5 +1,8 @@
 2012-02-16  Jakub Jelinek  <jakub@redhat.com>
 
+       PR tree-optimization/52255
+       * gcc.c-torture/compile/pr52255.c: New test.
+
        PR debug/52260
        * g++.dg/debug/dwarf2/pr52260.C: New test.
 
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr52255.c b/gcc/testsuite/gcc.c-torture/compile/pr52255.c
new file mode 100644 (file)
index 0000000..e68ae37
--- /dev/null
@@ -0,0 +1,12 @@
+/* PR tree-optimization/52255 */
+
+int a, b, c[10], d[10] = { 0, 0 };
+
+void
+foo (void)
+{
+  for (a = 1; a <= 4; a += 1)
+    d[a] = d[1];
+  for (; b; ++b)
+    c[0] |= 1;
+}
index 7ac3f67..70c4f89 100644 (file)
@@ -513,7 +513,7 @@ slpeel_update_phi_nodes_for_guard1 (edge guard_edge, struct loop *loop,
        !gsi_end_p (gsi_orig) && !gsi_end_p (gsi_update);
        gsi_next (&gsi_orig), gsi_next (&gsi_update))
     {
-      source_location loop_locus, guard_locus;;
+      source_location loop_locus, guard_locus;
       orig_phi = gsi_stmt (gsi_orig);
       update_phi = gsi_stmt (gsi_update);
 
@@ -1171,6 +1171,7 @@ slpeel_tree_peel_loop_to_edge (struct loop *loop,
   basic_block bb_before_first_loop;
   basic_block bb_between_loops;
   basic_block new_exit_bb;
+  gimple_stmt_iterator gsi;
   edge exit_e = single_exit (loop);
   LOC loop_loc;
   tree cost_pre_condition = NULL_TREE;
@@ -1184,6 +1185,40 @@ slpeel_tree_peel_loop_to_edge (struct loop *loop,
    the function tree_duplicate_bb is called.  */
   gimple_register_cfg_hooks ();
 
+  /* If the loop has a virtual PHI, but exit bb doesn't, create a virtual PHI
+     in the exit bb and rename all the uses after the loop.  This simplifies
+     the *guard[12] routines, which assume loop closed SSA form for all PHIs
+     (but normally loop closed SSA form doesn't require virtual PHIs to be
+     in the same form).  Doing this early simplifies the checking what
+     uses should be renamed.  */
+  for (gsi = gsi_start_phis (loop->header); !gsi_end_p (gsi); gsi_next (&gsi))
+    if (!is_gimple_reg (gimple_phi_result (gsi_stmt (gsi))))
+      {
+       gimple phi = gsi_stmt (gsi);
+       for (gsi = gsi_start_phis (exit_e->dest);
+            !gsi_end_p (gsi); gsi_next (&gsi))
+         if (!is_gimple_reg (gimple_phi_result (gsi_stmt (gsi))))
+           break;
+       if (gsi_end_p (gsi))
+         {
+           gimple new_phi = create_phi_node (SSA_NAME_VAR (PHI_RESULT (phi)),
+                                             exit_e->dest);
+           tree vop = PHI_ARG_DEF_FROM_EDGE (phi, EDGE_SUCC (loop->latch, 0));
+           imm_use_iterator imm_iter;
+           gimple stmt;
+           tree new_vop = make_ssa_name (SSA_NAME_VAR (PHI_RESULT (phi)),
+                                         new_phi);
+           use_operand_p use_p;
+
+           add_phi_arg (new_phi, vop, exit_e, UNKNOWN_LOCATION);
+           gimple_phi_set_result (new_phi, new_vop);
+           FOR_EACH_IMM_USE_STMT (stmt, imm_iter, vop)
+             if (stmt != new_phi && gimple_bb (stmt) != loop->header)
+               FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
+                 SET_USE (use_p, new_vop);
+         }
+       break;
+      }
 
   /* 1. Generate a copy of LOOP and put it on E (E is the entry/exit of LOOP).
         Resulting CFG would be: