]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile/ssa: generate less garbage in schedule
authorJosh Bleecher Snyder <josharian@gmail.com>
Fri, 25 Mar 2016 14:33:39 +0000 (07:33 -0700)
committerJosh Bleecher Snyder <josharian@gmail.com>
Fri, 25 Mar 2016 15:41:10 +0000 (15:41 +0000)
Passes toolstash -cmp.

name       old alloc/op    new alloc/op    delta
Template      58.5MB ± 0%     57.8MB ± 0%  -1.15%        (p=0.000 n=10+10)
Unicode       41.3MB ± 0%     41.2MB ± 0%  -0.17%        (p=0.000 n=10+10)
GoTypes        196MB ± 0%      193MB ± 0%  -1.26%        (p=0.000 n=10+10)
Compiler       863MB ± 0%      850MB ± 0%  -1.49%        (p=0.000 n=10+10)

name       old allocs/op   new allocs/op   delta
Template        522k ± 0%       507k ± 0%  -2.99%        (p=0.000 n=10+10)
Unicode         403k ± 0%       401k ± 0%  -0.42%        (p=0.000 n=10+10)
GoTypes        1.58M ± 0%      1.52M ± 0%  -3.61%        (p=0.000 n=10+10)
Compiler       6.47M ± 0%      6.17M ± 0%  -4.62%        (p=0.000 n=10+10)

Change-Id: Ia7a6242e8d226b41966c344d253814dcce6424a8
Reviewed-on: https://go-review.googlesource.com/21141
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
src/cmd/compile/internal/ssa/schedule.go

index 8124823040177be151df648b1292f9e39479ede7..765f0c1277363d0c2c5f890c2234c5f6b2c5401b 100644 (file)
@@ -16,8 +16,8 @@ const (
 )
 
 type ValHeap struct {
-       a    []*Value
-       less func(a, b *Value) bool
+       a     []*Value
+       score []int8
 }
 
 func (h ValHeap) Len() int      { return len(h.a) }
@@ -36,7 +36,24 @@ func (h *ValHeap) Pop() interface{} {
        h.a = old[0 : n-1]
        return x
 }
-func (h ValHeap) Less(i, j int) bool { return h.less(h.a[i], h.a[j]) }
+func (h ValHeap) Less(i, j int) bool {
+       x := h.a[i]
+       y := h.a[j]
+       sx := h.score[x.ID]
+       sy := h.score[y.ID]
+       if c := sx - sy; c != 0 {
+               return c > 0 // higher score comes later.
+       }
+       if x.Line != y.Line { // Favor in-order line stepping
+               return x.Line > y.Line
+       }
+       if x.Op != OpPhi {
+               if c := len(x.Args) - len(y.Args); c != 0 {
+                       return c < 0 // smaller args comes later
+               }
+       }
+       return x.ID > y.ID
+}
 
 // Schedule the Values in each Block. After this phase returns, the
 // order of b.Values matters and is the order in which those values
@@ -48,6 +65,9 @@ func schedule(f *Func) {
        // by values that have not been scheduled yet.
        uses := make([]int32, f.NumValues())
 
+       // reusable priority queue
+       priq := new(ValHeap)
+
        // "priority" for a value
        score := make([]int8, f.NumValues())
 
@@ -156,25 +176,8 @@ func schedule(f *Func) {
 
                // To put things into a priority queue
                // The values that should come last are least.
-               priq := &ValHeap{
-                       a: make([]*Value, 0, 8), // TODO allocate once and reuse.
-                       less: func(x, y *Value) bool {
-                               sx := score[x.ID]
-                               sy := score[y.ID]
-                               if c := sx - sy; c != 0 {
-                                       return c > 0 // higher score comes later.
-                               }
-                               if x.Line != y.Line { // Favor in-order line stepping
-                                       return x.Line > y.Line
-                               }
-                               if x.Op != OpPhi {
-                                       if c := len(x.Args) - len(y.Args); c != 0 {
-                                               return c < 0 // smaller args comes later
-                                       }
-                               }
-                               return x.ID > y.ID
-                       },
-               }
+               priq.score = score
+               priq.a = priq.a[:0]
 
                // Initialize priority queue with schedulable values.
                for _, v := range b.Values {