cfgloop.h (sort_sibling_loops): Declare.
authorRichard Biener <rguenther@suse.de>
Mon, 25 Sep 2017 13:19:16 +0000 (13:19 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 25 Sep 2017 13:19:16 +0000 (13:19 +0000)
2017-09-25  Richard Biener  <rguenther@suse.de>

* cfgloop.h (sort_sibling_loops): Declare.
* cfgloop.c (sort_sibling_loops_cmp): New helper.
(sort_sibling_loops): New function sorting the sibling loop list
in RPO order.
* graphite.c (graphite_transform_loops): Sort sibling loops.

From-SVN: r253149

gcc/ChangeLog
gcc/cfgloop.c
gcc/cfgloop.h
gcc/graphite.c

index b6dd97832f67059a37c5a817307c74704b72e81a..f4060b103bf3353a082e17a16496f2255477dfc7 100644 (file)
@@ -1,3 +1,11 @@
+2017-09-25  Richard Biener  <rguenther@suse.de>
+
+       * cfgloop.h (sort_sibling_loops): Declare.
+       * cfgloop.c (sort_sibling_loops_cmp): New helper.
+       (sort_sibling_loops): New function sorting the sibling loop list
+       in RPO order.
+       * graphite.c (graphite_transform_loops): Sort sibling loops.
+
 2017-09-25  Richard Sandiford  <richard.sandifird@linaro.org>
 
        * target.def (vec_perm_const_ok): Change sel parameter to
index a1e778b85865569f813b28be414bca24ff13cf1c..6911426787b1f470119536c56bf75931f7493444 100644 (file)
@@ -521,6 +521,58 @@ flow_loops_find (struct loops *loops)
   return loops;
 }
 
+/* qsort helper for sort_sibling_loops.  */
+
+static int *sort_sibling_loops_cmp_rpo;
+static int
+sort_sibling_loops_cmp (const void *la_, const void *lb_)
+{
+  const struct loop *la = *(const struct loop * const *)la_;
+  const struct loop *lb = *(const struct loop * const *)lb_;
+  return (sort_sibling_loops_cmp_rpo[la->header->index]
+         - sort_sibling_loops_cmp_rpo[lb->header->index]);
+}
+
+/* Sort sibling loops in RPO order.  */
+
+void
+sort_sibling_loops (function *fn)
+{
+  /* Match flow_loops_find in the order we sort sibling loops.  */
+  sort_sibling_loops_cmp_rpo = XNEWVEC (int, last_basic_block_for_fn (cfun));
+  int *rc_order = XNEWVEC (int, n_basic_blocks_for_fn (cfun));
+  pre_and_rev_post_order_compute_fn (fn, NULL, rc_order, false);
+  for (int i = 0; i < n_basic_blocks_for_fn (cfun) - NUM_FIXED_BLOCKS; ++i)
+    sort_sibling_loops_cmp_rpo[rc_order[i]] = i;
+  free (rc_order);
+
+  auto_vec<loop_p, 3> siblings;
+  loop_p loop;
+  FOR_EACH_LOOP_FN (fn, loop, LI_INCLUDE_ROOT)
+    if (loop->inner && loop->inner->next)
+      {
+       loop_p sibling = loop->inner;
+       do
+         {
+           siblings.safe_push (sibling);
+           sibling = sibling->next;
+         }
+       while (sibling);
+       siblings.qsort (sort_sibling_loops_cmp);
+       loop_p *siblingp = &loop->inner;
+       for (unsigned i = 0; i < siblings.length (); ++i)
+         {
+           *siblingp = siblings[i];
+           siblingp = &(*siblingp)->next;
+         }
+       *siblingp = NULL;
+       siblings.truncate (0);
+      }
+
+  free (sort_sibling_loops_cmp_rpo);
+  sort_sibling_loops_cmp_rpo = NULL;
+}
+
 /* Ratio of frequencies of edges so that one of more latch edges is
    considered to belong to inner loop with same header.  */
 #define HEAVY_EDGE_RATIO 8
index fcf366745dfdf2dacaa83459d90853a14248ff0f..0b164e97b1f08e8689cfff9fde2cea274b2eb754 100644 (file)
@@ -333,6 +333,7 @@ bool mark_irreducible_loops (void);
 void release_recorded_exits (function *);
 void record_loop_exits (void);
 void rescan_loop_exit (edge, bool, bool);
+void sort_sibling_loops (function *);
 
 /* Loop data structure manipulation/querying.  */
 extern void flow_loop_tree_node_add (struct loop *, struct loop *);
index a5a31c2c07446845998cf788cada2bc32e8b751d..7e6ba5078ecc3d7d96947a7d8fd347fd00b87ad2 100644 (file)
@@ -419,6 +419,7 @@ graphite_transform_loops (void)
   isl_options_set_on_error (ctx, ISL_ON_ERROR_ABORT);
   the_isl_ctx = ctx;
 
+  sort_sibling_loops (cfun);
   canonicalize_loop_closed_ssa_form ();
 
   calculate_dominance_info (CDI_POST_DOMINATORS);