DoctorWkt / acwj

A Compiler Writing Journey
GNU General Public License v3.0
10.55k stars 1.02k forks source link

How does the spilling ensure that there are no register-name collisions? #60

Closed PhilippRados closed 1 year ago

PhilippRados commented 1 year ago

How does the spilling mechanism ensure that when a register is spilled that that same register isn't needed in the expression with the newly acquired register? Hypothetical example (I know this would be optimized away): Say we have an expression that requires two free registers and there is only one

1 + 2:
======
movl $1, %r11d
// then lets say %r11 is the next one to be spilled
pushq    %r11
// now the other operand gets loaded into %r11
movl   $2, %r11d
// the add expression now uses the same register twice but it shouldn't
add   %r11d,%r11d
popq  %r11

how does the compiler ensure that this doesn't happen? I couldn't find any code that reloads the value if it's used in an operand. But it could happen that the spilled value is needed in an operation before it is reloaded. Does the compiler just assume that these cases are rare or are they avoided somehow?

DoctorWkt commented 1 year ago

That's a good question. The compiler definitely assumes that these cases are rare! One of the reasons that I chose to rewrite the back-end to use QBE in Part 63 was to have someone else solve the spilling problem for me.

The big omissions in this compiler are: poor register management and next to no optimisation. I got the code to the self-compiling stage and then stopped as I was happy to end things there.