re PR tree-optimization/71170 (ICE in rewrite_expr_tree, at tree-ssa-reassoc.c:3898)
authorKugan Vivekanandarajah <kuganv@linaro.org>
Tue, 24 May 2016 00:14:13 +0000 (00:14 +0000)
committerKugan Vivekanandarajah <kugan@gcc.gnu.org>
Tue, 24 May 2016 00:14:13 +0000 (00:14 +0000)
gcc/ChangeLog:

2016-05-24  Kugan Vivekanandarajah  <kuganv@linaro.org>

PR middle-end/71170
* tree-ssa-reassoc.c (struct operand_entry): Add field stmt_to_insert.
(add_to_ops_vec): Add stmt_to_insert.
(add_repeat_to_ops_vec): Init stmt_to_insert.
(insert_stmt_before_use): New.
(transform_add_to_multiply): Remove mult_stmt insertion and add it to ops vector.
(get_ops): Init stmt_to_insert.
(maybe_optimize_range_tests): Likewise.
(rewrite_expr_tree): Insert stmt_to_insert before use stmt.
(rewrite_expr_tree_parallel): Likewise.
(reassociate_bb): Likewise.

From-SVN: r236619

gcc/ChangeLog
gcc/tree-ssa-reassoc.c

index 4fd5899ddc5ddb7216510e4dddae0fae8b4f5fef..d4d12b140526b6d79ce3cf3e16ba1be44409c7f3 100644 (file)
@@ -1,3 +1,17 @@
+2016-05-24  Kugan Vivekanandarajah  <kuganv@linaro.org>
+
+       PR middle-end/71170
+       * tree-ssa-reassoc.c (struct operand_entry): Add field stmt_to_insert.
+       (add_to_ops_vec): Add stmt_to_insert.
+       (add_repeat_to_ops_vec): Init stmt_to_insert.
+       (insert_stmt_before_use): New.
+       (transform_add_to_multiply): Remove mult_stmt insertion and add it to ops vector.
+       (get_ops): Init stmt_to_insert.
+       (maybe_optimize_range_tests): Likewise.
+       (rewrite_expr_tree): Insert stmt_to_insert before use stmt.
+       (rewrite_expr_tree_parallel): Likewise.
+       (reassociate_bb): Likewise.
+
 2016-05-23  Michael Meissner  <meissner@linux.vnet.ibm.com>
 
        PR target/71201
index 596920f5197ab20663e8bb7c50698352e78c1fec..fb683adc9cc139f883a1c4228295934d0db2e096 100644 (file)
@@ -195,6 +195,7 @@ struct operand_entry
   int id;
   tree op;
   unsigned int count;
+  gimple *stmt_to_insert;
 };
 
 static object_allocator<operand_entry> operand_entry_pool
@@ -553,7 +554,7 @@ sort_by_operand_rank (const void *pa, const void *pb)
 /* Add an operand entry to *OPS for the tree operand OP.  */
 
 static void
-add_to_ops_vec (vec<operand_entry *> *ops, tree op)
+add_to_ops_vec (vec<operand_entry *> *ops, tree op, gimple *stmt_to_insert = NULL)
 {
   operand_entry *oe = operand_entry_pool.allocate ();
 
@@ -561,6 +562,7 @@ add_to_ops_vec (vec<operand_entry *> *ops, tree op)
   oe->rank = get_rank (op);
   oe->id = next_operand_entry_id++;
   oe->count = 1;
+  oe->stmt_to_insert = stmt_to_insert;
   ops->safe_push (oe);
 }
 
