Every time your program calls a function, the CPU pushes a return address, shuffles arguments into registers, jumps to the callee, and eventually jumps back. For a tiny helper — say, abs(x) or a one-line getter — that overhead can dwarf the actual work.
Inlining is the compiler's answer: instead of emitting a call instruction, just paste the callee's body directly into the caller. The call overhead vanishes, and now the surrounding code can see through the boundary — constant-folding, dead-code elimination, and further optimizations become possible.
The catch is code size. Each inline creates a fresh copy of the callee's instructions at every call site. A function called in a hundred places, each copy bloating the binary, spills the instruction cache and often costs more than the call overhead it replaced. So the compiler must answer: does the benefit of inlining outweigh the cost of growth?
That question has no closed-form solution. Instead, every production compiler — GCC, LLVM/Clang, javac's JIT — runs a heuristic: a scoring rule that estimates the gain and compares it to a size budget. Getting the threshold right is, quietly, one of the most consequential knobs in an optimizing compiler.
Comments
Loading comments...