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
This commit is contained in:
parent
4986f823a2
commit
1011119f47
4 changed files with 93 additions and 6 deletions
|
@ -1,3 +1,12 @@
|
|||
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
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
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
|
||||
|
|
17
gcc/testsuite/gcc.dg/tree-ssa/ifc-pr69489-2.c
Normal file
17
gcc/testsuite/gcc.dg/tree-ssa/ifc-pr69489-2.c
Normal file
|
@ -0,0 +1,17 @@
|
|||
/* { 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)
|
||||
|
|
Loading…
Add table
Reference in a new issue