Commit f5c517f0 by Jakub Jelinek Committed by Jakub Jelinek

re PR tree-optimization/83081 ([arm] gcc.dg/pr80218.c fails since r254888)

	PR tree-optimization/83081
	* profile-count.h (profile_probability::split): New method.
	* dojump.c (do_jump_1) <case TRUTH_ANDIF_EXPR, case TRUTH_ORIF_EXPR>:
	Use profile_probability::split.
	(do_compare_rtx_and_jump): Fix adjustment of probabilities
	when splitting a single conditional jump into 2.

	* gcc.dg/predict-8.c: Adjust expected probability.

From-SVN: r256966
parent c3b56023
2018-01-22 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/83081
* profile-count.h (profile_probability::split): New method.
* dojump.c (do_jump_1) <case TRUTH_ANDIF_EXPR, case TRUTH_ORIF_EXPR>:
Use profile_probability::split.
(do_compare_rtx_and_jump): Fix adjustment of probabilities
when splitting a single conditional jump into 2.
2018-01-22 David Malcolm <dmalcolm@redhat.com>
PR tree-optimization/69452
......
......@@ -347,13 +347,11 @@ do_jump_1 (enum tree_code code, tree op0, tree op1,
profile_probability op1_prob = profile_probability::uninitialized ();
if (prob.initialized_p ())
{
profile_probability false_prob = prob.invert ();
profile_probability op0_false_prob = false_prob.apply_scale (1, 2);
profile_probability op1_false_prob = false_prob.apply_scale (1, 2)
/ op0_false_prob.invert ();
op1_prob = prob.invert ();
op0_prob = op1_prob.split (profile_probability::even ());
/* Get the probability that each jump below is true. */
op0_prob = op0_false_prob.invert ();
op1_prob = op1_false_prob.invert ();
op0_prob = op0_prob.invert ();
op1_prob = op1_prob.invert ();
}
if (if_false_label == NULL)
{
......@@ -380,8 +378,8 @@ do_jump_1 (enum tree_code code, tree op0, tree op1,
profile_probability op1_prob = profile_probability::uninitialized ();
if (prob.initialized_p ())
{
op0_prob = prob.apply_scale (1, 2);
op1_prob = prob.apply_scale (1, 2) / op0_prob.invert ();
op1_prob = prob;
op0_prob = op1_prob.split (profile_probability::even ());
}
if (if_true_label == NULL)
{
......@@ -1120,16 +1118,27 @@ do_compare_rtx_and_jump (rtx op0, rtx op1, enum rtx_code code, int unsignedp,
else
{
profile_probability first_prob = prob;
profile_probability cprob
= profile_probability::guessed_always ();
if (first_code == UNORDERED)
first_prob = profile_probability::guessed_always ().apply_scale
(1, 100);
cprob = cprob.apply_scale (1, 100);
else if (first_code == ORDERED)
first_prob = profile_probability::guessed_always ().apply_scale
(99, 100);
cprob = cprob.apply_scale (99, 100);
else
cprob = profile_probability::even ();
/* We want to split:
if (x) goto t; // prob;
into
if (a) goto t; // first_prob;
if (b) goto t; // prob;
such that the overall probability of jumping to t
remains the same and first_prob is prob * cprob. */
if (and_them)
{
rtx_code_label *dest_label;
prob = prob.invert ();
profile_probability first_prob = prob.split (cprob).invert ();
prob = prob.invert ();
/* If we only jump if true, just bypass the second jump. */
if (! if_false_label)
{
......@@ -1143,8 +1152,11 @@ do_compare_rtx_and_jump (rtx op0, rtx op1, enum rtx_code code, int unsignedp,
size, dest_label, NULL, first_prob);
}
else
do_compare_rtx_and_jump (op0, op1, first_code, unsignedp, mode,
size, NULL, if_true_label, first_prob);
{
profile_probability first_prob = prob.split (cprob);
do_compare_rtx_and_jump (op0, op1, first_code, unsignedp, mode,
size, NULL, if_true_label, first_prob);
}
}
}
......
......@@ -410,6 +410,30 @@ public:
return *this;
}
/* Split *THIS (ORIG) probability into 2 probabilities, such that
the returned one (FIRST) is *THIS * CPROB and *THIS is
adjusted (SECOND) so that FIRST + FIRST.invert () * SECOND
== ORIG. This is useful e.g. when splitting a conditional
branch like:
if (cond)
goto lab; // ORIG probability
into
if (cond1)
goto lab; // FIRST = ORIG * CPROB probability
if (cond2)
goto lab; // SECOND probability
such that the overall probability of jumping to lab remains
the same. CPROB gives the relative probability between the
branches. */
profile_probability split (const profile_probability &cprob)
{
profile_probability ret = *this * cprob;
/* The following is equivalent to:
*this = cprob.invert () * *this / ret.invert (); */
*this = (*this - ret) / ret.invert ();
return ret;
}
gcov_type apply (gcov_type val) const
{
if (*this == profile_probability::uninitialized ())
......
2018-01-22 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/83081
* gcc.dg/predict-8.c: Adjust expected probability.
2018-01-22 Michael Meissner <meissner@linux.vnet.ibm.com>
PR target/83862
......
......@@ -8,4 +8,4 @@ int foo(float a, float b) {
return 2;
}
/* { dg-final { scan-rtl-dump-times "99.0. .guessed" 2 "expand"} } */
/* { dg-final { scan-rtl-dump-times "65.\[34]. .guessed" 2 "expand"} } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment