Add missing phis in expand_omp_for_generic
authorTom de Vries <tom@codesourcery.com>
Mon, 12 Oct 2015 14:14:22 +0000 (14:14 +0000)
committerTom de Vries <vries@gcc.gnu.org>
Mon, 12 Oct 2015 14:14:22 +0000 (14:14 +0000)
2015-10-12  Tom de Vries  <tom@codesourcery.com>

PR tree-optimization/67476
* omp-low.c (expand_omp_for_generic): Add missing phis.

From-SVN: r228718

gcc/ChangeLog
gcc/omp-low.c

index 97f4a0d7b2d26c2a74433f3472c6a4c4ef74d2ec..c34e0840c58ace39c3755dc61e62360f42496ac9 100644 (file)
@@ -1,3 +1,8 @@
+2015-10-12  Tom de Vries  <tom@codesourcery.com>
+
+       PR tree-optimization/67476
+       * omp-low.c (expand_omp_for_generic): Add missing phis.
+
 2015-10-12  Tom de Vries  <tom@codesourcery.com>
 
        PR tree-optimization/67476
index f59a6a436f02dae5fc8ea6f028cbc018e7e91cf4..b2a93b99c7eb2bbd5527c69d43355cca31bbee00 100644 (file)
@@ -238,6 +238,7 @@ static vec<omp_context *> taskreg_contexts;
 
 static void scan_omp (gimple_seq *, omp_context *);
 static tree scan_omp_1_op (tree *, int *, void *);
+static gphi *find_phi_with_arg_on_edge (tree, edge);
 
 #define WALK_SUBSTMTS  \
     case GIMPLE_BIND: \
@@ -6469,6 +6470,43 @@ expand_omp_for_generic (struct omp_region *region,
        }
       make_edge (l2_bb, l0_bb, EDGE_TRUE_VALUE);
 
+      if (gimple_in_ssa_p (cfun))
+       {
+         /* Add phis to the outer loop that connect to the phis in the inner,
+            original loop, and move the loop entry value of the inner phi to
+            the loop entry value of the outer phi.  */
+         gphi_iterator psi;
+         for (psi = gsi_start_phis (l3_bb); !gsi_end_p (psi); gsi_next (&psi))
+           {
+             source_location locus;
+             gphi *nphi;
+             gphi *exit_phi = psi.phi ();
+
+             edge l2_to_l3 = find_edge (l2_bb, l3_bb);
+             tree exit_res = PHI_ARG_DEF_FROM_EDGE (exit_phi, l2_to_l3);
+
+             basic_block latch = BRANCH_EDGE (cont_bb)->dest;
+             edge latch_to_l1 = find_edge (latch, l1_bb);
+             gphi *inner_phi
+               = find_phi_with_arg_on_edge (exit_res, latch_to_l1);
+
+             tree t = gimple_phi_result (exit_phi);
+             tree new_res = copy_ssa_name (t, NULL);
+             nphi = create_phi_node (new_res, l0_bb);
+
+             edge l0_to_l1 = find_edge (l0_bb, l1_bb);
+             t = PHI_ARG_DEF_FROM_EDGE (inner_phi, l0_to_l1);
+             locus = gimple_phi_arg_location_from_edge (inner_phi, l0_to_l1);
+             edge entry_to_l0 = find_edge (entry_bb, l0_bb);
+             add_phi_arg (nphi, t, entry_to_l0, locus);
+
+             edge l2_to_l0 = find_edge (l2_bb, l0_bb);
+             add_phi_arg (nphi, exit_res, l2_to_l0, UNKNOWN_LOCATION);
+
+             add_phi_arg (inner_phi, new_res, l0_to_l1, UNKNOWN_LOCATION);
+           };
+       }
+
       set_immediate_dominator (CDI_DOMINATORS, l2_bb,
                               recompute_dominator (CDI_DOMINATORS, l2_bb));
       set_immediate_dominator (CDI_DOMINATORS, l3_bb,