summaryrefslogtreecommitdiff
path: root/gcc/tree-if-conv.c
diff options
context:
space:
mode:
authordpatel <dpatel@138bc75d-0d04-0410-961f-82ee72b054a4>2005-04-21 17:03:23 +0000
committerdpatel <dpatel@138bc75d-0d04-0410-961f-82ee72b054a4>2005-04-21 17:03:23 +0000
commitdea55b965e6d9797591ae1cf17a71c92d691cb1c (patch)
tree7eeb771e582fffc15dda8ca8902f128ec68c8b8a /gcc/tree-if-conv.c
parent5b57171e4e8bec2f65f88e774c2e4a26be8a7057 (diff)
downloadgcc-dea55b965e6d9797591ae1cf17a71c92d691cb1c.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@98514 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-if-conv.c')
-rw-r--r--gcc/tree-if-conv.c85
1 files changed, 52 insertions, 33 deletions
diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c
index 2770539d435..4eb5a26e6c9 100644
--- a/gcc/tree-if-conv.c
+++ b/gcc/tree-if-conv.c
@@ -665,46 +665,64 @@ find_phi_replacement_condition (struct loop *loop,
basic_block bb, tree *cond,
block_stmt_iterator *bsi)
{
- edge e;
- basic_block p1 = NULL;
- basic_block p2 = NULL;
- basic_block true_bb = NULL;
+ basic_block first_bb = NULL;
+ basic_block second_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;
- }
- }
+ gcc_assert (EDGE_COUNT (bb->preds) == 2);
+ first_bb = (EDGE_PRED (bb, 0))->src;
+ second_bb = (EDGE_PRED (bb, 1))->src;
- /* Use condition that is not TRUTH_NOT_EXPR in conditional modify expr. */
- tmp_cond = p1->aux;
+ /* 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)
{
- /* 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;
+ basic_block tmp_bb;
+ tmp_bb = first_bb;
+ first_bb = second_bb;
+ second_bb = first_bb;
}
- else
+
+ /* Check if FIRST_BB is loop header or not. */
+ if (first_bb == loop->header)
{
- /* 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));
+ tmp_cond = second_bb->aux;
+ if (TREE_CODE (tmp_cond) == TRUTH_NOT_EXPR)
+ {
+ /* Select non loop header condition but do not switch basic blocks. */
+ *cond = invert_truthvalue (unshare_expr (tmp_cond));
+ }
else
- *cond = p1->aux;
- true_bb = p1;
+ {
+ /* 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
@@ -722,7 +740,7 @@ find_phi_replacement_condition (struct loop *loop,
gcc_assert (*cond);
- return true_bb;
+ return first_bb;
}
@@ -1119,6 +1137,7 @@ struct tree_opt_pass pass_if_conversion =
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
- TODO_dump_func | TODO_verify_loops, /* todo_flags_finish */
+ TODO_dump_func | TODO_verify_loops | TODO_verify_stmts | TODO_verify_flow,
+ /* todo_flags_finish */
0 /* letter */
};