I just want to add these reasons for having inlining despite
having compiler heuristics:
1. If you compile for embedded or PNACL on the web, you want a
small executable. That means the heuristics should not inline if
it increase the code size unless the programmer specified it in
the code. (Or that you specify a target size, and do compiler
re-runs until it fits.)
2. If you use profile guided opimization you should inline based
on call frequency, but the input set might have missed some
scenarios and you should be able to overrule the profile by
explicit inlining in code where you know that it matters. (e.g.
tight loop in an exception handler)