Commit fa2c9034 by Richard Biener Committed by Richard Biener

re PR tree-optimization/71261 (Trunk GCC hangs on knl and broadwell targets)

2016-06-01  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/71261
	* tree-vect-patterns.c (check_bool_pattern): Gather a hash-set
	of stmts successfully put in the bool pattern.  Remove
	single-use restriction.
	(adjust_bool_pattern_cast): Add cast at the use site via the
	pattern def sequence.
	(adjust_bool_pattern): Remove recursion, maintain a hash-map
	of patterned defs.  Use the pattern def seqence instead of
	multiple independent patterns.
	(sort_after_uid): New qsort compare function.
	(adjust_bool_stmts): New function to process stmts in the bool
	pattern in IL order.
	(vect_recog_bool_pattern): Adjust.
	* tree-if-conv.c (ifcvt_split_def_stmt): Remove.
	(ifcvt_walk_pattern_tree): Likewise.
	(stmt_is_root_of_bool_pattern): Likewise.
	(ifcvt_repair_bool_pattern): Likewise.
	(tree_if_conversion): Do not call ifcvt_repair_bool_pattern.

	* gcc.dg/torture/vect-bool-1.c: New testcase.

From-SVN: r236989
parent 3e32893c
2016-06-01 Richard Biener <rguenther@suse.de>
PR tree-optimization/71261
* tree-vect-patterns.c (check_bool_pattern): Gather a hash-set
of stmts successfully put in the bool pattern. Remove
single-use restriction.
(adjust_bool_pattern_cast): Add cast at the use site via the
pattern def sequence.
(adjust_bool_pattern): Remove recursion, maintain a hash-map
of patterned defs. Use the pattern def seqence instead of
multiple independent patterns.
(sort_after_uid): New qsort compare function.
(adjust_bool_stmts): New function to process stmts in the bool
pattern in IL order.
(vect_recog_bool_pattern): Adjust.
* tree-if-conv.c (ifcvt_split_def_stmt): Remove.
(ifcvt_walk_pattern_tree): Likewise.
(stmt_is_root_of_bool_pattern): Likewise.
(ifcvt_repair_bool_pattern): Likewise.
(tree_if_conversion): Do not call ifcvt_repair_bool_pattern.
2016-06-01 Jan Hubicka <hubicka@ucw.cz>
* loop-unroll.c (decide_unroll_constant_iterations,
......
2016-06-01 Richard Biener <rguenther@suse.de>
PR tree-optimization/71261
* gcc.dg/torture/vect-bool-1.c: New testcase.
2016-06-01 Jakub Jelinek <jakub@redhat.com>
* gfortran.dg/gomp/order-1.f90: New test.
......
/* { dg-do compile } */
int a[64];
long b[64];
void foo (void)
{
for (int i = 0; i < 64; ++i)
{
_Bool x = a[i] < 10;
a[i] = x;
b[i] = x;
}
}
......@@ -2516,194 +2516,6 @@ ifcvt_split_critical_edges (struct loop *loop, bool aggressive_if_conv)
return true;
}
/* Assumes that lhs of DEF_STMT have multiple uses.
Delete one use by (1) creation of copy DEF_STMT with
unique lhs; (2) change original use of lhs in one
use statement with newly created lhs. */
static void
ifcvt_split_def_stmt (gimple *def_stmt, gimple *use_stmt)
{
tree var;
tree lhs;
gimple *copy_stmt;
gimple_stmt_iterator gsi;
use_operand_p use_p;
ssa_op_iter iter;
var = gimple_assign_lhs (def_stmt);
copy_stmt = gimple_copy (def_stmt);
lhs = make_temp_ssa_name (TREE_TYPE (var), NULL, "_ifc_");
gimple_assign_set_lhs (copy_stmt, lhs);
SSA_NAME_DEF_STMT (lhs) = copy_stmt;
/* Insert copy of DEF_STMT. */
gsi = gsi_for_stmt (def_stmt);
gsi_insert_after (&gsi, copy_stmt, GSI_SAME_STMT);
/* Change use of var to lhs in use_stmt. */
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Change use of var ");
print_generic_expr (dump_file, var, TDF_SLIM);
fprintf (dump_file, " to ");
print_generic_expr (dump_file, lhs, TDF_SLIM);
fprintf (dump_file, "\n");
}
FOR_EACH_SSA_USE_OPERAND (use_p, use_stmt, iter, SSA_OP_USE)
{
if (USE_FROM_PTR (use_p) != var)
continue;
SET_USE (use_p, lhs);
break;
}
}
/* Traverse bool pattern recursively starting from VAR.
Save its def and use statements to defuse_list if VAR does
not have single use. */
static void
ifcvt_walk_pattern_tree (tree var, vec<gimple *> *defuse_list,
gimple *use_stmt)
{
tree rhs1, rhs2;
enum tree_code code;
gimple *def_stmt;
if (TREE_CODE (var) != SSA_NAME)
return;
def_stmt = SSA_NAME_DEF_STMT (var);
if (gimple_code (def_stmt) != GIMPLE_ASSIGN)
return;
if (!has_single_use (var))
{
/* Put def and use stmts into defuse_list. */
defuse_list->safe_push (def_stmt);
defuse_list->safe_push (use_stmt);
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Multiple lhs uses in stmt\n");
print_gimple_stmt (dump_file, def_stmt, 0, TDF_SLIM);
}
}
rhs1 = gimple_assign_rhs1 (def_stmt);
code = gimple_assign_rhs_code (def_stmt);
switch (code)
{
case SSA_NAME:
ifcvt_walk_pattern_tree (rhs1, defuse_list, def_stmt);
break;
CASE_CONVERT:
if ((TYPE_PRECISION (TREE_TYPE (rhs1)) != 1
|| !TYPE_UNSIGNED (TREE_TYPE (rhs1)))
&& TREE_CODE (TREE_TYPE (rhs1)) != BOOLEAN_TYPE)
break;
ifcvt_walk_pattern_tree (rhs1, defuse_list, def_stmt);
break;
case BIT_NOT_EXPR:
ifcvt_walk_pattern_tree (rhs1, defuse_list, def_stmt);
break;
case BIT_AND_EXPR:
case BIT_IOR_EXPR:
case BIT_XOR_EXPR:
ifcvt_walk_pattern_tree (rhs1, defuse_list, def_stmt);
rhs2 = gimple_assign_rhs2 (def_stmt);
ifcvt_walk_pattern_tree (rhs2, defuse_list, def_stmt);
break;
default:
break;
}
return;
}
/* Returns true if STMT can be a root of bool pattern applied
by vectorizer. */
static bool
stmt_is_root_of_bool_pattern (gimple *stmt)
{
enum tree_code code;
tree lhs, rhs;
code = gimple_assign_rhs_code (stmt);
if (CONVERT_EXPR_CODE_P (code))
{
lhs = gimple_assign_lhs (stmt);
rhs = gimple_assign_rhs1 (stmt);
if (TREE_CODE (TREE_TYPE (rhs)) != BOOLEAN_TYPE)
return false;
if (TREE_CODE (TREE_TYPE (lhs)) == BOOLEAN_TYPE)
return false;
return true;
}
else if (code == COND_EXPR)
{
rhs = gimple_assign_rhs1 (stmt);
if (TREE_CODE (rhs) != SSA_NAME)
return false;
return true;
}
return false;
}
/* Traverse all statements in BB which correspond to loop header to
find out all statements which can start bool pattern applied by
vectorizer and convert multiple uses in it to conform pattern
restrictions. Such case can occur if the same predicate is used both
for phi node conversion and load/store mask. */
static void
ifcvt_repair_bool_pattern (basic_block bb)
{
tree rhs;
gimple *stmt;
gimple_stmt_iterator gsi;
auto_vec<gimple *> defuse_list;
auto_vec<gimple *> pattern_roots;
bool repeat = true;
int niter = 0;
unsigned int ix;
/* Collect all root pattern statements. */
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
stmt = gsi_stmt (gsi);
if (gimple_code (stmt) != GIMPLE_ASSIGN)
continue;
if (!stmt_is_root_of_bool_pattern (stmt))
continue;
pattern_roots.safe_push (stmt);
}
if (pattern_roots.is_empty ())
return;
/* Split all statements with multiple uses iteratively since splitting
may create new multiple uses. */
while (repeat)
{
repeat = false;
niter++;
FOR_EACH_VEC_ELT (pattern_roots, ix, stmt)
{
rhs = gimple_assign_rhs1 (stmt);
ifcvt_walk_pattern_tree (rhs, &defuse_list, stmt);
while (defuse_list.length () > 0)
{
repeat = true;
gimple *def_stmt, *use_stmt;
use_stmt = defuse_list.pop ();
def_stmt = defuse_list.pop ();
ifcvt_split_def_stmt (def_stmt, use_stmt);
}
}
}
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "Repair bool pattern takes %d iterations. \n",
niter);
}
/* Delete redundant statements produced by predication which prevents
loop vectorization. */
......@@ -2850,10 +2662,8 @@ tree_if_conversion (struct loop *loop)
on-the-fly. */
combine_blocks (loop);
/* Delete dead predicate computations and repair tree correspondent
to bool pattern to delete multiple uses of predicates. */
/* Delete dead predicate computations. */
ifcvt_local_dce (loop->header);
ifcvt_repair_bool_pattern (loop->header);
todo |= TODO_cleanup_cfg;
mark_virtual_operands_for_renaming (cfun);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment