mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile: reorder how slicelit initializes a slice
func f(x, y, z *int) {
a := []*int{x,y,z}
...
}
We used to use:
var tmp [3]*int
a := tmp[:]
a[0] = x
a[1] = y
a[2] = z
Now we do:
var tmp [3]*int
tmp[0] = x
tmp[1] = y
tmp[2] = z
a := tmp[:]
Doesn't sound like a big deal, but the compiler has trouble
eliminating write barriers when using the former method because it
doesn't know that the slice points to the stack. In the latter
method, the compiler knows the array is on the stack and as a result
doesn't emit any write barriers.
This turns out to be extremely common when building ... args, like
for calls fmt.Printf.
Makes go binaries ~1% smaller.
Doesn't have a measurable effect on the go1 fmt benchmarks,
unfortunately.
Fixes #14263
Update #6853
Change-Id: I9074a2788ec9e561a75f3b71c119b69f304d6ba2
Reviewed-on: https://go-review.googlesource.com/22395
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
This commit is contained in:
parent
c4c182140a
commit
934c359964
3 changed files with 32 additions and 18 deletions
|
|
@ -745,15 +745,15 @@ func slicelit(ctxt int, n *Node, var_ *Node, init *Nodes) {
|
|||
// var vauto *[...]t = new([...]t)
|
||||
// 4. copy the static array to the auto array
|
||||
// *vauto = vstat
|
||||
// 5. assign slice of allocated heap to var
|
||||
// var = [0:]*auto
|
||||
// 6. for each dynamic part assign to the slice
|
||||
// var[i] = dynamic part
|
||||
// 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. var = [0:]*auto
|
||||
// 6. var[i] = dynamic part
|
||||
// 5. vauto[i] = dynamic part
|
||||
// 6. var = vauto[:]
|
||||
|
||||
// if the literal contains constants,
|
||||
// make static initialized array (1),(2)
|
||||
|
|
@ -811,21 +811,14 @@ func slicelit(ctxt int, n *Node, var_ *Node, init *Nodes) {
|
|||
init.Append(a)
|
||||
}
|
||||
|
||||
// make slice out of heap (5)
|
||||
a = Nod(OAS, var_, Nod(OSLICE, vauto, Nod(OKEY, nil, nil)))
|
||||
|
||||
a = typecheck(a, Etop)
|
||||
a = orderstmtinplace(a)
|
||||
a = walkstmt(a)
|
||||
init.Append(a)
|
||||
// put dynamics into slice (6)
|
||||
// put dynamics into array (5)
|
||||
for _, r := range n.List.Slice() {
|
||||
if r.Op != OKEY {
|
||||
Fatalf("slicelit: rhs not OKEY: %v", r)
|
||||
}
|
||||
index := r.Left
|
||||
value := r.Right
|
||||
a := Nod(OINDEX, var_, index)
|
||||
a := Nod(OINDEX, vauto, index)
|
||||
a.Bounded = true
|
||||
|
||||
// TODO need to check bounds?
|
||||
|
|
@ -847,7 +840,7 @@ func slicelit(ctxt int, n *Node, var_ *Node, init *Nodes) {
|
|||
continue
|
||||
}
|
||||
|
||||
// build list of var[c] = expr
|
||||
// build list of vauto[c] = expr
|
||||
setlineno(value)
|
||||
a = Nod(OAS, a, value)
|
||||
|
||||
|
|
@ -856,6 +849,14 @@ func slicelit(ctxt int, n *Node, var_ *Node, init *Nodes) {
|
|||
a = walkstmt(a)
|
||||
init.Append(a)
|
||||
}
|
||||
|
||||
// make slice out of heap (6)
|
||||
a = Nod(OAS, var_, Nod(OSLICE, vauto, Nod(OKEY, nil, nil)))
|
||||
|
||||
a = typecheck(a, Etop)
|
||||
a = orderstmtinplace(a)
|
||||
a = walkstmt(a)
|
||||
init.Append(a)
|
||||
}
|
||||
|
||||
func maplit(ctxt int, n *Node, var_ *Node, init *Nodes) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue