Something went wrong. Try again.
🌱 A minimal programming language and compiler. git.urbach.dev/cli/q
high-performance programming-language compiler
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071package optimizer
import ( "slices"
"git.urbach.dev/cli/q/src/ssa")
// ReorderBlocks moves rarely taken branch bodies to the end of the function.func ReorderBlocks(ir *ssa.IR) { blocks := ir.Blocks
for i := 0; i < len(blocks)-1; i++ { if blocks[i].Loop != nil { continue }
branch, isBranch := blocks[i].Last().(*ssa.Branch)
if !isBranch { continue }
rare := blocks[i+1]
if !isRareBody(blocks[i], rare) { continue }
normal := branch.Then
if rare == normal { normal = branch.Else }
end := -1
for j := i + 1; j < len(blocks); j++ { if blocks[j] == normal { end = j break } }
if end == -1 { continue }
rareRun := slices.Clone(blocks[i+1 : end]) blocks = append(blocks[:i+1], blocks[end:]...) blocks = append(blocks, rareRun...) }
ir.Blocks = blocks}
// isRareBody checks if the body can only be reached from the given block.func isRareBody(block *ssa.Block, body *ssa.Block) bool { if len(body.Predecessors) != 1 || body.Predecessors[0] != block { return false }
switch last := body.Last().(type) { case *ssa.Call: return last.Func.Typ.NoReturn case *ssa.Jump, *ssa.Return: return true default: return false }}