Commit bad5abf6 authored by Marvin Stenger's avatar Marvin Stenger Committed by Daniel Martí

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 <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: 's avatarCherry Zhang <cherryyz@google.com>
parent d8efa0e0
......@@ -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++
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment