re PR tree-optimization/71170 (ICE in rewrite_expr_tree, at tree-ssa-reassoc.c:3898)
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
This commit is contained in:
parent
fe3f334041
commit
d2db36ddd2
2 changed files with 76 additions and 18 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue