1
0
mirror of https://github.com/golang/go synced 2024-11-17 00:54:49 -07:00

cmd/compile: avoid implicit bounds checks after explicit checks for append

The generated code for the append builtin already checks if the appended
to slice is large enough and calls growslice if that is not the case.
Trust that this ensures the slice is large enough and avoid the
implicit bounds check when slicing the slice to its new size.

Removes 365 panicslice calls (-14%) from the go binary which
reduces the binary size by ~12kbyte.

Change-Id: I1b88418675ff409bc0b956853c9e95241274d5a6
Reviewed-on: https://go-review.googlesource.com/c/119315
Run-TryBot: Martin Möhrmann <moehrmann@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
Martin Möhrmann 2018-06-16 01:22:07 +02:00
parent c9130cae9a
commit 9f66b41bee
2 changed files with 15 additions and 10 deletions

View File

@ -2332,7 +2332,7 @@ func (s *state) expr(n *Node) *ssa.Value {
if max != nil { if max != nil {
k = s.extendIndex(s.expr(max), panicslice) k = s.extendIndex(s.expr(max), panicslice)
} }
p, l, c := s.slice(n.Left.Type, v, i, j, k) p, l, c := s.slice(n.Left.Type, v, i, j, k, n.Bounded())
return s.newValue3(ssa.OpSliceMake, n.Type, p, l, c) return s.newValue3(ssa.OpSliceMake, n.Type, p, l, c)
case OSLICESTR: case OSLICESTR:
@ -2345,7 +2345,7 @@ func (s *state) expr(n *Node) *ssa.Value {
if high != nil { if high != nil {
j = s.extendIndex(s.expr(high), panicslice) j = s.extendIndex(s.expr(high), panicslice)
} }
p, l, _ := s.slice(n.Left.Type, v, i, j, nil) p, l, _ := s.slice(n.Left.Type, v, i, j, nil, n.Bounded())
return s.newValue2(ssa.OpStringMake, n.Type, p, l) return s.newValue2(ssa.OpStringMake, n.Type, p, l)
case OCALLFUNC: case OCALLFUNC:
@ -4175,7 +4175,7 @@ func (s *state) storeTypePtrs(t *types.Type, left, right *ssa.Value) {
// slice computes the slice v[i:j:k] and returns ptr, len, and cap of result. // slice computes the slice v[i:j:k] and returns ptr, len, and cap of result.
// i,j,k may be nil, in which case they are set to their default value. // i,j,k may be nil, in which case they are set to their default value.
// t is a slice, ptr to array, or string type. // t is a slice, ptr to array, or string type.
func (s *state) slice(t *types.Type, v, i, j, k *ssa.Value) (p, l, c *ssa.Value) { func (s *state) slice(t *types.Type, v, i, j, k *ssa.Value, bounded bool) (p, l, c *ssa.Value) {
var elemtype *types.Type var elemtype *types.Type
var ptrtype *types.Type var ptrtype *types.Type
var ptr *ssa.Value var ptr *ssa.Value
@ -4220,13 +4220,15 @@ func (s *state) slice(t *types.Type, v, i, j, k *ssa.Value) (p, l, c *ssa.Value)
k = cap k = cap
} }
// Panic if slice indices are not in bounds. if !bounded {
s.sliceBoundsCheck(i, j) // Panic if slice indices are not in bounds.
if j != k { s.sliceBoundsCheck(i, j)
s.sliceBoundsCheck(j, k) if j != k {
} s.sliceBoundsCheck(j, k)
if k != cap { }
s.sliceBoundsCheck(k, cap) if k != cap {
s.sliceBoundsCheck(k, cap)
}
} }
// Generate the following code assuming that indexes are in bounds. // Generate the following code assuming that indexes are in bounds.

View File

@ -2818,6 +2818,7 @@ func appendslice(n *Node, init *Nodes) *Node {
// s = s[:n] // s = s[:n]
nt := nod(OSLICE, s, nil) nt := nod(OSLICE, s, nil)
nt.SetSliceBounds(nil, nn, nil) nt.SetSliceBounds(nil, nn, nil)
nt.SetBounded(true)
nodes.Append(nod(OAS, s, nt)) nodes.Append(nod(OAS, s, nt))
var ncopy *Node var ncopy *Node
@ -2987,6 +2988,7 @@ func extendslice(n *Node, init *Nodes) *Node {
// s = s[:n] // s = s[:n]
nt := nod(OSLICE, s, nil) nt := nod(OSLICE, s, nil)
nt.SetSliceBounds(nil, nn, nil) nt.SetSliceBounds(nil, nn, nil)
nt.SetBounded(true)
nodes = append(nodes, nod(OAS, s, nt)) nodes = append(nodes, nod(OAS, s, nt))
// lptr := &l1[0] // lptr := &l1[0]
@ -3109,6 +3111,7 @@ func walkappend(n *Node, init *Nodes, dst *Node) *Node {
nx = nod(OSLICE, ns, nil) // ...s[:n+argc] nx = nod(OSLICE, ns, nil) // ...s[:n+argc]
nx.SetSliceBounds(nil, nod(OADD, nn, na), nil) nx.SetSliceBounds(nil, nod(OADD, nn, na), nil)
nx.SetBounded(true)
l = append(l, nod(OAS, ns, nx)) // s = s[:n+argc] l = append(l, nod(OAS, ns, nx)) // s = s[:n+argc]
ls = n.List.Slice()[1:] ls = n.List.Slice()[1:]