From b3644ec7fc44464da0a84e3a257ac9301a2f8199 Mon Sep 17 00:00:00 2001 From: Michael McLoughlin Date: Mon, 24 Dec 2018 12:48:29 -0800 Subject: [PATCH] pass: tweak ordering in liveness analysis Previously we updated the set of live in registers before live out. This was extremely inefficient, since on each pass through live in depends on live out. We also change to processing the instructions in reverse order, which is more likely to be efficient, although we should replace this with topological sort order soon. --- pass/reg.go | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/pass/reg.go b/pass/reg.go index 853fa6e..e7162e6 100644 --- a/pass/reg.go +++ b/pass/reg.go @@ -15,9 +15,15 @@ func Liveness(fn *avo.Function) error { is := fn.Instructions() - // Initialize to empty sets. + // Process instructions in reverse: poor approximation to topological sort. + // TODO(mbm): process instructions in topological sort order + for l, r := 0, len(is)-1; l < r; l, r = l+1, r-1 { + is[l], is[r] = is[r], is[l] + } + + // Initialize. for _, i := range is { - i.LiveIn = reg.NewEmptySet() + i.LiveIn = reg.NewSetFromSlice(i.InputRegisters()) i.LiveOut = reg.NewEmptySet() } @@ -26,15 +32,6 @@ func Liveness(fn *avo.Function) error { changes := false for _, i := range is { - // in[n] = use[n] UNION (out[n] - def[n]) - nin := len(i.LiveIn) - i.LiveIn.Update(reg.NewSetFromSlice(i.InputRegisters())) - def := reg.NewSetFromSlice(i.OutputRegisters()) - i.LiveIn.Update(i.LiveOut.Difference(def)) - 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 { @@ -46,6 +43,19 @@ func Liveness(fn *avo.Function) error { if len(i.LiveOut) != nout { changes = true } + + // in[n] = use[n] UNION (out[n] - def[n]) + nin := len(i.LiveIn) + def := reg.NewSetFromSlice(i.OutputRegisters()) + i.LiveIn.Update(i.LiveOut.Difference(def)) + for r := range i.LiveOut { + if _, found := def[r]; !found { + i.LiveIn.Add(r) + } + } + if len(i.LiveIn) != nin { + changes = true + } } if !changes {