re PR tree-optimization/80213 (ICE in check_loop_closed_ssa_use, at tree-ssa-loop...
authorRichard Biener <rguenther@suse.de>
Wed, 20 Sep 2017 12:08:16 +0000 (12:08 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 20 Sep 2017 12:08:16 +0000 (12:08 +0000)
2017-09-20  Richard Biener  <rguenther@suse.de>

PR tree-optimization/80213
* graphite-scop-detection.c (trivially_empty_bb_p): Labels
are allowed in empty BBs as well.
(canonicalize_loop_closed_ssa): Also look for other complex
edges.
(scop_detection::get_sese): Include the loop-closed PHI block
in loop SESEs.
(scop_detection::merge_sese): Remove code adding extra blocks.
(scop_detection::region_has_one_loop): Adjust for get_sese changes.
(build_scops): Assert the final returned scop is invalid.

From-SVN: r253008

gcc/ChangeLog
gcc/graphite-scop-detection.c

index 15b1095..3ee9ea1 100644 (file)
@@ -1,5 +1,18 @@
 2017-09-20  Richard Biener  <rguenther@suse.de>
 
+       PR tree-optimization/80213
+       * graphite-scop-detection.c (trivially_empty_bb_p): Labels
+       are allowed in empty BBs as well.
+       (canonicalize_loop_closed_ssa): Also look for other complex
+       edges.
+       (scop_detection::get_sese): Include the loop-closed PHI block
+       in loop SESEs.
+       (scop_detection::merge_sese): Remove code adding extra blocks.
+       (scop_detection::region_has_one_loop): Adjust for get_sese changes.
+       (build_scops): Assert the final returned scop is invalid.
+
+2017-09-20  Richard Biener  <rguenther@suse.de>
+
        PR tree-optimization/82264
        * tree-ssa-sccvn.c (vn_phi_eq): Use safe_dyn_cast to check
        for GIMPLE_CONDs.
index 6fe375e..68e86ec 100644 (file)
@@ -261,7 +261,8 @@ trivially_empty_bb_p (basic_block bb)
   gimple_stmt_iterator gsi;
 
   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
-    if (gimple_code (gsi_stmt (gsi)) != GIMPLE_DEBUG)
+    if (gimple_code (gsi_stmt (gsi)) != GIMPLE_DEBUG
+       && gimple_code (gsi_stmt (gsi)) != GIMPLE_LABEL)
       return false;
 
   return true;
@@ -355,7 +356,7 @@ canonicalize_loop_closed_ssa (loop_p loop)
   edge e = single_exit (loop);
   basic_block bb;
 
-  if (!e || e->flags & EDGE_ABNORMAL)
+  if (!e || (e->flags & EDGE_COMPLEX))
     return;
 
   bb = e->dest;
@@ -674,14 +675,19 @@ scop_detection::get_sese (loop_p loop)
   if (!loop)
     return invalid_sese;
 
-  if (!loops_state_satisfies_p (LOOPS_HAVE_PREHEADERS))
-    return invalid_sese;
+  edge scop_begin = loop_preheader_edge (loop);
   edge scop_end = single_exit (loop);
-  if (!scop_end)
+  if (!scop_end || (scop_end->flags & EDGE_COMPLEX))
     return invalid_sese;
-  edge scop_begin = loop_preheader_edge (loop);
-  sese_l s (scop_begin, scop_end);
-  return s;
+  /* Include the BB with the loop-closed SSA PHI nodes.
+     canonicalize_loop_closed_ssa makes sure that is in proper shape.  */
+  if (! single_pred_p (scop_end->dest)
+      || ! single_succ_p (scop_end->dest)
+      || ! trivially_empty_bb_p (scop_end->dest))
+    gcc_unreachable ();
+  scop_end = single_succ_edge (scop_end->dest);
+
+  return sese_l (scop_begin, scop_end);
 }
 
 /* Return the closest dominator with a single entry edge.  */
@@ -848,26 +854,6 @@ scop_detection::merge_sese (sese_l first, sese_l second) const
       return invalid_sese;
     }
 
-  /* FIXME: We should remove this piece of code once
-     canonicalize_loop_closed_ssa has been removed, because that function
-     adds a BB with single exit.  */
-  if (!trivially_empty_bb_p (get_exit_bb (combined)))
-    {
-      /* Find the first empty succ (with single exit) of combined.exit.  */
-      basic_block imm_succ = combined.exit->dest;
-      if (single_succ_p (imm_succ)
-         && single_pred_p (imm_succ)
-         && trivially_empty_bb_p (imm_succ))
-       combined.exit = single_succ_edge (imm_succ);
-      else
-       {
-         DEBUG_PRINT (dp << "[scop-detection-fail] Discarding SCoP because "
-                         << "no single exit (empty succ) for sese exit";
-                      print_sese (dump_file, combined));
-         return invalid_sese;
-       }
-    }
-
   /* Analyze all the BBs in new sese.  */
   if (harmful_loop_in_region (combined))
     return invalid_sese;
@@ -1027,7 +1013,8 @@ scop_detection::region_has_one_loop (sese_l s)
     return false;
 
   /* Otherwise, check whether we have adjacent loops.  */
-  return begin->dest->loop_father == end->src->loop_father;
+  return (single_pred_p (end->src)
+         && begin->dest->loop_father == single_pred (end->src)->loop_father);
 }
 
 /* Add to SCOPS a scop starting at SCOP_BEGIN and ending at SCOP_END.  */
@@ -2053,8 +2040,12 @@ build_scops (vec<scop_p> *scops)
 
   canonicalize_loop_closed_ssa_form ();
 
+  /* ???  We walk the loop tree assuming loop->next is ordered.
+     This is not so but we'd be free to order it here.  */
   scop_detection sb;
-  sb.build_scop_depth (scop_detection::invalid_sese, current_loops->tree_root);
+  sese_l tem = sb.build_scop_depth (scop_detection::invalid_sese,
+                                   current_loops->tree_root);
+  gcc_assert (! tem);
 
   /* Now create scops from the lightweight SESEs.  */
   vec<sese_l> scops_l = sb.get_scops ();