"Spilling" version of GCM
- Finally implement an intellectually sound and working in practice complete global code motion package, including:
- Placing nodes into ordered basic blocks.
- Best-effort scheduling w/ respect to anti-dependencies.
- Spilling (as in register allocation) based approach for dealing with multiple live values that may represent the same collection at once.
- No longer treat collection constants specially in outlining, have separate pass for moving collection constants upwards (this can take into account device assignments for functions, so for example can avoid floating shared memory collections in GPU functions).
- TODO: bad things happen if we try to run PhiElim after GCM. I think this is fine to paper over, but I would like to understand why this makes things sad.