> Ok, you're right that we can preserve the predictor. However, let's consider > following test-case: > > static > int baz(int a) > { > if (a == 1) > return 1; > > return 0; > } > > > static > int bar(int a) > { > if (a == 1) > return baz(a); > > return 0; > } > > static > int foo(int a) > { > if (a == 1) > return bar(a); > > return 12; > } > > int main(int argc, char **argv) > { > return foo(argc); > } > > There after einline we have: > > main (int argc, char * * argv) > { > int D.1832; > int _3; > int _4; > > <bb 2> [100.00%]: > if (argc_2(D) == 1) > goto <bb 3>; [37.13%] > else > goto <bb 4>; [62.87%] > > <bb 3> [37.13%]: > // predicted unlikely by early return (on trees) predictor. > // predicted unlikely by early return (on trees) predictor. > // predicted unlikely by early return (on trees) predictor. > > <bb 4> [100.00%]: > # _3 = PHI <12(2), 1(3)> > _5 = _3; > _4 = _5; > return _4; > > } > > I'm thinking what's the best place to merge all the predictor > statements?
I wonder if we need to - predictors are relatively short lived. In fact they do not need to hit IPA passes but they do as at a time I was implementing them I was worrying about introducing yet another global IPA pass to remove them (we can't do during early inlining because we want to reuse them after inlining). I would just move pass_strip_predict_hints pre-IPA and not worry about them chaining. There is problem that after inlining the prediction may expand its scope and predict branch that it outside of the original function body, but I do not see very easy solution for that besides not re-doing prediction (we could also copy probabilities from the inlined function when they exists and honnor them in the outer function. I am not sure that is going to improve prediction quality though - extra context is probably useful) Thanks, Honza > > Thanks, > Martin > > > > > Where did you found this case? > > Honza > >> > >> /* Create a new deep copy of the statement. */ > >> copy = gimple_copy (stmt); > >> -- > >> 2.13.0 > >>