@@ -577,6 +579,7 @@ add_repeat_to_ops_vec (vec<operand_entry *> *ops, tree op,
   oe->rank = get_rank (op);
   oe->id = next_operand_entry_id++;
   oe->count = repeat;
+  oe->stmt_to_insert = NULL;
   ops->safe_push (oe);
 
   reassociate_stats.pows_encountered++;
@@ -1756,10 +1759,21 @@ eliminate_redundant_comparison (enum tree_code opcode,
   return false;
 }
 
+/* If the stmt that defines operand has to be inserted, insert it
+   before the use.  */
+static void
+insert_stmt_before_use (gimple *stmt, gimple *stmt_to_insert)
+{
+  gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
+  gimple_set_uid (stmt_to_insert, gimple_uid (stmt));
+  gsi_insert_before (&gsi, stmt_to_insert, GSI_NEW_STMT);
+}
+
+
 /* Transform repeated addition of same values into multiply with
    constant.  */
 static bool
-transform_add_to_multiply (gimple *stmt, vec<operand_entry *> *ops)
+transform_add_to_multiply (vec<operand_entry *> *ops)
 {
   operand_entry *oe;
   tree op = NULL_TREE;
@@ -1811,21 +1825,11 @@ transform_add_to_multiply (gimple *stmt, vec<operand_entry *> *ops)
        ops->unordered_remove (i);
       tree tmp = make_ssa_name (TREE_TYPE (op));
       tree cst = build_int_cst (integer_type_node, count);
-      gimple *def_stmt = SSA_NAME_DEF_STMT (op);
       gassign *mul_stmt
        = gimple_build_assign (tmp, MULT_EXPR,
                               op, fold_convert (TREE_TYPE (op), cst));
-      if (gimple_code (def_stmt) == GIMPLE_NOP
-         || gimple_bb (stmt) != gimple_bb (def_stmt))
-       {
-         gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
-         gimple_set_uid (mul_stmt, gimple_uid (stmt));
-         gsi_insert_before (&gsi, mul_stmt, GSI_NEW_STMT);
-       }
-      else
-       insert_stmt_after (mul_stmt, def_stmt);
       gimple_set_visited (mul_stmt, true);
-      add_to_ops_vec (ops, tmp);
+      add_to_ops_vec (ops, tmp, mul_stmt);
       changed = true;
     }
 
@@ -3225,6 +3229,7 @@ get_ops (tree var, enum tree_code code, vec<operand_entry *> *ops,
        oe->rank = code;
        oe->id = 0;
        oe->count = 1;
+       oe->stmt_to_insert = NULL;
        ops->safe_push (oe);
       }
   return true;
@@ -3465,6 +3470,7 @@ maybe_optimize_range_tests (gimple *stmt)
              oe->rank = code;
              oe->id = 0;
              oe->count = 1;
+             oe->stmt_to_insert = NULL;
              ops.safe_push (oe);
              bb_ent.last_idx++;
            }
@@ -3502,6 +3508,7 @@ maybe_optimize_range_tests (gimple *stmt)
             is.  */
          oe->id = bb->index;
          oe->count = 1;
+         oe->stmt_to_insert = NULL;
          ops.safe_push (oe);
          bb_ent.op = NULL;
          bb_ent.last_idx++;
