Files
avo/pass/reg.go

63 lines
1.1 KiB
Go
Raw Normal View History

2018-12-02 23:59:29 -08:00
package pass
import (
"github.com/mmcloughlin/avo"
"github.com/mmcloughlin/avo/reg"
)
// Liveness computes register liveness.
func Liveness(fn *avo.Function) error {
is := fn.Instructions()
// Initialize to empty sets.
for _, i := range is {
i.LiveIn = map[reg.ID]bool{}
i.LiveOut = map[reg.ID]bool{}
}
// Iterative dataflow analysis.
for {
changes := false
for _, i := range is {
// in[n] = use[n] UNION (out[n] - def[n])
nin := len(i.LiveIn)
for _, r := range i.InputRegisters() {
i.LiveIn[r.ID()] = true
}
def := map[reg.ID]bool{}
for _, r := range i.OutputRegisters() {
def[r.ID()] = true
}
for id := range i.LiveOut {
if !def[id] {
i.LiveIn[id] = true
}
}
if len(i.LiveIn) != nin {
changes = true
}
// out[n] = UNION[s IN succ[n]] in[s]
nout := len(i.LiveOut)
for _, s := range i.Succ {
if s == nil {
continue
}
for id := range s.LiveIn {
i.LiveOut[id] = true
}
}
if len(i.LiveOut) != nout {
changes = true
}
}
if !changes {
break
}
}
return nil
}