diff mbox

[match-and-simplify] Sort IVOPTs iv_uses after dominator

Message ID alpine.LSU.2.11.1408261453080.20733@zhemvz.fhfr.qr
State New
Headers show

Commit Message

Richard Biener Aug. 26, 2014, 12:57 p.m. UTC
The following is needed to allow building libada if the conversion
simplifications go in.  Currently IVOPTs replaces IV uses in
arbitrary order which can result in intermediate code that
still refers to IVs that are going to be removed.  As it folds
replacement statements via force_gimple_operand (which eventually
folds all generated statements) the match-and-simplify process
can still reach those IVs via SSA name definitions (that are
eventually replaced later).

The IVOPTs machinery removing unused IVs certainly doesn't expect
that to happen.

One option is to remove that "DCE", another is to make sure
we don't reach un-replaced USEs when processing other uses
which is what the patch below tries by sorting the iv_use
vector after dominators (and stmt uids).

Bootstrap and regtest in progress on x86_64-unknown-linux-gnu.

I hope we don't run into too many other similar cases...

Thanks,
Richard.

2014-08-26  Richard Biener  <rguenther@suse.de>

	* tree-ssa-loop-ivopts.c (ivuse_cmp): New function.
	(rewrite_uses): Sort the vector of iv_uses after dominator order.
diff mbox

Patch

Index: gcc/tree-ssa-loop-ivopts.c
===================================================================
--- gcc/tree-ssa-loop-ivopts.c	(revision 214500)
+++ gcc/tree-ssa-loop-ivopts.c	(working copy)
@@ -6526,6 +6526,30 @@  rewrite_use (struct ivopts_data *data, s
   update_stmt (use->stmt);
 }
 
+/* Compare routine for sorting the vector of iv_uses after dominance.  */
+
+static int
+ivuse_cmp (const void *a, const void *b)
+{
+  const struct iv_use *usea = *((const struct iv_use * const *)a);
+  const struct iv_use *useb = *((const struct iv_use * const *)b);
+  basic_block bba = gimple_bb (usea->stmt);
+  basic_block bbb = gimple_bb (useb->stmt);
+  if (bba == bbb)
+    {
+      if (usea->stmt == useb->stmt)
+	return 0;
+      if (gimple_uid (usea->stmt) > gimple_uid (useb->stmt))
+	return 1;
+      else
+	return -1;
+    }
+  else if (dominated_by_p (CDI_DOMINATORS, bba, bbb))
+    return 1;
+  else
+    return -1;
+}
+
 /* Rewrite the uses using the selected induction variables.  */
 
 static void
@@ -6535,6 +6559,9 @@  rewrite_uses (struct ivopts_data *data)
   struct iv_cand *cand;
   struct iv_use *use;
 
+  /* Sort uses so that dominating uses are processed first.  */
+  data->iv_uses.qsort (ivuse_cmp);
+
   for (i = 0; i < n_iv_uses (data); i++)
     {
       use = iv_use (data, i);