Commit d6dbf3a0 authored by Josh Bleecher Snyder's avatar Josh Bleecher Snyder

cmd/compile: use List instead of OKEY for OSLICE*

Performance changes are negligible, but that's expected.
This is a part of a general effort to eliminate OKEY nodes.

Passes toolstash -cmp.

Updates #15350

name       old alloc/op     new alloc/op     delta
Template       40.6MB ± 0%      40.6MB ± 0%  -0.04%         (p=0.000 n=9+10)
Unicode        33.4MB ± 0%      33.4MB ± 0%    ~           (p=0.853 n=10+10)
GoTypes         120MB ± 0%       120MB ± 0%  -0.03%         (p=0.000 n=9+10)
Compiler        470MB ± 0%       469MB ± 0%  -0.06%        (p=0.000 n=10+10)

name       old allocs/op    new allocs/op    delta
Template         404k ± 0%        404k ± 0%    ~           (p=0.165 n=10+10)
Unicode          350k ± 0%        350k ± 0%    ~            (p=0.211 n=9+10)
GoTypes         1.21M ± 0%       1.21M ± 0%    ~           (p=0.315 n=10+10)
Compiler        4.35M ± 0%       4.35M ± 0%  -0.03%        (p=0.001 n=10+10)

Change-Id: I17d547bf9568b1ee2514a7ffab930424617f995e
Reviewed-on: https://go-review.googlesource.com/32213
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarMatthew Dempsky <mdempsky@google.com>
parent 461adfd8
...@@ -248,9 +248,15 @@ func ishairy(n *Node, budget *int32, reason *string) bool { ...@@ -248,9 +248,15 @@ func ishairy(n *Node, budget *int32, reason *string) bool {
} }
(*budget)-- (*budget)--
// TODO(mdempsky): Hack to appease toolstash; remove. // TODO(mdempsky/josharian): Hacks to appease toolstash; remove.
if n.Op == OSTRUCTKEY { // See issue 17566 and CL 31674 for discussion.
switch n.Op {
case OSTRUCTKEY:
(*budget)--
case OSLICE, OSLICEARR, OSLICESTR:
(*budget)-- (*budget)--
case OSLICE3, OSLICE3ARR:
*budget -= 2
} }
return *budget < 0 || ishairy(n.Left, budget, reason) || ishairy(n.Right, budget, reason) || return *budget < 0 || ishairy(n.Left, budget, reason) || ishairy(n.Right, budget, reason) ||
...@@ -428,7 +434,7 @@ func inlnode(n *Node) *Node { ...@@ -428,7 +434,7 @@ func inlnode(n *Node) *Node {
default: default:
s := n.List.Slice() s := n.List.Slice()
for i1, n1 := range s { for i1, n1 := range s {
if n1.Op == OINLCALL { if n1 != nil && n1.Op == OINLCALL {
s[i1] = inlconv2expr(s[i1]) s[i1] = inlconv2expr(s[i1])
} }
} }
......
...@@ -1020,20 +1020,17 @@ func (n *Node) IsMethod() bool { ...@@ -1020,20 +1020,17 @@ func (n *Node) IsMethod() bool {
// SliceBounds returns n's slice bounds: low, high, and max in expr[low:high:max]. // SliceBounds returns n's slice bounds: low, high, and max in expr[low:high:max].
// n must be a slice expression. max is nil if n is a simple slice expression. // n must be a slice expression. max is nil if n is a simple slice expression.
func (n *Node) SliceBounds() (low, high, max *Node) { func (n *Node) SliceBounds() (low, high, max *Node) {
if n.List.Len() == 0 {
return nil, nil, nil
}
switch n.Op { switch n.Op {
case OSLICE, OSLICEARR, OSLICESTR: case OSLICE, OSLICEARR, OSLICESTR:
if n.Right == nil { s := n.List.Slice()
return nil, nil, nil return s[0], s[1], nil
}
if n.Right.Op != OKEY {
Fatalf("SliceBounds right %s", opnames[n.Right.Op])
}
return n.Right.Left, n.Right.Right, nil
case OSLICE3, OSLICE3ARR: case OSLICE3, OSLICE3ARR:
if n.Right.Op != OKEY || n.Right.Right.Op != OKEY { s := n.List.Slice()
Fatalf("SliceBounds right %s %s", opnames[n.Right.Op], opnames[n.Right.Right.Op]) return s[0], s[1], s[2]
}
return n.Right.Left, n.Right.Right.Left, n.Right.Right.Right
} }
Fatalf("SliceBounds op %v: %v", n.Op, n) Fatalf("SliceBounds op %v: %v", n.Op, n)
return nil, nil, nil return nil, nil, nil
...@@ -1047,20 +1044,29 @@ func (n *Node) SetSliceBounds(low, high, max *Node) { ...@@ -1047,20 +1044,29 @@ func (n *Node) SetSliceBounds(low, high, max *Node) {
if max != nil { if max != nil {
Fatalf("SetSliceBounds %v given three bounds", n.Op) Fatalf("SetSliceBounds %v given three bounds", n.Op)
} }
if n.Right == nil { s := n.List.Slice()
n.Right = nod(OKEY, low, high) if s == nil {
if low == nil && high == nil {
return
}
n.List.Set([]*Node{low, high})
return return
} }
n.Right.Left = low s[0] = low
n.Right.Right = high s[1] = high
return return
case OSLICE3, OSLICE3ARR: case OSLICE3, OSLICE3ARR:
if n.Right == nil { s := n.List.Slice()
n.Right = nod(OKEY, low, nod(OKEY, high, max)) if s == nil {
if low == nil && high == nil && max == nil {
return
}
n.List.Set([]*Node{low, high, max})
return
} }
n.Right.Left = low s[0] = low
n.Right.Right.Left = high s[1] = high
n.Right.Right.Right = max s[2] = max
return return
} }
Fatalf("SetSliceBounds op %v: %v", n.Op, n) Fatalf("SetSliceBounds op %v: %v", n.Op, n)
......
...@@ -409,11 +409,11 @@ const ( ...@@ -409,11 +409,11 @@ const (
OPRINTN // println(List) OPRINTN // println(List)
OPAREN // (Left) OPAREN // (Left)
OSEND // Left <- Right OSEND // Left <- Right
OSLICE // Left[Right.Left : Right.Right] (Left is untypechecked or slice; Right.Op==OKEY) OSLICE // Left[List[0] : List[1]] (Left is untypechecked or slice)
OSLICEARR // Left[Right.Left : Right.Right] (Left is array) OSLICEARR // Left[List[0] : List[1]] (Left is array)
OSLICESTR // Left[Right.Left : Right.Right] (Left is string) OSLICESTR // Left[List[0] : List[1]] (Left is string)
OSLICE3 // Left[R.Left : R.R.Left : R.R.R] (R=Right; Left is untypedchecked or slice; R.Op and R.R.Op==OKEY) OSLICE3 // Left[List[0] : List[1] : List[2]] (Left is untypedchecked or slice)
OSLICE3ARR // Left[R.Left : R.R.Left : R.R.R] (R=Right; Left is array; R.Op and R.R.Op==OKEY) OSLICE3ARR // Left[List[0] : List[1] : List[2]] (Left is array)
ORECOVER // recover() ORECOVER // recover()
ORECV // <-Left ORECV // <-Left
ORUNESTR // Type(Left) (Type is string, Left is rune) ORUNESTR // Type(Left) (Type is string, Left is rune)
......
...@@ -3866,6 +3866,9 @@ func markbreaklist(l Nodes, implicit *Node) { ...@@ -3866,6 +3866,9 @@ func markbreaklist(l Nodes, implicit *Node) {
s := l.Slice() s := l.Slice()
for i := 0; i < len(s); i++ { for i := 0; i < len(s); i++ {
n := s[i] n := s[i]
if n == nil {
continue
}
if n.Op == OLABEL && i+1 < len(s) && n.Name.Defn == s[i+1] { if n.Op == OLABEL && i+1 < len(s) && n.Name.Defn == s[i+1] {
switch n.Name.Defn.Op { switch n.Name.Defn.Op {
case OFOR, OSWITCH, OTYPESW, OSELECT, ORANGE: case OFOR, OSWITCH, OTYPESW, OSELECT, ORANGE:
......
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