]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: use a counter to track whether writebarrier rewriting is done
authorCherry Zhang <cherryyz@google.com>
Wed, 30 Aug 2017 15:12:52 +0000 (11:12 -0400)
committerCherry Zhang <cherryyz@google.com>
Wed, 20 Sep 2017 23:57:19 +0000 (23:57 +0000)
Use a counter, instead of a loop, to see whether there are more
writebarrier ops in the current block that need to be rewritten.

No visible change in normal compiler speed benchmarks.

Passes toolstash -cmp on std cmd.

Fixes #20416.

Change-Id: Ifbbde23611cd668c35b8a4a3e9a92726bfe19956
Reviewed-on: https://go-review.googlesource.com/60310
Reviewed-by: David Chase <drchase@google.com>
src/cmd/compile/internal/ssa/writebarrier.go

index 032a905abd271caa3ed00ceb86b0487b701c4178..0daff45b4372be656fa4784c2f266a7eaecc0a1c 100644 (file)
@@ -52,7 +52,7 @@ func writebarrier(f *Func) {
        for _, b := range f.Blocks { // range loop is safe since the blocks we added contain no stores to expand
                // first, identify all the stores that need to insert a write barrier.
                // mark them with WB ops temporarily. record presence of WB ops.
-               hasStore := false
+               nWBops := 0 // count of temporarily created WB ops remaining to be rewritten in the current block
                for _, v := range b.Values {
                        switch v.Op {
                        case OpStore, OpMove, OpZero:
@@ -65,11 +65,11 @@ func writebarrier(f *Func) {
                                        case OpZero:
                                                v.Op = OpZeroWB
                                        }
-                                       hasStore = true
+                                       nWBops++
                                }
                        }
                }
-               if !hasStore {
+               if nWBops == 0 {
                        continue
                }
 
@@ -188,13 +188,16 @@ func writebarrier(f *Func) {
                        case OpStoreWB:
                                fn = writebarrierptr
                                val = w.Args[1]
+                               nWBops--
                        case OpMoveWB:
                                fn = typedmemmove
                                val = w.Args[1]
                                typ = w.Aux.(*types.Type).Symbol()
+                               nWBops--
                        case OpZeroWB:
                                fn = typedmemclr
                                typ = w.Aux.(*types.Type).Symbol()
+                               nWBops--
                        case OpVarDef, OpVarLive, OpVarKill:
                        }
 
@@ -261,13 +264,8 @@ func writebarrier(f *Func) {
                }
 
                // if we have more stores in this block, do this block again
-               // check from end to beginning, to avoid quadratic behavior; issue 13554
-               // TODO: track the final value to avoid any looping here at all
-               for i := len(b.Values) - 1; i >= 0; i-- {
-                       switch b.Values[i].Op {
-                       case OpStoreWB, OpMoveWB, OpZeroWB:
-                               goto again
-                       }
+               if nWBops > 0 {
+                       goto again
                }
        }
 }