From bad5abf64d76f9c302c084c5f62e6f70920d3c81 Mon Sep 17 00:00:00 2001 From: Marvin Stenger Date: Sat, 23 Sep 2017 01:20:12 +0200 Subject: [PATCH] cmd/compile: avoid copying in nilcheckelim2 nilcheckelim2 cleans up by copying b.Values in a loop, omitting OpUnknowns. However, the common case is that there are no OpUnknowns, in which case we can skip a lot of work. So we track the first nilcheck which was eliminated, if any, and only start copying from there. If no nilcheck was eliminated we won't copy at all. Fixes #20964 Change-Id: Icd44194cf8ac81ce6485ce257b4d33e093003a40 Reviewed-on: https://go-review.googlesource.com/65651 Run-TryBot: Cherry Zhang TryBot-Result: Gobot Gobot Reviewed-by: Cherry Zhang --- src/cmd/compile/internal/ssa/nilcheck.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/cmd/compile/internal/ssa/nilcheck.go b/src/cmd/compile/internal/ssa/nilcheck.go index f8c7a5019c..1f789df2a8 100644 --- a/src/cmd/compile/internal/ssa/nilcheck.go +++ b/src/cmd/compile/internal/ssa/nilcheck.go @@ -168,6 +168,8 @@ func nilcheckelim2(f *Func) { // input pointer is nil. Remove nil checks on those pointers, as the // faulting instruction effectively does the nil check for free. unnecessary.clear() + // Optimization: keep track of removed nilckeck with smallest index + firstToRemove := len(b.Values) for i := len(b.Values) - 1; i >= 0; i-- { v := b.Values[i] if opcodeTable[v.Op].nilCheck && unnecessary.contains(v.Args[0].ID) { @@ -175,6 +177,7 @@ func nilcheckelim2(f *Func) { f.Warnl(v.Pos, "removed nil check") } v.reset(OpUnknown) + firstToRemove = i continue } if v.Type.IsMemory() || v.Type.IsTuple() && v.Type.FieldType(1).IsMemory() { @@ -224,8 +227,9 @@ func nilcheckelim2(f *Func) { } } // Remove values we've clobbered with OpUnknown. - i := 0 - for _, v := range b.Values { + i := firstToRemove + for j := i; j < len(b.Values); j++ { + v := b.Values[j] if v.Op != OpUnknown { b.Values[i] = v i++ -- 2.48.1