Main idea
Q & A
When implementing a function, why does compiler use callee-saved / call-preserved registers for local variables?
Suppose function A calls B. If B is a leaf function, it uses caller-saved register (ex. rdi) for a local variable.
But if B calls other function C, B is now the caller. So B must save and restore the rdi to stack each time it calls C. With many function calls, this is more expensive than save and restoring a callee-saved register (ex. rbx) once.
More specifically, if the variable’s lifetime crosses call instructions, compiler uses callee-saved register for efficiency.