This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] PR 20994
- From: Devang Patel <dpatel at apple dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Thu, 21 Apr 2005 09:06:40 -0700
- Subject: [PATCH] PR 20994
This is the case when tree if-conversion produces
x = ! (a == b) : p , q;
This patch fixes tree if-convertor so that it produces
x = (a == b) : q , p ;
This is preferable over
t1 = (a == b);
x = !t1 : p : q;
, hence this song-and-dance.
* tree-if-conv.c (find_phi_replacement_condition): Avoid
generating x = !(a == b) : p : q;.
(pass_if_conversion): Verify stmts and flow.
* gcc.dg/tree-ssa/ifc-3.c: New test.
Bootstrapped and tested on powerpc-darwin.
OK for mainline ?
Thanks,
-
Devang
[Patch is small so I am including it here instead of attaching
diff file. ]
Index: tree-if-conv.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-if-conv.c,v
retrieving revision 2.37
diff -Idpatel.pbxuser -c -3 -p -r2.37 tree-if-conv.c
*** tree-if-conv.c 13 Apr 2005 19:02:31 -0000 2.37
--- tree-if-conv.c 19 Apr 2005 18:02:46 -0000
*************** find_phi_replacement_condition (struct l
*** 665,710 ****
basic_block bb, tree *cond,
block_stmt_iterator *bsi)
{
! edge e;
! basic_block p1 = NULL;
! basic_block p2 = NULL;
! basic_block true_bb = NULL;
tree tmp_cond;
- edge_iterator ei;
! FOR_EACH_EDGE (e, ei, bb->preds)
! {
! if (p1 == NULL)
! p1 = e->src;
! else
! {
! gcc_assert (!p2);
! p2 = e->src;
! }
! }
! /* Use condition that is not TRUTH_NOT_EXPR in conditional modify
expr. */
! tmp_cond = p1->aux;
if (TREE_CODE (tmp_cond) == TRUTH_NOT_EXPR)
{
! /* If p2 is loop->header than its aux field does not have useful
! info. Instead use !(cond) where cond is p1's aux field. */
! if (p2 == loop->header)
! *cond = invert_truthvalue (unshare_expr (p1->aux));
! else
! *cond = p2->aux;
! true_bb = p2;
}
! else
{
! /* If p1 is loop->header than its aux field does not have useful
! info. Instead use !(cond) where cond is p2's aux field. */
! if (p1 == loop->header)
! *cond = invert_truthvalue (unshare_expr (p2->aux));
else
! *cond = p1->aux;
! true_bb = p1;
}
/* Create temp. for the condition. Vectorizer prefers to have
gimple
value as condition. Various targets use different means to
communicate
--- 665,728 ----
basic_block bb, tree *cond,
block_stmt_iterator *bsi)
{
! basic_block first_bb = NULL;
! basic_block second_bb = NULL;
tree tmp_cond;
! gcc_assert (EDGE_COUNT (bb->preds) == 2);
! first_bb = (EDGE_PRED (bb, 0))->src;
! second_bb = (EDGE_PRED (bb, 1))->src;
! /* Use condition based on following criteria:
! 1)
! S1: x = !c ? a : b;
!
! S2: x = c ? b : a;
!
! S2 is preferred over S1. Make 'b' first_bb and use its
condition.
!
! 2) Do not make loop header first_bb.
!
! 3)
! S1: x = !(c == d)? a : b;
!
! S21: t1 = c == d;
! S22: x = t1 ? b : a;
!
! S3: x = (c == d) ? b : a;
!
! S3 is preferred over S1 and S2*, Make 'b' first_bb and use
! its condition. */
!
! /* Select condition that is not TRUTH_NOT_EXPR. */
! tmp_cond = first_bb->aux;
if (TREE_CODE (tmp_cond) == TRUTH_NOT_EXPR)
{
! basic_block tmp_bb;
! tmp_bb = first_bb;
! first_bb = second_bb;
! second_bb = first_bb;
}
!
! /* Check if first_bb is loop header or not. */
! if (first_bb == loop->header)
{
! tmp_cond = second_bb->aux;
! if (TREE_CODE (tmp_cond) == TRUTH_NOT_EXPR)
! {
! /* Select non loop header condition but do not swith bb. */
! *cond = invert_truthvalue (unshare_expr (tmp_cond));
! }
else
! {
! /* Select non loop header condition. */
! first_bb = second_bb;
! *cond = first_bb->aux;
! }
}
+ else
+ /* first_bb is not loop header */
+ *cond = first_bb->aux;
/* Create temp. for the condition. Vectorizer prefers to have
gimple
value as condition. Various targets use different means to
communicate
*************** find_phi_replacement_condition (struct l
*** 722,728 ****
gcc_assert (*cond);
! return true_bb;
}
--- 740,746 ----
gcc_assert (*cond);
! return first_bb;
}
*************** struct tree_opt_pass pass_if_conversion
*** 1119,1124 ****
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
! TODO_dump_func | TODO_verify_loops, /* todo_flags_finish */
0 /* letter */
};
--- 1137,1143 ----
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
! TODO_dump_func | TODO_verify_loops | TODO_verify_stmts |
TODO_verify_flow,
! /* todo_flags_finish */
0 /* letter */
};
Index: testsuite/gcc.dg/tree-ssa/ifc-3.c
===================================================================
RCS file: testsuite/gcc.dg/tree-ssa/ifc-3.c
diff -N testsuite/gcc.dg/tree-ssa/ifc-3.c
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.dg/tree-ssa/ifc-3.c 19 Apr 2005 18:02:49 -0000
***************
*** 0 ****
--- 1,12 ----
+ /* PR 20994 */
+ /* { dg-do compile } */
+ int foo(double* p, double* q)
+ {
+ int i=0;
+
+ for (; q!=p; ++q)
+ if (*q)
+ ++i;
+
+ return i;
+ }