]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: avoid implicit bounds checks after explicit checks for append
authorMartin Möhrmann <moehrmann@google.com>
Fri, 15 Jun 2018 23:22:07 +0000 (01:22 +0200)
committerMartin Möhrmann <moehrmann@google.com>
Mon, 15 Oct 2018 18:23:03 +0000 (18:23 +0000)
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>
src/cmd/compile/internal/gc/ssa.go
src/cmd/compile/internal/gc/walk.go

index 4a4461948c9a820847976390eee5f7715bc341ef..ca1c7df9a0ff78c5eade77364cb6a1688c162ba1 100644 (file)
@@ -2332,7 +2332,7 @@ func (s *state) expr(n *Node) *ssa.Value {
                if max != nil {
                        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)
 
        case OSLICESTR:
@@ -2345,7 +2345,7 @@ func (s *state) expr(n *Node) *ssa.Value {
                if high != nil {
                        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)
 
        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.
 // 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.
-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 ptrtype *types.Type
        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
        }
 
-       // Panic if slice indices are not in bounds.
-       s.sliceBoundsCheck(i, j)
-       if j != k {
-               s.sliceBoundsCheck(j, k)
-       }
-       if k != cap {
-               s.sliceBoundsCheck(k, cap)
+       if !bounded {
+               // Panic if slice indices are not in bounds.
+               s.sliceBoundsCheck(i, j)
+               if j != k {
+                       s.sliceBoundsCheck(j, k)
+               }
+               if k != cap {
+                       s.sliceBoundsCheck(k, cap)
+               }
        }
 
        // Generate the following code assuming that indexes are in bounds.
index f7676310e9cf6e8386055dcaf3f3e46e5ce23900..9868a33ba9c338ee3f5838033a532c75ee6c36e2 100644 (file)
@@ -2818,6 +2818,7 @@ func appendslice(n *Node, init *Nodes) *Node {
        // s = s[:n]
        nt := nod(OSLICE, s, nil)
        nt.SetSliceBounds(nil, nn, nil)
+       nt.SetBounded(true)
        nodes.Append(nod(OAS, s, nt))
 
        var ncopy *Node
@@ -2987,6 +2988,7 @@ func extendslice(n *Node, init *Nodes) *Node {
        // s = s[:n]
        nt := nod(OSLICE, s, nil)
        nt.SetSliceBounds(nil, nn, nil)
+       nt.SetBounded(true)
        nodes = append(nodes, nod(OAS, s, nt))
 
        // 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.SetSliceBounds(nil, nod(OADD, nn, na), nil)
+       nx.SetBounded(true)
        l = append(l, nod(OAS, ns, nx)) // s = s[:n+argc]
 
        ls = n.List.Slice()[1:]