Hi I'm writing a tiger compiler from the book "Modern Compiler Implementation in C" and have some questions with caller and callee saved registers.
As described by the book, when calling a function, the caller need to save registers that satisfy:
Similarly for callee, it need to save the following registers:
Thus I the following is what I think should be true:
Therefore, I would like to ask that "Do I have to do a second time liveness analysis and register coloring??"
What if after coloring, the callee uses more registers and require a new loop of this??
Furthermore, when calling external function(runtime C functions compiled by gcc), I should save and restore all registers that are alive in the call instruction right?
The details depend on how you encode register constraints, i.e., the need to use specific physical regs.
One common thing is "pre-coloring".
Let's say you have a function func
with an argument x
which returns one value.
Then your code generator (instruction selection) could emit the following sequence (this is AT&T syntax, so ins src,dst
):
mov x,%rdi
call func
mov %rax,res
So we emit code connecting our virtual registers with physical registers. The register allocator then has to connect the dots.
Liveness analysis should see, that %rdi
is born in the move and dies in the call.
In general, when calling random external functions, you won't know which registers that function will clobber. So you'll have to spill all caller-saves registers. If your register allocator is smart enough, it can move them to callee-saves registers, but I'd keep it simple in the beginning. Register allocation is super hard and debugging it is hell.