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.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475package codegen
import ( "slices"
"git.urbach.dev/cli/q/src/ssa")
// markAlive marks the `live` value in the `block` as alive and recursively// proceeds in the predecessors of `block` if they can reach the definition.func (f *Function) markAlive(live *Step, block *ssa.Block, use *Step, first bool) { if use.Block == block { phi, isPhi := use.Value.(*ssa.Phi)
if isPhi { for index, value := range phi.Arguments { if value == live.Value { f.markAlive(live, block.Predecessors[index], use, false) } }
return } }
region := f.BlockToRegion[block]
if first && use.Block == block && (block.Loop == nil || live.Block.Loop != nil) { region.End = uint32(use.Index) }
var ( steps = f.Steps[region.Start:region.End] field *ssa.Field isField bool )
for _, current := range slices.Backward(steps) { if slices.Contains(current.Live, live) { return }
if isField && field.Tuple == current.Value { return }
current.Live = append(current.Live, live)
if live.Value == current.Value { field, isField = current.Value.(*ssa.Field) _, isParam := current.Value.(*ssa.Parameter) _, isPhi := current.Value.(*ssa.Phi)
if !isParam && !isPhi && !isField { return } } }
for _, pre := range block.Predecessors { if pre == block { continue }
if !pre.CanReachPredecessor(live.Block) { continue }
if f.isDeadAtEnd(live, pre) { continue }
f.markAlive(live, pre, use, false) }}