go/src/cmd/compile/internal/gc/sinit.go

1356 lines
30 KiB
Go
Raw Normal View History

// Copyright 2009 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 gc
import (
"cmd/compile/internal/types"
"fmt"
)
// Static initialization ordering state.
// These values are stored in two bits in Node.flags.
const (
InitNotStarted = iota
InitDone
InitPending
)
type InitEntry struct {
Xoffset int64 // struct, array only
Expr *Node // bytes of run-time computed expressions
}
type InitPlan struct {
E []InitEntry
}
var (
initlist []*Node
initplans map[*Node]*InitPlan
inittemps = make(map[*Node]*Node)
)
// init1 walks the AST starting at n, and accumulates in out
// the list of definitions needing init code in dependency order.
func init1(n *Node, out *[]*Node) {
if n == nil {
return
}
init1(n.Left, out)
init1(n.Right, out)
for _, n1 := range n.List.Slice() {
init1(n1, out)
}
if n.isMethodExpression() {
// Methods called as Type.Method(receiver, ...).
// Definitions for method expressions are stored in type->nname.
init1(asNode(n.Type.FuncType().Nname), out)
}
if n.Op != ONAME {
return
}
cmd/compile: move Node.Class to flags Put it at position zero, since it is fairly hot. This shrinks gc.Node into a smaller size class on 64 bit systems. name old time/op new time/op delta Template 193ms ± 5% 192ms ± 3% ~ (p=0.353 n=94+93) Unicode 86.1ms ± 5% 85.0ms ± 4% -1.23% (p=0.000 n=95+98) GoTypes 546ms ± 3% 544ms ± 4% -0.40% (p=0.007 n=94+97) Compiler 2.56s ± 3% 2.54s ± 3% -0.67% (p=0.000 n=99+97) SSA 5.13s ± 2% 5.10s ± 3% -0.55% (p=0.000 n=94+98) Flate 122ms ± 6% 121ms ± 4% -0.75% (p=0.002 n=97+95) GoParser 144ms ± 5% 144ms ± 4% ~ (p=0.298 n=98+97) Reflect 348ms ± 4% 349ms ± 4% ~ (p=0.350 n=98+97) Tar 105ms ± 5% 104ms ± 5% ~ (p=0.154 n=96+98) XML 200ms ± 5% 198ms ± 4% -0.71% (p=0.015 n=97+98) [Geo mean] 330ms 328ms -0.52% name old user-time/op new user-time/op delta Template 229ms ±11% 224ms ± 7% -2.16% (p=0.001 n=100+87) Unicode 109ms ± 5% 109ms ± 6% ~ (p=0.897 n=96+91) GoTypes 712ms ± 4% 709ms ± 4% ~ (p=0.085 n=96+98) Compiler 3.41s ± 3% 3.36s ± 3% -1.43% (p=0.000 n=98+98) SSA 7.46s ± 3% 7.31s ± 3% -2.02% (p=0.000 n=100+99) Flate 145ms ± 6% 143ms ± 6% -1.11% (p=0.001 n=99+97) GoParser 177ms ± 5% 176ms ± 5% -0.78% (p=0.018 n=95+95) Reflect 432ms ± 7% 435ms ± 9% ~ (p=0.296 n=100+100) Tar 121ms ± 7% 121ms ± 5% ~ (p=0.072 n=100+95) XML 241ms ± 4% 239ms ± 5% ~ (p=0.085 n=97+99) [Geo mean] 413ms 410ms -0.73% name old alloc/op new alloc/op delta Template 38.4MB ± 0% 37.7MB ± 0% -1.85% (p=0.008 n=5+5) Unicode 30.1MB ± 0% 28.8MB ± 0% -4.09% (p=0.008 n=5+5) GoTypes 112MB ± 0% 110MB ± 0% -1.69% (p=0.008 n=5+5) Compiler 470MB ± 0% 461MB ± 0% -1.91% (p=0.008 n=5+5) SSA 1.13GB ± 0% 1.11GB ± 0% -1.70% (p=0.008 n=5+5) Flate 25.0MB ± 0% 24.6MB ± 0% -1.67% (p=0.008 n=5+5) GoParser 31.6MB ± 0% 31.1MB ± 0% -1.66% (p=0.008 n=5+5) Reflect 77.1MB ± 0% 75.8MB ± 0% -1.69% (p=0.008 n=5+5) Tar 26.3MB ± 0% 25.7MB ± 0% -2.06% (p=0.008 n=5+5) XML 41.9MB ± 0% 41.1MB ± 0% -1.93% (p=0.008 n=5+5) [Geo mean] 73.5MB 72.0MB -2.03% name old allocs/op new allocs/op delta Template 383k ± 0% 383k ± 0% ~ (p=0.690 n=5+5) Unicode 343k ± 0% 343k ± 0% ~ (p=0.841 n=5+5) GoTypes 1.16M ± 0% 1.16M ± 0% ~ (p=0.310 n=5+5) Compiler 4.43M ± 0% 4.42M ± 0% -0.17% (p=0.008 n=5+5) SSA 9.85M ± 0% 9.85M ± 0% ~ (p=0.310 n=5+5) Flate 236k ± 0% 236k ± 1% ~ (p=0.841 n=5+5) GoParser 320k ± 0% 320k ± 0% ~ (p=0.421 n=5+5) Reflect 988k ± 0% 987k ± 0% ~ (p=0.690 n=5+5) Tar 252k ± 0% 251k ± 0% ~ (p=0.095 n=5+5) XML 399k ± 0% 399k ± 0% ~ (p=1.000 n=5+5) [Geo mean] 741k 740k -0.07% Change-Id: I9e952b58a98e30a12494304db9ce50d0a85e459c Reviewed-on: https://go-review.googlesource.com/41797 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Marvin Stenger <marvin.stenger94@gmail.com>
2017-04-25 18:14:12 -07:00
switch n.Class() {
case PEXTERN, PFUNC:
default:
if n.isBlank() && n.Name.Curfn == nil && n.Name.Defn != nil && n.Name.Defn.Initorder() == InitNotStarted {
// blank names initialization is part of init() but not
// when they are inside a function.
break
}
return
}
if n.Initorder() == InitDone {
return
}
if n.Initorder() == InitPending {
// Since mutually recursive sets of functions are allowed,
// we don't necessarily raise an error if n depends on a node
// which is already waiting for its dependencies to be visited.
//
// initlist contains a cycle of identifiers referring to each other.
// If this cycle contains a variable, then this variable refers to itself.
// Conversely, if there exists an initialization cycle involving
// a variable in the program, the tree walk will reach a cycle
// involving that variable.
cmd/compile: move Node.Class to flags Put it at position zero, since it is fairly hot. This shrinks gc.Node into a smaller size class on 64 bit systems. name old time/op new time/op delta Template 193ms ± 5% 192ms ± 3% ~ (p=0.353 n=94+93) Unicode 86.1ms ± 5% 85.0ms ± 4% -1.23% (p=0.000 n=95+98) GoTypes 546ms ± 3% 544ms ± 4% -0.40% (p=0.007 n=94+97) Compiler 2.56s ± 3% 2.54s ± 3% -0.67% (p=0.000 n=99+97) SSA 5.13s ± 2% 5.10s ± 3% -0.55% (p=0.000 n=94+98) Flate 122ms ± 6% 121ms ± 4% -0.75% (p=0.002 n=97+95) GoParser 144ms ± 5% 144ms ± 4% ~ (p=0.298 n=98+97) Reflect 348ms ± 4% 349ms ± 4% ~ (p=0.350 n=98+97) Tar 105ms ± 5% 104ms ± 5% ~ (p=0.154 n=96+98) XML 200ms ± 5% 198ms ± 4% -0.71% (p=0.015 n=97+98) [Geo mean] 330ms 328ms -0.52% name old user-time/op new user-time/op delta Template 229ms ±11% 224ms ± 7% -2.16% (p=0.001 n=100+87) Unicode 109ms ± 5% 109ms ± 6% ~ (p=0.897 n=96+91) GoTypes 712ms ± 4% 709ms ± 4% ~ (p=0.085 n=96+98) Compiler 3.41s ± 3% 3.36s ± 3% -1.43% (p=0.000 n=98+98) SSA 7.46s ± 3% 7.31s ± 3% -2.02% (p=0.000 n=100+99) Flate 145ms ± 6% 143ms ± 6% -1.11% (p=0.001 n=99+97) GoParser 177ms ± 5% 176ms ± 5% -0.78% (p=0.018 n=95+95) Reflect 432ms ± 7% 435ms ± 9% ~ (p=0.296 n=100+100) Tar 121ms ± 7% 121ms ± 5% ~ (p=0.072 n=100+95) XML 241ms ± 4% 239ms ± 5% ~ (p=0.085 n=97+99) [Geo mean] 413ms 410ms -0.73% name old alloc/op new alloc/op delta Template 38.4MB ± 0% 37.7MB ± 0% -1.85% (p=0.008 n=5+5) Unicode 30.1MB ± 0% 28.8MB ± 0% -4.09% (p=0.008 n=5+5) GoTypes 112MB ± 0% 110MB ± 0% -1.69% (p=0.008 n=5+5) Compiler 470MB ± 0% 461MB ± 0% -1.91% (p=0.008 n=5+5) SSA 1.13GB ± 0% 1.11GB ± 0% -1.70% (p=0.008 n=5+5) Flate 25.0MB ± 0% 24.6MB ± 0% -1.67% (p=0.008 n=5+5) GoParser 31.6MB ± 0% 31.1MB ± 0% -1.66% (p=0.008 n=5+5) Reflect 77.1MB ± 0% 75.8MB ± 0% -1.69% (p=0.008 n=5+5) Tar 26.3MB ± 0% 25.7MB ± 0% -2.06% (p=0.008 n=5+5) XML 41.9MB ± 0% 41.1MB ± 0% -1.93% (p=0.008 n=5+5) [Geo mean] 73.5MB 72.0MB -2.03% name old allocs/op new allocs/op delta Template 383k ± 0% 383k ± 0% ~ (p=0.690 n=5+5) Unicode 343k ± 0% 343k ± 0% ~ (p=0.841 n=5+5) GoTypes 1.16M ± 0% 1.16M ± 0% ~ (p=0.310 n=5+5) Compiler 4.43M ± 0% 4.42M ± 0% -0.17% (p=0.008 n=5+5) SSA 9.85M ± 0% 9.85M ± 0% ~ (p=0.310 n=5+5) Flate 236k ± 0% 236k ± 1% ~ (p=0.841 n=5+5) GoParser 320k ± 0% 320k ± 0% ~ (p=0.421 n=5+5) Reflect 988k ± 0% 987k ± 0% ~ (p=0.690 n=5+5) Tar 252k ± 0% 251k ± 0% ~ (p=0.095 n=5+5) XML 399k ± 0% 399k ± 0% ~ (p=1.000 n=5+5) [Geo mean] 741k 740k -0.07% Change-Id: I9e952b58a98e30a12494304db9ce50d0a85e459c Reviewed-on: https://go-review.googlesource.com/41797 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Marvin Stenger <marvin.stenger94@gmail.com>
2017-04-25 18:14:12 -07:00
if n.Class() != PFUNC {
foundinitloop(n, n)
}
for i := len(initlist) - 1; i >= 0; i-- {
x := initlist[i]
if x == n {
break
}
cmd/compile: move Node.Class to flags Put it at position zero, since it is fairly hot. This shrinks gc.Node into a smaller size class on 64 bit systems. name old time/op new time/op delta Template 193ms ± 5% 192ms ± 3% ~ (p=0.353 n=94+93) Unicode 86.1ms ± 5% 85.0ms ± 4% -1.23% (p=0.000 n=95+98) GoTypes 546ms ± 3% 544ms ± 4% -0.40% (p=0.007 n=94+97) Compiler 2.56s ± 3% 2.54s ± 3% -0.67% (p=0.000 n=99+97) SSA 5.13s ± 2% 5.10s ± 3% -0.55% (p=0.000 n=94+98) Flate 122ms ± 6% 121ms ± 4% -0.75% (p=0.002 n=97+95) GoParser 144ms ± 5% 144ms ± 4% ~ (p=0.298 n=98+97) Reflect 348ms ± 4% 349ms ± 4% ~ (p=0.350 n=98+97) Tar 105ms ± 5% 104ms ± 5% ~ (p=0.154 n=96+98) XML 200ms ± 5% 198ms ± 4% -0.71% (p=0.015 n=97+98) [Geo mean] 330ms 328ms -0.52% name old user-time/op new user-time/op delta Template 229ms ±11% 224ms ± 7% -2.16% (p=0.001 n=100+87) Unicode 109ms ± 5% 109ms ± 6% ~ (p=0.897 n=96+91) GoTypes 712ms ± 4% 709ms ± 4% ~ (p=0.085 n=96+98) Compiler 3.41s ± 3% 3.36s ± 3% -1.43% (p=0.000 n=98+98) SSA 7.46s ± 3% 7.31s ± 3% -2.02% (p=0.000 n=100+99) Flate 145ms ± 6% 143ms ± 6% -1.11% (p=0.001 n=99+97) GoParser 177ms ± 5% 176ms ± 5% -0.78% (p=0.018 n=95+95) Reflect 432ms ± 7% 435ms ± 9% ~ (p=0.296 n=100+100) Tar 121ms ± 7% 121ms ± 5% ~ (p=0.072 n=100+95) XML 241ms ± 4% 239ms ± 5% ~ (p=0.085 n=97+99) [Geo mean] 413ms 410ms -0.73% name old alloc/op new alloc/op delta Template 38.4MB ± 0% 37.7MB ± 0% -1.85% (p=0.008 n=5+5) Unicode 30.1MB ± 0% 28.8MB ± 0% -4.09% (p=0.008 n=5+5) GoTypes 112MB ± 0% 110MB ± 0% -1.69% (p=0.008 n=5+5) Compiler 470MB ± 0% 461MB ± 0% -1.91% (p=0.008 n=5+5) SSA 1.13GB ± 0% 1.11GB ± 0% -1.70% (p=0.008 n=5+5) Flate 25.0MB ± 0% 24.6MB ± 0% -1.67% (p=0.008 n=5+5) GoParser 31.6MB ± 0% 31.1MB ± 0% -1.66% (p=0.008 n=5+5) Reflect 77.1MB ± 0% 75.8MB ± 0% -1.69% (p=0.008 n=5+5) Tar 26.3MB ± 0% 25.7MB ± 0% -2.06% (p=0.008 n=5+5) XML 41.9MB ± 0% 41.1MB ± 0% -1.93% (p=0.008 n=5+5) [Geo mean] 73.5MB 72.0MB -2.03% name old allocs/op new allocs/op delta Template 383k ± 0% 383k ± 0% ~ (p=0.690 n=5+5) Unicode 343k ± 0% 343k ± 0% ~ (p=0.841 n=5+5) GoTypes 1.16M ± 0% 1.16M ± 0% ~ (p=0.310 n=5+5) Compiler 4.43M ± 0% 4.42M ± 0% -0.17% (p=0.008 n=5+5) SSA 9.85M ± 0% 9.85M ± 0% ~ (p=0.310 n=5+5) Flate 236k ± 0% 236k ± 1% ~ (p=0.841 n=5+5) GoParser 320k ± 0% 320k ± 0% ~ (p=0.421 n=5+5) Reflect 988k ± 0% 987k ± 0% ~ (p=0.690 n=5+5) Tar 252k ± 0% 251k ± 0% ~ (p=0.095 n=5+5) XML 399k ± 0% 399k ± 0% ~ (p=1.000 n=5+5) [Geo mean] 741k 740k -0.07% Change-Id: I9e952b58a98e30a12494304db9ce50d0a85e459c Reviewed-on: https://go-review.googlesource.com/41797 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Marvin Stenger <marvin.stenger94@gmail.com>
2017-04-25 18:14:12 -07:00
if x.Class() != PFUNC {
foundinitloop(n, x)
}
}
// The loop involves only functions, ok.
return
}
// reached a new unvisited node.
n.SetInitorder(InitPending)
initlist = append(initlist, n)
// make sure that everything n depends on is initialized.
// n->defn is an assignment to n
if defn := n.Name.Defn; defn != nil {
switch defn.Op {
default:
Dump("defn", defn)
Fatalf("init1: bad defn")
case ODCLFUNC:
init2list(defn.Nbody, out)
case OAS:
if defn.Left != n {
Dump("defn", defn)
Fatalf("init1: bad defn")
}
if defn.Left.isBlank() && candiscard(defn.Right) {
defn.Op = OEMPTY
defn.Left = nil
defn.Right = nil
break
}
init2(defn.Right, out)
if Debug['j'] != 0 {
fmt.Printf("%v\n", n.Sym)
}
if n.isBlank() || !staticinit(n, out) {
if Debug['%'] != 0 {
Dump("nonstatic", defn)
}
*out = append(*out, defn)
}
case OAS2FUNC, OAS2MAPR, OAS2DOTTYPE, OAS2RECV:
if defn.Initorder() == InitDone {
break
}
defn.SetInitorder(InitPending)
for _, n2 := range defn.Rlist.Slice() {
init1(n2, out)
}
if Debug['%'] != 0 {
Dump("nonstatic", defn)
}
*out = append(*out, defn)
defn.SetInitorder(InitDone)
}
}
last := len(initlist) - 1
if initlist[last] != n {
Fatalf("bad initlist %v", initlist)
}
initlist[last] = nil // allow GC
initlist = initlist[:last]
n.SetInitorder(InitDone)
}
// foundinitloop prints an init loop error and exits.
func foundinitloop(node, visited *Node) {
// If there have already been errors printed,
// those errors probably confused us and
// there might not be a loop. Let the user
// fix those first.
flusherrors()
if nerrors > 0 {
errorexit()
}
// Find the index of node and visited in the initlist.
var nodeindex, visitedindex int
for ; initlist[nodeindex] != node; nodeindex++ {
}
for ; initlist[visitedindex] != visited; visitedindex++ {
}
// There is a loop involving visited. We know about node and
// initlist = n1 <- ... <- visited <- ... <- node <- ...
fmt.Printf("%v: initialization loop:\n", visited.Line())
// Print visited -> ... -> n1 -> node.
for _, n := range initlist[visitedindex:] {
fmt.Printf("\t%v %v refers to\n", n.Line(), n.Sym)
}
// Print node -> ... -> visited.
for _, n := range initlist[nodeindex:visitedindex] {
fmt.Printf("\t%v %v refers to\n", n.Line(), n.Sym)
}
fmt.Printf("\t%v %v\n", visited.Line(), visited.Sym)
errorexit()
}
// recurse over n, doing init1 everywhere.
func init2(n *Node, out *[]*Node) {
if n == nil || n.Initorder() == InitDone {
return
}
if n.Op == ONAME && n.Ninit.Len() != 0 {
Fatalf("name %v with ninit: %+v\n", n.Sym, n)
}
init1(n, out)
init2(n.Left, out)
init2(n.Right, out)
init2list(n.Ninit, out)
init2list(n.List, out)
init2list(n.Rlist, out)
init2list(n.Nbody, out)
switch n.Op {
case OCLOSURE:
init2list(n.Func.Closure.Nbody, out)
case ODOTMETH, OCALLPART:
init2(asNode(n.Type.FuncType().Nname), out)
}
}
func init2list(l Nodes, out *[]*Node) {
for _, n := range l.Slice() {
init2(n, out)
}
}
func initreorder(l []*Node, out *[]*Node) {
for _, n := range l {
switch n.Op {
case ODCLFUNC, ODCLCONST, ODCLTYPE:
continue
}
initreorder(n.Ninit.Slice(), out)
n.Ninit.Set(nil)
init1(n, out)
}
}
// initfix computes initialization order for a list l of top-level
// declarations and outputs the corresponding list of statements
// to include in the init() function body.
func initfix(l []*Node) []*Node {
var lout []*Node
initplans = make(map[*Node]*InitPlan)
lno := lineno
initreorder(l, &lout)
lineno = lno
initplans = nil
return lout
}
// compilation of top-level (static) assignments
// into DATA statements if at all possible.
func staticinit(n *Node, out *[]*Node) bool {
cmd/compile: move Node.Class to flags Put it at position zero, since it is fairly hot. This shrinks gc.Node into a smaller size class on 64 bit systems. name old time/op new time/op delta Template 193ms ± 5% 192ms ± 3% ~ (p=0.353 n=94+93) Unicode 86.1ms ± 5% 85.0ms ± 4% -1.23% (p=0.000 n=95+98) GoTypes 546ms ± 3% 544ms ± 4% -0.40% (p=0.007 n=94+97) Compiler 2.56s ± 3% 2.54s ± 3% -0.67% (p=0.000 n=99+97) SSA 5.13s ± 2% 5.10s ± 3% -0.55% (p=0.000 n=94+98) Flate 122ms ± 6% 121ms ± 4% -0.75% (p=0.002 n=97+95) GoParser 144ms ± 5% 144ms ± 4% ~ (p=0.298 n=98+97) Reflect 348ms ± 4% 349ms ± 4% ~ (p=0.350 n=98+97) Tar 105ms ± 5% 104ms ± 5% ~ (p=0.154 n=96+98) XML 200ms ± 5% 198ms ± 4% -0.71% (p=0.015 n=97+98) [Geo mean] 330ms 328ms -0.52% name old user-time/op new user-time/op delta Template 229ms ±11% 224ms ± 7% -2.16% (p=0.001 n=100+87) Unicode 109ms ± 5% 109ms ± 6% ~ (p=0.897 n=96+91) GoTypes 712ms ± 4% 709ms ± 4% ~ (p=0.085 n=96+98) Compiler 3.41s ± 3% 3.36s ± 3% -1.43% (p=0.000 n=98+98) SSA 7.46s ± 3% 7.31s ± 3% -2.02% (p=0.000 n=100+99) Flate 145ms ± 6% 143ms ± 6% -1.11% (p=0.001 n=99+97) GoParser 177ms ± 5% 176ms ± 5% -0.78% (p=0.018 n=95+95) Reflect 432ms ± 7% 435ms ± 9% ~ (p=0.296 n=100+100) Tar 121ms ± 7% 121ms ± 5% ~ (p=0.072 n=100+95) XML 241ms ± 4% 239ms ± 5% ~ (p=0.085 n=97+99) [Geo mean] 413ms 410ms -0.73% name old alloc/op new alloc/op delta Template 38.4MB ± 0% 37.7MB ± 0% -1.85% (p=0.008 n=5+5) Unicode 30.1MB ± 0% 28.8MB ± 0% -4.09% (p=0.008 n=5+5) GoTypes 112MB ± 0% 110MB ± 0% -1.69% (p=0.008 n=5+5) Compiler 470MB ± 0% 461MB ± 0% -1.91% (p=0.008 n=5+5) SSA 1.13GB ± 0% 1.11GB ± 0% -1.70% (p=0.008 n=5+5) Flate 25.0MB ± 0% 24.6MB ± 0% -1.67% (p=0.008 n=5+5) GoParser 31.6MB ± 0% 31.1MB ± 0% -1.66% (p=0.008 n=5+5) Reflect 77.1MB ± 0% 75.8MB ± 0% -1.69% (p=0.008 n=5+5) Tar 26.3MB ± 0% 25.7MB ± 0% -2.06% (p=0.008 n=5+5) XML 41.9MB ± 0% 41.1MB ± 0% -1.93% (p=0.008 n=5+5) [Geo mean] 73.5MB 72.0MB -2.03% name old allocs/op new allocs/op delta Template 383k ± 0% 383k ± 0% ~ (p=0.690 n=5+5) Unicode 343k ± 0% 343k ± 0% ~ (p=0.841 n=5+5) GoTypes 1.16M ± 0% 1.16M ± 0% ~ (p=0.310 n=5+5) Compiler 4.43M ± 0% 4.42M ± 0% -0.17% (p=0.008 n=5+5) SSA 9.85M ± 0% 9.85M ± 0% ~ (p=0.310 n=5+5) Flate 236k ± 0% 236k ± 1% ~ (p=0.841 n=5+5) GoParser 320k ± 0% 320k ± 0% ~ (p=0.421 n=5+5) Reflect 988k ± 0% 987k ± 0% ~ (p=0.690 n=5+5) Tar 252k ± 0% 251k ± 0% ~ (p=0.095 n=5+5) XML 399k ± 0% 399k ± 0% ~ (p=1.000 n=5+5) [Geo mean] 741k 740k -0.07% Change-Id: I9e952b58a98e30a12494304db9ce50d0a85e459c Reviewed-on: https://go-review.googlesource.com/41797 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Marvin Stenger <marvin.stenger94@gmail.com>
2017-04-25 18:14:12 -07:00
if n.Op != ONAME || n.Class() != PEXTERN || n.Name.Defn == nil || n.Name.Defn.Op != OAS {
Fatalf("staticinit")
}
lineno = n.Pos
l := n.Name.Defn.Left
r := n.Name.Defn.Right
return staticassign(l, r, out)
}
// like staticassign but we are copying an already
// initialized value r.
func staticcopy(l *Node, r *Node, out *[]*Node) bool {
if r.Op != ONAME {
return false
}
cmd/compile: move Node.Class to flags Put it at position zero, since it is fairly hot. This shrinks gc.Node into a smaller size class on 64 bit systems. name old time/op new time/op delta Template 193ms ± 5% 192ms ± 3% ~ (p=0.353 n=94+93) Unicode 86.1ms ± 5% 85.0ms ± 4% -1.23% (p=0.000 n=95+98) GoTypes 546ms ± 3% 544ms ± 4% -0.40% (p=0.007 n=94+97) Compiler 2.56s ± 3% 2.54s ± 3% -0.67% (p=0.000 n=99+97) SSA 5.13s ± 2% 5.10s ± 3% -0.55% (p=0.000 n=94+98) Flate 122ms ± 6% 121ms ± 4% -0.75% (p=0.002 n=97+95) GoParser 144ms ± 5% 144ms ± 4% ~ (p=0.298 n=98+97) Reflect 348ms ± 4% 349ms ± 4% ~ (p=0.350 n=98+97) Tar 105ms ± 5% 104ms ± 5% ~ (p=0.154 n=96+98) XML 200ms ± 5% 198ms ± 4% -0.71% (p=0.015 n=97+98) [Geo mean] 330ms 328ms -0.52% name old user-time/op new user-time/op delta Template 229ms ±11% 224ms ± 7% -2.16% (p=0.001 n=100+87) Unicode 109ms ± 5% 109ms ± 6% ~ (p=0.897 n=96+91) GoTypes 712ms ± 4% 709ms ± 4% ~ (p=0.085 n=96+98) Compiler 3.41s ± 3% 3.36s ± 3% -1.43% (p=0.000 n=98+98) SSA 7.46s ± 3% 7.31s ± 3% -2.02% (p=0.000 n=100+99) Flate 145ms ± 6% 143ms ± 6% -1.11% (p=0.001 n=99+97) GoParser 177ms ± 5% 176ms ± 5% -0.78% (p=0.018 n=95+95) Reflect 432ms ± 7% 435ms ± 9% ~ (p=0.296 n=100+100) Tar 121ms ± 7% 121ms ± 5% ~ (p=0.072 n=100+95) XML 241ms ± 4% 239ms ± 5% ~ (p=0.085 n=97+99) [Geo mean] 413ms 410ms -0.73% name old alloc/op new alloc/op delta Template 38.4MB ± 0% 37.7MB ± 0% -1.85% (p=0.008 n=5+5) Unicode 30.1MB ± 0% 28.8MB ± 0% -4.09% (p=0.008 n=5+5) GoTypes 112MB ± 0% 110MB ± 0% -1.69% (p=0.008 n=5+5) Compiler 470MB ± 0% 461MB ± 0% -1.91% (p=0.008 n=5+5) SSA 1.13GB ± 0% 1.11GB ± 0% -1.70% (p=0.008 n=5+5) Flate 25.0MB ± 0% 24.6MB ± 0% -1.67% (p=0.008 n=5+5) GoParser 31.6MB ± 0% 31.1MB ± 0% -1.66% (p=0.008 n=5+5) Reflect 77.1MB ± 0% 75.8MB ± 0% -1.69% (p=0.008 n=5+5) Tar 26.3MB ± 0% 25.7MB ± 0% -2.06% (p=0.008 n=5+5) XML 41.9MB ± 0% 41.1MB ± 0% -1.93% (p=0.008 n=5+5) [Geo mean] 73.5MB 72.0MB -2.03% name old allocs/op new allocs/op delta Template 383k ± 0% 383k ± 0% ~ (p=0.690 n=5+5) Unicode 343k ± 0% 343k ± 0% ~ (p=0.841 n=5+5) GoTypes 1.16M ± 0% 1.16M ± 0% ~ (p=0.310 n=5+5) Compiler 4.43M ± 0% 4.42M ± 0% -0.17% (p=0.008 n=5+5) SSA 9.85M ± 0% 9.85M ± 0% ~ (p=0.310 n=5+5) Flate 236k ± 0% 236k ± 1% ~ (p=0.841 n=5+5) GoParser 320k ± 0% 320k ± 0% ~ (p=0.421 n=5+5) Reflect 988k ± 0% 987k ± 0% ~ (p=0.690 n=5+5) Tar 252k ± 0% 251k ± 0% ~ (p=0.095 n=5+5) XML 399k ± 0% 399k ± 0% ~ (p=1.000 n=5+5) [Geo mean] 741k 740k -0.07% Change-Id: I9e952b58a98e30a12494304db9ce50d0a85e459c Reviewed-on: https://go-review.googlesource.com/41797 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Marvin Stenger <marvin.stenger94@gmail.com>
2017-04-25 18:14:12 -07:00
if r.Class() == PFUNC {
gdata(l, r, Widthptr)
return true
}
cmd/compile: move Node.Class to flags Put it at position zero, since it is fairly hot. This shrinks gc.Node into a smaller size class on 64 bit systems. name old time/op new time/op delta Template 193ms ± 5% 192ms ± 3% ~ (p=0.353 n=94+93) Unicode 86.1ms ± 5% 85.0ms ± 4% -1.23% (p=0.000 n=95+98) GoTypes 546ms ± 3% 544ms ± 4% -0.40% (p=0.007 n=94+97) Compiler 2.56s ± 3% 2.54s ± 3% -0.67% (p=0.000 n=99+97) SSA 5.13s ± 2% 5.10s ± 3% -0.55% (p=0.000 n=94+98) Flate 122ms ± 6% 121ms ± 4% -0.75% (p=0.002 n=97+95) GoParser 144ms ± 5% 144ms ± 4% ~ (p=0.298 n=98+97) Reflect 348ms ± 4% 349ms ± 4% ~ (p=0.350 n=98+97) Tar 105ms ± 5% 104ms ± 5% ~ (p=0.154 n=96+98) XML 200ms ± 5% 198ms ± 4% -0.71% (p=0.015 n=97+98) [Geo mean] 330ms 328ms -0.52% name old user-time/op new user-time/op delta Template 229ms ±11% 224ms ± 7% -2.16% (p=0.001 n=100+87) Unicode 109ms ± 5% 109ms ± 6% ~ (p=0.897 n=96+91) GoTypes 712ms ± 4% 709ms ± 4% ~ (p=0.085 n=96+98) Compiler 3.41s ± 3% 3.36s ± 3% -1.43% (p=0.000 n=98+98) SSA 7.46s ± 3% 7.31s ± 3% -2.02% (p=0.000 n=100+99) Flate 145ms ± 6% 143ms ± 6% -1.11% (p=0.001 n=99+97) GoParser 177ms ± 5% 176ms ± 5% -0.78% (p=0.018 n=95+95) Reflect 432ms ± 7% 435ms ± 9% ~ (p=0.296 n=100+100) Tar 121ms ± 7% 121ms ± 5% ~ (p=0.072 n=100+95) XML 241ms ± 4% 239ms ± 5% ~ (p=0.085 n=97+99) [Geo mean] 413ms 410ms -0.73% name old alloc/op new alloc/op delta Template 38.4MB ± 0% 37.7MB ± 0% -1.85% (p=0.008 n=5+5) Unicode 30.1MB ± 0% 28.8MB ± 0% -4.09% (p=0.008 n=5+5) GoTypes 112MB ± 0% 110MB ± 0% -1.69% (p=0.008 n=5+5) Compiler 470MB ± 0% 461MB ± 0% -1.91% (p=0.008 n=5+5) SSA 1.13GB ± 0% 1.11GB ± 0% -1.70% (p=0.008 n=5+5) Flate 25.0MB ± 0% 24.6MB ± 0% -1.67% (p=0.008 n=5+5) GoParser 31.6MB ± 0% 31.1MB ± 0% -1.66% (p=0.008 n=5+5) Reflect 77.1MB ± 0% 75.8MB ± 0% -1.69% (p=0.008 n=5+5) Tar 26.3MB ± 0% 25.7MB ± 0% -2.06% (p=0.008 n=5+5) XML 41.9MB ± 0% 41.1MB ± 0% -1.93% (p=0.008 n=5+5) [Geo mean] 73.5MB 72.0MB -2.03% name old allocs/op new allocs/op delta Template 383k ± 0% 383k ± 0% ~ (p=0.690 n=5+5) Unicode 343k ± 0% 343k ± 0% ~ (p=0.841 n=5+5) GoTypes 1.16M ± 0% 1.16M ± 0% ~ (p=0.310 n=5+5) Compiler 4.43M ± 0% 4.42M ± 0% -0.17% (p=0.008 n=5+5) SSA 9.85M ± 0% 9.85M ± 0% ~ (p=0.310 n=5+5) Flate 236k ± 0% 236k ± 1% ~ (p=0.841 n=5+5) GoParser 320k ± 0% 320k ± 0% ~ (p=0.421 n=5+5) Reflect 988k ± 0% 987k ± 0% ~ (p=0.690 n=5+5) Tar 252k ± 0% 251k ± 0% ~ (p=0.095 n=5+5) XML 399k ± 0% 399k ± 0% ~ (p=1.000 n=5+5) [Geo mean] 741k 740k -0.07% Change-Id: I9e952b58a98e30a12494304db9ce50d0a85e459c Reviewed-on: https://go-review.googlesource.com/41797 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Marvin Stenger <marvin.stenger94@gmail.com>
2017-04-25 18:14:12 -07:00
if r.Class() != PEXTERN || r.Sym.Pkg != localpkg {
return false
}
if r.Name.Defn == nil { // probably zeroed but perhaps supplied externally and of unknown value
return false
}
if r.Name.Defn.Op != OAS {
return false
}
orig := r
r = r.Name.Defn.Right
for r.Op == OCONVNOP && !eqtype(r.Type, l.Type) {
r = r.Left
}
switch r.Op {
case ONAME:
if staticcopy(l, r, out) {
return true
}
// We may have skipped past one or more OCONVNOPs, so
// use conv to ensure r is assignable to l (#13263).
*out = append(*out, nod(OAS, l, conv(r, l.Type)))
return true
case OLITERAL:
if isZero(r) {
return true
}
gdata(l, r, int(l.Type.Width))
return true
case OADDR:
switch r.Left.Op {
case ONAME:
gdata(l, r, int(l.Type.Width))
return true
}
case OPTRLIT:
switch r.Left.Op {
case OARRAYLIT, OSLICELIT, OSTRUCTLIT, OMAPLIT:
// copy pointer
gdata(l, nod(OADDR, inittemps[r], nil), int(l.Type.Width))
return true
}
case OSLICELIT:
// copy slice
a := inittemps[r]
n := l.copy()
n.Xoffset = l.Xoffset + int64(array_array)
gdata(n, nod(OADDR, a, nil), Widthptr)
n.Xoffset = l.Xoffset + int64(array_nel)
gdata(n, r.Right, Widthptr)
n.Xoffset = l.Xoffset + int64(array_cap)
gdata(n, r.Right, Widthptr)
return true
case OARRAYLIT, OSTRUCTLIT:
p := initplans[r]
n := l.copy()
for i := range p.E {
e := &p.E[i]
n.Xoffset = l.Xoffset + e.Xoffset
n.Type = e.Expr.Type
if e.Expr.Op == OLITERAL {
gdata(n, e.Expr, int(n.Type.Width))
continue
}
ll := n.sepcopy()
if staticassign(ll, e.Expr, out) {
continue
}
// Requires computation, but we're
// copying someone else's computation.
rr := orig.sepcopy()
rr.Type = ll.Type
rr.Xoffset += e.Xoffset
setlineno(rr)
*out = append(*out, nod(OAS, ll, rr))
}
return true
}
return false
}
func staticassign(l *Node, r *Node, out *[]*Node) bool {
for r.Op == OCONVNOP {
r = r.Left
}
switch r.Op {
case ONAME:
return staticcopy(l, r, out)
case OLITERAL:
if isZero(r) {
return true
}
gdata(l, r, int(l.Type.Width))
return true
case OADDR:
var nam Node
if stataddr(&nam, r.Left) {
n := *r
n.Left = &nam
gdata(l, &n, int(l.Type.Width))
return true
}
fallthrough
case OPTRLIT:
switch r.Left.Op {
case OARRAYLIT, OSLICELIT, OMAPLIT, OSTRUCTLIT:
cmd/compile: captureless closures are constants In particular, we can initialize globals with them at link time instead of generating code for them in an init() function. Less code, less startup cost. But the real reason for this change is binary size. This change reduces the binary size of hello world by ~4%. The culprit is fmt.ssFree, a global variable which is a sync.Pool of scratch scan states. It is initalized with a captureless closure as the pool's New action. That action in turn references all the scanf code. If you never call any of the fmt.Scanf* routines, ssFree is never used. But before this change, ssFree is still referenced by fmt's init function. That keeps ssFree and all the code it references in the binary. With this change, ssFree is initialized at link time. As a result, fmt.init never mentions ssFree. If you don't call fmt.Scanf*, ssFree is unreferenced and it and the scanf code are not included. This change is an easy fix for what is generally a much harder problem, the unnecessary initializing of unused globals (and retention of code that they reference). Ideally we should have separate init code for each global and only include that code if the corresponding global is live. (We'd need to make sure that the initializing code has no side effects, except on the global being initialized.) That is a much harder change. Update #6853 Change-Id: I19d1e33992287882c83efea6ce113b7cfc504b67 Reviewed-on: https://go-review.googlesource.com/17398 Reviewed-by: Russ Cox <rsc@golang.org> Run-TryBot: Russ Cox <rsc@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-03 13:20:58 -08:00
// Init pointer.
a := staticname(r.Left.Type)
inittemps[r] = a
gdata(l, nod(OADDR, a, nil), int(l.Type.Width))
// Init underlying literal.
if !staticassign(a, r.Left, out) {
*out = append(*out, nod(OAS, a, r.Left))
}
return true
}
cmd/compile: captureless closures are constants In particular, we can initialize globals with them at link time instead of generating code for them in an init() function. Less code, less startup cost. But the real reason for this change is binary size. This change reduces the binary size of hello world by ~4%. The culprit is fmt.ssFree, a global variable which is a sync.Pool of scratch scan states. It is initalized with a captureless closure as the pool's New action. That action in turn references all the scanf code. If you never call any of the fmt.Scanf* routines, ssFree is never used. But before this change, ssFree is still referenced by fmt's init function. That keeps ssFree and all the code it references in the binary. With this change, ssFree is initialized at link time. As a result, fmt.init never mentions ssFree. If you don't call fmt.Scanf*, ssFree is unreferenced and it and the scanf code are not included. This change is an easy fix for what is generally a much harder problem, the unnecessary initializing of unused globals (and retention of code that they reference). Ideally we should have separate init code for each global and only include that code if the corresponding global is live. (We'd need to make sure that the initializing code has no side effects, except on the global being initialized.) That is a much harder change. Update #6853 Change-Id: I19d1e33992287882c83efea6ce113b7cfc504b67 Reviewed-on: https://go-review.googlesource.com/17398 Reviewed-by: Russ Cox <rsc@golang.org> Run-TryBot: Russ Cox <rsc@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-03 13:20:58 -08:00
//dump("not static ptrlit", r);
case OSTRARRAYBYTE:
cmd/compile: move Node.Class to flags Put it at position zero, since it is fairly hot. This shrinks gc.Node into a smaller size class on 64 bit systems. name old time/op new time/op delta Template 193ms ± 5% 192ms ± 3% ~ (p=0.353 n=94+93) Unicode 86.1ms ± 5% 85.0ms ± 4% -1.23% (p=0.000 n=95+98) GoTypes 546ms ± 3% 544ms ± 4% -0.40% (p=0.007 n=94+97) Compiler 2.56s ± 3% 2.54s ± 3% -0.67% (p=0.000 n=99+97) SSA 5.13s ± 2% 5.10s ± 3% -0.55% (p=0.000 n=94+98) Flate 122ms ± 6% 121ms ± 4% -0.75% (p=0.002 n=97+95) GoParser 144ms ± 5% 144ms ± 4% ~ (p=0.298 n=98+97) Reflect 348ms ± 4% 349ms ± 4% ~ (p=0.350 n=98+97) Tar 105ms ± 5% 104ms ± 5% ~ (p=0.154 n=96+98) XML 200ms ± 5% 198ms ± 4% -0.71% (p=0.015 n=97+98) [Geo mean] 330ms 328ms -0.52% name old user-time/op new user-time/op delta Template 229ms ±11% 224ms ± 7% -2.16% (p=0.001 n=100+87) Unicode 109ms ± 5% 109ms ± 6% ~ (p=0.897 n=96+91) GoTypes 712ms ± 4% 709ms ± 4% ~ (p=0.085 n=96+98) Compiler 3.41s ± 3% 3.36s ± 3% -1.43% (p=0.000 n=98+98) SSA 7.46s ± 3% 7.31s ± 3% -2.02% (p=0.000 n=100+99) Flate 145ms ± 6% 143ms ± 6% -1.11% (p=0.001 n=99+97) GoParser 177ms ± 5% 176ms ± 5% -0.78% (p=0.018 n=95+95) Reflect 432ms ± 7% 435ms ± 9% ~ (p=0.296 n=100+100) Tar 121ms ± 7% 121ms ± 5% ~ (p=0.072 n=100+95) XML 241ms ± 4% 239ms ± 5% ~ (p=0.085 n=97+99) [Geo mean] 413ms 410ms -0.73% name old alloc/op new alloc/op delta Template 38.4MB ± 0% 37.7MB ± 0% -1.85% (p=0.008 n=5+5) Unicode 30.1MB ± 0% 28.8MB ± 0% -4.09% (p=0.008 n=5+5) GoTypes 112MB ± 0% 110MB ± 0% -1.69% (p=0.008 n=5+5) Compiler 470MB ± 0% 461MB ± 0% -1.91% (p=0.008 n=5+5) SSA 1.13GB ± 0% 1.11GB ± 0% -1.70% (p=0.008 n=5+5) Flate 25.0MB ± 0% 24.6MB ± 0% -1.67% (p=0.008 n=5+5) GoParser 31.6MB ± 0% 31.1MB ± 0% -1.66% (p=0.008 n=5+5) Reflect 77.1MB ± 0% 75.8MB ± 0% -1.69% (p=0.008 n=5+5) Tar 26.3MB ± 0% 25.7MB ± 0% -2.06% (p=0.008 n=5+5) XML 41.9MB ± 0% 41.1MB ± 0% -1.93% (p=0.008 n=5+5) [Geo mean] 73.5MB 72.0MB -2.03% name old allocs/op new allocs/op delta Template 383k ± 0% 383k ± 0% ~ (p=0.690 n=5+5) Unicode 343k ± 0% 343k ± 0% ~ (p=0.841 n=5+5) GoTypes 1.16M ± 0% 1.16M ± 0% ~ (p=0.310 n=5+5) Compiler 4.43M ± 0% 4.42M ± 0% -0.17% (p=0.008 n=5+5) SSA 9.85M ± 0% 9.85M ± 0% ~ (p=0.310 n=5+5) Flate 236k ± 0% 236k ± 1% ~ (p=0.841 n=5+5) GoParser 320k ± 0% 320k ± 0% ~ (p=0.421 n=5+5) Reflect 988k ± 0% 987k ± 0% ~ (p=0.690 n=5+5) Tar 252k ± 0% 251k ± 0% ~ (p=0.095 n=5+5) XML 399k ± 0% 399k ± 0% ~ (p=1.000 n=5+5) [Geo mean] 741k 740k -0.07% Change-Id: I9e952b58a98e30a12494304db9ce50d0a85e459c Reviewed-on: https://go-review.googlesource.com/41797 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Marvin Stenger <marvin.stenger94@gmail.com>
2017-04-25 18:14:12 -07:00
if l.Class() == PEXTERN && r.Left.Op == OLITERAL {
sval := r.Left.Val().U.(string)
slicebytes(l, sval, len(sval))
return true
}
case OSLICELIT:
initplan(r)
// Init slice.
bound := r.Right.Int64()
ta := types.NewArray(r.Type.Elem(), bound)
a := staticname(ta)
inittemps[r] = a
n := l.copy()
n.Xoffset = l.Xoffset + int64(array_array)
gdata(n, nod(OADDR, a, nil), Widthptr)
n.Xoffset = l.Xoffset + int64(array_nel)
gdata(n, r.Right, Widthptr)
n.Xoffset = l.Xoffset + int64(array_cap)
gdata(n, r.Right, Widthptr)
// Fall through to init underlying array.
l = a
fallthrough
case OARRAYLIT, OSTRUCTLIT:
initplan(r)
p := initplans[r]
n := l.copy()
for i := range p.E {
e := &p.E[i]
n.Xoffset = l.Xoffset + e.Xoffset
n.Type = e.Expr.Type
if e.Expr.Op == OLITERAL {
gdata(n, e.Expr, int(n.Type.Width))
continue
}
setlineno(e.Expr)
a := n.sepcopy()
if !staticassign(a, e.Expr, out) {
*out = append(*out, nod(OAS, a, e.Expr))
}
}
return true
case OMAPLIT:
break
cmd/compile: captureless closures are constants In particular, we can initialize globals with them at link time instead of generating code for them in an init() function. Less code, less startup cost. But the real reason for this change is binary size. This change reduces the binary size of hello world by ~4%. The culprit is fmt.ssFree, a global variable which is a sync.Pool of scratch scan states. It is initalized with a captureless closure as the pool's New action. That action in turn references all the scanf code. If you never call any of the fmt.Scanf* routines, ssFree is never used. But before this change, ssFree is still referenced by fmt's init function. That keeps ssFree and all the code it references in the binary. With this change, ssFree is initialized at link time. As a result, fmt.init never mentions ssFree. If you don't call fmt.Scanf*, ssFree is unreferenced and it and the scanf code are not included. This change is an easy fix for what is generally a much harder problem, the unnecessary initializing of unused globals (and retention of code that they reference). Ideally we should have separate init code for each global and only include that code if the corresponding global is live. (We'd need to make sure that the initializing code has no side effects, except on the global being initialized.) That is a much harder change. Update #6853 Change-Id: I19d1e33992287882c83efea6ce113b7cfc504b67 Reviewed-on: https://go-review.googlesource.com/17398 Reviewed-by: Russ Cox <rsc@golang.org> Run-TryBot: Russ Cox <rsc@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-03 13:20:58 -08:00
case OCLOSURE:
cmd/compile: ignore OXXX nodes in closure captured vars list Added a debug flag "-d closure" to explain compilation of closures (should this be done some other way? Should we rewrite the "-m" flag to "-d escapes"?) Used this to discover that cause was an OXXX node in the captured vars list, and in turn noticed that OXXX nodes are explicitly ignored in all other processing of captured variables. Couldn't figure out a reproducer, did verify that this OXXX was not caused by an unnamed return value (which is one use of these). Verified lack of heap allocation by examining -S output. Assembly: (runtime/mgc.go:1371) PCDATA $0, $2 (runtime/mgc.go:1371) CALL "".notewakeup(SB) (runtime/mgc.go:1377) LEAQ "".gcBgMarkWorker.func1·f(SB), AX (runtime/mgc.go:1404) MOVQ AX, (SP) (runtime/mgc.go:1404) MOVQ "".autotmp_2242+88(SP), CX (runtime/mgc.go:1404) MOVQ CX, 8(SP) (runtime/mgc.go:1404) LEAQ go.string."GC worker (idle)"(SB), AX (runtime/mgc.go:1404) MOVQ AX, 16(SP) (runtime/mgc.go:1404) MOVQ $16, 24(SP) (runtime/mgc.go:1404) MOVB $20, 32(SP) (runtime/mgc.go:1404) MOVQ $0, 40(SP) (runtime/mgc.go:1404) PCDATA $0, $2 (runtime/mgc.go:1404) CALL "".gopark(SB) Added a check for compiling_runtime to ensure that this is caught in the future. Added a test to test the check. Verified that 1.5.3 did NOT reject the test case when compiled with -+ flag, so this is not a recently added bug. Cause of bug is two-part -- there was no leaking closure detection ever, and instead it relied on capture-of-variables to trigger compiling_runtime test, but closures improved in 1.5.3 so that mere capture of a value did not also capture the variable, which thus allowed closures to escape, as well as this case where the escape was spurious. In fixedbugs/issue14999.go, compare messages for f and g; 1.5.3 would reject g, but not f. 1.4 rejects both because 1.4 heap-allocates parameter x for both. Fixes #14999. Change-Id: I40bcdd27056810628e96763a44f2acddd503aee1 Reviewed-on: https://go-review.googlesource.com/21322 Run-TryBot: David Chase <drchase@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
2016-03-30 14:14:00 -04:00
if hasemptycvars(r) {
if Debug_closure > 0 {
Warnl(r.Pos, "closure converted to global")
cmd/compile: ignore OXXX nodes in closure captured vars list Added a debug flag "-d closure" to explain compilation of closures (should this be done some other way? Should we rewrite the "-m" flag to "-d escapes"?) Used this to discover that cause was an OXXX node in the captured vars list, and in turn noticed that OXXX nodes are explicitly ignored in all other processing of captured variables. Couldn't figure out a reproducer, did verify that this OXXX was not caused by an unnamed return value (which is one use of these). Verified lack of heap allocation by examining -S output. Assembly: (runtime/mgc.go:1371) PCDATA $0, $2 (runtime/mgc.go:1371) CALL "".notewakeup(SB) (runtime/mgc.go:1377) LEAQ "".gcBgMarkWorker.func1·f(SB), AX (runtime/mgc.go:1404) MOVQ AX, (SP) (runtime/mgc.go:1404) MOVQ "".autotmp_2242+88(SP), CX (runtime/mgc.go:1404) MOVQ CX, 8(SP) (runtime/mgc.go:1404) LEAQ go.string."GC worker (idle)"(SB), AX (runtime/mgc.go:1404) MOVQ AX, 16(SP) (runtime/mgc.go:1404) MOVQ $16, 24(SP) (runtime/mgc.go:1404) MOVB $20, 32(SP) (runtime/mgc.go:1404) MOVQ $0, 40(SP) (runtime/mgc.go:1404) PCDATA $0, $2 (runtime/mgc.go:1404) CALL "".gopark(SB) Added a check for compiling_runtime to ensure that this is caught in the future. Added a test to test the check. Verified that 1.5.3 did NOT reject the test case when compiled with -+ flag, so this is not a recently added bug. Cause of bug is two-part -- there was no leaking closure detection ever, and instead it relied on capture-of-variables to trigger compiling_runtime test, but closures improved in 1.5.3 so that mere capture of a value did not also capture the variable, which thus allowed closures to escape, as well as this case where the escape was spurious. In fixedbugs/issue14999.go, compare messages for f and g; 1.5.3 would reject g, but not f. 1.4 rejects both because 1.4 heap-allocates parameter x for both. Fixes #14999. Change-Id: I40bcdd27056810628e96763a44f2acddd503aee1 Reviewed-on: https://go-review.googlesource.com/21322 Run-TryBot: David Chase <drchase@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
2016-03-30 14:14:00 -04:00
}
cmd/compile: captureless closures are constants In particular, we can initialize globals with them at link time instead of generating code for them in an init() function. Less code, less startup cost. But the real reason for this change is binary size. This change reduces the binary size of hello world by ~4%. The culprit is fmt.ssFree, a global variable which is a sync.Pool of scratch scan states. It is initalized with a captureless closure as the pool's New action. That action in turn references all the scanf code. If you never call any of the fmt.Scanf* routines, ssFree is never used. But before this change, ssFree is still referenced by fmt's init function. That keeps ssFree and all the code it references in the binary. With this change, ssFree is initialized at link time. As a result, fmt.init never mentions ssFree. If you don't call fmt.Scanf*, ssFree is unreferenced and it and the scanf code are not included. This change is an easy fix for what is generally a much harder problem, the unnecessary initializing of unused globals (and retention of code that they reference). Ideally we should have separate init code for each global and only include that code if the corresponding global is live. (We'd need to make sure that the initializing code has no side effects, except on the global being initialized.) That is a much harder change. Update #6853 Change-Id: I19d1e33992287882c83efea6ce113b7cfc504b67 Reviewed-on: https://go-review.googlesource.com/17398 Reviewed-by: Russ Cox <rsc@golang.org> Run-TryBot: Russ Cox <rsc@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-03 13:20:58 -08:00
// Closures with no captured variables are globals,
// so the assignment can be done at link time.
gdata(l, r.Func.Closure.Func.Nname, Widthptr)
cmd/compile: captureless closures are constants In particular, we can initialize globals with them at link time instead of generating code for them in an init() function. Less code, less startup cost. But the real reason for this change is binary size. This change reduces the binary size of hello world by ~4%. The culprit is fmt.ssFree, a global variable which is a sync.Pool of scratch scan states. It is initalized with a captureless closure as the pool's New action. That action in turn references all the scanf code. If you never call any of the fmt.Scanf* routines, ssFree is never used. But before this change, ssFree is still referenced by fmt's init function. That keeps ssFree and all the code it references in the binary. With this change, ssFree is initialized at link time. As a result, fmt.init never mentions ssFree. If you don't call fmt.Scanf*, ssFree is unreferenced and it and the scanf code are not included. This change is an easy fix for what is generally a much harder problem, the unnecessary initializing of unused globals (and retention of code that they reference). Ideally we should have separate init code for each global and only include that code if the corresponding global is live. (We'd need to make sure that the initializing code has no side effects, except on the global being initialized.) That is a much harder change. Update #6853 Change-Id: I19d1e33992287882c83efea6ce113b7cfc504b67 Reviewed-on: https://go-review.googlesource.com/17398 Reviewed-by: Russ Cox <rsc@golang.org> Run-TryBot: Russ Cox <rsc@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-03 13:20:58 -08:00
return true
}
closuredebugruntimecheck(r)
case OCONVIFACE:
// This logic is mirrored in isStaticCompositeLiteral.
// If you change something here, change it there, and vice versa.
// Determine the underlying concrete type and value we are converting from.
val := r
for val.Op == OCONVIFACE {
val = val.Left
}
if val.Type.IsInterface() {
// val is an interface type.
// If val is nil, we can statically initialize l;
// both words are zero and so there no work to do, so report success.
// If val is non-nil, we have no concrete type to record,
// and we won't be able to statically initialize its value, so report failure.
return Isconst(val, CTNIL)
}
var itab *Node
if l.Type.IsEmptyInterface() {
itab = typename(val.Type)
} else {
itab = itabname(val.Type, l.Type)
}
// Create a copy of l to modify while we emit data.
n := l.copy()
// Emit itab, advance offset.
gdata(n, itab, Widthptr)
n.Xoffset += int64(Widthptr)
// Emit data.
if isdirectiface(val.Type) {
if Isconst(val, CTNIL) {
// Nil is zero, nothing to do.
return true
}
// Copy val directly into n.
n.Type = val.Type
setlineno(val)
a := n.sepcopy()
if !staticassign(a, val, out) {
*out = append(*out, nod(OAS, a, val))
}
} else {
// Construct temp to hold val, write pointer to temp into n.
a := staticname(val.Type)
inittemps[val] = a
if !staticassign(a, val, out) {
*out = append(*out, nod(OAS, a, val))
}
ptr := nod(OADDR, a, nil)
n.Type = types.NewPtr(val.Type)
gdata(n, ptr, Widthptr)
}
return true
}
cmd/compile: captureless closures are constants In particular, we can initialize globals with them at link time instead of generating code for them in an init() function. Less code, less startup cost. But the real reason for this change is binary size. This change reduces the binary size of hello world by ~4%. The culprit is fmt.ssFree, a global variable which is a sync.Pool of scratch scan states. It is initalized with a captureless closure as the pool's New action. That action in turn references all the scanf code. If you never call any of the fmt.Scanf* routines, ssFree is never used. But before this change, ssFree is still referenced by fmt's init function. That keeps ssFree and all the code it references in the binary. With this change, ssFree is initialized at link time. As a result, fmt.init never mentions ssFree. If you don't call fmt.Scanf*, ssFree is unreferenced and it and the scanf code are not included. This change is an easy fix for what is generally a much harder problem, the unnecessary initializing of unused globals (and retention of code that they reference). Ideally we should have separate init code for each global and only include that code if the corresponding global is live. (We'd need to make sure that the initializing code has no side effects, except on the global being initialized.) That is a much harder change. Update #6853 Change-Id: I19d1e33992287882c83efea6ce113b7cfc504b67 Reviewed-on: https://go-review.googlesource.com/17398 Reviewed-by: Russ Cox <rsc@golang.org> Run-TryBot: Russ Cox <rsc@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-12-03 13:20:58 -08:00
//dump("not static", r);
return false
}
// initContext is the context in which static data is populated.
// It is either in an init function or in any other function.
// Static data populated in an init function will be written either
// zero times (as a readonly, static data symbol) or
// one time (during init function execution).
// Either way, there is no opportunity for races or further modification,
// so the data can be written to a (possibly readonly) data symbol.
// Static data populated in any other function needs to be local to
// that function to allow multiple instances of that function
// to execute concurrently without clobbering each others' data.
type initContext uint8
const (
inInitFunction initContext = iota
inNonInitFunction
)
// from here down is the walk analysis
// of composite literals.
// most of the work is to generate
// data statements for the constant
// part of the composite literal.
cmd/compile: number autotmps per-func, not per-package Prior to this CL, autotmps were global to a package. They also shared numbering with static variables. Switch autotmp numbering to be per-function instead, and do implicit numbering based on len(Func.Dcl). This eliminates a dependency on a global variable from the backend without adding to the Func struct. While we're here, move statuniqgen closer to its sole remaining user. This actually improves compiler performance, because the autotmp_* names can now be reused across functions. name old alloc/op new alloc/op delta Template 40.6MB ± 0% 40.1MB ± 0% -1.38% (p=0.000 n=10+10) Unicode 29.9MB ± 0% 29.9MB ± 0% ~ (p=0.912 n=10+10) GoTypes 116MB ± 0% 114MB ± 0% -1.53% (p=0.000 n=10+10) SSA 865MB ± 0% 856MB ± 0% -1.04% (p=0.000 n=10+10) Flate 25.8MB ± 0% 25.4MB ± 0% -1.36% (p=0.000 n=10+10) GoParser 32.2MB ± 0% 32.0MB ± 0% -0.72% (p=0.000 n=10+10) Reflect 80.3MB ± 0% 79.0MB ± 0% -1.65% (p=0.000 n=9+10) Tar 27.0MB ± 0% 26.7MB ± 0% -0.86% (p=0.000 n=10+9) XML 42.8MB ± 0% 42.4MB ± 0% -0.95% (p=0.000 n=10+10) name old allocs/op new allocs/op delta Template 398k ± 1% 396k ± 1% -0.59% (p=0.002 n=10+10) Unicode 321k ± 1% 321k ± 0% ~ (p=0.912 n=10+10) GoTypes 1.17M ± 0% 1.16M ± 0% -0.77% (p=0.000 n=10+10) SSA 7.65M ± 0% 7.62M ± 0% -0.40% (p=0.000 n=10+10) Flate 240k ± 1% 238k ± 1% -0.56% (p=0.001 n=10+10) GoParser 323k ± 1% 320k ± 1% -0.65% (p=0.002 n=10+10) Reflect 1.01M ± 0% 1.00M ± 0% -0.37% (p=0.001 n=9+10) Tar 256k ± 1% 255k ± 0% ~ (p=0.101 n=10+8) XML 400k ± 1% 398k ± 1% ~ (p=0.063 n=10+10) Change-Id: I3c23ca98129137d373106990b1a3e1507bbe0cc3 Reviewed-on: https://go-review.googlesource.com/38729 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-03-28 10:36:18 -07:00
var statuniqgen int // name generator for static temps
// staticname returns a name backed by a static data symbol.
cmd/compile: pack bool fields in Node, Name, Func and Type structs to bitsets This reduces compiler memory usage by up to 4% - see compilebench results below. name old time/op new time/op delta Template 245ms ± 4% 241ms ± 2% -1.88% (p=0.029 n=10+10) Unicode 126ms ± 3% 124ms ± 3% ~ (p=0.105 n=10+10) GoTypes 805ms ± 2% 813ms ± 3% ~ (p=0.515 n=8+10) Compiler 3.95s ± 2% 3.83s ± 1% -2.96% (p=0.000 n=9+10) MakeBash 47.4s ± 4% 46.6s ± 1% -1.59% (p=0.028 n=9+10) name old user-ns/op new user-ns/op delta Template 324M ± 5% 326M ± 3% ~ (p=0.935 n=10+10) Unicode 186M ± 5% 178M ±10% ~ (p=0.067 n=9+10) GoTypes 1.08G ± 7% 1.09G ± 4% ~ (p=0.956 n=10+10) Compiler 5.34G ± 4% 5.31G ± 1% ~ (p=0.501 n=10+8) name old alloc/op new alloc/op delta Template 41.0MB ± 0% 39.8MB ± 0% -3.03% (p=0.000 n=10+10) Unicode 32.3MB ± 0% 31.0MB ± 0% -4.13% (p=0.000 n=10+10) GoTypes 119MB ± 0% 116MB ± 0% -2.39% (p=0.000 n=10+10) Compiler 499MB ± 0% 487MB ± 0% -2.48% (p=0.000 n=10+10) name old allocs/op new allocs/op delta Template 380k ± 1% 379k ± 1% ~ (p=0.436 n=10+10) Unicode 324k ± 1% 324k ± 0% ~ (p=0.853 n=10+10) GoTypes 1.15M ± 0% 1.15M ± 0% ~ (p=0.481 n=10+10) Compiler 4.41M ± 0% 4.41M ± 0% -0.12% (p=0.007 n=10+10) name old text-bytes new text-bytes delta HelloSize 623k ± 0% 623k ± 0% ~ (all equal) CmdGoSize 6.64M ± 0% 6.64M ± 0% ~ (all equal) name old data-bytes new data-bytes delta HelloSize 5.81k ± 0% 5.81k ± 0% ~ (all equal) CmdGoSize 238k ± 0% 238k ± 0% ~ (all equal) name old bss-bytes new bss-bytes delta HelloSize 134k ± 0% 134k ± 0% ~ (all equal) CmdGoSize 152k ± 0% 152k ± 0% ~ (all equal) name old exe-bytes new exe-bytes delta HelloSize 967k ± 0% 967k ± 0% ~ (all equal) CmdGoSize 10.2M ± 0% 10.2M ± 0% ~ (all equal) Change-Id: I1f40af738254892bd6c8ba2eb43390b175753d52 Reviewed-on: https://go-review.googlesource.com/37445 Reviewed-by: Matthew Dempsky <mdempsky@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-02-27 19:56:38 +02:00
// Callers should call n.Name.SetReadonly(true) on the
// returned node for readonly nodes.
func staticname(t *types.Type) *Node {
// Don't use lookupN; it interns the resulting string, but these are all unique.
n := newname(lookup(fmt.Sprintf("statictmp_%d", statuniqgen)))
statuniqgen++
addvar(n, t, PEXTERN)
return n
}
func isLiteral(n *Node) bool {
// Treat nils as zeros rather than literals.
return n.Op == OLITERAL && n.Val().Ctype() != CTNIL
}
func (n *Node) isSimpleName() bool {
cmd/compile: move Node.Class to flags Put it at position zero, since it is fairly hot. This shrinks gc.Node into a smaller size class on 64 bit systems. name old time/op new time/op delta Template 193ms ± 5% 192ms ± 3% ~ (p=0.353 n=94+93) Unicode 86.1ms ± 5% 85.0ms ± 4% -1.23% (p=0.000 n=95+98) GoTypes 546ms ± 3% 544ms ± 4% -0.40% (p=0.007 n=94+97) Compiler 2.56s ± 3% 2.54s ± 3% -0.67% (p=0.000 n=99+97) SSA 5.13s ± 2% 5.10s ± 3% -0.55% (p=0.000 n=94+98) Flate 122ms ± 6% 121ms ± 4% -0.75% (p=0.002 n=97+95) GoParser 144ms ± 5% 144ms ± 4% ~ (p=0.298 n=98+97) Reflect 348ms ± 4% 349ms ± 4% ~ (p=0.350 n=98+97) Tar 105ms ± 5% 104ms ± 5% ~ (p=0.154 n=96+98) XML 200ms ± 5% 198ms ± 4% -0.71% (p=0.015 n=97+98) [Geo mean] 330ms 328ms -0.52% name old user-time/op new user-time/op delta Template 229ms ±11% 224ms ± 7% -2.16% (p=0.001 n=100+87) Unicode 109ms ± 5% 109ms ± 6% ~ (p=0.897 n=96+91) GoTypes 712ms ± 4% 709ms ± 4% ~ (p=0.085 n=96+98) Compiler 3.41s ± 3% 3.36s ± 3% -1.43% (p=0.000 n=98+98) SSA 7.46s ± 3% 7.31s ± 3% -2.02% (p=0.000 n=100+99) Flate 145ms ± 6% 143ms ± 6% -1.11% (p=0.001 n=99+97) GoParser 177ms ± 5% 176ms ± 5% -0.78% (p=0.018 n=95+95) Reflect 432ms ± 7% 435ms ± 9% ~ (p=0.296 n=100+100) Tar 121ms ± 7% 121ms ± 5% ~ (p=0.072 n=100+95) XML 241ms ± 4% 239ms ± 5% ~ (p=0.085 n=97+99) [Geo mean] 413ms 410ms -0.73% name old alloc/op new alloc/op delta Template 38.4MB ± 0% 37.7MB ± 0% -1.85% (p=0.008 n=5+5) Unicode 30.1MB ± 0% 28.8MB ± 0% -4.09% (p=0.008 n=5+5) GoTypes 112MB ± 0% 110MB ± 0% -1.69% (p=0.008 n=5+5) Compiler 470MB ± 0% 461MB ± 0% -1.91% (p=0.008 n=5+5) SSA 1.13GB ± 0% 1.11GB ± 0% -1.70% (p=0.008 n=5+5) Flate 25.0MB ± 0% 24.6MB ± 0% -1.67% (p=0.008 n=5+5) GoParser 31.6MB ± 0% 31.1MB ± 0% -1.66% (p=0.008 n=5+5) Reflect 77.1MB ± 0% 75.8MB ± 0% -1.69% (p=0.008 n=5+5) Tar 26.3MB ± 0% 25.7MB ± 0% -2.06% (p=0.008 n=5+5) XML 41.9MB ± 0% 41.1MB ± 0% -1.93% (p=0.008 n=5+5) [Geo mean] 73.5MB 72.0MB -2.03% name old allocs/op new allocs/op delta Template 383k ± 0% 383k ± 0% ~ (p=0.690 n=5+5) Unicode 343k ± 0% 343k ± 0% ~ (p=0.841 n=5+5) GoTypes 1.16M ± 0% 1.16M ± 0% ~ (p=0.310 n=5+5) Compiler 4.43M ± 0% 4.42M ± 0% -0.17% (p=0.008 n=5+5) SSA 9.85M ± 0% 9.85M ± 0% ~ (p=0.310 n=5+5) Flate 236k ± 0% 236k ± 1% ~ (p=0.841 n=5+5) GoParser 320k ± 0% 320k ± 0% ~ (p=0.421 n=5+5) Reflect 988k ± 0% 987k ± 0% ~ (p=0.690 n=5+5) Tar 252k ± 0% 251k ± 0% ~ (p=0.095 n=5+5) XML 399k ± 0% 399k ± 0% ~ (p=1.000 n=5+5) [Geo mean] 741k 740k -0.07% Change-Id: I9e952b58a98e30a12494304db9ce50d0a85e459c Reviewed-on: https://go-review.googlesource.com/41797 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Marvin Stenger <marvin.stenger94@gmail.com>
2017-04-25 18:14:12 -07:00
return n.Op == ONAME && n.Addable() && n.Class() != PAUTOHEAP && n.Class() != PEXTERN
}
func litas(l *Node, r *Node, init *Nodes) {
a := nod(OAS, l, r)
cmd/compile: reduce use of **Node parameters Escape analysis has a hard time with tree-like structures (see #13493 and #14858). This is unlikely to change. As a result, when invoking a function that accepts a **Node parameter, we usually allocate a *Node on the heap. This happens a whole lot. This CL changes functions from taking a **Node to acting more like append: It both modifies the input and returns a replacement for it. Because of the cascading nature of escape analysis, in order to get the benefits, I had to modify almost all such functions. The remaining functions are in racewalk and the backend. I would be happy to update them as well in a separate CL. This CL was created by manually updating the function signatures and the directly impacted bits of code. The callsites were then automatically updated using a bespoke script: https://gist.github.com/josharian/046b1be7aceae244de39 For ease of reviewing and future understanding, this CL is also broken down into four CLs, mailed separately, which show the manual and the automated changes separately. They are CLs 20990, 20991, 20992, and 20993. Passes toolstash -cmp. name old time/op new time/op delta Template 335ms ± 5% 324ms ± 5% -3.35% (p=0.000 n=23+24) Unicode 176ms ± 9% 165ms ± 6% -6.12% (p=0.000 n=23+24) GoTypes 1.10s ± 4% 1.07s ± 2% -2.77% (p=0.000 n=24+24) Compiler 5.31s ± 3% 5.15s ± 3% -2.95% (p=0.000 n=24+24) MakeBash 41.6s ± 1% 41.7s ± 2% ~ (p=0.586 n=23+23) name old alloc/op new alloc/op delta Template 63.3MB ± 0% 62.4MB ± 0% -1.36% (p=0.000 n=25+23) Unicode 42.4MB ± 0% 41.6MB ± 0% -1.99% (p=0.000 n=24+25) GoTypes 220MB ± 0% 217MB ± 0% -1.11% (p=0.000 n=25+25) Compiler 994MB ± 0% 973MB ± 0% -2.08% (p=0.000 n=24+25) name old allocs/op new allocs/op delta Template 681k ± 0% 574k ± 0% -15.71% (p=0.000 n=24+25) Unicode 518k ± 0% 413k ± 0% -20.34% (p=0.000 n=25+24) GoTypes 2.08M ± 0% 1.78M ± 0% -14.62% (p=0.000 n=25+25) Compiler 9.26M ± 0% 7.64M ± 0% -17.48% (p=0.000 n=25+25) name old text-bytes new text-bytes delta HelloSize 578k ± 0% 578k ± 0% ~ (all samples are equal) CmdGoSize 6.46M ± 0% 6.46M ± 0% ~ (all samples are equal) name old data-bytes new data-bytes delta HelloSize 128k ± 0% 128k ± 0% ~ (all samples are equal) CmdGoSize 281k ± 0% 281k ± 0% ~ (all samples are equal) name old exe-bytes new exe-bytes delta HelloSize 921k ± 0% 921k ± 0% ~ (all samples are equal) CmdGoSize 9.86M ± 0% 9.86M ± 0% ~ (all samples are equal) Change-Id: I277d95bd56d51c166ef7f560647aeaa092f3f475 Reviewed-on: https://go-review.googlesource.com/20959 Reviewed-by: Dave Cheney <dave@cheney.net> Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-03-20 08:03:31 -07:00
a = typecheck(a, Etop)
a = walkexpr(a, init)
init.Append(a)
}
// initGenType is a bitmap indicating the types of generation that will occur for a static value.
type initGenType uint8
const (
initDynamic initGenType = 1 << iota // contains some dynamic values, for which init code will be generated
initConst // contains some constant values, which may be written into data symbols
)
// getdyn calculates the initGenType for n.
// If top is false, getdyn is recursing.
func getdyn(n *Node, top bool) initGenType {
switch n.Op {
default:
if isLiteral(n) {
return initConst
}
return initDynamic
case OSLICELIT:
if !top {
return initDynamic
}
case OARRAYLIT, OSTRUCTLIT:
}
var mode initGenType
for _, n1 := range n.List.Slice() {
cmd/compile: stop adding implicit OKEY nodes Keys are uncommon in array and slice literals, and normalizing OARRAYLIT and OSLICELIT nodes to always use OKEY ends up not reducing complexity much. Instead, only create OKEY nodes to represent explicit keys, and recalculate implicit keys when/where necessary. Fixes #15350. name old time/op new time/op delta Template 299ms ± 9% 299ms ±12% ~ (p=0.694 n=28+30) Unicode 165ms ± 7% 162ms ± 9% ~ (p=0.084 n=27+27) GoTypes 950ms ± 9% 963ms ± 5% ~ (p=0.301 n=30+29) Compiler 4.23s ± 7% 4.17s ± 7% ~ (p=0.057 n=29+27) name old user-ns/op new user-ns/op delta Template 389M ±15% 400M ±12% ~ (p=0.202 n=30+29) Unicode 246M ±21% 232M ±22% -5.76% (p=0.006 n=28+29) GoTypes 1.34G ± 8% 1.34G ± 7% ~ (p=0.775 n=28+30) Compiler 5.91G ± 6% 5.87G ± 7% ~ (p=0.298 n=28+29) name old alloc/op new alloc/op delta Template 41.2MB ± 0% 41.2MB ± 0% ~ (p=0.085 n=30+30) Unicode 34.0MB ± 0% 31.5MB ± 0% -7.28% (p=0.000 n=30+29) GoTypes 121MB ± 0% 121MB ± 0% ~ (p=0.657 n=30+30) Compiler 511MB ± 0% 511MB ± 0% -0.01% (p=0.001 n=29+29) name old allocs/op new allocs/op delta Template 390k ± 0% 390k ± 0% ~ (p=0.225 n=30+29) Unicode 318k ± 0% 293k ± 0% -8.03% (p=0.000 n=30+29) GoTypes 1.16M ± 0% 1.16M ± 0% ~ (p=0.745 n=30+30) Compiler 4.35M ± 0% 4.35M ± 0% ~ (p=0.105 n=30+30) Change-Id: I6310739a0bfdb54f1ab8a460b2c03615ad1ff5bc Reviewed-on: https://go-review.googlesource.com/32221 Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-10-27 02:02:30 -07:00
switch n1.Op {
case OKEY:
n1 = n1.Right
case OSTRUCTKEY:
n1 = n1.Left
cmd/compile: add OSTRUCTKEY for keyed struct literals Previously, we used OKEY nodes to represent keyed struct literal elements. The field names were represented by an ONAME node, but this is clumsy because it's the only remaining case where ONAME was used to represent a bare identifier and not a variable. This CL introduces a new OSTRUCTKEY node op for use in struct literals. These ops instead store the field name in the node's own Sym field. This is similar in spirit to golang.org/cl/20890. Significant reduction in allocations for struct literal heavy code like package unicode: name old time/op new time/op delta Template 345ms ± 6% 341ms ± 6% ~ (p=0.141 n=29+28) Unicode 200ms ± 9% 184ms ± 7% -7.77% (p=0.000 n=29+30) GoTypes 1.04s ± 3% 1.05s ± 3% ~ (p=0.096 n=30+30) Compiler 4.47s ± 9% 4.49s ± 6% ~ (p=0.890 n=29+29) name old user-ns/op new user-ns/op delta Template 523M ±13% 516M ±17% ~ (p=0.400 n=29+30) Unicode 334M ±27% 314M ±30% ~ (p=0.093 n=30+30) GoTypes 1.53G ±10% 1.52G ±10% ~ (p=0.572 n=30+30) Compiler 6.28G ± 7% 6.34G ±11% ~ (p=0.300 n=30+30) name old alloc/op new alloc/op delta Template 44.5MB ± 0% 44.4MB ± 0% -0.35% (p=0.000 n=27+30) Unicode 39.2MB ± 0% 34.5MB ± 0% -11.79% (p=0.000 n=26+30) GoTypes 125MB ± 0% 125MB ± 0% -0.12% (p=0.000 n=29+30) Compiler 515MB ± 0% 515MB ± 0% -0.10% (p=0.000 n=29+30) name old allocs/op new allocs/op delta Template 426k ± 0% 424k ± 0% -0.39% (p=0.000 n=29+30) Unicode 374k ± 0% 323k ± 0% -13.67% (p=0.000 n=29+30) GoTypes 1.21M ± 0% 1.21M ± 0% -0.14% (p=0.000 n=29+29) Compiler 4.40M ± 0% 4.39M ± 0% -0.13% (p=0.000 n=29+30) Passes toolstash/buildall. Change-Id: Iba4ee765dd1748f67e52fcade1cd75c9f6e13fa9 Reviewed-on: https://go-review.googlesource.com/30974 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-10-12 15:48:18 -07:00
}
cmd/compile: stop adding implicit OKEY nodes Keys are uncommon in array and slice literals, and normalizing OARRAYLIT and OSLICELIT nodes to always use OKEY ends up not reducing complexity much. Instead, only create OKEY nodes to represent explicit keys, and recalculate implicit keys when/where necessary. Fixes #15350. name old time/op new time/op delta Template 299ms ± 9% 299ms ±12% ~ (p=0.694 n=28+30) Unicode 165ms ± 7% 162ms ± 9% ~ (p=0.084 n=27+27) GoTypes 950ms ± 9% 963ms ± 5% ~ (p=0.301 n=30+29) Compiler 4.23s ± 7% 4.17s ± 7% ~ (p=0.057 n=29+27) name old user-ns/op new user-ns/op delta Template 389M ±15% 400M ±12% ~ (p=0.202 n=30+29) Unicode 246M ±21% 232M ±22% -5.76% (p=0.006 n=28+29) GoTypes 1.34G ± 8% 1.34G ± 7% ~ (p=0.775 n=28+30) Compiler 5.91G ± 6% 5.87G ± 7% ~ (p=0.298 n=28+29) name old alloc/op new alloc/op delta Template 41.2MB ± 0% 41.2MB ± 0% ~ (p=0.085 n=30+30) Unicode 34.0MB ± 0% 31.5MB ± 0% -7.28% (p=0.000 n=30+29) GoTypes 121MB ± 0% 121MB ± 0% ~ (p=0.657 n=30+30) Compiler 511MB ± 0% 511MB ± 0% -0.01% (p=0.001 n=29+29) name old allocs/op new allocs/op delta Template 390k ± 0% 390k ± 0% ~ (p=0.225 n=30+29) Unicode 318k ± 0% 293k ± 0% -8.03% (p=0.000 n=30+29) GoTypes 1.16M ± 0% 1.16M ± 0% ~ (p=0.745 n=30+30) Compiler 4.35M ± 0% 4.35M ± 0% ~ (p=0.105 n=30+30) Change-Id: I6310739a0bfdb54f1ab8a460b2c03615ad1ff5bc Reviewed-on: https://go-review.googlesource.com/32221 Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-10-27 02:02:30 -07:00
mode |= getdyn(n1, false)
if mode == initDynamic|initConst {
break
}
}
return mode
}
// isStaticCompositeLiteral reports whether n is a compile-time constant.
func isStaticCompositeLiteral(n *Node) bool {
switch n.Op {
case OSLICELIT:
return false
cmd/compile: add OSTRUCTKEY for keyed struct literals Previously, we used OKEY nodes to represent keyed struct literal elements. The field names were represented by an ONAME node, but this is clumsy because it's the only remaining case where ONAME was used to represent a bare identifier and not a variable. This CL introduces a new OSTRUCTKEY node op for use in struct literals. These ops instead store the field name in the node's own Sym field. This is similar in spirit to golang.org/cl/20890. Significant reduction in allocations for struct literal heavy code like package unicode: name old time/op new time/op delta Template 345ms ± 6% 341ms ± 6% ~ (p=0.141 n=29+28) Unicode 200ms ± 9% 184ms ± 7% -7.77% (p=0.000 n=29+30) GoTypes 1.04s ± 3% 1.05s ± 3% ~ (p=0.096 n=30+30) Compiler 4.47s ± 9% 4.49s ± 6% ~ (p=0.890 n=29+29) name old user-ns/op new user-ns/op delta Template 523M ±13% 516M ±17% ~ (p=0.400 n=29+30) Unicode 334M ±27% 314M ±30% ~ (p=0.093 n=30+30) GoTypes 1.53G ±10% 1.52G ±10% ~ (p=0.572 n=30+30) Compiler 6.28G ± 7% 6.34G ±11% ~ (p=0.300 n=30+30) name old alloc/op new alloc/op delta Template 44.5MB ± 0% 44.4MB ± 0% -0.35% (p=0.000 n=27+30) Unicode 39.2MB ± 0% 34.5MB ± 0% -11.79% (p=0.000 n=26+30) GoTypes 125MB ± 0% 125MB ± 0% -0.12% (p=0.000 n=29+30) Compiler 515MB ± 0% 515MB ± 0% -0.10% (p=0.000 n=29+30) name old allocs/op new allocs/op delta Template 426k ± 0% 424k ± 0% -0.39% (p=0.000 n=29+30) Unicode 374k ± 0% 323k ± 0% -13.67% (p=0.000 n=29+30) GoTypes 1.21M ± 0% 1.21M ± 0% -0.14% (p=0.000 n=29+29) Compiler 4.40M ± 0% 4.39M ± 0% -0.13% (p=0.000 n=29+30) Passes toolstash/buildall. Change-Id: Iba4ee765dd1748f67e52fcade1cd75c9f6e13fa9 Reviewed-on: https://go-review.googlesource.com/30974 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-10-12 15:48:18 -07:00
case OARRAYLIT:
for _, r := range n.List.Slice() {
cmd/compile: stop adding implicit OKEY nodes Keys are uncommon in array and slice literals, and normalizing OARRAYLIT and OSLICELIT nodes to always use OKEY ends up not reducing complexity much. Instead, only create OKEY nodes to represent explicit keys, and recalculate implicit keys when/where necessary. Fixes #15350. name old time/op new time/op delta Template 299ms ± 9% 299ms ±12% ~ (p=0.694 n=28+30) Unicode 165ms ± 7% 162ms ± 9% ~ (p=0.084 n=27+27) GoTypes 950ms ± 9% 963ms ± 5% ~ (p=0.301 n=30+29) Compiler 4.23s ± 7% 4.17s ± 7% ~ (p=0.057 n=29+27) name old user-ns/op new user-ns/op delta Template 389M ±15% 400M ±12% ~ (p=0.202 n=30+29) Unicode 246M ±21% 232M ±22% -5.76% (p=0.006 n=28+29) GoTypes 1.34G ± 8% 1.34G ± 7% ~ (p=0.775 n=28+30) Compiler 5.91G ± 6% 5.87G ± 7% ~ (p=0.298 n=28+29) name old alloc/op new alloc/op delta Template 41.2MB ± 0% 41.2MB ± 0% ~ (p=0.085 n=30+30) Unicode 34.0MB ± 0% 31.5MB ± 0% -7.28% (p=0.000 n=30+29) GoTypes 121MB ± 0% 121MB ± 0% ~ (p=0.657 n=30+30) Compiler 511MB ± 0% 511MB ± 0% -0.01% (p=0.001 n=29+29) name old allocs/op new allocs/op delta Template 390k ± 0% 390k ± 0% ~ (p=0.225 n=30+29) Unicode 318k ± 0% 293k ± 0% -8.03% (p=0.000 n=30+29) GoTypes 1.16M ± 0% 1.16M ± 0% ~ (p=0.745 n=30+30) Compiler 4.35M ± 0% 4.35M ± 0% ~ (p=0.105 n=30+30) Change-Id: I6310739a0bfdb54f1ab8a460b2c03615ad1ff5bc Reviewed-on: https://go-review.googlesource.com/32221 Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-10-27 02:02:30 -07:00
if r.Op == OKEY {
r = r.Right
}
cmd/compile: stop adding implicit OKEY nodes Keys are uncommon in array and slice literals, and normalizing OARRAYLIT and OSLICELIT nodes to always use OKEY ends up not reducing complexity much. Instead, only create OKEY nodes to represent explicit keys, and recalculate implicit keys when/where necessary. Fixes #15350. name old time/op new time/op delta Template 299ms ± 9% 299ms ±12% ~ (p=0.694 n=28+30) Unicode 165ms ± 7% 162ms ± 9% ~ (p=0.084 n=27+27) GoTypes 950ms ± 9% 963ms ± 5% ~ (p=0.301 n=30+29) Compiler 4.23s ± 7% 4.17s ± 7% ~ (p=0.057 n=29+27) name old user-ns/op new user-ns/op delta Template 389M ±15% 400M ±12% ~ (p=0.202 n=30+29) Unicode 246M ±21% 232M ±22% -5.76% (p=0.006 n=28+29) GoTypes 1.34G ± 8% 1.34G ± 7% ~ (p=0.775 n=28+30) Compiler 5.91G ± 6% 5.87G ± 7% ~ (p=0.298 n=28+29) name old alloc/op new alloc/op delta Template 41.2MB ± 0% 41.2MB ± 0% ~ (p=0.085 n=30+30) Unicode 34.0MB ± 0% 31.5MB ± 0% -7.28% (p=0.000 n=30+29) GoTypes 121MB ± 0% 121MB ± 0% ~ (p=0.657 n=30+30) Compiler 511MB ± 0% 511MB ± 0% -0.01% (p=0.001 n=29+29) name old allocs/op new allocs/op delta Template 390k ± 0% 390k ± 0% ~ (p=0.225 n=30+29) Unicode 318k ± 0% 293k ± 0% -8.03% (p=0.000 n=30+29) GoTypes 1.16M ± 0% 1.16M ± 0% ~ (p=0.745 n=30+30) Compiler 4.35M ± 0% 4.35M ± 0% ~ (p=0.105 n=30+30) Change-Id: I6310739a0bfdb54f1ab8a460b2c03615ad1ff5bc Reviewed-on: https://go-review.googlesource.com/32221 Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-10-27 02:02:30 -07:00
if !isStaticCompositeLiteral(r) {
return false
}
cmd/compile: add OSTRUCTKEY for keyed struct literals Previously, we used OKEY nodes to represent keyed struct literal elements. The field names were represented by an ONAME node, but this is clumsy because it's the only remaining case where ONAME was used to represent a bare identifier and not a variable. This CL introduces a new OSTRUCTKEY node op for use in struct literals. These ops instead store the field name in the node's own Sym field. This is similar in spirit to golang.org/cl/20890. Significant reduction in allocations for struct literal heavy code like package unicode: name old time/op new time/op delta Template 345ms ± 6% 341ms ± 6% ~ (p=0.141 n=29+28) Unicode 200ms ± 9% 184ms ± 7% -7.77% (p=0.000 n=29+30) GoTypes 1.04s ± 3% 1.05s ± 3% ~ (p=0.096 n=30+30) Compiler 4.47s ± 9% 4.49s ± 6% ~ (p=0.890 n=29+29) name old user-ns/op new user-ns/op delta Template 523M ±13% 516M ±17% ~ (p=0.400 n=29+30) Unicode 334M ±27% 314M ±30% ~ (p=0.093 n=30+30) GoTypes 1.53G ±10% 1.52G ±10% ~ (p=0.572 n=30+30) Compiler 6.28G ± 7% 6.34G ±11% ~ (p=0.300 n=30+30) name old alloc/op new alloc/op delta Template 44.5MB ± 0% 44.4MB ± 0% -0.35% (p=0.000 n=27+30) Unicode 39.2MB ± 0% 34.5MB ± 0% -11.79% (p=0.000 n=26+30) GoTypes 125MB ± 0% 125MB ± 0% -0.12% (p=0.000 n=29+30) Compiler 515MB ± 0% 515MB ± 0% -0.10% (p=0.000 n=29+30) name old allocs/op new allocs/op delta Template 426k ± 0% 424k ± 0% -0.39% (p=0.000 n=29+30) Unicode 374k ± 0% 323k ± 0% -13.67% (p=0.000 n=29+30) GoTypes 1.21M ± 0% 1.21M ± 0% -0.14% (p=0.000 n=29+29) Compiler 4.40M ± 0% 4.39M ± 0% -0.13% (p=0.000 n=29+30) Passes toolstash/buildall. Change-Id: Iba4ee765dd1748f67e52fcade1cd75c9f6e13fa9 Reviewed-on: https://go-review.googlesource.com/30974 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-10-12 15:48:18 -07:00
}
return true
case OSTRUCTLIT:
for _, r := range n.List.Slice() {
if r.Op != OSTRUCTKEY {
Fatalf("isStaticCompositeLiteral: rhs not OSTRUCTKEY: %v", r)
}
if !isStaticCompositeLiteral(r.Left) {
return false
}
}
return true
case OLITERAL:
return true
case OCONVIFACE:
// See staticassign's OCONVIFACE case for comments.
val := n
for val.Op == OCONVIFACE {
val = val.Left
}
if val.Type.IsInterface() {
return Isconst(val, CTNIL)
}
if isdirectiface(val.Type) && Isconst(val, CTNIL) {
return true
}
return isStaticCompositeLiteral(val)
}
return false
}
// initKind is a kind of static initialization: static, dynamic, or local.
// Static initialization represents literals and
// literal components of composite literals.
// Dynamic initialization represents non-literals and
// non-literal components of composite literals.
// LocalCode initializion represents initialization
// that occurs purely in generated code local to the function of use.
// Initialization code is sometimes generated in passes,
// first static then dynamic.
type initKind uint8
const (
initKindStatic initKind = iota + 1
initKindDynamic
initKindLocalCode
)
// fixedlit handles struct, array, and slice literals.
// TODO: expand documentation.
func fixedlit(ctxt initContext, kind initKind, n *Node, var_ *Node, init *Nodes) {
cmd/compile: add OSTRUCTKEY for keyed struct literals Previously, we used OKEY nodes to represent keyed struct literal elements. The field names were represented by an ONAME node, but this is clumsy because it's the only remaining case where ONAME was used to represent a bare identifier and not a variable. This CL introduces a new OSTRUCTKEY node op for use in struct literals. These ops instead store the field name in the node's own Sym field. This is similar in spirit to golang.org/cl/20890. Significant reduction in allocations for struct literal heavy code like package unicode: name old time/op new time/op delta Template 345ms ± 6% 341ms ± 6% ~ (p=0.141 n=29+28) Unicode 200ms ± 9% 184ms ± 7% -7.77% (p=0.000 n=29+30) GoTypes 1.04s ± 3% 1.05s ± 3% ~ (p=0.096 n=30+30) Compiler 4.47s ± 9% 4.49s ± 6% ~ (p=0.890 n=29+29) name old user-ns/op new user-ns/op delta Template 523M ±13% 516M ±17% ~ (p=0.400 n=29+30) Unicode 334M ±27% 314M ±30% ~ (p=0.093 n=30+30) GoTypes 1.53G ±10% 1.52G ±10% ~ (p=0.572 n=30+30) Compiler 6.28G ± 7% 6.34G ±11% ~ (p=0.300 n=30+30) name old alloc/op new alloc/op delta Template 44.5MB ± 0% 44.4MB ± 0% -0.35% (p=0.000 n=27+30) Unicode 39.2MB ± 0% 34.5MB ± 0% -11.79% (p=0.000 n=26+30) GoTypes 125MB ± 0% 125MB ± 0% -0.12% (p=0.000 n=29+30) Compiler 515MB ± 0% 515MB ± 0% -0.10% (p=0.000 n=29+30) name old allocs/op new allocs/op delta Template 426k ± 0% 424k ± 0% -0.39% (p=0.000 n=29+30) Unicode 374k ± 0% 323k ± 0% -13.67% (p=0.000 n=29+30) GoTypes 1.21M ± 0% 1.21M ± 0% -0.14% (p=0.000 n=29+29) Compiler 4.40M ± 0% 4.39M ± 0% -0.13% (p=0.000 n=29+30) Passes toolstash/buildall. Change-Id: Iba4ee765dd1748f67e52fcade1cd75c9f6e13fa9 Reviewed-on: https://go-review.googlesource.com/30974 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-10-12 15:48:18 -07:00
var splitnode func(*Node) (a *Node, value *Node)
switch n.Op {
case OARRAYLIT, OSLICELIT:
cmd/compile: stop adding implicit OKEY nodes Keys are uncommon in array and slice literals, and normalizing OARRAYLIT and OSLICELIT nodes to always use OKEY ends up not reducing complexity much. Instead, only create OKEY nodes to represent explicit keys, and recalculate implicit keys when/where necessary. Fixes #15350. name old time/op new time/op delta Template 299ms ± 9% 299ms ±12% ~ (p=0.694 n=28+30) Unicode 165ms ± 7% 162ms ± 9% ~ (p=0.084 n=27+27) GoTypes 950ms ± 9% 963ms ± 5% ~ (p=0.301 n=30+29) Compiler 4.23s ± 7% 4.17s ± 7% ~ (p=0.057 n=29+27) name old user-ns/op new user-ns/op delta Template 389M ±15% 400M ±12% ~ (p=0.202 n=30+29) Unicode 246M ±21% 232M ±22% -5.76% (p=0.006 n=28+29) GoTypes 1.34G ± 8% 1.34G ± 7% ~ (p=0.775 n=28+30) Compiler 5.91G ± 6% 5.87G ± 7% ~ (p=0.298 n=28+29) name old alloc/op new alloc/op delta Template 41.2MB ± 0% 41.2MB ± 0% ~ (p=0.085 n=30+30) Unicode 34.0MB ± 0% 31.5MB ± 0% -7.28% (p=0.000 n=30+29) GoTypes 121MB ± 0% 121MB ± 0% ~ (p=0.657 n=30+30) Compiler 511MB ± 0% 511MB ± 0% -0.01% (p=0.001 n=29+29) name old allocs/op new allocs/op delta Template 390k ± 0% 390k ± 0% ~ (p=0.225 n=30+29) Unicode 318k ± 0% 293k ± 0% -8.03% (p=0.000 n=30+29) GoTypes 1.16M ± 0% 1.16M ± 0% ~ (p=0.745 n=30+30) Compiler 4.35M ± 0% 4.35M ± 0% ~ (p=0.105 n=30+30) Change-Id: I6310739a0bfdb54f1ab8a460b2c03615ad1ff5bc Reviewed-on: https://go-review.googlesource.com/32221 Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-10-27 02:02:30 -07:00
var k int64
cmd/compile: add OSTRUCTKEY for keyed struct literals Previously, we used OKEY nodes to represent keyed struct literal elements. The field names were represented by an ONAME node, but this is clumsy because it's the only remaining case where ONAME was used to represent a bare identifier and not a variable. This CL introduces a new OSTRUCTKEY node op for use in struct literals. These ops instead store the field name in the node's own Sym field. This is similar in spirit to golang.org/cl/20890. Significant reduction in allocations for struct literal heavy code like package unicode: name old time/op new time/op delta Template 345ms ± 6% 341ms ± 6% ~ (p=0.141 n=29+28) Unicode 200ms ± 9% 184ms ± 7% -7.77% (p=0.000 n=29+30) GoTypes 1.04s ± 3% 1.05s ± 3% ~ (p=0.096 n=30+30) Compiler 4.47s ± 9% 4.49s ± 6% ~ (p=0.890 n=29+29) name old user-ns/op new user-ns/op delta Template 523M ±13% 516M ±17% ~ (p=0.400 n=29+30) Unicode 334M ±27% 314M ±30% ~ (p=0.093 n=30+30) GoTypes 1.53G ±10% 1.52G ±10% ~ (p=0.572 n=30+30) Compiler 6.28G ± 7% 6.34G ±11% ~ (p=0.300 n=30+30) name old alloc/op new alloc/op delta Template 44.5MB ± 0% 44.4MB ± 0% -0.35% (p=0.000 n=27+30) Unicode 39.2MB ± 0% 34.5MB ± 0% -11.79% (p=0.000 n=26+30) GoTypes 125MB ± 0% 125MB ± 0% -0.12% (p=0.000 n=29+30) Compiler 515MB ± 0% 515MB ± 0% -0.10% (p=0.000 n=29+30) name old allocs/op new allocs/op delta Template 426k ± 0% 424k ± 0% -0.39% (p=0.000 n=29+30) Unicode 374k ± 0% 323k ± 0% -13.67% (p=0.000 n=29+30) GoTypes 1.21M ± 0% 1.21M ± 0% -0.14% (p=0.000 n=29+29) Compiler 4.40M ± 0% 4.39M ± 0% -0.13% (p=0.000 n=29+30) Passes toolstash/buildall. Change-Id: Iba4ee765dd1748f67e52fcade1cd75c9f6e13fa9 Reviewed-on: https://go-review.googlesource.com/30974 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-10-12 15:48:18 -07:00
splitnode = func(r *Node) (*Node, *Node) {
cmd/compile: stop adding implicit OKEY nodes Keys are uncommon in array and slice literals, and normalizing OARRAYLIT and OSLICELIT nodes to always use OKEY ends up not reducing complexity much. Instead, only create OKEY nodes to represent explicit keys, and recalculate implicit keys when/where necessary. Fixes #15350. name old time/op new time/op delta Template 299ms ± 9% 299ms ±12% ~ (p=0.694 n=28+30) Unicode 165ms ± 7% 162ms ± 9% ~ (p=0.084 n=27+27) GoTypes 950ms ± 9% 963ms ± 5% ~ (p=0.301 n=30+29) Compiler 4.23s ± 7% 4.17s ± 7% ~ (p=0.057 n=29+27) name old user-ns/op new user-ns/op delta Template 389M ±15% 400M ±12% ~ (p=0.202 n=30+29) Unicode 246M ±21% 232M ±22% -5.76% (p=0.006 n=28+29) GoTypes 1.34G ± 8% 1.34G ± 7% ~ (p=0.775 n=28+30) Compiler 5.91G ± 6% 5.87G ± 7% ~ (p=0.298 n=28+29) name old alloc/op new alloc/op delta Template 41.2MB ± 0% 41.2MB ± 0% ~ (p=0.085 n=30+30) Unicode 34.0MB ± 0% 31.5MB ± 0% -7.28% (p=0.000 n=30+29) GoTypes 121MB ± 0% 121MB ± 0% ~ (p=0.657 n=30+30) Compiler 511MB ± 0% 511MB ± 0% -0.01% (p=0.001 n=29+29) name old allocs/op new allocs/op delta Template 390k ± 0% 390k ± 0% ~ (p=0.225 n=30+29) Unicode 318k ± 0% 293k ± 0% -8.03% (p=0.000 n=30+29) GoTypes 1.16M ± 0% 1.16M ± 0% ~ (p=0.745 n=30+30) Compiler 4.35M ± 0% 4.35M ± 0% ~ (p=0.105 n=30+30) Change-Id: I6310739a0bfdb54f1ab8a460b2c03615ad1ff5bc Reviewed-on: https://go-review.googlesource.com/32221 Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-10-27 02:02:30 -07:00
if r.Op == OKEY {
k = nonnegintconst(r.Left)
r = r.Right
cmd/compile: add OSTRUCTKEY for keyed struct literals Previously, we used OKEY nodes to represent keyed struct literal elements. The field names were represented by an ONAME node, but this is clumsy because it's the only remaining case where ONAME was used to represent a bare identifier and not a variable. This CL introduces a new OSTRUCTKEY node op for use in struct literals. These ops instead store the field name in the node's own Sym field. This is similar in spirit to golang.org/cl/20890. Significant reduction in allocations for struct literal heavy code like package unicode: name old time/op new time/op delta Template 345ms ± 6% 341ms ± 6% ~ (p=0.141 n=29+28) Unicode 200ms ± 9% 184ms ± 7% -7.77% (p=0.000 n=29+30) GoTypes 1.04s ± 3% 1.05s ± 3% ~ (p=0.096 n=30+30) Compiler 4.47s ± 9% 4.49s ± 6% ~ (p=0.890 n=29+29) name old user-ns/op new user-ns/op delta Template 523M ±13% 516M ±17% ~ (p=0.400 n=29+30) Unicode 334M ±27% 314M ±30% ~ (p=0.093 n=30+30) GoTypes 1.53G ±10% 1.52G ±10% ~ (p=0.572 n=30+30) Compiler 6.28G ± 7% 6.34G ±11% ~ (p=0.300 n=30+30) name old alloc/op new alloc/op delta Template 44.5MB ± 0% 44.4MB ± 0% -0.35% (p=0.000 n=27+30) Unicode 39.2MB ± 0% 34.5MB ± 0% -11.79% (p=0.000 n=26+30) GoTypes 125MB ± 0% 125MB ± 0% -0.12% (p=0.000 n=29+30) Compiler 515MB ± 0% 515MB ± 0% -0.10% (p=0.000 n=29+30) name old allocs/op new allocs/op delta Template 426k ± 0% 424k ± 0% -0.39% (p=0.000 n=29+30) Unicode 374k ± 0% 323k ± 0% -13.67% (p=0.000 n=29+30) GoTypes 1.21M ± 0% 1.21M ± 0% -0.14% (p=0.000 n=29+29) Compiler 4.40M ± 0% 4.39M ± 0% -0.13% (p=0.000 n=29+30) Passes toolstash/buildall. Change-Id: Iba4ee765dd1748f67e52fcade1cd75c9f6e13fa9 Reviewed-on: https://go-review.googlesource.com/30974 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-10-12 15:48:18 -07:00
}
cmd/compile: stop adding implicit OKEY nodes Keys are uncommon in array and slice literals, and normalizing OARRAYLIT and OSLICELIT nodes to always use OKEY ends up not reducing complexity much. Instead, only create OKEY nodes to represent explicit keys, and recalculate implicit keys when/where necessary. Fixes #15350. name old time/op new time/op delta Template 299ms ± 9% 299ms ±12% ~ (p=0.694 n=28+30) Unicode 165ms ± 7% 162ms ± 9% ~ (p=0.084 n=27+27) GoTypes 950ms ± 9% 963ms ± 5% ~ (p=0.301 n=30+29) Compiler 4.23s ± 7% 4.17s ± 7% ~ (p=0.057 n=29+27) name old user-ns/op new user-ns/op delta Template 389M ±15% 400M ±12% ~ (p=0.202 n=30+29) Unicode 246M ±21% 232M ±22% -5.76% (p=0.006 n=28+29) GoTypes 1.34G ± 8% 1.34G ± 7% ~ (p=0.775 n=28+30) Compiler 5.91G ± 6% 5.87G ± 7% ~ (p=0.298 n=28+29) name old alloc/op new alloc/op delta Template 41.2MB ± 0% 41.2MB ± 0% ~ (p=0.085 n=30+30) Unicode 34.0MB ± 0% 31.5MB ± 0% -7.28% (p=0.000 n=30+29) GoTypes 121MB ± 0% 121MB ± 0% ~ (p=0.657 n=30+30) Compiler 511MB ± 0% 511MB ± 0% -0.01% (p=0.001 n=29+29) name old allocs/op new allocs/op delta Template 390k ± 0% 390k ± 0% ~ (p=0.225 n=30+29) Unicode 318k ± 0% 293k ± 0% -8.03% (p=0.000 n=30+29) GoTypes 1.16M ± 0% 1.16M ± 0% ~ (p=0.745 n=30+30) Compiler 4.35M ± 0% 4.35M ± 0% ~ (p=0.105 n=30+30) Change-Id: I6310739a0bfdb54f1ab8a460b2c03615ad1ff5bc Reviewed-on: https://go-review.googlesource.com/32221 Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-10-27 02:02:30 -07:00
a := nod(OINDEX, var_, nodintconst(k))
k++
return a, r
cmd/compile: add OSTRUCTKEY for keyed struct literals Previously, we used OKEY nodes to represent keyed struct literal elements. The field names were represented by an ONAME node, but this is clumsy because it's the only remaining case where ONAME was used to represent a bare identifier and not a variable. This CL introduces a new OSTRUCTKEY node op for use in struct literals. These ops instead store the field name in the node's own Sym field. This is similar in spirit to golang.org/cl/20890. Significant reduction in allocations for struct literal heavy code like package unicode: name old time/op new time/op delta Template 345ms ± 6% 341ms ± 6% ~ (p=0.141 n=29+28) Unicode 200ms ± 9% 184ms ± 7% -7.77% (p=0.000 n=29+30) GoTypes 1.04s ± 3% 1.05s ± 3% ~ (p=0.096 n=30+30) Compiler 4.47s ± 9% 4.49s ± 6% ~ (p=0.890 n=29+29) name old user-ns/op new user-ns/op delta Template 523M ±13% 516M ±17% ~ (p=0.400 n=29+30) Unicode 334M ±27% 314M ±30% ~ (p=0.093 n=30+30) GoTypes 1.53G ±10% 1.52G ±10% ~ (p=0.572 n=30+30) Compiler 6.28G ± 7% 6.34G ±11% ~ (p=0.300 n=30+30) name old alloc/op new alloc/op delta Template 44.5MB ± 0% 44.4MB ± 0% -0.35% (p=0.000 n=27+30) Unicode 39.2MB ± 0% 34.5MB ± 0% -11.79% (p=0.000 n=26+30) GoTypes 125MB ± 0% 125MB ± 0% -0.12% (p=0.000 n=29+30) Compiler 515MB ± 0% 515MB ± 0% -0.10% (p=0.000 n=29+30) name old allocs/op new allocs/op delta Template 426k ± 0% 424k ± 0% -0.39% (p=0.000 n=29+30) Unicode 374k ± 0% 323k ± 0% -13.67% (p=0.000 n=29+30) GoTypes 1.21M ± 0% 1.21M ± 0% -0.14% (p=0.000 n=29+29) Compiler 4.40M ± 0% 4.39M ± 0% -0.13% (p=0.000 n=29+30) Passes toolstash/buildall. Change-Id: Iba4ee765dd1748f67e52fcade1cd75c9f6e13fa9 Reviewed-on: https://go-review.googlesource.com/30974 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-10-12 15:48:18 -07:00
}
case OSTRUCTLIT:
cmd/compile: add OSTRUCTKEY for keyed struct literals Previously, we used OKEY nodes to represent keyed struct literal elements. The field names were represented by an ONAME node, but this is clumsy because it's the only remaining case where ONAME was used to represent a bare identifier and not a variable. This CL introduces a new OSTRUCTKEY node op for use in struct literals. These ops instead store the field name in the node's own Sym field. This is similar in spirit to golang.org/cl/20890. Significant reduction in allocations for struct literal heavy code like package unicode: name old time/op new time/op delta Template 345ms ± 6% 341ms ± 6% ~ (p=0.141 n=29+28) Unicode 200ms ± 9% 184ms ± 7% -7.77% (p=0.000 n=29+30) GoTypes 1.04s ± 3% 1.05s ± 3% ~ (p=0.096 n=30+30) Compiler 4.47s ± 9% 4.49s ± 6% ~ (p=0.890 n=29+29) name old user-ns/op new user-ns/op delta Template 523M ±13% 516M ±17% ~ (p=0.400 n=29+30) Unicode 334M ±27% 314M ±30% ~ (p=0.093 n=30+30) GoTypes 1.53G ±10% 1.52G ±10% ~ (p=0.572 n=30+30) Compiler 6.28G ± 7% 6.34G ±11% ~ (p=0.300 n=30+30) name old alloc/op new alloc/op delta Template 44.5MB ± 0% 44.4MB ± 0% -0.35% (p=0.000 n=27+30) Unicode 39.2MB ± 0% 34.5MB ± 0% -11.79% (p=0.000 n=26+30) GoTypes 125MB ± 0% 125MB ± 0% -0.12% (p=0.000 n=29+30) Compiler 515MB ± 0% 515MB ± 0% -0.10% (p=0.000 n=29+30) name old allocs/op new allocs/op delta Template 426k ± 0% 424k ± 0% -0.39% (p=0.000 n=29+30) Unicode 374k ± 0% 323k ± 0% -13.67% (p=0.000 n=29+30) GoTypes 1.21M ± 0% 1.21M ± 0% -0.14% (p=0.000 n=29+29) Compiler 4.40M ± 0% 4.39M ± 0% -0.13% (p=0.000 n=29+30) Passes toolstash/buildall. Change-Id: Iba4ee765dd1748f67e52fcade1cd75c9f6e13fa9 Reviewed-on: https://go-review.googlesource.com/30974 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-10-12 15:48:18 -07:00
splitnode = func(r *Node) (*Node, *Node) {
if r.Op != OSTRUCTKEY {
Fatalf("fixedlit: rhs not OSTRUCTKEY: %v", r)
}
if r.Sym.IsBlank() {
return nblank, r.Left
}
cmd/compile: add OSTRUCTKEY for keyed struct literals Previously, we used OKEY nodes to represent keyed struct literal elements. The field names were represented by an ONAME node, but this is clumsy because it's the only remaining case where ONAME was used to represent a bare identifier and not a variable. This CL introduces a new OSTRUCTKEY node op for use in struct literals. These ops instead store the field name in the node's own Sym field. This is similar in spirit to golang.org/cl/20890. Significant reduction in allocations for struct literal heavy code like package unicode: name old time/op new time/op delta Template 345ms ± 6% 341ms ± 6% ~ (p=0.141 n=29+28) Unicode 200ms ± 9% 184ms ± 7% -7.77% (p=0.000 n=29+30) GoTypes 1.04s ± 3% 1.05s ± 3% ~ (p=0.096 n=30+30) Compiler 4.47s ± 9% 4.49s ± 6% ~ (p=0.890 n=29+29) name old user-ns/op new user-ns/op delta Template 523M ±13% 516M ±17% ~ (p=0.400 n=29+30) Unicode 334M ±27% 314M ±30% ~ (p=0.093 n=30+30) GoTypes 1.53G ±10% 1.52G ±10% ~ (p=0.572 n=30+30) Compiler 6.28G ± 7% 6.34G ±11% ~ (p=0.300 n=30+30) name old alloc/op new alloc/op delta Template 44.5MB ± 0% 44.4MB ± 0% -0.35% (p=0.000 n=27+30) Unicode 39.2MB ± 0% 34.5MB ± 0% -11.79% (p=0.000 n=26+30) GoTypes 125MB ± 0% 125MB ± 0% -0.12% (p=0.000 n=29+30) Compiler 515MB ± 0% 515MB ± 0% -0.10% (p=0.000 n=29+30) name old allocs/op new allocs/op delta Template 426k ± 0% 424k ± 0% -0.39% (p=0.000 n=29+30) Unicode 374k ± 0% 323k ± 0% -13.67% (p=0.000 n=29+30) GoTypes 1.21M ± 0% 1.21M ± 0% -0.14% (p=0.000 n=29+29) Compiler 4.40M ± 0% 4.39M ± 0% -0.13% (p=0.000 n=29+30) Passes toolstash/buildall. Change-Id: Iba4ee765dd1748f67e52fcade1cd75c9f6e13fa9 Reviewed-on: https://go-review.googlesource.com/30974 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-10-12 15:48:18 -07:00
return nodSym(ODOT, var_, r.Sym), r.Left
}
default:
Fatalf("fixedlit bad op: %v", n.Op)
}
for _, r := range n.List.Slice() {
cmd/compile: add OSTRUCTKEY for keyed struct literals Previously, we used OKEY nodes to represent keyed struct literal elements. The field names were represented by an ONAME node, but this is clumsy because it's the only remaining case where ONAME was used to represent a bare identifier and not a variable. This CL introduces a new OSTRUCTKEY node op for use in struct literals. These ops instead store the field name in the node's own Sym field. This is similar in spirit to golang.org/cl/20890. Significant reduction in allocations for struct literal heavy code like package unicode: name old time/op new time/op delta Template 345ms ± 6% 341ms ± 6% ~ (p=0.141 n=29+28) Unicode 200ms ± 9% 184ms ± 7% -7.77% (p=0.000 n=29+30) GoTypes 1.04s ± 3% 1.05s ± 3% ~ (p=0.096 n=30+30) Compiler 4.47s ± 9% 4.49s ± 6% ~ (p=0.890 n=29+29) name old user-ns/op new user-ns/op delta Template 523M ±13% 516M ±17% ~ (p=0.400 n=29+30) Unicode 334M ±27% 314M ±30% ~ (p=0.093 n=30+30) GoTypes 1.53G ±10% 1.52G ±10% ~ (p=0.572 n=30+30) Compiler 6.28G ± 7% 6.34G ±11% ~ (p=0.300 n=30+30) name old alloc/op new alloc/op delta Template 44.5MB ± 0% 44.4MB ± 0% -0.35% (p=0.000 n=27+30) Unicode 39.2MB ± 0% 34.5MB ± 0% -11.79% (p=0.000 n=26+30) GoTypes 125MB ± 0% 125MB ± 0% -0.12% (p=0.000 n=29+30) Compiler 515MB ± 0% 515MB ± 0% -0.10% (p=0.000 n=29+30) name old allocs/op new allocs/op delta Template 426k ± 0% 424k ± 0% -0.39% (p=0.000 n=29+30) Unicode 374k ± 0% 323k ± 0% -13.67% (p=0.000 n=29+30) GoTypes 1.21M ± 0% 1.21M ± 0% -0.14% (p=0.000 n=29+29) Compiler 4.40M ± 0% 4.39M ± 0% -0.13% (p=0.000 n=29+30) Passes toolstash/buildall. Change-Id: Iba4ee765dd1748f67e52fcade1cd75c9f6e13fa9 Reviewed-on: https://go-review.googlesource.com/30974 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-10-12 15:48:18 -07:00
a, value := splitnode(r)
switch value.Op {
case OSLICELIT:
if (kind == initKindStatic && ctxt == inNonInitFunction) || (kind == initKindDynamic && ctxt == inInitFunction) {
slicelit(ctxt, value, a, init)
continue
}
case OARRAYLIT, OSTRUCTLIT:
fixedlit(ctxt, kind, value, a, init)
continue
}
islit := isLiteral(value)
if (kind == initKindStatic && !islit) || (kind == initKindDynamic && islit) {
continue
}
// build list of assignments: var[index] = expr
setlineno(value)
cmd/compile: add OSTRUCTKEY for keyed struct literals Previously, we used OKEY nodes to represent keyed struct literal elements. The field names were represented by an ONAME node, but this is clumsy because it's the only remaining case where ONAME was used to represent a bare identifier and not a variable. This CL introduces a new OSTRUCTKEY node op for use in struct literals. These ops instead store the field name in the node's own Sym field. This is similar in spirit to golang.org/cl/20890. Significant reduction in allocations for struct literal heavy code like package unicode: name old time/op new time/op delta Template 345ms ± 6% 341ms ± 6% ~ (p=0.141 n=29+28) Unicode 200ms ± 9% 184ms ± 7% -7.77% (p=0.000 n=29+30) GoTypes 1.04s ± 3% 1.05s ± 3% ~ (p=0.096 n=30+30) Compiler 4.47s ± 9% 4.49s ± 6% ~ (p=0.890 n=29+29) name old user-ns/op new user-ns/op delta Template 523M ±13% 516M ±17% ~ (p=0.400 n=29+30) Unicode 334M ±27% 314M ±30% ~ (p=0.093 n=30+30) GoTypes 1.53G ±10% 1.52G ±10% ~ (p=0.572 n=30+30) Compiler 6.28G ± 7% 6.34G ±11% ~ (p=0.300 n=30+30) name old alloc/op new alloc/op delta Template 44.5MB ± 0% 44.4MB ± 0% -0.35% (p=0.000 n=27+30) Unicode 39.2MB ± 0% 34.5MB ± 0% -11.79% (p=0.000 n=26+30) GoTypes 125MB ± 0% 125MB ± 0% -0.12% (p=0.000 n=29+30) Compiler 515MB ± 0% 515MB ± 0% -0.10% (p=0.000 n=29+30) name old allocs/op new allocs/op delta Template 426k ± 0% 424k ± 0% -0.39% (p=0.000 n=29+30) Unicode 374k ± 0% 323k ± 0% -13.67% (p=0.000 n=29+30) GoTypes 1.21M ± 0% 1.21M ± 0% -0.14% (p=0.000 n=29+29) Compiler 4.40M ± 0% 4.39M ± 0% -0.13% (p=0.000 n=29+30) Passes toolstash/buildall. Change-Id: Iba4ee765dd1748f67e52fcade1cd75c9f6e13fa9 Reviewed-on: https://go-review.googlesource.com/30974 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-10-12 15:48:18 -07:00
a = nod(OAS, a, value)
cmd/compile: reduce use of **Node parameters Escape analysis has a hard time with tree-like structures (see #13493 and #14858). This is unlikely to change. As a result, when invoking a function that accepts a **Node parameter, we usually allocate a *Node on the heap. This happens a whole lot. This CL changes functions from taking a **Node to acting more like append: It both modifies the input and returns a replacement for it. Because of the cascading nature of escape analysis, in order to get the benefits, I had to modify almost all such functions. The remaining functions are in racewalk and the backend. I would be happy to update them as well in a separate CL. This CL was created by manually updating the function signatures and the directly impacted bits of code. The callsites were then automatically updated using a bespoke script: https://gist.github.com/josharian/046b1be7aceae244de39 For ease of reviewing and future understanding, this CL is also broken down into four CLs, mailed separately, which show the manual and the automated changes separately. They are CLs 20990, 20991, 20992, and 20993. Passes toolstash -cmp. name old time/op new time/op delta Template 335ms ± 5% 324ms ± 5% -3.35% (p=0.000 n=23+24) Unicode 176ms ± 9% 165ms ± 6% -6.12% (p=0.000 n=23+24) GoTypes 1.10s ± 4% 1.07s ± 2% -2.77% (p=0.000 n=24+24) Compiler 5.31s ± 3% 5.15s ± 3% -2.95% (p=0.000 n=24+24) MakeBash 41.6s ± 1% 41.7s ± 2% ~ (p=0.586 n=23+23) name old alloc/op new alloc/op delta Template 63.3MB ± 0% 62.4MB ± 0% -1.36% (p=0.000 n=25+23) Unicode 42.4MB ± 0% 41.6MB ± 0% -1.99% (p=0.000 n=24+25) GoTypes 220MB ± 0% 217MB ± 0% -1.11% (p=0.000 n=25+25) Compiler 994MB ± 0% 973MB ± 0% -2.08% (p=0.000 n=24+25) name old allocs/op new allocs/op delta Template 681k ± 0% 574k ± 0% -15.71% (p=0.000 n=24+25) Unicode 518k ± 0% 413k ± 0% -20.34% (p=0.000 n=25+24) GoTypes 2.08M ± 0% 1.78M ± 0% -14.62% (p=0.000 n=25+25) Compiler 9.26M ± 0% 7.64M ± 0% -17.48% (p=0.000 n=25+25) name old text-bytes new text-bytes delta HelloSize 578k ± 0% 578k ± 0% ~ (all samples are equal) CmdGoSize 6.46M ± 0% 6.46M ± 0% ~ (all samples are equal) name old data-bytes new data-bytes delta HelloSize 128k ± 0% 128k ± 0% ~ (all samples are equal) CmdGoSize 281k ± 0% 281k ± 0% ~ (all samples are equal) name old exe-bytes new exe-bytes delta HelloSize 921k ± 0% 921k ± 0% ~ (all samples are equal) CmdGoSize 9.86M ± 0% 9.86M ± 0% ~ (all samples are equal) Change-Id: I277d95bd56d51c166ef7f560647aeaa092f3f475 Reviewed-on: https://go-review.googlesource.com/20959 Reviewed-by: Dave Cheney <dave@cheney.net> Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-03-20 08:03:31 -07:00
a = typecheck(a, Etop)
switch kind {
case initKindStatic:
genAsStatic(a)
case initKindDynamic, initKindLocalCode:
a = orderStmtInPlace(a)
cmd/compile: reduce use of **Node parameters Escape analysis has a hard time with tree-like structures (see #13493 and #14858). This is unlikely to change. As a result, when invoking a function that accepts a **Node parameter, we usually allocate a *Node on the heap. This happens a whole lot. This CL changes functions from taking a **Node to acting more like append: It both modifies the input and returns a replacement for it. Because of the cascading nature of escape analysis, in order to get the benefits, I had to modify almost all such functions. The remaining functions are in racewalk and the backend. I would be happy to update them as well in a separate CL. This CL was created by manually updating the function signatures and the directly impacted bits of code. The callsites were then automatically updated using a bespoke script: https://gist.github.com/josharian/046b1be7aceae244de39 For ease of reviewing and future understanding, this CL is also broken down into four CLs, mailed separately, which show the manual and the automated changes separately. They are CLs 20990, 20991, 20992, and 20993. Passes toolstash -cmp. name old time/op new time/op delta Template 335ms ± 5% 324ms ± 5% -3.35% (p=0.000 n=23+24) Unicode 176ms ± 9% 165ms ± 6% -6.12% (p=0.000 n=23+24) GoTypes 1.10s ± 4% 1.07s ± 2% -2.77% (p=0.000 n=24+24) Compiler 5.31s ± 3% 5.15s ± 3% -2.95% (p=0.000 n=24+24) MakeBash 41.6s ± 1% 41.7s ± 2% ~ (p=0.586 n=23+23) name old alloc/op new alloc/op delta Template 63.3MB ± 0% 62.4MB ± 0% -1.36% (p=0.000 n=25+23) Unicode 42.4MB ± 0% 41.6MB ± 0% -1.99% (p=0.000 n=24+25) GoTypes 220MB ± 0% 217MB ± 0% -1.11% (p=0.000 n=25+25) Compiler 994MB ± 0% 973MB ± 0% -2.08% (p=0.000 n=24+25) name old allocs/op new allocs/op delta Template 681k ± 0% 574k ± 0% -15.71% (p=0.000 n=24+25) Unicode 518k ± 0% 413k ± 0% -20.34% (p=0.000 n=25+24) GoTypes 2.08M ± 0% 1.78M ± 0% -14.62% (p=0.000 n=25+25) Compiler 9.26M ± 0% 7.64M ± 0% -17.48% (p=0.000 n=25+25) name old text-bytes new text-bytes delta HelloSize 578k ± 0% 578k ± 0% ~ (all samples are equal) CmdGoSize 6.46M ± 0% 6.46M ± 0% ~ (all samples are equal) name old data-bytes new data-bytes delta HelloSize 128k ± 0% 128k ± 0% ~ (all samples are equal) CmdGoSize 281k ± 0% 281k ± 0% ~ (all samples are equal) name old exe-bytes new exe-bytes delta HelloSize 921k ± 0% 921k ± 0% ~ (all samples are equal) CmdGoSize 9.86M ± 0% 9.86M ± 0% ~ (all samples are equal) Change-Id: I277d95bd56d51c166ef7f560647aeaa092f3f475 Reviewed-on: https://go-review.googlesource.com/20959 Reviewed-by: Dave Cheney <dave@cheney.net> Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-03-20 08:03:31 -07:00
a = walkstmt(a)
init.Append(a)
default:
Fatalf("fixedlit: bad kind %d", kind)
}
}
}
func slicelit(ctxt initContext, n *Node, var_ *Node, init *Nodes) {
// make an array type corresponding the number of elements we have
t := types.NewArray(n.Type.Elem(), n.Right.Int64())
dowidth(t)
if ctxt == inNonInitFunction {
// put everything into static array
vstat := staticname(t)
fixedlit(ctxt, initKindStatic, n, vstat, init)
fixedlit(ctxt, initKindDynamic, n, vstat, init)
// copy static to slice
var_ = typecheck(var_, Erv|Easgn)
var nam Node
cmd/compile: move Node.Class to flags Put it at position zero, since it is fairly hot. This shrinks gc.Node into a smaller size class on 64 bit systems. name old time/op new time/op delta Template 193ms ± 5% 192ms ± 3% ~ (p=0.353 n=94+93) Unicode 86.1ms ± 5% 85.0ms ± 4% -1.23% (p=0.000 n=95+98) GoTypes 546ms ± 3% 544ms ± 4% -0.40% (p=0.007 n=94+97) Compiler 2.56s ± 3% 2.54s ± 3% -0.67% (p=0.000 n=99+97) SSA 5.13s ± 2% 5.10s ± 3% -0.55% (p=0.000 n=94+98) Flate 122ms ± 6% 121ms ± 4% -0.75% (p=0.002 n=97+95) GoParser 144ms ± 5% 144ms ± 4% ~ (p=0.298 n=98+97) Reflect 348ms ± 4% 349ms ± 4% ~ (p=0.350 n=98+97) Tar 105ms ± 5% 104ms ± 5% ~ (p=0.154 n=96+98) XML 200ms ± 5% 198ms ± 4% -0.71% (p=0.015 n=97+98) [Geo mean] 330ms 328ms -0.52% name old user-time/op new user-time/op delta Template 229ms ±11% 224ms ± 7% -2.16% (p=0.001 n=100+87) Unicode 109ms ± 5% 109ms ± 6% ~ (p=0.897 n=96+91) GoTypes 712ms ± 4% 709ms ± 4% ~ (p=0.085 n=96+98) Compiler 3.41s ± 3% 3.36s ± 3% -1.43% (p=0.000 n=98+98) SSA 7.46s ± 3% 7.31s ± 3% -2.02% (p=0.000 n=100+99) Flate 145ms ± 6% 143ms ± 6% -1.11% (p=0.001 n=99+97) GoParser 177ms ± 5% 176ms ± 5% -0.78% (p=0.018 n=95+95) Reflect 432ms ± 7% 435ms ± 9% ~ (p=0.296 n=100+100) Tar 121ms ± 7% 121ms ± 5% ~ (p=0.072 n=100+95) XML 241ms ± 4% 239ms ± 5% ~ (p=0.085 n=97+99) [Geo mean] 413ms 410ms -0.73% name old alloc/op new alloc/op delta Template 38.4MB ± 0% 37.7MB ± 0% -1.85% (p=0.008 n=5+5) Unicode 30.1MB ± 0% 28.8MB ± 0% -4.09% (p=0.008 n=5+5) GoTypes 112MB ± 0% 110MB ± 0% -1.69% (p=0.008 n=5+5) Compiler 470MB ± 0% 461MB ± 0% -1.91% (p=0.008 n=5+5) SSA 1.13GB ± 0% 1.11GB ± 0% -1.70% (p=0.008 n=5+5) Flate 25.0MB ± 0% 24.6MB ± 0% -1.67% (p=0.008 n=5+5) GoParser 31.6MB ± 0% 31.1MB ± 0% -1.66% (p=0.008 n=5+5) Reflect 77.1MB ± 0% 75.8MB ± 0% -1.69% (p=0.008 n=5+5) Tar 26.3MB ± 0% 25.7MB ± 0% -2.06% (p=0.008 n=5+5) XML 41.9MB ± 0% 41.1MB ± 0% -1.93% (p=0.008 n=5+5) [Geo mean] 73.5MB 72.0MB -2.03% name old allocs/op new allocs/op delta Template 383k ± 0% 383k ± 0% ~ (p=0.690 n=5+5) Unicode 343k ± 0% 343k ± 0% ~ (p=0.841 n=5+5) GoTypes 1.16M ± 0% 1.16M ± 0% ~ (p=0.310 n=5+5) Compiler 4.43M ± 0% 4.42M ± 0% -0.17% (p=0.008 n=5+5) SSA 9.85M ± 0% 9.85M ± 0% ~ (p=0.310 n=5+5) Flate 236k ± 0% 236k ± 1% ~ (p=0.841 n=5+5) GoParser 320k ± 0% 320k ± 0% ~ (p=0.421 n=5+5) Reflect 988k ± 0% 987k ± 0% ~ (p=0.690 n=5+5) Tar 252k ± 0% 251k ± 0% ~ (p=0.095 n=5+5) XML 399k ± 0% 399k ± 0% ~ (p=1.000 n=5+5) [Geo mean] 741k 740k -0.07% Change-Id: I9e952b58a98e30a12494304db9ce50d0a85e459c Reviewed-on: https://go-review.googlesource.com/41797 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Marvin Stenger <marvin.stenger94@gmail.com>
2017-04-25 18:14:12 -07:00
if !stataddr(&nam, var_) || nam.Class() != PEXTERN {
Fatalf("slicelit: %v", var_)
}
var v Node
v.Type = types.Types[TINT]
setintconst(&v, t.NumElem())
nam.Xoffset += int64(array_array)
gdata(&nam, nod(OADDR, vstat, nil), Widthptr)
nam.Xoffset += int64(array_nel) - int64(array_array)
gdata(&nam, &v, Widthptr)
nam.Xoffset += int64(array_cap) - int64(array_nel)
gdata(&nam, &v, Widthptr)
return
}
// recipe for var = []t{...}
// 1. make a static array
// var vstat [...]t
// 2. assign (data statements) the constant part
// vstat = constpart{}
// 3. make an auto pointer to array and allocate heap to it
// var vauto *[...]t = new([...]t)
// 4. copy the static array to the auto array
// *vauto = vstat
// 5. for each dynamic part assign to the array
// vauto[i] = dynamic part
// 6. assign slice of allocated heap to var
// var = vauto[:]
//
// an optimization is done if there is no constant part
// 3. var vauto *[...]t = new([...]t)
// 5. vauto[i] = dynamic part
// 6. var = vauto[:]
// if the literal contains constants,
// make static initialized array (1),(2)
var vstat *Node
mode := getdyn(n, true)
if mode&initConst != 0 {
vstat = staticname(t)
if ctxt == inInitFunction {
cmd/compile: pack bool fields in Node, Name, Func and Type structs to bitsets This reduces compiler memory usage by up to 4% - see compilebench results below. name old time/op new time/op delta Template 245ms ± 4% 241ms ± 2% -1.88% (p=0.029 n=10+10) Unicode 126ms ± 3% 124ms ± 3% ~ (p=0.105 n=10+10) GoTypes 805ms ± 2% 813ms ± 3% ~ (p=0.515 n=8+10) Compiler 3.95s ± 2% 3.83s ± 1% -2.96% (p=0.000 n=9+10) MakeBash 47.4s ± 4% 46.6s ± 1% -1.59% (p=0.028 n=9+10) name old user-ns/op new user-ns/op delta Template 324M ± 5% 326M ± 3% ~ (p=0.935 n=10+10) Unicode 186M ± 5% 178M ±10% ~ (p=0.067 n=9+10) GoTypes 1.08G ± 7% 1.09G ± 4% ~ (p=0.956 n=10+10) Compiler 5.34G ± 4% 5.31G ± 1% ~ (p=0.501 n=10+8) name old alloc/op new alloc/op delta Template 41.0MB ± 0% 39.8MB ± 0% -3.03% (p=0.000 n=10+10) Unicode 32.3MB ± 0% 31.0MB ± 0% -4.13% (p=0.000 n=10+10) GoTypes 119MB ± 0% 116MB ± 0% -2.39% (p=0.000 n=10+10) Compiler 499MB ± 0% 487MB ± 0% -2.48% (p=0.000 n=10+10) name old allocs/op new allocs/op delta Template 380k ± 1% 379k ± 1% ~ (p=0.436 n=10+10) Unicode 324k ± 1% 324k ± 0% ~ (p=0.853 n=10+10) GoTypes 1.15M ± 0% 1.15M ± 0% ~ (p=0.481 n=10+10) Compiler 4.41M ± 0% 4.41M ± 0% -0.12% (p=0.007 n=10+10) name old text-bytes new text-bytes delta HelloSize 623k ± 0% 623k ± 0% ~ (all equal) CmdGoSize 6.64M ± 0% 6.64M ± 0% ~ (all equal) name old data-bytes new data-bytes delta HelloSize 5.81k ± 0% 5.81k ± 0% ~ (all equal) CmdGoSize 238k ± 0% 238k ± 0% ~ (all equal) name old bss-bytes new bss-bytes delta HelloSize 134k ± 0% 134k ± 0% ~ (all equal) CmdGoSize 152k ± 0% 152k ± 0% ~ (all equal) name old exe-bytes new exe-bytes delta HelloSize 967k ± 0% 967k ± 0% ~ (all equal) CmdGoSize 10.2M ± 0% 10.2M ± 0% ~ (all equal) Change-Id: I1f40af738254892bd6c8ba2eb43390b175753d52 Reviewed-on: https://go-review.googlesource.com/37445 Reviewed-by: Matthew Dempsky <mdempsky@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-02-27 19:56:38 +02:00
vstat.Name.SetReadonly(true)
}
fixedlit(ctxt, initKindStatic, n, vstat, init)
}
// make new auto *array (3 declare)
vauto := temp(types.NewPtr(t))
// set auto to point at new temp or heap (3 assign)
var a *Node
if x := prealloc[n]; x != nil {
// temp allocated during order.go for dddarg
x.Type = t
if vstat == nil {
a = nod(OAS, x, nil)
cmd/compile: reduce use of **Node parameters Escape analysis has a hard time with tree-like structures (see #13493 and #14858). This is unlikely to change. As a result, when invoking a function that accepts a **Node parameter, we usually allocate a *Node on the heap. This happens a whole lot. This CL changes functions from taking a **Node to acting more like append: It both modifies the input and returns a replacement for it. Because of the cascading nature of escape analysis, in order to get the benefits, I had to modify almost all such functions. The remaining functions are in racewalk and the backend. I would be happy to update them as well in a separate CL. This CL was created by manually updating the function signatures and the directly impacted bits of code. The callsites were then automatically updated using a bespoke script: https://gist.github.com/josharian/046b1be7aceae244de39 For ease of reviewing and future understanding, this CL is also broken down into four CLs, mailed separately, which show the manual and the automated changes separately. They are CLs 20990, 20991, 20992, and 20993. Passes toolstash -cmp. name old time/op new time/op delta Template 335ms ± 5% 324ms ± 5% -3.35% (p=0.000 n=23+24) Unicode 176ms ± 9% 165ms ± 6% -6.12% (p=0.000 n=23+24) GoTypes 1.10s ± 4% 1.07s ± 2% -2.77% (p=0.000 n=24+24) Compiler 5.31s ± 3% 5.15s ± 3% -2.95% (p=0.000 n=24+24) MakeBash 41.6s ± 1% 41.7s ± 2% ~ (p=0.586 n=23+23) name old alloc/op new alloc/op delta Template 63.3MB ± 0% 62.4MB ± 0% -1.36% (p=0.000 n=25+23) Unicode 42.4MB ± 0% 41.6MB ± 0% -1.99% (p=0.000 n=24+25) GoTypes 220MB ± 0% 217MB ± 0% -1.11% (p=0.000 n=25+25) Compiler 994MB ± 0% 973MB ± 0% -2.08% (p=0.000 n=24+25) name old allocs/op new allocs/op delta Template 681k ± 0% 574k ± 0% -15.71% (p=0.000 n=24+25) Unicode 518k ± 0% 413k ± 0% -20.34% (p=0.000 n=25+24) GoTypes 2.08M ± 0% 1.78M ± 0% -14.62% (p=0.000 n=25+25) Compiler 9.26M ± 0% 7.64M ± 0% -17.48% (p=0.000 n=25+25) name old text-bytes new text-bytes delta HelloSize 578k ± 0% 578k ± 0% ~ (all samples are equal) CmdGoSize 6.46M ± 0% 6.46M ± 0% ~ (all samples are equal) name old data-bytes new data-bytes delta HelloSize 128k ± 0% 128k ± 0% ~ (all samples are equal) CmdGoSize 281k ± 0% 281k ± 0% ~ (all samples are equal) name old exe-bytes new exe-bytes delta HelloSize 921k ± 0% 921k ± 0% ~ (all samples are equal) CmdGoSize 9.86M ± 0% 9.86M ± 0% ~ (all samples are equal) Change-Id: I277d95bd56d51c166ef7f560647aeaa092f3f475 Reviewed-on: https://go-review.googlesource.com/20959 Reviewed-by: Dave Cheney <dave@cheney.net> Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-03-20 08:03:31 -07:00
a = typecheck(a, Etop)
init.Append(a) // zero new temp
} else {
// Declare that we're about to initialize all of x.
// (Which happens at the *vauto = vstat below.)
init.Append(nod(OVARDEF, x, nil))
}
a = nod(OADDR, x, nil)
} else if n.Esc == EscNone {
a = temp(t)
if vstat == nil {
a = nod(OAS, temp(t), nil)
cmd/compile: reduce use of **Node parameters Escape analysis has a hard time with tree-like structures (see #13493 and #14858). This is unlikely to change. As a result, when invoking a function that accepts a **Node parameter, we usually allocate a *Node on the heap. This happens a whole lot. This CL changes functions from taking a **Node to acting more like append: It both modifies the input and returns a replacement for it. Because of the cascading nature of escape analysis, in order to get the benefits, I had to modify almost all such functions. The remaining functions are in racewalk and the backend. I would be happy to update them as well in a separate CL. This CL was created by manually updating the function signatures and the directly impacted bits of code. The callsites were then automatically updated using a bespoke script: https://gist.github.com/josharian/046b1be7aceae244de39 For ease of reviewing and future understanding, this CL is also broken down into four CLs, mailed separately, which show the manual and the automated changes separately. They are CLs 20990, 20991, 20992, and 20993. Passes toolstash -cmp. name old time/op new time/op delta Template 335ms ± 5% 324ms ± 5% -3.35% (p=0.000 n=23+24) Unicode 176ms ± 9% 165ms ± 6% -6.12% (p=0.000 n=23+24) GoTypes 1.10s ± 4% 1.07s ± 2% -2.77% (p=0.000 n=24+24) Compiler 5.31s ± 3% 5.15s ± 3% -2.95% (p=0.000 n=24+24) MakeBash 41.6s ± 1% 41.7s ± 2% ~ (p=0.586 n=23+23) name old alloc/op new alloc/op delta Template 63.3MB ± 0% 62.4MB ± 0% -1.36% (p=0.000 n=25+23) Unicode 42.4MB ± 0% 41.6MB ± 0% -1.99% (p=0.000 n=24+25) GoTypes 220MB ± 0% 217MB ± 0% -1.11% (p=0.000 n=25+25) Compiler 994MB ± 0% 973MB ± 0% -2.08% (p=0.000 n=24+25) name old allocs/op new allocs/op delta Template 681k ± 0% 574k ± 0% -15.71% (p=0.000 n=24+25) Unicode 518k ± 0% 413k ± 0% -20.34% (p=0.000 n=25+24) GoTypes 2.08M ± 0% 1.78M ± 0% -14.62% (p=0.000 n=25+25) Compiler 9.26M ± 0% 7.64M ± 0% -17.48% (p=0.000 n=25+25) name old text-bytes new text-bytes delta HelloSize 578k ± 0% 578k ± 0% ~ (all samples are equal) CmdGoSize 6.46M ± 0% 6.46M ± 0% ~ (all samples are equal) name old data-bytes new data-bytes delta HelloSize 128k ± 0% 128k ± 0% ~ (all samples are equal) CmdGoSize 281k ± 0% 281k ± 0% ~ (all samples are equal) name old exe-bytes new exe-bytes delta HelloSize 921k ± 0% 921k ± 0% ~ (all samples are equal) CmdGoSize 9.86M ± 0% 9.86M ± 0% ~ (all samples are equal) Change-Id: I277d95bd56d51c166ef7f560647aeaa092f3f475 Reviewed-on: https://go-review.googlesource.com/20959 Reviewed-by: Dave Cheney <dave@cheney.net> Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-03-20 08:03:31 -07:00
a = typecheck(a, Etop)
init.Append(a) // zero new temp
a = a.Left
} else {
init.Append(nod(OVARDEF, a, nil))
}
a = nod(OADDR, a, nil)
} else {
a = nod(ONEW, nil, nil)
a.List.Set1(typenod(t))
}
a = nod(OAS, vauto, a)
cmd/compile: reduce use of **Node parameters Escape analysis has a hard time with tree-like structures (see #13493 and #14858). This is unlikely to change. As a result, when invoking a function that accepts a **Node parameter, we usually allocate a *Node on the heap. This happens a whole lot. This CL changes functions from taking a **Node to acting more like append: It both modifies the input and returns a replacement for it. Because of the cascading nature of escape analysis, in order to get the benefits, I had to modify almost all such functions. The remaining functions are in racewalk and the backend. I would be happy to update them as well in a separate CL. This CL was created by manually updating the function signatures and the directly impacted bits of code. The callsites were then automatically updated using a bespoke script: https://gist.github.com/josharian/046b1be7aceae244de39 For ease of reviewing and future understanding, this CL is also broken down into four CLs, mailed separately, which show the manual and the automated changes separately. They are CLs 20990, 20991, 20992, and 20993. Passes toolstash -cmp. name old time/op new time/op delta Template 335ms ± 5% 324ms ± 5% -3.35% (p=0.000 n=23+24) Unicode 176ms ± 9% 165ms ± 6% -6.12% (p=0.000 n=23+24) GoTypes 1.10s ± 4% 1.07s ± 2% -2.77% (p=0.000 n=24+24) Compiler 5.31s ± 3% 5.15s ± 3% -2.95% (p=0.000 n=24+24) MakeBash 41.6s ± 1% 41.7s ± 2% ~ (p=0.586 n=23+23) name old alloc/op new alloc/op delta Template 63.3MB ± 0% 62.4MB ± 0% -1.36% (p=0.000 n=25+23) Unicode 42.4MB ± 0% 41.6MB ± 0% -1.99% (p=0.000 n=24+25) GoTypes 220MB ± 0% 217MB ± 0% -1.11% (p=0.000 n=25+25) Compiler 994MB ± 0% 973MB ± 0% -2.08% (p=0.000 n=24+25) name old allocs/op new allocs/op delta Template 681k ± 0% 574k ± 0% -15.71% (p=0.000 n=24+25) Unicode 518k ± 0% 413k ± 0% -20.34% (p=0.000 n=25+24) GoTypes 2.08M ± 0% 1.78M ± 0% -14.62% (p=0.000 n=25+25) Compiler 9.26M ± 0% 7.64M ± 0% -17.48% (p=0.000 n=25+25) name old text-bytes new text-bytes delta HelloSize 578k ± 0% 578k ± 0% ~ (all samples are equal) CmdGoSize 6.46M ± 0% 6.46M ± 0% ~ (all samples are equal) name old data-bytes new data-bytes delta HelloSize 128k ± 0% 128k ± 0% ~ (all samples are equal) CmdGoSize 281k ± 0% 281k ± 0% ~ (all samples are equal) name old exe-bytes new exe-bytes delta HelloSize 921k ± 0% 921k ± 0% ~ (all samples are equal) CmdGoSize 9.86M ± 0% 9.86M ± 0% ~ (all samples are equal) Change-Id: I277d95bd56d51c166ef7f560647aeaa092f3f475 Reviewed-on: https://go-review.googlesource.com/20959 Reviewed-by: Dave Cheney <dave@cheney.net> Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-03-20 08:03:31 -07:00
a = typecheck(a, Etop)
a = walkexpr(a, init)
init.Append(a)
if vstat != nil {
// copy static to heap (4)
a = nod(OIND, vauto, nil)
a = nod(OAS, a, vstat)
cmd/compile: reduce use of **Node parameters Escape analysis has a hard time with tree-like structures (see #13493 and #14858). This is unlikely to change. As a result, when invoking a function that accepts a **Node parameter, we usually allocate a *Node on the heap. This happens a whole lot. This CL changes functions from taking a **Node to acting more like append: It both modifies the input and returns a replacement for it. Because of the cascading nature of escape analysis, in order to get the benefits, I had to modify almost all such functions. The remaining functions are in racewalk and the backend. I would be happy to update them as well in a separate CL. This CL was created by manually updating the function signatures and the directly impacted bits of code. The callsites were then automatically updated using a bespoke script: https://gist.github.com/josharian/046b1be7aceae244de39 For ease of reviewing and future understanding, this CL is also broken down into four CLs, mailed separately, which show the manual and the automated changes separately. They are CLs 20990, 20991, 20992, and 20993. Passes toolstash -cmp. name old time/op new time/op delta Template 335ms ± 5% 324ms ± 5% -3.35% (p=0.000 n=23+24) Unicode 176ms ± 9% 165ms ± 6% -6.12% (p=0.000 n=23+24) GoTypes 1.10s ± 4% 1.07s ± 2% -2.77% (p=0.000 n=24+24) Compiler 5.31s ± 3% 5.15s ± 3% -2.95% (p=0.000 n=24+24) MakeBash 41.6s ± 1% 41.7s ± 2% ~ (p=0.586 n=23+23) name old alloc/op new alloc/op delta Template 63.3MB ± 0% 62.4MB ± 0% -1.36% (p=0.000 n=25+23) Unicode 42.4MB ± 0% 41.6MB ± 0% -1.99% (p=0.000 n=24+25) GoTypes 220MB ± 0% 217MB ± 0% -1.11% (p=0.000 n=25+25) Compiler 994MB ± 0% 973MB ± 0% -2.08% (p=0.000 n=24+25) name old allocs/op new allocs/op delta Template 681k ± 0% 574k ± 0% -15.71% (p=0.000 n=24+25) Unicode 518k ± 0% 413k ± 0% -20.34% (p=0.000 n=25+24) GoTypes 2.08M ± 0% 1.78M ± 0% -14.62% (p=0.000 n=25+25) Compiler 9.26M ± 0% 7.64M ± 0% -17.48% (p=0.000 n=25+25) name old text-bytes new text-bytes delta HelloSize 578k ± 0% 578k ± 0% ~ (all samples are equal) CmdGoSize 6.46M ± 0% 6.46M ± 0% ~ (all samples are equal) name old data-bytes new data-bytes delta HelloSize 128k ± 0% 128k ± 0% ~ (all samples are equal) CmdGoSize 281k ± 0% 281k ± 0% ~ (all samples are equal) name old exe-bytes new exe-bytes delta HelloSize 921k ± 0% 921k ± 0% ~ (all samples are equal) CmdGoSize 9.86M ± 0% 9.86M ± 0% ~ (all samples are equal) Change-Id: I277d95bd56d51c166ef7f560647aeaa092f3f475 Reviewed-on: https://go-review.googlesource.com/20959 Reviewed-by: Dave Cheney <dave@cheney.net> Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-03-20 08:03:31 -07:00
a = typecheck(a, Etop)
a = walkexpr(a, init)
init.Append(a)
}
// put dynamics into array (5)
cmd/compile: stop adding implicit OKEY nodes Keys are uncommon in array and slice literals, and normalizing OARRAYLIT and OSLICELIT nodes to always use OKEY ends up not reducing complexity much. Instead, only create OKEY nodes to represent explicit keys, and recalculate implicit keys when/where necessary. Fixes #15350. name old time/op new time/op delta Template 299ms ± 9% 299ms ±12% ~ (p=0.694 n=28+30) Unicode 165ms ± 7% 162ms ± 9% ~ (p=0.084 n=27+27) GoTypes 950ms ± 9% 963ms ± 5% ~ (p=0.301 n=30+29) Compiler 4.23s ± 7% 4.17s ± 7% ~ (p=0.057 n=29+27) name old user-ns/op new user-ns/op delta Template 389M ±15% 400M ±12% ~ (p=0.202 n=30+29) Unicode 246M ±21% 232M ±22% -5.76% (p=0.006 n=28+29) GoTypes 1.34G ± 8% 1.34G ± 7% ~ (p=0.775 n=28+30) Compiler 5.91G ± 6% 5.87G ± 7% ~ (p=0.298 n=28+29) name old alloc/op new alloc/op delta Template 41.2MB ± 0% 41.2MB ± 0% ~ (p=0.085 n=30+30) Unicode 34.0MB ± 0% 31.5MB ± 0% -7.28% (p=0.000 n=30+29) GoTypes 121MB ± 0% 121MB ± 0% ~ (p=0.657 n=30+30) Compiler 511MB ± 0% 511MB ± 0% -0.01% (p=0.001 n=29+29) name old allocs/op new allocs/op delta Template 390k ± 0% 390k ± 0% ~ (p=0.225 n=30+29) Unicode 318k ± 0% 293k ± 0% -8.03% (p=0.000 n=30+29) GoTypes 1.16M ± 0% 1.16M ± 0% ~ (p=0.745 n=30+30) Compiler 4.35M ± 0% 4.35M ± 0% ~ (p=0.105 n=30+30) Change-Id: I6310739a0bfdb54f1ab8a460b2c03615ad1ff5bc Reviewed-on: https://go-review.googlesource.com/32221 Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-10-27 02:02:30 -07:00
var index int64
for _, value := range n.List.Slice() {
if value.Op == OKEY {
index = nonnegintconst(value.Left)
value = value.Right
}
cmd/compile: stop adding implicit OKEY nodes Keys are uncommon in array and slice literals, and normalizing OARRAYLIT and OSLICELIT nodes to always use OKEY ends up not reducing complexity much. Instead, only create OKEY nodes to represent explicit keys, and recalculate implicit keys when/where necessary. Fixes #15350. name old time/op new time/op delta Template 299ms ± 9% 299ms ±12% ~ (p=0.694 n=28+30) Unicode 165ms ± 7% 162ms ± 9% ~ (p=0.084 n=27+27) GoTypes 950ms ± 9% 963ms ± 5% ~ (p=0.301 n=30+29) Compiler 4.23s ± 7% 4.17s ± 7% ~ (p=0.057 n=29+27) name old user-ns/op new user-ns/op delta Template 389M ±15% 400M ±12% ~ (p=0.202 n=30+29) Unicode 246M ±21% 232M ±22% -5.76% (p=0.006 n=28+29) GoTypes 1.34G ± 8% 1.34G ± 7% ~ (p=0.775 n=28+30) Compiler 5.91G ± 6% 5.87G ± 7% ~ (p=0.298 n=28+29) name old alloc/op new alloc/op delta Template 41.2MB ± 0% 41.2MB ± 0% ~ (p=0.085 n=30+30) Unicode 34.0MB ± 0% 31.5MB ± 0% -7.28% (p=0.000 n=30+29) GoTypes 121MB ± 0% 121MB ± 0% ~ (p=0.657 n=30+30) Compiler 511MB ± 0% 511MB ± 0% -0.01% (p=0.001 n=29+29) name old allocs/op new allocs/op delta Template 390k ± 0% 390k ± 0% ~ (p=0.225 n=30+29) Unicode 318k ± 0% 293k ± 0% -8.03% (p=0.000 n=30+29) GoTypes 1.16M ± 0% 1.16M ± 0% ~ (p=0.745 n=30+30) Compiler 4.35M ± 0% 4.35M ± 0% ~ (p=0.105 n=30+30) Change-Id: I6310739a0bfdb54f1ab8a460b2c03615ad1ff5bc Reviewed-on: https://go-review.googlesource.com/32221 Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-10-27 02:02:30 -07:00
a := nod(OINDEX, vauto, nodintconst(index))
cmd/compile: pack bool fields in Node, Name, Func and Type structs to bitsets This reduces compiler memory usage by up to 4% - see compilebench results below. name old time/op new time/op delta Template 245ms ± 4% 241ms ± 2% -1.88% (p=0.029 n=10+10) Unicode 126ms ± 3% 124ms ± 3% ~ (p=0.105 n=10+10) GoTypes 805ms ± 2% 813ms ± 3% ~ (p=0.515 n=8+10) Compiler 3.95s ± 2% 3.83s ± 1% -2.96% (p=0.000 n=9+10) MakeBash 47.4s ± 4% 46.6s ± 1% -1.59% (p=0.028 n=9+10) name old user-ns/op new user-ns/op delta Template 324M ± 5% 326M ± 3% ~ (p=0.935 n=10+10) Unicode 186M ± 5% 178M ±10% ~ (p=0.067 n=9+10) GoTypes 1.08G ± 7% 1.09G ± 4% ~ (p=0.956 n=10+10) Compiler 5.34G ± 4% 5.31G ± 1% ~ (p=0.501 n=10+8) name old alloc/op new alloc/op delta Template 41.0MB ± 0% 39.8MB ± 0% -3.03% (p=0.000 n=10+10) Unicode 32.3MB ± 0% 31.0MB ± 0% -4.13% (p=0.000 n=10+10) GoTypes 119MB ± 0% 116MB ± 0% -2.39% (p=0.000 n=10+10) Compiler 499MB ± 0% 487MB ± 0% -2.48% (p=0.000 n=10+10) name old allocs/op new allocs/op delta Template 380k ± 1% 379k ± 1% ~ (p=0.436 n=10+10) Unicode 324k ± 1% 324k ± 0% ~ (p=0.853 n=10+10) GoTypes 1.15M ± 0% 1.15M ± 0% ~ (p=0.481 n=10+10) Compiler 4.41M ± 0% 4.41M ± 0% -0.12% (p=0.007 n=10+10) name old text-bytes new text-bytes delta HelloSize 623k ± 0% 623k ± 0% ~ (all equal) CmdGoSize 6.64M ± 0% 6.64M ± 0% ~ (all equal) name old data-bytes new data-bytes delta HelloSize 5.81k ± 0% 5.81k ± 0% ~ (all equal) CmdGoSize 238k ± 0% 238k ± 0% ~ (all equal) name old bss-bytes new bss-bytes delta HelloSize 134k ± 0% 134k ± 0% ~ (all equal) CmdGoSize 152k ± 0% 152k ± 0% ~ (all equal) name old exe-bytes new exe-bytes delta HelloSize 967k ± 0% 967k ± 0% ~ (all equal) CmdGoSize 10.2M ± 0% 10.2M ± 0% ~ (all equal) Change-Id: I1f40af738254892bd6c8ba2eb43390b175753d52 Reviewed-on: https://go-review.googlesource.com/37445 Reviewed-by: Matthew Dempsky <mdempsky@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-02-27 19:56:38 +02:00
a.SetBounded(true)
cmd/compile: stop adding implicit OKEY nodes Keys are uncommon in array and slice literals, and normalizing OARRAYLIT and OSLICELIT nodes to always use OKEY ends up not reducing complexity much. Instead, only create OKEY nodes to represent explicit keys, and recalculate implicit keys when/where necessary. Fixes #15350. name old time/op new time/op delta Template 299ms ± 9% 299ms ±12% ~ (p=0.694 n=28+30) Unicode 165ms ± 7% 162ms ± 9% ~ (p=0.084 n=27+27) GoTypes 950ms ± 9% 963ms ± 5% ~ (p=0.301 n=30+29) Compiler 4.23s ± 7% 4.17s ± 7% ~ (p=0.057 n=29+27) name old user-ns/op new user-ns/op delta Template 389M ±15% 400M ±12% ~ (p=0.202 n=30+29) Unicode 246M ±21% 232M ±22% -5.76% (p=0.006 n=28+29) GoTypes 1.34G ± 8% 1.34G ± 7% ~ (p=0.775 n=28+30) Compiler 5.91G ± 6% 5.87G ± 7% ~ (p=0.298 n=28+29) name old alloc/op new alloc/op delta Template 41.2MB ± 0% 41.2MB ± 0% ~ (p=0.085 n=30+30) Unicode 34.0MB ± 0% 31.5MB ± 0% -7.28% (p=0.000 n=30+29) GoTypes 121MB ± 0% 121MB ± 0% ~ (p=0.657 n=30+30) Compiler 511MB ± 0% 511MB ± 0% -0.01% (p=0.001 n=29+29) name old allocs/op new allocs/op delta Template 390k ± 0% 390k ± 0% ~ (p=0.225 n=30+29) Unicode 318k ± 0% 293k ± 0% -8.03% (p=0.000 n=30+29) GoTypes 1.16M ± 0% 1.16M ± 0% ~ (p=0.745 n=30+30) Compiler 4.35M ± 0% 4.35M ± 0% ~ (p=0.105 n=30+30) Change-Id: I6310739a0bfdb54f1ab8a460b2c03615ad1ff5bc Reviewed-on: https://go-review.googlesource.com/32221 Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-10-27 02:02:30 -07:00
index++
// TODO need to check bounds?
switch value.Op {
case OSLICELIT:
break
case OARRAYLIT, OSTRUCTLIT:
fixedlit(ctxt, initKindDynamic, value, a, init)
continue
}
if isLiteral(value) {
continue
}
// build list of vauto[c] = expr
setlineno(value)
a = nod(OAS, a, value)
cmd/compile: reduce use of **Node parameters Escape analysis has a hard time with tree-like structures (see #13493 and #14858). This is unlikely to change. As a result, when invoking a function that accepts a **Node parameter, we usually allocate a *Node on the heap. This happens a whole lot. This CL changes functions from taking a **Node to acting more like append: It both modifies the input and returns a replacement for it. Because of the cascading nature of escape analysis, in order to get the benefits, I had to modify almost all such functions. The remaining functions are in racewalk and the backend. I would be happy to update them as well in a separate CL. This CL was created by manually updating the function signatures and the directly impacted bits of code. The callsites were then automatically updated using a bespoke script: https://gist.github.com/josharian/046b1be7aceae244de39 For ease of reviewing and future understanding, this CL is also broken down into four CLs, mailed separately, which show the manual and the automated changes separately. They are CLs 20990, 20991, 20992, and 20993. Passes toolstash -cmp. name old time/op new time/op delta Template 335ms ± 5% 324ms ± 5% -3.35% (p=0.000 n=23+24) Unicode 176ms ± 9% 165ms ± 6% -6.12% (p=0.000 n=23+24) GoTypes 1.10s ± 4% 1.07s ± 2% -2.77% (p=0.000 n=24+24) Compiler 5.31s ± 3% 5.15s ± 3% -2.95% (p=0.000 n=24+24) MakeBash 41.6s ± 1% 41.7s ± 2% ~ (p=0.586 n=23+23) name old alloc/op new alloc/op delta Template 63.3MB ± 0% 62.4MB ± 0% -1.36% (p=0.000 n=25+23) Unicode 42.4MB ± 0% 41.6MB ± 0% -1.99% (p=0.000 n=24+25) GoTypes 220MB ± 0% 217MB ± 0% -1.11% (p=0.000 n=25+25) Compiler 994MB ± 0% 973MB ± 0% -2.08% (p=0.000 n=24+25) name old allocs/op new allocs/op delta Template 681k ± 0% 574k ± 0% -15.71% (p=0.000 n=24+25) Unicode 518k ± 0% 413k ± 0% -20.34% (p=0.000 n=25+24) GoTypes 2.08M ± 0% 1.78M ± 0% -14.62% (p=0.000 n=25+25) Compiler 9.26M ± 0% 7.64M ± 0% -17.48% (p=0.000 n=25+25) name old text-bytes new text-bytes delta HelloSize 578k ± 0% 578k ± 0% ~ (all samples are equal) CmdGoSize 6.46M ± 0% 6.46M ± 0% ~ (all samples are equal) name old data-bytes new data-bytes delta HelloSize 128k ± 0% 128k ± 0% ~ (all samples are equal) CmdGoSize 281k ± 0% 281k ± 0% ~ (all samples are equal) name old exe-bytes new exe-bytes delta HelloSize 921k ± 0% 921k ± 0% ~ (all samples are equal) CmdGoSize 9.86M ± 0% 9.86M ± 0% ~ (all samples are equal) Change-Id: I277d95bd56d51c166ef7f560647aeaa092f3f475 Reviewed-on: https://go-review.googlesource.com/20959 Reviewed-by: Dave Cheney <dave@cheney.net> Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-03-20 08:03:31 -07:00
a = typecheck(a, Etop)
a = orderStmtInPlace(a)
cmd/compile: reduce use of **Node parameters Escape analysis has a hard time with tree-like structures (see #13493 and #14858). This is unlikely to change. As a result, when invoking a function that accepts a **Node parameter, we usually allocate a *Node on the heap. This happens a whole lot. This CL changes functions from taking a **Node to acting more like append: It both modifies the input and returns a replacement for it. Because of the cascading nature of escape analysis, in order to get the benefits, I had to modify almost all such functions. The remaining functions are in racewalk and the backend. I would be happy to update them as well in a separate CL. This CL was created by manually updating the function signatures and the directly impacted bits of code. The callsites were then automatically updated using a bespoke script: https://gist.github.com/josharian/046b1be7aceae244de39 For ease of reviewing and future understanding, this CL is also broken down into four CLs, mailed separately, which show the manual and the automated changes separately. They are CLs 20990, 20991, 20992, and 20993. Passes toolstash -cmp. name old time/op new time/op delta Template 335ms ± 5% 324ms ± 5% -3.35% (p=0.000 n=23+24) Unicode 176ms ± 9% 165ms ± 6% -6.12% (p=0.000 n=23+24) GoTypes 1.10s ± 4% 1.07s ± 2% -2.77% (p=0.000 n=24+24) Compiler 5.31s ± 3% 5.15s ± 3% -2.95% (p=0.000 n=24+24) MakeBash 41.6s ± 1% 41.7s ± 2% ~ (p=0.586 n=23+23) name old alloc/op new alloc/op delta Template 63.3MB ± 0% 62.4MB ± 0% -1.36% (p=0.000 n=25+23) Unicode 42.4MB ± 0% 41.6MB ± 0% -1.99% (p=0.000 n=24+25) GoTypes 220MB ± 0% 217MB ± 0% -1.11% (p=0.000 n=25+25) Compiler 994MB ± 0% 973MB ± 0% -2.08% (p=0.000 n=24+25) name old allocs/op new allocs/op delta Template 681k ± 0% 574k ± 0% -15.71% (p=0.000 n=24+25) Unicode 518k ± 0% 413k ± 0% -20.34% (p=0.000 n=25+24) GoTypes 2.08M ± 0% 1.78M ± 0% -14.62% (p=0.000 n=25+25) Compiler 9.26M ± 0% 7.64M ± 0% -17.48% (p=0.000 n=25+25) name old text-bytes new text-bytes delta HelloSize 578k ± 0% 578k ± 0% ~ (all samples are equal) CmdGoSize 6.46M ± 0% 6.46M ± 0% ~ (all samples are equal) name old data-bytes new data-bytes delta HelloSize 128k ± 0% 128k ± 0% ~ (all samples are equal) CmdGoSize 281k ± 0% 281k ± 0% ~ (all samples are equal) name old exe-bytes new exe-bytes delta HelloSize 921k ± 0% 921k ± 0% ~ (all samples are equal) CmdGoSize 9.86M ± 0% 9.86M ± 0% ~ (all samples are equal) Change-Id: I277d95bd56d51c166ef7f560647aeaa092f3f475 Reviewed-on: https://go-review.googlesource.com/20959 Reviewed-by: Dave Cheney <dave@cheney.net> Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-03-20 08:03:31 -07:00
a = walkstmt(a)
init.Append(a)
}
// make slice out of heap (6)
a = nod(OAS, var_, nod(OSLICE, vauto, nil))
a = typecheck(a, Etop)
a = orderStmtInPlace(a)
a = walkstmt(a)
init.Append(a)
}
func maplit(n *Node, m *Node, init *Nodes) {
// make the map var
a := nod(OMAKE, nil, nil)
a.Esc = n.Esc
a.List.Set2(typenod(n.Type), nodintconst(int64(n.List.Len())))
litas(m, a, init)
// Split the initializers into static and dynamic.
var stat, dyn []*Node
for _, r := range n.List.Slice() {
if r.Op != OKEY {
Fatalf("maplit: rhs not OKEY: %v", r)
}
if isStaticCompositeLiteral(r.Left) && isStaticCompositeLiteral(r.Right) {
stat = append(stat, r)
} else {
dyn = append(dyn, r)
}
}
// Add static entries.
cmd/compile: unroll small static maps When a map is small, it's not worth putting the contents in an array and then looping over the array. Just generate code instead. This makes smaller binaries. It might also be better for cache lines. It also can avoids adding control flow in the middle of the init function, which can be very large. Eliminating this source of extra blocks makes phi insertion easier for temp-heavy init functions. This reduces the time required for compiler to panic while compiling the code in #19751 from 15 minutes to 45 seconds. The cutoff of 25 was chosen fairly unscientifically by looking at the size of cmd/go. Cutoff of 0: 10689604 Cutoff of 5: 10683572 Cutoff of 15: 10682324 Cutoff of 25: 10681700 Cutoff of 50: 10685476 Cutoff of 100: 10689412 There are probably more sophisticated mechanisms available. For example, the smaller the key/value sizes, the better generated code will be vs a table. Nevertheless this is simple and seems like a good start. Updates #19751 name old time/op new time/op delta Template 204ms ± 6% 202ms ± 5% -0.78% (p=0.027 n=47+45) Unicode 84.8ms ± 6% 85.2ms ± 7% ~ (p=0.146 n=46+45) GoTypes 551ms ± 2% 556ms ± 3% +0.76% (p=0.004 n=43+45) SSA 3.93s ± 3% 3.95s ± 4% ~ (p=0.179 n=50+49) Flate 123ms ± 4% 123ms ± 5% ~ (p=0.201 n=47+49) GoParser 145ms ± 3% 145ms ± 4% ~ (p=0.937 n=50+50) Reflect 356ms ± 3% 354ms ± 5% -0.44% (p=0.048 n=46+50) Tar 107ms ± 6% 106ms ± 6% ~ (p=0.188 n=50+49) XML 201ms ± 4% 200ms ± 4% ~ (p=0.085 n=50+49) name old user-ns/op new user-ns/op delta Template 252M ± 9% 250M ± 7% ~ (p=0.206 n=49+47) Unicode 106M ± 7% 106M ± 9% ~ (p=0.331 n=47+46) GoTypes 724M ± 5% 729M ± 5% ~ (p=0.160 n=47+49) SSA 5.64G ± 2% 5.62G ± 4% ~ (p=0.148 n=47+50) Flate 147M ± 6% 147M ± 5% ~ (p=0.466 n=50+49) GoParser 179M ± 5% 179M ± 6% ~ (p=0.584 n=50+49) Reflect 448M ± 6% 441M ± 8% -1.39% (p=0.027 n=50+49) Tar 124M ± 6% 123M ± 5% ~ (p=0.221 n=50+47) XML 244M ± 5% 243M ± 4% ~ (p=0.275 n=49+49) name old alloc/op new alloc/op delta Template 39.9MB ± 0% 39.4MB ± 0% -1.28% (p=0.008 n=5+5) Unicode 29.8MB ± 0% 29.8MB ± 0% ~ (p=0.310 n=5+5) GoTypes 113MB ± 0% 113MB ± 0% ~ (p=0.421 n=5+5) SSA 854MB ± 0% 854MB ± 0% ~ (p=0.151 n=5+5) Flate 25.3MB ± 0% 25.3MB ± 0% ~ (p=1.000 n=5+5) GoParser 31.8MB ± 0% 31.8MB ± 0% ~ (p=0.222 n=5+5) Reflect 78.2MB ± 0% 78.2MB ± 0% ~ (p=1.000 n=5+5) Tar 26.7MB ± 0% 26.7MB ± 0% ~ (p=0.841 n=5+5) XML 42.3MB ± 0% 42.3MB ± 0% -0.15% (p=0.008 n=5+5) name old allocs/op new allocs/op delta Template 390k ± 1% 386k ± 1% -1.05% (p=0.016 n=5+5) Unicode 319k ± 0% 320k ± 0% ~ (p=0.310 n=5+5) GoTypes 1.14M ± 0% 1.14M ± 0% ~ (p=0.421 n=5+5) SSA 7.60M ± 0% 7.59M ± 0% ~ (p=0.310 n=5+5) Flate 234k ± 0% 235k ± 1% ~ (p=1.000 n=5+5) GoParser 315k ± 1% 317k ± 0% ~ (p=0.151 n=5+5) Reflect 978k ± 0% 978k ± 0% ~ (p=0.841 n=5+5) Tar 251k ± 1% 251k ± 1% ~ (p=0.690 n=5+5) XML 394k ± 0% 392k ± 0% ~ (p=0.056 n=5+5) Change-Id: Ic53a18627082abe075a1cbc33330ce015e50850a Reviewed-on: https://go-review.googlesource.com/39354 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
2017-04-03 11:27:06 -07:00
if len(stat) > 25 {
// For a large number of static entries, put them in an array and loop.
// build types [count]Tindex and [count]Tvalue
tk := types.NewArray(n.Type.Key(), int64(len(stat)))
tv := types.NewArray(n.Type.Elem(), int64(len(stat)))
// TODO(josharian): suppress alg generation for these types?
dowidth(tk)
dowidth(tv)
// make and initialize static arrays
vstatk := staticname(tk)
cmd/compile: pack bool fields in Node, Name, Func and Type structs to bitsets This reduces compiler memory usage by up to 4% - see compilebench results below. name old time/op new time/op delta Template 245ms ± 4% 241ms ± 2% -1.88% (p=0.029 n=10+10) Unicode 126ms ± 3% 124ms ± 3% ~ (p=0.105 n=10+10) GoTypes 805ms ± 2% 813ms ± 3% ~ (p=0.515 n=8+10) Compiler 3.95s ± 2% 3.83s ± 1% -2.96% (p=0.000 n=9+10) MakeBash 47.4s ± 4% 46.6s ± 1% -1.59% (p=0.028 n=9+10) name old user-ns/op new user-ns/op delta Template 324M ± 5% 326M ± 3% ~ (p=0.935 n=10+10) Unicode 186M ± 5% 178M ±10% ~ (p=0.067 n=9+10) GoTypes 1.08G ± 7% 1.09G ± 4% ~ (p=0.956 n=10+10) Compiler 5.34G ± 4% 5.31G ± 1% ~ (p=0.501 n=10+8) name old alloc/op new alloc/op delta Template 41.0MB ± 0% 39.8MB ± 0% -3.03% (p=0.000 n=10+10) Unicode 32.3MB ± 0% 31.0MB ± 0% -4.13% (p=0.000 n=10+10) GoTypes 119MB ± 0% 116MB ± 0% -2.39% (p=0.000 n=10+10) Compiler 499MB ± 0% 487MB ± 0% -2.48% (p=0.000 n=10+10) name old allocs/op new allocs/op delta Template 380k ± 1% 379k ± 1% ~ (p=0.436 n=10+10) Unicode 324k ± 1% 324k ± 0% ~ (p=0.853 n=10+10) GoTypes 1.15M ± 0% 1.15M ± 0% ~ (p=0.481 n=10+10) Compiler 4.41M ± 0% 4.41M ± 0% -0.12% (p=0.007 n=10+10) name old text-bytes new text-bytes delta HelloSize 623k ± 0% 623k ± 0% ~ (all equal) CmdGoSize 6.64M ± 0% 6.64M ± 0% ~ (all equal) name old data-bytes new data-bytes delta HelloSize 5.81k ± 0% 5.81k ± 0% ~ (all equal) CmdGoSize 238k ± 0% 238k ± 0% ~ (all equal) name old bss-bytes new bss-bytes delta HelloSize 134k ± 0% 134k ± 0% ~ (all equal) CmdGoSize 152k ± 0% 152k ± 0% ~ (all equal) name old exe-bytes new exe-bytes delta HelloSize 967k ± 0% 967k ± 0% ~ (all equal) CmdGoSize 10.2M ± 0% 10.2M ± 0% ~ (all equal) Change-Id: I1f40af738254892bd6c8ba2eb43390b175753d52 Reviewed-on: https://go-review.googlesource.com/37445 Reviewed-by: Matthew Dempsky <mdempsky@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-02-27 19:56:38 +02:00
vstatk.Name.SetReadonly(true)
vstatv := staticname(tv)
cmd/compile: pack bool fields in Node, Name, Func and Type structs to bitsets This reduces compiler memory usage by up to 4% - see compilebench results below. name old time/op new time/op delta Template 245ms ± 4% 241ms ± 2% -1.88% (p=0.029 n=10+10) Unicode 126ms ± 3% 124ms ± 3% ~ (p=0.105 n=10+10) GoTypes 805ms ± 2% 813ms ± 3% ~ (p=0.515 n=8+10) Compiler 3.95s ± 2% 3.83s ± 1% -2.96% (p=0.000 n=9+10) MakeBash 47.4s ± 4% 46.6s ± 1% -1.59% (p=0.028 n=9+10) name old user-ns/op new user-ns/op delta Template 324M ± 5% 326M ± 3% ~ (p=0.935 n=10+10) Unicode 186M ± 5% 178M ±10% ~ (p=0.067 n=9+10) GoTypes 1.08G ± 7% 1.09G ± 4% ~ (p=0.956 n=10+10) Compiler 5.34G ± 4% 5.31G ± 1% ~ (p=0.501 n=10+8) name old alloc/op new alloc/op delta Template 41.0MB ± 0% 39.8MB ± 0% -3.03% (p=0.000 n=10+10) Unicode 32.3MB ± 0% 31.0MB ± 0% -4.13% (p=0.000 n=10+10) GoTypes 119MB ± 0% 116MB ± 0% -2.39% (p=0.000 n=10+10) Compiler 499MB ± 0% 487MB ± 0% -2.48% (p=0.000 n=10+10) name old allocs/op new allocs/op delta Template 380k ± 1% 379k ± 1% ~ (p=0.436 n=10+10) Unicode 324k ± 1% 324k ± 0% ~ (p=0.853 n=10+10) GoTypes 1.15M ± 0% 1.15M ± 0% ~ (p=0.481 n=10+10) Compiler 4.41M ± 0% 4.41M ± 0% -0.12% (p=0.007 n=10+10) name old text-bytes new text-bytes delta HelloSize 623k ± 0% 623k ± 0% ~ (all equal) CmdGoSize 6.64M ± 0% 6.64M ± 0% ~ (all equal) name old data-bytes new data-bytes delta HelloSize 5.81k ± 0% 5.81k ± 0% ~ (all equal) CmdGoSize 238k ± 0% 238k ± 0% ~ (all equal) name old bss-bytes new bss-bytes delta HelloSize 134k ± 0% 134k ± 0% ~ (all equal) CmdGoSize 152k ± 0% 152k ± 0% ~ (all equal) name old exe-bytes new exe-bytes delta HelloSize 967k ± 0% 967k ± 0% ~ (all equal) CmdGoSize 10.2M ± 0% 10.2M ± 0% ~ (all equal) Change-Id: I1f40af738254892bd6c8ba2eb43390b175753d52 Reviewed-on: https://go-review.googlesource.com/37445 Reviewed-by: Matthew Dempsky <mdempsky@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-02-27 19:56:38 +02:00
vstatv.Name.SetReadonly(true)
datak := nod(OARRAYLIT, nil, nil)
datav := nod(OARRAYLIT, nil, nil)
for _, r := range stat {
datak.List.Append(r.Left)
datav.List.Append(r.Right)
}
fixedlit(inInitFunction, initKindStatic, datak, vstatk, init)
fixedlit(inInitFunction, initKindStatic, datav, vstatv, init)
// loop adding structure elements to map
// for i = 0; i < len(vstatk); i++ {
// map[vstatk[i]] = vstatv[i]
// }
i := temp(types.Types[TINT])
rhs := nod(OINDEX, vstatv, i)
cmd/compile: pack bool fields in Node, Name, Func and Type structs to bitsets This reduces compiler memory usage by up to 4% - see compilebench results below. name old time/op new time/op delta Template 245ms ± 4% 241ms ± 2% -1.88% (p=0.029 n=10+10) Unicode 126ms ± 3% 124ms ± 3% ~ (p=0.105 n=10+10) GoTypes 805ms ± 2% 813ms ± 3% ~ (p=0.515 n=8+10) Compiler 3.95s ± 2% 3.83s ± 1% -2.96% (p=0.000 n=9+10) MakeBash 47.4s ± 4% 46.6s ± 1% -1.59% (p=0.028 n=9+10) name old user-ns/op new user-ns/op delta Template 324M ± 5% 326M ± 3% ~ (p=0.935 n=10+10) Unicode 186M ± 5% 178M ±10% ~ (p=0.067 n=9+10) GoTypes 1.08G ± 7% 1.09G ± 4% ~ (p=0.956 n=10+10) Compiler 5.34G ± 4% 5.31G ± 1% ~ (p=0.501 n=10+8) name old alloc/op new alloc/op delta Template 41.0MB ± 0% 39.8MB ± 0% -3.03% (p=0.000 n=10+10) Unicode 32.3MB ± 0% 31.0MB ± 0% -4.13% (p=0.000 n=10+10) GoTypes 119MB ± 0% 116MB ± 0% -2.39% (p=0.000 n=10+10) Compiler 499MB ± 0% 487MB ± 0% -2.48% (p=0.000 n=10+10) name old allocs/op new allocs/op delta Template 380k ± 1% 379k ± 1% ~ (p=0.436 n=10+10) Unicode 324k ± 1% 324k ± 0% ~ (p=0.853 n=10+10) GoTypes 1.15M ± 0% 1.15M ± 0% ~ (p=0.481 n=10+10) Compiler 4.41M ± 0% 4.41M ± 0% -0.12% (p=0.007 n=10+10) name old text-bytes new text-bytes delta HelloSize 623k ± 0% 623k ± 0% ~ (all equal) CmdGoSize 6.64M ± 0% 6.64M ± 0% ~ (all equal) name old data-bytes new data-bytes delta HelloSize 5.81k ± 0% 5.81k ± 0% ~ (all equal) CmdGoSize 238k ± 0% 238k ± 0% ~ (all equal) name old bss-bytes new bss-bytes delta HelloSize 134k ± 0% 134k ± 0% ~ (all equal) CmdGoSize 152k ± 0% 152k ± 0% ~ (all equal) name old exe-bytes new exe-bytes delta HelloSize 967k ± 0% 967k ± 0% ~ (all equal) CmdGoSize 10.2M ± 0% 10.2M ± 0% ~ (all equal) Change-Id: I1f40af738254892bd6c8ba2eb43390b175753d52 Reviewed-on: https://go-review.googlesource.com/37445 Reviewed-by: Matthew Dempsky <mdempsky@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-02-27 19:56:38 +02:00
rhs.SetBounded(true)
kidx := nod(OINDEX, vstatk, i)
cmd/compile: pack bool fields in Node, Name, Func and Type structs to bitsets This reduces compiler memory usage by up to 4% - see compilebench results below. name old time/op new time/op delta Template 245ms ± 4% 241ms ± 2% -1.88% (p=0.029 n=10+10) Unicode 126ms ± 3% 124ms ± 3% ~ (p=0.105 n=10+10) GoTypes 805ms ± 2% 813ms ± 3% ~ (p=0.515 n=8+10) Compiler 3.95s ± 2% 3.83s ± 1% -2.96% (p=0.000 n=9+10) MakeBash 47.4s ± 4% 46.6s ± 1% -1.59% (p=0.028 n=9+10) name old user-ns/op new user-ns/op delta Template 324M ± 5% 326M ± 3% ~ (p=0.935 n=10+10) Unicode 186M ± 5% 178M ±10% ~ (p=0.067 n=9+10) GoTypes 1.08G ± 7% 1.09G ± 4% ~ (p=0.956 n=10+10) Compiler 5.34G ± 4% 5.31G ± 1% ~ (p=0.501 n=10+8) name old alloc/op new alloc/op delta Template 41.0MB ± 0% 39.8MB ± 0% -3.03% (p=0.000 n=10+10) Unicode 32.3MB ± 0% 31.0MB ± 0% -4.13% (p=0.000 n=10+10) GoTypes 119MB ± 0% 116MB ± 0% -2.39% (p=0.000 n=10+10) Compiler 499MB ± 0% 487MB ± 0% -2.48% (p=0.000 n=10+10) name old allocs/op new allocs/op delta Template 380k ± 1% 379k ± 1% ~ (p=0.436 n=10+10) Unicode 324k ± 1% 324k ± 0% ~ (p=0.853 n=10+10) GoTypes 1.15M ± 0% 1.15M ± 0% ~ (p=0.481 n=10+10) Compiler 4.41M ± 0% 4.41M ± 0% -0.12% (p=0.007 n=10+10) name old text-bytes new text-bytes delta HelloSize 623k ± 0% 623k ± 0% ~ (all equal) CmdGoSize 6.64M ± 0% 6.64M ± 0% ~ (all equal) name old data-bytes new data-bytes delta HelloSize 5.81k ± 0% 5.81k ± 0% ~ (all equal) CmdGoSize 238k ± 0% 238k ± 0% ~ (all equal) name old bss-bytes new bss-bytes delta HelloSize 134k ± 0% 134k ± 0% ~ (all equal) CmdGoSize 152k ± 0% 152k ± 0% ~ (all equal) name old exe-bytes new exe-bytes delta HelloSize 967k ± 0% 967k ± 0% ~ (all equal) CmdGoSize 10.2M ± 0% 10.2M ± 0% ~ (all equal) Change-Id: I1f40af738254892bd6c8ba2eb43390b175753d52 Reviewed-on: https://go-review.googlesource.com/37445 Reviewed-by: Matthew Dempsky <mdempsky@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-02-27 19:56:38 +02:00
kidx.SetBounded(true)
lhs := nod(OINDEX, m, kidx)
zero := nod(OAS, i, nodintconst(0))
cond := nod(OLT, i, nodintconst(tk.NumElem()))
incr := nod(OAS, i, nod(OADD, i, nodintconst(1)))
body := nod(OAS, lhs, rhs)
loop := nod(OFOR, cond, incr)
loop.Nbody.Set1(body)
loop.Ninit.Set1(zero)
loop = typecheck(loop, Etop)
loop = walkstmt(loop)
init.Append(loop)
cmd/compile: unroll small static maps When a map is small, it's not worth putting the contents in an array and then looping over the array. Just generate code instead. This makes smaller binaries. It might also be better for cache lines. It also can avoids adding control flow in the middle of the init function, which can be very large. Eliminating this source of extra blocks makes phi insertion easier for temp-heavy init functions. This reduces the time required for compiler to panic while compiling the code in #19751 from 15 minutes to 45 seconds. The cutoff of 25 was chosen fairly unscientifically by looking at the size of cmd/go. Cutoff of 0: 10689604 Cutoff of 5: 10683572 Cutoff of 15: 10682324 Cutoff of 25: 10681700 Cutoff of 50: 10685476 Cutoff of 100: 10689412 There are probably more sophisticated mechanisms available. For example, the smaller the key/value sizes, the better generated code will be vs a table. Nevertheless this is simple and seems like a good start. Updates #19751 name old time/op new time/op delta Template 204ms ± 6% 202ms ± 5% -0.78% (p=0.027 n=47+45) Unicode 84.8ms ± 6% 85.2ms ± 7% ~ (p=0.146 n=46+45) GoTypes 551ms ± 2% 556ms ± 3% +0.76% (p=0.004 n=43+45) SSA 3.93s ± 3% 3.95s ± 4% ~ (p=0.179 n=50+49) Flate 123ms ± 4% 123ms ± 5% ~ (p=0.201 n=47+49) GoParser 145ms ± 3% 145ms ± 4% ~ (p=0.937 n=50+50) Reflect 356ms ± 3% 354ms ± 5% -0.44% (p=0.048 n=46+50) Tar 107ms ± 6% 106ms ± 6% ~ (p=0.188 n=50+49) XML 201ms ± 4% 200ms ± 4% ~ (p=0.085 n=50+49) name old user-ns/op new user-ns/op delta Template 252M ± 9% 250M ± 7% ~ (p=0.206 n=49+47) Unicode 106M ± 7% 106M ± 9% ~ (p=0.331 n=47+46) GoTypes 724M ± 5% 729M ± 5% ~ (p=0.160 n=47+49) SSA 5.64G ± 2% 5.62G ± 4% ~ (p=0.148 n=47+50) Flate 147M ± 6% 147M ± 5% ~ (p=0.466 n=50+49) GoParser 179M ± 5% 179M ± 6% ~ (p=0.584 n=50+49) Reflect 448M ± 6% 441M ± 8% -1.39% (p=0.027 n=50+49) Tar 124M ± 6% 123M ± 5% ~ (p=0.221 n=50+47) XML 244M ± 5% 243M ± 4% ~ (p=0.275 n=49+49) name old alloc/op new alloc/op delta Template 39.9MB ± 0% 39.4MB ± 0% -1.28% (p=0.008 n=5+5) Unicode 29.8MB ± 0% 29.8MB ± 0% ~ (p=0.310 n=5+5) GoTypes 113MB ± 0% 113MB ± 0% ~ (p=0.421 n=5+5) SSA 854MB ± 0% 854MB ± 0% ~ (p=0.151 n=5+5) Flate 25.3MB ± 0% 25.3MB ± 0% ~ (p=1.000 n=5+5) GoParser 31.8MB ± 0% 31.8MB ± 0% ~ (p=0.222 n=5+5) Reflect 78.2MB ± 0% 78.2MB ± 0% ~ (p=1.000 n=5+5) Tar 26.7MB ± 0% 26.7MB ± 0% ~ (p=0.841 n=5+5) XML 42.3MB ± 0% 42.3MB ± 0% -0.15% (p=0.008 n=5+5) name old allocs/op new allocs/op delta Template 390k ± 1% 386k ± 1% -1.05% (p=0.016 n=5+5) Unicode 319k ± 0% 320k ± 0% ~ (p=0.310 n=5+5) GoTypes 1.14M ± 0% 1.14M ± 0% ~ (p=0.421 n=5+5) SSA 7.60M ± 0% 7.59M ± 0% ~ (p=0.310 n=5+5) Flate 234k ± 0% 235k ± 1% ~ (p=1.000 n=5+5) GoParser 315k ± 1% 317k ± 0% ~ (p=0.151 n=5+5) Reflect 978k ± 0% 978k ± 0% ~ (p=0.841 n=5+5) Tar 251k ± 1% 251k ± 1% ~ (p=0.690 n=5+5) XML 394k ± 0% 392k ± 0% ~ (p=0.056 n=5+5) Change-Id: Ic53a18627082abe075a1cbc33330ce015e50850a Reviewed-on: https://go-review.googlesource.com/39354 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
2017-04-03 11:27:06 -07:00
} else {
// For a small number of static entries, just add them directly.
addMapEntries(m, stat, init)
}
// Add dynamic entries.
addMapEntries(m, dyn, init)
}
func addMapEntries(m *Node, dyn []*Node, init *Nodes) {
if len(dyn) == 0 {
return
}
nerr := nerrors
// Build list of var[c] = expr.
// Use temporaries so that mapassign1 can have addressable key, val.
// TODO(josharian): avoid map key temporaries for mapfast_* assignments with literal keys.
key := temp(m.Type.Key())
val := temp(m.Type.Elem())
for _, r := range dyn {
index, value := r.Left, r.Right
setlineno(index)
a := nod(OAS, key, index)
cmd/compile: reduce use of **Node parameters Escape analysis has a hard time with tree-like structures (see #13493 and #14858). This is unlikely to change. As a result, when invoking a function that accepts a **Node parameter, we usually allocate a *Node on the heap. This happens a whole lot. This CL changes functions from taking a **Node to acting more like append: It both modifies the input and returns a replacement for it. Because of the cascading nature of escape analysis, in order to get the benefits, I had to modify almost all such functions. The remaining functions are in racewalk and the backend. I would be happy to update them as well in a separate CL. This CL was created by manually updating the function signatures and the directly impacted bits of code. The callsites were then automatically updated using a bespoke script: https://gist.github.com/josharian/046b1be7aceae244de39 For ease of reviewing and future understanding, this CL is also broken down into four CLs, mailed separately, which show the manual and the automated changes separately. They are CLs 20990, 20991, 20992, and 20993. Passes toolstash -cmp. name old time/op new time/op delta Template 335ms ± 5% 324ms ± 5% -3.35% (p=0.000 n=23+24) Unicode 176ms ± 9% 165ms ± 6% -6.12% (p=0.000 n=23+24) GoTypes 1.10s ± 4% 1.07s ± 2% -2.77% (p=0.000 n=24+24) Compiler 5.31s ± 3% 5.15s ± 3% -2.95% (p=0.000 n=24+24) MakeBash 41.6s ± 1% 41.7s ± 2% ~ (p=0.586 n=23+23) name old alloc/op new alloc/op delta Template 63.3MB ± 0% 62.4MB ± 0% -1.36% (p=0.000 n=25+23) Unicode 42.4MB ± 0% 41.6MB ± 0% -1.99% (p=0.000 n=24+25) GoTypes 220MB ± 0% 217MB ± 0% -1.11% (p=0.000 n=25+25) Compiler 994MB ± 0% 973MB ± 0% -2.08% (p=0.000 n=24+25) name old allocs/op new allocs/op delta Template 681k ± 0% 574k ± 0% -15.71% (p=0.000 n=24+25) Unicode 518k ± 0% 413k ± 0% -20.34% (p=0.000 n=25+24) GoTypes 2.08M ± 0% 1.78M ± 0% -14.62% (p=0.000 n=25+25) Compiler 9.26M ± 0% 7.64M ± 0% -17.48% (p=0.000 n=25+25) name old text-bytes new text-bytes delta HelloSize 578k ± 0% 578k ± 0% ~ (all samples are equal) CmdGoSize 6.46M ± 0% 6.46M ± 0% ~ (all samples are equal) name old data-bytes new data-bytes delta HelloSize 128k ± 0% 128k ± 0% ~ (all samples are equal) CmdGoSize 281k ± 0% 281k ± 0% ~ (all samples are equal) name old exe-bytes new exe-bytes delta HelloSize 921k ± 0% 921k ± 0% ~ (all samples are equal) CmdGoSize 9.86M ± 0% 9.86M ± 0% ~ (all samples are equal) Change-Id: I277d95bd56d51c166ef7f560647aeaa092f3f475 Reviewed-on: https://go-review.googlesource.com/20959 Reviewed-by: Dave Cheney <dave@cheney.net> Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-03-20 08:03:31 -07:00
a = typecheck(a, Etop)
a = walkstmt(a)
init.Append(a)
setlineno(value)
a = nod(OAS, val, value)
cmd/compile: reduce use of **Node parameters Escape analysis has a hard time with tree-like structures (see #13493 and #14858). This is unlikely to change. As a result, when invoking a function that accepts a **Node parameter, we usually allocate a *Node on the heap. This happens a whole lot. This CL changes functions from taking a **Node to acting more like append: It both modifies the input and returns a replacement for it. Because of the cascading nature of escape analysis, in order to get the benefits, I had to modify almost all such functions. The remaining functions are in racewalk and the backend. I would be happy to update them as well in a separate CL. This CL was created by manually updating the function signatures and the directly impacted bits of code. The callsites were then automatically updated using a bespoke script: https://gist.github.com/josharian/046b1be7aceae244de39 For ease of reviewing and future understanding, this CL is also broken down into four CLs, mailed separately, which show the manual and the automated changes separately. They are CLs 20990, 20991, 20992, and 20993. Passes toolstash -cmp. name old time/op new time/op delta Template 335ms ± 5% 324ms ± 5% -3.35% (p=0.000 n=23+24) Unicode 176ms ± 9% 165ms ± 6% -6.12% (p=0.000 n=23+24) GoTypes 1.10s ± 4% 1.07s ± 2% -2.77% (p=0.000 n=24+24) Compiler 5.31s ± 3% 5.15s ± 3% -2.95% (p=0.000 n=24+24) MakeBash 41.6s ± 1% 41.7s ± 2% ~ (p=0.586 n=23+23) name old alloc/op new alloc/op delta Template 63.3MB ± 0% 62.4MB ± 0% -1.36% (p=0.000 n=25+23) Unicode 42.4MB ± 0% 41.6MB ± 0% -1.99% (p=0.000 n=24+25) GoTypes 220MB ± 0% 217MB ± 0% -1.11% (p=0.000 n=25+25) Compiler 994MB ± 0% 973MB ± 0% -2.08% (p=0.000 n=24+25) name old allocs/op new allocs/op delta Template 681k ± 0% 574k ± 0% -15.71% (p=0.000 n=24+25) Unicode 518k ± 0% 413k ± 0% -20.34% (p=0.000 n=25+24) GoTypes 2.08M ± 0% 1.78M ± 0% -14.62% (p=0.000 n=25+25) Compiler 9.26M ± 0% 7.64M ± 0% -17.48% (p=0.000 n=25+25) name old text-bytes new text-bytes delta HelloSize 578k ± 0% 578k ± 0% ~ (all samples are equal) CmdGoSize 6.46M ± 0% 6.46M ± 0% ~ (all samples are equal) name old data-bytes new data-bytes delta HelloSize 128k ± 0% 128k ± 0% ~ (all samples are equal) CmdGoSize 281k ± 0% 281k ± 0% ~ (all samples are equal) name old exe-bytes new exe-bytes delta HelloSize 921k ± 0% 921k ± 0% ~ (all samples are equal) CmdGoSize 9.86M ± 0% 9.86M ± 0% ~ (all samples are equal) Change-Id: I277d95bd56d51c166ef7f560647aeaa092f3f475 Reviewed-on: https://go-review.googlesource.com/20959 Reviewed-by: Dave Cheney <dave@cheney.net> Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-03-20 08:03:31 -07:00
a = typecheck(a, Etop)
a = walkstmt(a)
init.Append(a)
setlineno(val)
a = nod(OAS, nod(OINDEX, m, key), val)
cmd/compile: reduce use of **Node parameters Escape analysis has a hard time with tree-like structures (see #13493 and #14858). This is unlikely to change. As a result, when invoking a function that accepts a **Node parameter, we usually allocate a *Node on the heap. This happens a whole lot. This CL changes functions from taking a **Node to acting more like append: It both modifies the input and returns a replacement for it. Because of the cascading nature of escape analysis, in order to get the benefits, I had to modify almost all such functions. The remaining functions are in racewalk and the backend. I would be happy to update them as well in a separate CL. This CL was created by manually updating the function signatures and the directly impacted bits of code. The callsites were then automatically updated using a bespoke script: https://gist.github.com/josharian/046b1be7aceae244de39 For ease of reviewing and future understanding, this CL is also broken down into four CLs, mailed separately, which show the manual and the automated changes separately. They are CLs 20990, 20991, 20992, and 20993. Passes toolstash -cmp. name old time/op new time/op delta Template 335ms ± 5% 324ms ± 5% -3.35% (p=0.000 n=23+24) Unicode 176ms ± 9% 165ms ± 6% -6.12% (p=0.000 n=23+24) GoTypes 1.10s ± 4% 1.07s ± 2% -2.77% (p=0.000 n=24+24) Compiler 5.31s ± 3% 5.15s ± 3% -2.95% (p=0.000 n=24+24) MakeBash 41.6s ± 1% 41.7s ± 2% ~ (p=0.586 n=23+23) name old alloc/op new alloc/op delta Template 63.3MB ± 0% 62.4MB ± 0% -1.36% (p=0.000 n=25+23) Unicode 42.4MB ± 0% 41.6MB ± 0% -1.99% (p=0.000 n=24+25) GoTypes 220MB ± 0% 217MB ± 0% -1.11% (p=0.000 n=25+25) Compiler 994MB ± 0% 973MB ± 0% -2.08% (p=0.000 n=24+25) name old allocs/op new allocs/op delta Template 681k ± 0% 574k ± 0% -15.71% (p=0.000 n=24+25) Unicode 518k ± 0% 413k ± 0% -20.34% (p=0.000 n=25+24) GoTypes 2.08M ± 0% 1.78M ± 0% -14.62% (p=0.000 n=25+25) Compiler 9.26M ± 0% 7.64M ± 0% -17.48% (p=0.000 n=25+25) name old text-bytes new text-bytes delta HelloSize 578k ± 0% 578k ± 0% ~ (all samples are equal) CmdGoSize 6.46M ± 0% 6.46M ± 0% ~ (all samples are equal) name old data-bytes new data-bytes delta HelloSize 128k ± 0% 128k ± 0% ~ (all samples are equal) CmdGoSize 281k ± 0% 281k ± 0% ~ (all samples are equal) name old exe-bytes new exe-bytes delta HelloSize 921k ± 0% 921k ± 0% ~ (all samples are equal) CmdGoSize 9.86M ± 0% 9.86M ± 0% ~ (all samples are equal) Change-Id: I277d95bd56d51c166ef7f560647aeaa092f3f475 Reviewed-on: https://go-review.googlesource.com/20959 Reviewed-by: Dave Cheney <dave@cheney.net> Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-03-20 08:03:31 -07:00
a = typecheck(a, Etop)
a = walkstmt(a)
init.Append(a)
if nerr != nerrors {
break
}
}
a := nod(OVARKILL, key, nil)
a = typecheck(a, Etop)
init.Append(a)
a = nod(OVARKILL, val, nil)
a = typecheck(a, Etop)
init.Append(a)
}
func anylit(n *Node, var_ *Node, init *Nodes) {
t := n.Type
switch n.Op {
default:
Fatalf("anylit: not lit, op=%v node=%v", n.Op, n)
case OPTRLIT:
if !t.IsPtr() {
Fatalf("anylit: not ptr")
}
var r *Node
if n.Right != nil {
// n.Right is stack temporary used as backing store.
init.Append(nod(OAS, n.Right, nil)) // zero backing store, just in case (#18410)
r = nod(OADDR, n.Right, nil)
cmd/compile: reduce use of **Node parameters Escape analysis has a hard time with tree-like structures (see #13493 and #14858). This is unlikely to change. As a result, when invoking a function that accepts a **Node parameter, we usually allocate a *Node on the heap. This happens a whole lot. This CL changes functions from taking a **Node to acting more like append: It both modifies the input and returns a replacement for it. Because of the cascading nature of escape analysis, in order to get the benefits, I had to modify almost all such functions. The remaining functions are in racewalk and the backend. I would be happy to update them as well in a separate CL. This CL was created by manually updating the function signatures and the directly impacted bits of code. The callsites were then automatically updated using a bespoke script: https://gist.github.com/josharian/046b1be7aceae244de39 For ease of reviewing and future understanding, this CL is also broken down into four CLs, mailed separately, which show the manual and the automated changes separately. They are CLs 20990, 20991, 20992, and 20993. Passes toolstash -cmp. name old time/op new time/op delta Template 335ms ± 5% 324ms ± 5% -3.35% (p=0.000 n=23+24) Unicode 176ms ± 9% 165ms ± 6% -6.12% (p=0.000 n=23+24) GoTypes 1.10s ± 4% 1.07s ± 2% -2.77% (p=0.000 n=24+24) Compiler 5.31s ± 3% 5.15s ± 3% -2.95% (p=0.000 n=24+24) MakeBash 41.6s ± 1% 41.7s ± 2% ~ (p=0.586 n=23+23) name old alloc/op new alloc/op delta Template 63.3MB ± 0% 62.4MB ± 0% -1.36% (p=0.000 n=25+23) Unicode 42.4MB ± 0% 41.6MB ± 0% -1.99% (p=0.000 n=24+25) GoTypes 220MB ± 0% 217MB ± 0% -1.11% (p=0.000 n=25+25) Compiler 994MB ± 0% 973MB ± 0% -2.08% (p=0.000 n=24+25) name old allocs/op new allocs/op delta Template 681k ± 0% 574k ± 0% -15.71% (p=0.000 n=24+25) Unicode 518k ± 0% 413k ± 0% -20.34% (p=0.000 n=25+24) GoTypes 2.08M ± 0% 1.78M ± 0% -14.62% (p=0.000 n=25+25) Compiler 9.26M ± 0% 7.64M ± 0% -17.48% (p=0.000 n=25+25) name old text-bytes new text-bytes delta HelloSize 578k ± 0% 578k ± 0% ~ (all samples are equal) CmdGoSize 6.46M ± 0% 6.46M ± 0% ~ (all samples are equal) name old data-bytes new data-bytes delta HelloSize 128k ± 0% 128k ± 0% ~ (all samples are equal) CmdGoSize 281k ± 0% 281k ± 0% ~ (all samples are equal) name old exe-bytes new exe-bytes delta HelloSize 921k ± 0% 921k ± 0% ~ (all samples are equal) CmdGoSize 9.86M ± 0% 9.86M ± 0% ~ (all samples are equal) Change-Id: I277d95bd56d51c166ef7f560647aeaa092f3f475 Reviewed-on: https://go-review.googlesource.com/20959 Reviewed-by: Dave Cheney <dave@cheney.net> Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-03-20 08:03:31 -07:00
r = typecheck(r, Erv)
} else {
r = nod(ONEW, nil, nil)
r.SetTypecheck(1)
r.Type = t
r.Esc = n.Esc
}
cmd/compile: reduce use of **Node parameters Escape analysis has a hard time with tree-like structures (see #13493 and #14858). This is unlikely to change. As a result, when invoking a function that accepts a **Node parameter, we usually allocate a *Node on the heap. This happens a whole lot. This CL changes functions from taking a **Node to acting more like append: It both modifies the input and returns a replacement for it. Because of the cascading nature of escape analysis, in order to get the benefits, I had to modify almost all such functions. The remaining functions are in racewalk and the backend. I would be happy to update them as well in a separate CL. This CL was created by manually updating the function signatures and the directly impacted bits of code. The callsites were then automatically updated using a bespoke script: https://gist.github.com/josharian/046b1be7aceae244de39 For ease of reviewing and future understanding, this CL is also broken down into four CLs, mailed separately, which show the manual and the automated changes separately. They are CLs 20990, 20991, 20992, and 20993. Passes toolstash -cmp. name old time/op new time/op delta Template 335ms ± 5% 324ms ± 5% -3.35% (p=0.000 n=23+24) Unicode 176ms ± 9% 165ms ± 6% -6.12% (p=0.000 n=23+24) GoTypes 1.10s ± 4% 1.07s ± 2% -2.77% (p=0.000 n=24+24) Compiler 5.31s ± 3% 5.15s ± 3% -2.95% (p=0.000 n=24+24) MakeBash 41.6s ± 1% 41.7s ± 2% ~ (p=0.586 n=23+23) name old alloc/op new alloc/op delta Template 63.3MB ± 0% 62.4MB ± 0% -1.36% (p=0.000 n=25+23) Unicode 42.4MB ± 0% 41.6MB ± 0% -1.99% (p=0.000 n=24+25) GoTypes 220MB ± 0% 217MB ± 0% -1.11% (p=0.000 n=25+25) Compiler 994MB ± 0% 973MB ± 0% -2.08% (p=0.000 n=24+25) name old allocs/op new allocs/op delta Template 681k ± 0% 574k ± 0% -15.71% (p=0.000 n=24+25) Unicode 518k ± 0% 413k ± 0% -20.34% (p=0.000 n=25+24) GoTypes 2.08M ± 0% 1.78M ± 0% -14.62% (p=0.000 n=25+25) Compiler 9.26M ± 0% 7.64M ± 0% -17.48% (p=0.000 n=25+25) name old text-bytes new text-bytes delta HelloSize 578k ± 0% 578k ± 0% ~ (all samples are equal) CmdGoSize 6.46M ± 0% 6.46M ± 0% ~ (all samples are equal) name old data-bytes new data-bytes delta HelloSize 128k ± 0% 128k ± 0% ~ (all samples are equal) CmdGoSize 281k ± 0% 281k ± 0% ~ (all samples are equal) name old exe-bytes new exe-bytes delta HelloSize 921k ± 0% 921k ± 0% ~ (all samples are equal) CmdGoSize 9.86M ± 0% 9.86M ± 0% ~ (all samples are equal) Change-Id: I277d95bd56d51c166ef7f560647aeaa092f3f475 Reviewed-on: https://go-review.googlesource.com/20959 Reviewed-by: Dave Cheney <dave@cheney.net> Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-03-20 08:03:31 -07:00
r = walkexpr(r, init)
a := nod(OAS, var_, r)
cmd/compile: reduce use of **Node parameters Escape analysis has a hard time with tree-like structures (see #13493 and #14858). This is unlikely to change. As a result, when invoking a function that accepts a **Node parameter, we usually allocate a *Node on the heap. This happens a whole lot. This CL changes functions from taking a **Node to acting more like append: It both modifies the input and returns a replacement for it. Because of the cascading nature of escape analysis, in order to get the benefits, I had to modify almost all such functions. The remaining functions are in racewalk and the backend. I would be happy to update them as well in a separate CL. This CL was created by manually updating the function signatures and the directly impacted bits of code. The callsites were then automatically updated using a bespoke script: https://gist.github.com/josharian/046b1be7aceae244de39 For ease of reviewing and future understanding, this CL is also broken down into four CLs, mailed separately, which show the manual and the automated changes separately. They are CLs 20990, 20991, 20992, and 20993. Passes toolstash -cmp. name old time/op new time/op delta Template 335ms ± 5% 324ms ± 5% -3.35% (p=0.000 n=23+24) Unicode 176ms ± 9% 165ms ± 6% -6.12% (p=0.000 n=23+24) GoTypes 1.10s ± 4% 1.07s ± 2% -2.77% (p=0.000 n=24+24) Compiler 5.31s ± 3% 5.15s ± 3% -2.95% (p=0.000 n=24+24) MakeBash 41.6s ± 1% 41.7s ± 2% ~ (p=0.586 n=23+23) name old alloc/op new alloc/op delta Template 63.3MB ± 0% 62.4MB ± 0% -1.36% (p=0.000 n=25+23) Unicode 42.4MB ± 0% 41.6MB ± 0% -1.99% (p=0.000 n=24+25) GoTypes 220MB ± 0% 217MB ± 0% -1.11% (p=0.000 n=25+25) Compiler 994MB ± 0% 973MB ± 0% -2.08% (p=0.000 n=24+25) name old allocs/op new allocs/op delta Template 681k ± 0% 574k ± 0% -15.71% (p=0.000 n=24+25) Unicode 518k ± 0% 413k ± 0% -20.34% (p=0.000 n=25+24) GoTypes 2.08M ± 0% 1.78M ± 0% -14.62% (p=0.000 n=25+25) Compiler 9.26M ± 0% 7.64M ± 0% -17.48% (p=0.000 n=25+25) name old text-bytes new text-bytes delta HelloSize 578k ± 0% 578k ± 0% ~ (all samples are equal) CmdGoSize 6.46M ± 0% 6.46M ± 0% ~ (all samples are equal) name old data-bytes new data-bytes delta HelloSize 128k ± 0% 128k ± 0% ~ (all samples are equal) CmdGoSize 281k ± 0% 281k ± 0% ~ (all samples are equal) name old exe-bytes new exe-bytes delta HelloSize 921k ± 0% 921k ± 0% ~ (all samples are equal) CmdGoSize 9.86M ± 0% 9.86M ± 0% ~ (all samples are equal) Change-Id: I277d95bd56d51c166ef7f560647aeaa092f3f475 Reviewed-on: https://go-review.googlesource.com/20959 Reviewed-by: Dave Cheney <dave@cheney.net> Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-03-20 08:03:31 -07:00
a = typecheck(a, Etop)
init.Append(a)
var_ = nod(OIND, var_, nil)
cmd/compile: reduce use of **Node parameters Escape analysis has a hard time with tree-like structures (see #13493 and #14858). This is unlikely to change. As a result, when invoking a function that accepts a **Node parameter, we usually allocate a *Node on the heap. This happens a whole lot. This CL changes functions from taking a **Node to acting more like append: It both modifies the input and returns a replacement for it. Because of the cascading nature of escape analysis, in order to get the benefits, I had to modify almost all such functions. The remaining functions are in racewalk and the backend. I would be happy to update them as well in a separate CL. This CL was created by manually updating the function signatures and the directly impacted bits of code. The callsites were then automatically updated using a bespoke script: https://gist.github.com/josharian/046b1be7aceae244de39 For ease of reviewing and future understanding, this CL is also broken down into four CLs, mailed separately, which show the manual and the automated changes separately. They are CLs 20990, 20991, 20992, and 20993. Passes toolstash -cmp. name old time/op new time/op delta Template 335ms ± 5% 324ms ± 5% -3.35% (p=0.000 n=23+24) Unicode 176ms ± 9% 165ms ± 6% -6.12% (p=0.000 n=23+24) GoTypes 1.10s ± 4% 1.07s ± 2% -2.77% (p=0.000 n=24+24) Compiler 5.31s ± 3% 5.15s ± 3% -2.95% (p=0.000 n=24+24) MakeBash 41.6s ± 1% 41.7s ± 2% ~ (p=0.586 n=23+23) name old alloc/op new alloc/op delta Template 63.3MB ± 0% 62.4MB ± 0% -1.36% (p=0.000 n=25+23) Unicode 42.4MB ± 0% 41.6MB ± 0% -1.99% (p=0.000 n=24+25) GoTypes 220MB ± 0% 217MB ± 0% -1.11% (p=0.000 n=25+25) Compiler 994MB ± 0% 973MB ± 0% -2.08% (p=0.000 n=24+25) name old allocs/op new allocs/op delta Template 681k ± 0% 574k ± 0% -15.71% (p=0.000 n=24+25) Unicode 518k ± 0% 413k ± 0% -20.34% (p=0.000 n=25+24) GoTypes 2.08M ± 0% 1.78M ± 0% -14.62% (p=0.000 n=25+25) Compiler 9.26M ± 0% 7.64M ± 0% -17.48% (p=0.000 n=25+25) name old text-bytes new text-bytes delta HelloSize 578k ± 0% 578k ± 0% ~ (all samples are equal) CmdGoSize 6.46M ± 0% 6.46M ± 0% ~ (all samples are equal) name old data-bytes new data-bytes delta HelloSize 128k ± 0% 128k ± 0% ~ (all samples are equal) CmdGoSize 281k ± 0% 281k ± 0% ~ (all samples are equal) name old exe-bytes new exe-bytes delta HelloSize 921k ± 0% 921k ± 0% ~ (all samples are equal) CmdGoSize 9.86M ± 0% 9.86M ± 0% ~ (all samples are equal) Change-Id: I277d95bd56d51c166ef7f560647aeaa092f3f475 Reviewed-on: https://go-review.googlesource.com/20959 Reviewed-by: Dave Cheney <dave@cheney.net> Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-03-20 08:03:31 -07:00
var_ = typecheck(var_, Erv|Easgn)
anylit(n.Left, var_, init)
case OSTRUCTLIT, OARRAYLIT:
if !t.IsStruct() && !t.IsArray() {
Fatalf("anylit: not struct/array")
}
if var_.isSimpleName() && n.List.Len() > 4 {
// lay out static data
vstat := staticname(t)
cmd/compile: pack bool fields in Node, Name, Func and Type structs to bitsets This reduces compiler memory usage by up to 4% - see compilebench results below. name old time/op new time/op delta Template 245ms ± 4% 241ms ± 2% -1.88% (p=0.029 n=10+10) Unicode 126ms ± 3% 124ms ± 3% ~ (p=0.105 n=10+10) GoTypes 805ms ± 2% 813ms ± 3% ~ (p=0.515 n=8+10) Compiler 3.95s ± 2% 3.83s ± 1% -2.96% (p=0.000 n=9+10) MakeBash 47.4s ± 4% 46.6s ± 1% -1.59% (p=0.028 n=9+10) name old user-ns/op new user-ns/op delta Template 324M ± 5% 326M ± 3% ~ (p=0.935 n=10+10) Unicode 186M ± 5% 178M ±10% ~ (p=0.067 n=9+10) GoTypes 1.08G ± 7% 1.09G ± 4% ~ (p=0.956 n=10+10) Compiler 5.34G ± 4% 5.31G ± 1% ~ (p=0.501 n=10+8) name old alloc/op new alloc/op delta Template 41.0MB ± 0% 39.8MB ± 0% -3.03% (p=0.000 n=10+10) Unicode 32.3MB ± 0% 31.0MB ± 0% -4.13% (p=0.000 n=10+10) GoTypes 119MB ± 0% 116MB ± 0% -2.39% (p=0.000 n=10+10) Compiler 499MB ± 0% 487MB ± 0% -2.48% (p=0.000 n=10+10) name old allocs/op new allocs/op delta Template 380k ± 1% 379k ± 1% ~ (p=0.436 n=10+10) Unicode 324k ± 1% 324k ± 0% ~ (p=0.853 n=10+10) GoTypes 1.15M ± 0% 1.15M ± 0% ~ (p=0.481 n=10+10) Compiler 4.41M ± 0% 4.41M ± 0% -0.12% (p=0.007 n=10+10) name old text-bytes new text-bytes delta HelloSize 623k ± 0% 623k ± 0% ~ (all equal) CmdGoSize 6.64M ± 0% 6.64M ± 0% ~ (all equal) name old data-bytes new data-bytes delta HelloSize 5.81k ± 0% 5.81k ± 0% ~ (all equal) CmdGoSize 238k ± 0% 238k ± 0% ~ (all equal) name old bss-bytes new bss-bytes delta HelloSize 134k ± 0% 134k ± 0% ~ (all equal) CmdGoSize 152k ± 0% 152k ± 0% ~ (all equal) name old exe-bytes new exe-bytes delta HelloSize 967k ± 0% 967k ± 0% ~ (all equal) CmdGoSize 10.2M ± 0% 10.2M ± 0% ~ (all equal) Change-Id: I1f40af738254892bd6c8ba2eb43390b175753d52 Reviewed-on: https://go-review.googlesource.com/37445 Reviewed-by: Matthew Dempsky <mdempsky@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-02-27 19:56:38 +02:00
vstat.Name.SetReadonly(true)
ctxt := inInitFunction
if n.Op == OARRAYLIT {
ctxt = inNonInitFunction
}
fixedlit(ctxt, initKindStatic, n, vstat, init)
// copy static to var
a := nod(OAS, var_, vstat)
a = typecheck(a, Etop)
a = walkexpr(a, init)
init.Append(a)
// add expressions to automatic
fixedlit(inInitFunction, initKindDynamic, n, var_, init)
break
}
var components int64
if n.Op == OARRAYLIT {
components = t.NumElem()
} else {
components = int64(t.NumFields())
}
// initialization of an array or struct with unspecified components (missing fields or arrays)
if var_.isSimpleName() || int64(n.List.Len()) < components {
a := nod(OAS, var_, nil)
cmd/compile: reduce use of **Node parameters Escape analysis has a hard time with tree-like structures (see #13493 and #14858). This is unlikely to change. As a result, when invoking a function that accepts a **Node parameter, we usually allocate a *Node on the heap. This happens a whole lot. This CL changes functions from taking a **Node to acting more like append: It both modifies the input and returns a replacement for it. Because of the cascading nature of escape analysis, in order to get the benefits, I had to modify almost all such functions. The remaining functions are in racewalk and the backend. I would be happy to update them as well in a separate CL. This CL was created by manually updating the function signatures and the directly impacted bits of code. The callsites were then automatically updated using a bespoke script: https://gist.github.com/josharian/046b1be7aceae244de39 For ease of reviewing and future understanding, this CL is also broken down into four CLs, mailed separately, which show the manual and the automated changes separately. They are CLs 20990, 20991, 20992, and 20993. Passes toolstash -cmp. name old time/op new time/op delta Template 335ms ± 5% 324ms ± 5% -3.35% (p=0.000 n=23+24) Unicode 176ms ± 9% 165ms ± 6% -6.12% (p=0.000 n=23+24) GoTypes 1.10s ± 4% 1.07s ± 2% -2.77% (p=0.000 n=24+24) Compiler 5.31s ± 3% 5.15s ± 3% -2.95% (p=0.000 n=24+24) MakeBash 41.6s ± 1% 41.7s ± 2% ~ (p=0.586 n=23+23) name old alloc/op new alloc/op delta Template 63.3MB ± 0% 62.4MB ± 0% -1.36% (p=0.000 n=25+23) Unicode 42.4MB ± 0% 41.6MB ± 0% -1.99% (p=0.000 n=24+25) GoTypes 220MB ± 0% 217MB ± 0% -1.11% (p=0.000 n=25+25) Compiler 994MB ± 0% 973MB ± 0% -2.08% (p=0.000 n=24+25) name old allocs/op new allocs/op delta Template 681k ± 0% 574k ± 0% -15.71% (p=0.000 n=24+25) Unicode 518k ± 0% 413k ± 0% -20.34% (p=0.000 n=25+24) GoTypes 2.08M ± 0% 1.78M ± 0% -14.62% (p=0.000 n=25+25) Compiler 9.26M ± 0% 7.64M ± 0% -17.48% (p=0.000 n=25+25) name old text-bytes new text-bytes delta HelloSize 578k ± 0% 578k ± 0% ~ (all samples are equal) CmdGoSize 6.46M ± 0% 6.46M ± 0% ~ (all samples are equal) name old data-bytes new data-bytes delta HelloSize 128k ± 0% 128k ± 0% ~ (all samples are equal) CmdGoSize 281k ± 0% 281k ± 0% ~ (all samples are equal) name old exe-bytes new exe-bytes delta HelloSize 921k ± 0% 921k ± 0% ~ (all samples are equal) CmdGoSize 9.86M ± 0% 9.86M ± 0% ~ (all samples are equal) Change-Id: I277d95bd56d51c166ef7f560647aeaa092f3f475 Reviewed-on: https://go-review.googlesource.com/20959 Reviewed-by: Dave Cheney <dave@cheney.net> Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-03-20 08:03:31 -07:00
a = typecheck(a, Etop)
a = walkexpr(a, init)
init.Append(a)
}
fixedlit(inInitFunction, initKindLocalCode, n, var_, init)
case OSLICELIT:
slicelit(inInitFunction, n, var_, init)
case OMAPLIT:
if !t.IsMap() {
Fatalf("anylit: not map")
}
maplit(n, var_, init)
}
}
func oaslit(n *Node, init *Nodes) bool {
if n.Left == nil || n.Right == nil {
// not a special composite literal assignment
return false
}
if n.Left.Type == nil || n.Right.Type == nil {
// not a special composite literal assignment
return false
}
if !n.Left.isSimpleName() {
// not a special composite literal assignment
return false
}
if !eqtype(n.Left.Type, n.Right.Type) {
// not a special composite literal assignment
return false
}
switch n.Right.Op {
default:
// not a special composite literal assignment
return false
case OSTRUCTLIT, OARRAYLIT, OSLICELIT, OMAPLIT:
if vmatch1(n.Left, n.Right) {
// not a special composite literal assignment
return false
}
anylit(n.Right, n.Left, init)
}
n.Op = OEMPTY
n.Right = nil
return true
}
func getlit(lit *Node) int {
if smallintconst(lit) {
return int(lit.Int64())
}
return -1
}
// stataddr sets nam to the static address of n and reports whether it succeeded.
func stataddr(nam *Node, n *Node) bool {
if n == nil {
return false
}
switch n.Op {
case ONAME:
*nam = *n
cmd/compile: pack bool fields in Node, Name, Func and Type structs to bitsets This reduces compiler memory usage by up to 4% - see compilebench results below. name old time/op new time/op delta Template 245ms ± 4% 241ms ± 2% -1.88% (p=0.029 n=10+10) Unicode 126ms ± 3% 124ms ± 3% ~ (p=0.105 n=10+10) GoTypes 805ms ± 2% 813ms ± 3% ~ (p=0.515 n=8+10) Compiler 3.95s ± 2% 3.83s ± 1% -2.96% (p=0.000 n=9+10) MakeBash 47.4s ± 4% 46.6s ± 1% -1.59% (p=0.028 n=9+10) name old user-ns/op new user-ns/op delta Template 324M ± 5% 326M ± 3% ~ (p=0.935 n=10+10) Unicode 186M ± 5% 178M ±10% ~ (p=0.067 n=9+10) GoTypes 1.08G ± 7% 1.09G ± 4% ~ (p=0.956 n=10+10) Compiler 5.34G ± 4% 5.31G ± 1% ~ (p=0.501 n=10+8) name old alloc/op new alloc/op delta Template 41.0MB ± 0% 39.8MB ± 0% -3.03% (p=0.000 n=10+10) Unicode 32.3MB ± 0% 31.0MB ± 0% -4.13% (p=0.000 n=10+10) GoTypes 119MB ± 0% 116MB ± 0% -2.39% (p=0.000 n=10+10) Compiler 499MB ± 0% 487MB ± 0% -2.48% (p=0.000 n=10+10) name old allocs/op new allocs/op delta Template 380k ± 1% 379k ± 1% ~ (p=0.436 n=10+10) Unicode 324k ± 1% 324k ± 0% ~ (p=0.853 n=10+10) GoTypes 1.15M ± 0% 1.15M ± 0% ~ (p=0.481 n=10+10) Compiler 4.41M ± 0% 4.41M ± 0% -0.12% (p=0.007 n=10+10) name old text-bytes new text-bytes delta HelloSize 623k ± 0% 623k ± 0% ~ (all equal) CmdGoSize 6.64M ± 0% 6.64M ± 0% ~ (all equal) name old data-bytes new data-bytes delta HelloSize 5.81k ± 0% 5.81k ± 0% ~ (all equal) CmdGoSize 238k ± 0% 238k ± 0% ~ (all equal) name old bss-bytes new bss-bytes delta HelloSize 134k ± 0% 134k ± 0% ~ (all equal) CmdGoSize 152k ± 0% 152k ± 0% ~ (all equal) name old exe-bytes new exe-bytes delta HelloSize 967k ± 0% 967k ± 0% ~ (all equal) CmdGoSize 10.2M ± 0% 10.2M ± 0% ~ (all equal) Change-Id: I1f40af738254892bd6c8ba2eb43390b175753d52 Reviewed-on: https://go-review.googlesource.com/37445 Reviewed-by: Matthew Dempsky <mdempsky@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-02-27 19:56:38 +02:00
return n.Addable()
case ODOT:
if !stataddr(nam, n.Left) {
break
}
nam.Xoffset += n.Xoffset
nam.Type = n.Type
return true
case OINDEX:
if n.Left.Type.IsSlice() {
break
}
if !stataddr(nam, n.Left) {
break
}
l := getlit(n.Right)
if l < 0 {
break
}
// Check for overflow.
if n.Type.Width != 0 && thearch.MAXWIDTH/n.Type.Width <= int64(l) {
break
}
nam.Xoffset += int64(l) * n.Type.Width
nam.Type = n.Type
return true
}
return false
}
func initplan(n *Node) {
if initplans[n] != nil {
return
}
p := new(InitPlan)
initplans[n] = p
switch n.Op {
default:
Fatalf("initplan")
case OARRAYLIT, OSLICELIT:
cmd/compile: stop adding implicit OKEY nodes Keys are uncommon in array and slice literals, and normalizing OARRAYLIT and OSLICELIT nodes to always use OKEY ends up not reducing complexity much. Instead, only create OKEY nodes to represent explicit keys, and recalculate implicit keys when/where necessary. Fixes #15350. name old time/op new time/op delta Template 299ms ± 9% 299ms ±12% ~ (p=0.694 n=28+30) Unicode 165ms ± 7% 162ms ± 9% ~ (p=0.084 n=27+27) GoTypes 950ms ± 9% 963ms ± 5% ~ (p=0.301 n=30+29) Compiler 4.23s ± 7% 4.17s ± 7% ~ (p=0.057 n=29+27) name old user-ns/op new user-ns/op delta Template 389M ±15% 400M ±12% ~ (p=0.202 n=30+29) Unicode 246M ±21% 232M ±22% -5.76% (p=0.006 n=28+29) GoTypes 1.34G ± 8% 1.34G ± 7% ~ (p=0.775 n=28+30) Compiler 5.91G ± 6% 5.87G ± 7% ~ (p=0.298 n=28+29) name old alloc/op new alloc/op delta Template 41.2MB ± 0% 41.2MB ± 0% ~ (p=0.085 n=30+30) Unicode 34.0MB ± 0% 31.5MB ± 0% -7.28% (p=0.000 n=30+29) GoTypes 121MB ± 0% 121MB ± 0% ~ (p=0.657 n=30+30) Compiler 511MB ± 0% 511MB ± 0% -0.01% (p=0.001 n=29+29) name old allocs/op new allocs/op delta Template 390k ± 0% 390k ± 0% ~ (p=0.225 n=30+29) Unicode 318k ± 0% 293k ± 0% -8.03% (p=0.000 n=30+29) GoTypes 1.16M ± 0% 1.16M ± 0% ~ (p=0.745 n=30+30) Compiler 4.35M ± 0% 4.35M ± 0% ~ (p=0.105 n=30+30) Change-Id: I6310739a0bfdb54f1ab8a460b2c03615ad1ff5bc Reviewed-on: https://go-review.googlesource.com/32221 Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-10-27 02:02:30 -07:00
var k int64
for _, a := range n.List.Slice() {
cmd/compile: stop adding implicit OKEY nodes Keys are uncommon in array and slice literals, and normalizing OARRAYLIT and OSLICELIT nodes to always use OKEY ends up not reducing complexity much. Instead, only create OKEY nodes to represent explicit keys, and recalculate implicit keys when/where necessary. Fixes #15350. name old time/op new time/op delta Template 299ms ± 9% 299ms ±12% ~ (p=0.694 n=28+30) Unicode 165ms ± 7% 162ms ± 9% ~ (p=0.084 n=27+27) GoTypes 950ms ± 9% 963ms ± 5% ~ (p=0.301 n=30+29) Compiler 4.23s ± 7% 4.17s ± 7% ~ (p=0.057 n=29+27) name old user-ns/op new user-ns/op delta Template 389M ±15% 400M ±12% ~ (p=0.202 n=30+29) Unicode 246M ±21% 232M ±22% -5.76% (p=0.006 n=28+29) GoTypes 1.34G ± 8% 1.34G ± 7% ~ (p=0.775 n=28+30) Compiler 5.91G ± 6% 5.87G ± 7% ~ (p=0.298 n=28+29) name old alloc/op new alloc/op delta Template 41.2MB ± 0% 41.2MB ± 0% ~ (p=0.085 n=30+30) Unicode 34.0MB ± 0% 31.5MB ± 0% -7.28% (p=0.000 n=30+29) GoTypes 121MB ± 0% 121MB ± 0% ~ (p=0.657 n=30+30) Compiler 511MB ± 0% 511MB ± 0% -0.01% (p=0.001 n=29+29) name old allocs/op new allocs/op delta Template 390k ± 0% 390k ± 0% ~ (p=0.225 n=30+29) Unicode 318k ± 0% 293k ± 0% -8.03% (p=0.000 n=30+29) GoTypes 1.16M ± 0% 1.16M ± 0% ~ (p=0.745 n=30+30) Compiler 4.35M ± 0% 4.35M ± 0% ~ (p=0.105 n=30+30) Change-Id: I6310739a0bfdb54f1ab8a460b2c03615ad1ff5bc Reviewed-on: https://go-review.googlesource.com/32221 Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-10-27 02:02:30 -07:00
if a.Op == OKEY {
k = nonnegintconst(a.Left)
a = a.Right
}
cmd/compile: stop adding implicit OKEY nodes Keys are uncommon in array and slice literals, and normalizing OARRAYLIT and OSLICELIT nodes to always use OKEY ends up not reducing complexity much. Instead, only create OKEY nodes to represent explicit keys, and recalculate implicit keys when/where necessary. Fixes #15350. name old time/op new time/op delta Template 299ms ± 9% 299ms ±12% ~ (p=0.694 n=28+30) Unicode 165ms ± 7% 162ms ± 9% ~ (p=0.084 n=27+27) GoTypes 950ms ± 9% 963ms ± 5% ~ (p=0.301 n=30+29) Compiler 4.23s ± 7% 4.17s ± 7% ~ (p=0.057 n=29+27) name old user-ns/op new user-ns/op delta Template 389M ±15% 400M ±12% ~ (p=0.202 n=30+29) Unicode 246M ±21% 232M ±22% -5.76% (p=0.006 n=28+29) GoTypes 1.34G ± 8% 1.34G ± 7% ~ (p=0.775 n=28+30) Compiler 5.91G ± 6% 5.87G ± 7% ~ (p=0.298 n=28+29) name old alloc/op new alloc/op delta Template 41.2MB ± 0% 41.2MB ± 0% ~ (p=0.085 n=30+30) Unicode 34.0MB ± 0% 31.5MB ± 0% -7.28% (p=0.000 n=30+29) GoTypes 121MB ± 0% 121MB ± 0% ~ (p=0.657 n=30+30) Compiler 511MB ± 0% 511MB ± 0% -0.01% (p=0.001 n=29+29) name old allocs/op new allocs/op delta Template 390k ± 0% 390k ± 0% ~ (p=0.225 n=30+29) Unicode 318k ± 0% 293k ± 0% -8.03% (p=0.000 n=30+29) GoTypes 1.16M ± 0% 1.16M ± 0% ~ (p=0.745 n=30+30) Compiler 4.35M ± 0% 4.35M ± 0% ~ (p=0.105 n=30+30) Change-Id: I6310739a0bfdb54f1ab8a460b2c03615ad1ff5bc Reviewed-on: https://go-review.googlesource.com/32221 Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-10-27 02:02:30 -07:00
addvalue(p, k*n.Type.Elem().Width, a)
k++
}
case OSTRUCTLIT:
for _, a := range n.List.Slice() {
cmd/compile: add OSTRUCTKEY for keyed struct literals Previously, we used OKEY nodes to represent keyed struct literal elements. The field names were represented by an ONAME node, but this is clumsy because it's the only remaining case where ONAME was used to represent a bare identifier and not a variable. This CL introduces a new OSTRUCTKEY node op for use in struct literals. These ops instead store the field name in the node's own Sym field. This is similar in spirit to golang.org/cl/20890. Significant reduction in allocations for struct literal heavy code like package unicode: name old time/op new time/op delta Template 345ms ± 6% 341ms ± 6% ~ (p=0.141 n=29+28) Unicode 200ms ± 9% 184ms ± 7% -7.77% (p=0.000 n=29+30) GoTypes 1.04s ± 3% 1.05s ± 3% ~ (p=0.096 n=30+30) Compiler 4.47s ± 9% 4.49s ± 6% ~ (p=0.890 n=29+29) name old user-ns/op new user-ns/op delta Template 523M ±13% 516M ±17% ~ (p=0.400 n=29+30) Unicode 334M ±27% 314M ±30% ~ (p=0.093 n=30+30) GoTypes 1.53G ±10% 1.52G ±10% ~ (p=0.572 n=30+30) Compiler 6.28G ± 7% 6.34G ±11% ~ (p=0.300 n=30+30) name old alloc/op new alloc/op delta Template 44.5MB ± 0% 44.4MB ± 0% -0.35% (p=0.000 n=27+30) Unicode 39.2MB ± 0% 34.5MB ± 0% -11.79% (p=0.000 n=26+30) GoTypes 125MB ± 0% 125MB ± 0% -0.12% (p=0.000 n=29+30) Compiler 515MB ± 0% 515MB ± 0% -0.10% (p=0.000 n=29+30) name old allocs/op new allocs/op delta Template 426k ± 0% 424k ± 0% -0.39% (p=0.000 n=29+30) Unicode 374k ± 0% 323k ± 0% -13.67% (p=0.000 n=29+30) GoTypes 1.21M ± 0% 1.21M ± 0% -0.14% (p=0.000 n=29+29) Compiler 4.40M ± 0% 4.39M ± 0% -0.13% (p=0.000 n=29+30) Passes toolstash/buildall. Change-Id: Iba4ee765dd1748f67e52fcade1cd75c9f6e13fa9 Reviewed-on: https://go-review.googlesource.com/30974 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-10-12 15:48:18 -07:00
if a.Op != OSTRUCTKEY {
Fatalf("initplan fixedlit")
}
cmd/compile: add OSTRUCTKEY for keyed struct literals Previously, we used OKEY nodes to represent keyed struct literal elements. The field names were represented by an ONAME node, but this is clumsy because it's the only remaining case where ONAME was used to represent a bare identifier and not a variable. This CL introduces a new OSTRUCTKEY node op for use in struct literals. These ops instead store the field name in the node's own Sym field. This is similar in spirit to golang.org/cl/20890. Significant reduction in allocations for struct literal heavy code like package unicode: name old time/op new time/op delta Template 345ms ± 6% 341ms ± 6% ~ (p=0.141 n=29+28) Unicode 200ms ± 9% 184ms ± 7% -7.77% (p=0.000 n=29+30) GoTypes 1.04s ± 3% 1.05s ± 3% ~ (p=0.096 n=30+30) Compiler 4.47s ± 9% 4.49s ± 6% ~ (p=0.890 n=29+29) name old user-ns/op new user-ns/op delta Template 523M ±13% 516M ±17% ~ (p=0.400 n=29+30) Unicode 334M ±27% 314M ±30% ~ (p=0.093 n=30+30) GoTypes 1.53G ±10% 1.52G ±10% ~ (p=0.572 n=30+30) Compiler 6.28G ± 7% 6.34G ±11% ~ (p=0.300 n=30+30) name old alloc/op new alloc/op delta Template 44.5MB ± 0% 44.4MB ± 0% -0.35% (p=0.000 n=27+30) Unicode 39.2MB ± 0% 34.5MB ± 0% -11.79% (p=0.000 n=26+30) GoTypes 125MB ± 0% 125MB ± 0% -0.12% (p=0.000 n=29+30) Compiler 515MB ± 0% 515MB ± 0% -0.10% (p=0.000 n=29+30) name old allocs/op new allocs/op delta Template 426k ± 0% 424k ± 0% -0.39% (p=0.000 n=29+30) Unicode 374k ± 0% 323k ± 0% -13.67% (p=0.000 n=29+30) GoTypes 1.21M ± 0% 1.21M ± 0% -0.14% (p=0.000 n=29+29) Compiler 4.40M ± 0% 4.39M ± 0% -0.13% (p=0.000 n=29+30) Passes toolstash/buildall. Change-Id: Iba4ee765dd1748f67e52fcade1cd75c9f6e13fa9 Reviewed-on: https://go-review.googlesource.com/30974 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-10-12 15:48:18 -07:00
addvalue(p, a.Xoffset, a.Left)
}
case OMAPLIT:
for _, a := range n.List.Slice() {
if a.Op != OKEY {
Fatalf("initplan maplit")
}
addvalue(p, -1, a.Right)
}
}
}
func addvalue(p *InitPlan, xoffset int64, n *Node) {
// special case: zero can be dropped entirely
if isZero(n) {
return
}
// special case: inline struct and array (not slice) literals
if isvaluelit(n) {
initplan(n)
q := initplans[n]
for _, qe := range q.E {
// qe is a copy; we are not modifying entries in q.E
qe.Xoffset += xoffset
p.E = append(p.E, qe)
}
return
}
// add to plan
p.E = append(p.E, InitEntry{Xoffset: xoffset, Expr: n})
}
func isZero(n *Node) bool {
switch n.Op {
case OLITERAL:
switch u := n.Val().U.(type) {
default:
Dump("unexpected literal", n)
Fatalf("isZero")
case *NilVal:
return true
case string:
return u == ""
case bool:
return !u
case *Mpint:
return u.CmpInt64(0) == 0
case *Mpflt:
return u.CmpFloat64(0) == 0
case *Mpcplx:
return u.Real.CmpFloat64(0) == 0 && u.Imag.CmpFloat64(0) == 0
}
cmd/compile: add OSTRUCTKEY for keyed struct literals Previously, we used OKEY nodes to represent keyed struct literal elements. The field names were represented by an ONAME node, but this is clumsy because it's the only remaining case where ONAME was used to represent a bare identifier and not a variable. This CL introduces a new OSTRUCTKEY node op for use in struct literals. These ops instead store the field name in the node's own Sym field. This is similar in spirit to golang.org/cl/20890. Significant reduction in allocations for struct literal heavy code like package unicode: name old time/op new time/op delta Template 345ms ± 6% 341ms ± 6% ~ (p=0.141 n=29+28) Unicode 200ms ± 9% 184ms ± 7% -7.77% (p=0.000 n=29+30) GoTypes 1.04s ± 3% 1.05s ± 3% ~ (p=0.096 n=30+30) Compiler 4.47s ± 9% 4.49s ± 6% ~ (p=0.890 n=29+29) name old user-ns/op new user-ns/op delta Template 523M ±13% 516M ±17% ~ (p=0.400 n=29+30) Unicode 334M ±27% 314M ±30% ~ (p=0.093 n=30+30) GoTypes 1.53G ±10% 1.52G ±10% ~ (p=0.572 n=30+30) Compiler 6.28G ± 7% 6.34G ±11% ~ (p=0.300 n=30+30) name old alloc/op new alloc/op delta Template 44.5MB ± 0% 44.4MB ± 0% -0.35% (p=0.000 n=27+30) Unicode 39.2MB ± 0% 34.5MB ± 0% -11.79% (p=0.000 n=26+30) GoTypes 125MB ± 0% 125MB ± 0% -0.12% (p=0.000 n=29+30) Compiler 515MB ± 0% 515MB ± 0% -0.10% (p=0.000 n=29+30) name old allocs/op new allocs/op delta Template 426k ± 0% 424k ± 0% -0.39% (p=0.000 n=29+30) Unicode 374k ± 0% 323k ± 0% -13.67% (p=0.000 n=29+30) GoTypes 1.21M ± 0% 1.21M ± 0% -0.14% (p=0.000 n=29+29) Compiler 4.40M ± 0% 4.39M ± 0% -0.13% (p=0.000 n=29+30) Passes toolstash/buildall. Change-Id: Iba4ee765dd1748f67e52fcade1cd75c9f6e13fa9 Reviewed-on: https://go-review.googlesource.com/30974 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-10-12 15:48:18 -07:00
case OARRAYLIT:
for _, n1 := range n.List.Slice() {
cmd/compile: stop adding implicit OKEY nodes Keys are uncommon in array and slice literals, and normalizing OARRAYLIT and OSLICELIT nodes to always use OKEY ends up not reducing complexity much. Instead, only create OKEY nodes to represent explicit keys, and recalculate implicit keys when/where necessary. Fixes #15350. name old time/op new time/op delta Template 299ms ± 9% 299ms ±12% ~ (p=0.694 n=28+30) Unicode 165ms ± 7% 162ms ± 9% ~ (p=0.084 n=27+27) GoTypes 950ms ± 9% 963ms ± 5% ~ (p=0.301 n=30+29) Compiler 4.23s ± 7% 4.17s ± 7% ~ (p=0.057 n=29+27) name old user-ns/op new user-ns/op delta Template 389M ±15% 400M ±12% ~ (p=0.202 n=30+29) Unicode 246M ±21% 232M ±22% -5.76% (p=0.006 n=28+29) GoTypes 1.34G ± 8% 1.34G ± 7% ~ (p=0.775 n=28+30) Compiler 5.91G ± 6% 5.87G ± 7% ~ (p=0.298 n=28+29) name old alloc/op new alloc/op delta Template 41.2MB ± 0% 41.2MB ± 0% ~ (p=0.085 n=30+30) Unicode 34.0MB ± 0% 31.5MB ± 0% -7.28% (p=0.000 n=30+29) GoTypes 121MB ± 0% 121MB ± 0% ~ (p=0.657 n=30+30) Compiler 511MB ± 0% 511MB ± 0% -0.01% (p=0.001 n=29+29) name old allocs/op new allocs/op delta Template 390k ± 0% 390k ± 0% ~ (p=0.225 n=30+29) Unicode 318k ± 0% 293k ± 0% -8.03% (p=0.000 n=30+29) GoTypes 1.16M ± 0% 1.16M ± 0% ~ (p=0.745 n=30+30) Compiler 4.35M ± 0% 4.35M ± 0% ~ (p=0.105 n=30+30) Change-Id: I6310739a0bfdb54f1ab8a460b2c03615ad1ff5bc Reviewed-on: https://go-review.googlesource.com/32221 Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-10-27 02:02:30 -07:00
if n1.Op == OKEY {
n1 = n1.Right
}
if !isZero(n1) {
return false
}
}
return true
cmd/compile: add OSTRUCTKEY for keyed struct literals Previously, we used OKEY nodes to represent keyed struct literal elements. The field names were represented by an ONAME node, but this is clumsy because it's the only remaining case where ONAME was used to represent a bare identifier and not a variable. This CL introduces a new OSTRUCTKEY node op for use in struct literals. These ops instead store the field name in the node's own Sym field. This is similar in spirit to golang.org/cl/20890. Significant reduction in allocations for struct literal heavy code like package unicode: name old time/op new time/op delta Template 345ms ± 6% 341ms ± 6% ~ (p=0.141 n=29+28) Unicode 200ms ± 9% 184ms ± 7% -7.77% (p=0.000 n=29+30) GoTypes 1.04s ± 3% 1.05s ± 3% ~ (p=0.096 n=30+30) Compiler 4.47s ± 9% 4.49s ± 6% ~ (p=0.890 n=29+29) name old user-ns/op new user-ns/op delta Template 523M ±13% 516M ±17% ~ (p=0.400 n=29+30) Unicode 334M ±27% 314M ±30% ~ (p=0.093 n=30+30) GoTypes 1.53G ±10% 1.52G ±10% ~ (p=0.572 n=30+30) Compiler 6.28G ± 7% 6.34G ±11% ~ (p=0.300 n=30+30) name old alloc/op new alloc/op delta Template 44.5MB ± 0% 44.4MB ± 0% -0.35% (p=0.000 n=27+30) Unicode 39.2MB ± 0% 34.5MB ± 0% -11.79% (p=0.000 n=26+30) GoTypes 125MB ± 0% 125MB ± 0% -0.12% (p=0.000 n=29+30) Compiler 515MB ± 0% 515MB ± 0% -0.10% (p=0.000 n=29+30) name old allocs/op new allocs/op delta Template 426k ± 0% 424k ± 0% -0.39% (p=0.000 n=29+30) Unicode 374k ± 0% 323k ± 0% -13.67% (p=0.000 n=29+30) GoTypes 1.21M ± 0% 1.21M ± 0% -0.14% (p=0.000 n=29+29) Compiler 4.40M ± 0% 4.39M ± 0% -0.13% (p=0.000 n=29+30) Passes toolstash/buildall. Change-Id: Iba4ee765dd1748f67e52fcade1cd75c9f6e13fa9 Reviewed-on: https://go-review.googlesource.com/30974 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-10-12 15:48:18 -07:00
case OSTRUCTLIT:
for _, n1 := range n.List.Slice() {
if !isZero(n1.Left) {
cmd/compile: add OSTRUCTKEY for keyed struct literals Previously, we used OKEY nodes to represent keyed struct literal elements. The field names were represented by an ONAME node, but this is clumsy because it's the only remaining case where ONAME was used to represent a bare identifier and not a variable. This CL introduces a new OSTRUCTKEY node op for use in struct literals. These ops instead store the field name in the node's own Sym field. This is similar in spirit to golang.org/cl/20890. Significant reduction in allocations for struct literal heavy code like package unicode: name old time/op new time/op delta Template 345ms ± 6% 341ms ± 6% ~ (p=0.141 n=29+28) Unicode 200ms ± 9% 184ms ± 7% -7.77% (p=0.000 n=29+30) GoTypes 1.04s ± 3% 1.05s ± 3% ~ (p=0.096 n=30+30) Compiler 4.47s ± 9% 4.49s ± 6% ~ (p=0.890 n=29+29) name old user-ns/op new user-ns/op delta Template 523M ±13% 516M ±17% ~ (p=0.400 n=29+30) Unicode 334M ±27% 314M ±30% ~ (p=0.093 n=30+30) GoTypes 1.53G ±10% 1.52G ±10% ~ (p=0.572 n=30+30) Compiler 6.28G ± 7% 6.34G ±11% ~ (p=0.300 n=30+30) name old alloc/op new alloc/op delta Template 44.5MB ± 0% 44.4MB ± 0% -0.35% (p=0.000 n=27+30) Unicode 39.2MB ± 0% 34.5MB ± 0% -11.79% (p=0.000 n=26+30) GoTypes 125MB ± 0% 125MB ± 0% -0.12% (p=0.000 n=29+30) Compiler 515MB ± 0% 515MB ± 0% -0.10% (p=0.000 n=29+30) name old allocs/op new allocs/op delta Template 426k ± 0% 424k ± 0% -0.39% (p=0.000 n=29+30) Unicode 374k ± 0% 323k ± 0% -13.67% (p=0.000 n=29+30) GoTypes 1.21M ± 0% 1.21M ± 0% -0.14% (p=0.000 n=29+29) Compiler 4.40M ± 0% 4.39M ± 0% -0.13% (p=0.000 n=29+30) Passes toolstash/buildall. Change-Id: Iba4ee765dd1748f67e52fcade1cd75c9f6e13fa9 Reviewed-on: https://go-review.googlesource.com/30974 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-10-12 15:48:18 -07:00
return false
}
}
return true
}
return false
}
func isvaluelit(n *Node) bool {
return n.Op == OARRAYLIT || n.Op == OSTRUCTLIT
}
func genAsStatic(as *Node) {
if as.Left.Type == nil {
Fatalf("genAsStatic as.Left not typechecked")
}
var nam Node
cmd/compile: move Node.Class to flags Put it at position zero, since it is fairly hot. This shrinks gc.Node into a smaller size class on 64 bit systems. name old time/op new time/op delta Template 193ms ± 5% 192ms ± 3% ~ (p=0.353 n=94+93) Unicode 86.1ms ± 5% 85.0ms ± 4% -1.23% (p=0.000 n=95+98) GoTypes 546ms ± 3% 544ms ± 4% -0.40% (p=0.007 n=94+97) Compiler 2.56s ± 3% 2.54s ± 3% -0.67% (p=0.000 n=99+97) SSA 5.13s ± 2% 5.10s ± 3% -0.55% (p=0.000 n=94+98) Flate 122ms ± 6% 121ms ± 4% -0.75% (p=0.002 n=97+95) GoParser 144ms ± 5% 144ms ± 4% ~ (p=0.298 n=98+97) Reflect 348ms ± 4% 349ms ± 4% ~ (p=0.350 n=98+97) Tar 105ms ± 5% 104ms ± 5% ~ (p=0.154 n=96+98) XML 200ms ± 5% 198ms ± 4% -0.71% (p=0.015 n=97+98) [Geo mean] 330ms 328ms -0.52% name old user-time/op new user-time/op delta Template 229ms ±11% 224ms ± 7% -2.16% (p=0.001 n=100+87) Unicode 109ms ± 5% 109ms ± 6% ~ (p=0.897 n=96+91) GoTypes 712ms ± 4% 709ms ± 4% ~ (p=0.085 n=96+98) Compiler 3.41s ± 3% 3.36s ± 3% -1.43% (p=0.000 n=98+98) SSA 7.46s ± 3% 7.31s ± 3% -2.02% (p=0.000 n=100+99) Flate 145ms ± 6% 143ms ± 6% -1.11% (p=0.001 n=99+97) GoParser 177ms ± 5% 176ms ± 5% -0.78% (p=0.018 n=95+95) Reflect 432ms ± 7% 435ms ± 9% ~ (p=0.296 n=100+100) Tar 121ms ± 7% 121ms ± 5% ~ (p=0.072 n=100+95) XML 241ms ± 4% 239ms ± 5% ~ (p=0.085 n=97+99) [Geo mean] 413ms 410ms -0.73% name old alloc/op new alloc/op delta Template 38.4MB ± 0% 37.7MB ± 0% -1.85% (p=0.008 n=5+5) Unicode 30.1MB ± 0% 28.8MB ± 0% -4.09% (p=0.008 n=5+5) GoTypes 112MB ± 0% 110MB ± 0% -1.69% (p=0.008 n=5+5) Compiler 470MB ± 0% 461MB ± 0% -1.91% (p=0.008 n=5+5) SSA 1.13GB ± 0% 1.11GB ± 0% -1.70% (p=0.008 n=5+5) Flate 25.0MB ± 0% 24.6MB ± 0% -1.67% (p=0.008 n=5+5) GoParser 31.6MB ± 0% 31.1MB ± 0% -1.66% (p=0.008 n=5+5) Reflect 77.1MB ± 0% 75.8MB ± 0% -1.69% (p=0.008 n=5+5) Tar 26.3MB ± 0% 25.7MB ± 0% -2.06% (p=0.008 n=5+5) XML 41.9MB ± 0% 41.1MB ± 0% -1.93% (p=0.008 n=5+5) [Geo mean] 73.5MB 72.0MB -2.03% name old allocs/op new allocs/op delta Template 383k ± 0% 383k ± 0% ~ (p=0.690 n=5+5) Unicode 343k ± 0% 343k ± 0% ~ (p=0.841 n=5+5) GoTypes 1.16M ± 0% 1.16M ± 0% ~ (p=0.310 n=5+5) Compiler 4.43M ± 0% 4.42M ± 0% -0.17% (p=0.008 n=5+5) SSA 9.85M ± 0% 9.85M ± 0% ~ (p=0.310 n=5+5) Flate 236k ± 0% 236k ± 1% ~ (p=0.841 n=5+5) GoParser 320k ± 0% 320k ± 0% ~ (p=0.421 n=5+5) Reflect 988k ± 0% 987k ± 0% ~ (p=0.690 n=5+5) Tar 252k ± 0% 251k ± 0% ~ (p=0.095 n=5+5) XML 399k ± 0% 399k ± 0% ~ (p=1.000 n=5+5) [Geo mean] 741k 740k -0.07% Change-Id: I9e952b58a98e30a12494304db9ce50d0a85e459c Reviewed-on: https://go-review.googlesource.com/41797 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Marvin Stenger <marvin.stenger94@gmail.com>
2017-04-25 18:14:12 -07:00
if !stataddr(&nam, as.Left) || (nam.Class() != PEXTERN && as.Left != nblank) {
Fatalf("genAsStatic: lhs %v", as.Left)
}
switch {
case as.Right.Op == OLITERAL:
case as.Right.Op == ONAME && as.Right.Class() == PFUNC:
default:
Fatalf("genAsStatic: rhs %v", as.Right)
}
gdata(&nam, as.Right, int(as.Right.Type.Width))
}