function inlining
Calling a function has a small cost: the program jumps away, sets up arguments, runs the body, and jumps back. For a tiny helper called millions of times, that bookkeeping can dwarf the actual work. Function inlining is the optimization that removes the call by pasting the callee's body directly into the caller, as if you had written it out by hand at the call site.
Concretely, when the compiler decides to inline a call to f() inside g(), it replaces the call instruction with a copy of f's body, substituting the actual arguments for f's parameters. The payoff is more than skipping the call-and-return overhead: once f's code sits inside g, the optimizer can see across the old boundary. Constants you passed in can now be folded, branches can be resolved, dead paths deleted, and further optimizations cascade. This is why inlining is often called an enabling optimization — its biggest benefit is the work it unlocks for other passes.
It matters because inlining is one of the highest-impact optimizations at -O2 and the reason small accessor functions cost nothing at run time. But it is governed by a cost model, a heuristic that weighs the expected speedup against code growth: inlining a large function into many call sites bloats the binary, can hurt instruction-cache behavior, and may even slow things down. So compilers inline aggressively for small or hot callees and decline for big ones. Honest caveats: the inline keyword in C and C++ is a hint, not a command — the compiler decides; and more inlining is not always better, which is again a place to measure rather than assume.
static int sq(int x) { return x * x; } int f(void) { return sq(5); } // after inlining sq into f, then constant folding: int f(void) { return 25; } // the call is gone, and 5*5 is precomputed
Inlining removes the call, then exposes 5 as a constant so the body collapses to 25 — the enabling effect.
The inline keyword is a hint, not a guarantee: the compiler's cost model has the final say, and over-inlining can grow the binary and pessimize the instruction cache, so it is not 'always faster'.