Commit 1011119f by Bin Cheng Committed by Bin Cheng

re PR tree-optimization/69489 (missed vectorization for boolean loop, missed if-conversion)

	PR tree-optimization/69489
	* tree-if-conv.c (phi_convertible_by_degenerating_args): New.
	(if_convertible_phi_p): Call phi_convertible_by_degenerating_args.
	Revise dump message.
	(if_convertible_bb_p): Remove check on edge count of basic block's
	predecessors.

	gcc/testsuite/ChangeLog
	PR tree-optimization/69489
	* gcc.dg/tree-ssa/ifc-pr69489-2.c: New test.

From-SVN: r235292
parent 4986f823
2016-04-20 Bin Cheng <bin.cheng@arm.com>
PR tree-optimization/69489
* tree-if-conv.c (phi_convertible_by_degenerating_args): New.
(if_convertible_phi_p): Call phi_convertible_by_degenerating_args.
Revise dump message.
(if_convertible_bb_p): Remove check on edge count of basic block's
predecessors.
2016-04-20 Bin Cheng <bin.cheng@arm.com>
PR tree-optimization/56625
PR tree-optimization/69489
* tree-data-ref.h (DR_INNERMOST): New macro.
......
2016-04-20 Bin Cheng <bin.cheng@arm.com>
PR tree-optimization/69489
* gcc.dg/tree-ssa/ifc-pr69489-2.c: New test.
2016-04-20 Ilya Verbin <ilya.verbin@intel.com>
PR c++/69363
......
/* { dg-do compile } */
/* { dg-options "-S -O2 -ftree-vectorize -fdump-tree-ifcvt-stats" { target *-*-* } } */
double
foo (const char *u, const char *v, long n)
{
long i, n1 = 0, n2 = 0;
for (i = 0; i < n; i++)
{
n2 += (u[i] && !v[i]);
n1 += (!u[i] && v[i]);
}
return (2.0 * n2 * n1);
}
/* { dg-final { scan-tree-dump-times "Applying if-conversion" 1 "ifcvt" } } */
......@@ -575,6 +575,65 @@ bb_with_exit_edge_p (struct loop *loop, basic_block bb)
return false;
}
/* Given PHI which has more than two arguments, this function checks if
it's if-convertible by degenerating its arguments. Specifically, if
below two conditions are satisfied:
1) Number of PHI arguments with different values equals to 2 and one
argument has the only occurrence.
2) The edge corresponding to the unique argument isn't critical edge.
Such PHI can be handled as PHIs have only two arguments. For example,
below PHI:
res = PHI <A_1(e1), A_1(e2), A_2(e3)>;
can be transformed into:
res = (predicate of e3) ? A_2 : A_1;
Return TRUE if it is the case, FALSE otherwise. */
static bool
phi_convertible_by_degenerating_args (gphi *phi)
{
edge e;
tree arg, t1 = NULL, t2 = NULL;
unsigned int i, i1 = 0, i2 = 0, n1 = 0, n2 = 0;
unsigned int num_args = gimple_phi_num_args (phi);
gcc_assert (num_args > 2);
for (i = 0; i < num_args; i++)
{
arg = gimple_phi_arg_def (phi, i);
if (t1 == NULL || operand_equal_p (t1, arg, 0))
{
n1++;
i1 = i;
t1 = arg;
}
else if (t2 == NULL || operand_equal_p (t2, arg, 0))
{
n2++;
i2 = i;
t2 = arg;
}
else
return false;
}
if (n1 != 1 && n2 != 1)
return false;
/* Check if the edge corresponding to the unique arg is critical. */
e = gimple_phi_arg_edge (phi, (n1 == 1) ? i1 : i2);
if (EDGE_COUNT (e->src->succs) > 1)
return false;
return true;
}
/* Return true when PHI is if-convertible. PHI is part of loop LOOP
and it belongs to basic block BB.
......@@ -601,10 +660,11 @@ if_convertible_phi_p (struct loop *loop, basic_block bb, gphi *phi,
if (bb != loop->header)
{
if (gimple_phi_num_args (phi) != 2
&& !aggressive_if_conv)
&& !aggressive_if_conv
&& !phi_convertible_by_degenerating_args (phi))
{
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "More than two phi node args.\n");
fprintf (dump_file, "Phi can't be predicated by single cond.\n");
return false;
}
}
......@@ -1003,10 +1063,6 @@ if_convertible_bb_p (struct loop *loop, basic_block bb, basic_block exit_bb)
if (EDGE_COUNT (bb->succs) > 2)
return false;
if (EDGE_COUNT (bb->preds) > 2
&& !aggressive_if_conv)
return false;
if (exit_bb)
{
if (bb != loop->latch)
......
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