> 2018-07-24  Martin Liska  <mli...@suse.cz>
> 
>         PR target/83610
>       * builtin-types.def (BT_FN_LONG_LONG_LONG_DOUBLE): New type.
>       * builtins.c (expand_builtin_expect_with_probability):
>         New function.
>       (expand_builtin): Handle also BUILT_IN_EXPECT_WITH_PROBABILITY.
>       (build_builtin_expect_predicate): Likewise.
>       (fold_builtin_expect): Likewise.
>       (fold_builtin_2): Likewise.
>       (fold_builtin_3): Likewise.
>       * builtins.def (BUILT_IN_EXPECT_WITH_PROBABILITY): Define new
>         builtin.
>       * builtins.h (fold_builtin_expect): Add new argument
>         (probability).
>       * doc/extend.texi: Document the new builtin.
>       * doc/invoke.texi: Likewise.
>       * gimple-fold.c (gimple_fold_call): Pass new argument.
>       * ipa-fnsummary.c (find_foldable_builtin_expect):
>         Handle also BUILT_IN_EXPECT_WITH_PROBABILITY.
>       * predict.c (expr_expected_value): Add new out argument which
>         is probability.
>       (expr_expected_value_1): Likewise.
>       (tree_predict_by_opcode): Predict edge based on
>         provided probability.
>       (pass_strip_predict_hints::execute): Use newly added
>         DECL_BUILT_IN_P macro.
>       * predict.def (PRED_BUILTIN_EXPECT_WITH_PROBABILITY):
>         Define new predictor.
>       * tree.h (DECL_BUILT_IN_P): Define.
> 
> gcc/testsuite/ChangeLog:
> 
> 2018-07-24  Martin Liska  <mli...@suse.cz>
> 
>       * gcc.dg/predict-16.c: New test.
>       * gcc.dg/predict-17.c: New test.

OK
> +@deftypefn {Built-in Function} long __builtin_expect_with_probability
> +(long @var{exp}, long @var{c}, long @var{probability})
> +
> +The built-in has same semantics as @code{__builtin_expect_with_probability},
> +but user can provide expected probability (in percent) for value of 
> @var{exp}.
> +Last argument @var{probability} is of flaot type and valid values
flaot->float :)
> @@ -2426,10 +2444,10 @@ expr_expected_value_1 (tree type, tree op0, enum 
> tree_code code,
>      {
>        tree res;
>        enum br_predictor predictor2;
> -      op0 = expr_expected_value (op0, visited, predictor);
> +      op0 = expr_expected_value (op0, visited, predictor, probability);
>        if (!op0)
>       return NULL;
> -      op1 = expr_expected_value (op1, visited, &predictor2);
> +      op1 = expr_expected_value (op1, visited, &predictor2, probability);
>        if (predictor && *predictor < predictor2)
>       *predictor = predictor2;
>        if (!op1)

Here you need to combine probabilities together.

I would probably convert it early into profile_probability type (at the time
builtin is handled) because then combination is better defined.

If probability is known only over one path I guess you will need to turn
predictor into probability and then do the combination. The predictor combining
logic simply takes the weaker one (assumes that they are all first match), 
perhaps
with probability one can just combine probabilties and throw away predictor info
in this case.

It would be still very nice to arrange loop code to set 
loop->nb_iterations_estimate
accordingly in this case.  That would be useful for loop opts as reliable hint 
that
number of iterations is about that much.

Honza

Reply via email to