2015-02-13 14:40:36 -05:00
|
|
|
// 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/internal/obj"
|
|
|
|
|
"fmt"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* portable half of code generator.
|
|
|
|
|
* mainly statements and control flow.
|
|
|
|
|
*/
|
|
|
|
|
var labellist *Label
|
|
|
|
|
|
|
|
|
|
var lastlabel *Label
|
|
|
|
|
|
|
|
|
|
func Sysfunc(name string) *Node {
|
2015-02-23 16:07:24 -05:00
|
|
|
n := newname(Pkglookup(name, Runtimepkg))
|
2015-02-13 14:40:36 -05:00
|
|
|
n.Class = PFUNC
|
|
|
|
|
return n
|
|
|
|
|
}
|
|
|
|
|
|
cmd/internal/gc: improve flow of input params to output params
This includes the following information in the per-function summary:
outK = paramJ encoded in outK bits for paramJ
outK = *paramJ encoded in outK bits for paramJ
heap = paramJ EscHeap
heap = *paramJ EscContentEscapes
Note that (currently) if the address of a parameter is taken and
returned, necessarily a heap allocation occurred to contain that
reference, and the heap can never refer to stack, therefore the
parameter and everything downstream from it escapes to the heap.
The per-function summary information now has a tuneable number of bits
(2 is probably noticeably better than 1, 3 is likely overkill, but it
is now easy to check and the -m debugging output includes information
that allows you to figure out if more would be better.)
A new test was added to check pointer flow through struct-typed and
*struct-typed parameters and returns; some of these are sensitive to
the number of summary bits, and ought to yield better results with a
more competent escape analysis algorithm. Another new test checks
(some) correctness with array parameters, results, and operations.
The old analysis inferred a piece of plan9 runtime was non-escaping by
counteracting overconservative analysis with buggy analysis; with the
bug fixed, the result was too conservative (and it's not easy to fix
in this framework) so the source code was tweaked to get the desired
result. A test was added against the discovered bug.
The escape analysis was further improved splitting the "level" into
3 parts, one tracking the conventional "level" and the other two
computing the highest-level-suffix-from-copy, which is used to
generally model the cancelling effect of indirection applied to
address-of.
With the improved escape analysis enabled, it was necessary to
modify one of the runtime tests because it now attempts to allocate
too much on the (small, fixed-size) G0 (system) stack and this
failed the test.
Compiling src/std after touching src/runtime/*.go with -m logging
turned on shows 420 fewer heap allocation sites (10538 vs 10968).
Profiling allocations in src/html/template with
for i in {1..5} ;
do go tool 6g -memprofile=mastx.${i}.prof -memprofilerate=1 *.go;
go tool pprof -alloc_objects -text mastx.${i}.prof ;
done
showed a 15% reduction in allocations performed by the compiler.
Update #3753
Update #4720
Fixes #10466
Change-Id: I0fd97d5f5ac527b45f49e2218d158a6e89951432
Reviewed-on: https://go-review.googlesource.com/8202
Run-TryBot: David Chase <drchase@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
2015-03-26 16:36:15 -04:00
|
|
|
// addrescapes tags node n as having had its address taken
|
|
|
|
|
// by "increasing" the "value" of n.Esc to EscHeap.
|
|
|
|
|
// Storage is allocated as necessary to allow the address
|
|
|
|
|
// to be taken.
|
2015-02-13 14:40:36 -05:00
|
|
|
func addrescapes(n *Node) {
|
|
|
|
|
switch n.Op {
|
|
|
|
|
// probably a type error already.
|
|
|
|
|
// dump("addrescapes", n);
|
|
|
|
|
default:
|
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
case ONAME:
|
|
|
|
|
if n == nodfp {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if this is a tmpname (PAUTO), it was tagged by tmpname as not escaping.
|
|
|
|
|
// on PPARAM it means something different.
|
|
|
|
|
if n.Class == PAUTO && n.Esc == EscNever {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch n.Class {
|
|
|
|
|
case PPARAMREF:
|
2015-05-26 22:19:27 -04:00
|
|
|
addrescapes(n.Name.Defn)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
cmd/internal/gc: improve flow of input params to output params
This includes the following information in the per-function summary:
outK = paramJ encoded in outK bits for paramJ
outK = *paramJ encoded in outK bits for paramJ
heap = paramJ EscHeap
heap = *paramJ EscContentEscapes
Note that (currently) if the address of a parameter is taken and
returned, necessarily a heap allocation occurred to contain that
reference, and the heap can never refer to stack, therefore the
parameter and everything downstream from it escapes to the heap.
The per-function summary information now has a tuneable number of bits
(2 is probably noticeably better than 1, 3 is likely overkill, but it
is now easy to check and the -m debugging output includes information
that allows you to figure out if more would be better.)
A new test was added to check pointer flow through struct-typed and
*struct-typed parameters and returns; some of these are sensitive to
the number of summary bits, and ought to yield better results with a
more competent escape analysis algorithm. Another new test checks
(some) correctness with array parameters, results, and operations.
The old analysis inferred a piece of plan9 runtime was non-escaping by
counteracting overconservative analysis with buggy analysis; with the
bug fixed, the result was too conservative (and it's not easy to fix
in this framework) so the source code was tweaked to get the desired
result. A test was added against the discovered bug.
The escape analysis was further improved splitting the "level" into
3 parts, one tracking the conventional "level" and the other two
computing the highest-level-suffix-from-copy, which is used to
generally model the cancelling effect of indirection applied to
address-of.
With the improved escape analysis enabled, it was necessary to
modify one of the runtime tests because it now attempts to allocate
too much on the (small, fixed-size) G0 (system) stack and this
failed the test.
Compiling src/std after touching src/runtime/*.go with -m logging
turned on shows 420 fewer heap allocation sites (10538 vs 10968).
Profiling allocations in src/html/template with
for i in {1..5} ;
do go tool 6g -memprofile=mastx.${i}.prof -memprofilerate=1 *.go;
go tool pprof -alloc_objects -text mastx.${i}.prof ;
done
showed a 15% reduction in allocations performed by the compiler.
Update #3753
Update #4720
Fixes #10466
Change-Id: I0fd97d5f5ac527b45f49e2218d158a6e89951432
Reviewed-on: https://go-review.googlesource.com/8202
Run-TryBot: David Chase <drchase@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
2015-03-26 16:36:15 -04:00
|
|
|
// if func param, need separate temporary
|
2015-02-13 14:40:36 -05:00
|
|
|
// to hold heap pointer.
|
|
|
|
|
// the function type has already been checked
|
|
|
|
|
// (we're in the function body)
|
|
|
|
|
// so the param already has a valid xoffset.
|
|
|
|
|
|
|
|
|
|
// expression to refer to stack copy
|
2015-04-01 09:38:44 -07:00
|
|
|
case PPARAM, PPARAMOUT:
|
2015-05-27 00:44:05 -04:00
|
|
|
n.Name.Param.Stackparam = Nod(OPARAM, n, nil)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2015-05-27 00:44:05 -04:00
|
|
|
n.Name.Param.Stackparam.Type = n.Type
|
|
|
|
|
n.Name.Param.Stackparam.Addable = true
|
2015-02-13 14:40:36 -05:00
|
|
|
if n.Xoffset == BADWIDTH {
|
|
|
|
|
Fatal("addrescapes before param assignment")
|
|
|
|
|
}
|
2015-05-27 00:44:05 -04:00
|
|
|
n.Name.Param.Stackparam.Xoffset = n.Xoffset
|
2015-02-13 14:40:36 -05:00
|
|
|
fallthrough
|
|
|
|
|
|
|
|
|
|
case PAUTO:
|
|
|
|
|
n.Class |= PHEAP
|
|
|
|
|
|
2015-04-02 19:58:37 -07:00
|
|
|
n.Addable = false
|
2015-02-13 14:40:36 -05:00
|
|
|
n.Ullman = 2
|
|
|
|
|
n.Xoffset = 0
|
|
|
|
|
|
|
|
|
|
// create stack variable to hold pointer to heap
|
2015-02-23 16:07:24 -05:00
|
|
|
oldfn := Curfn
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
Curfn = n.Curfn
|
2015-05-15 10:02:19 -07:00
|
|
|
n.Name.Heapaddr = temp(Ptrto(n.Type))
|
2015-04-17 12:03:22 -04:00
|
|
|
buf := fmt.Sprintf("&%v", n.Sym)
|
2015-05-15 10:02:19 -07:00
|
|
|
n.Name.Heapaddr.Sym = Lookup(buf)
|
|
|
|
|
n.Name.Heapaddr.Orig.Sym = n.Name.Heapaddr.Sym
|
2015-02-13 14:40:36 -05:00
|
|
|
n.Esc = EscHeap
|
|
|
|
|
if Debug['m'] != 0 {
|
2015-04-17 12:03:22 -04:00
|
|
|
fmt.Printf("%v: moved to heap: %v\n", n.Line(), n)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
Curfn = oldfn
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-01 09:38:44 -07:00
|
|
|
case OIND, ODOTPTR:
|
2015-02-13 14:40:36 -05:00
|
|
|
break
|
|
|
|
|
|
cmd/internal/gc: improve flow of input params to output params
This includes the following information in the per-function summary:
outK = paramJ encoded in outK bits for paramJ
outK = *paramJ encoded in outK bits for paramJ
heap = paramJ EscHeap
heap = *paramJ EscContentEscapes
Note that (currently) if the address of a parameter is taken and
returned, necessarily a heap allocation occurred to contain that
reference, and the heap can never refer to stack, therefore the
parameter and everything downstream from it escapes to the heap.
The per-function summary information now has a tuneable number of bits
(2 is probably noticeably better than 1, 3 is likely overkill, but it
is now easy to check and the -m debugging output includes information
that allows you to figure out if more would be better.)
A new test was added to check pointer flow through struct-typed and
*struct-typed parameters and returns; some of these are sensitive to
the number of summary bits, and ought to yield better results with a
more competent escape analysis algorithm. Another new test checks
(some) correctness with array parameters, results, and operations.
The old analysis inferred a piece of plan9 runtime was non-escaping by
counteracting overconservative analysis with buggy analysis; with the
bug fixed, the result was too conservative (and it's not easy to fix
in this framework) so the source code was tweaked to get the desired
result. A test was added against the discovered bug.
The escape analysis was further improved splitting the "level" into
3 parts, one tracking the conventional "level" and the other two
computing the highest-level-suffix-from-copy, which is used to
generally model the cancelling effect of indirection applied to
address-of.
With the improved escape analysis enabled, it was necessary to
modify one of the runtime tests because it now attempts to allocate
too much on the (small, fixed-size) G0 (system) stack and this
failed the test.
Compiling src/std after touching src/runtime/*.go with -m logging
turned on shows 420 fewer heap allocation sites (10538 vs 10968).
Profiling allocations in src/html/template with
for i in {1..5} ;
do go tool 6g -memprofile=mastx.${i}.prof -memprofilerate=1 *.go;
go tool pprof -alloc_objects -text mastx.${i}.prof ;
done
showed a 15% reduction in allocations performed by the compiler.
Update #3753
Update #4720
Fixes #10466
Change-Id: I0fd97d5f5ac527b45f49e2218d158a6e89951432
Reviewed-on: https://go-review.googlesource.com/8202
Run-TryBot: David Chase <drchase@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
2015-03-26 16:36:15 -04:00
|
|
|
// ODOTPTR has already been introduced,
|
2015-02-13 14:40:36 -05:00
|
|
|
// so these are the non-pointer ODOT and OINDEX.
|
|
|
|
|
// In &x[0], if x is a slice, then x does not
|
|
|
|
|
// escape--the pointer inside x does, but that
|
|
|
|
|
// is always a heap pointer anyway.
|
cmd/internal/gc: improve flow of input params to output params
This includes the following information in the per-function summary:
outK = paramJ encoded in outK bits for paramJ
outK = *paramJ encoded in outK bits for paramJ
heap = paramJ EscHeap
heap = *paramJ EscContentEscapes
Note that (currently) if the address of a parameter is taken and
returned, necessarily a heap allocation occurred to contain that
reference, and the heap can never refer to stack, therefore the
parameter and everything downstream from it escapes to the heap.
The per-function summary information now has a tuneable number of bits
(2 is probably noticeably better than 1, 3 is likely overkill, but it
is now easy to check and the -m debugging output includes information
that allows you to figure out if more would be better.)
A new test was added to check pointer flow through struct-typed and
*struct-typed parameters and returns; some of these are sensitive to
the number of summary bits, and ought to yield better results with a
more competent escape analysis algorithm. Another new test checks
(some) correctness with array parameters, results, and operations.
The old analysis inferred a piece of plan9 runtime was non-escaping by
counteracting overconservative analysis with buggy analysis; with the
bug fixed, the result was too conservative (and it's not easy to fix
in this framework) so the source code was tweaked to get the desired
result. A test was added against the discovered bug.
The escape analysis was further improved splitting the "level" into
3 parts, one tracking the conventional "level" and the other two
computing the highest-level-suffix-from-copy, which is used to
generally model the cancelling effect of indirection applied to
address-of.
With the improved escape analysis enabled, it was necessary to
modify one of the runtime tests because it now attempts to allocate
too much on the (small, fixed-size) G0 (system) stack and this
failed the test.
Compiling src/std after touching src/runtime/*.go with -m logging
turned on shows 420 fewer heap allocation sites (10538 vs 10968).
Profiling allocations in src/html/template with
for i in {1..5} ;
do go tool 6g -memprofile=mastx.${i}.prof -memprofilerate=1 *.go;
go tool pprof -alloc_objects -text mastx.${i}.prof ;
done
showed a 15% reduction in allocations performed by the compiler.
Update #3753
Update #4720
Fixes #10466
Change-Id: I0fd97d5f5ac527b45f49e2218d158a6e89951432
Reviewed-on: https://go-review.googlesource.com/8202
Run-TryBot: David Chase <drchase@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
2015-03-26 16:36:15 -04:00
|
|
|
case ODOT, OINDEX, OPAREN, OCONVNOP:
|
2015-02-17 22:13:49 -05:00
|
|
|
if !Isslice(n.Left.Type) {
|
2015-02-13 14:40:36 -05:00
|
|
|
addrescapes(n.Left)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func clearlabels() {
|
2015-02-23 16:07:24 -05:00
|
|
|
for l := labellist; l != nil; l = l.Link {
|
2015-02-13 14:40:36 -05:00
|
|
|
l.Sym.Label = nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
labellist = nil
|
|
|
|
|
lastlabel = nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func newlab(n *Node) *Label {
|
2015-02-23 16:07:24 -05:00
|
|
|
s := n.Left.Sym
|
|
|
|
|
lab := s.Label
|
2015-02-13 14:40:36 -05:00
|
|
|
if lab == nil {
|
|
|
|
|
lab = new(Label)
|
|
|
|
|
if lastlabel == nil {
|
|
|
|
|
labellist = lab
|
|
|
|
|
} else {
|
|
|
|
|
lastlabel.Link = lab
|
|
|
|
|
}
|
|
|
|
|
lastlabel = lab
|
|
|
|
|
lab.Sym = s
|
|
|
|
|
s.Label = lab
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if n.Op == OLABEL {
|
|
|
|
|
if lab.Def != nil {
|
2015-04-17 12:03:22 -04:00
|
|
|
Yyerror("label %v already defined at %v", s, lab.Def.Line())
|
2015-02-13 14:40:36 -05:00
|
|
|
} else {
|
|
|
|
|
lab.Def = n
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
lab.Use = list(lab.Use, n)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return lab
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func checkgoto(from *Node, to *Node) {
|
|
|
|
|
if from.Sym == to.Sym {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-23 16:07:24 -05:00
|
|
|
nf := 0
|
|
|
|
|
for fs := from.Sym; fs != nil; fs = fs.Link {
|
2015-02-13 14:40:36 -05:00
|
|
|
nf++
|
|
|
|
|
}
|
2015-02-23 16:07:24 -05:00
|
|
|
nt := 0
|
|
|
|
|
for fs := to.Sym; fs != nil; fs = fs.Link {
|
2015-02-13 14:40:36 -05:00
|
|
|
nt++
|
|
|
|
|
}
|
2015-02-23 16:07:24 -05:00
|
|
|
fs := from.Sym
|
2015-02-13 14:40:36 -05:00
|
|
|
for ; nf > nt; nf-- {
|
|
|
|
|
fs = fs.Link
|
|
|
|
|
}
|
|
|
|
|
if fs != to.Sym {
|
2015-02-23 16:07:24 -05:00
|
|
|
lno := int(lineno)
|
2015-02-13 14:40:36 -05:00
|
|
|
setlineno(from)
|
|
|
|
|
|
|
|
|
|
// decide what to complain about.
|
|
|
|
|
// prefer to complain about 'into block' over declarations,
|
|
|
|
|
// so scan backward to find most recent block or else dcl.
|
2015-03-02 14:22:05 -05:00
|
|
|
var block *Sym
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2015-03-02 14:22:05 -05:00
|
|
|
var dcl *Sym
|
2015-05-15 16:35:43 +00:00
|
|
|
ts := to.Sym
|
2015-02-13 14:40:36 -05:00
|
|
|
for ; nt > nf; nt-- {
|
|
|
|
|
if ts.Pkg == nil {
|
|
|
|
|
block = ts
|
2015-05-15 16:35:43 +00:00
|
|
|
} else {
|
2015-02-13 14:40:36 -05:00
|
|
|
dcl = ts
|
|
|
|
|
}
|
|
|
|
|
ts = ts.Link
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for ts != fs {
|
|
|
|
|
if ts.Pkg == nil {
|
|
|
|
|
block = ts
|
2015-05-15 16:35:43 +00:00
|
|
|
} else {
|
2015-02-13 14:40:36 -05:00
|
|
|
dcl = ts
|
|
|
|
|
}
|
|
|
|
|
ts = ts.Link
|
|
|
|
|
fs = fs.Link
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if block != nil {
|
2015-04-17 12:03:22 -04:00
|
|
|
Yyerror("goto %v jumps into block starting at %v", from.Left.Sym, Ctxt.Line(int(block.Lastlineno)))
|
2015-02-13 14:40:36 -05:00
|
|
|
} else {
|
2015-04-17 12:03:22 -04:00
|
|
|
Yyerror("goto %v jumps over declaration of %v at %v", from.Left.Sym, dcl, Ctxt.Line(int(dcl.Lastlineno)))
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
lineno = int32(lno)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func stmtlabel(n *Node) *Label {
|
|
|
|
|
if n.Sym != nil {
|
2015-02-23 16:07:24 -05:00
|
|
|
lab := n.Sym.Label
|
2015-02-13 14:40:36 -05:00
|
|
|
if lab != nil {
|
|
|
|
|
if lab.Def != nil {
|
2015-05-26 22:19:27 -04:00
|
|
|
if lab.Def.Name.Defn == n {
|
2015-02-13 14:40:36 -05:00
|
|
|
return lab
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* compile statements
|
|
|
|
|
*/
|
|
|
|
|
func Genlist(l *NodeList) {
|
|
|
|
|
for ; l != nil; l = l.Next {
|
|
|
|
|
gen(l.N)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* generate code to start new proc running call n.
|
|
|
|
|
*/
|
|
|
|
|
func cgen_proc(n *Node, proc int) {
|
|
|
|
|
switch n.Left.Op {
|
|
|
|
|
default:
|
|
|
|
|
Fatal("cgen_proc: unknown call %v", Oconv(int(n.Left.Op), 0))
|
|
|
|
|
|
|
|
|
|
case OCALLMETH:
|
2015-03-18 17:26:36 -04:00
|
|
|
cgen_callmeth(n.Left, proc)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
case OCALLINTER:
|
2015-03-18 17:26:36 -04:00
|
|
|
cgen_callinter(n.Left, nil, proc)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
case OCALLFUNC:
|
2015-03-18 17:26:36 -04:00
|
|
|
cgen_call(n.Left, proc)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* generate declaration.
|
|
|
|
|
* have to allocate heap copy
|
|
|
|
|
* for escaped variables.
|
|
|
|
|
*/
|
|
|
|
|
func cgen_dcl(n *Node) {
|
|
|
|
|
if Debug['g'] != 0 {
|
|
|
|
|
Dump("\ncgen-dcl", n)
|
|
|
|
|
}
|
|
|
|
|
if n.Op != ONAME {
|
|
|
|
|
Dump("cgen_dcl", n)
|
|
|
|
|
Fatal("cgen_dcl")
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-17 22:13:49 -05:00
|
|
|
if n.Class&PHEAP == 0 {
|
2015-02-13 14:40:36 -05:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if compiling_runtime != 0 {
|
2015-04-17 12:03:22 -04:00
|
|
|
Yyerror("%v escapes to heap, not allowed in runtime.", n)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2015-05-26 23:05:35 -04:00
|
|
|
if prealloc[n] == nil {
|
|
|
|
|
prealloc[n] = callnew(n.Type)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2015-05-26 23:05:35 -04:00
|
|
|
Cgen_as(n.Name.Heapaddr, prealloc[n])
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* generate discard of value
|
|
|
|
|
*/
|
|
|
|
|
func cgen_discard(nr *Node) {
|
|
|
|
|
if nr == nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch nr.Op {
|
|
|
|
|
case ONAME:
|
2015-02-17 22:13:49 -05:00
|
|
|
if nr.Class&PHEAP == 0 && nr.Class != PEXTERN && nr.Class != PFUNC && nr.Class != PPARAMREF {
|
2015-02-13 14:40:36 -05:00
|
|
|
gused(nr)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// unary
|
|
|
|
|
case OADD,
|
|
|
|
|
OAND,
|
|
|
|
|
ODIV,
|
|
|
|
|
OEQ,
|
|
|
|
|
OGE,
|
|
|
|
|
OGT,
|
|
|
|
|
OLE,
|
|
|
|
|
OLSH,
|
|
|
|
|
OLT,
|
|
|
|
|
OMOD,
|
|
|
|
|
OMUL,
|
|
|
|
|
ONE,
|
|
|
|
|
OOR,
|
|
|
|
|
ORSH,
|
|
|
|
|
OSUB,
|
|
|
|
|
OXOR:
|
|
|
|
|
cgen_discard(nr.Left)
|
|
|
|
|
|
|
|
|
|
cgen_discard(nr.Right)
|
|
|
|
|
|
|
|
|
|
// binary
|
|
|
|
|
case OCAP,
|
|
|
|
|
OCOM,
|
|
|
|
|
OLEN,
|
|
|
|
|
OMINUS,
|
|
|
|
|
ONOT,
|
|
|
|
|
OPLUS:
|
|
|
|
|
cgen_discard(nr.Left)
|
|
|
|
|
|
|
|
|
|
case OIND:
|
|
|
|
|
Cgen_checknil(nr.Left)
|
|
|
|
|
|
|
|
|
|
// special enough to just evaluate
|
|
|
|
|
default:
|
2015-02-23 16:07:24 -05:00
|
|
|
var tmp Node
|
2015-02-13 14:40:36 -05:00
|
|
|
Tempname(&tmp, nr.Type)
|
|
|
|
|
|
|
|
|
|
Cgen_as(&tmp, nr)
|
|
|
|
|
gused(&tmp)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* clearslim generates code to zero a slim node.
|
|
|
|
|
*/
|
|
|
|
|
func Clearslim(n *Node) {
|
2015-03-02 14:22:05 -05:00
|
|
|
var z Node
|
2015-02-13 14:40:36 -05:00
|
|
|
z.Op = OLITERAL
|
|
|
|
|
z.Type = n.Type
|
2015-04-02 19:58:37 -07:00
|
|
|
z.Addable = true
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
switch Simtype[n.Type.Etype] {
|
2015-04-01 09:38:44 -07:00
|
|
|
case TCOMPLEX64, TCOMPLEX128:
|
2015-05-14 17:57:42 -07:00
|
|
|
z.Val.U = new(Mpcplx)
|
|
|
|
|
Mpmovecflt(&z.Val.U.(*Mpcplx).Real, 0.0)
|
|
|
|
|
Mpmovecflt(&z.Val.U.(*Mpcplx).Imag, 0.0)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2015-04-01 09:38:44 -07:00
|
|
|
case TFLOAT32, TFLOAT64:
|
2015-02-23 16:07:24 -05:00
|
|
|
var zero Mpflt
|
2015-02-13 14:40:36 -05:00
|
|
|
Mpmovecflt(&zero, 0.0)
|
2015-05-14 17:57:42 -07:00
|
|
|
z.Val.U = &zero
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2015-04-01 09:38:44 -07:00
|
|
|
case TPTR32, TPTR64, TCHAN, TMAP:
|
2015-05-26 22:50:45 -04:00
|
|
|
z.Val.U = new(NilVal)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
case TBOOL:
|
2015-05-14 17:57:42 -07:00
|
|
|
z.Val.U = false
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
case TINT8,
|
|
|
|
|
TINT16,
|
|
|
|
|
TINT32,
|
|
|
|
|
TINT64,
|
|
|
|
|
TUINT8,
|
|
|
|
|
TUINT16,
|
|
|
|
|
TUINT32,
|
|
|
|
|
TUINT64:
|
2015-05-14 17:57:42 -07:00
|
|
|
z.Val.U = new(Mpint)
|
|
|
|
|
Mpmovecfix(z.Val.U.(*Mpint), 0)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
default:
|
2015-04-17 12:03:22 -04:00
|
|
|
Fatal("clearslim called on type %v", n.Type)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ullmancalc(&z)
|
2015-03-18 17:26:36 -04:00
|
|
|
Cgen(&z, n)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* generate:
|
|
|
|
|
* res = iface{typ, data}
|
|
|
|
|
* n->left is typ
|
|
|
|
|
* n->right is data
|
|
|
|
|
*/
|
|
|
|
|
func Cgen_eface(n *Node, res *Node) {
|
|
|
|
|
/*
|
|
|
|
|
* the right node of an eface may contain function calls that uses res as an argument,
|
|
|
|
|
* so it's important that it is done first
|
|
|
|
|
*/
|
|
|
|
|
|
2015-02-23 16:07:24 -05:00
|
|
|
tmp := temp(Types[Tptr])
|
2015-03-18 17:26:36 -04:00
|
|
|
Cgen(n.Right, tmp)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
Gvardef(res)
|
|
|
|
|
|
2015-02-23 16:07:24 -05:00
|
|
|
dst := *res
|
2015-02-13 14:40:36 -05:00
|
|
|
dst.Type = Types[Tptr]
|
|
|
|
|
dst.Xoffset += int64(Widthptr)
|
2015-03-18 17:26:36 -04:00
|
|
|
Cgen(tmp, &dst)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
dst.Xoffset -= int64(Widthptr)
|
2015-03-18 17:26:36 -04:00
|
|
|
Cgen(n.Left, &dst)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2015-03-20 00:06:10 -04:00
|
|
|
/*
|
|
|
|
|
* generate one of:
|
|
|
|
|
* res, resok = x.(T)
|
|
|
|
|
* res = x.(T) (when resok == nil)
|
|
|
|
|
* n.Left is x
|
|
|
|
|
* n.Type is T
|
|
|
|
|
*/
|
cmd/internal/gc: emit write barriers at lower level
This is primarily preparation for inlining, not an optimization by itself,
but it still helps some.
name old new delta
BenchmarkBinaryTree17 18.2s × (0.99,1.01) 17.9s × (0.99,1.01) -1.57%
BenchmarkFannkuch11 4.44s × (1.00,1.00) 4.42s × (1.00,1.00) -0.40%
BenchmarkFmtFprintfEmpty 119ns × (0.95,1.02) 118ns × (0.96,1.02) ~
BenchmarkFmtFprintfString 501ns × (0.99,1.02) 486ns × (0.99,1.01) -2.89%
BenchmarkFmtFprintfInt 474ns × (0.99,1.00) 457ns × (0.99,1.01) -3.59%
BenchmarkFmtFprintfIntInt 792ns × (1.00,1.00) 768ns × (1.00,1.01) -3.03%
BenchmarkFmtFprintfPrefixedInt 574ns × (1.00,1.01) 584ns × (0.99,1.03) +1.83%
BenchmarkFmtFprintfFloat 749ns × (1.00,1.00) 739ns × (0.99,1.00) -1.34%
BenchmarkFmtManyArgs 2.94µs × (1.00,1.01) 2.77µs × (1.00,1.00) -5.76%
BenchmarkGobDecode 39.5ms × (0.99,1.01) 39.3ms × (0.99,1.01) ~
BenchmarkGobEncode 39.4ms × (1.00,1.01) 39.4ms × (0.99,1.00) ~
BenchmarkGzip 658ms × (1.00,1.01) 661ms × (0.99,1.01) ~
BenchmarkGunzip 142ms × (1.00,1.00) 142ms × (1.00,1.00) +0.22%
BenchmarkHTTPClientServer 134µs × (0.99,1.01) 133µs × (0.98,1.01) ~
BenchmarkJSONEncode 57.1ms × (0.99,1.01) 56.5ms × (0.99,1.01) ~
BenchmarkJSONDecode 141ms × (1.00,1.00) 143ms × (1.00,1.00) +1.09%
BenchmarkMandelbrot200 6.01ms × (1.00,1.00) 6.01ms × (1.00,1.00) ~
BenchmarkGoParse 10.1ms × (0.91,1.09) 9.6ms × (0.94,1.07) ~
BenchmarkRegexpMatchEasy0_32 207ns × (1.00,1.01) 210ns × (1.00,1.00) +1.45%
BenchmarkRegexpMatchEasy0_1K 592ns × (0.99,1.00) 596ns × (0.99,1.01) +0.68%
BenchmarkRegexpMatchEasy1_32 184ns × (0.99,1.01) 184ns × (0.99,1.01) ~
BenchmarkRegexpMatchEasy1_1K 1.01µs × (1.00,1.00) 1.01µs × (0.99,1.01) ~
BenchmarkRegexpMatchMedium_32 327ns × (0.99,1.00) 327ns × (1.00,1.01) ~
BenchmarkRegexpMatchMedium_1K 92.5µs × (1.00,1.00) 93.0µs × (1.00,1.02) +0.48%
BenchmarkRegexpMatchHard_32 4.79µs × (0.95,1.00) 4.76µs × (0.95,1.01) ~
BenchmarkRegexpMatchHard_1K 136µs × (1.00,1.00) 136µs × (1.00,1.01) ~
BenchmarkRevcomp 900ms × (0.99,1.01) 892ms × (1.00,1.01) ~
BenchmarkTemplate 170ms × (0.99,1.01) 175ms × (0.99,1.00) +2.95%
BenchmarkTimeParse 645ns × (1.00,1.00) 638ns × (1.00,1.00) -1.16%
BenchmarkTimeFormat 740ns × (1.00,1.00) 772ns × (1.00,1.00) +4.39%
Change-Id: I0be905e32791e0cb70ff01f169c4b309a971d981
Reviewed-on: https://go-review.googlesource.com/9159
Reviewed-by: Rick Hudson <rlh@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-04-17 00:25:10 -04:00
|
|
|
func cgen_dottype(n *Node, res, resok *Node, wb bool) {
|
2015-03-20 00:06:10 -04:00
|
|
|
if Debug_typeassert > 0 {
|
|
|
|
|
Warn("type assertion inlined")
|
|
|
|
|
}
|
|
|
|
|
// iface := n.Left
|
|
|
|
|
// r1 := iword(iface)
|
|
|
|
|
// if n.Left is non-empty interface {
|
|
|
|
|
// r1 = *r1
|
|
|
|
|
// }
|
|
|
|
|
// if r1 == T {
|
|
|
|
|
// res = idata(iface)
|
|
|
|
|
// resok = true
|
|
|
|
|
// } else {
|
|
|
|
|
// assert[EI]2T(x, T, nil) // (when resok == nil; does not return)
|
|
|
|
|
// resok = false // (when resok != nil)
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
var iface Node
|
|
|
|
|
Igen(n.Left, &iface, res)
|
|
|
|
|
var r1, r2 Node
|
|
|
|
|
byteptr := Ptrto(Types[TUINT8]) // type used in runtime prototypes for runtime type (*byte)
|
|
|
|
|
Regalloc(&r1, byteptr, nil)
|
|
|
|
|
iface.Type = byteptr
|
|
|
|
|
Cgen(&iface, &r1)
|
|
|
|
|
if !isnilinter(n.Left.Type) {
|
|
|
|
|
// Holding itab, want concrete type in second word.
|
2015-05-06 12:28:19 -04:00
|
|
|
p := Thearch.Ginscmp(OEQ, byteptr, &r1, Nodintconst(0), -1)
|
2015-03-20 00:06:10 -04:00
|
|
|
r2 = r1
|
|
|
|
|
r2.Op = OINDREG
|
|
|
|
|
r2.Xoffset = int64(Widthptr)
|
|
|
|
|
Cgen(&r2, &r1)
|
|
|
|
|
Patch(p, Pc)
|
|
|
|
|
}
|
|
|
|
|
Regalloc(&r2, byteptr, nil)
|
|
|
|
|
Cgen(typename(n.Type), &r2)
|
2015-05-06 12:28:19 -04:00
|
|
|
p := Thearch.Ginscmp(ONE, byteptr, &r1, &r2, -1)
|
cmd/internal/gc: emit write barriers at lower level
This is primarily preparation for inlining, not an optimization by itself,
but it still helps some.
name old new delta
BenchmarkBinaryTree17 18.2s × (0.99,1.01) 17.9s × (0.99,1.01) -1.57%
BenchmarkFannkuch11 4.44s × (1.00,1.00) 4.42s × (1.00,1.00) -0.40%
BenchmarkFmtFprintfEmpty 119ns × (0.95,1.02) 118ns × (0.96,1.02) ~
BenchmarkFmtFprintfString 501ns × (0.99,1.02) 486ns × (0.99,1.01) -2.89%
BenchmarkFmtFprintfInt 474ns × (0.99,1.00) 457ns × (0.99,1.01) -3.59%
BenchmarkFmtFprintfIntInt 792ns × (1.00,1.00) 768ns × (1.00,1.01) -3.03%
BenchmarkFmtFprintfPrefixedInt 574ns × (1.00,1.01) 584ns × (0.99,1.03) +1.83%
BenchmarkFmtFprintfFloat 749ns × (1.00,1.00) 739ns × (0.99,1.00) -1.34%
BenchmarkFmtManyArgs 2.94µs × (1.00,1.01) 2.77µs × (1.00,1.00) -5.76%
BenchmarkGobDecode 39.5ms × (0.99,1.01) 39.3ms × (0.99,1.01) ~
BenchmarkGobEncode 39.4ms × (1.00,1.01) 39.4ms × (0.99,1.00) ~
BenchmarkGzip 658ms × (1.00,1.01) 661ms × (0.99,1.01) ~
BenchmarkGunzip 142ms × (1.00,1.00) 142ms × (1.00,1.00) +0.22%
BenchmarkHTTPClientServer 134µs × (0.99,1.01) 133µs × (0.98,1.01) ~
BenchmarkJSONEncode 57.1ms × (0.99,1.01) 56.5ms × (0.99,1.01) ~
BenchmarkJSONDecode 141ms × (1.00,1.00) 143ms × (1.00,1.00) +1.09%
BenchmarkMandelbrot200 6.01ms × (1.00,1.00) 6.01ms × (1.00,1.00) ~
BenchmarkGoParse 10.1ms × (0.91,1.09) 9.6ms × (0.94,1.07) ~
BenchmarkRegexpMatchEasy0_32 207ns × (1.00,1.01) 210ns × (1.00,1.00) +1.45%
BenchmarkRegexpMatchEasy0_1K 592ns × (0.99,1.00) 596ns × (0.99,1.01) +0.68%
BenchmarkRegexpMatchEasy1_32 184ns × (0.99,1.01) 184ns × (0.99,1.01) ~
BenchmarkRegexpMatchEasy1_1K 1.01µs × (1.00,1.00) 1.01µs × (0.99,1.01) ~
BenchmarkRegexpMatchMedium_32 327ns × (0.99,1.00) 327ns × (1.00,1.01) ~
BenchmarkRegexpMatchMedium_1K 92.5µs × (1.00,1.00) 93.0µs × (1.00,1.02) +0.48%
BenchmarkRegexpMatchHard_32 4.79µs × (0.95,1.00) 4.76µs × (0.95,1.01) ~
BenchmarkRegexpMatchHard_1K 136µs × (1.00,1.00) 136µs × (1.00,1.01) ~
BenchmarkRevcomp 900ms × (0.99,1.01) 892ms × (1.00,1.01) ~
BenchmarkTemplate 170ms × (0.99,1.01) 175ms × (0.99,1.00) +2.95%
BenchmarkTimeParse 645ns × (1.00,1.00) 638ns × (1.00,1.00) -1.16%
BenchmarkTimeFormat 740ns × (1.00,1.00) 772ns × (1.00,1.00) +4.39%
Change-Id: I0be905e32791e0cb70ff01f169c4b309a971d981
Reviewed-on: https://go-review.googlesource.com/9159
Reviewed-by: Rick Hudson <rlh@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-04-17 00:25:10 -04:00
|
|
|
Regfree(&r2) // not needed for success path; reclaimed on one failure path
|
2015-03-20 00:06:10 -04:00
|
|
|
iface.Xoffset += int64(Widthptr)
|
|
|
|
|
Cgen(&iface, &r1)
|
|
|
|
|
Regfree(&iface)
|
|
|
|
|
|
|
|
|
|
if resok == nil {
|
|
|
|
|
r1.Type = res.Type
|
cmd/internal/gc: emit write barriers at lower level
This is primarily preparation for inlining, not an optimization by itself,
but it still helps some.
name old new delta
BenchmarkBinaryTree17 18.2s × (0.99,1.01) 17.9s × (0.99,1.01) -1.57%
BenchmarkFannkuch11 4.44s × (1.00,1.00) 4.42s × (1.00,1.00) -0.40%
BenchmarkFmtFprintfEmpty 119ns × (0.95,1.02) 118ns × (0.96,1.02) ~
BenchmarkFmtFprintfString 501ns × (0.99,1.02) 486ns × (0.99,1.01) -2.89%
BenchmarkFmtFprintfInt 474ns × (0.99,1.00) 457ns × (0.99,1.01) -3.59%
BenchmarkFmtFprintfIntInt 792ns × (1.00,1.00) 768ns × (1.00,1.01) -3.03%
BenchmarkFmtFprintfPrefixedInt 574ns × (1.00,1.01) 584ns × (0.99,1.03) +1.83%
BenchmarkFmtFprintfFloat 749ns × (1.00,1.00) 739ns × (0.99,1.00) -1.34%
BenchmarkFmtManyArgs 2.94µs × (1.00,1.01) 2.77µs × (1.00,1.00) -5.76%
BenchmarkGobDecode 39.5ms × (0.99,1.01) 39.3ms × (0.99,1.01) ~
BenchmarkGobEncode 39.4ms × (1.00,1.01) 39.4ms × (0.99,1.00) ~
BenchmarkGzip 658ms × (1.00,1.01) 661ms × (0.99,1.01) ~
BenchmarkGunzip 142ms × (1.00,1.00) 142ms × (1.00,1.00) +0.22%
BenchmarkHTTPClientServer 134µs × (0.99,1.01) 133µs × (0.98,1.01) ~
BenchmarkJSONEncode 57.1ms × (0.99,1.01) 56.5ms × (0.99,1.01) ~
BenchmarkJSONDecode 141ms × (1.00,1.00) 143ms × (1.00,1.00) +1.09%
BenchmarkMandelbrot200 6.01ms × (1.00,1.00) 6.01ms × (1.00,1.00) ~
BenchmarkGoParse 10.1ms × (0.91,1.09) 9.6ms × (0.94,1.07) ~
BenchmarkRegexpMatchEasy0_32 207ns × (1.00,1.01) 210ns × (1.00,1.00) +1.45%
BenchmarkRegexpMatchEasy0_1K 592ns × (0.99,1.00) 596ns × (0.99,1.01) +0.68%
BenchmarkRegexpMatchEasy1_32 184ns × (0.99,1.01) 184ns × (0.99,1.01) ~
BenchmarkRegexpMatchEasy1_1K 1.01µs × (1.00,1.00) 1.01µs × (0.99,1.01) ~
BenchmarkRegexpMatchMedium_32 327ns × (0.99,1.00) 327ns × (1.00,1.01) ~
BenchmarkRegexpMatchMedium_1K 92.5µs × (1.00,1.00) 93.0µs × (1.00,1.02) +0.48%
BenchmarkRegexpMatchHard_32 4.79µs × (0.95,1.00) 4.76µs × (0.95,1.01) ~
BenchmarkRegexpMatchHard_1K 136µs × (1.00,1.00) 136µs × (1.00,1.01) ~
BenchmarkRevcomp 900ms × (0.99,1.01) 892ms × (1.00,1.01) ~
BenchmarkTemplate 170ms × (0.99,1.01) 175ms × (0.99,1.00) +2.95%
BenchmarkTimeParse 645ns × (1.00,1.00) 638ns × (1.00,1.00) -1.16%
BenchmarkTimeFormat 740ns × (1.00,1.00) 772ns × (1.00,1.00) +4.39%
Change-Id: I0be905e32791e0cb70ff01f169c4b309a971d981
Reviewed-on: https://go-review.googlesource.com/9159
Reviewed-by: Rick Hudson <rlh@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-04-17 00:25:10 -04:00
|
|
|
cgen_wb(&r1, res, wb)
|
2015-03-20 00:06:10 -04:00
|
|
|
q := Gbranch(obj.AJMP, nil, 0)
|
|
|
|
|
Patch(p, Pc)
|
cmd/internal/gc: emit write barriers at lower level
This is primarily preparation for inlining, not an optimization by itself,
but it still helps some.
name old new delta
BenchmarkBinaryTree17 18.2s × (0.99,1.01) 17.9s × (0.99,1.01) -1.57%
BenchmarkFannkuch11 4.44s × (1.00,1.00) 4.42s × (1.00,1.00) -0.40%
BenchmarkFmtFprintfEmpty 119ns × (0.95,1.02) 118ns × (0.96,1.02) ~
BenchmarkFmtFprintfString 501ns × (0.99,1.02) 486ns × (0.99,1.01) -2.89%
BenchmarkFmtFprintfInt 474ns × (0.99,1.00) 457ns × (0.99,1.01) -3.59%
BenchmarkFmtFprintfIntInt 792ns × (1.00,1.00) 768ns × (1.00,1.01) -3.03%
BenchmarkFmtFprintfPrefixedInt 574ns × (1.00,1.01) 584ns × (0.99,1.03) +1.83%
BenchmarkFmtFprintfFloat 749ns × (1.00,1.00) 739ns × (0.99,1.00) -1.34%
BenchmarkFmtManyArgs 2.94µs × (1.00,1.01) 2.77µs × (1.00,1.00) -5.76%
BenchmarkGobDecode 39.5ms × (0.99,1.01) 39.3ms × (0.99,1.01) ~
BenchmarkGobEncode 39.4ms × (1.00,1.01) 39.4ms × (0.99,1.00) ~
BenchmarkGzip 658ms × (1.00,1.01) 661ms × (0.99,1.01) ~
BenchmarkGunzip 142ms × (1.00,1.00) 142ms × (1.00,1.00) +0.22%
BenchmarkHTTPClientServer 134µs × (0.99,1.01) 133µs × (0.98,1.01) ~
BenchmarkJSONEncode 57.1ms × (0.99,1.01) 56.5ms × (0.99,1.01) ~
BenchmarkJSONDecode 141ms × (1.00,1.00) 143ms × (1.00,1.00) +1.09%
BenchmarkMandelbrot200 6.01ms × (1.00,1.00) 6.01ms × (1.00,1.00) ~
BenchmarkGoParse 10.1ms × (0.91,1.09) 9.6ms × (0.94,1.07) ~
BenchmarkRegexpMatchEasy0_32 207ns × (1.00,1.01) 210ns × (1.00,1.00) +1.45%
BenchmarkRegexpMatchEasy0_1K 592ns × (0.99,1.00) 596ns × (0.99,1.01) +0.68%
BenchmarkRegexpMatchEasy1_32 184ns × (0.99,1.01) 184ns × (0.99,1.01) ~
BenchmarkRegexpMatchEasy1_1K 1.01µs × (1.00,1.00) 1.01µs × (0.99,1.01) ~
BenchmarkRegexpMatchMedium_32 327ns × (0.99,1.00) 327ns × (1.00,1.01) ~
BenchmarkRegexpMatchMedium_1K 92.5µs × (1.00,1.00) 93.0µs × (1.00,1.02) +0.48%
BenchmarkRegexpMatchHard_32 4.79µs × (0.95,1.00) 4.76µs × (0.95,1.01) ~
BenchmarkRegexpMatchHard_1K 136µs × (1.00,1.00) 136µs × (1.00,1.01) ~
BenchmarkRevcomp 900ms × (0.99,1.01) 892ms × (1.00,1.01) ~
BenchmarkTemplate 170ms × (0.99,1.01) 175ms × (0.99,1.00) +2.95%
BenchmarkTimeParse 645ns × (1.00,1.00) 638ns × (1.00,1.00) -1.16%
BenchmarkTimeFormat 740ns × (1.00,1.00) 772ns × (1.00,1.00) +4.39%
Change-Id: I0be905e32791e0cb70ff01f169c4b309a971d981
Reviewed-on: https://go-review.googlesource.com/9159
Reviewed-by: Rick Hudson <rlh@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-04-17 00:25:10 -04:00
|
|
|
Regrealloc(&r2) // reclaim from above, for this failure path
|
2015-03-20 00:06:10 -04:00
|
|
|
fn := syslook("panicdottype", 0)
|
|
|
|
|
dowidth(fn.Type)
|
|
|
|
|
call := Nod(OCALLFUNC, fn, nil)
|
|
|
|
|
r1.Type = byteptr
|
|
|
|
|
r2.Type = byteptr
|
|
|
|
|
call.List = list(list(list1(&r1), &r2), typename(n.Left.Type))
|
|
|
|
|
call.List = ascompatte(OCALLFUNC, call, false, getinarg(fn.Type), call.List, 0, nil)
|
|
|
|
|
gen(call)
|
|
|
|
|
Regfree(&r1)
|
|
|
|
|
Regfree(&r2)
|
|
|
|
|
Thearch.Gins(obj.AUNDEF, nil, nil)
|
|
|
|
|
Patch(q, Pc)
|
|
|
|
|
} else {
|
|
|
|
|
// This half is handling the res, resok = x.(T) case,
|
|
|
|
|
// which is called from gen, not cgen, and is consequently fussier
|
|
|
|
|
// about blank assignments. We have to avoid calling cgen for those.
|
|
|
|
|
r1.Type = res.Type
|
|
|
|
|
if !isblank(res) {
|
cmd/internal/gc: emit write barriers at lower level
This is primarily preparation for inlining, not an optimization by itself,
but it still helps some.
name old new delta
BenchmarkBinaryTree17 18.2s × (0.99,1.01) 17.9s × (0.99,1.01) -1.57%
BenchmarkFannkuch11 4.44s × (1.00,1.00) 4.42s × (1.00,1.00) -0.40%
BenchmarkFmtFprintfEmpty 119ns × (0.95,1.02) 118ns × (0.96,1.02) ~
BenchmarkFmtFprintfString 501ns × (0.99,1.02) 486ns × (0.99,1.01) -2.89%
BenchmarkFmtFprintfInt 474ns × (0.99,1.00) 457ns × (0.99,1.01) -3.59%
BenchmarkFmtFprintfIntInt 792ns × (1.00,1.00) 768ns × (1.00,1.01) -3.03%
BenchmarkFmtFprintfPrefixedInt 574ns × (1.00,1.01) 584ns × (0.99,1.03) +1.83%
BenchmarkFmtFprintfFloat 749ns × (1.00,1.00) 739ns × (0.99,1.00) -1.34%
BenchmarkFmtManyArgs 2.94µs × (1.00,1.01) 2.77µs × (1.00,1.00) -5.76%
BenchmarkGobDecode 39.5ms × (0.99,1.01) 39.3ms × (0.99,1.01) ~
BenchmarkGobEncode 39.4ms × (1.00,1.01) 39.4ms × (0.99,1.00) ~
BenchmarkGzip 658ms × (1.00,1.01) 661ms × (0.99,1.01) ~
BenchmarkGunzip 142ms × (1.00,1.00) 142ms × (1.00,1.00) +0.22%
BenchmarkHTTPClientServer 134µs × (0.99,1.01) 133µs × (0.98,1.01) ~
BenchmarkJSONEncode 57.1ms × (0.99,1.01) 56.5ms × (0.99,1.01) ~
BenchmarkJSONDecode 141ms × (1.00,1.00) 143ms × (1.00,1.00) +1.09%
BenchmarkMandelbrot200 6.01ms × (1.00,1.00) 6.01ms × (1.00,1.00) ~
BenchmarkGoParse 10.1ms × (0.91,1.09) 9.6ms × (0.94,1.07) ~
BenchmarkRegexpMatchEasy0_32 207ns × (1.00,1.01) 210ns × (1.00,1.00) +1.45%
BenchmarkRegexpMatchEasy0_1K 592ns × (0.99,1.00) 596ns × (0.99,1.01) +0.68%
BenchmarkRegexpMatchEasy1_32 184ns × (0.99,1.01) 184ns × (0.99,1.01) ~
BenchmarkRegexpMatchEasy1_1K 1.01µs × (1.00,1.00) 1.01µs × (0.99,1.01) ~
BenchmarkRegexpMatchMedium_32 327ns × (0.99,1.00) 327ns × (1.00,1.01) ~
BenchmarkRegexpMatchMedium_1K 92.5µs × (1.00,1.00) 93.0µs × (1.00,1.02) +0.48%
BenchmarkRegexpMatchHard_32 4.79µs × (0.95,1.00) 4.76µs × (0.95,1.01) ~
BenchmarkRegexpMatchHard_1K 136µs × (1.00,1.00) 136µs × (1.00,1.01) ~
BenchmarkRevcomp 900ms × (0.99,1.01) 892ms × (1.00,1.01) ~
BenchmarkTemplate 170ms × (0.99,1.01) 175ms × (0.99,1.00) +2.95%
BenchmarkTimeParse 645ns × (1.00,1.00) 638ns × (1.00,1.00) -1.16%
BenchmarkTimeFormat 740ns × (1.00,1.00) 772ns × (1.00,1.00) +4.39%
Change-Id: I0be905e32791e0cb70ff01f169c4b309a971d981
Reviewed-on: https://go-review.googlesource.com/9159
Reviewed-by: Rick Hudson <rlh@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-04-17 00:25:10 -04:00
|
|
|
cgen_wb(&r1, res, wb)
|
2015-03-20 00:06:10 -04:00
|
|
|
}
|
|
|
|
|
Regfree(&r1)
|
|
|
|
|
if !isblank(resok) {
|
|
|
|
|
Cgen(Nodbool(true), resok)
|
|
|
|
|
}
|
|
|
|
|
q := Gbranch(obj.AJMP, nil, 0)
|
|
|
|
|
Patch(p, Pc)
|
|
|
|
|
if !isblank(res) {
|
|
|
|
|
n := nodnil()
|
|
|
|
|
n.Type = res.Type
|
|
|
|
|
Cgen(n, res)
|
|
|
|
|
}
|
|
|
|
|
if !isblank(resok) {
|
|
|
|
|
Cgen(Nodbool(false), resok)
|
|
|
|
|
}
|
|
|
|
|
Patch(q, Pc)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* generate:
|
|
|
|
|
* res, resok = x.(T)
|
|
|
|
|
* n.Left is x
|
|
|
|
|
* n.Type is T
|
|
|
|
|
*/
|
|
|
|
|
func Cgen_As2dottype(n, res, resok *Node) {
|
|
|
|
|
if Debug_typeassert > 0 {
|
|
|
|
|
Warn("type assertion inlined")
|
|
|
|
|
}
|
|
|
|
|
// iface := n.Left
|
|
|
|
|
// r1 := iword(iface)
|
|
|
|
|
// if n.Left is non-empty interface {
|
|
|
|
|
// r1 = *r1
|
|
|
|
|
// }
|
|
|
|
|
// if r1 == T {
|
|
|
|
|
// res = idata(iface)
|
|
|
|
|
// resok = true
|
|
|
|
|
// } else {
|
|
|
|
|
// res = nil
|
|
|
|
|
// resok = false
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
var iface Node
|
|
|
|
|
Igen(n.Left, &iface, nil)
|
|
|
|
|
var r1, r2 Node
|
|
|
|
|
byteptr := Ptrto(Types[TUINT8]) // type used in runtime prototypes for runtime type (*byte)
|
|
|
|
|
Regalloc(&r1, byteptr, res)
|
|
|
|
|
iface.Type = byteptr
|
|
|
|
|
Cgen(&iface, &r1)
|
|
|
|
|
if !isnilinter(n.Left.Type) {
|
|
|
|
|
// Holding itab, want concrete type in second word.
|
2015-05-06 12:28:19 -04:00
|
|
|
p := Thearch.Ginscmp(OEQ, byteptr, &r1, Nodintconst(0), -1)
|
2015-03-20 00:06:10 -04:00
|
|
|
r2 = r1
|
|
|
|
|
r2.Op = OINDREG
|
|
|
|
|
r2.Xoffset = int64(Widthptr)
|
|
|
|
|
Cgen(&r2, &r1)
|
|
|
|
|
Patch(p, Pc)
|
|
|
|
|
}
|
|
|
|
|
Regalloc(&r2, byteptr, nil)
|
|
|
|
|
Cgen(typename(n.Type), &r2)
|
2015-05-06 12:28:19 -04:00
|
|
|
p := Thearch.Ginscmp(ONE, byteptr, &r1, &r2, -1)
|
2015-03-20 00:06:10 -04:00
|
|
|
iface.Type = n.Type
|
|
|
|
|
iface.Xoffset += int64(Widthptr)
|
|
|
|
|
Cgen(&iface, &r1)
|
|
|
|
|
if iface.Op != 0 {
|
|
|
|
|
Regfree(&iface)
|
|
|
|
|
}
|
|
|
|
|
Cgen(&r1, res)
|
|
|
|
|
q := Gbranch(obj.AJMP, nil, 0)
|
|
|
|
|
Patch(p, Pc)
|
|
|
|
|
|
|
|
|
|
fn := syslook("panicdottype", 0)
|
|
|
|
|
dowidth(fn.Type)
|
|
|
|
|
call := Nod(OCALLFUNC, fn, nil)
|
|
|
|
|
call.List = list(list(list1(&r1), &r2), typename(n.Left.Type))
|
|
|
|
|
call.List = ascompatte(OCALLFUNC, call, false, getinarg(fn.Type), call.List, 0, nil)
|
|
|
|
|
gen(call)
|
|
|
|
|
Regfree(&r1)
|
|
|
|
|
Regfree(&r2)
|
|
|
|
|
Thearch.Gins(obj.AUNDEF, nil, nil)
|
|
|
|
|
Patch(q, Pc)
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-13 14:40:36 -05:00
|
|
|
/*
|
|
|
|
|
* gather series of offsets
|
|
|
|
|
* >=0 is direct addressed field
|
|
|
|
|
* <0 is pointer to next field (+1)
|
|
|
|
|
*/
|
|
|
|
|
func Dotoffset(n *Node, oary []int64, nn **Node) int {
|
|
|
|
|
var i int
|
|
|
|
|
|
|
|
|
|
switch n.Op {
|
|
|
|
|
case ODOT:
|
|
|
|
|
if n.Xoffset == BADWIDTH {
|
|
|
|
|
Dump("bad width in dotoffset", n)
|
|
|
|
|
Fatal("bad width in dotoffset")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
i = Dotoffset(n.Left, oary, nn)
|
|
|
|
|
if i > 0 {
|
|
|
|
|
if oary[i-1] >= 0 {
|
|
|
|
|
oary[i-1] += n.Xoffset
|
|
|
|
|
} else {
|
|
|
|
|
oary[i-1] -= n.Xoffset
|
|
|
|
|
}
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if i < 10 {
|
|
|
|
|
oary[i] = n.Xoffset
|
|
|
|
|
i++
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case ODOTPTR:
|
|
|
|
|
if n.Xoffset == BADWIDTH {
|
|
|
|
|
Dump("bad width in dotoffset", n)
|
|
|
|
|
Fatal("bad width in dotoffset")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
i = Dotoffset(n.Left, oary, nn)
|
|
|
|
|
if i < 10 {
|
|
|
|
|
oary[i] = -(n.Xoffset + 1)
|
|
|
|
|
i++
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
*nn = n
|
|
|
|
|
return 0
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if i >= 10 {
|
|
|
|
|
*nn = nil
|
|
|
|
|
}
|
|
|
|
|
return i
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* make a new off the books
|
|
|
|
|
*/
|
|
|
|
|
func Tempname(nn *Node, t *Type) {
|
|
|
|
|
if Curfn == nil {
|
|
|
|
|
Fatal("no curfn for tempname")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if t == nil {
|
|
|
|
|
Yyerror("tempname called with nil type")
|
|
|
|
|
t = Types[TINT32]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// give each tmp a different name so that there
|
|
|
|
|
// a chance to registerizer them
|
2015-03-06 12:02:24 -08:00
|
|
|
s := Lookupf("autotmp_%.4d", statuniqgen)
|
2015-02-13 14:40:36 -05:00
|
|
|
statuniqgen++
|
2015-02-23 16:07:24 -05:00
|
|
|
n := Nod(ONAME, nil, nil)
|
2015-02-13 14:40:36 -05:00
|
|
|
n.Sym = s
|
|
|
|
|
s.Def = n
|
|
|
|
|
n.Type = t
|
|
|
|
|
n.Class = PAUTO
|
2015-04-02 19:58:37 -07:00
|
|
|
n.Addable = true
|
2015-02-13 14:40:36 -05:00
|
|
|
n.Ullman = 1
|
|
|
|
|
n.Esc = EscNever
|
|
|
|
|
n.Curfn = Curfn
|
2015-03-25 19:33:01 -07:00
|
|
|
Curfn.Func.Dcl = list(Curfn.Func.Dcl, n)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
dowidth(t)
|
|
|
|
|
n.Xoffset = 0
|
|
|
|
|
*nn = *n
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func temp(t *Type) *Node {
|
2015-02-23 16:07:24 -05:00
|
|
|
n := Nod(OXXX, nil, nil)
|
2015-02-13 14:40:36 -05:00
|
|
|
Tempname(n, t)
|
2015-03-06 21:18:41 +11:00
|
|
|
n.Sym.Def.Used = true
|
2015-02-13 14:40:36 -05:00
|
|
|
return n.Orig
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func gen(n *Node) {
|
|
|
|
|
//dump("gen", n);
|
|
|
|
|
|
2015-02-23 16:07:24 -05:00
|
|
|
lno := setlineno(n)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2015-03-18 17:26:36 -04:00
|
|
|
wasregalloc := Anyregalloc()
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
if n == nil {
|
|
|
|
|
goto ret
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if n.Ninit != nil {
|
|
|
|
|
Genlist(n.Ninit)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setlineno(n)
|
|
|
|
|
|
|
|
|
|
switch n.Op {
|
|
|
|
|
default:
|
|
|
|
|
Fatal("gen: unknown op %v", Nconv(n, obj.FmtShort|obj.FmtSign))
|
|
|
|
|
|
|
|
|
|
case OCASE,
|
|
|
|
|
OFALL,
|
|
|
|
|
OXCASE,
|
|
|
|
|
OXFALL,
|
|
|
|
|
ODCLCONST,
|
|
|
|
|
ODCLFUNC,
|
|
|
|
|
ODCLTYPE:
|
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
case OEMPTY:
|
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
case OBLOCK:
|
|
|
|
|
Genlist(n.List)
|
|
|
|
|
|
|
|
|
|
case OLABEL:
|
|
|
|
|
if isblanksym(n.Left.Sym) {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-23 16:07:24 -05:00
|
|
|
lab := newlab(n)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
// if there are pending gotos, resolve them all to the current pc.
|
2015-02-23 16:07:24 -05:00
|
|
|
var p2 *obj.Prog
|
|
|
|
|
for p1 := lab.Gotopc; p1 != nil; p1 = p2 {
|
2015-02-13 14:40:36 -05:00
|
|
|
p2 = unpatch(p1)
|
|
|
|
|
Patch(p1, Pc)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lab.Gotopc = nil
|
|
|
|
|
if lab.Labelpc == nil {
|
|
|
|
|
lab.Labelpc = Pc
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-26 22:19:27 -04:00
|
|
|
if n.Name.Defn != nil {
|
|
|
|
|
switch n.Name.Defn.Op {
|
2015-02-13 14:40:36 -05:00
|
|
|
// so stmtlabel can find the label
|
2015-04-01 09:38:44 -07:00
|
|
|
case OFOR, OSWITCH, OSELECT:
|
2015-05-26 22:19:27 -04:00
|
|
|
n.Name.Defn.Sym = lab.Sym
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if label is defined, emit jump to it.
|
|
|
|
|
// otherwise save list of pending gotos in lab->gotopc.
|
|
|
|
|
// the list is linked through the normal jump target field
|
|
|
|
|
// to avoid a second list. (the jumps are actually still
|
|
|
|
|
// valid code, since they're just going to another goto
|
|
|
|
|
// to the same label. we'll unwind it when we learn the pc
|
|
|
|
|
// of the label in the OLABEL case above.)
|
|
|
|
|
case OGOTO:
|
2015-02-23 16:07:24 -05:00
|
|
|
lab := newlab(n)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
if lab.Labelpc != nil {
|
|
|
|
|
gjmp(lab.Labelpc)
|
|
|
|
|
} else {
|
|
|
|
|
lab.Gotopc = gjmp(lab.Gotopc)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case OBREAK:
|
|
|
|
|
if n.Left != nil {
|
2015-02-23 16:07:24 -05:00
|
|
|
lab := n.Left.Sym.Label
|
2015-02-13 14:40:36 -05:00
|
|
|
if lab == nil {
|
2015-04-17 12:03:22 -04:00
|
|
|
Yyerror("break label not defined: %v", n.Left.Sym)
|
2015-02-13 14:40:36 -05:00
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lab.Used = 1
|
|
|
|
|
if lab.Breakpc == nil {
|
2015-04-17 12:03:22 -04:00
|
|
|
Yyerror("invalid break label %v", n.Left.Sym)
|
2015-02-13 14:40:36 -05:00
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gjmp(lab.Breakpc)
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if breakpc == nil {
|
|
|
|
|
Yyerror("break is not in a loop")
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gjmp(breakpc)
|
|
|
|
|
|
|
|
|
|
case OCONTINUE:
|
|
|
|
|
if n.Left != nil {
|
2015-02-23 16:07:24 -05:00
|
|
|
lab := n.Left.Sym.Label
|
2015-02-13 14:40:36 -05:00
|
|
|
if lab == nil {
|
2015-04-17 12:03:22 -04:00
|
|
|
Yyerror("continue label not defined: %v", n.Left.Sym)
|
2015-02-13 14:40:36 -05:00
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lab.Used = 1
|
|
|
|
|
if lab.Continpc == nil {
|
2015-04-17 12:03:22 -04:00
|
|
|
Yyerror("invalid continue label %v", n.Left.Sym)
|
2015-02-13 14:40:36 -05:00
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gjmp(lab.Continpc)
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if continpc == nil {
|
|
|
|
|
Yyerror("continue is not in a loop")
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gjmp(continpc)
|
|
|
|
|
|
|
|
|
|
case OFOR:
|
2015-02-23 16:07:24 -05:00
|
|
|
sbreak := breakpc
|
|
|
|
|
p1 := gjmp(nil) // goto test
|
2015-02-13 14:40:36 -05:00
|
|
|
breakpc = gjmp(nil) // break: goto done
|
2015-02-23 16:07:24 -05:00
|
|
|
scontin := continpc
|
2015-02-13 14:40:36 -05:00
|
|
|
continpc = Pc
|
|
|
|
|
|
|
|
|
|
// define break and continue labels
|
2015-02-23 16:07:24 -05:00
|
|
|
lab := stmtlabel(n)
|
2015-02-13 14:40:36 -05:00
|
|
|
if lab != nil {
|
|
|
|
|
lab.Breakpc = breakpc
|
|
|
|
|
lab.Continpc = continpc
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-26 21:30:20 -04:00
|
|
|
gen(n.Right) // contin: incr
|
|
|
|
|
Patch(p1, Pc) // test:
|
|
|
|
|
Bgen(n.Left, false, -1, breakpc) // if(!test) goto break
|
|
|
|
|
Genlist(n.Nbody) // body
|
2015-02-13 14:40:36 -05:00
|
|
|
gjmp(continpc)
|
|
|
|
|
Patch(breakpc, Pc) // done:
|
|
|
|
|
continpc = scontin
|
|
|
|
|
breakpc = sbreak
|
|
|
|
|
if lab != nil {
|
|
|
|
|
lab.Breakpc = nil
|
|
|
|
|
lab.Continpc = nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case OIF:
|
2015-05-26 21:30:20 -04:00
|
|
|
p1 := gjmp(nil) // goto test
|
|
|
|
|
p2 := gjmp(nil) // p2: goto else
|
|
|
|
|
Patch(p1, Pc) // test:
|
|
|
|
|
Bgen(n.Left, false, int(-n.Likely), p2) // if(!test) goto p2
|
|
|
|
|
Genlist(n.Nbody) // then
|
|
|
|
|
p3 := gjmp(nil) // goto done
|
|
|
|
|
Patch(p2, Pc) // else:
|
|
|
|
|
Genlist(n.Rlist) // else
|
|
|
|
|
Patch(p3, Pc) // done:
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
case OSWITCH:
|
2015-02-23 16:07:24 -05:00
|
|
|
sbreak := breakpc
|
|
|
|
|
p1 := gjmp(nil) // goto test
|
2015-02-13 14:40:36 -05:00
|
|
|
breakpc = gjmp(nil) // break: goto done
|
|
|
|
|
|
|
|
|
|
// define break label
|
2015-02-23 16:07:24 -05:00
|
|
|
lab := stmtlabel(n)
|
2015-02-13 14:40:36 -05:00
|
|
|
if lab != nil {
|
|
|
|
|
lab.Breakpc = breakpc
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Patch(p1, Pc) // test:
|
|
|
|
|
Genlist(n.Nbody) // switch(test) body
|
|
|
|
|
Patch(breakpc, Pc) // done:
|
|
|
|
|
breakpc = sbreak
|
|
|
|
|
if lab != nil {
|
|
|
|
|
lab.Breakpc = nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case OSELECT:
|
2015-02-23 16:07:24 -05:00
|
|
|
sbreak := breakpc
|
|
|
|
|
p1 := gjmp(nil) // goto test
|
2015-02-13 14:40:36 -05:00
|
|
|
breakpc = gjmp(nil) // break: goto done
|
|
|
|
|
|
|
|
|
|
// define break label
|
2015-02-23 16:07:24 -05:00
|
|
|
lab := stmtlabel(n)
|
2015-02-13 14:40:36 -05:00
|
|
|
if lab != nil {
|
|
|
|
|
lab.Breakpc = breakpc
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Patch(p1, Pc) // test:
|
|
|
|
|
Genlist(n.Nbody) // select() body
|
|
|
|
|
Patch(breakpc, Pc) // done:
|
|
|
|
|
breakpc = sbreak
|
|
|
|
|
if lab != nil {
|
|
|
|
|
lab.Breakpc = nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case ODCL:
|
|
|
|
|
cgen_dcl(n.Left)
|
|
|
|
|
|
|
|
|
|
case OAS:
|
2015-02-17 22:13:49 -05:00
|
|
|
if gen_as_init(n) {
|
2015-02-13 14:40:36 -05:00
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
Cgen_as(n.Left, n.Right)
|
|
|
|
|
|
cmd/internal/gc: emit write barriers at lower level
This is primarily preparation for inlining, not an optimization by itself,
but it still helps some.
name old new delta
BenchmarkBinaryTree17 18.2s × (0.99,1.01) 17.9s × (0.99,1.01) -1.57%
BenchmarkFannkuch11 4.44s × (1.00,1.00) 4.42s × (1.00,1.00) -0.40%
BenchmarkFmtFprintfEmpty 119ns × (0.95,1.02) 118ns × (0.96,1.02) ~
BenchmarkFmtFprintfString 501ns × (0.99,1.02) 486ns × (0.99,1.01) -2.89%
BenchmarkFmtFprintfInt 474ns × (0.99,1.00) 457ns × (0.99,1.01) -3.59%
BenchmarkFmtFprintfIntInt 792ns × (1.00,1.00) 768ns × (1.00,1.01) -3.03%
BenchmarkFmtFprintfPrefixedInt 574ns × (1.00,1.01) 584ns × (0.99,1.03) +1.83%
BenchmarkFmtFprintfFloat 749ns × (1.00,1.00) 739ns × (0.99,1.00) -1.34%
BenchmarkFmtManyArgs 2.94µs × (1.00,1.01) 2.77µs × (1.00,1.00) -5.76%
BenchmarkGobDecode 39.5ms × (0.99,1.01) 39.3ms × (0.99,1.01) ~
BenchmarkGobEncode 39.4ms × (1.00,1.01) 39.4ms × (0.99,1.00) ~
BenchmarkGzip 658ms × (1.00,1.01) 661ms × (0.99,1.01) ~
BenchmarkGunzip 142ms × (1.00,1.00) 142ms × (1.00,1.00) +0.22%
BenchmarkHTTPClientServer 134µs × (0.99,1.01) 133µs × (0.98,1.01) ~
BenchmarkJSONEncode 57.1ms × (0.99,1.01) 56.5ms × (0.99,1.01) ~
BenchmarkJSONDecode 141ms × (1.00,1.00) 143ms × (1.00,1.00) +1.09%
BenchmarkMandelbrot200 6.01ms × (1.00,1.00) 6.01ms × (1.00,1.00) ~
BenchmarkGoParse 10.1ms × (0.91,1.09) 9.6ms × (0.94,1.07) ~
BenchmarkRegexpMatchEasy0_32 207ns × (1.00,1.01) 210ns × (1.00,1.00) +1.45%
BenchmarkRegexpMatchEasy0_1K 592ns × (0.99,1.00) 596ns × (0.99,1.01) +0.68%
BenchmarkRegexpMatchEasy1_32 184ns × (0.99,1.01) 184ns × (0.99,1.01) ~
BenchmarkRegexpMatchEasy1_1K 1.01µs × (1.00,1.00) 1.01µs × (0.99,1.01) ~
BenchmarkRegexpMatchMedium_32 327ns × (0.99,1.00) 327ns × (1.00,1.01) ~
BenchmarkRegexpMatchMedium_1K 92.5µs × (1.00,1.00) 93.0µs × (1.00,1.02) +0.48%
BenchmarkRegexpMatchHard_32 4.79µs × (0.95,1.00) 4.76µs × (0.95,1.01) ~
BenchmarkRegexpMatchHard_1K 136µs × (1.00,1.00) 136µs × (1.00,1.01) ~
BenchmarkRevcomp 900ms × (0.99,1.01) 892ms × (1.00,1.01) ~
BenchmarkTemplate 170ms × (0.99,1.01) 175ms × (0.99,1.00) +2.95%
BenchmarkTimeParse 645ns × (1.00,1.00) 638ns × (1.00,1.00) -1.16%
BenchmarkTimeFormat 740ns × (1.00,1.00) 772ns × (1.00,1.00) +4.39%
Change-Id: I0be905e32791e0cb70ff01f169c4b309a971d981
Reviewed-on: https://go-review.googlesource.com/9159
Reviewed-by: Rick Hudson <rlh@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-04-17 00:25:10 -04:00
|
|
|
case OASWB:
|
|
|
|
|
Cgen_as_wb(n.Left, n.Right, true)
|
|
|
|
|
|
2015-03-20 00:06:10 -04:00
|
|
|
case OAS2DOTTYPE:
|
cmd/internal/gc: emit write barriers at lower level
This is primarily preparation for inlining, not an optimization by itself,
but it still helps some.
name old new delta
BenchmarkBinaryTree17 18.2s × (0.99,1.01) 17.9s × (0.99,1.01) -1.57%
BenchmarkFannkuch11 4.44s × (1.00,1.00) 4.42s × (1.00,1.00) -0.40%
BenchmarkFmtFprintfEmpty 119ns × (0.95,1.02) 118ns × (0.96,1.02) ~
BenchmarkFmtFprintfString 501ns × (0.99,1.02) 486ns × (0.99,1.01) -2.89%
BenchmarkFmtFprintfInt 474ns × (0.99,1.00) 457ns × (0.99,1.01) -3.59%
BenchmarkFmtFprintfIntInt 792ns × (1.00,1.00) 768ns × (1.00,1.01) -3.03%
BenchmarkFmtFprintfPrefixedInt 574ns × (1.00,1.01) 584ns × (0.99,1.03) +1.83%
BenchmarkFmtFprintfFloat 749ns × (1.00,1.00) 739ns × (0.99,1.00) -1.34%
BenchmarkFmtManyArgs 2.94µs × (1.00,1.01) 2.77µs × (1.00,1.00) -5.76%
BenchmarkGobDecode 39.5ms × (0.99,1.01) 39.3ms × (0.99,1.01) ~
BenchmarkGobEncode 39.4ms × (1.00,1.01) 39.4ms × (0.99,1.00) ~
BenchmarkGzip 658ms × (1.00,1.01) 661ms × (0.99,1.01) ~
BenchmarkGunzip 142ms × (1.00,1.00) 142ms × (1.00,1.00) +0.22%
BenchmarkHTTPClientServer 134µs × (0.99,1.01) 133µs × (0.98,1.01) ~
BenchmarkJSONEncode 57.1ms × (0.99,1.01) 56.5ms × (0.99,1.01) ~
BenchmarkJSONDecode 141ms × (1.00,1.00) 143ms × (1.00,1.00) +1.09%
BenchmarkMandelbrot200 6.01ms × (1.00,1.00) 6.01ms × (1.00,1.00) ~
BenchmarkGoParse 10.1ms × (0.91,1.09) 9.6ms × (0.94,1.07) ~
BenchmarkRegexpMatchEasy0_32 207ns × (1.00,1.01) 210ns × (1.00,1.00) +1.45%
BenchmarkRegexpMatchEasy0_1K 592ns × (0.99,1.00) 596ns × (0.99,1.01) +0.68%
BenchmarkRegexpMatchEasy1_32 184ns × (0.99,1.01) 184ns × (0.99,1.01) ~
BenchmarkRegexpMatchEasy1_1K 1.01µs × (1.00,1.00) 1.01µs × (0.99,1.01) ~
BenchmarkRegexpMatchMedium_32 327ns × (0.99,1.00) 327ns × (1.00,1.01) ~
BenchmarkRegexpMatchMedium_1K 92.5µs × (1.00,1.00) 93.0µs × (1.00,1.02) +0.48%
BenchmarkRegexpMatchHard_32 4.79µs × (0.95,1.00) 4.76µs × (0.95,1.01) ~
BenchmarkRegexpMatchHard_1K 136µs × (1.00,1.00) 136µs × (1.00,1.01) ~
BenchmarkRevcomp 900ms × (0.99,1.01) 892ms × (1.00,1.01) ~
BenchmarkTemplate 170ms × (0.99,1.01) 175ms × (0.99,1.00) +2.95%
BenchmarkTimeParse 645ns × (1.00,1.00) 638ns × (1.00,1.00) -1.16%
BenchmarkTimeFormat 740ns × (1.00,1.00) 772ns × (1.00,1.00) +4.39%
Change-Id: I0be905e32791e0cb70ff01f169c4b309a971d981
Reviewed-on: https://go-review.googlesource.com/9159
Reviewed-by: Rick Hudson <rlh@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-04-17 00:25:10 -04:00
|
|
|
cgen_dottype(n.Rlist.N, n.List.N, n.List.Next.N, false)
|
2015-03-20 00:06:10 -04:00
|
|
|
|
2015-02-13 14:40:36 -05:00
|
|
|
case OCALLMETH:
|
2015-03-18 17:26:36 -04:00
|
|
|
cgen_callmeth(n, 0)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
case OCALLINTER:
|
2015-03-18 17:26:36 -04:00
|
|
|
cgen_callinter(n, nil, 0)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
case OCALLFUNC:
|
2015-03-18 17:26:36 -04:00
|
|
|
cgen_call(n, 0)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
case OPROC:
|
|
|
|
|
cgen_proc(n, 1)
|
|
|
|
|
|
|
|
|
|
case ODEFER:
|
|
|
|
|
cgen_proc(n, 2)
|
|
|
|
|
|
2015-04-01 09:38:44 -07:00
|
|
|
case ORETURN, ORETJMP:
|
2015-03-18 17:26:36 -04:00
|
|
|
cgen_ret(n)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2015-04-03 12:23:28 -04:00
|
|
|
// Function calls turned into compiler intrinsics.
|
|
|
|
|
// At top level, can just ignore the call and make sure to preserve side effects in the argument, if any.
|
|
|
|
|
case OGETG:
|
|
|
|
|
// nothing
|
2015-04-01 16:02:34 -04:00
|
|
|
case OSQRT:
|
|
|
|
|
cgen_discard(n.Left)
|
|
|
|
|
|
2015-02-13 14:40:36 -05:00
|
|
|
case OCHECKNIL:
|
|
|
|
|
Cgen_checknil(n.Left)
|
|
|
|
|
|
|
|
|
|
case OVARKILL:
|
|
|
|
|
gvarkill(n.Left)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ret:
|
2015-03-18 17:26:36 -04:00
|
|
|
if Anyregalloc() != wasregalloc {
|
2015-02-13 14:40:36 -05:00
|
|
|
Dump("node", n)
|
|
|
|
|
Fatal("registers left allocated")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lineno = lno
|
|
|
|
|
}
|
|
|
|
|
|
cmd/internal/gc: emit write barriers at lower level
This is primarily preparation for inlining, not an optimization by itself,
but it still helps some.
name old new delta
BenchmarkBinaryTree17 18.2s × (0.99,1.01) 17.9s × (0.99,1.01) -1.57%
BenchmarkFannkuch11 4.44s × (1.00,1.00) 4.42s × (1.00,1.00) -0.40%
BenchmarkFmtFprintfEmpty 119ns × (0.95,1.02) 118ns × (0.96,1.02) ~
BenchmarkFmtFprintfString 501ns × (0.99,1.02) 486ns × (0.99,1.01) -2.89%
BenchmarkFmtFprintfInt 474ns × (0.99,1.00) 457ns × (0.99,1.01) -3.59%
BenchmarkFmtFprintfIntInt 792ns × (1.00,1.00) 768ns × (1.00,1.01) -3.03%
BenchmarkFmtFprintfPrefixedInt 574ns × (1.00,1.01) 584ns × (0.99,1.03) +1.83%
BenchmarkFmtFprintfFloat 749ns × (1.00,1.00) 739ns × (0.99,1.00) -1.34%
BenchmarkFmtManyArgs 2.94µs × (1.00,1.01) 2.77µs × (1.00,1.00) -5.76%
BenchmarkGobDecode 39.5ms × (0.99,1.01) 39.3ms × (0.99,1.01) ~
BenchmarkGobEncode 39.4ms × (1.00,1.01) 39.4ms × (0.99,1.00) ~
BenchmarkGzip 658ms × (1.00,1.01) 661ms × (0.99,1.01) ~
BenchmarkGunzip 142ms × (1.00,1.00) 142ms × (1.00,1.00) +0.22%
BenchmarkHTTPClientServer 134µs × (0.99,1.01) 133µs × (0.98,1.01) ~
BenchmarkJSONEncode 57.1ms × (0.99,1.01) 56.5ms × (0.99,1.01) ~
BenchmarkJSONDecode 141ms × (1.00,1.00) 143ms × (1.00,1.00) +1.09%
BenchmarkMandelbrot200 6.01ms × (1.00,1.00) 6.01ms × (1.00,1.00) ~
BenchmarkGoParse 10.1ms × (0.91,1.09) 9.6ms × (0.94,1.07) ~
BenchmarkRegexpMatchEasy0_32 207ns × (1.00,1.01) 210ns × (1.00,1.00) +1.45%
BenchmarkRegexpMatchEasy0_1K 592ns × (0.99,1.00) 596ns × (0.99,1.01) +0.68%
BenchmarkRegexpMatchEasy1_32 184ns × (0.99,1.01) 184ns × (0.99,1.01) ~
BenchmarkRegexpMatchEasy1_1K 1.01µs × (1.00,1.00) 1.01µs × (0.99,1.01) ~
BenchmarkRegexpMatchMedium_32 327ns × (0.99,1.00) 327ns × (1.00,1.01) ~
BenchmarkRegexpMatchMedium_1K 92.5µs × (1.00,1.00) 93.0µs × (1.00,1.02) +0.48%
BenchmarkRegexpMatchHard_32 4.79µs × (0.95,1.00) 4.76µs × (0.95,1.01) ~
BenchmarkRegexpMatchHard_1K 136µs × (1.00,1.00) 136µs × (1.00,1.01) ~
BenchmarkRevcomp 900ms × (0.99,1.01) 892ms × (1.00,1.01) ~
BenchmarkTemplate 170ms × (0.99,1.01) 175ms × (0.99,1.00) +2.95%
BenchmarkTimeParse 645ns × (1.00,1.00) 638ns × (1.00,1.00) -1.16%
BenchmarkTimeFormat 740ns × (1.00,1.00) 772ns × (1.00,1.00) +4.39%
Change-Id: I0be905e32791e0cb70ff01f169c4b309a971d981
Reviewed-on: https://go-review.googlesource.com/9159
Reviewed-by: Rick Hudson <rlh@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-04-17 00:25:10 -04:00
|
|
|
func Cgen_as(nl, nr *Node) {
|
|
|
|
|
Cgen_as_wb(nl, nr, false)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func Cgen_as_wb(nl, nr *Node, wb bool) {
|
2015-02-13 14:40:36 -05:00
|
|
|
if Debug['g'] != 0 {
|
cmd/internal/gc: emit write barriers at lower level
This is primarily preparation for inlining, not an optimization by itself,
but it still helps some.
name old new delta
BenchmarkBinaryTree17 18.2s × (0.99,1.01) 17.9s × (0.99,1.01) -1.57%
BenchmarkFannkuch11 4.44s × (1.00,1.00) 4.42s × (1.00,1.00) -0.40%
BenchmarkFmtFprintfEmpty 119ns × (0.95,1.02) 118ns × (0.96,1.02) ~
BenchmarkFmtFprintfString 501ns × (0.99,1.02) 486ns × (0.99,1.01) -2.89%
BenchmarkFmtFprintfInt 474ns × (0.99,1.00) 457ns × (0.99,1.01) -3.59%
BenchmarkFmtFprintfIntInt 792ns × (1.00,1.00) 768ns × (1.00,1.01) -3.03%
BenchmarkFmtFprintfPrefixedInt 574ns × (1.00,1.01) 584ns × (0.99,1.03) +1.83%
BenchmarkFmtFprintfFloat 749ns × (1.00,1.00) 739ns × (0.99,1.00) -1.34%
BenchmarkFmtManyArgs 2.94µs × (1.00,1.01) 2.77µs × (1.00,1.00) -5.76%
BenchmarkGobDecode 39.5ms × (0.99,1.01) 39.3ms × (0.99,1.01) ~
BenchmarkGobEncode 39.4ms × (1.00,1.01) 39.4ms × (0.99,1.00) ~
BenchmarkGzip 658ms × (1.00,1.01) 661ms × (0.99,1.01) ~
BenchmarkGunzip 142ms × (1.00,1.00) 142ms × (1.00,1.00) +0.22%
BenchmarkHTTPClientServer 134µs × (0.99,1.01) 133µs × (0.98,1.01) ~
BenchmarkJSONEncode 57.1ms × (0.99,1.01) 56.5ms × (0.99,1.01) ~
BenchmarkJSONDecode 141ms × (1.00,1.00) 143ms × (1.00,1.00) +1.09%
BenchmarkMandelbrot200 6.01ms × (1.00,1.00) 6.01ms × (1.00,1.00) ~
BenchmarkGoParse 10.1ms × (0.91,1.09) 9.6ms × (0.94,1.07) ~
BenchmarkRegexpMatchEasy0_32 207ns × (1.00,1.01) 210ns × (1.00,1.00) +1.45%
BenchmarkRegexpMatchEasy0_1K 592ns × (0.99,1.00) 596ns × (0.99,1.01) +0.68%
BenchmarkRegexpMatchEasy1_32 184ns × (0.99,1.01) 184ns × (0.99,1.01) ~
BenchmarkRegexpMatchEasy1_1K 1.01µs × (1.00,1.00) 1.01µs × (0.99,1.01) ~
BenchmarkRegexpMatchMedium_32 327ns × (0.99,1.00) 327ns × (1.00,1.01) ~
BenchmarkRegexpMatchMedium_1K 92.5µs × (1.00,1.00) 93.0µs × (1.00,1.02) +0.48%
BenchmarkRegexpMatchHard_32 4.79µs × (0.95,1.00) 4.76µs × (0.95,1.01) ~
BenchmarkRegexpMatchHard_1K 136µs × (1.00,1.00) 136µs × (1.00,1.01) ~
BenchmarkRevcomp 900ms × (0.99,1.01) 892ms × (1.00,1.01) ~
BenchmarkTemplate 170ms × (0.99,1.01) 175ms × (0.99,1.00) +2.95%
BenchmarkTimeParse 645ns × (1.00,1.00) 638ns × (1.00,1.00) -1.16%
BenchmarkTimeFormat 740ns × (1.00,1.00) 772ns × (1.00,1.00) +4.39%
Change-Id: I0be905e32791e0cb70ff01f169c4b309a971d981
Reviewed-on: https://go-review.googlesource.com/9159
Reviewed-by: Rick Hudson <rlh@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-04-17 00:25:10 -04:00
|
|
|
op := "cgen_as"
|
|
|
|
|
if wb {
|
|
|
|
|
op = "cgen_as_wb"
|
|
|
|
|
}
|
|
|
|
|
Dump(op, nl)
|
|
|
|
|
Dump(op+" = ", nr)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for nr != nil && nr.Op == OCONVNOP {
|
|
|
|
|
nr = nr.Left
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if nl == nil || isblank(nl) {
|
|
|
|
|
cgen_discard(nr)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-17 22:13:49 -05:00
|
|
|
if nr == nil || iszero(nr) {
|
2015-02-13 14:40:36 -05:00
|
|
|
// heaps should already be clear
|
|
|
|
|
if nr == nil && (nl.Class&PHEAP != 0) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-23 16:07:24 -05:00
|
|
|
tl := nl.Type
|
2015-02-13 14:40:36 -05:00
|
|
|
if tl == nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
2015-02-17 22:13:49 -05:00
|
|
|
if Isfat(tl) {
|
2015-02-13 14:40:36 -05:00
|
|
|
if nl.Op == ONAME {
|
|
|
|
|
Gvardef(nl)
|
|
|
|
|
}
|
|
|
|
|
Thearch.Clearfat(nl)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Clearslim(nl)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-23 16:07:24 -05:00
|
|
|
tl := nl.Type
|
2015-02-13 14:40:36 -05:00
|
|
|
if tl == nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
cmd/internal/gc: emit write barriers at lower level
This is primarily preparation for inlining, not an optimization by itself,
but it still helps some.
name old new delta
BenchmarkBinaryTree17 18.2s × (0.99,1.01) 17.9s × (0.99,1.01) -1.57%
BenchmarkFannkuch11 4.44s × (1.00,1.00) 4.42s × (1.00,1.00) -0.40%
BenchmarkFmtFprintfEmpty 119ns × (0.95,1.02) 118ns × (0.96,1.02) ~
BenchmarkFmtFprintfString 501ns × (0.99,1.02) 486ns × (0.99,1.01) -2.89%
BenchmarkFmtFprintfInt 474ns × (0.99,1.00) 457ns × (0.99,1.01) -3.59%
BenchmarkFmtFprintfIntInt 792ns × (1.00,1.00) 768ns × (1.00,1.01) -3.03%
BenchmarkFmtFprintfPrefixedInt 574ns × (1.00,1.01) 584ns × (0.99,1.03) +1.83%
BenchmarkFmtFprintfFloat 749ns × (1.00,1.00) 739ns × (0.99,1.00) -1.34%
BenchmarkFmtManyArgs 2.94µs × (1.00,1.01) 2.77µs × (1.00,1.00) -5.76%
BenchmarkGobDecode 39.5ms × (0.99,1.01) 39.3ms × (0.99,1.01) ~
BenchmarkGobEncode 39.4ms × (1.00,1.01) 39.4ms × (0.99,1.00) ~
BenchmarkGzip 658ms × (1.00,1.01) 661ms × (0.99,1.01) ~
BenchmarkGunzip 142ms × (1.00,1.00) 142ms × (1.00,1.00) +0.22%
BenchmarkHTTPClientServer 134µs × (0.99,1.01) 133µs × (0.98,1.01) ~
BenchmarkJSONEncode 57.1ms × (0.99,1.01) 56.5ms × (0.99,1.01) ~
BenchmarkJSONDecode 141ms × (1.00,1.00) 143ms × (1.00,1.00) +1.09%
BenchmarkMandelbrot200 6.01ms × (1.00,1.00) 6.01ms × (1.00,1.00) ~
BenchmarkGoParse 10.1ms × (0.91,1.09) 9.6ms × (0.94,1.07) ~
BenchmarkRegexpMatchEasy0_32 207ns × (1.00,1.01) 210ns × (1.00,1.00) +1.45%
BenchmarkRegexpMatchEasy0_1K 592ns × (0.99,1.00) 596ns × (0.99,1.01) +0.68%
BenchmarkRegexpMatchEasy1_32 184ns × (0.99,1.01) 184ns × (0.99,1.01) ~
BenchmarkRegexpMatchEasy1_1K 1.01µs × (1.00,1.00) 1.01µs × (0.99,1.01) ~
BenchmarkRegexpMatchMedium_32 327ns × (0.99,1.00) 327ns × (1.00,1.01) ~
BenchmarkRegexpMatchMedium_1K 92.5µs × (1.00,1.00) 93.0µs × (1.00,1.02) +0.48%
BenchmarkRegexpMatchHard_32 4.79µs × (0.95,1.00) 4.76µs × (0.95,1.01) ~
BenchmarkRegexpMatchHard_1K 136µs × (1.00,1.00) 136µs × (1.00,1.01) ~
BenchmarkRevcomp 900ms × (0.99,1.01) 892ms × (1.00,1.01) ~
BenchmarkTemplate 170ms × (0.99,1.01) 175ms × (0.99,1.00) +2.95%
BenchmarkTimeParse 645ns × (1.00,1.00) 638ns × (1.00,1.00) -1.16%
BenchmarkTimeFormat 740ns × (1.00,1.00) 772ns × (1.00,1.00) +4.39%
Change-Id: I0be905e32791e0cb70ff01f169c4b309a971d981
Reviewed-on: https://go-review.googlesource.com/9159
Reviewed-by: Rick Hudson <rlh@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-04-17 00:25:10 -04:00
|
|
|
cgen_wb(nr, nl, wb)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2015-03-18 17:26:36 -04:00
|
|
|
func cgen_callmeth(n *Node, proc int) {
|
2015-02-13 14:40:36 -05:00
|
|
|
// generate a rewrite in n2 for the method call
|
|
|
|
|
// (p.f)(...) goes to (f)(p,...)
|
|
|
|
|
|
2015-02-23 16:07:24 -05:00
|
|
|
l := n.Left
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
if l.Op != ODOTMETH {
|
2015-05-13 19:05:50 -04:00
|
|
|
Fatal("cgen_callmeth: not dotmethod: %v", l)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2015-02-23 16:07:24 -05:00
|
|
|
n2 := *n
|
2015-02-13 14:40:36 -05:00
|
|
|
n2.Op = OCALLFUNC
|
|
|
|
|
n2.Left = l.Right
|
|
|
|
|
n2.Left.Type = l.Type
|
|
|
|
|
|
|
|
|
|
if n2.Left.Op == ONAME {
|
|
|
|
|
n2.Left.Class = PFUNC
|
|
|
|
|
}
|
2015-03-18 17:26:36 -04:00
|
|
|
cgen_call(&n2, proc)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2015-04-06 19:36:36 -07:00
|
|
|
// CgenTemp creates a temporary node, assigns n to it, and returns it.
|
|
|
|
|
func CgenTemp(n *Node) *Node {
|
|
|
|
|
var tmp Node
|
|
|
|
|
Tempname(&tmp, n.Type)
|
|
|
|
|
Cgen(n, &tmp)
|
|
|
|
|
return &tmp
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-13 14:40:36 -05:00
|
|
|
func checklabels() {
|
|
|
|
|
var l *NodeList
|
|
|
|
|
|
2015-02-23 16:07:24 -05:00
|
|
|
for lab := labellist; lab != nil; lab = lab.Link {
|
2015-02-13 14:40:36 -05:00
|
|
|
if lab.Def == nil {
|
|
|
|
|
for l = lab.Use; l != nil; l = l.Next {
|
2015-04-17 12:03:22 -04:00
|
|
|
yyerrorl(int(l.N.Lineno), "label %v not defined", lab.Sym)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-17 22:13:49 -05:00
|
|
|
if lab.Use == nil && lab.Used == 0 {
|
2015-04-17 12:03:22 -04:00
|
|
|
yyerrorl(int(lab.Def.Lineno), "label %v defined and not used", lab.Sym)
|
2015-02-13 14:40:36 -05:00
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if lab.Gotopc != nil {
|
2015-04-17 12:03:22 -04:00
|
|
|
Fatal("label %v never resolved", lab.Sym)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
for l = lab.Use; l != nil; l = l.Next {
|
|
|
|
|
checkgoto(l.N, lab.Def)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-03-18 12:29:40 -04:00
|
|
|
|
2015-04-09 20:10:16 +10:00
|
|
|
// Componentgen copies a composite value by moving its individual components.
|
|
|
|
|
// Slices, strings and interfaces are supported. Small structs or arrays with
|
|
|
|
|
// elements of basic type are also supported.
|
|
|
|
|
// nr is nil when assigning a zero value.
|
cmd/internal/gc: emit write barriers at lower level
This is primarily preparation for inlining, not an optimization by itself,
but it still helps some.
name old new delta
BenchmarkBinaryTree17 18.2s × (0.99,1.01) 17.9s × (0.99,1.01) -1.57%
BenchmarkFannkuch11 4.44s × (1.00,1.00) 4.42s × (1.00,1.00) -0.40%
BenchmarkFmtFprintfEmpty 119ns × (0.95,1.02) 118ns × (0.96,1.02) ~
BenchmarkFmtFprintfString 501ns × (0.99,1.02) 486ns × (0.99,1.01) -2.89%
BenchmarkFmtFprintfInt 474ns × (0.99,1.00) 457ns × (0.99,1.01) -3.59%
BenchmarkFmtFprintfIntInt 792ns × (1.00,1.00) 768ns × (1.00,1.01) -3.03%
BenchmarkFmtFprintfPrefixedInt 574ns × (1.00,1.01) 584ns × (0.99,1.03) +1.83%
BenchmarkFmtFprintfFloat 749ns × (1.00,1.00) 739ns × (0.99,1.00) -1.34%
BenchmarkFmtManyArgs 2.94µs × (1.00,1.01) 2.77µs × (1.00,1.00) -5.76%
BenchmarkGobDecode 39.5ms × (0.99,1.01) 39.3ms × (0.99,1.01) ~
BenchmarkGobEncode 39.4ms × (1.00,1.01) 39.4ms × (0.99,1.00) ~
BenchmarkGzip 658ms × (1.00,1.01) 661ms × (0.99,1.01) ~
BenchmarkGunzip 142ms × (1.00,1.00) 142ms × (1.00,1.00) +0.22%
BenchmarkHTTPClientServer 134µs × (0.99,1.01) 133µs × (0.98,1.01) ~
BenchmarkJSONEncode 57.1ms × (0.99,1.01) 56.5ms × (0.99,1.01) ~
BenchmarkJSONDecode 141ms × (1.00,1.00) 143ms × (1.00,1.00) +1.09%
BenchmarkMandelbrot200 6.01ms × (1.00,1.00) 6.01ms × (1.00,1.00) ~
BenchmarkGoParse 10.1ms × (0.91,1.09) 9.6ms × (0.94,1.07) ~
BenchmarkRegexpMatchEasy0_32 207ns × (1.00,1.01) 210ns × (1.00,1.00) +1.45%
BenchmarkRegexpMatchEasy0_1K 592ns × (0.99,1.00) 596ns × (0.99,1.01) +0.68%
BenchmarkRegexpMatchEasy1_32 184ns × (0.99,1.01) 184ns × (0.99,1.01) ~
BenchmarkRegexpMatchEasy1_1K 1.01µs × (1.00,1.00) 1.01µs × (0.99,1.01) ~
BenchmarkRegexpMatchMedium_32 327ns × (0.99,1.00) 327ns × (1.00,1.01) ~
BenchmarkRegexpMatchMedium_1K 92.5µs × (1.00,1.00) 93.0µs × (1.00,1.02) +0.48%
BenchmarkRegexpMatchHard_32 4.79µs × (0.95,1.00) 4.76µs × (0.95,1.01) ~
BenchmarkRegexpMatchHard_1K 136µs × (1.00,1.00) 136µs × (1.00,1.01) ~
BenchmarkRevcomp 900ms × (0.99,1.01) 892ms × (1.00,1.01) ~
BenchmarkTemplate 170ms × (0.99,1.01) 175ms × (0.99,1.00) +2.95%
BenchmarkTimeParse 645ns × (1.00,1.00) 638ns × (1.00,1.00) -1.16%
BenchmarkTimeFormat 740ns × (1.00,1.00) 772ns × (1.00,1.00) +4.39%
Change-Id: I0be905e32791e0cb70ff01f169c4b309a971d981
Reviewed-on: https://go-review.googlesource.com/9159
Reviewed-by: Rick Hudson <rlh@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-04-17 00:25:10 -04:00
|
|
|
func Componentgen(nr, nl *Node) bool {
|
|
|
|
|
return componentgen_wb(nr, nl, false)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// componentgen_wb is like componentgen but if wb==true emits write barriers for pointer updates.
|
|
|
|
|
func componentgen_wb(nr, nl *Node, wb bool) bool {
|
|
|
|
|
// Don't generate any code for complete copy of a variable into itself.
|
|
|
|
|
// It's useless, and the VARDEF will incorrectly mark the old value as dead.
|
|
|
|
|
// (This check assumes that the arguments passed to componentgen did not
|
|
|
|
|
// themselves come from Igen, or else we could have Op==ONAME but
|
|
|
|
|
// with a Type and Xoffset describing an individual field, not the entire
|
|
|
|
|
// variable.)
|
|
|
|
|
if nl.Op == ONAME && nl == nr {
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-16 16:22:30 -04:00
|
|
|
// Count number of moves required to move components.
|
cmd/internal/gc: emit write barriers at lower level
This is primarily preparation for inlining, not an optimization by itself,
but it still helps some.
name old new delta
BenchmarkBinaryTree17 18.2s × (0.99,1.01) 17.9s × (0.99,1.01) -1.57%
BenchmarkFannkuch11 4.44s × (1.00,1.00) 4.42s × (1.00,1.00) -0.40%
BenchmarkFmtFprintfEmpty 119ns × (0.95,1.02) 118ns × (0.96,1.02) ~
BenchmarkFmtFprintfString 501ns × (0.99,1.02) 486ns × (0.99,1.01) -2.89%
BenchmarkFmtFprintfInt 474ns × (0.99,1.00) 457ns × (0.99,1.01) -3.59%
BenchmarkFmtFprintfIntInt 792ns × (1.00,1.00) 768ns × (1.00,1.01) -3.03%
BenchmarkFmtFprintfPrefixedInt 574ns × (1.00,1.01) 584ns × (0.99,1.03) +1.83%
BenchmarkFmtFprintfFloat 749ns × (1.00,1.00) 739ns × (0.99,1.00) -1.34%
BenchmarkFmtManyArgs 2.94µs × (1.00,1.01) 2.77µs × (1.00,1.00) -5.76%
BenchmarkGobDecode 39.5ms × (0.99,1.01) 39.3ms × (0.99,1.01) ~
BenchmarkGobEncode 39.4ms × (1.00,1.01) 39.4ms × (0.99,1.00) ~
BenchmarkGzip 658ms × (1.00,1.01) 661ms × (0.99,1.01) ~
BenchmarkGunzip 142ms × (1.00,1.00) 142ms × (1.00,1.00) +0.22%
BenchmarkHTTPClientServer 134µs × (0.99,1.01) 133µs × (0.98,1.01) ~
BenchmarkJSONEncode 57.1ms × (0.99,1.01) 56.5ms × (0.99,1.01) ~
BenchmarkJSONDecode 141ms × (1.00,1.00) 143ms × (1.00,1.00) +1.09%
BenchmarkMandelbrot200 6.01ms × (1.00,1.00) 6.01ms × (1.00,1.00) ~
BenchmarkGoParse 10.1ms × (0.91,1.09) 9.6ms × (0.94,1.07) ~
BenchmarkRegexpMatchEasy0_32 207ns × (1.00,1.01) 210ns × (1.00,1.00) +1.45%
BenchmarkRegexpMatchEasy0_1K 592ns × (0.99,1.00) 596ns × (0.99,1.01) +0.68%
BenchmarkRegexpMatchEasy1_32 184ns × (0.99,1.01) 184ns × (0.99,1.01) ~
BenchmarkRegexpMatchEasy1_1K 1.01µs × (1.00,1.00) 1.01µs × (0.99,1.01) ~
BenchmarkRegexpMatchMedium_32 327ns × (0.99,1.00) 327ns × (1.00,1.01) ~
BenchmarkRegexpMatchMedium_1K 92.5µs × (1.00,1.00) 93.0µs × (1.00,1.02) +0.48%
BenchmarkRegexpMatchHard_32 4.79µs × (0.95,1.00) 4.76µs × (0.95,1.01) ~
BenchmarkRegexpMatchHard_1K 136µs × (1.00,1.00) 136µs × (1.00,1.01) ~
BenchmarkRevcomp 900ms × (0.99,1.01) 892ms × (1.00,1.01) ~
BenchmarkTemplate 170ms × (0.99,1.01) 175ms × (0.99,1.00) +2.95%
BenchmarkTimeParse 645ns × (1.00,1.00) 638ns × (1.00,1.00) -1.16%
BenchmarkTimeFormat 740ns × (1.00,1.00) 772ns × (1.00,1.00) +4.39%
Change-Id: I0be905e32791e0cb70ff01f169c4b309a971d981
Reviewed-on: https://go-review.googlesource.com/9159
Reviewed-by: Rick Hudson <rlh@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-04-17 00:25:10 -04:00
|
|
|
// If using write barrier, can only emit one pointer.
|
|
|
|
|
// TODO(rsc): Allow more pointers, for reflect.Value.
|
2015-04-16 16:22:30 -04:00
|
|
|
const maxMoves = 8
|
|
|
|
|
n := 0
|
cmd/internal/gc: emit write barriers at lower level
This is primarily preparation for inlining, not an optimization by itself,
but it still helps some.
name old new delta
BenchmarkBinaryTree17 18.2s × (0.99,1.01) 17.9s × (0.99,1.01) -1.57%
BenchmarkFannkuch11 4.44s × (1.00,1.00) 4.42s × (1.00,1.00) -0.40%
BenchmarkFmtFprintfEmpty 119ns × (0.95,1.02) 118ns × (0.96,1.02) ~
BenchmarkFmtFprintfString 501ns × (0.99,1.02) 486ns × (0.99,1.01) -2.89%
BenchmarkFmtFprintfInt 474ns × (0.99,1.00) 457ns × (0.99,1.01) -3.59%
BenchmarkFmtFprintfIntInt 792ns × (1.00,1.00) 768ns × (1.00,1.01) -3.03%
BenchmarkFmtFprintfPrefixedInt 574ns × (1.00,1.01) 584ns × (0.99,1.03) +1.83%
BenchmarkFmtFprintfFloat 749ns × (1.00,1.00) 739ns × (0.99,1.00) -1.34%
BenchmarkFmtManyArgs 2.94µs × (1.00,1.01) 2.77µs × (1.00,1.00) -5.76%
BenchmarkGobDecode 39.5ms × (0.99,1.01) 39.3ms × (0.99,1.01) ~
BenchmarkGobEncode 39.4ms × (1.00,1.01) 39.4ms × (0.99,1.00) ~
BenchmarkGzip 658ms × (1.00,1.01) 661ms × (0.99,1.01) ~
BenchmarkGunzip 142ms × (1.00,1.00) 142ms × (1.00,1.00) +0.22%
BenchmarkHTTPClientServer 134µs × (0.99,1.01) 133µs × (0.98,1.01) ~
BenchmarkJSONEncode 57.1ms × (0.99,1.01) 56.5ms × (0.99,1.01) ~
BenchmarkJSONDecode 141ms × (1.00,1.00) 143ms × (1.00,1.00) +1.09%
BenchmarkMandelbrot200 6.01ms × (1.00,1.00) 6.01ms × (1.00,1.00) ~
BenchmarkGoParse 10.1ms × (0.91,1.09) 9.6ms × (0.94,1.07) ~
BenchmarkRegexpMatchEasy0_32 207ns × (1.00,1.01) 210ns × (1.00,1.00) +1.45%
BenchmarkRegexpMatchEasy0_1K 592ns × (0.99,1.00) 596ns × (0.99,1.01) +0.68%
BenchmarkRegexpMatchEasy1_32 184ns × (0.99,1.01) 184ns × (0.99,1.01) ~
BenchmarkRegexpMatchEasy1_1K 1.01µs × (1.00,1.00) 1.01µs × (0.99,1.01) ~
BenchmarkRegexpMatchMedium_32 327ns × (0.99,1.00) 327ns × (1.00,1.01) ~
BenchmarkRegexpMatchMedium_1K 92.5µs × (1.00,1.00) 93.0µs × (1.00,1.02) +0.48%
BenchmarkRegexpMatchHard_32 4.79µs × (0.95,1.00) 4.76µs × (0.95,1.01) ~
BenchmarkRegexpMatchHard_1K 136µs × (1.00,1.00) 136µs × (1.00,1.01) ~
BenchmarkRevcomp 900ms × (0.99,1.01) 892ms × (1.00,1.01) ~
BenchmarkTemplate 170ms × (0.99,1.01) 175ms × (0.99,1.00) +2.95%
BenchmarkTimeParse 645ns × (1.00,1.00) 638ns × (1.00,1.00) -1.16%
BenchmarkTimeFormat 740ns × (1.00,1.00) 772ns × (1.00,1.00) +4.39%
Change-Id: I0be905e32791e0cb70ff01f169c4b309a971d981
Reviewed-on: https://go-review.googlesource.com/9159
Reviewed-by: Rick Hudson <rlh@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-04-17 00:25:10 -04:00
|
|
|
numPtr := 0
|
2015-04-16 16:22:30 -04:00
|
|
|
visitComponents(nl.Type, 0, func(t *Type, offset int64) bool {
|
|
|
|
|
n++
|
cmd/internal/gc: emit write barriers at lower level
This is primarily preparation for inlining, not an optimization by itself,
but it still helps some.
name old new delta
BenchmarkBinaryTree17 18.2s × (0.99,1.01) 17.9s × (0.99,1.01) -1.57%
BenchmarkFannkuch11 4.44s × (1.00,1.00) 4.42s × (1.00,1.00) -0.40%
BenchmarkFmtFprintfEmpty 119ns × (0.95,1.02) 118ns × (0.96,1.02) ~
BenchmarkFmtFprintfString 501ns × (0.99,1.02) 486ns × (0.99,1.01) -2.89%
BenchmarkFmtFprintfInt 474ns × (0.99,1.00) 457ns × (0.99,1.01) -3.59%
BenchmarkFmtFprintfIntInt 792ns × (1.00,1.00) 768ns × (1.00,1.01) -3.03%
BenchmarkFmtFprintfPrefixedInt 574ns × (1.00,1.01) 584ns × (0.99,1.03) +1.83%
BenchmarkFmtFprintfFloat 749ns × (1.00,1.00) 739ns × (0.99,1.00) -1.34%
BenchmarkFmtManyArgs 2.94µs × (1.00,1.01) 2.77µs × (1.00,1.00) -5.76%
BenchmarkGobDecode 39.5ms × (0.99,1.01) 39.3ms × (0.99,1.01) ~
BenchmarkGobEncode 39.4ms × (1.00,1.01) 39.4ms × (0.99,1.00) ~
BenchmarkGzip 658ms × (1.00,1.01) 661ms × (0.99,1.01) ~
BenchmarkGunzip 142ms × (1.00,1.00) 142ms × (1.00,1.00) +0.22%
BenchmarkHTTPClientServer 134µs × (0.99,1.01) 133µs × (0.98,1.01) ~
BenchmarkJSONEncode 57.1ms × (0.99,1.01) 56.5ms × (0.99,1.01) ~
BenchmarkJSONDecode 141ms × (1.00,1.00) 143ms × (1.00,1.00) +1.09%
BenchmarkMandelbrot200 6.01ms × (1.00,1.00) 6.01ms × (1.00,1.00) ~
BenchmarkGoParse 10.1ms × (0.91,1.09) 9.6ms × (0.94,1.07) ~
BenchmarkRegexpMatchEasy0_32 207ns × (1.00,1.01) 210ns × (1.00,1.00) +1.45%
BenchmarkRegexpMatchEasy0_1K 592ns × (0.99,1.00) 596ns × (0.99,1.01) +0.68%
BenchmarkRegexpMatchEasy1_32 184ns × (0.99,1.01) 184ns × (0.99,1.01) ~
BenchmarkRegexpMatchEasy1_1K 1.01µs × (1.00,1.00) 1.01µs × (0.99,1.01) ~
BenchmarkRegexpMatchMedium_32 327ns × (0.99,1.00) 327ns × (1.00,1.01) ~
BenchmarkRegexpMatchMedium_1K 92.5µs × (1.00,1.00) 93.0µs × (1.00,1.02) +0.48%
BenchmarkRegexpMatchHard_32 4.79µs × (0.95,1.00) 4.76µs × (0.95,1.01) ~
BenchmarkRegexpMatchHard_1K 136µs × (1.00,1.00) 136µs × (1.00,1.01) ~
BenchmarkRevcomp 900ms × (0.99,1.01) 892ms × (1.00,1.01) ~
BenchmarkTemplate 170ms × (0.99,1.01) 175ms × (0.99,1.00) +2.95%
BenchmarkTimeParse 645ns × (1.00,1.00) 638ns × (1.00,1.00) -1.16%
BenchmarkTimeFormat 740ns × (1.00,1.00) 772ns × (1.00,1.00) +4.39%
Change-Id: I0be905e32791e0cb70ff01f169c4b309a971d981
Reviewed-on: https://go-review.googlesource.com/9159
Reviewed-by: Rick Hudson <rlh@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-04-17 00:25:10 -04:00
|
|
|
if int(Simtype[t.Etype]) == Tptr && t != itable {
|
|
|
|
|
numPtr++
|
|
|
|
|
}
|
|
|
|
|
return n <= maxMoves && (!wb || numPtr <= 1)
|
2015-04-16 16:22:30 -04:00
|
|
|
})
|
cmd/internal/gc: emit write barriers at lower level
This is primarily preparation for inlining, not an optimization by itself,
but it still helps some.
name old new delta
BenchmarkBinaryTree17 18.2s × (0.99,1.01) 17.9s × (0.99,1.01) -1.57%
BenchmarkFannkuch11 4.44s × (1.00,1.00) 4.42s × (1.00,1.00) -0.40%
BenchmarkFmtFprintfEmpty 119ns × (0.95,1.02) 118ns × (0.96,1.02) ~
BenchmarkFmtFprintfString 501ns × (0.99,1.02) 486ns × (0.99,1.01) -2.89%
BenchmarkFmtFprintfInt 474ns × (0.99,1.00) 457ns × (0.99,1.01) -3.59%
BenchmarkFmtFprintfIntInt 792ns × (1.00,1.00) 768ns × (1.00,1.01) -3.03%
BenchmarkFmtFprintfPrefixedInt 574ns × (1.00,1.01) 584ns × (0.99,1.03) +1.83%
BenchmarkFmtFprintfFloat 749ns × (1.00,1.00) 739ns × (0.99,1.00) -1.34%
BenchmarkFmtManyArgs 2.94µs × (1.00,1.01) 2.77µs × (1.00,1.00) -5.76%
BenchmarkGobDecode 39.5ms × (0.99,1.01) 39.3ms × (0.99,1.01) ~
BenchmarkGobEncode 39.4ms × (1.00,1.01) 39.4ms × (0.99,1.00) ~
BenchmarkGzip 658ms × (1.00,1.01) 661ms × (0.99,1.01) ~
BenchmarkGunzip 142ms × (1.00,1.00) 142ms × (1.00,1.00) +0.22%
BenchmarkHTTPClientServer 134µs × (0.99,1.01) 133µs × (0.98,1.01) ~
BenchmarkJSONEncode 57.1ms × (0.99,1.01) 56.5ms × (0.99,1.01) ~
BenchmarkJSONDecode 141ms × (1.00,1.00) 143ms × (1.00,1.00) +1.09%
BenchmarkMandelbrot200 6.01ms × (1.00,1.00) 6.01ms × (1.00,1.00) ~
BenchmarkGoParse 10.1ms × (0.91,1.09) 9.6ms × (0.94,1.07) ~
BenchmarkRegexpMatchEasy0_32 207ns × (1.00,1.01) 210ns × (1.00,1.00) +1.45%
BenchmarkRegexpMatchEasy0_1K 592ns × (0.99,1.00) 596ns × (0.99,1.01) +0.68%
BenchmarkRegexpMatchEasy1_32 184ns × (0.99,1.01) 184ns × (0.99,1.01) ~
BenchmarkRegexpMatchEasy1_1K 1.01µs × (1.00,1.00) 1.01µs × (0.99,1.01) ~
BenchmarkRegexpMatchMedium_32 327ns × (0.99,1.00) 327ns × (1.00,1.01) ~
BenchmarkRegexpMatchMedium_1K 92.5µs × (1.00,1.00) 93.0µs × (1.00,1.02) +0.48%
BenchmarkRegexpMatchHard_32 4.79µs × (0.95,1.00) 4.76µs × (0.95,1.01) ~
BenchmarkRegexpMatchHard_1K 136µs × (1.00,1.00) 136µs × (1.00,1.01) ~
BenchmarkRevcomp 900ms × (0.99,1.01) 892ms × (1.00,1.01) ~
BenchmarkTemplate 170ms × (0.99,1.01) 175ms × (0.99,1.00) +2.95%
BenchmarkTimeParse 645ns × (1.00,1.00) 638ns × (1.00,1.00) -1.16%
BenchmarkTimeFormat 740ns × (1.00,1.00) 772ns × (1.00,1.00) +4.39%
Change-Id: I0be905e32791e0cb70ff01f169c4b309a971d981
Reviewed-on: https://go-review.googlesource.com/9159
Reviewed-by: Rick Hudson <rlh@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-04-17 00:25:10 -04:00
|
|
|
if n > maxMoves || wb && numPtr > 1 {
|
2015-04-09 20:10:16 +10:00
|
|
|
return false
|
2015-03-18 12:29:40 -04:00
|
|
|
}
|
|
|
|
|
|
cmd/internal/gc: emit write barriers at lower level
This is primarily preparation for inlining, not an optimization by itself,
but it still helps some.
name old new delta
BenchmarkBinaryTree17 18.2s × (0.99,1.01) 17.9s × (0.99,1.01) -1.57%
BenchmarkFannkuch11 4.44s × (1.00,1.00) 4.42s × (1.00,1.00) -0.40%
BenchmarkFmtFprintfEmpty 119ns × (0.95,1.02) 118ns × (0.96,1.02) ~
BenchmarkFmtFprintfString 501ns × (0.99,1.02) 486ns × (0.99,1.01) -2.89%
BenchmarkFmtFprintfInt 474ns × (0.99,1.00) 457ns × (0.99,1.01) -3.59%
BenchmarkFmtFprintfIntInt 792ns × (1.00,1.00) 768ns × (1.00,1.01) -3.03%
BenchmarkFmtFprintfPrefixedInt 574ns × (1.00,1.01) 584ns × (0.99,1.03) +1.83%
BenchmarkFmtFprintfFloat 749ns × (1.00,1.00) 739ns × (0.99,1.00) -1.34%
BenchmarkFmtManyArgs 2.94µs × (1.00,1.01) 2.77µs × (1.00,1.00) -5.76%
BenchmarkGobDecode 39.5ms × (0.99,1.01) 39.3ms × (0.99,1.01) ~
BenchmarkGobEncode 39.4ms × (1.00,1.01) 39.4ms × (0.99,1.00) ~
BenchmarkGzip 658ms × (1.00,1.01) 661ms × (0.99,1.01) ~
BenchmarkGunzip 142ms × (1.00,1.00) 142ms × (1.00,1.00) +0.22%
BenchmarkHTTPClientServer 134µs × (0.99,1.01) 133µs × (0.98,1.01) ~
BenchmarkJSONEncode 57.1ms × (0.99,1.01) 56.5ms × (0.99,1.01) ~
BenchmarkJSONDecode 141ms × (1.00,1.00) 143ms × (1.00,1.00) +1.09%
BenchmarkMandelbrot200 6.01ms × (1.00,1.00) 6.01ms × (1.00,1.00) ~
BenchmarkGoParse 10.1ms × (0.91,1.09) 9.6ms × (0.94,1.07) ~
BenchmarkRegexpMatchEasy0_32 207ns × (1.00,1.01) 210ns × (1.00,1.00) +1.45%
BenchmarkRegexpMatchEasy0_1K 592ns × (0.99,1.00) 596ns × (0.99,1.01) +0.68%
BenchmarkRegexpMatchEasy1_32 184ns × (0.99,1.01) 184ns × (0.99,1.01) ~
BenchmarkRegexpMatchEasy1_1K 1.01µs × (1.00,1.00) 1.01µs × (0.99,1.01) ~
BenchmarkRegexpMatchMedium_32 327ns × (0.99,1.00) 327ns × (1.00,1.01) ~
BenchmarkRegexpMatchMedium_1K 92.5µs × (1.00,1.00) 93.0µs × (1.00,1.02) +0.48%
BenchmarkRegexpMatchHard_32 4.79µs × (0.95,1.00) 4.76µs × (0.95,1.01) ~
BenchmarkRegexpMatchHard_1K 136µs × (1.00,1.00) 136µs × (1.00,1.01) ~
BenchmarkRevcomp 900ms × (0.99,1.01) 892ms × (1.00,1.01) ~
BenchmarkTemplate 170ms × (0.99,1.01) 175ms × (0.99,1.00) +2.95%
BenchmarkTimeParse 645ns × (1.00,1.00) 638ns × (1.00,1.00) -1.16%
BenchmarkTimeFormat 740ns × (1.00,1.00) 772ns × (1.00,1.00) +4.39%
Change-Id: I0be905e32791e0cb70ff01f169c4b309a971d981
Reviewed-on: https://go-review.googlesource.com/9159
Reviewed-by: Rick Hudson <rlh@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-04-17 00:25:10 -04:00
|
|
|
// Must call emitVardef after evaluating rhs but before writing to lhs.
|
2015-04-16 16:22:30 -04:00
|
|
|
emitVardef := func() {
|
|
|
|
|
// Emit vardef if needed.
|
|
|
|
|
if nl.Op == ONAME {
|
|
|
|
|
switch nl.Type.Etype {
|
|
|
|
|
case TARRAY, TSTRING, TINTER, TSTRUCT:
|
|
|
|
|
Gvardef(nl)
|
|
|
|
|
}
|
2015-03-18 12:29:40 -04:00
|
|
|
}
|
2015-04-16 16:22:30 -04:00
|
|
|
}
|
|
|
|
|
|
cmd/internal/gc: emit write barriers at lower level
This is primarily preparation for inlining, not an optimization by itself,
but it still helps some.
name old new delta
BenchmarkBinaryTree17 18.2s × (0.99,1.01) 17.9s × (0.99,1.01) -1.57%
BenchmarkFannkuch11 4.44s × (1.00,1.00) 4.42s × (1.00,1.00) -0.40%
BenchmarkFmtFprintfEmpty 119ns × (0.95,1.02) 118ns × (0.96,1.02) ~
BenchmarkFmtFprintfString 501ns × (0.99,1.02) 486ns × (0.99,1.01) -2.89%
BenchmarkFmtFprintfInt 474ns × (0.99,1.00) 457ns × (0.99,1.01) -3.59%
BenchmarkFmtFprintfIntInt 792ns × (1.00,1.00) 768ns × (1.00,1.01) -3.03%
BenchmarkFmtFprintfPrefixedInt 574ns × (1.00,1.01) 584ns × (0.99,1.03) +1.83%
BenchmarkFmtFprintfFloat 749ns × (1.00,1.00) 739ns × (0.99,1.00) -1.34%
BenchmarkFmtManyArgs 2.94µs × (1.00,1.01) 2.77µs × (1.00,1.00) -5.76%
BenchmarkGobDecode 39.5ms × (0.99,1.01) 39.3ms × (0.99,1.01) ~
BenchmarkGobEncode 39.4ms × (1.00,1.01) 39.4ms × (0.99,1.00) ~
BenchmarkGzip 658ms × (1.00,1.01) 661ms × (0.99,1.01) ~
BenchmarkGunzip 142ms × (1.00,1.00) 142ms × (1.00,1.00) +0.22%
BenchmarkHTTPClientServer 134µs × (0.99,1.01) 133µs × (0.98,1.01) ~
BenchmarkJSONEncode 57.1ms × (0.99,1.01) 56.5ms × (0.99,1.01) ~
BenchmarkJSONDecode 141ms × (1.00,1.00) 143ms × (1.00,1.00) +1.09%
BenchmarkMandelbrot200 6.01ms × (1.00,1.00) 6.01ms × (1.00,1.00) ~
BenchmarkGoParse 10.1ms × (0.91,1.09) 9.6ms × (0.94,1.07) ~
BenchmarkRegexpMatchEasy0_32 207ns × (1.00,1.01) 210ns × (1.00,1.00) +1.45%
BenchmarkRegexpMatchEasy0_1K 592ns × (0.99,1.00) 596ns × (0.99,1.01) +0.68%
BenchmarkRegexpMatchEasy1_32 184ns × (0.99,1.01) 184ns × (0.99,1.01) ~
BenchmarkRegexpMatchEasy1_1K 1.01µs × (1.00,1.00) 1.01µs × (0.99,1.01) ~
BenchmarkRegexpMatchMedium_32 327ns × (0.99,1.00) 327ns × (1.00,1.01) ~
BenchmarkRegexpMatchMedium_1K 92.5µs × (1.00,1.00) 93.0µs × (1.00,1.02) +0.48%
BenchmarkRegexpMatchHard_32 4.79µs × (0.95,1.00) 4.76µs × (0.95,1.01) ~
BenchmarkRegexpMatchHard_1K 136µs × (1.00,1.00) 136µs × (1.00,1.01) ~
BenchmarkRevcomp 900ms × (0.99,1.01) 892ms × (1.00,1.01) ~
BenchmarkTemplate 170ms × (0.99,1.01) 175ms × (0.99,1.00) +2.95%
BenchmarkTimeParse 645ns × (1.00,1.00) 638ns × (1.00,1.00) -1.16%
BenchmarkTimeFormat 740ns × (1.00,1.00) 772ns × (1.00,1.00) +4.39%
Change-Id: I0be905e32791e0cb70ff01f169c4b309a971d981
Reviewed-on: https://go-review.googlesource.com/9159
Reviewed-by: Rick Hudson <rlh@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-04-17 00:25:10 -04:00
|
|
|
isConstString := Isconst(nr, CTSTR)
|
|
|
|
|
|
|
|
|
|
if !cadable(nl) && nr != nil && !cadable(nr) && !isConstString {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var nodl Node
|
|
|
|
|
if cadable(nl) {
|
|
|
|
|
nodl = *nl
|
|
|
|
|
} else {
|
|
|
|
|
if nr != nil && !cadable(nr) && !isConstString {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
if nr == nil || isConstString || nl.Ullman >= nr.Ullman {
|
|
|
|
|
Igen(nl, &nodl, nil)
|
|
|
|
|
defer Regfree(&nodl)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
lbase := nodl.Xoffset
|
|
|
|
|
|
2015-04-16 16:22:30 -04:00
|
|
|
// Special case: zeroing.
|
|
|
|
|
var nodr Node
|
|
|
|
|
if nr == nil {
|
2015-03-18 12:29:40 -04:00
|
|
|
// When zeroing, prepare a register containing zero.
|
2015-04-16 16:22:30 -04:00
|
|
|
// TODO(rsc): Check that this is actually generating the best code.
|
2015-04-09 21:25:48 +10:00
|
|
|
if Thearch.REGZERO != 0 {
|
|
|
|
|
// cpu has a dedicated zero register
|
|
|
|
|
Nodreg(&nodr, Types[TUINT], Thearch.REGZERO)
|
|
|
|
|
} else {
|
|
|
|
|
// no dedicated zero register
|
2015-04-16 16:22:30 -04:00
|
|
|
var zero Node
|
|
|
|
|
Nodconst(&zero, nl.Type, 0)
|
2015-04-09 21:25:48 +10:00
|
|
|
Regalloc(&nodr, Types[TUINT], nil)
|
2015-04-16 16:22:30 -04:00
|
|
|
Thearch.Gmove(&zero, &nodr)
|
2015-04-09 21:25:48 +10:00
|
|
|
defer Regfree(&nodr)
|
|
|
|
|
}
|
2015-03-18 12:29:40 -04:00
|
|
|
|
2015-04-16 16:22:30 -04:00
|
|
|
emitVardef()
|
|
|
|
|
visitComponents(nl.Type, 0, func(t *Type, offset int64) bool {
|
|
|
|
|
nodl.Type = t
|
|
|
|
|
nodl.Xoffset = lbase + offset
|
|
|
|
|
nodr.Type = t
|
|
|
|
|
if Isfloat[t.Etype] {
|
|
|
|
|
// TODO(rsc): Cache zero register like we do for integers?
|
|
|
|
|
Clearslim(&nodl)
|
|
|
|
|
} else {
|
|
|
|
|
Thearch.Gmove(&nodr, &nodl)
|
2015-03-18 12:29:40 -04:00
|
|
|
}
|
2015-04-09 20:10:16 +10:00
|
|
|
return true
|
2015-04-16 16:22:30 -04:00
|
|
|
})
|
|
|
|
|
return true
|
|
|
|
|
}
|
2015-03-18 12:29:40 -04:00
|
|
|
|
2015-04-16 16:22:30 -04:00
|
|
|
// Special case: assignment of string constant.
|
|
|
|
|
if isConstString {
|
|
|
|
|
emitVardef()
|
2015-03-18 12:29:40 -04:00
|
|
|
|
2015-04-16 16:22:30 -04:00
|
|
|
// base
|
|
|
|
|
nodl.Type = Ptrto(Types[TUINT8])
|
|
|
|
|
Regalloc(&nodr, Types[Tptr], nil)
|
|
|
|
|
p := Thearch.Gins(Thearch.Optoas(OAS, Types[Tptr]), nil, &nodr)
|
2015-05-14 17:57:42 -07:00
|
|
|
Datastring(nr.Val.U.(string), &p.From)
|
2015-04-16 16:22:30 -04:00
|
|
|
p.From.Type = obj.TYPE_ADDR
|
2015-03-18 12:29:40 -04:00
|
|
|
Thearch.Gmove(&nodr, &nodl)
|
2015-04-16 16:22:30 -04:00
|
|
|
Regfree(&nodr)
|
2015-03-18 12:29:40 -04:00
|
|
|
|
2015-04-16 16:22:30 -04:00
|
|
|
// length
|
2015-03-18 12:29:40 -04:00
|
|
|
nodl.Type = Types[Simtype[TUINT]]
|
2015-04-16 16:22:30 -04:00
|
|
|
nodl.Xoffset += int64(Array_nel) - int64(Array_array)
|
2015-05-14 17:57:42 -07:00
|
|
|
Nodconst(&nodr, nodl.Type, int64(len(nr.Val.U.(string))))
|
2015-03-18 12:29:40 -04:00
|
|
|
Thearch.Gmove(&nodr, &nodl)
|
2015-04-16 16:22:30 -04:00
|
|
|
return true
|
|
|
|
|
}
|
2015-03-18 12:29:40 -04:00
|
|
|
|
2015-04-16 16:22:30 -04:00
|
|
|
// General case: copy nl = nr.
|
|
|
|
|
nodr = *nr
|
|
|
|
|
if !cadable(nr) {
|
cmd/internal/gc: emit write barriers at lower level
This is primarily preparation for inlining, not an optimization by itself,
but it still helps some.
name old new delta
BenchmarkBinaryTree17 18.2s × (0.99,1.01) 17.9s × (0.99,1.01) -1.57%
BenchmarkFannkuch11 4.44s × (1.00,1.00) 4.42s × (1.00,1.00) -0.40%
BenchmarkFmtFprintfEmpty 119ns × (0.95,1.02) 118ns × (0.96,1.02) ~
BenchmarkFmtFprintfString 501ns × (0.99,1.02) 486ns × (0.99,1.01) -2.89%
BenchmarkFmtFprintfInt 474ns × (0.99,1.00) 457ns × (0.99,1.01) -3.59%
BenchmarkFmtFprintfIntInt 792ns × (1.00,1.00) 768ns × (1.00,1.01) -3.03%
BenchmarkFmtFprintfPrefixedInt 574ns × (1.00,1.01) 584ns × (0.99,1.03) +1.83%
BenchmarkFmtFprintfFloat 749ns × (1.00,1.00) 739ns × (0.99,1.00) -1.34%
BenchmarkFmtManyArgs 2.94µs × (1.00,1.01) 2.77µs × (1.00,1.00) -5.76%
BenchmarkGobDecode 39.5ms × (0.99,1.01) 39.3ms × (0.99,1.01) ~
BenchmarkGobEncode 39.4ms × (1.00,1.01) 39.4ms × (0.99,1.00) ~
BenchmarkGzip 658ms × (1.00,1.01) 661ms × (0.99,1.01) ~
BenchmarkGunzip 142ms × (1.00,1.00) 142ms × (1.00,1.00) +0.22%
BenchmarkHTTPClientServer 134µs × (0.99,1.01) 133µs × (0.98,1.01) ~
BenchmarkJSONEncode 57.1ms × (0.99,1.01) 56.5ms × (0.99,1.01) ~
BenchmarkJSONDecode 141ms × (1.00,1.00) 143ms × (1.00,1.00) +1.09%
BenchmarkMandelbrot200 6.01ms × (1.00,1.00) 6.01ms × (1.00,1.00) ~
BenchmarkGoParse 10.1ms × (0.91,1.09) 9.6ms × (0.94,1.07) ~
BenchmarkRegexpMatchEasy0_32 207ns × (1.00,1.01) 210ns × (1.00,1.00) +1.45%
BenchmarkRegexpMatchEasy0_1K 592ns × (0.99,1.00) 596ns × (0.99,1.01) +0.68%
BenchmarkRegexpMatchEasy1_32 184ns × (0.99,1.01) 184ns × (0.99,1.01) ~
BenchmarkRegexpMatchEasy1_1K 1.01µs × (1.00,1.00) 1.01µs × (0.99,1.01) ~
BenchmarkRegexpMatchMedium_32 327ns × (0.99,1.00) 327ns × (1.00,1.01) ~
BenchmarkRegexpMatchMedium_1K 92.5µs × (1.00,1.00) 93.0µs × (1.00,1.02) +0.48%
BenchmarkRegexpMatchHard_32 4.79µs × (0.95,1.00) 4.76µs × (0.95,1.01) ~
BenchmarkRegexpMatchHard_1K 136µs × (1.00,1.00) 136µs × (1.00,1.01) ~
BenchmarkRevcomp 900ms × (0.99,1.01) 892ms × (1.00,1.01) ~
BenchmarkTemplate 170ms × (0.99,1.01) 175ms × (0.99,1.00) +2.95%
BenchmarkTimeParse 645ns × (1.00,1.00) 638ns × (1.00,1.00) -1.16%
BenchmarkTimeFormat 740ns × (1.00,1.00) 772ns × (1.00,1.00) +4.39%
Change-Id: I0be905e32791e0cb70ff01f169c4b309a971d981
Reviewed-on: https://go-review.googlesource.com/9159
Reviewed-by: Rick Hudson <rlh@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-04-17 00:25:10 -04:00
|
|
|
if nr.Ullman >= UINF && nodl.Op == OINDREG {
|
|
|
|
|
Fatal("miscompile")
|
|
|
|
|
}
|
2015-04-16 16:22:30 -04:00
|
|
|
Igen(nr, &nodr, nil)
|
|
|
|
|
defer Regfree(&nodr)
|
|
|
|
|
}
|
|
|
|
|
rbase := nodr.Xoffset
|
|
|
|
|
|
cmd/internal/gc: emit write barriers at lower level
This is primarily preparation for inlining, not an optimization by itself,
but it still helps some.
name old new delta
BenchmarkBinaryTree17 18.2s × (0.99,1.01) 17.9s × (0.99,1.01) -1.57%
BenchmarkFannkuch11 4.44s × (1.00,1.00) 4.42s × (1.00,1.00) -0.40%
BenchmarkFmtFprintfEmpty 119ns × (0.95,1.02) 118ns × (0.96,1.02) ~
BenchmarkFmtFprintfString 501ns × (0.99,1.02) 486ns × (0.99,1.01) -2.89%
BenchmarkFmtFprintfInt 474ns × (0.99,1.00) 457ns × (0.99,1.01) -3.59%
BenchmarkFmtFprintfIntInt 792ns × (1.00,1.00) 768ns × (1.00,1.01) -3.03%
BenchmarkFmtFprintfPrefixedInt 574ns × (1.00,1.01) 584ns × (0.99,1.03) +1.83%
BenchmarkFmtFprintfFloat 749ns × (1.00,1.00) 739ns × (0.99,1.00) -1.34%
BenchmarkFmtManyArgs 2.94µs × (1.00,1.01) 2.77µs × (1.00,1.00) -5.76%
BenchmarkGobDecode 39.5ms × (0.99,1.01) 39.3ms × (0.99,1.01) ~
BenchmarkGobEncode 39.4ms × (1.00,1.01) 39.4ms × (0.99,1.00) ~
BenchmarkGzip 658ms × (1.00,1.01) 661ms × (0.99,1.01) ~
BenchmarkGunzip 142ms × (1.00,1.00) 142ms × (1.00,1.00) +0.22%
BenchmarkHTTPClientServer 134µs × (0.99,1.01) 133µs × (0.98,1.01) ~
BenchmarkJSONEncode 57.1ms × (0.99,1.01) 56.5ms × (0.99,1.01) ~
BenchmarkJSONDecode 141ms × (1.00,1.00) 143ms × (1.00,1.00) +1.09%
BenchmarkMandelbrot200 6.01ms × (1.00,1.00) 6.01ms × (1.00,1.00) ~
BenchmarkGoParse 10.1ms × (0.91,1.09) 9.6ms × (0.94,1.07) ~
BenchmarkRegexpMatchEasy0_32 207ns × (1.00,1.01) 210ns × (1.00,1.00) +1.45%
BenchmarkRegexpMatchEasy0_1K 592ns × (0.99,1.00) 596ns × (0.99,1.01) +0.68%
BenchmarkRegexpMatchEasy1_32 184ns × (0.99,1.01) 184ns × (0.99,1.01) ~
BenchmarkRegexpMatchEasy1_1K 1.01µs × (1.00,1.00) 1.01µs × (0.99,1.01) ~
BenchmarkRegexpMatchMedium_32 327ns × (0.99,1.00) 327ns × (1.00,1.01) ~
BenchmarkRegexpMatchMedium_1K 92.5µs × (1.00,1.00) 93.0µs × (1.00,1.02) +0.48%
BenchmarkRegexpMatchHard_32 4.79µs × (0.95,1.00) 4.76µs × (0.95,1.01) ~
BenchmarkRegexpMatchHard_1K 136µs × (1.00,1.00) 136µs × (1.00,1.01) ~
BenchmarkRevcomp 900ms × (0.99,1.01) 892ms × (1.00,1.01) ~
BenchmarkTemplate 170ms × (0.99,1.01) 175ms × (0.99,1.00) +2.95%
BenchmarkTimeParse 645ns × (1.00,1.00) 638ns × (1.00,1.00) -1.16%
BenchmarkTimeFormat 740ns × (1.00,1.00) 772ns × (1.00,1.00) +4.39%
Change-Id: I0be905e32791e0cb70ff01f169c4b309a971d981
Reviewed-on: https://go-review.googlesource.com/9159
Reviewed-by: Rick Hudson <rlh@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-04-17 00:25:10 -04:00
|
|
|
if nodl.Op == 0 {
|
|
|
|
|
Igen(nl, &nodl, nil)
|
|
|
|
|
defer Regfree(&nodl)
|
|
|
|
|
lbase = nodl.Xoffset
|
2015-04-16 16:22:30 -04:00
|
|
|
}
|
2015-03-18 12:29:40 -04:00
|
|
|
|
2015-04-16 16:22:30 -04:00
|
|
|
emitVardef()
|
cmd/internal/gc: emit write barriers at lower level
This is primarily preparation for inlining, not an optimization by itself,
but it still helps some.
name old new delta
BenchmarkBinaryTree17 18.2s × (0.99,1.01) 17.9s × (0.99,1.01) -1.57%
BenchmarkFannkuch11 4.44s × (1.00,1.00) 4.42s × (1.00,1.00) -0.40%
BenchmarkFmtFprintfEmpty 119ns × (0.95,1.02) 118ns × (0.96,1.02) ~
BenchmarkFmtFprintfString 501ns × (0.99,1.02) 486ns × (0.99,1.01) -2.89%
BenchmarkFmtFprintfInt 474ns × (0.99,1.00) 457ns × (0.99,1.01) -3.59%
BenchmarkFmtFprintfIntInt 792ns × (1.00,1.00) 768ns × (1.00,1.01) -3.03%
BenchmarkFmtFprintfPrefixedInt 574ns × (1.00,1.01) 584ns × (0.99,1.03) +1.83%
BenchmarkFmtFprintfFloat 749ns × (1.00,1.00) 739ns × (0.99,1.00) -1.34%
BenchmarkFmtManyArgs 2.94µs × (1.00,1.01) 2.77µs × (1.00,1.00) -5.76%
BenchmarkGobDecode 39.5ms × (0.99,1.01) 39.3ms × (0.99,1.01) ~
BenchmarkGobEncode 39.4ms × (1.00,1.01) 39.4ms × (0.99,1.00) ~
BenchmarkGzip 658ms × (1.00,1.01) 661ms × (0.99,1.01) ~
BenchmarkGunzip 142ms × (1.00,1.00) 142ms × (1.00,1.00) +0.22%
BenchmarkHTTPClientServer 134µs × (0.99,1.01) 133µs × (0.98,1.01) ~
BenchmarkJSONEncode 57.1ms × (0.99,1.01) 56.5ms × (0.99,1.01) ~
BenchmarkJSONDecode 141ms × (1.00,1.00) 143ms × (1.00,1.00) +1.09%
BenchmarkMandelbrot200 6.01ms × (1.00,1.00) 6.01ms × (1.00,1.00) ~
BenchmarkGoParse 10.1ms × (0.91,1.09) 9.6ms × (0.94,1.07) ~
BenchmarkRegexpMatchEasy0_32 207ns × (1.00,1.01) 210ns × (1.00,1.00) +1.45%
BenchmarkRegexpMatchEasy0_1K 592ns × (0.99,1.00) 596ns × (0.99,1.01) +0.68%
BenchmarkRegexpMatchEasy1_32 184ns × (0.99,1.01) 184ns × (0.99,1.01) ~
BenchmarkRegexpMatchEasy1_1K 1.01µs × (1.00,1.00) 1.01µs × (0.99,1.01) ~
BenchmarkRegexpMatchMedium_32 327ns × (0.99,1.00) 327ns × (1.00,1.01) ~
BenchmarkRegexpMatchMedium_1K 92.5µs × (1.00,1.00) 93.0µs × (1.00,1.02) +0.48%
BenchmarkRegexpMatchHard_32 4.79µs × (0.95,1.00) 4.76µs × (0.95,1.01) ~
BenchmarkRegexpMatchHard_1K 136µs × (1.00,1.00) 136µs × (1.00,1.01) ~
BenchmarkRevcomp 900ms × (0.99,1.01) 892ms × (1.00,1.01) ~
BenchmarkTemplate 170ms × (0.99,1.01) 175ms × (0.99,1.00) +2.95%
BenchmarkTimeParse 645ns × (1.00,1.00) 638ns × (1.00,1.00) -1.16%
BenchmarkTimeFormat 740ns × (1.00,1.00) 772ns × (1.00,1.00) +4.39%
Change-Id: I0be905e32791e0cb70ff01f169c4b309a971d981
Reviewed-on: https://go-review.googlesource.com/9159
Reviewed-by: Rick Hudson <rlh@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-04-17 00:25:10 -04:00
|
|
|
var (
|
|
|
|
|
ptrType *Type
|
|
|
|
|
ptrOffset int64
|
|
|
|
|
)
|
2015-04-16 16:22:30 -04:00
|
|
|
visitComponents(nl.Type, 0, func(t *Type, offset int64) bool {
|
cmd/internal/gc: emit write barriers at lower level
This is primarily preparation for inlining, not an optimization by itself,
but it still helps some.
name old new delta
BenchmarkBinaryTree17 18.2s × (0.99,1.01) 17.9s × (0.99,1.01) -1.57%
BenchmarkFannkuch11 4.44s × (1.00,1.00) 4.42s × (1.00,1.00) -0.40%
BenchmarkFmtFprintfEmpty 119ns × (0.95,1.02) 118ns × (0.96,1.02) ~
BenchmarkFmtFprintfString 501ns × (0.99,1.02) 486ns × (0.99,1.01) -2.89%
BenchmarkFmtFprintfInt 474ns × (0.99,1.00) 457ns × (0.99,1.01) -3.59%
BenchmarkFmtFprintfIntInt 792ns × (1.00,1.00) 768ns × (1.00,1.01) -3.03%
BenchmarkFmtFprintfPrefixedInt 574ns × (1.00,1.01) 584ns × (0.99,1.03) +1.83%
BenchmarkFmtFprintfFloat 749ns × (1.00,1.00) 739ns × (0.99,1.00) -1.34%
BenchmarkFmtManyArgs 2.94µs × (1.00,1.01) 2.77µs × (1.00,1.00) -5.76%
BenchmarkGobDecode 39.5ms × (0.99,1.01) 39.3ms × (0.99,1.01) ~
BenchmarkGobEncode 39.4ms × (1.00,1.01) 39.4ms × (0.99,1.00) ~
BenchmarkGzip 658ms × (1.00,1.01) 661ms × (0.99,1.01) ~
BenchmarkGunzip 142ms × (1.00,1.00) 142ms × (1.00,1.00) +0.22%
BenchmarkHTTPClientServer 134µs × (0.99,1.01) 133µs × (0.98,1.01) ~
BenchmarkJSONEncode 57.1ms × (0.99,1.01) 56.5ms × (0.99,1.01) ~
BenchmarkJSONDecode 141ms × (1.00,1.00) 143ms × (1.00,1.00) +1.09%
BenchmarkMandelbrot200 6.01ms × (1.00,1.00) 6.01ms × (1.00,1.00) ~
BenchmarkGoParse 10.1ms × (0.91,1.09) 9.6ms × (0.94,1.07) ~
BenchmarkRegexpMatchEasy0_32 207ns × (1.00,1.01) 210ns × (1.00,1.00) +1.45%
BenchmarkRegexpMatchEasy0_1K 592ns × (0.99,1.00) 596ns × (0.99,1.01) +0.68%
BenchmarkRegexpMatchEasy1_32 184ns × (0.99,1.01) 184ns × (0.99,1.01) ~
BenchmarkRegexpMatchEasy1_1K 1.01µs × (1.00,1.00) 1.01µs × (0.99,1.01) ~
BenchmarkRegexpMatchMedium_32 327ns × (0.99,1.00) 327ns × (1.00,1.01) ~
BenchmarkRegexpMatchMedium_1K 92.5µs × (1.00,1.00) 93.0µs × (1.00,1.02) +0.48%
BenchmarkRegexpMatchHard_32 4.79µs × (0.95,1.00) 4.76µs × (0.95,1.01) ~
BenchmarkRegexpMatchHard_1K 136µs × (1.00,1.00) 136µs × (1.00,1.01) ~
BenchmarkRevcomp 900ms × (0.99,1.01) 892ms × (1.00,1.01) ~
BenchmarkTemplate 170ms × (0.99,1.01) 175ms × (0.99,1.00) +2.95%
BenchmarkTimeParse 645ns × (1.00,1.00) 638ns × (1.00,1.00) -1.16%
BenchmarkTimeFormat 740ns × (1.00,1.00) 772ns × (1.00,1.00) +4.39%
Change-Id: I0be905e32791e0cb70ff01f169c4b309a971d981
Reviewed-on: https://go-review.googlesource.com/9159
Reviewed-by: Rick Hudson <rlh@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-04-17 00:25:10 -04:00
|
|
|
if wb && int(Simtype[t.Etype]) == Tptr && t != itable {
|
|
|
|
|
if ptrType != nil {
|
|
|
|
|
Fatal("componentgen_wb %v", Tconv(nl.Type, 0))
|
|
|
|
|
}
|
|
|
|
|
ptrType = t
|
|
|
|
|
ptrOffset = offset
|
|
|
|
|
return true
|
|
|
|
|
}
|
2015-04-16 16:22:30 -04:00
|
|
|
nodl.Type = t
|
|
|
|
|
nodl.Xoffset = lbase + offset
|
|
|
|
|
nodr.Type = t
|
|
|
|
|
nodr.Xoffset = rbase + offset
|
2015-03-18 12:29:40 -04:00
|
|
|
Thearch.Gmove(&nodr, &nodl)
|
2015-04-09 20:10:16 +10:00
|
|
|
return true
|
2015-04-16 16:22:30 -04:00
|
|
|
})
|
cmd/internal/gc: emit write barriers at lower level
This is primarily preparation for inlining, not an optimization by itself,
but it still helps some.
name old new delta
BenchmarkBinaryTree17 18.2s × (0.99,1.01) 17.9s × (0.99,1.01) -1.57%
BenchmarkFannkuch11 4.44s × (1.00,1.00) 4.42s × (1.00,1.00) -0.40%
BenchmarkFmtFprintfEmpty 119ns × (0.95,1.02) 118ns × (0.96,1.02) ~
BenchmarkFmtFprintfString 501ns × (0.99,1.02) 486ns × (0.99,1.01) -2.89%
BenchmarkFmtFprintfInt 474ns × (0.99,1.00) 457ns × (0.99,1.01) -3.59%
BenchmarkFmtFprintfIntInt 792ns × (1.00,1.00) 768ns × (1.00,1.01) -3.03%
BenchmarkFmtFprintfPrefixedInt 574ns × (1.00,1.01) 584ns × (0.99,1.03) +1.83%
BenchmarkFmtFprintfFloat 749ns × (1.00,1.00) 739ns × (0.99,1.00) -1.34%
BenchmarkFmtManyArgs 2.94µs × (1.00,1.01) 2.77µs × (1.00,1.00) -5.76%
BenchmarkGobDecode 39.5ms × (0.99,1.01) 39.3ms × (0.99,1.01) ~
BenchmarkGobEncode 39.4ms × (1.00,1.01) 39.4ms × (0.99,1.00) ~
BenchmarkGzip 658ms × (1.00,1.01) 661ms × (0.99,1.01) ~
BenchmarkGunzip 142ms × (1.00,1.00) 142ms × (1.00,1.00) +0.22%
BenchmarkHTTPClientServer 134µs × (0.99,1.01) 133µs × (0.98,1.01) ~
BenchmarkJSONEncode 57.1ms × (0.99,1.01) 56.5ms × (0.99,1.01) ~
BenchmarkJSONDecode 141ms × (1.00,1.00) 143ms × (1.00,1.00) +1.09%
BenchmarkMandelbrot200 6.01ms × (1.00,1.00) 6.01ms × (1.00,1.00) ~
BenchmarkGoParse 10.1ms × (0.91,1.09) 9.6ms × (0.94,1.07) ~
BenchmarkRegexpMatchEasy0_32 207ns × (1.00,1.01) 210ns × (1.00,1.00) +1.45%
BenchmarkRegexpMatchEasy0_1K 592ns × (0.99,1.00) 596ns × (0.99,1.01) +0.68%
BenchmarkRegexpMatchEasy1_32 184ns × (0.99,1.01) 184ns × (0.99,1.01) ~
BenchmarkRegexpMatchEasy1_1K 1.01µs × (1.00,1.00) 1.01µs × (0.99,1.01) ~
BenchmarkRegexpMatchMedium_32 327ns × (0.99,1.00) 327ns × (1.00,1.01) ~
BenchmarkRegexpMatchMedium_1K 92.5µs × (1.00,1.00) 93.0µs × (1.00,1.02) +0.48%
BenchmarkRegexpMatchHard_32 4.79µs × (0.95,1.00) 4.76µs × (0.95,1.01) ~
BenchmarkRegexpMatchHard_1K 136µs × (1.00,1.00) 136µs × (1.00,1.01) ~
BenchmarkRevcomp 900ms × (0.99,1.01) 892ms × (1.00,1.01) ~
BenchmarkTemplate 170ms × (0.99,1.01) 175ms × (0.99,1.00) +2.95%
BenchmarkTimeParse 645ns × (1.00,1.00) 638ns × (1.00,1.00) -1.16%
BenchmarkTimeFormat 740ns × (1.00,1.00) 772ns × (1.00,1.00) +4.39%
Change-Id: I0be905e32791e0cb70ff01f169c4b309a971d981
Reviewed-on: https://go-review.googlesource.com/9159
Reviewed-by: Rick Hudson <rlh@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-04-17 00:25:10 -04:00
|
|
|
if ptrType != nil {
|
|
|
|
|
nodl.Type = ptrType
|
|
|
|
|
nodl.Xoffset = lbase + ptrOffset
|
|
|
|
|
nodr.Type = ptrType
|
|
|
|
|
nodr.Xoffset = rbase + ptrOffset
|
|
|
|
|
cgen_wbptr(&nodr, &nodl)
|
|
|
|
|
}
|
2015-04-16 16:22:30 -04:00
|
|
|
return true
|
|
|
|
|
}
|
2015-03-18 12:29:40 -04:00
|
|
|
|
2015-04-16 16:22:30 -04:00
|
|
|
// visitComponents walks the individual components of the type t,
|
|
|
|
|
// walking into array elements, struct fields, the real and imaginary
|
|
|
|
|
// parts of complex numbers, and on 32-bit systems the high and
|
|
|
|
|
// low halves of 64-bit integers.
|
|
|
|
|
// It calls f for each such component, passing the component (aka element)
|
|
|
|
|
// type and memory offset, assuming t starts at startOffset.
|
|
|
|
|
// If f ever returns false, visitComponents returns false without any more
|
|
|
|
|
// calls to f. Otherwise visitComponents returns true.
|
|
|
|
|
func visitComponents(t *Type, startOffset int64, f func(elem *Type, elemOffset int64) bool) bool {
|
|
|
|
|
switch t.Etype {
|
|
|
|
|
case TINT64:
|
|
|
|
|
if Widthreg == 8 {
|
|
|
|
|
break
|
2015-03-18 12:29:40 -04:00
|
|
|
}
|
2015-04-16 16:22:30 -04:00
|
|
|
// NOTE: Assuming little endian (signed top half at offset 4).
|
|
|
|
|
// We don't have any 32-bit big-endian systems.
|
|
|
|
|
if Thearch.Thechar != '5' && Thearch.Thechar != '8' {
|
|
|
|
|
Fatal("unknown 32-bit architecture")
|
2015-03-18 12:29:40 -04:00
|
|
|
}
|
2015-04-16 16:22:30 -04:00
|
|
|
return f(Types[TUINT32], startOffset) &&
|
|
|
|
|
f(Types[TINT32], startOffset+4)
|
2015-03-18 12:29:40 -04:00
|
|
|
|
2015-04-16 16:22:30 -04:00
|
|
|
case TUINT64:
|
|
|
|
|
if Widthreg == 8 {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
return f(Types[TUINT32], startOffset) &&
|
|
|
|
|
f(Types[TUINT32], startOffset+4)
|
2015-03-18 12:29:40 -04:00
|
|
|
|
2015-04-16 16:22:30 -04:00
|
|
|
case TCOMPLEX64:
|
|
|
|
|
return f(Types[TFLOAT32], startOffset) &&
|
|
|
|
|
f(Types[TFLOAT32], startOffset+4)
|
2015-03-18 12:29:40 -04:00
|
|
|
|
2015-04-16 16:22:30 -04:00
|
|
|
case TCOMPLEX128:
|
|
|
|
|
return f(Types[TFLOAT64], startOffset) &&
|
|
|
|
|
f(Types[TFLOAT64], startOffset+8)
|
2015-03-18 12:29:40 -04:00
|
|
|
|
2015-04-16 16:22:30 -04:00
|
|
|
case TINTER:
|
cmd/internal/gc: emit write barriers at lower level
This is primarily preparation for inlining, not an optimization by itself,
but it still helps some.
name old new delta
BenchmarkBinaryTree17 18.2s × (0.99,1.01) 17.9s × (0.99,1.01) -1.57%
BenchmarkFannkuch11 4.44s × (1.00,1.00) 4.42s × (1.00,1.00) -0.40%
BenchmarkFmtFprintfEmpty 119ns × (0.95,1.02) 118ns × (0.96,1.02) ~
BenchmarkFmtFprintfString 501ns × (0.99,1.02) 486ns × (0.99,1.01) -2.89%
BenchmarkFmtFprintfInt 474ns × (0.99,1.00) 457ns × (0.99,1.01) -3.59%
BenchmarkFmtFprintfIntInt 792ns × (1.00,1.00) 768ns × (1.00,1.01) -3.03%
BenchmarkFmtFprintfPrefixedInt 574ns × (1.00,1.01) 584ns × (0.99,1.03) +1.83%
BenchmarkFmtFprintfFloat 749ns × (1.00,1.00) 739ns × (0.99,1.00) -1.34%
BenchmarkFmtManyArgs 2.94µs × (1.00,1.01) 2.77µs × (1.00,1.00) -5.76%
BenchmarkGobDecode 39.5ms × (0.99,1.01) 39.3ms × (0.99,1.01) ~
BenchmarkGobEncode 39.4ms × (1.00,1.01) 39.4ms × (0.99,1.00) ~
BenchmarkGzip 658ms × (1.00,1.01) 661ms × (0.99,1.01) ~
BenchmarkGunzip 142ms × (1.00,1.00) 142ms × (1.00,1.00) +0.22%
BenchmarkHTTPClientServer 134µs × (0.99,1.01) 133µs × (0.98,1.01) ~
BenchmarkJSONEncode 57.1ms × (0.99,1.01) 56.5ms × (0.99,1.01) ~
BenchmarkJSONDecode 141ms × (1.00,1.00) 143ms × (1.00,1.00) +1.09%
BenchmarkMandelbrot200 6.01ms × (1.00,1.00) 6.01ms × (1.00,1.00) ~
BenchmarkGoParse 10.1ms × (0.91,1.09) 9.6ms × (0.94,1.07) ~
BenchmarkRegexpMatchEasy0_32 207ns × (1.00,1.01) 210ns × (1.00,1.00) +1.45%
BenchmarkRegexpMatchEasy0_1K 592ns × (0.99,1.00) 596ns × (0.99,1.01) +0.68%
BenchmarkRegexpMatchEasy1_32 184ns × (0.99,1.01) 184ns × (0.99,1.01) ~
BenchmarkRegexpMatchEasy1_1K 1.01µs × (1.00,1.00) 1.01µs × (0.99,1.01) ~
BenchmarkRegexpMatchMedium_32 327ns × (0.99,1.00) 327ns × (1.00,1.01) ~
BenchmarkRegexpMatchMedium_1K 92.5µs × (1.00,1.00) 93.0µs × (1.00,1.02) +0.48%
BenchmarkRegexpMatchHard_32 4.79µs × (0.95,1.00) 4.76µs × (0.95,1.01) ~
BenchmarkRegexpMatchHard_1K 136µs × (1.00,1.00) 136µs × (1.00,1.01) ~
BenchmarkRevcomp 900ms × (0.99,1.01) 892ms × (1.00,1.01) ~
BenchmarkTemplate 170ms × (0.99,1.01) 175ms × (0.99,1.00) +2.95%
BenchmarkTimeParse 645ns × (1.00,1.00) 638ns × (1.00,1.00) -1.16%
BenchmarkTimeFormat 740ns × (1.00,1.00) 772ns × (1.00,1.00) +4.39%
Change-Id: I0be905e32791e0cb70ff01f169c4b309a971d981
Reviewed-on: https://go-review.googlesource.com/9159
Reviewed-by: Rick Hudson <rlh@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-04-17 00:25:10 -04:00
|
|
|
return f(itable, startOffset) &&
|
2015-04-16 16:22:30 -04:00
|
|
|
f(Ptrto(Types[TUINT8]), startOffset+int64(Widthptr))
|
2015-04-09 20:10:16 +10:00
|
|
|
return true
|
2015-03-18 12:29:40 -04:00
|
|
|
|
2015-04-16 16:22:30 -04:00
|
|
|
case TSTRING:
|
|
|
|
|
return f(Ptrto(Types[TUINT8]), startOffset) &&
|
|
|
|
|
f(Types[Simtype[TUINT]], startOffset+int64(Widthptr))
|
2015-03-18 12:29:40 -04:00
|
|
|
|
2015-04-16 16:22:30 -04:00
|
|
|
case TARRAY:
|
|
|
|
|
if Isslice(t) {
|
|
|
|
|
return f(Ptrto(t.Type), startOffset+int64(Array_array)) &&
|
|
|
|
|
f(Types[Simtype[TUINT]], startOffset+int64(Array_nel)) &&
|
|
|
|
|
f(Types[Simtype[TUINT]], startOffset+int64(Array_cap))
|
2015-03-18 12:29:40 -04:00
|
|
|
}
|
|
|
|
|
|
2015-04-16 16:22:30 -04:00
|
|
|
// Short-circuit [1e6]struct{}.
|
|
|
|
|
if t.Type.Width == 0 {
|
|
|
|
|
return true
|
2015-03-18 12:29:40 -04:00
|
|
|
}
|
|
|
|
|
|
2015-04-16 16:22:30 -04:00
|
|
|
for i := int64(0); i < t.Bound; i++ {
|
|
|
|
|
if !visitComponents(t.Type, startOffset+i*t.Type.Width, f) {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-04-09 20:10:16 +10:00
|
|
|
return true
|
2015-03-18 12:29:40 -04:00
|
|
|
|
|
|
|
|
case TSTRUCT:
|
2015-04-16 16:22:30 -04:00
|
|
|
if t.Type != nil && t.Type.Width != 0 {
|
|
|
|
|
// NOTE(rsc): If this happens, the right thing to do is to say
|
|
|
|
|
// startOffset -= t.Type.Width
|
|
|
|
|
// but I want to see if it does.
|
|
|
|
|
// The old version of componentgen handled this,
|
|
|
|
|
// in code introduced in CL 6932045 to fix issue #4518.
|
|
|
|
|
// But the test case in issue 4518 does not trigger this anymore,
|
|
|
|
|
// so maybe this complication is no longer needed.
|
|
|
|
|
Fatal("struct not at offset 0")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for field := t.Type; field != nil; field = field.Down {
|
|
|
|
|
if field.Etype != TFIELD {
|
|
|
|
|
Fatal("bad struct")
|
|
|
|
|
}
|
|
|
|
|
if !visitComponents(field.Type, startOffset+field.Width, f) {
|
|
|
|
|
return false
|
2015-03-18 12:29:40 -04:00
|
|
|
}
|
|
|
|
|
}
|
2015-04-09 20:10:16 +10:00
|
|
|
return true
|
2015-03-18 12:29:40 -04:00
|
|
|
}
|
2015-04-16 16:22:30 -04:00
|
|
|
return f(t, startOffset)
|
2015-03-18 12:29:40 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func cadable(n *Node) bool {
|
2015-04-16 16:22:30 -04:00
|
|
|
// Note: Not sure why you can have n.Op == ONAME without n.Addable, but you can.
|
|
|
|
|
return n.Addable && n.Op == ONAME
|
2015-03-18 12:29:40 -04:00
|
|
|
}
|