@@ -3818,6 +3825,12 @@ rewrite_expr_tree (gimple *stmt, unsigned int opindex,
            {
              gimple *insert_point
                = find_insert_point (stmt, oe1->op, oe2->op);
+             /* If the stmt that defines operand has to be inserted, insert it
+                before the use.  */
+             if (oe1->stmt_to_insert)
+               insert_stmt_before_use (stmt, oe1->stmt_to_insert);
+             if (oe2->stmt_to_insert)
+               insert_stmt_before_use (stmt, oe2->stmt_to_insert);
              lhs = make_ssa_name (TREE_TYPE (lhs));
              stmt
                = gimple_build_assign (lhs, gimple_assign_rhs_code (stmt),
@@ -3833,6 +3846,12 @@ rewrite_expr_tree (gimple *stmt, unsigned int opindex,
            {
              gcc_checking_assert (find_insert_point (stmt, oe1->op, oe2->op)
                                   == stmt);
+             /* If the stmt that defines operand has to be inserted, insert it
+                before the use.  */
+             if (oe1->stmt_to_insert)
+               insert_stmt_before_use (stmt, oe1->stmt_to_insert);
+             if (oe2->stmt_to_insert)
+               insert_stmt_before_use (stmt, oe2->stmt_to_insert);
              gimple_assign_set_rhs1 (stmt, oe1->op);
              gimple_assign_set_rhs2 (stmt, oe2->op);
              update_stmt (stmt);
@@ -3856,6 +3875,11 @@ rewrite_expr_tree (gimple *stmt, unsigned int opindex,
   /* Rewrite the next operator.  */
   oe = ops[opindex];
 
+  /* If the stmt that defines operand has to be inserted, insert it
+     before the use.  */
+  if (oe->stmt_to_insert)
+    insert_stmt_before_use (stmt, oe->stmt_to_insert);
+
   /* Recurse on the LHS of the binary operator, which is guaranteed to
      be the non-leaf side.  */
   tree new_rhs1
@@ -4000,6 +4024,7 @@ rewrite_expr_tree_parallel (gassign *stmt, int width,
   int stmt_index = 0;
   int ready_stmts_end = 0;
   int i = 0;
+  gimple *stmt1 = NULL, *stmt2 = NULL;
   tree last_rhs1 = gimple_assign_rhs1 (stmt);
 
   /* We start expression rewriting from the top statements.
@@ -4028,7 +4053,11 @@ rewrite_expr_tree_parallel (gassign *stmt, int width,
          if (ready_stmts_end > stmt_index)
            op2 = gimple_assign_lhs (stmts[stmt_index++]);
          else if (op_index >= 0)
-           op2 = ops[op_index--]->op;
+           {
+             operand_entry *oe = ops[op_index--];
+             stmt2 = oe->stmt_to_insert;
+             op2 = oe->op;
+           }
          else
            {
              gcc_assert (stmt_index < i);
@@ -4042,8 +4071,12 @@ rewrite_expr_tree_parallel (gassign *stmt, int width,
        {
          if (op_index > 1)
            swap_ops_for_binary_stmt (ops, op_index - 2, NULL);
-         op2 = ops[op_index--]->op;
-         op1 = ops[op_index--]->op;
+         operand_entry *oe2 = ops[op_index--];
+         operand_entry *oe1 = ops[op_index--];
+         op2 = oe2->op;
+         stmt2 = oe2->stmt_to_insert;
+         op1 = oe1->op;
+         stmt1 = oe1->stmt_to_insert;
        }
 
       /* If we emit the last statement then we should put
@@ -4058,6 +4091,13 @@ rewrite_expr_tree_parallel (gassign *stmt, int width,
          print_gimple_stmt (dump_file, stmts[i], 0, 0);
        }
 
+      /* If the stmt that defines operand has to be inserted, insert it
+        before the use.  */
+      if (stmt1)
+       insert_stmt_before_use (stmts[i], stmt1);
+      if (stmt2)
+       insert_stmt_before_use (stmts[i], stmt2);
+
       /* We keep original statement only for the last one.  All
         others are recreated.  */
       if (i == stmt_num - 1)
@@ -5202,7 +5242,7 @@ reassociate_bb (basic_block bb)
                }
 
              if (rhs_code == PLUS_EXPR
-                 && transform_add_to_multiply (stmt, &ops))
+                 && transform_add_to_multiply (&ops))
                ops.qsort (sort_by_operand_rank);
 
              if (rhs_code == BIT_IOR_EXPR || rhs_code == BIT_AND_EXPR)
@@ -5247,7 +5287,11 @@ reassociate_bb (basic_block bb)
              else if (ops.length () == 1)
                {
                  tree last_op = ops.last ()->op;
-                 
+
+                 /* If the stmt that defines operand has to be inserted, insert it
+                    before the use.  */
+                 if (ops.last ()->stmt_to_insert)
+                   insert_stmt_before_use (stmt, ops.last ()->stmt_to_insert);
                  if (powi_result)
                    transform_stmt_to_multiply (&gsi, stmt, last_op,
                                                powi_result);