[GCC8,19/33] Rewrite nonlinear iv_use by re-associating invariant and induction parts separately

Submitted by Bin Cheng on April 18, 2017, 10:47 a.m.

Details

Message ID VI1PR0802MB217626C633E783C0F11C2C8CE7190@VI1PR0802MB2176.eurprd08.prod.outlook.com
State New
Headers show

Commit Message

Bin Cheng April 18, 2017, 10:47 a.m.
Hi,
This patch rewrites nonlinear iv_use by re-associating invariant part and
induction part separately so that invariant expressions are exposed to
later lim pass.
Is it OK?

Thanks,
bin
2017-04-11  Bin Cheng  <bin.cheng@arm.com>

	* tree-ssa-loop-ivopts.c (rewrite_use_nonlinear_expr): Re-associate
	nonlinear iv_use computation in loop invariant sensitive way.
From 12aaf8c773f6215205ddadd182d162fa68195198 Mon Sep 17 00:00:00 2001
From: Bin Cheng <binche01@e108451-lin.cambridge.arm.com>
Date: Wed, 1 Mar 2017 16:22:13 +0000
Subject: [PATCH 19/33] nonlinear-iv_use-rewrite-20170220.txt

---
 gcc/tree-ssa-loop-ivopts.c | 52 +++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 45 insertions(+), 7 deletions(-)

Comments

Richard Guenther April 26, 2017, 1:14 p.m.
On Tue, Apr 18, 2017 at 12:47 PM, Bin Cheng <Bin.Cheng@arm.com> wrote:
> Hi,
> This patch rewrites nonlinear iv_use by re-associating invariant part and
> induction part separately so that invariant expressions are exposed to
> later lim pass.
> Is it OK?

Ok.

Thanks,
Richard.

> Thanks,
> bin
> 2017-04-11  Bin Cheng  <bin.cheng@arm.com>
>
>         * tree-ssa-loop-ivopts.c (rewrite_use_nonlinear_expr): Re-associate
>         nonlinear iv_use computation in loop invariant sensitive way.

Patch hide | download patch | download mbox

diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
index 0f78a46..6e9df43 100644
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -6659,10 +6659,9 @@  static void
 rewrite_use_nonlinear_expr (struct ivopts_data *data,
 			    struct iv_use *use, struct iv_cand *cand)
 {
-  tree comp;
-  tree tgt;
   gassign *ass;
   gimple_stmt_iterator bsi;
+  tree comp, type = get_use_type (use), tgt;
 
   /* An important special case -- if we are asked to express value of
      the original iv by itself, just exit; there is no need to
@@ -6706,9 +6705,6 @@  rewrite_use_nonlinear_expr (struct ivopts_data *data,
 	}
     }
 
-  comp = get_computation_at (data->current_loop, use->stmt, use, cand);
-  gcc_assert (comp != NULL_TREE);
-
   switch (gimple_code (use->stmt))
     {
     case GIMPLE_PHI:
@@ -6730,6 +6726,47 @@  rewrite_use_nonlinear_expr (struct ivopts_data *data,
       gcc_unreachable ();
     }
 
+  aff_tree aff_inv, aff_var;
+  if (!get_computation_aff_1 (data->current_loop, use->stmt,
+			      use, cand, &aff_inv, &aff_var))
+    gcc_unreachable ();
+
+  unshare_aff_combination (&aff_inv);
+  unshare_aff_combination (&aff_var);
+  /* Prefer CSE opportunity than loop invariantby adding offset at last
+     so that iv_uses only have different offsets can be CSEed.  */
+  widest_int offset = aff_inv.offset;
+  aff_inv.offset = 0;
+
+  gimple_seq stmt_list = NULL, seq = NULL;
+  tree comp_op1 = aff_combination_to_tree (&aff_inv);
+  tree comp_op2 = aff_combination_to_tree (&aff_var);
+  gcc_assert (comp_op1 && comp_op2);
+
+  comp_op1 = force_gimple_operand (comp_op1, &seq, true, NULL);
+  gimple_seq_add_seq (&stmt_list, seq);
+  comp_op2 = force_gimple_operand (comp_op2, &seq, true, NULL);
+  gimple_seq_add_seq (&stmt_list, seq);
+
+  if (POINTER_TYPE_P (TREE_TYPE (comp_op2)))
+    std::swap (comp_op1, comp_op2);
+
+  if (POINTER_TYPE_P (TREE_TYPE (comp_op1)))
+    {
+      comp = fold_build_pointer_plus (comp_op1,
+				      fold_convert (sizetype, comp_op2));
+      comp = fold_build_pointer_plus (comp,
+				      wide_int_to_tree (sizetype, offset));
+    }
+  else
+    {
+      comp = fold_build2 (PLUS_EXPR, TREE_TYPE (comp_op1), comp_op1,
+			  fold_convert (TREE_TYPE (comp_op1), comp_op2));
+      comp = fold_build2 (PLUS_EXPR, TREE_TYPE (comp_op1), comp,
+			  wide_int_to_tree (TREE_TYPE (comp_op1), offset));
+    }
+
+  comp = fold_convert (type, comp);
   if (!valid_gimple_rhs_p (comp)
       || (gimple_code (use->stmt) != GIMPLE_PHI
 	  /* We can't allow re-allocating the stmt as it might be pointed
@@ -6737,8 +6774,8 @@  rewrite_use_nonlinear_expr (struct ivopts_data *data,
 	  && (get_gimple_rhs_num_ops (TREE_CODE (comp))
 	      >= gimple_num_ops (gsi_stmt (bsi)))))
     {
-      comp = force_gimple_operand_gsi (&bsi, comp, true, NULL_TREE,
-				       true, GSI_SAME_STMT);
+      comp = force_gimple_operand (comp, &seq, true, NULL);
+      gimple_seq_add_seq (&stmt_list, seq);
       if (POINTER_TYPE_P (TREE_TYPE (tgt)))
 	{
 	  duplicate_ssa_name_ptr_info (comp, SSA_NAME_PTR_INFO (tgt));
@@ -6749,6 +6786,7 @@  rewrite_use_nonlinear_expr (struct ivopts_data *data,
 	}
     }
 
+  gsi_insert_seq_before (&bsi, stmt_list, GSI_SAME_STMT);
   if (gimple_code (use->stmt) == GIMPLE_PHI)
     {
       ass = gimple_build_assign (tgt, comp);