This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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;
+ }



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]