summaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-ifcombine.c
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@ucw.cz>2017-02-03 15:03:35 +0100
committerJan Hubicka <hubicka@gcc.gnu.org>2017-02-03 14:03:35 +0000
commit30c6ec2f5309f78a1ded63243ae0037b63974d29 (patch)
treeaf9a108f3707a0072eb12193f8868bd736521ea3 /gcc/tree-ssa-ifcombine.c
parent778e0ac39798b142bbc96c78da568e2debeeff0b (diff)
tree-ssa-ifcombine.c (update_profile_after_ifcombine): New function.
* tree-ssa-ifcombine.c (update_profile_after_ifcombine): New function. (ifcombine_ifandif): Use it. * gcc.dg/tree-ssa/ssa-ifcombine-1.c: Check for no profile mismatches. * gcc.dg/tree-ssa/ssa-ifcombine-2.c: Check for no profile mismatches. * gcc.dg/tree-ssa/ssa-ifcombine-3.c: Check for no profile mismatches. * gcc.dg/tree-ssa/ssa-ifcombine-4.c: Check for no profile mismatches. * gcc.dg/tree-ssa/ssa-ifcombine-5.c: Check for no profile mismatches. * gcc.dg/tree-ssa/ssa-ifcombine-6.c: Check for no profile mismatches. * gcc.dg/tree-ssa/ssa-ifcombine-7.c: Check for no profile mismatches. * gcc.dg/tree-ssa/ssa-ifcombine-8.c: Check for no profile mismatches. * gcc.dg/tree-ssa/ssa-ifcombine-9.c: Check for no profile mismatches. * gcc.dg/tree-ssa/ssa-ifcombine-10.c: Check for no profile mismatches. * gcc.dg/tree-ssa/ssa-ifcombine-11.c: Check for no profile mismatches. * gcc.dg/tree-ssa/ssa-ifcombine-12.c: Check for no profile mismatches. * gcc.dg/tree-ssa/ssa-ifcombine-13.c: Check for no profile mismatches. From-SVN: r245151
Diffstat (limited to 'gcc/tree-ssa-ifcombine.c')
-rw-r--r--gcc/tree-ssa-ifcombine.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/gcc/tree-ssa-ifcombine.c b/gcc/tree-ssa-ifcombine.c
index 6e43b5c25a2..16f6c73d7e6 100644
--- a/gcc/tree-ssa-ifcombine.c
+++ b/gcc/tree-ssa-ifcombine.c
@@ -332,6 +332,51 @@ recognize_bits_test (gcond *cond, tree *name, tree *bits, bool inv)
return true;
}
+
+/* Update profile after code in outer_cond_bb was adjusted so
+ outer_cond_bb has no condition. */
+
+static void
+update_profile_after_ifcombine (basic_block inner_cond_bb,
+ basic_block outer_cond_bb)
+{
+ edge outer_to_inner = find_edge (outer_cond_bb, inner_cond_bb);
+ edge outer2 = (EDGE_SUCC (outer_cond_bb, 0) == outer_to_inner
+ ? EDGE_SUCC (outer_cond_bb, 1)
+ : EDGE_SUCC (outer_cond_bb, 0));
+ edge inner_taken = EDGE_SUCC (inner_cond_bb, 0);
+ edge inner_not_taken = EDGE_SUCC (inner_cond_bb, 1);
+
+ if (inner_taken->dest != outer2->dest)
+ std::swap (inner_taken, inner_not_taken);
+ gcc_assert (inner_taken->dest == outer2->dest);
+
+ /* In the following we assume that inner_cond_bb has single predecessor. */
+ gcc_assert (single_pred_p (inner_cond_bb));
+
+ /* Path outer_cond_bb->(outer2) needs to be merged into path
+ outer_cond_bb->(outer_to_inner)->inner_cond_bb->(inner_taken)
+ and probability of inner_not_taken updated. */
+
+ outer_to_inner->count = outer_cond_bb->count;
+ inner_cond_bb->count = outer_cond_bb->count;
+ inner_taken->count += outer2->count;
+ outer2->count = 0;
+
+ inner_taken->probability = outer2->probability
+ + RDIV (outer_to_inner->probability
+ * inner_taken->probability,
+ REG_BR_PROB_BASE);
+ if (inner_taken->probability > REG_BR_PROB_BASE)
+ inner_taken->probability = REG_BR_PROB_BASE;
+ inner_not_taken->probability = REG_BR_PROB_BASE
+ - inner_taken->probability;
+
+ outer_to_inner->probability = REG_BR_PROB_BASE;
+ inner_cond_bb->frequency = outer_cond_bb->frequency;
+ outer2->probability = 0;
+}
+
/* If-convert on a and pattern with a common else block. The inner
if is specified by its INNER_COND_BB, the outer by OUTER_COND_BB.
inner_inv, outer_inv and result_inv indicate whether the conditions
@@ -394,6 +439,8 @@ ifcombine_ifandif (basic_block inner_cond_bb, bool inner_inv,
outer_inv ? boolean_false_node : boolean_true_node);
update_stmt (outer_cond);
+ update_profile_after_ifcombine (inner_cond_bb, outer_cond_bb);
+
if (dump_file)
{
fprintf (dump_file, "optimizing double bit test to ");
@@ -471,6 +518,7 @@ ifcombine_ifandif (basic_block inner_cond_bb, bool inner_inv,
gimple_cond_set_condition_from_tree (outer_cond,
outer_inv ? boolean_false_node : boolean_true_node);
update_stmt (outer_cond);
+ update_profile_after_ifcombine (inner_cond_bb, outer_cond_bb);
if (dump_file)
{
@@ -554,6 +602,7 @@ ifcombine_ifandif (basic_block inner_cond_bb, bool inner_inv,
gimple_cond_set_condition_from_tree (outer_cond,
outer_inv ? boolean_false_node : boolean_true_node);
update_stmt (outer_cond);
+ update_profile_after_ifcombine (inner_cond_bb, outer_cond_bb);
if (dump_file)
{