I've been researching register allocation and was wondering why they all built graphs from the live registers list when there could be a better way to do it. The way I think they could do it is when the live registers crosses the number of registers available, then registers could be spilled. Here is an example (pseudo-assembly):
## ldi: load immediate
## addr: add registers and store in arg 2
## store: store memory at offset from stack pointer
.text
main:
# live registers: {}
ldi %t0, 12 # t0 = 12
# live registers: {t0}
ldi %t1, 8 # t1 = 8
# live registers: {t0, t1}
addr %t0, %t1 # t1 = t0 + t1
# live registers: {t1}
store -4(%sp), %t1 # -4(%sp) = t1
# live registers: {}
exit
I have laid out the live registers in the assembly code. Now, all the tutorials and texts construct interference graphs from here, etc. But instead of that (as I mentioned above), they could look at the alive registers. For example if this was a one 1 register machine, then when the live registers are {t0, t1}, we will have to choose a register to spill. I feel this is much simpler than constructing a graph and doing all the other stuff to check if we have to spill registers. I know ignorance is not global (somebody must have thought of this and deemed it not fit), so what am I not seeing here?