]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.ssa] cmd/compile: speed up liveness analysis
authorJosh Bleecher Snyder <josharian@gmail.com>
Thu, 23 Jul 2015 03:40:18 +0000 (20:40 -0700)
committerJosh Bleecher Snyder <josharian@gmail.com>
Thu, 23 Jul 2015 17:27:08 +0000 (17:27 +0000)
This reduces the wall time to run test/slice3.go
on my laptop from >10m to ~20s.

This could perhaps be further reduced by using
a worklist of blocks and/or implementing the
suggestion in the comment in this CL, but at this
point, it's fast enough that there is no need.

Change-Id: I741119e0c8310051d7185459f78be8b89237b85b
Reviewed-on: https://go-review.googlesource.com/12564
Reviewed-by: Keith Randall <khr@golang.org>
src/cmd/compile/internal/ssa/regalloc.go

index 27e4f754d1f702a7c17c9ff4179c3def7de1dc7b..f46fe25be4e792f3dd7424401e8ac0496355450e 100644 (file)
@@ -419,13 +419,24 @@ func live(f *Func) [][]ID {
 
        s := newSparseSet(f.NumValues())
        t := newSparseSet(f.NumValues())
+
+       // Instead of iterating over f.Blocks, iterate over their postordering.
+       // Liveness information flows backward, so starting at the end
+       // increases the probability that we will stabilize quickly.
+       // TODO: Do a better job yet. Here's one possibility:
+       // Calculate the dominator tree and locate all strongly connected components.
+       // If a value is live in one block of an SCC, it is live in all.
+       // Walk the dominator tree from end to beginning, just once, treating SCC
+       // components as single blocks, duplicated calculated liveness information
+       // out to all of them.
+       po := postorder(f)
        for {
-               for _, b := range f.Blocks {
+               for _, b := range po {
                        f.Logf("live %s %v\n", b, live[b.ID])
                }
                changed := false
 
-               for _, b := range f.Blocks {
+               for _, b := range po {
                        // Start with known live values at the end of the block
                        s.clear()
                        s.addAll(live[b.ID])