From 9f66b41beea82cc613cad9138c10a50f2b3ea137 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Martin=20M=C3=B6hrmann?= Date: Sat, 16 Jun 2018 01:22:07 +0200 Subject: [PATCH] cmd/compile: avoid implicit bounds checks after explicit checks for append MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 TryBot-Result: Gobot Gobot Reviewed-by: Keith Randall --- src/cmd/compile/internal/gc/ssa.go | 22 ++++++++++++---------- src/cmd/compile/internal/gc/walk.go | 3 +++ 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/cmd/compile/internal/gc/ssa.go b/src/cmd/compile/internal/gc/ssa.go index 4a4461948c..ca1c7df9a0 100644 --- a/src/cmd/compile/internal/gc/ssa.go +++ b/src/cmd/compile/internal/gc/ssa.go @@ -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. diff --git a/src/cmd/compile/internal/gc/walk.go b/src/cmd/compile/internal/gc/walk.go index f7676310e9..9868a33ba9 100644 --- a/src/cmd/compile/internal/gc/walk.go +++ b/src/cmd/compile/internal/gc/walk.go @@ -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:] -- 2.48.1