mirror of
https://github.com/golang/go
synced 2024-11-26 17:56:55 -07:00
cmd/compile: refactor memclrrange for arrays and slices
Rename memclrrange to signify that it does not handle all types of range clears. Simplify checks to detect the range clear idiom for arrays and slices. Add tests to verify the optimization for the slice range clear idiom is being applied by the compiler. Change-Id: I5c3b7c9a479699ebdb4c407fde692f30f377860c Reviewed-on: https://go-review.googlesource.com/110477 Run-TryBot: Martin Möhrmann <moehrmann@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
parent
eec8fb5ef3
commit
500d79c410
@ -204,7 +204,7 @@ func walkrange(n *Node) *Node {
|
||||
Fatalf("walkrange")
|
||||
|
||||
case TARRAY, TSLICE:
|
||||
if memclrrange(n, v1, v2, a) {
|
||||
if arrayClear(n, v1, v2, a) {
|
||||
lineno = lno
|
||||
return n
|
||||
}
|
||||
@ -460,23 +460,28 @@ func walkrange(n *Node) *Node {
|
||||
// in which the evaluation of a is side-effect-free.
|
||||
//
|
||||
// Parameters are as in walkrange: "for v1, v2 = range a".
|
||||
func memclrrange(n, v1, v2, a *Node) bool {
|
||||
func arrayClear(n, v1, v2, a *Node) bool {
|
||||
if Debug['N'] != 0 || instrumenting {
|
||||
return false
|
||||
}
|
||||
|
||||
if v1 == nil || v2 != nil {
|
||||
return false
|
||||
}
|
||||
if n.Nbody.Len() == 0 || n.Nbody.First() == nil || n.Nbody.Len() > 1 {
|
||||
|
||||
if n.Nbody.Len() != 1 || n.Nbody.First() == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
stmt := n.Nbody.First() // only stmt in body
|
||||
if stmt.Op != OAS || stmt.Left.Op != OINDEX {
|
||||
return false
|
||||
}
|
||||
|
||||
if !samesafeexpr(stmt.Left.Left, a) || !samesafeexpr(stmt.Left.Right, v1) {
|
||||
return false
|
||||
}
|
||||
|
||||
elemsize := n.Type.Elem().Width
|
||||
if elemsize <= 0 || !isZero(stmt.Right) {
|
||||
return false
|
||||
|
32
test/codegen/slices.go
Normal file
32
test/codegen/slices.go
Normal file
@ -0,0 +1,32 @@
|
||||
// asmcheck
|
||||
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package codegen
|
||||
|
||||
// This file contains code generation tests related to the handling of
|
||||
// slice types.
|
||||
|
||||
// ------------------ //
|
||||
// Clear //
|
||||
// ------------------ //
|
||||
|
||||
// Issue #5373 optimize memset idiom
|
||||
|
||||
func SliceClear(s []int) []int {
|
||||
// amd64:`.*memclrNoHeapPointers`
|
||||
for i := range s {
|
||||
s[i] = 0
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func SliceClearPointers(s []*int) []*int {
|
||||
// amd64:`.*memclrHasPointers`
|
||||
for i := range s {
|
||||
s[i] = nil
|
||||
}
|
||||
return s
|
||||
}
|
Loading…
Reference in New Issue
Block a user