On 12/01/2016 05:49 PM, Martin Sebor wrote:
Okay, thanks for the clarification.  One other question though.
Why would the probability be near zero?  In the absence of any
hints the expression 2 != sprintf(d, "%i", 12) should have
a very high probability of being true, near 100% in fact.

I ask because the test I referenced tries to verify the absence
of the sprintf return value optimization.  Without it the
likelihood of each of the calls to abort should in the EQL kind
of test cases like the one above should be nearly 100% (but not
quite).  When it's the opposite it suggests that the sprintf
optimization is providing some hint (in the form of a range of
return values) that changes the odds.  I have verified that
the optimization is not performed so something else must be
setting the probability or the value isn't correct.

I think I see what's going on.  It's the call to abort that GCC
uses for the probability (more precisely its attribute noreturn).
When I replace the abort with a function of my own that GCC knows
nothing about the probability goes up to just over 52%.  Still it
seems very low given that 2 is just one of UINT_MAX values the
function can possibly return.

Martin

Hi Martin.

Situation is more complicated:
$ gcc predictor.c -fdump-tree-profile_estimate=/dev/stdout -O2 -c

;; Function bar (bar, funcdef_no=0, decl_uid=1797, cgraph_uid=0, symbol_order=0)

;; 1 loops found
;;
;; Loop 0
;;  header 0, latch 1
;;  depth 0, outer -1
;;  nodes: 0 1 2 3 4
;; 2 succs { 3 4 }
;; 3 succs { 4 }
;; 4 succs { 1 }
Predictions for bb 2
  DS theory heuristics: 52.9%
  combined heuristics: 52.9%
  opcode values nonequal (on trees) heuristics of edge 2->3: 66.0%
  early return (on trees) heuristics of edge 2->4: 46.0%
  call heuristics of edge 2->3: 33.0%
Predictions for bb 3
1 edges in bb 3 predicted to even probabilities
Predictions for bb 4
1 edges in bb 4 predicted to even probabilities
bar ()
{
  char d[2];
  int _1;

  <bb 2> [100.0%]:
  _1 = __builtin_sprintf (&d, "%i", 12);
  if (_1 != 2)
    goto <bb 3>; [52.9%]
  else
    goto <bb 4>; [47.1%]

  <bb 3> [52.9%]:
  foo ();

  <bb 4> [100.0%]:
  d ={v} {CLOBBER};
  return;

}

As you can see, multiple predictors do match to edge 2->3:
  opcode values nonequal (on trees) heuristics of edge 2->3: 66.0% // this is 
the real probability that _x != a_value
  early return (on trees) heuristics of edge 2->4: 46.0% // 2->3 would have 
54.0%
  call heuristics of edge 2->3: 33.0% // performing condition that triggers a 
call is unlikely

These 3 combined together would result in 52.9%. Real values for all of these 
predictors are received from
SPEC benchmarks (https://gcc.gnu.org/ml/gcc-patches/2016-06/msg00511.html), 
where we use contrib/analyze_brprob.py
script which is capable of parsing of the tree profile_estimate dumps.

Back to your question about probability that a given value (from UINT_MAX 
range) is equal to 2. As the predictor
is only driven by opcode and it's quite common that a comparison in a source 
code is to a 'special' value, that's
why the tuned value of the predictor is equal to 66%.

Martin



$ cat a.c && gcc -O2 -S -w -fdump-tree-optimized=/dev/stdout a.c
void foo (void);

void bar (void)
{
  char d [2];
  if (2 != __builtin_sprintf (d, "%i", 12))
    foo ();
}

;; Function bar (bar, funcdef_no=0, decl_uid=1797, cgraph_uid=0, symbol_order=0)

Removing basic block 5
bar ()
{
  char d[2];
  int _1;

  <bb 2> [100.0%]:
  _1 = __builtin_sprintf (&d, "%i", 12);
  if (_1 != 2)
    goto <bb 3>; [52.9%]
  else
    goto <bb 4>; [47.1%]

  <bb 3> [52.9%]:
  foo ();

  <bb 4> [100.0%]:
  d ={v} {CLOBBER};
  return;

}



Reply via email to