2015-01-19 14:34:58 -05:00
|
|
|
// Inferno utils/6l/pass.c
|
2020-06-03 13:17:17 +02:00
|
|
|
// https://bitbucket.org/inferno-os/inferno-os/src/master/utils/6l/pass.c
|
2015-01-19 14:34:58 -05:00
|
|
|
//
|
|
|
|
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
|
|
|
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
|
|
|
|
// Portions Copyright © 1997-1999 Vita Nuova Limited
|
|
|
|
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
|
|
|
|
// Portions Copyright © 2004,2006 Bruce Ellis
|
|
|
|
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
|
|
|
|
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
|
2016-04-10 14:32:26 -07:00
|
|
|
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
2015-01-19 14:34:58 -05:00
|
|
|
//
|
|
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
// of this software and associated documentation files (the "Software"), to deal
|
|
|
|
// in the Software without restriction, including without limitation the rights
|
|
|
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
// copies of the Software, and to permit persons to whom the Software is
|
|
|
|
// furnished to do so, subject to the following conditions:
|
|
|
|
//
|
|
|
|
// The above copyright notice and this permission notice shall be included in
|
|
|
|
// all copies or substantial portions of the Software.
|
|
|
|
//
|
|
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
|
// THE SOFTWARE.
|
|
|
|
|
|
|
|
package x86
|
|
|
|
|
|
|
|
import (
|
|
|
|
"cmd/internal/obj"
|
2017-04-18 12:53:25 -07:00
|
|
|
"cmd/internal/objabi"
|
2018-04-30 23:52:14 -04:00
|
|
|
"cmd/internal/src"
|
2016-04-06 12:01:40 -07:00
|
|
|
"cmd/internal/sys"
|
2015-01-19 14:34:58 -05:00
|
|
|
"math"
|
[dev.ssa] cmd/compile: fix PIC for SSA-generated code
Access to globals requires a 2-instruction sequence on PIC 386.
MOVL foo(SB), AX
is translated by the obj package into:
CALL getPCofNextInstructionInTempRegister(SB)
MOVL (&foo-&thisInstruction)(tmpReg), AX
The call returns the PC of the next instruction in a register.
The next instruction then offsets from that register to get the
address required. The tricky part is the allocation of the
temp register. The legacy compiler always used CX, and forbid
the register allocator from allocating CX when in PIC mode.
We can't easily do that in SSA because CX is actually a required
register for shift instructions. (I think the old backend got away
with this because the register allocator never uses CX, only
codegen knows that shifts must use CX.)
Instead, we allow the temp register to be anything. When the
destination of the MOV (or LEA) is an integer register, we can
use that register. Otherwise, we make sure to compile the
operation using an LEA to reference the global. So
MOVL AX, foo(SB)
is never generated directly. Instead, SSA generates:
LEAL foo(SB), DX
MOVL AX, (DX)
which is then rewritten by the obj package to:
CALL getPcInDX(SB)
LEAL (&foo-&thisInstruction)(DX), AX
MOVL AX, (DX)
So this CL modifies the obj package to use different thunks
to materialize the pc into different registers. We use the
registers that regalloc chose so that SSA can still allocate
the full set of registers.
Change-Id: Ie095644f7164a026c62e95baf9d18a8bcaed0bba
Reviewed-on: https://go-review.googlesource.com/25442
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
2016-08-03 13:00:49 -07:00
|
|
|
"strings"
|
2015-01-19 14:34:58 -05:00
|
|
|
)
|
|
|
|
|
2015-08-12 11:22:16 -07:00
|
|
|
func CanUse1InsnTLS(ctxt *obj.Link) bool {
|
2015-10-16 14:04:29 -04:00
|
|
|
if isAndroid {
|
2019-03-28 13:11:53 +01:00
|
|
|
// Android uses a global variable for the tls offset.
|
|
|
|
return false
|
2015-10-16 14:04:29 -04:00
|
|
|
}
|
|
|
|
|
2017-03-26 08:05:40 -07:00
|
|
|
if ctxt.Arch.Family == sys.I386 {
|
cmd/internal/obj/x86: take over i386 duty, clean up PINSRQ, CMPSD
Make cmd/internal/obj/x86 support 32-bit mode and use
instead of cmd/internal/obj/i386. Delete cmd/internal/obj/i386.
Clean up encoding of PINSRQ, CMPSD to use explicit third arg
instead of jamming it into an unused slot of a different arg.
Also fix bug in old6a, which declared the wrong grammar.
The accepted (and encoded) arguments to CMPSD etc are mem,reg not reg,mem.
Code that did try to use mem,reg before would be rejected by liblink,
so only reg,reg ever worked, so existing code is not affected.
After this change, code can use mem,reg successfully.
The real bug here is that the encoding tables inverted the argument
order, making the comparisons all backward from what they say on the page.
It's too late to swap them, though: people have already written code that
expects the inverted comparisons (like in package math, and likely externally).
The best we can do is make the argument that should and can take a
memory operand accept it.
Bit-for-bit compatibility checked against tree without this CL.
Change-Id: Ife5685bc98c95001f64407f35066b34b4dae11c1
Reviewed-on: https://go-review.googlesource.com/6810
Reviewed-by: Rob Pike <r@golang.org>
2015-03-04 15:46:52 -05:00
|
|
|
switch ctxt.Headtype {
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.Hlinux,
|
|
|
|
objabi.Hplan9,
|
|
|
|
objabi.Hwindows:
|
cmd/internal/obj/x86: take over i386 duty, clean up PINSRQ, CMPSD
Make cmd/internal/obj/x86 support 32-bit mode and use
instead of cmd/internal/obj/i386. Delete cmd/internal/obj/i386.
Clean up encoding of PINSRQ, CMPSD to use explicit third arg
instead of jamming it into an unused slot of a different arg.
Also fix bug in old6a, which declared the wrong grammar.
The accepted (and encoded) arguments to CMPSD etc are mem,reg not reg,mem.
Code that did try to use mem,reg before would be rejected by liblink,
so only reg,reg ever worked, so existing code is not affected.
After this change, code can use mem,reg successfully.
The real bug here is that the encoding tables inverted the argument
order, making the comparisons all backward from what they say on the page.
It's too late to swap them, though: people have already written code that
expects the inverted comparisons (like in package math, and likely externally).
The best we can do is make the argument that should and can take a
memory operand accept it.
Bit-for-bit compatibility checked against tree without this CL.
Change-Id: Ife5685bc98c95001f64407f35066b34b4dae11c1
Reviewed-on: https://go-review.googlesource.com/6810
Reviewed-by: Rob Pike <r@golang.org>
2015-03-04 15:46:52 -05:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2015-01-19 14:34:58 -05:00
|
|
|
switch ctxt.Headtype {
|
2017-04-18 12:53:25 -07:00
|
|
|
case objabi.Hplan9, objabi.Hwindows:
|
2015-02-17 22:13:49 -05:00
|
|
|
return false
|
2018-02-13 19:00:17 -08:00
|
|
|
case objabi.Hlinux, objabi.Hfreebsd:
|
2016-04-13 18:41:59 -07:00
|
|
|
return !ctxt.Flag_shared
|
2015-01-19 14:34:58 -05:00
|
|
|
}
|
|
|
|
|
2015-02-17 22:13:49 -05:00
|
|
|
return true
|
2015-01-19 14:34:58 -05:00
|
|
|
}
|
|
|
|
|
2017-04-04 14:31:55 -07:00
|
|
|
func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
|
2015-01-19 14:34:58 -05:00
|
|
|
// Thread-local storage references use the TLS pseudo-register.
|
|
|
|
// As a register, TLS refers to the thread-local storage base, and it
|
|
|
|
// can only be loaded into another register:
|
|
|
|
//
|
|
|
|
// MOVQ TLS, AX
|
|
|
|
//
|
|
|
|
// An offset from the thread-local storage base is written off(reg)(TLS*1).
|
|
|
|
// Semantically it is off(reg), but the (TLS*1) annotation marks this as
|
|
|
|
// indexing from the loaded TLS base. This emits a relocation so that
|
|
|
|
// if the linker needs to adjust the offset, it can. For example:
|
|
|
|
//
|
|
|
|
// MOVQ TLS, AX
|
2015-04-23 21:53:48 +12:00
|
|
|
// MOVQ 0(AX)(TLS*1), CX // load g into CX
|
2015-01-19 14:34:58 -05:00
|
|
|
//
|
|
|
|
// On systems that support direct access to the TLS memory, this
|
|
|
|
// pair of instructions can be reduced to a direct TLS memory reference:
|
|
|
|
//
|
2015-04-23 21:53:48 +12:00
|
|
|
// MOVQ 0(TLS), CX // load g into CX
|
2015-01-19 14:34:58 -05:00
|
|
|
//
|
2015-04-23 21:53:48 +12:00
|
|
|
// The 2-instruction and 1-instruction forms correspond to the two code
|
|
|
|
// sequences for loading a TLS variable in the local exec model given in "ELF
|
|
|
|
// Handling For Thread-Local Storage".
|
2015-01-19 14:34:58 -05:00
|
|
|
//
|
2015-04-23 21:53:48 +12:00
|
|
|
// We apply this rewrite on systems that support the 1-instruction form.
|
|
|
|
// The decision is made using only the operating system and the -shared flag,
|
|
|
|
// not the link mode. If some link modes on a particular operating system
|
|
|
|
// require the 2-instruction form, then all builds for that operating system
|
|
|
|
// will use the 2-instruction form, so that the link mode decision can be
|
|
|
|
// delayed to link time.
|
2015-01-19 14:34:58 -05:00
|
|
|
//
|
|
|
|
// In this way, all supported systems use identical instructions to
|
|
|
|
// access TLS, and they are rewritten appropriately first here in
|
|
|
|
// liblink and then finally using relocations in the linker.
|
2015-04-23 21:53:48 +12:00
|
|
|
//
|
|
|
|
// When -shared is passed, we leave the code in the 2-instruction form but
|
|
|
|
// assemble (and relocate) them in different ways to generate the initial
|
|
|
|
// exec code sequence. It's a bit of a fluke that this is possible without
|
|
|
|
// rewriting the instructions more comprehensively, and it only does because
|
|
|
|
// we only support a single TLS variable (g).
|
2015-01-19 14:34:58 -05:00
|
|
|
|
2015-08-12 11:22:16 -07:00
|
|
|
if CanUse1InsnTLS(ctxt) {
|
2015-04-23 21:53:48 +12:00
|
|
|
// Reduce 2-instruction sequence to 1-instruction sequence.
|
2015-01-19 14:34:58 -05:00
|
|
|
// Sequences like
|
|
|
|
// MOVQ TLS, BX
|
|
|
|
// ... off(BX)(TLS*1) ...
|
|
|
|
// become
|
|
|
|
// NOP
|
|
|
|
// ... off(TLS) ...
|
|
|
|
//
|
|
|
|
// TODO(rsc): Remove the Hsolaris special case. It exists only to
|
|
|
|
// guarantee we are producing byte-identical binaries as before this code.
|
|
|
|
// But it should be unnecessary.
|
2017-04-18 12:53:25 -07:00
|
|
|
if (p.As == AMOVQ || p.As == AMOVL) && p.From.Type == obj.TYPE_REG && p.From.Reg == REG_TLS && p.To.Type == obj.TYPE_REG && REG_AX <= p.To.Reg && p.To.Reg <= REG_R15 && ctxt.Headtype != objabi.Hsolaris {
|
2015-02-13 14:40:36 -05:00
|
|
|
obj.Nopout(p)
|
2015-01-19 14:34:58 -05:00
|
|
|
}
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
if p.From.Type == obj.TYPE_MEM && p.From.Index == REG_TLS && REG_AX <= p.From.Reg && p.From.Reg <= REG_R15 {
|
|
|
|
p.From.Reg = REG_TLS
|
2015-01-19 14:34:58 -05:00
|
|
|
p.From.Scale = 0
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
p.From.Index = REG_NONE
|
2015-01-19 14:34:58 -05:00
|
|
|
}
|
|
|
|
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
if p.To.Type == obj.TYPE_MEM && p.To.Index == REG_TLS && REG_AX <= p.To.Reg && p.To.Reg <= REG_R15 {
|
|
|
|
p.To.Reg = REG_TLS
|
2015-01-19 14:34:58 -05:00
|
|
|
p.To.Scale = 0
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
p.To.Index = REG_NONE
|
2015-01-19 14:34:58 -05:00
|
|
|
}
|
|
|
|
} else {
|
2015-04-23 21:53:48 +12:00
|
|
|
// load_g_cx, below, always inserts the 1-instruction sequence. Rewrite it
|
|
|
|
// as the 2-instruction sequence if necessary.
|
|
|
|
// MOVQ 0(TLS), BX
|
|
|
|
// becomes
|
2015-01-19 14:34:58 -05:00
|
|
|
// MOVQ TLS, BX
|
2015-04-23 21:53:48 +12:00
|
|
|
// MOVQ 0(BX)(TLS*1), BX
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
if (p.As == AMOVQ || p.As == AMOVL) && p.From.Type == obj.TYPE_MEM && p.From.Reg == REG_TLS && p.To.Type == obj.TYPE_REG && REG_AX <= p.To.Reg && p.To.Reg <= REG_R15 {
|
2017-04-04 14:31:55 -07:00
|
|
|
q := obj.Appendp(p, newprog)
|
2015-01-19 14:34:58 -05:00
|
|
|
q.As = p.As
|
|
|
|
q.From = p.From
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
q.From.Type = obj.TYPE_MEM
|
|
|
|
q.From.Reg = p.To.Reg
|
|
|
|
q.From.Index = REG_TLS
|
2015-01-19 14:34:58 -05:00
|
|
|
q.From.Scale = 2 // TODO: use 1
|
|
|
|
q.To = p.To
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
p.From.Type = obj.TYPE_REG
|
|
|
|
p.From.Reg = REG_TLS
|
|
|
|
p.From.Index = REG_NONE
|
2015-01-19 14:34:58 -05:00
|
|
|
p.From.Offset = 0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-28 13:11:53 +01:00
|
|
|
// Android uses a tls offset determined at runtime. Rewrite
|
|
|
|
// MOVQ TLS, BX
|
|
|
|
// to
|
|
|
|
// MOVQ runtime.tls_g(SB), BX
|
|
|
|
if isAndroid && (p.As == AMOVQ || p.As == AMOVL) && p.From.Type == obj.TYPE_REG && p.From.Reg == REG_TLS && p.To.Type == obj.TYPE_REG && REG_AX <= p.To.Reg && p.To.Reg <= REG_R15 {
|
|
|
|
p.From.Type = obj.TYPE_MEM
|
|
|
|
p.From.Name = obj.NAME_EXTERN
|
|
|
|
p.From.Reg = REG_NONE
|
|
|
|
p.From.Sym = ctxt.Lookup("runtime.tls_g")
|
|
|
|
p.From.Index = REG_NONE
|
|
|
|
}
|
|
|
|
|
2015-01-19 14:34:58 -05:00
|
|
|
// TODO: Remove.
|
2017-04-18 12:53:25 -07:00
|
|
|
if ctxt.Headtype == objabi.Hwindows && ctxt.Arch.Family == sys.AMD64 || ctxt.Headtype == objabi.Hplan9 {
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
if p.From.Scale == 1 && p.From.Index == REG_TLS {
|
2015-01-19 14:34:58 -05:00
|
|
|
p.From.Scale = 2
|
|
|
|
}
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
if p.To.Scale == 1 && p.To.Index == REG_TLS {
|
2015-01-19 14:34:58 -05:00
|
|
|
p.To.Scale = 2
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-24 11:55:20 +01:00
|
|
|
// Rewrite 0 to $0 in 3rd argument to CMPPS etc.
|
2015-03-05 00:43:21 -05:00
|
|
|
// That's what the tables expect.
|
|
|
|
switch p.As {
|
|
|
|
case ACMPPD, ACMPPS, ACMPSD, ACMPSS:
|
|
|
|
if p.To.Type == obj.TYPE_MEM && p.To.Name == obj.NAME_NONE && p.To.Reg == REG_NONE && p.To.Index == REG_NONE && p.To.Sym == nil {
|
|
|
|
p.To.Type = obj.TYPE_CONST
|
|
|
|
}
|
2015-01-19 14:34:58 -05:00
|
|
|
}
|
|
|
|
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
// Rewrite CALL/JMP/RET to symbol as TYPE_BRANCH.
|
2015-01-19 14:34:58 -05:00
|
|
|
switch p.As {
|
cmd/internal/obj/x86: take over i386 duty, clean up PINSRQ, CMPSD
Make cmd/internal/obj/x86 support 32-bit mode and use
instead of cmd/internal/obj/i386. Delete cmd/internal/obj/i386.
Clean up encoding of PINSRQ, CMPSD to use explicit third arg
instead of jamming it into an unused slot of a different arg.
Also fix bug in old6a, which declared the wrong grammar.
The accepted (and encoded) arguments to CMPSD etc are mem,reg not reg,mem.
Code that did try to use mem,reg before would be rejected by liblink,
so only reg,reg ever worked, so existing code is not affected.
After this change, code can use mem,reg successfully.
The real bug here is that the encoding tables inverted the argument
order, making the comparisons all backward from what they say on the page.
It's too late to swap them, though: people have already written code that
expects the inverted comparisons (like in package math, and likely externally).
The best we can do is make the argument that should and can take a
memory operand accept it.
Bit-for-bit compatibility checked against tree without this CL.
Change-Id: Ife5685bc98c95001f64407f35066b34b4dae11c1
Reviewed-on: https://go-review.googlesource.com/6810
Reviewed-by: Rob Pike <r@golang.org>
2015-03-04 15:46:52 -05:00
|
|
|
case obj.ACALL, obj.AJMP, obj.ARET:
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
if p.To.Type == obj.TYPE_MEM && (p.To.Name == obj.NAME_EXTERN || p.To.Name == obj.NAME_STATIC) && p.To.Sym != nil {
|
|
|
|
p.To.Type = obj.TYPE_BRANCH
|
2015-01-19 14:34:58 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-18 17:26:36 -04:00
|
|
|
// Rewrite MOVL/MOVQ $XXX(FP/SP) as LEAL/LEAQ.
|
2016-04-06 12:01:40 -07:00
|
|
|
if p.From.Type == obj.TYPE_ADDR && (ctxt.Arch.Family == sys.AMD64 || p.From.Name != obj.NAME_EXTERN && p.From.Name != obj.NAME_STATIC) {
|
2015-03-18 17:26:36 -04:00
|
|
|
switch p.As {
|
|
|
|
case AMOVL:
|
|
|
|
p.As = ALEAL
|
|
|
|
p.From.Type = obj.TYPE_MEM
|
|
|
|
case AMOVQ:
|
|
|
|
p.As = ALEAQ
|
|
|
|
p.From.Type = obj.TYPE_MEM
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-19 14:34:58 -05:00
|
|
|
// Rewrite float constants to values stored in memory.
|
|
|
|
switch p.As {
|
|
|
|
// Convert AMOVSS $(0), Xx to AXORPS Xx, Xx
|
|
|
|
case AMOVSS:
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
if p.From.Type == obj.TYPE_FCONST {
|
2015-09-01 21:25:24 -05:00
|
|
|
// f == 0 can't be used here due to -0, so use Float64bits
|
|
|
|
if f := p.From.Val.(float64); math.Float64bits(f) == 0 {
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
if p.To.Type == obj.TYPE_REG && REG_X0 <= p.To.Reg && p.To.Reg <= REG_X15 {
|
|
|
|
p.As = AXORPS
|
|
|
|
p.From = p.To
|
|
|
|
break
|
2015-01-19 14:34:58 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fallthrough
|
|
|
|
|
|
|
|
case AFMOVF,
|
|
|
|
AFADDF,
|
|
|
|
AFSUBF,
|
|
|
|
AFSUBRF,
|
|
|
|
AFMULF,
|
|
|
|
AFDIVF,
|
|
|
|
AFDIVRF,
|
|
|
|
AFCOMF,
|
|
|
|
AFCOMFP,
|
|
|
|
AADDSS,
|
|
|
|
ASUBSS,
|
|
|
|
AMULSS,
|
|
|
|
ADIVSS,
|
|
|
|
ACOMISS,
|
|
|
|
AUCOMISS:
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
if p.From.Type == obj.TYPE_FCONST {
|
2015-03-16 15:54:44 -04:00
|
|
|
f32 := float32(p.From.Val.(float64))
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
p.From.Type = obj.TYPE_MEM
|
|
|
|
p.From.Name = obj.NAME_EXTERN
|
2017-04-06 10:29:29 -07:00
|
|
|
p.From.Sym = ctxt.Float32Sym(f32)
|
2015-01-19 14:34:58 -05:00
|
|
|
p.From.Offset = 0
|
|
|
|
}
|
|
|
|
|
|
|
|
case AMOVSD:
|
cmd/internal/obj/x86: take over i386 duty, clean up PINSRQ, CMPSD
Make cmd/internal/obj/x86 support 32-bit mode and use
instead of cmd/internal/obj/i386. Delete cmd/internal/obj/i386.
Clean up encoding of PINSRQ, CMPSD to use explicit third arg
instead of jamming it into an unused slot of a different arg.
Also fix bug in old6a, which declared the wrong grammar.
The accepted (and encoded) arguments to CMPSD etc are mem,reg not reg,mem.
Code that did try to use mem,reg before would be rejected by liblink,
so only reg,reg ever worked, so existing code is not affected.
After this change, code can use mem,reg successfully.
The real bug here is that the encoding tables inverted the argument
order, making the comparisons all backward from what they say on the page.
It's too late to swap them, though: people have already written code that
expects the inverted comparisons (like in package math, and likely externally).
The best we can do is make the argument that should and can take a
memory operand accept it.
Bit-for-bit compatibility checked against tree without this CL.
Change-Id: Ife5685bc98c95001f64407f35066b34b4dae11c1
Reviewed-on: https://go-review.googlesource.com/6810
Reviewed-by: Rob Pike <r@golang.org>
2015-03-04 15:46:52 -05:00
|
|
|
// Convert AMOVSD $(0), Xx to AXORPS Xx, Xx
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
if p.From.Type == obj.TYPE_FCONST {
|
2015-09-01 21:25:24 -05:00
|
|
|
// f == 0 can't be used here due to -0, so use Float64bits
|
|
|
|
if f := p.From.Val.(float64); math.Float64bits(f) == 0 {
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
if p.To.Type == obj.TYPE_REG && REG_X0 <= p.To.Reg && p.To.Reg <= REG_X15 {
|
|
|
|
p.As = AXORPS
|
|
|
|
p.From = p.To
|
|
|
|
break
|
2015-01-19 14:34:58 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fallthrough
|
|
|
|
|
|
|
|
case AFMOVD,
|
|
|
|
AFADDD,
|
|
|
|
AFSUBD,
|
|
|
|
AFSUBRD,
|
|
|
|
AFMULD,
|
|
|
|
AFDIVD,
|
|
|
|
AFDIVRD,
|
|
|
|
AFCOMD,
|
|
|
|
AFCOMDP,
|
|
|
|
AADDSD,
|
|
|
|
ASUBSD,
|
|
|
|
AMULSD,
|
|
|
|
ADIVSD,
|
|
|
|
ACOMISD,
|
|
|
|
AUCOMISD:
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
if p.From.Type == obj.TYPE_FCONST {
|
2017-04-06 10:29:29 -07:00
|
|
|
f64 := p.From.Val.(float64)
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
p.From.Type = obj.TYPE_MEM
|
|
|
|
p.From.Name = obj.NAME_EXTERN
|
2017-04-06 10:29:29 -07:00
|
|
|
p.From.Sym = ctxt.Float64Sym(f64)
|
2015-01-19 14:34:58 -05:00
|
|
|
p.From.Offset = 0
|
|
|
|
}
|
|
|
|
}
|
2015-03-30 00:49:25 +00:00
|
|
|
|
2015-11-11 15:57:42 +13:00
|
|
|
if ctxt.Flag_dynlink {
|
2017-04-04 14:31:55 -07:00
|
|
|
rewriteToUseGot(ctxt, p, newprog)
|
2015-11-11 15:57:42 +13:00
|
|
|
}
|
2015-11-18 12:14:07 +13:00
|
|
|
|
2017-03-26 08:05:40 -07:00
|
|
|
if ctxt.Flag_shared && ctxt.Arch.Family == sys.I386 {
|
2017-04-04 14:31:55 -07:00
|
|
|
rewriteToPcrel(ctxt, p, newprog)
|
2015-11-18 12:14:07 +13:00
|
|
|
}
|
2015-11-11 15:57:42 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
// Rewrite p, if necessary, to access global data via the global offset table.
|
2017-04-04 14:31:55 -07:00
|
|
|
func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
|
2017-04-27 11:56:42 +12:00
|
|
|
var lea, mov obj.As
|
2016-03-07 18:00:08 -08:00
|
|
|
var reg int16
|
2017-03-26 08:05:40 -07:00
|
|
|
if ctxt.Arch.Family == sys.AMD64 {
|
2015-11-18 12:30:23 +13:00
|
|
|
lea = ALEAQ
|
|
|
|
mov = AMOVQ
|
|
|
|
reg = REG_R15
|
|
|
|
} else {
|
|
|
|
lea = ALEAL
|
|
|
|
mov = AMOVL
|
|
|
|
reg = REG_CX
|
2016-08-11 12:56:36 -07:00
|
|
|
if p.As == ALEAL && p.To.Reg != p.From.Reg && p.To.Reg != p.From.Index {
|
|
|
|
// Special case: clobber the destination register with
|
|
|
|
// the PC so we don't have to clobber CX.
|
|
|
|
// The SSA backend depends on CX not being clobbered across LEAL.
|
|
|
|
// See cmd/compile/internal/ssa/gen/386.rules (search for Flag_shared).
|
|
|
|
reg = p.To.Reg
|
2016-08-09 13:58:06 -07:00
|
|
|
}
|
2015-11-18 12:30:23 +13:00
|
|
|
}
|
|
|
|
|
2015-11-11 15:57:42 +13:00
|
|
|
if p.As == obj.ADUFFCOPY || p.As == obj.ADUFFZERO {
|
|
|
|
// ADUFFxxx $offset
|
|
|
|
// becomes
|
2015-11-18 12:30:23 +13:00
|
|
|
// $MOV runtime.duffxxx@GOT, $reg
|
2017-04-27 11:56:42 +12:00
|
|
|
// $LEA $offset($reg), $reg
|
2015-11-18 12:30:23 +13:00
|
|
|
// CALL $reg
|
2017-04-27 11:56:42 +12:00
|
|
|
// (we use LEAx rather than ADDx because ADDx clobbers
|
2017-11-15 13:45:31 -05:00
|
|
|
// flags and duffzero on 386 does not otherwise do so).
|
2015-03-30 01:54:49 +00:00
|
|
|
var sym *obj.LSym
|
|
|
|
if p.As == obj.ADUFFZERO {
|
2017-04-20 07:13:02 -07:00
|
|
|
sym = ctxt.Lookup("runtime.duffzero")
|
2015-03-30 01:54:49 +00:00
|
|
|
} else {
|
2017-04-20 07:13:02 -07:00
|
|
|
sym = ctxt.Lookup("runtime.duffcopy")
|
2015-03-30 01:54:49 +00:00
|
|
|
}
|
|
|
|
offset := p.To.Offset
|
2015-11-18 12:30:23 +13:00
|
|
|
p.As = mov
|
2015-03-30 01:54:49 +00:00
|
|
|
p.From.Type = obj.TYPE_MEM
|
|
|
|
p.From.Name = obj.NAME_GOTREF
|
|
|
|
p.From.Sym = sym
|
|
|
|
p.To.Type = obj.TYPE_REG
|
2015-11-18 12:30:23 +13:00
|
|
|
p.To.Reg = reg
|
2015-03-30 01:54:49 +00:00
|
|
|
p.To.Offset = 0
|
|
|
|
p.To.Sym = nil
|
2017-04-04 14:31:55 -07:00
|
|
|
p1 := obj.Appendp(p, newprog)
|
2017-04-27 11:56:42 +12:00
|
|
|
p1.As = lea
|
|
|
|
p1.From.Type = obj.TYPE_MEM
|
2015-03-30 01:54:49 +00:00
|
|
|
p1.From.Offset = offset
|
2017-04-27 11:56:42 +12:00
|
|
|
p1.From.Reg = reg
|
2015-03-30 01:54:49 +00:00
|
|
|
p1.To.Type = obj.TYPE_REG
|
2015-11-18 12:30:23 +13:00
|
|
|
p1.To.Reg = reg
|
2017-04-04 14:31:55 -07:00
|
|
|
p2 := obj.Appendp(p1, newprog)
|
2015-03-30 01:54:49 +00:00
|
|
|
p2.As = obj.ACALL
|
|
|
|
p2.To.Type = obj.TYPE_REG
|
2015-11-18 12:30:23 +13:00
|
|
|
p2.To.Reg = reg
|
2015-03-30 01:54:49 +00:00
|
|
|
}
|
|
|
|
|
2015-11-11 15:57:42 +13:00
|
|
|
// We only care about global data: NAME_EXTERN means a global
|
|
|
|
// symbol in the Go sense, and p.Sym.Local is true for a few
|
|
|
|
// internally defined symbols.
|
2016-10-24 23:15:41 +03:00
|
|
|
if p.As == lea && p.From.Type == obj.TYPE_MEM && p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local() {
|
2015-11-18 12:30:23 +13:00
|
|
|
// $LEA sym, Rx becomes $MOV $sym, Rx which will be rewritten below
|
|
|
|
p.As = mov
|
2015-11-11 15:57:42 +13:00
|
|
|
p.From.Type = obj.TYPE_ADDR
|
|
|
|
}
|
2016-10-24 23:15:41 +03:00
|
|
|
if p.From.Type == obj.TYPE_ADDR && p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local() {
|
2015-11-18 12:30:23 +13:00
|
|
|
// $MOV $sym, Rx becomes $MOV sym@GOT, Rx
|
2016-02-04 11:21:31 -08:00
|
|
|
// $MOV $sym+<off>, Rx becomes $MOV sym@GOT, Rx; $LEA <off>(Rx), Rx
|
2015-11-18 12:30:23 +13:00
|
|
|
// On 386 only, more complicated things like PUSHL $sym become $MOV sym@GOT, CX; PUSHL CX
|
|
|
|
cmplxdest := false
|
|
|
|
pAs := p.As
|
|
|
|
var dest obj.Addr
|
|
|
|
if p.To.Type != obj.TYPE_REG || pAs != mov {
|
2017-03-26 08:05:40 -07:00
|
|
|
if ctxt.Arch.Family == sys.AMD64 {
|
2015-11-18 12:30:23 +13:00
|
|
|
ctxt.Diag("do not know how to handle LEA-type insn to non-register in %v with -dynlink", p)
|
2015-03-30 00:49:25 +00:00
|
|
|
}
|
2015-11-18 12:30:23 +13:00
|
|
|
cmplxdest = true
|
|
|
|
dest = p.To
|
|
|
|
p.As = mov
|
|
|
|
p.To.Type = obj.TYPE_REG
|
2016-08-09 13:58:06 -07:00
|
|
|
p.To.Reg = reg
|
2015-11-18 12:30:23 +13:00
|
|
|
p.To.Sym = nil
|
|
|
|
p.To.Name = obj.NAME_NONE
|
2015-03-30 00:49:25 +00:00
|
|
|
}
|
2015-11-11 15:57:42 +13:00
|
|
|
p.From.Type = obj.TYPE_MEM
|
|
|
|
p.From.Name = obj.NAME_GOTREF
|
2015-11-18 12:30:23 +13:00
|
|
|
q := p
|
2015-11-11 15:57:42 +13:00
|
|
|
if p.From.Offset != 0 {
|
2017-04-04 14:31:55 -07:00
|
|
|
q = obj.Appendp(p, newprog)
|
2016-02-04 11:21:31 -08:00
|
|
|
q.As = lea
|
|
|
|
q.From.Type = obj.TYPE_MEM
|
|
|
|
q.From.Reg = p.To.Reg
|
2015-11-11 15:57:42 +13:00
|
|
|
q.From.Offset = p.From.Offset
|
|
|
|
q.To = p.To
|
|
|
|
p.From.Offset = 0
|
2015-03-30 00:49:25 +00:00
|
|
|
}
|
2015-11-18 12:30:23 +13:00
|
|
|
if cmplxdest {
|
2017-04-04 14:31:55 -07:00
|
|
|
q = obj.Appendp(q, newprog)
|
2015-11-18 12:30:23 +13:00
|
|
|
q.As = pAs
|
|
|
|
q.To = dest
|
|
|
|
q.From.Type = obj.TYPE_REG
|
2016-08-09 13:58:06 -07:00
|
|
|
q.From.Reg = reg
|
2015-03-30 00:49:25 +00:00
|
|
|
}
|
2015-11-11 15:57:42 +13:00
|
|
|
}
|
2017-09-13 14:32:08 +03:00
|
|
|
if p.GetFrom3() != nil && p.GetFrom3().Name == obj.NAME_EXTERN {
|
2015-11-11 15:57:42 +13:00
|
|
|
ctxt.Diag("don't know how to handle %v with -dynlink", p)
|
|
|
|
}
|
|
|
|
var source *obj.Addr
|
2015-11-18 12:30:23 +13:00
|
|
|
// MOVx sym, Ry becomes $MOV sym@GOT, R15; MOVx (R15), Ry
|
|
|
|
// MOVx Ry, sym becomes $MOV sym@GOT, R15; MOVx Ry, (R15)
|
2015-11-11 15:57:42 +13:00
|
|
|
// An addition may be inserted between the two MOVs if there is an offset.
|
2016-10-24 23:15:41 +03:00
|
|
|
if p.From.Name == obj.NAME_EXTERN && !p.From.Sym.Local() {
|
|
|
|
if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() {
|
2015-11-11 15:57:42 +13:00
|
|
|
ctxt.Diag("cannot handle NAME_EXTERN on both sides in %v with -dynlink", p)
|
2015-03-30 00:49:25 +00:00
|
|
|
}
|
2015-11-11 15:57:42 +13:00
|
|
|
source = &p.From
|
2016-10-24 23:15:41 +03:00
|
|
|
} else if p.To.Name == obj.NAME_EXTERN && !p.To.Sym.Local() {
|
2015-11-11 15:57:42 +13:00
|
|
|
source = &p.To
|
|
|
|
} else {
|
|
|
|
return
|
|
|
|
}
|
2015-11-18 12:30:23 +13:00
|
|
|
if p.As == obj.ACALL {
|
|
|
|
// When dynlinking on 386, almost any call might end up being a call
|
|
|
|
// to a PLT, so make sure the GOT pointer is loaded into BX.
|
|
|
|
// RegTo2 is set on the replacement call insn to stop it being
|
|
|
|
// processed when it is in turn passed to progedit.
|
cmd/compile, cmd/link, runtime: make defers low-cost through inline code and extra funcdata
Generate inline code at defer time to save the args of defer calls to unique
(autotmp) stack slots, and generate inline code at exit time to check which defer
calls were made and make the associated function/method/interface calls. We
remember that a particular defer statement was reached by storing in the deferBits
variable (always stored on the stack). At exit time, we check the bits of the
deferBits variable to determine which defer function calls to make (in reverse
order). These low-cost defers are only used for functions where no defers
appear in loops. In addition, we don't do these low-cost defers if there are too
many defer statements or too many exits in a function (to limit code increase).
When a function uses open-coded defers, we produce extra
FUNCDATA_OpenCodedDeferInfo information that specifies the number of defers, and
for each defer, the stack slots where the closure and associated args have been
stored. The funcdata also includes the location of the deferBits variable.
Therefore, for panics, we can use this funcdata to determine exactly which defers
are active, and call the appropriate functions/methods/closures with the correct
arguments for each active defer.
In order to unwind the stack correctly after a recover(), we need to add an extra
code segment to functions with open-coded defers that simply calls deferreturn()
and returns. This segment is not reachable by the normal function, but is returned
to by the runtime during recovery. We set the liveness information of this
deferreturn() to be the same as the liveness at the first function call during the
last defer exit code (so all return values and all stack slots needed by the defer
calls will be live).
I needed to increase the stackguard constant from 880 to 896, because of a small
amount of new code in deferreturn().
The -N flag disables open-coded defers. '-d defer' prints out the kind of defer
being used at each defer statement (heap-allocated, stack-allocated, or
open-coded).
Cost of defer statement [ go test -run NONE -bench BenchmarkDefer$ runtime ]
With normal (stack-allocated) defers only: 35.4 ns/op
With open-coded defers: 5.6 ns/op
Cost of function call alone (remove defer keyword): 4.4 ns/op
Text size increase (including funcdata) for go binary without/with open-coded defers: 0.09%
The average size increase (including funcdata) for only the functions that use
open-coded defers is 1.1%.
The cost of a panic followed by a recover got noticeably slower, since panic
processing now requires a scan of the stack for open-coded defer frames. This scan
is required, even if no frames are using open-coded defers:
Cost of panic and recover [ go test -run NONE -bench BenchmarkPanicRecover runtime ]
Without open-coded defers: 62.0 ns/op
With open-coded defers: 255 ns/op
A CGO Go-to-C-to-Go benchmark got noticeably faster because of open-coded defers:
CGO Go-to-C-to-Go benchmark [cd misc/cgo/test; go test -run NONE -bench BenchmarkCGoCallback ]
Without open-coded defers: 443 ns/op
With open-coded defers: 347 ns/op
Updates #14939 (defer performance)
Updates #34481 (design doc)
Change-Id: I63b1a60d1ebf28126f55ee9fd7ecffe9cb23d1ff
Reviewed-on: https://go-review.googlesource.com/c/go/+/202340
Reviewed-by: Austin Clements <austin@google.com>
2019-06-24 12:59:22 -07:00
|
|
|
//
|
|
|
|
// We disable open-coded defers in buildssa() on 386 ONLY with shared
|
|
|
|
// libraries because of this extra code added before deferreturn calls.
|
2017-03-26 08:05:40 -07:00
|
|
|
if ctxt.Arch.Family == sys.AMD64 || (p.To.Sym != nil && p.To.Sym.Local()) || p.RegTo2 != 0 {
|
2015-11-18 12:30:23 +13:00
|
|
|
return
|
2015-03-30 00:49:25 +00:00
|
|
|
}
|
2017-04-04 14:31:55 -07:00
|
|
|
p1 := obj.Appendp(p, newprog)
|
|
|
|
p2 := obj.Appendp(p1, newprog)
|
2015-03-30 00:49:25 +00:00
|
|
|
|
2015-11-18 12:30:23 +13:00
|
|
|
p1.As = ALEAL
|
2015-03-30 00:49:25 +00:00
|
|
|
p1.From.Type = obj.TYPE_MEM
|
2015-11-18 12:30:23 +13:00
|
|
|
p1.From.Name = obj.NAME_STATIC
|
2017-04-20 07:13:02 -07:00
|
|
|
p1.From.Sym = ctxt.Lookup("_GLOBAL_OFFSET_TABLE_")
|
2015-03-30 00:49:25 +00:00
|
|
|
p1.To.Type = obj.TYPE_REG
|
2015-11-18 12:30:23 +13:00
|
|
|
p1.To.Reg = REG_BX
|
2015-03-30 00:49:25 +00:00
|
|
|
|
|
|
|
p2.As = p.As
|
2015-11-18 12:30:23 +13:00
|
|
|
p2.Scond = p.Scond
|
2015-03-30 00:49:25 +00:00
|
|
|
p2.From = p.From
|
2017-09-13 14:32:08 +03:00
|
|
|
if p.RestArgs != nil {
|
|
|
|
p2.RestArgs = append(p2.RestArgs, p.RestArgs...)
|
|
|
|
}
|
2015-11-18 12:30:23 +13:00
|
|
|
p2.Reg = p.Reg
|
2015-03-30 00:49:25 +00:00
|
|
|
p2.To = p.To
|
2015-11-18 12:30:23 +13:00
|
|
|
// p.To.Type was set to TYPE_BRANCH above, but that makes checkaddr
|
|
|
|
// in ../pass.go complain, so set it back to TYPE_MEM here, until p2
|
|
|
|
// itself gets passed to progedit.
|
|
|
|
p2.To.Type = obj.TYPE_MEM
|
|
|
|
p2.RegTo2 = 1
|
|
|
|
|
|
|
|
obj.Nopout(p)
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
if p.As == obj.ATEXT || p.As == obj.AFUNCDATA || p.As == obj.ARET || p.As == obj.AJMP {
|
2015-11-11 15:57:42 +13:00
|
|
|
return
|
|
|
|
}
|
|
|
|
if source.Type != obj.TYPE_MEM {
|
|
|
|
ctxt.Diag("don't know how to handle %v with -dynlink", p)
|
|
|
|
}
|
2017-04-04 14:31:55 -07:00
|
|
|
p1 := obj.Appendp(p, newprog)
|
|
|
|
p2 := obj.Appendp(p1, newprog)
|
2015-03-30 00:49:25 +00:00
|
|
|
|
2015-11-18 12:30:23 +13:00
|
|
|
p1.As = mov
|
2015-11-11 15:57:42 +13:00
|
|
|
p1.From.Type = obj.TYPE_MEM
|
|
|
|
p1.From.Sym = source.Sym
|
|
|
|
p1.From.Name = obj.NAME_GOTREF
|
|
|
|
p1.To.Type = obj.TYPE_REG
|
2015-11-18 12:30:23 +13:00
|
|
|
p1.To.Reg = reg
|
2015-03-30 00:49:25 +00:00
|
|
|
|
2015-11-11 15:57:42 +13:00
|
|
|
p2.As = p.As
|
|
|
|
p2.From = p.From
|
|
|
|
p2.To = p.To
|
|
|
|
if p.From.Name == obj.NAME_EXTERN {
|
2015-11-18 12:30:23 +13:00
|
|
|
p2.From.Reg = reg
|
2015-11-11 15:57:42 +13:00
|
|
|
p2.From.Name = obj.NAME_NONE
|
|
|
|
p2.From.Sym = nil
|
|
|
|
} else if p.To.Name == obj.NAME_EXTERN {
|
2015-11-18 12:30:23 +13:00
|
|
|
p2.To.Reg = reg
|
2015-11-11 15:57:42 +13:00
|
|
|
p2.To.Name = obj.NAME_NONE
|
|
|
|
p2.To.Sym = nil
|
|
|
|
} else {
|
|
|
|
return
|
2015-03-30 00:49:25 +00:00
|
|
|
}
|
2015-11-11 15:57:42 +13:00
|
|
|
obj.Nopout(p)
|
2015-01-19 14:34:58 -05:00
|
|
|
}
|
|
|
|
|
2017-04-04 14:31:55 -07:00
|
|
|
func rewriteToPcrel(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
|
2015-11-18 12:14:07 +13:00
|
|
|
// RegTo2 is set on the instructions we insert here so they don't get
|
|
|
|
// processed twice.
|
|
|
|
if p.RegTo2 != 0 {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if p.As == obj.ATEXT || p.As == obj.AFUNCDATA || p.As == obj.ACALL || p.As == obj.ARET || p.As == obj.AJMP {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
// Any Prog (aside from the above special cases) with an Addr with Name ==
|
[dev.ssa] cmd/compile: fix PIC for SSA-generated code
Access to globals requires a 2-instruction sequence on PIC 386.
MOVL foo(SB), AX
is translated by the obj package into:
CALL getPCofNextInstructionInTempRegister(SB)
MOVL (&foo-&thisInstruction)(tmpReg), AX
The call returns the PC of the next instruction in a register.
The next instruction then offsets from that register to get the
address required. The tricky part is the allocation of the
temp register. The legacy compiler always used CX, and forbid
the register allocator from allocating CX when in PIC mode.
We can't easily do that in SSA because CX is actually a required
register for shift instructions. (I think the old backend got away
with this because the register allocator never uses CX, only
codegen knows that shifts must use CX.)
Instead, we allow the temp register to be anything. When the
destination of the MOV (or LEA) is an integer register, we can
use that register. Otherwise, we make sure to compile the
operation using an LEA to reference the global. So
MOVL AX, foo(SB)
is never generated directly. Instead, SSA generates:
LEAL foo(SB), DX
MOVL AX, (DX)
which is then rewritten by the obj package to:
CALL getPcInDX(SB)
LEAL (&foo-&thisInstruction)(DX), AX
MOVL AX, (DX)
So this CL modifies the obj package to use different thunks
to materialize the pc into different registers. We use the
registers that regalloc chose so that SSA can still allocate
the full set of registers.
Change-Id: Ie095644f7164a026c62e95baf9d18a8bcaed0bba
Reviewed-on: https://go-review.googlesource.com/25442
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
2016-08-03 13:00:49 -07:00
|
|
|
// NAME_EXTERN, NAME_STATIC or NAME_GOTREF has a CALL __x86.get_pc_thunk.XX
|
2015-11-18 12:14:07 +13:00
|
|
|
// inserted before it.
|
|
|
|
isName := func(a *obj.Addr) bool {
|
|
|
|
if a.Sym == nil || (a.Type != obj.TYPE_MEM && a.Type != obj.TYPE_ADDR) || a.Reg != 0 {
|
|
|
|
return false
|
|
|
|
}
|
2017-04-18 12:53:25 -07:00
|
|
|
if a.Sym.Type == objabi.STLSBSS {
|
2015-11-18 12:14:07 +13:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
return a.Name == obj.NAME_EXTERN || a.Name == obj.NAME_STATIC || a.Name == obj.NAME_GOTREF
|
|
|
|
}
|
|
|
|
|
|
|
|
if isName(&p.From) && p.From.Type == obj.TYPE_ADDR {
|
|
|
|
// Handle things like "MOVL $sym, (SP)" or "PUSHL $sym" by rewriting
|
|
|
|
// to "MOVL $sym, CX; MOVL CX, (SP)" or "MOVL $sym, CX; PUSHL CX"
|
|
|
|
// respectively.
|
|
|
|
if p.To.Type != obj.TYPE_REG {
|
2017-04-04 14:31:55 -07:00
|
|
|
q := obj.Appendp(p, newprog)
|
2015-11-18 12:14:07 +13:00
|
|
|
q.As = p.As
|
|
|
|
q.From.Type = obj.TYPE_REG
|
|
|
|
q.From.Reg = REG_CX
|
|
|
|
q.To = p.To
|
|
|
|
p.As = AMOVL
|
|
|
|
p.To.Type = obj.TYPE_REG
|
|
|
|
p.To.Reg = REG_CX
|
|
|
|
p.To.Sym = nil
|
|
|
|
p.To.Name = obj.NAME_NONE
|
2015-03-30 00:49:25 +00:00
|
|
|
}
|
|
|
|
}
|
2015-11-18 12:14:07 +13:00
|
|
|
|
2017-09-13 14:32:08 +03:00
|
|
|
if !isName(&p.From) && !isName(&p.To) && (p.GetFrom3() == nil || !isName(p.GetFrom3())) {
|
2015-11-18 12:14:07 +13:00
|
|
|
return
|
|
|
|
}
|
[dev.ssa] cmd/compile: fix PIC for SSA-generated code
Access to globals requires a 2-instruction sequence on PIC 386.
MOVL foo(SB), AX
is translated by the obj package into:
CALL getPCofNextInstructionInTempRegister(SB)
MOVL (&foo-&thisInstruction)(tmpReg), AX
The call returns the PC of the next instruction in a register.
The next instruction then offsets from that register to get the
address required. The tricky part is the allocation of the
temp register. The legacy compiler always used CX, and forbid
the register allocator from allocating CX when in PIC mode.
We can't easily do that in SSA because CX is actually a required
register for shift instructions. (I think the old backend got away
with this because the register allocator never uses CX, only
codegen knows that shifts must use CX.)
Instead, we allow the temp register to be anything. When the
destination of the MOV (or LEA) is an integer register, we can
use that register. Otherwise, we make sure to compile the
operation using an LEA to reference the global. So
MOVL AX, foo(SB)
is never generated directly. Instead, SSA generates:
LEAL foo(SB), DX
MOVL AX, (DX)
which is then rewritten by the obj package to:
CALL getPcInDX(SB)
LEAL (&foo-&thisInstruction)(DX), AX
MOVL AX, (DX)
So this CL modifies the obj package to use different thunks
to materialize the pc into different registers. We use the
registers that regalloc chose so that SSA can still allocate
the full set of registers.
Change-Id: Ie095644f7164a026c62e95baf9d18a8bcaed0bba
Reviewed-on: https://go-review.googlesource.com/25442
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
2016-08-03 13:00:49 -07:00
|
|
|
var dst int16 = REG_CX
|
2016-08-11 12:56:36 -07:00
|
|
|
if (p.As == ALEAL || p.As == AMOVL) && p.To.Reg != p.From.Reg && p.To.Reg != p.From.Index {
|
|
|
|
dst = p.To.Reg
|
2017-08-19 22:33:51 +02:00
|
|
|
// Why? See the comment near the top of rewriteToUseGot above.
|
2016-08-11 12:56:36 -07:00
|
|
|
// AMOVLs might be introduced by the GOT rewrites.
|
[dev.ssa] cmd/compile: fix PIC for SSA-generated code
Access to globals requires a 2-instruction sequence on PIC 386.
MOVL foo(SB), AX
is translated by the obj package into:
CALL getPCofNextInstructionInTempRegister(SB)
MOVL (&foo-&thisInstruction)(tmpReg), AX
The call returns the PC of the next instruction in a register.
The next instruction then offsets from that register to get the
address required. The tricky part is the allocation of the
temp register. The legacy compiler always used CX, and forbid
the register allocator from allocating CX when in PIC mode.
We can't easily do that in SSA because CX is actually a required
register for shift instructions. (I think the old backend got away
with this because the register allocator never uses CX, only
codegen knows that shifts must use CX.)
Instead, we allow the temp register to be anything. When the
destination of the MOV (or LEA) is an integer register, we can
use that register. Otherwise, we make sure to compile the
operation using an LEA to reference the global. So
MOVL AX, foo(SB)
is never generated directly. Instead, SSA generates:
LEAL foo(SB), DX
MOVL AX, (DX)
which is then rewritten by the obj package to:
CALL getPcInDX(SB)
LEAL (&foo-&thisInstruction)(DX), AX
MOVL AX, (DX)
So this CL modifies the obj package to use different thunks
to materialize the pc into different registers. We use the
registers that regalloc chose so that SSA can still allocate
the full set of registers.
Change-Id: Ie095644f7164a026c62e95baf9d18a8bcaed0bba
Reviewed-on: https://go-review.googlesource.com/25442
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
2016-08-03 13:00:49 -07:00
|
|
|
}
|
2017-04-04 14:31:55 -07:00
|
|
|
q := obj.Appendp(p, newprog)
|
2015-11-18 12:14:07 +13:00
|
|
|
q.RegTo2 = 1
|
2017-04-04 14:31:55 -07:00
|
|
|
r := obj.Appendp(q, newprog)
|
2015-11-18 12:14:07 +13:00
|
|
|
r.RegTo2 = 1
|
|
|
|
q.As = obj.ACALL
|
2017-04-06 11:47:33 -07:00
|
|
|
thunkname := "__x86.get_pc_thunk." + strings.ToLower(rconv(int(dst)))
|
2017-04-20 07:13:02 -07:00
|
|
|
q.To.Sym = ctxt.LookupInit(thunkname, func(s *obj.LSym) { s.Set(obj.AttrLocal, true) })
|
2015-11-18 12:14:07 +13:00
|
|
|
q.To.Type = obj.TYPE_MEM
|
|
|
|
q.To.Name = obj.NAME_EXTERN
|
|
|
|
r.As = p.As
|
|
|
|
r.Scond = p.Scond
|
|
|
|
r.From = p.From
|
2017-09-13 14:32:08 +03:00
|
|
|
r.RestArgs = p.RestArgs
|
2015-11-18 12:14:07 +13:00
|
|
|
r.Reg = p.Reg
|
|
|
|
r.To = p.To
|
[dev.ssa] cmd/compile: fix PIC for SSA-generated code
Access to globals requires a 2-instruction sequence on PIC 386.
MOVL foo(SB), AX
is translated by the obj package into:
CALL getPCofNextInstructionInTempRegister(SB)
MOVL (&foo-&thisInstruction)(tmpReg), AX
The call returns the PC of the next instruction in a register.
The next instruction then offsets from that register to get the
address required. The tricky part is the allocation of the
temp register. The legacy compiler always used CX, and forbid
the register allocator from allocating CX when in PIC mode.
We can't easily do that in SSA because CX is actually a required
register for shift instructions. (I think the old backend got away
with this because the register allocator never uses CX, only
codegen knows that shifts must use CX.)
Instead, we allow the temp register to be anything. When the
destination of the MOV (or LEA) is an integer register, we can
use that register. Otherwise, we make sure to compile the
operation using an LEA to reference the global. So
MOVL AX, foo(SB)
is never generated directly. Instead, SSA generates:
LEAL foo(SB), DX
MOVL AX, (DX)
which is then rewritten by the obj package to:
CALL getPcInDX(SB)
LEAL (&foo-&thisInstruction)(DX), AX
MOVL AX, (DX)
So this CL modifies the obj package to use different thunks
to materialize the pc into different registers. We use the
registers that regalloc chose so that SSA can still allocate
the full set of registers.
Change-Id: Ie095644f7164a026c62e95baf9d18a8bcaed0bba
Reviewed-on: https://go-review.googlesource.com/25442
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
2016-08-03 13:00:49 -07:00
|
|
|
if isName(&p.From) {
|
|
|
|
r.From.Reg = dst
|
|
|
|
}
|
|
|
|
if isName(&p.To) {
|
|
|
|
r.To.Reg = dst
|
|
|
|
}
|
2017-09-13 14:32:08 +03:00
|
|
|
if p.GetFrom3() != nil && isName(p.GetFrom3()) {
|
|
|
|
r.GetFrom3().Reg = dst
|
[dev.ssa] cmd/compile: fix PIC for SSA-generated code
Access to globals requires a 2-instruction sequence on PIC 386.
MOVL foo(SB), AX
is translated by the obj package into:
CALL getPCofNextInstructionInTempRegister(SB)
MOVL (&foo-&thisInstruction)(tmpReg), AX
The call returns the PC of the next instruction in a register.
The next instruction then offsets from that register to get the
address required. The tricky part is the allocation of the
temp register. The legacy compiler always used CX, and forbid
the register allocator from allocating CX when in PIC mode.
We can't easily do that in SSA because CX is actually a required
register for shift instructions. (I think the old backend got away
with this because the register allocator never uses CX, only
codegen knows that shifts must use CX.)
Instead, we allow the temp register to be anything. When the
destination of the MOV (or LEA) is an integer register, we can
use that register. Otherwise, we make sure to compile the
operation using an LEA to reference the global. So
MOVL AX, foo(SB)
is never generated directly. Instead, SSA generates:
LEAL foo(SB), DX
MOVL AX, (DX)
which is then rewritten by the obj package to:
CALL getPcInDX(SB)
LEAL (&foo-&thisInstruction)(DX), AX
MOVL AX, (DX)
So this CL modifies the obj package to use different thunks
to materialize the pc into different registers. We use the
registers that regalloc chose so that SSA can still allocate
the full set of registers.
Change-Id: Ie095644f7164a026c62e95baf9d18a8bcaed0bba
Reviewed-on: https://go-review.googlesource.com/25442
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
2016-08-03 13:00:49 -07:00
|
|
|
}
|
2015-11-18 12:14:07 +13:00
|
|
|
obj.Nopout(p)
|
2015-01-19 14:34:58 -05:00
|
|
|
}
|
|
|
|
|
2017-04-04 14:31:55 -07:00
|
|
|
func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
2017-04-18 10:18:34 -07:00
|
|
|
if cursym.Func.Text == nil || cursym.Func.Text.Link == nil {
|
2015-01-19 14:34:58 -05:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2017-04-18 10:18:34 -07:00
|
|
|
p := cursym.Func.Text
|
2015-03-02 12:35:15 -05:00
|
|
|
autoffset := int32(p.To.Offset)
|
2015-01-19 14:34:58 -05:00
|
|
|
if autoffset < 0 {
|
|
|
|
autoffset = 0
|
|
|
|
}
|
|
|
|
|
2016-11-30 16:15:32 -08:00
|
|
|
hasCall := false
|
|
|
|
for q := p; q != nil; q = q.Link {
|
|
|
|
if q.As == obj.ACALL || q.As == obj.ADUFFCOPY || q.As == obj.ADUFFZERO {
|
|
|
|
hasCall = true
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-02 12:35:15 -05:00
|
|
|
var bpsize int
|
2020-08-21 11:09:45 -07:00
|
|
|
if ctxt.Arch.Family == sys.AMD64 &&
|
cmd/internal/obj: stop storing Text flags in From3
Prior to this CL, flags such as NOSPLIT
on ATEXT Progs were stored in From3.Offset.
Some but not all of those flags were also
duplicated into From.Sym.Attribute.
This CL migrates all of those flags into
From.Sym.Attribute and stops creating a From3.
A side-effect of this is that printing an
ATEXT Prog can no longer simply dump From3.Offset.
That's kind of good, since the raw flag value
wasn't very informative anyway, but it did
necessitate a bunch of updates to the cmd/asm tests.
The reason I'm doing this work now is that
avoiding storing flags in both From.Sym and From3.Offset
simplifies some other changes to fix the data
race first described in CL 40254.
This CL almost passes toolstash-check -all.
The only changes are in cases where the assembler
has decided that a function's flags may be altered,
e.g. to make a function with no calls in it NOSPLIT.
Prior to this CL, that information was not printed.
Sample before:
"".Ctz64 t=1 size=63 args=0x10 locals=0x0
0x0000 00000 (/Users/josh/go/tip/src/runtime/internal/sys/intrinsics.go:35) TEXT "".Ctz64(SB), $0-16
0x0000 00000 (/Users/josh/go/tip/src/runtime/internal/sys/intrinsics.go:35) FUNCDATA $0, gclocals·f207267fbf96a0178e8758c6e3e0ce28(SB)
Sample after:
"".Ctz64 t=1 nosplit size=63 args=0x10 locals=0x0
0x0000 00000 (/Users/josh/go/tip/src/runtime/internal/sys/intrinsics.go:35) TEXT "".Ctz64(SB), NOSPLIT, $0-16
0x0000 00000 (/Users/josh/go/tip/src/runtime/internal/sys/intrinsics.go:35) FUNCDATA $0, gclocals·f207267fbf96a0178e8758c6e3e0ce28(SB)
Observe the additional "nosplit" in the first line
and the additional "NOSPLIT" in the second line.
Updates #15756
Change-Id: I5c59bd8f3bdc7c780361f801d94a261f0aef3d13
Reviewed-on: https://go-review.googlesource.com/40495
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-04-11 15:15:04 -07:00
|
|
|
!p.From.Sym.NoFrame() && // (1) below
|
|
|
|
!(autoffset == 0 && p.From.Sym.NoSplit()) && // (2) below
|
2016-11-30 16:15:32 -08:00
|
|
|
!(autoffset == 0 && !hasCall) { // (3) below
|
|
|
|
// Make room to save a base pointer.
|
|
|
|
// There are 2 cases we must avoid:
|
|
|
|
// 1) If noframe is set (which we do for functions which tail call).
|
|
|
|
// 2) Scary runtime internals which would be all messed up by frame pointers.
|
|
|
|
// We detect these using a heuristic: frameless nosplit functions.
|
|
|
|
// TODO: Maybe someday we label them all with NOFRAME and get rid of this heuristic.
|
|
|
|
// For performance, we also want to avoid:
|
|
|
|
// 3) Frameless leaf functions
|
2016-04-06 12:01:40 -07:00
|
|
|
bpsize = ctxt.Arch.PtrSize
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
autoffset += int32(bpsize)
|
|
|
|
p.To.Offset += int64(bpsize)
|
|
|
|
} else {
|
|
|
|
bpsize = 0
|
|
|
|
}
|
|
|
|
|
2015-03-16 15:54:44 -04:00
|
|
|
textarg := int64(p.To.Val.(int32))
|
2017-04-18 10:18:34 -07:00
|
|
|
cursym.Func.Args = int32(textarg)
|
|
|
|
cursym.Func.Locals = int32(p.To.Offset)
|
2015-01-19 14:34:58 -05:00
|
|
|
|
cmd/internal/obj/x86: take over i386 duty, clean up PINSRQ, CMPSD
Make cmd/internal/obj/x86 support 32-bit mode and use
instead of cmd/internal/obj/i386. Delete cmd/internal/obj/i386.
Clean up encoding of PINSRQ, CMPSD to use explicit third arg
instead of jamming it into an unused slot of a different arg.
Also fix bug in old6a, which declared the wrong grammar.
The accepted (and encoded) arguments to CMPSD etc are mem,reg not reg,mem.
Code that did try to use mem,reg before would be rejected by liblink,
so only reg,reg ever worked, so existing code is not affected.
After this change, code can use mem,reg successfully.
The real bug here is that the encoding tables inverted the argument
order, making the comparisons all backward from what they say on the page.
It's too late to swap them, though: people have already written code that
expects the inverted comparisons (like in package math, and likely externally).
The best we can do is make the argument that should and can take a
memory operand accept it.
Bit-for-bit compatibility checked against tree without this CL.
Change-Id: Ife5685bc98c95001f64407f35066b34b4dae11c1
Reviewed-on: https://go-review.googlesource.com/6810
Reviewed-by: Rob Pike <r@golang.org>
2015-03-04 15:46:52 -05:00
|
|
|
// TODO(rsc): Remove.
|
2017-04-18 10:18:34 -07:00
|
|
|
if ctxt.Arch.Family == sys.I386 && cursym.Func.Locals < 0 {
|
|
|
|
cursym.Func.Locals = 0
|
cmd/internal/obj/x86: take over i386 duty, clean up PINSRQ, CMPSD
Make cmd/internal/obj/x86 support 32-bit mode and use
instead of cmd/internal/obj/i386. Delete cmd/internal/obj/i386.
Clean up encoding of PINSRQ, CMPSD to use explicit third arg
instead of jamming it into an unused slot of a different arg.
Also fix bug in old6a, which declared the wrong grammar.
The accepted (and encoded) arguments to CMPSD etc are mem,reg not reg,mem.
Code that did try to use mem,reg before would be rejected by liblink,
so only reg,reg ever worked, so existing code is not affected.
After this change, code can use mem,reg successfully.
The real bug here is that the encoding tables inverted the argument
order, making the comparisons all backward from what they say on the page.
It's too late to swap them, though: people have already written code that
expects the inverted comparisons (like in package math, and likely externally).
The best we can do is make the argument that should and can take a
memory operand accept it.
Bit-for-bit compatibility checked against tree without this CL.
Change-Id: Ife5685bc98c95001f64407f35066b34b4dae11c1
Reviewed-on: https://go-review.googlesource.com/6810
Reviewed-by: Rob Pike <r@golang.org>
2015-03-04 15:46:52 -05:00
|
|
|
}
|
|
|
|
|
2017-03-26 08:05:40 -07:00
|
|
|
// TODO(rsc): Remove 'ctxt.Arch.Family == sys.AMD64 &&'.
|
2017-04-18 12:53:25 -07:00
|
|
|
if ctxt.Arch.Family == sys.AMD64 && autoffset < objabi.StackSmall && !p.From.Sym.NoSplit() {
|
2016-07-07 16:21:53 -07:00
|
|
|
leaf := true
|
|
|
|
LeafSearch:
|
2015-03-02 12:35:15 -05:00
|
|
|
for q := p; q != nil; q = q.Link {
|
2016-07-07 16:21:53 -07:00
|
|
|
switch q.As {
|
|
|
|
case obj.ACALL:
|
cmd/compile/internal/obj/x86: eliminate some function prologues
The standard sort swap method
func (t T) Swap(i, j int) {
t[i], t[j] = t[j], t[i]
}
uses no stack space on architectures for which
FixedFrameSize == 0, currently 386 and amd64.
Nevertheless, we insert a stack check prologue.
This is because it contains a call to
runtime.panicindex.
However, for a few common runtime functions,
we know at compile time that they require
no arguments. Allow them to pass unnoticed.
Triggers for 380 functions during make.bash.
Cuts 4k off cmd/go.
encoding/binary benchmarks:
ReadSlice1000Int32s-8 9.49µs ± 3% 9.41µs ± 5% ~ (p=0.075 n=29+27)
ReadStruct-8 1.50µs ± 3% 1.48µs ± 2% -1.49% (p=0.000 n=30+28)
ReadInts-8 599ns ± 3% 600ns ± 3% ~ (p=0.471 n=30+29)
WriteInts-8 836ns ± 4% 841ns ± 3% ~ (p=0.371 n=30+29)
WriteSlice1000Int32s-8 8.84µs ± 3% 8.69µs ± 5% -1.71% (p=0.001 n=30+30)
PutUvarint32-8 29.6ns ± 1% 28.1ns ± 3% -5.21% (p=0.000 n=28+28)
PutUvarint64-8 82.6ns ± 5% 82.3ns ±10% -0.43% (p=0.014 n=27+30)
Swap assembly before:
"".T.Swap t=1 size=74 args=0x28 locals=0x0
0x0000 00000 (swap.go:5) TEXT "".T.Swap(SB), $0-40
0x0000 00000 (swap.go:5) MOVQ (TLS), CX
0x0009 00009 (swap.go:5) CMPQ SP, 16(CX)
0x000d 00013 (swap.go:5) JLS 67
0x000f 00015 (swap.go:5) FUNCDATA $0, gclocals·3cadd97b66f25a3a642be35e9362338f(SB)
0x000f 00015 (swap.go:5) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x000f 00015 (swap.go:5) MOVQ "".i+32(FP), AX
0x0014 00020 (swap.go:5) MOVQ "".t+16(FP), CX
0x0019 00025 (swap.go:5) CMPQ AX, CX
0x001c 00028 (swap.go:5) JCC $0, 60
0x001e 00030 (swap.go:5) MOVQ "".t+8(FP), DX
0x0023 00035 (swap.go:5) MOVBLZX (DX)(AX*1), BX
0x0027 00039 (swap.go:5) MOVQ "".j+40(FP), SI
0x002c 00044 (swap.go:5) CMPQ SI, CX
0x002f 00047 (swap.go:5) JCC $0, 60
0x0031 00049 (swap.go:5) MOVBLZX (DX)(SI*1), CX
0x0035 00053 (swap.go:5) MOVB CL, (DX)(AX*1)
0x0038 00056 (swap.go:5) MOVB BL, (DX)(SI*1)
0x003b 00059 (swap.go:5) RET
0x003c 00060 (swap.go:5) PCDATA $0, $1
0x003c 00060 (swap.go:5) CALL runtime.panicindex(SB)
0x0041 00065 (swap.go:5) UNDEF
0x0043 00067 (swap.go:5) NOP
0x0043 00067 (swap.go:5) CALL runtime.morestack_noctxt(SB)
0x0048 00072 (swap.go:5) JMP 0
Swap assembly after:
"".T.Swap t=1 size=52 args=0x28 locals=0x0
0x0000 00000 (swap.go:5) TEXT "".T.Swap(SB), $0-40
0x0000 00000 (swap.go:5) FUNCDATA $0, gclocals·3cadd97b66f25a3a642be35e9362338f(SB)
0x0000 00000 (swap.go:5) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x0000 00000 (swap.go:5) MOVQ "".i+32(FP), AX
0x0005 00005 (swap.go:5) MOVQ "".t+16(FP), CX
0x000a 00010 (swap.go:5) CMPQ AX, CX
0x000d 00013 (swap.go:5) JCC $0, 45
0x000f 00015 (swap.go:5) MOVQ "".t+8(FP), DX
0x0014 00020 (swap.go:5) MOVBLZX (DX)(AX*1), BX
0x0018 00024 (swap.go:5) MOVQ "".j+40(FP), SI
0x001d 00029 (swap.go:5) CMPQ SI, CX
0x0020 00032 (swap.go:5) JCC $0, 45
0x0022 00034 (swap.go:5) MOVBLZX (DX)(SI*1), CX
0x0026 00038 (swap.go:5) MOVB CL, (DX)(AX*1)
0x0029 00041 (swap.go:5) MOVB BL, (DX)(SI*1)
0x002c 00044 (swap.go:5) RET
0x002d 00045 (swap.go:5) PCDATA $0, $1
0x002d 00045 (swap.go:5) CALL runtime.panicindex(SB)
0x0032 00050 (swap.go:5) UNDEF
Change-Id: I57dad14af8aaa5e6112deac407cfadc2bfaf1f54
Reviewed-on: https://go-review.googlesource.com/24814
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
2016-07-07 16:50:46 -07:00
|
|
|
// Treat common runtime calls that take no arguments
|
|
|
|
// the same as duffcopy and duffzero.
|
|
|
|
if !isZeroArgRuntimeCall(q.To.Sym) {
|
|
|
|
leaf = false
|
|
|
|
break LeafSearch
|
|
|
|
}
|
|
|
|
fallthrough
|
2016-07-07 16:21:53 -07:00
|
|
|
case obj.ADUFFCOPY, obj.ADUFFZERO:
|
2017-04-18 12:53:25 -07:00
|
|
|
if autoffset >= objabi.StackSmall-8 {
|
2016-07-07 16:21:53 -07:00
|
|
|
leaf = false
|
|
|
|
break LeafSearch
|
|
|
|
}
|
2015-01-19 14:34:58 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-07-07 16:21:53 -07:00
|
|
|
if leaf {
|
cmd/internal/obj: stop storing Text flags in From3
Prior to this CL, flags such as NOSPLIT
on ATEXT Progs were stored in From3.Offset.
Some but not all of those flags were also
duplicated into From.Sym.Attribute.
This CL migrates all of those flags into
From.Sym.Attribute and stops creating a From3.
A side-effect of this is that printing an
ATEXT Prog can no longer simply dump From3.Offset.
That's kind of good, since the raw flag value
wasn't very informative anyway, but it did
necessitate a bunch of updates to the cmd/asm tests.
The reason I'm doing this work now is that
avoiding storing flags in both From.Sym and From3.Offset
simplifies some other changes to fix the data
race first described in CL 40254.
This CL almost passes toolstash-check -all.
The only changes are in cases where the assembler
has decided that a function's flags may be altered,
e.g. to make a function with no calls in it NOSPLIT.
Prior to this CL, that information was not printed.
Sample before:
"".Ctz64 t=1 size=63 args=0x10 locals=0x0
0x0000 00000 (/Users/josh/go/tip/src/runtime/internal/sys/intrinsics.go:35) TEXT "".Ctz64(SB), $0-16
0x0000 00000 (/Users/josh/go/tip/src/runtime/internal/sys/intrinsics.go:35) FUNCDATA $0, gclocals·f207267fbf96a0178e8758c6e3e0ce28(SB)
Sample after:
"".Ctz64 t=1 nosplit size=63 args=0x10 locals=0x0
0x0000 00000 (/Users/josh/go/tip/src/runtime/internal/sys/intrinsics.go:35) TEXT "".Ctz64(SB), NOSPLIT, $0-16
0x0000 00000 (/Users/josh/go/tip/src/runtime/internal/sys/intrinsics.go:35) FUNCDATA $0, gclocals·f207267fbf96a0178e8758c6e3e0ce28(SB)
Observe the additional "nosplit" in the first line
and the additional "NOSPLIT" in the second line.
Updates #15756
Change-Id: I5c59bd8f3bdc7c780361f801d94a261f0aef3d13
Reviewed-on: https://go-review.googlesource.com/40495
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-04-11 15:15:04 -07:00
|
|
|
p.From.Sym.Set(obj.AttrNoSplit, true)
|
2016-07-07 16:21:53 -07:00
|
|
|
}
|
2015-01-19 14:34:58 -05:00
|
|
|
}
|
|
|
|
|
cmd/internal/obj: stop storing Text flags in From3
Prior to this CL, flags such as NOSPLIT
on ATEXT Progs were stored in From3.Offset.
Some but not all of those flags were also
duplicated into From.Sym.Attribute.
This CL migrates all of those flags into
From.Sym.Attribute and stops creating a From3.
A side-effect of this is that printing an
ATEXT Prog can no longer simply dump From3.Offset.
That's kind of good, since the raw flag value
wasn't very informative anyway, but it did
necessitate a bunch of updates to the cmd/asm tests.
The reason I'm doing this work now is that
avoiding storing flags in both From.Sym and From3.Offset
simplifies some other changes to fix the data
race first described in CL 40254.
This CL almost passes toolstash-check -all.
The only changes are in cases where the assembler
has decided that a function's flags may be altered,
e.g. to make a function with no calls in it NOSPLIT.
Prior to this CL, that information was not printed.
Sample before:
"".Ctz64 t=1 size=63 args=0x10 locals=0x0
0x0000 00000 (/Users/josh/go/tip/src/runtime/internal/sys/intrinsics.go:35) TEXT "".Ctz64(SB), $0-16
0x0000 00000 (/Users/josh/go/tip/src/runtime/internal/sys/intrinsics.go:35) FUNCDATA $0, gclocals·f207267fbf96a0178e8758c6e3e0ce28(SB)
Sample after:
"".Ctz64 t=1 nosplit size=63 args=0x10 locals=0x0
0x0000 00000 (/Users/josh/go/tip/src/runtime/internal/sys/intrinsics.go:35) TEXT "".Ctz64(SB), NOSPLIT, $0-16
0x0000 00000 (/Users/josh/go/tip/src/runtime/internal/sys/intrinsics.go:35) FUNCDATA $0, gclocals·f207267fbf96a0178e8758c6e3e0ce28(SB)
Observe the additional "nosplit" in the first line
and the additional "NOSPLIT" in the second line.
Updates #15756
Change-Id: I5c59bd8f3bdc7c780361f801d94a261f0aef3d13
Reviewed-on: https://go-review.googlesource.com/40495
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-04-11 15:15:04 -07:00
|
|
|
if !p.From.Sym.NoSplit() || p.From.Sym.Wrapper() {
|
2017-04-04 14:31:55 -07:00
|
|
|
p = obj.Appendp(p, newprog)
|
|
|
|
p = load_g_cx(ctxt, p, newprog) // load g into CX
|
2015-01-19 14:34:58 -05:00
|
|
|
}
|
|
|
|
|
2017-04-18 10:18:34 -07:00
|
|
|
if !cursym.Func.Text.From.Sym.NoSplit() {
|
2017-04-04 14:31:55 -07:00
|
|
|
p = stacksplit(ctxt, cursym, p, newprog, autoffset, int32(textarg)) // emit split check
|
2015-01-19 14:34:58 -05:00
|
|
|
}
|
|
|
|
|
2018-04-30 23:52:14 -04:00
|
|
|
// Delve debugger would like the next instruction to be noted as the end of the function prologue.
|
|
|
|
// TODO: are there other cases (e.g., wrapper functions) that need marking?
|
|
|
|
markedPrologue := false
|
|
|
|
|
2015-01-19 14:34:58 -05:00
|
|
|
if autoffset != 0 {
|
2016-04-06 12:01:40 -07:00
|
|
|
if autoffset%int32(ctxt.Arch.RegSize) != 0 {
|
2015-01-19 14:34:58 -05:00
|
|
|
ctxt.Diag("unaligned stack size %d", autoffset)
|
|
|
|
}
|
2017-04-04 14:31:55 -07:00
|
|
|
p = obj.Appendp(p, newprog)
|
2015-01-19 14:34:58 -05:00
|
|
|
p.As = AADJSP
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
p.From.Type = obj.TYPE_CONST
|
2015-01-19 14:34:58 -05:00
|
|
|
p.From.Offset = int64(autoffset)
|
|
|
|
p.Spadj = autoffset
|
2018-04-30 23:52:14 -04:00
|
|
|
p.Pos = p.Pos.WithXlogue(src.PosPrologueEnd)
|
|
|
|
markedPrologue = true
|
2015-01-19 14:34:58 -05:00
|
|
|
}
|
|
|
|
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
if bpsize > 0 {
|
|
|
|
// Save caller's BP
|
2017-04-04 14:31:55 -07:00
|
|
|
p = obj.Appendp(p, newprog)
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
|
|
|
|
p.As = AMOVQ
|
|
|
|
p.From.Type = obj.TYPE_REG
|
|
|
|
p.From.Reg = REG_BP
|
|
|
|
p.To.Type = obj.TYPE_MEM
|
|
|
|
p.To.Reg = REG_SP
|
|
|
|
p.To.Scale = 1
|
|
|
|
p.To.Offset = int64(autoffset) - int64(bpsize)
|
2018-04-30 23:52:14 -04:00
|
|
|
if !markedPrologue {
|
|
|
|
p.Pos = p.Pos.WithXlogue(src.PosPrologueEnd)
|
|
|
|
}
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
|
|
|
|
// Move current frame to BP
|
2017-04-04 14:31:55 -07:00
|
|
|
p = obj.Appendp(p, newprog)
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
|
|
|
|
p.As = ALEAQ
|
|
|
|
p.From.Type = obj.TYPE_MEM
|
|
|
|
p.From.Reg = REG_SP
|
|
|
|
p.From.Scale = 1
|
|
|
|
p.From.Offset = int64(autoffset) - int64(bpsize)
|
|
|
|
p.To.Type = obj.TYPE_REG
|
|
|
|
p.To.Reg = REG_BP
|
|
|
|
}
|
|
|
|
|
2017-04-18 10:18:34 -07:00
|
|
|
if cursym.Func.Text.From.Sym.Wrapper() {
|
2017-02-10 14:56:05 -08:00
|
|
|
// if g._panic != nil && g._panic.argp == FP {
|
|
|
|
// g._panic.argp = bottom-of-frame
|
|
|
|
// }
|
2015-01-19 14:34:58 -05:00
|
|
|
//
|
|
|
|
// MOVQ g_panic(CX), BX
|
|
|
|
// TESTQ BX, BX
|
cmd/internal/obj/x86: improve static branch prediction for wrapper prologue
Static branch prediction assumes that forward branches are not taken.
The existing wrapper prologue almost always takes the first forward
branch.
Move the rare case to the end of the function.
This CL is amd64 only. Other architectures will be done in separate CLs.
Updates #19042.
Package sort benchmarks:
SearchWrappers-8 104ns ± 2% 104ns ± 0% -0.41% (p=0.006 n=30+41)
SortString1K-8 128µs ± 1% 128µs ± 1% -0.25% (p=0.045 n=30+56)
SortString1K_Slice-8 117µs ± 1% 117µs ± 1% ~ (p=0.855 n=30+59)
StableString1K-8 18.6µs ± 1% 18.6µs ± 1% ~ (p=0.599 n=29+60)
SortInt1K-8 61.0µs ± 1% 56.5µs ± 1% -7.36% (p=0.000 n=29+58)
StableInt1K-8 74.6µs ± 1% 70.4µs ± 3% -5.54% (p=0.000 n=28+60)
StableInt1K_Slice-8 59.9µs ± 1% 58.3µs ± 4% -2.64% (p=0.000 n=29+60)
SortInt64K-8 6.02ms ± 2% 5.98ms ± 2% -0.60% (p=0.000 n=29+59)
SortInt64K_Slice-8 5.07ms ± 2% 5.05ms ± 2% -0.38% (p=0.006 n=30+58)
StableInt64K-8 6.41ms ± 1% 6.22ms ± 1% -3.00% (p=0.000 n=27+58)
Sort1e2-8 37.4µs ± 1% 37.1µs ± 1% -0.91% (p=0.000 n=30+57)
Stable1e2-8 74.8µs ± 1% 75.2µs ± 1% +0.52% (p=0.000 n=30+57)
Sort1e4-8 8.11ms ± 1% 8.01ms ± 1% -1.20% (p=0.000 n=30+59)
Stable1e4-8 24.3ms ± 1% 24.3ms ± 1% ~ (p=0.157 n=30+60)
Sort1e6-8 1.25s ± 1% 1.23s ± 1% -1.43% (p=0.000 n=29+58)
Stable1e6-8 4.93s ± 1% 4.90s ± 1% -0.56% (p=0.000 n=29+59)
[Geo mean] 720µs 709µs -1.52%
Assembly for sort.(*intPairs).Swap:
Before:
"".(*intPairs).Swap t=1 size=147 args=0x18 locals=0x8
0x0000 00000 (<autogenerated>:1) TEXT "".(*intPairs).Swap(SB), $8-24
0x0000 00000 (<autogenerated>:1) MOVQ (TLS), CX
0x0009 00009 (<autogenerated>:1) SUBQ $8, SP
0x000d 00013 (<autogenerated>:1) MOVQ BP, (SP)
0x0011 00017 (<autogenerated>:1) LEAQ (SP), BP
0x0015 00021 (<autogenerated>:1) MOVQ 32(CX), BX
0x0019 00025 (<autogenerated>:1) TESTQ BX, BX
0x001c 00028 (<autogenerated>:1) JEQ 43
0x001e 00030 (<autogenerated>:1) LEAQ 16(SP), DI
0x0023 00035 (<autogenerated>:1) CMPQ (BX), DI
0x0026 00038 (<autogenerated>:1) JNE 43
0x0028 00040 (<autogenerated>:1) MOVQ SP, (BX)
0x002b 00043 (<autogenerated>:1) NOP
0x002b 00043 (<autogenerated>:1) FUNCDATA $0, gclocals·e6397a44f8e1b6e77d0f200b4fba5269(SB)
0x002b 00043 (<autogenerated>:1) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x002b 00043 (<autogenerated>:1) MOVQ ""..this+16(FP), AX
0x0030 00048 (<autogenerated>:1) TESTQ AX, AX
0x0033 00051 (<autogenerated>:1) JEQ $0, 140
0x0035 00053 (<autogenerated>:1) MOVQ (AX), CX
0x0038 00056 (<autogenerated>:1) MOVQ 8(AX), AX
0x003c 00060 (<autogenerated>:1) MOVQ "".i+24(FP), DX
0x0041 00065 (<autogenerated>:1) CMPQ DX, AX
0x0044 00068 (<autogenerated>:1) JCC $0, 133
0x0046 00070 (<autogenerated>:1) SHLQ $4, DX
0x004a 00074 (<autogenerated>:1) MOVQ 8(CX)(DX*1), BX
0x004f 00079 (<autogenerated>:1) MOVQ (CX)(DX*1), SI
0x0053 00083 (<autogenerated>:1) MOVQ "".j+32(FP), DI
0x0058 00088 (<autogenerated>:1) CMPQ DI, AX
0x005b 00091 (<autogenerated>:1) JCC $0, 133
0x005d 00093 (<autogenerated>:1) SHLQ $4, DI
0x0061 00097 (<autogenerated>:1) MOVQ 8(CX)(DI*1), AX
0x0066 00102 (<autogenerated>:1) MOVQ (CX)(DI*1), R8
0x006a 00106 (<autogenerated>:1) MOVQ R8, (CX)(DX*1)
0x006e 00110 (<autogenerated>:1) MOVQ AX, 8(CX)(DX*1)
0x0073 00115 (<autogenerated>:1) MOVQ SI, (CX)(DI*1)
0x0077 00119 (<autogenerated>:1) MOVQ BX, 8(CX)(DI*1)
0x007c 00124 (<autogenerated>:1) MOVQ (SP), BP
0x0080 00128 (<autogenerated>:1) ADDQ $8, SP
0x0084 00132 (<autogenerated>:1) RET
0x0085 00133 (<autogenerated>:1) PCDATA $0, $1
0x0085 00133 (<autogenerated>:1) CALL runtime.panicindex(SB)
0x008a 00138 (<autogenerated>:1) UNDEF
0x008c 00140 (<autogenerated>:1) PCDATA $0, $1
0x008c 00140 (<autogenerated>:1) CALL runtime.panicwrap(SB)
0x0091 00145 (<autogenerated>:1) UNDEF
After:
"".(*intPairs).Swap t=1 size=149 args=0x18 locals=0x8
0x0000 00000 (<autogenerated>:1) TEXT "".(*intPairs).Swap(SB), $8-24
0x0000 00000 (<autogenerated>:1) MOVQ (TLS), CX
0x0009 00009 (<autogenerated>:1) SUBQ $8, SP
0x000d 00013 (<autogenerated>:1) MOVQ BP, (SP)
0x0011 00017 (<autogenerated>:1) LEAQ (SP), BP
0x0015 00021 (<autogenerated>:1) MOVQ 32(CX), BX
0x0019 00025 (<autogenerated>:1) TESTQ BX, BX
0x001c 00028 (<autogenerated>:1) JNE 134
0x001e 00030 (<autogenerated>:1) NOP
0x001e 00030 (<autogenerated>:1) FUNCDATA $0, gclocals·e6397a44f8e1b6e77d0f200b4fba5269(SB)
0x001e 00030 (<autogenerated>:1) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x001e 00030 (<autogenerated>:1) MOVQ ""..this+16(FP), AX
0x0023 00035 (<autogenerated>:1) TESTQ AX, AX
0x0026 00038 (<autogenerated>:1) JEQ $0, 127
0x0028 00040 (<autogenerated>:1) MOVQ (AX), CX
0x002b 00043 (<autogenerated>:1) MOVQ 8(AX), AX
0x002f 00047 (<autogenerated>:1) MOVQ "".i+24(FP), DX
0x0034 00052 (<autogenerated>:1) CMPQ DX, AX
0x0037 00055 (<autogenerated>:1) JCC $0, 120
0x0039 00057 (<autogenerated>:1) SHLQ $4, DX
0x003d 00061 (<autogenerated>:1) MOVQ 8(CX)(DX*1), BX
0x0042 00066 (<autogenerated>:1) MOVQ (CX)(DX*1), SI
0x0046 00070 (<autogenerated>:1) MOVQ "".j+32(FP), DI
0x004b 00075 (<autogenerated>:1) CMPQ DI, AX
0x004e 00078 (<autogenerated>:1) JCC $0, 120
0x0050 00080 (<autogenerated>:1) SHLQ $4, DI
0x0054 00084 (<autogenerated>:1) MOVQ 8(CX)(DI*1), AX
0x0059 00089 (<autogenerated>:1) MOVQ (CX)(DI*1), R8
0x005d 00093 (<autogenerated>:1) MOVQ R8, (CX)(DX*1)
0x0061 00097 (<autogenerated>:1) MOVQ AX, 8(CX)(DX*1)
0x0066 00102 (<autogenerated>:1) MOVQ SI, (CX)(DI*1)
0x006a 00106 (<autogenerated>:1) MOVQ BX, 8(CX)(DI*1)
0x006f 00111 (<autogenerated>:1) MOVQ (SP), BP
0x0073 00115 (<autogenerated>:1) ADDQ $8, SP
0x0077 00119 (<autogenerated>:1) RET
0x0078 00120 (<autogenerated>:1) PCDATA $0, $1
0x0078 00120 (<autogenerated>:1) CALL runtime.panicindex(SB)
0x007d 00125 (<autogenerated>:1) UNDEF
0x007f 00127 (<autogenerated>:1) PCDATA $0, $1
0x007f 00127 (<autogenerated>:1) CALL runtime.panicwrap(SB)
0x0084 00132 (<autogenerated>:1) UNDEF
0x0086 00134 (<autogenerated>:1) LEAQ 16(SP), DI
0x008b 00139 (<autogenerated>:1) CMPQ (BX), DI
0x008e 00142 (<autogenerated>:1) JNE 30
0x0090 00144 (<autogenerated>:1) MOVQ SP, (BX)
0x0093 00147 (<autogenerated>:1) JMP 30
Change-Id: Ie8c37f384bba10fbacaa754bb0a6b0a7e520ef01
Reviewed-on: https://go-review.googlesource.com/36893
Reviewed-by: Keith Randall <khr@golang.org>
2017-02-10 15:26:47 -08:00
|
|
|
// JNE checkargp
|
|
|
|
// end:
|
|
|
|
// NOP
|
|
|
|
// ... rest of function ...
|
|
|
|
// checkargp:
|
2015-01-19 14:34:58 -05:00
|
|
|
// LEAQ (autoffset+8)(SP), DI
|
|
|
|
// CMPQ panic_argp(BX), DI
|
|
|
|
// JNE end
|
cmd/internal/obj/x86: improve static branch prediction for wrapper prologue
Static branch prediction assumes that forward branches are not taken.
The existing wrapper prologue almost always takes the first forward
branch.
Move the rare case to the end of the function.
This CL is amd64 only. Other architectures will be done in separate CLs.
Updates #19042.
Package sort benchmarks:
SearchWrappers-8 104ns ± 2% 104ns ± 0% -0.41% (p=0.006 n=30+41)
SortString1K-8 128µs ± 1% 128µs ± 1% -0.25% (p=0.045 n=30+56)
SortString1K_Slice-8 117µs ± 1% 117µs ± 1% ~ (p=0.855 n=30+59)
StableString1K-8 18.6µs ± 1% 18.6µs ± 1% ~ (p=0.599 n=29+60)
SortInt1K-8 61.0µs ± 1% 56.5µs ± 1% -7.36% (p=0.000 n=29+58)
StableInt1K-8 74.6µs ± 1% 70.4µs ± 3% -5.54% (p=0.000 n=28+60)
StableInt1K_Slice-8 59.9µs ± 1% 58.3µs ± 4% -2.64% (p=0.000 n=29+60)
SortInt64K-8 6.02ms ± 2% 5.98ms ± 2% -0.60% (p=0.000 n=29+59)
SortInt64K_Slice-8 5.07ms ± 2% 5.05ms ± 2% -0.38% (p=0.006 n=30+58)
StableInt64K-8 6.41ms ± 1% 6.22ms ± 1% -3.00% (p=0.000 n=27+58)
Sort1e2-8 37.4µs ± 1% 37.1µs ± 1% -0.91% (p=0.000 n=30+57)
Stable1e2-8 74.8µs ± 1% 75.2µs ± 1% +0.52% (p=0.000 n=30+57)
Sort1e4-8 8.11ms ± 1% 8.01ms ± 1% -1.20% (p=0.000 n=30+59)
Stable1e4-8 24.3ms ± 1% 24.3ms ± 1% ~ (p=0.157 n=30+60)
Sort1e6-8 1.25s ± 1% 1.23s ± 1% -1.43% (p=0.000 n=29+58)
Stable1e6-8 4.93s ± 1% 4.90s ± 1% -0.56% (p=0.000 n=29+59)
[Geo mean] 720µs 709µs -1.52%
Assembly for sort.(*intPairs).Swap:
Before:
"".(*intPairs).Swap t=1 size=147 args=0x18 locals=0x8
0x0000 00000 (<autogenerated>:1) TEXT "".(*intPairs).Swap(SB), $8-24
0x0000 00000 (<autogenerated>:1) MOVQ (TLS), CX
0x0009 00009 (<autogenerated>:1) SUBQ $8, SP
0x000d 00013 (<autogenerated>:1) MOVQ BP, (SP)
0x0011 00017 (<autogenerated>:1) LEAQ (SP), BP
0x0015 00021 (<autogenerated>:1) MOVQ 32(CX), BX
0x0019 00025 (<autogenerated>:1) TESTQ BX, BX
0x001c 00028 (<autogenerated>:1) JEQ 43
0x001e 00030 (<autogenerated>:1) LEAQ 16(SP), DI
0x0023 00035 (<autogenerated>:1) CMPQ (BX), DI
0x0026 00038 (<autogenerated>:1) JNE 43
0x0028 00040 (<autogenerated>:1) MOVQ SP, (BX)
0x002b 00043 (<autogenerated>:1) NOP
0x002b 00043 (<autogenerated>:1) FUNCDATA $0, gclocals·e6397a44f8e1b6e77d0f200b4fba5269(SB)
0x002b 00043 (<autogenerated>:1) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x002b 00043 (<autogenerated>:1) MOVQ ""..this+16(FP), AX
0x0030 00048 (<autogenerated>:1) TESTQ AX, AX
0x0033 00051 (<autogenerated>:1) JEQ $0, 140
0x0035 00053 (<autogenerated>:1) MOVQ (AX), CX
0x0038 00056 (<autogenerated>:1) MOVQ 8(AX), AX
0x003c 00060 (<autogenerated>:1) MOVQ "".i+24(FP), DX
0x0041 00065 (<autogenerated>:1) CMPQ DX, AX
0x0044 00068 (<autogenerated>:1) JCC $0, 133
0x0046 00070 (<autogenerated>:1) SHLQ $4, DX
0x004a 00074 (<autogenerated>:1) MOVQ 8(CX)(DX*1), BX
0x004f 00079 (<autogenerated>:1) MOVQ (CX)(DX*1), SI
0x0053 00083 (<autogenerated>:1) MOVQ "".j+32(FP), DI
0x0058 00088 (<autogenerated>:1) CMPQ DI, AX
0x005b 00091 (<autogenerated>:1) JCC $0, 133
0x005d 00093 (<autogenerated>:1) SHLQ $4, DI
0x0061 00097 (<autogenerated>:1) MOVQ 8(CX)(DI*1), AX
0x0066 00102 (<autogenerated>:1) MOVQ (CX)(DI*1), R8
0x006a 00106 (<autogenerated>:1) MOVQ R8, (CX)(DX*1)
0x006e 00110 (<autogenerated>:1) MOVQ AX, 8(CX)(DX*1)
0x0073 00115 (<autogenerated>:1) MOVQ SI, (CX)(DI*1)
0x0077 00119 (<autogenerated>:1) MOVQ BX, 8(CX)(DI*1)
0x007c 00124 (<autogenerated>:1) MOVQ (SP), BP
0x0080 00128 (<autogenerated>:1) ADDQ $8, SP
0x0084 00132 (<autogenerated>:1) RET
0x0085 00133 (<autogenerated>:1) PCDATA $0, $1
0x0085 00133 (<autogenerated>:1) CALL runtime.panicindex(SB)
0x008a 00138 (<autogenerated>:1) UNDEF
0x008c 00140 (<autogenerated>:1) PCDATA $0, $1
0x008c 00140 (<autogenerated>:1) CALL runtime.panicwrap(SB)
0x0091 00145 (<autogenerated>:1) UNDEF
After:
"".(*intPairs).Swap t=1 size=149 args=0x18 locals=0x8
0x0000 00000 (<autogenerated>:1) TEXT "".(*intPairs).Swap(SB), $8-24
0x0000 00000 (<autogenerated>:1) MOVQ (TLS), CX
0x0009 00009 (<autogenerated>:1) SUBQ $8, SP
0x000d 00013 (<autogenerated>:1) MOVQ BP, (SP)
0x0011 00017 (<autogenerated>:1) LEAQ (SP), BP
0x0015 00021 (<autogenerated>:1) MOVQ 32(CX), BX
0x0019 00025 (<autogenerated>:1) TESTQ BX, BX
0x001c 00028 (<autogenerated>:1) JNE 134
0x001e 00030 (<autogenerated>:1) NOP
0x001e 00030 (<autogenerated>:1) FUNCDATA $0, gclocals·e6397a44f8e1b6e77d0f200b4fba5269(SB)
0x001e 00030 (<autogenerated>:1) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x001e 00030 (<autogenerated>:1) MOVQ ""..this+16(FP), AX
0x0023 00035 (<autogenerated>:1) TESTQ AX, AX
0x0026 00038 (<autogenerated>:1) JEQ $0, 127
0x0028 00040 (<autogenerated>:1) MOVQ (AX), CX
0x002b 00043 (<autogenerated>:1) MOVQ 8(AX), AX
0x002f 00047 (<autogenerated>:1) MOVQ "".i+24(FP), DX
0x0034 00052 (<autogenerated>:1) CMPQ DX, AX
0x0037 00055 (<autogenerated>:1) JCC $0, 120
0x0039 00057 (<autogenerated>:1) SHLQ $4, DX
0x003d 00061 (<autogenerated>:1) MOVQ 8(CX)(DX*1), BX
0x0042 00066 (<autogenerated>:1) MOVQ (CX)(DX*1), SI
0x0046 00070 (<autogenerated>:1) MOVQ "".j+32(FP), DI
0x004b 00075 (<autogenerated>:1) CMPQ DI, AX
0x004e 00078 (<autogenerated>:1) JCC $0, 120
0x0050 00080 (<autogenerated>:1) SHLQ $4, DI
0x0054 00084 (<autogenerated>:1) MOVQ 8(CX)(DI*1), AX
0x0059 00089 (<autogenerated>:1) MOVQ (CX)(DI*1), R8
0x005d 00093 (<autogenerated>:1) MOVQ R8, (CX)(DX*1)
0x0061 00097 (<autogenerated>:1) MOVQ AX, 8(CX)(DX*1)
0x0066 00102 (<autogenerated>:1) MOVQ SI, (CX)(DI*1)
0x006a 00106 (<autogenerated>:1) MOVQ BX, 8(CX)(DI*1)
0x006f 00111 (<autogenerated>:1) MOVQ (SP), BP
0x0073 00115 (<autogenerated>:1) ADDQ $8, SP
0x0077 00119 (<autogenerated>:1) RET
0x0078 00120 (<autogenerated>:1) PCDATA $0, $1
0x0078 00120 (<autogenerated>:1) CALL runtime.panicindex(SB)
0x007d 00125 (<autogenerated>:1) UNDEF
0x007f 00127 (<autogenerated>:1) PCDATA $0, $1
0x007f 00127 (<autogenerated>:1) CALL runtime.panicwrap(SB)
0x0084 00132 (<autogenerated>:1) UNDEF
0x0086 00134 (<autogenerated>:1) LEAQ 16(SP), DI
0x008b 00139 (<autogenerated>:1) CMPQ (BX), DI
0x008e 00142 (<autogenerated>:1) JNE 30
0x0090 00144 (<autogenerated>:1) MOVQ SP, (BX)
0x0093 00147 (<autogenerated>:1) JMP 30
Change-Id: Ie8c37f384bba10fbacaa754bb0a6b0a7e520ef01
Reviewed-on: https://go-review.googlesource.com/36893
Reviewed-by: Keith Randall <khr@golang.org>
2017-02-10 15:26:47 -08:00
|
|
|
// MOVQ SP, panic_argp(BX)
|
|
|
|
// JMP end
|
2015-01-19 14:34:58 -05:00
|
|
|
//
|
|
|
|
// The NOP is needed to give the jumps somewhere to land.
|
|
|
|
// It is a liblink NOP, not an x86 NOP: it encodes to 0 instruction bytes.
|
cmd/internal/obj/x86: improve static branch prediction for wrapper prologue
Static branch prediction assumes that forward branches are not taken.
The existing wrapper prologue almost always takes the first forward
branch.
Move the rare case to the end of the function.
This CL is amd64 only. Other architectures will be done in separate CLs.
Updates #19042.
Package sort benchmarks:
SearchWrappers-8 104ns ± 2% 104ns ± 0% -0.41% (p=0.006 n=30+41)
SortString1K-8 128µs ± 1% 128µs ± 1% -0.25% (p=0.045 n=30+56)
SortString1K_Slice-8 117µs ± 1% 117µs ± 1% ~ (p=0.855 n=30+59)
StableString1K-8 18.6µs ± 1% 18.6µs ± 1% ~ (p=0.599 n=29+60)
SortInt1K-8 61.0µs ± 1% 56.5µs ± 1% -7.36% (p=0.000 n=29+58)
StableInt1K-8 74.6µs ± 1% 70.4µs ± 3% -5.54% (p=0.000 n=28+60)
StableInt1K_Slice-8 59.9µs ± 1% 58.3µs ± 4% -2.64% (p=0.000 n=29+60)
SortInt64K-8 6.02ms ± 2% 5.98ms ± 2% -0.60% (p=0.000 n=29+59)
SortInt64K_Slice-8 5.07ms ± 2% 5.05ms ± 2% -0.38% (p=0.006 n=30+58)
StableInt64K-8 6.41ms ± 1% 6.22ms ± 1% -3.00% (p=0.000 n=27+58)
Sort1e2-8 37.4µs ± 1% 37.1µs ± 1% -0.91% (p=0.000 n=30+57)
Stable1e2-8 74.8µs ± 1% 75.2µs ± 1% +0.52% (p=0.000 n=30+57)
Sort1e4-8 8.11ms ± 1% 8.01ms ± 1% -1.20% (p=0.000 n=30+59)
Stable1e4-8 24.3ms ± 1% 24.3ms ± 1% ~ (p=0.157 n=30+60)
Sort1e6-8 1.25s ± 1% 1.23s ± 1% -1.43% (p=0.000 n=29+58)
Stable1e6-8 4.93s ± 1% 4.90s ± 1% -0.56% (p=0.000 n=29+59)
[Geo mean] 720µs 709µs -1.52%
Assembly for sort.(*intPairs).Swap:
Before:
"".(*intPairs).Swap t=1 size=147 args=0x18 locals=0x8
0x0000 00000 (<autogenerated>:1) TEXT "".(*intPairs).Swap(SB), $8-24
0x0000 00000 (<autogenerated>:1) MOVQ (TLS), CX
0x0009 00009 (<autogenerated>:1) SUBQ $8, SP
0x000d 00013 (<autogenerated>:1) MOVQ BP, (SP)
0x0011 00017 (<autogenerated>:1) LEAQ (SP), BP
0x0015 00021 (<autogenerated>:1) MOVQ 32(CX), BX
0x0019 00025 (<autogenerated>:1) TESTQ BX, BX
0x001c 00028 (<autogenerated>:1) JEQ 43
0x001e 00030 (<autogenerated>:1) LEAQ 16(SP), DI
0x0023 00035 (<autogenerated>:1) CMPQ (BX), DI
0x0026 00038 (<autogenerated>:1) JNE 43
0x0028 00040 (<autogenerated>:1) MOVQ SP, (BX)
0x002b 00043 (<autogenerated>:1) NOP
0x002b 00043 (<autogenerated>:1) FUNCDATA $0, gclocals·e6397a44f8e1b6e77d0f200b4fba5269(SB)
0x002b 00043 (<autogenerated>:1) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x002b 00043 (<autogenerated>:1) MOVQ ""..this+16(FP), AX
0x0030 00048 (<autogenerated>:1) TESTQ AX, AX
0x0033 00051 (<autogenerated>:1) JEQ $0, 140
0x0035 00053 (<autogenerated>:1) MOVQ (AX), CX
0x0038 00056 (<autogenerated>:1) MOVQ 8(AX), AX
0x003c 00060 (<autogenerated>:1) MOVQ "".i+24(FP), DX
0x0041 00065 (<autogenerated>:1) CMPQ DX, AX
0x0044 00068 (<autogenerated>:1) JCC $0, 133
0x0046 00070 (<autogenerated>:1) SHLQ $4, DX
0x004a 00074 (<autogenerated>:1) MOVQ 8(CX)(DX*1), BX
0x004f 00079 (<autogenerated>:1) MOVQ (CX)(DX*1), SI
0x0053 00083 (<autogenerated>:1) MOVQ "".j+32(FP), DI
0x0058 00088 (<autogenerated>:1) CMPQ DI, AX
0x005b 00091 (<autogenerated>:1) JCC $0, 133
0x005d 00093 (<autogenerated>:1) SHLQ $4, DI
0x0061 00097 (<autogenerated>:1) MOVQ 8(CX)(DI*1), AX
0x0066 00102 (<autogenerated>:1) MOVQ (CX)(DI*1), R8
0x006a 00106 (<autogenerated>:1) MOVQ R8, (CX)(DX*1)
0x006e 00110 (<autogenerated>:1) MOVQ AX, 8(CX)(DX*1)
0x0073 00115 (<autogenerated>:1) MOVQ SI, (CX)(DI*1)
0x0077 00119 (<autogenerated>:1) MOVQ BX, 8(CX)(DI*1)
0x007c 00124 (<autogenerated>:1) MOVQ (SP), BP
0x0080 00128 (<autogenerated>:1) ADDQ $8, SP
0x0084 00132 (<autogenerated>:1) RET
0x0085 00133 (<autogenerated>:1) PCDATA $0, $1
0x0085 00133 (<autogenerated>:1) CALL runtime.panicindex(SB)
0x008a 00138 (<autogenerated>:1) UNDEF
0x008c 00140 (<autogenerated>:1) PCDATA $0, $1
0x008c 00140 (<autogenerated>:1) CALL runtime.panicwrap(SB)
0x0091 00145 (<autogenerated>:1) UNDEF
After:
"".(*intPairs).Swap t=1 size=149 args=0x18 locals=0x8
0x0000 00000 (<autogenerated>:1) TEXT "".(*intPairs).Swap(SB), $8-24
0x0000 00000 (<autogenerated>:1) MOVQ (TLS), CX
0x0009 00009 (<autogenerated>:1) SUBQ $8, SP
0x000d 00013 (<autogenerated>:1) MOVQ BP, (SP)
0x0011 00017 (<autogenerated>:1) LEAQ (SP), BP
0x0015 00021 (<autogenerated>:1) MOVQ 32(CX), BX
0x0019 00025 (<autogenerated>:1) TESTQ BX, BX
0x001c 00028 (<autogenerated>:1) JNE 134
0x001e 00030 (<autogenerated>:1) NOP
0x001e 00030 (<autogenerated>:1) FUNCDATA $0, gclocals·e6397a44f8e1b6e77d0f200b4fba5269(SB)
0x001e 00030 (<autogenerated>:1) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x001e 00030 (<autogenerated>:1) MOVQ ""..this+16(FP), AX
0x0023 00035 (<autogenerated>:1) TESTQ AX, AX
0x0026 00038 (<autogenerated>:1) JEQ $0, 127
0x0028 00040 (<autogenerated>:1) MOVQ (AX), CX
0x002b 00043 (<autogenerated>:1) MOVQ 8(AX), AX
0x002f 00047 (<autogenerated>:1) MOVQ "".i+24(FP), DX
0x0034 00052 (<autogenerated>:1) CMPQ DX, AX
0x0037 00055 (<autogenerated>:1) JCC $0, 120
0x0039 00057 (<autogenerated>:1) SHLQ $4, DX
0x003d 00061 (<autogenerated>:1) MOVQ 8(CX)(DX*1), BX
0x0042 00066 (<autogenerated>:1) MOVQ (CX)(DX*1), SI
0x0046 00070 (<autogenerated>:1) MOVQ "".j+32(FP), DI
0x004b 00075 (<autogenerated>:1) CMPQ DI, AX
0x004e 00078 (<autogenerated>:1) JCC $0, 120
0x0050 00080 (<autogenerated>:1) SHLQ $4, DI
0x0054 00084 (<autogenerated>:1) MOVQ 8(CX)(DI*1), AX
0x0059 00089 (<autogenerated>:1) MOVQ (CX)(DI*1), R8
0x005d 00093 (<autogenerated>:1) MOVQ R8, (CX)(DX*1)
0x0061 00097 (<autogenerated>:1) MOVQ AX, 8(CX)(DX*1)
0x0066 00102 (<autogenerated>:1) MOVQ SI, (CX)(DI*1)
0x006a 00106 (<autogenerated>:1) MOVQ BX, 8(CX)(DI*1)
0x006f 00111 (<autogenerated>:1) MOVQ (SP), BP
0x0073 00115 (<autogenerated>:1) ADDQ $8, SP
0x0077 00119 (<autogenerated>:1) RET
0x0078 00120 (<autogenerated>:1) PCDATA $0, $1
0x0078 00120 (<autogenerated>:1) CALL runtime.panicindex(SB)
0x007d 00125 (<autogenerated>:1) UNDEF
0x007f 00127 (<autogenerated>:1) PCDATA $0, $1
0x007f 00127 (<autogenerated>:1) CALL runtime.panicwrap(SB)
0x0084 00132 (<autogenerated>:1) UNDEF
0x0086 00134 (<autogenerated>:1) LEAQ 16(SP), DI
0x008b 00139 (<autogenerated>:1) CMPQ (BX), DI
0x008e 00142 (<autogenerated>:1) JNE 30
0x0090 00144 (<autogenerated>:1) MOVQ SP, (BX)
0x0093 00147 (<autogenerated>:1) JMP 30
Change-Id: Ie8c37f384bba10fbacaa754bb0a6b0a7e520ef01
Reviewed-on: https://go-review.googlesource.com/36893
Reviewed-by: Keith Randall <khr@golang.org>
2017-02-10 15:26:47 -08:00
|
|
|
//
|
|
|
|
// The layout is chosen to help static branch prediction:
|
|
|
|
// Both conditional jumps are unlikely, so they are arranged to be forward jumps.
|
2015-01-19 14:34:58 -05:00
|
|
|
|
2017-02-10 14:56:05 -08:00
|
|
|
// MOVQ g_panic(CX), BX
|
2017-04-04 14:31:55 -07:00
|
|
|
p = obj.Appendp(p, newprog)
|
2015-01-19 14:34:58 -05:00
|
|
|
p.As = AMOVQ
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
p.From.Type = obj.TYPE_MEM
|
|
|
|
p.From.Reg = REG_CX
|
2017-02-10 14:56:05 -08:00
|
|
|
p.From.Offset = 4 * int64(ctxt.Arch.PtrSize) // g_panic
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
p.To.Type = obj.TYPE_REG
|
|
|
|
p.To.Reg = REG_BX
|
2017-03-26 08:05:40 -07:00
|
|
|
if ctxt.Arch.Family == sys.I386 {
|
cmd/internal/obj/x86: take over i386 duty, clean up PINSRQ, CMPSD
Make cmd/internal/obj/x86 support 32-bit mode and use
instead of cmd/internal/obj/i386. Delete cmd/internal/obj/i386.
Clean up encoding of PINSRQ, CMPSD to use explicit third arg
instead of jamming it into an unused slot of a different arg.
Also fix bug in old6a, which declared the wrong grammar.
The accepted (and encoded) arguments to CMPSD etc are mem,reg not reg,mem.
Code that did try to use mem,reg before would be rejected by liblink,
so only reg,reg ever worked, so existing code is not affected.
After this change, code can use mem,reg successfully.
The real bug here is that the encoding tables inverted the argument
order, making the comparisons all backward from what they say on the page.
It's too late to swap them, though: people have already written code that
expects the inverted comparisons (like in package math, and likely externally).
The best we can do is make the argument that should and can take a
memory operand accept it.
Bit-for-bit compatibility checked against tree without this CL.
Change-Id: Ife5685bc98c95001f64407f35066b34b4dae11c1
Reviewed-on: https://go-review.googlesource.com/6810
Reviewed-by: Rob Pike <r@golang.org>
2015-03-04 15:46:52 -05:00
|
|
|
p.As = AMOVL
|
|
|
|
}
|
2015-01-19 14:34:58 -05:00
|
|
|
|
2017-02-10 14:56:05 -08:00
|
|
|
// TESTQ BX, BX
|
2017-04-04 14:31:55 -07:00
|
|
|
p = obj.Appendp(p, newprog)
|
2015-01-19 14:34:58 -05:00
|
|
|
p.As = ATESTQ
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
p.From.Type = obj.TYPE_REG
|
|
|
|
p.From.Reg = REG_BX
|
|
|
|
p.To.Type = obj.TYPE_REG
|
|
|
|
p.To.Reg = REG_BX
|
2019-10-09 16:22:47 +00:00
|
|
|
if ctxt.Arch.Family == sys.I386 {
|
2015-01-19 14:34:58 -05:00
|
|
|
p.As = ATESTL
|
|
|
|
}
|
|
|
|
|
cmd/internal/obj/x86: improve static branch prediction for wrapper prologue
Static branch prediction assumes that forward branches are not taken.
The existing wrapper prologue almost always takes the first forward
branch.
Move the rare case to the end of the function.
This CL is amd64 only. Other architectures will be done in separate CLs.
Updates #19042.
Package sort benchmarks:
SearchWrappers-8 104ns ± 2% 104ns ± 0% -0.41% (p=0.006 n=30+41)
SortString1K-8 128µs ± 1% 128µs ± 1% -0.25% (p=0.045 n=30+56)
SortString1K_Slice-8 117µs ± 1% 117µs ± 1% ~ (p=0.855 n=30+59)
StableString1K-8 18.6µs ± 1% 18.6µs ± 1% ~ (p=0.599 n=29+60)
SortInt1K-8 61.0µs ± 1% 56.5µs ± 1% -7.36% (p=0.000 n=29+58)
StableInt1K-8 74.6µs ± 1% 70.4µs ± 3% -5.54% (p=0.000 n=28+60)
StableInt1K_Slice-8 59.9µs ± 1% 58.3µs ± 4% -2.64% (p=0.000 n=29+60)
SortInt64K-8 6.02ms ± 2% 5.98ms ± 2% -0.60% (p=0.000 n=29+59)
SortInt64K_Slice-8 5.07ms ± 2% 5.05ms ± 2% -0.38% (p=0.006 n=30+58)
StableInt64K-8 6.41ms ± 1% 6.22ms ± 1% -3.00% (p=0.000 n=27+58)
Sort1e2-8 37.4µs ± 1% 37.1µs ± 1% -0.91% (p=0.000 n=30+57)
Stable1e2-8 74.8µs ± 1% 75.2µs ± 1% +0.52% (p=0.000 n=30+57)
Sort1e4-8 8.11ms ± 1% 8.01ms ± 1% -1.20% (p=0.000 n=30+59)
Stable1e4-8 24.3ms ± 1% 24.3ms ± 1% ~ (p=0.157 n=30+60)
Sort1e6-8 1.25s ± 1% 1.23s ± 1% -1.43% (p=0.000 n=29+58)
Stable1e6-8 4.93s ± 1% 4.90s ± 1% -0.56% (p=0.000 n=29+59)
[Geo mean] 720µs 709µs -1.52%
Assembly for sort.(*intPairs).Swap:
Before:
"".(*intPairs).Swap t=1 size=147 args=0x18 locals=0x8
0x0000 00000 (<autogenerated>:1) TEXT "".(*intPairs).Swap(SB), $8-24
0x0000 00000 (<autogenerated>:1) MOVQ (TLS), CX
0x0009 00009 (<autogenerated>:1) SUBQ $8, SP
0x000d 00013 (<autogenerated>:1) MOVQ BP, (SP)
0x0011 00017 (<autogenerated>:1) LEAQ (SP), BP
0x0015 00021 (<autogenerated>:1) MOVQ 32(CX), BX
0x0019 00025 (<autogenerated>:1) TESTQ BX, BX
0x001c 00028 (<autogenerated>:1) JEQ 43
0x001e 00030 (<autogenerated>:1) LEAQ 16(SP), DI
0x0023 00035 (<autogenerated>:1) CMPQ (BX), DI
0x0026 00038 (<autogenerated>:1) JNE 43
0x0028 00040 (<autogenerated>:1) MOVQ SP, (BX)
0x002b 00043 (<autogenerated>:1) NOP
0x002b 00043 (<autogenerated>:1) FUNCDATA $0, gclocals·e6397a44f8e1b6e77d0f200b4fba5269(SB)
0x002b 00043 (<autogenerated>:1) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x002b 00043 (<autogenerated>:1) MOVQ ""..this+16(FP), AX
0x0030 00048 (<autogenerated>:1) TESTQ AX, AX
0x0033 00051 (<autogenerated>:1) JEQ $0, 140
0x0035 00053 (<autogenerated>:1) MOVQ (AX), CX
0x0038 00056 (<autogenerated>:1) MOVQ 8(AX), AX
0x003c 00060 (<autogenerated>:1) MOVQ "".i+24(FP), DX
0x0041 00065 (<autogenerated>:1) CMPQ DX, AX
0x0044 00068 (<autogenerated>:1) JCC $0, 133
0x0046 00070 (<autogenerated>:1) SHLQ $4, DX
0x004a 00074 (<autogenerated>:1) MOVQ 8(CX)(DX*1), BX
0x004f 00079 (<autogenerated>:1) MOVQ (CX)(DX*1), SI
0x0053 00083 (<autogenerated>:1) MOVQ "".j+32(FP), DI
0x0058 00088 (<autogenerated>:1) CMPQ DI, AX
0x005b 00091 (<autogenerated>:1) JCC $0, 133
0x005d 00093 (<autogenerated>:1) SHLQ $4, DI
0x0061 00097 (<autogenerated>:1) MOVQ 8(CX)(DI*1), AX
0x0066 00102 (<autogenerated>:1) MOVQ (CX)(DI*1), R8
0x006a 00106 (<autogenerated>:1) MOVQ R8, (CX)(DX*1)
0x006e 00110 (<autogenerated>:1) MOVQ AX, 8(CX)(DX*1)
0x0073 00115 (<autogenerated>:1) MOVQ SI, (CX)(DI*1)
0x0077 00119 (<autogenerated>:1) MOVQ BX, 8(CX)(DI*1)
0x007c 00124 (<autogenerated>:1) MOVQ (SP), BP
0x0080 00128 (<autogenerated>:1) ADDQ $8, SP
0x0084 00132 (<autogenerated>:1) RET
0x0085 00133 (<autogenerated>:1) PCDATA $0, $1
0x0085 00133 (<autogenerated>:1) CALL runtime.panicindex(SB)
0x008a 00138 (<autogenerated>:1) UNDEF
0x008c 00140 (<autogenerated>:1) PCDATA $0, $1
0x008c 00140 (<autogenerated>:1) CALL runtime.panicwrap(SB)
0x0091 00145 (<autogenerated>:1) UNDEF
After:
"".(*intPairs).Swap t=1 size=149 args=0x18 locals=0x8
0x0000 00000 (<autogenerated>:1) TEXT "".(*intPairs).Swap(SB), $8-24
0x0000 00000 (<autogenerated>:1) MOVQ (TLS), CX
0x0009 00009 (<autogenerated>:1) SUBQ $8, SP
0x000d 00013 (<autogenerated>:1) MOVQ BP, (SP)
0x0011 00017 (<autogenerated>:1) LEAQ (SP), BP
0x0015 00021 (<autogenerated>:1) MOVQ 32(CX), BX
0x0019 00025 (<autogenerated>:1) TESTQ BX, BX
0x001c 00028 (<autogenerated>:1) JNE 134
0x001e 00030 (<autogenerated>:1) NOP
0x001e 00030 (<autogenerated>:1) FUNCDATA $0, gclocals·e6397a44f8e1b6e77d0f200b4fba5269(SB)
0x001e 00030 (<autogenerated>:1) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x001e 00030 (<autogenerated>:1) MOVQ ""..this+16(FP), AX
0x0023 00035 (<autogenerated>:1) TESTQ AX, AX
0x0026 00038 (<autogenerated>:1) JEQ $0, 127
0x0028 00040 (<autogenerated>:1) MOVQ (AX), CX
0x002b 00043 (<autogenerated>:1) MOVQ 8(AX), AX
0x002f 00047 (<autogenerated>:1) MOVQ "".i+24(FP), DX
0x0034 00052 (<autogenerated>:1) CMPQ DX, AX
0x0037 00055 (<autogenerated>:1) JCC $0, 120
0x0039 00057 (<autogenerated>:1) SHLQ $4, DX
0x003d 00061 (<autogenerated>:1) MOVQ 8(CX)(DX*1), BX
0x0042 00066 (<autogenerated>:1) MOVQ (CX)(DX*1), SI
0x0046 00070 (<autogenerated>:1) MOVQ "".j+32(FP), DI
0x004b 00075 (<autogenerated>:1) CMPQ DI, AX
0x004e 00078 (<autogenerated>:1) JCC $0, 120
0x0050 00080 (<autogenerated>:1) SHLQ $4, DI
0x0054 00084 (<autogenerated>:1) MOVQ 8(CX)(DI*1), AX
0x0059 00089 (<autogenerated>:1) MOVQ (CX)(DI*1), R8
0x005d 00093 (<autogenerated>:1) MOVQ R8, (CX)(DX*1)
0x0061 00097 (<autogenerated>:1) MOVQ AX, 8(CX)(DX*1)
0x0066 00102 (<autogenerated>:1) MOVQ SI, (CX)(DI*1)
0x006a 00106 (<autogenerated>:1) MOVQ BX, 8(CX)(DI*1)
0x006f 00111 (<autogenerated>:1) MOVQ (SP), BP
0x0073 00115 (<autogenerated>:1) ADDQ $8, SP
0x0077 00119 (<autogenerated>:1) RET
0x0078 00120 (<autogenerated>:1) PCDATA $0, $1
0x0078 00120 (<autogenerated>:1) CALL runtime.panicindex(SB)
0x007d 00125 (<autogenerated>:1) UNDEF
0x007f 00127 (<autogenerated>:1) PCDATA $0, $1
0x007f 00127 (<autogenerated>:1) CALL runtime.panicwrap(SB)
0x0084 00132 (<autogenerated>:1) UNDEF
0x0086 00134 (<autogenerated>:1) LEAQ 16(SP), DI
0x008b 00139 (<autogenerated>:1) CMPQ (BX), DI
0x008e 00142 (<autogenerated>:1) JNE 30
0x0090 00144 (<autogenerated>:1) MOVQ SP, (BX)
0x0093 00147 (<autogenerated>:1) JMP 30
Change-Id: Ie8c37f384bba10fbacaa754bb0a6b0a7e520ef01
Reviewed-on: https://go-review.googlesource.com/36893
Reviewed-by: Keith Randall <khr@golang.org>
2017-02-10 15:26:47 -08:00
|
|
|
// JNE checkargp (checkargp to be resolved later)
|
2017-04-04 14:31:55 -07:00
|
|
|
jne := obj.Appendp(p, newprog)
|
cmd/internal/obj/x86: improve static branch prediction for wrapper prologue
Static branch prediction assumes that forward branches are not taken.
The existing wrapper prologue almost always takes the first forward
branch.
Move the rare case to the end of the function.
This CL is amd64 only. Other architectures will be done in separate CLs.
Updates #19042.
Package sort benchmarks:
SearchWrappers-8 104ns ± 2% 104ns ± 0% -0.41% (p=0.006 n=30+41)
SortString1K-8 128µs ± 1% 128µs ± 1% -0.25% (p=0.045 n=30+56)
SortString1K_Slice-8 117µs ± 1% 117µs ± 1% ~ (p=0.855 n=30+59)
StableString1K-8 18.6µs ± 1% 18.6µs ± 1% ~ (p=0.599 n=29+60)
SortInt1K-8 61.0µs ± 1% 56.5µs ± 1% -7.36% (p=0.000 n=29+58)
StableInt1K-8 74.6µs ± 1% 70.4µs ± 3% -5.54% (p=0.000 n=28+60)
StableInt1K_Slice-8 59.9µs ± 1% 58.3µs ± 4% -2.64% (p=0.000 n=29+60)
SortInt64K-8 6.02ms ± 2% 5.98ms ± 2% -0.60% (p=0.000 n=29+59)
SortInt64K_Slice-8 5.07ms ± 2% 5.05ms ± 2% -0.38% (p=0.006 n=30+58)
StableInt64K-8 6.41ms ± 1% 6.22ms ± 1% -3.00% (p=0.000 n=27+58)
Sort1e2-8 37.4µs ± 1% 37.1µs ± 1% -0.91% (p=0.000 n=30+57)
Stable1e2-8 74.8µs ± 1% 75.2µs ± 1% +0.52% (p=0.000 n=30+57)
Sort1e4-8 8.11ms ± 1% 8.01ms ± 1% -1.20% (p=0.000 n=30+59)
Stable1e4-8 24.3ms ± 1% 24.3ms ± 1% ~ (p=0.157 n=30+60)
Sort1e6-8 1.25s ± 1% 1.23s ± 1% -1.43% (p=0.000 n=29+58)
Stable1e6-8 4.93s ± 1% 4.90s ± 1% -0.56% (p=0.000 n=29+59)
[Geo mean] 720µs 709µs -1.52%
Assembly for sort.(*intPairs).Swap:
Before:
"".(*intPairs).Swap t=1 size=147 args=0x18 locals=0x8
0x0000 00000 (<autogenerated>:1) TEXT "".(*intPairs).Swap(SB), $8-24
0x0000 00000 (<autogenerated>:1) MOVQ (TLS), CX
0x0009 00009 (<autogenerated>:1) SUBQ $8, SP
0x000d 00013 (<autogenerated>:1) MOVQ BP, (SP)
0x0011 00017 (<autogenerated>:1) LEAQ (SP), BP
0x0015 00021 (<autogenerated>:1) MOVQ 32(CX), BX
0x0019 00025 (<autogenerated>:1) TESTQ BX, BX
0x001c 00028 (<autogenerated>:1) JEQ 43
0x001e 00030 (<autogenerated>:1) LEAQ 16(SP), DI
0x0023 00035 (<autogenerated>:1) CMPQ (BX), DI
0x0026 00038 (<autogenerated>:1) JNE 43
0x0028 00040 (<autogenerated>:1) MOVQ SP, (BX)
0x002b 00043 (<autogenerated>:1) NOP
0x002b 00043 (<autogenerated>:1) FUNCDATA $0, gclocals·e6397a44f8e1b6e77d0f200b4fba5269(SB)
0x002b 00043 (<autogenerated>:1) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x002b 00043 (<autogenerated>:1) MOVQ ""..this+16(FP), AX
0x0030 00048 (<autogenerated>:1) TESTQ AX, AX
0x0033 00051 (<autogenerated>:1) JEQ $0, 140
0x0035 00053 (<autogenerated>:1) MOVQ (AX), CX
0x0038 00056 (<autogenerated>:1) MOVQ 8(AX), AX
0x003c 00060 (<autogenerated>:1) MOVQ "".i+24(FP), DX
0x0041 00065 (<autogenerated>:1) CMPQ DX, AX
0x0044 00068 (<autogenerated>:1) JCC $0, 133
0x0046 00070 (<autogenerated>:1) SHLQ $4, DX
0x004a 00074 (<autogenerated>:1) MOVQ 8(CX)(DX*1), BX
0x004f 00079 (<autogenerated>:1) MOVQ (CX)(DX*1), SI
0x0053 00083 (<autogenerated>:1) MOVQ "".j+32(FP), DI
0x0058 00088 (<autogenerated>:1) CMPQ DI, AX
0x005b 00091 (<autogenerated>:1) JCC $0, 133
0x005d 00093 (<autogenerated>:1) SHLQ $4, DI
0x0061 00097 (<autogenerated>:1) MOVQ 8(CX)(DI*1), AX
0x0066 00102 (<autogenerated>:1) MOVQ (CX)(DI*1), R8
0x006a 00106 (<autogenerated>:1) MOVQ R8, (CX)(DX*1)
0x006e 00110 (<autogenerated>:1) MOVQ AX, 8(CX)(DX*1)
0x0073 00115 (<autogenerated>:1) MOVQ SI, (CX)(DI*1)
0x0077 00119 (<autogenerated>:1) MOVQ BX, 8(CX)(DI*1)
0x007c 00124 (<autogenerated>:1) MOVQ (SP), BP
0x0080 00128 (<autogenerated>:1) ADDQ $8, SP
0x0084 00132 (<autogenerated>:1) RET
0x0085 00133 (<autogenerated>:1) PCDATA $0, $1
0x0085 00133 (<autogenerated>:1) CALL runtime.panicindex(SB)
0x008a 00138 (<autogenerated>:1) UNDEF
0x008c 00140 (<autogenerated>:1) PCDATA $0, $1
0x008c 00140 (<autogenerated>:1) CALL runtime.panicwrap(SB)
0x0091 00145 (<autogenerated>:1) UNDEF
After:
"".(*intPairs).Swap t=1 size=149 args=0x18 locals=0x8
0x0000 00000 (<autogenerated>:1) TEXT "".(*intPairs).Swap(SB), $8-24
0x0000 00000 (<autogenerated>:1) MOVQ (TLS), CX
0x0009 00009 (<autogenerated>:1) SUBQ $8, SP
0x000d 00013 (<autogenerated>:1) MOVQ BP, (SP)
0x0011 00017 (<autogenerated>:1) LEAQ (SP), BP
0x0015 00021 (<autogenerated>:1) MOVQ 32(CX), BX
0x0019 00025 (<autogenerated>:1) TESTQ BX, BX
0x001c 00028 (<autogenerated>:1) JNE 134
0x001e 00030 (<autogenerated>:1) NOP
0x001e 00030 (<autogenerated>:1) FUNCDATA $0, gclocals·e6397a44f8e1b6e77d0f200b4fba5269(SB)
0x001e 00030 (<autogenerated>:1) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x001e 00030 (<autogenerated>:1) MOVQ ""..this+16(FP), AX
0x0023 00035 (<autogenerated>:1) TESTQ AX, AX
0x0026 00038 (<autogenerated>:1) JEQ $0, 127
0x0028 00040 (<autogenerated>:1) MOVQ (AX), CX
0x002b 00043 (<autogenerated>:1) MOVQ 8(AX), AX
0x002f 00047 (<autogenerated>:1) MOVQ "".i+24(FP), DX
0x0034 00052 (<autogenerated>:1) CMPQ DX, AX
0x0037 00055 (<autogenerated>:1) JCC $0, 120
0x0039 00057 (<autogenerated>:1) SHLQ $4, DX
0x003d 00061 (<autogenerated>:1) MOVQ 8(CX)(DX*1), BX
0x0042 00066 (<autogenerated>:1) MOVQ (CX)(DX*1), SI
0x0046 00070 (<autogenerated>:1) MOVQ "".j+32(FP), DI
0x004b 00075 (<autogenerated>:1) CMPQ DI, AX
0x004e 00078 (<autogenerated>:1) JCC $0, 120
0x0050 00080 (<autogenerated>:1) SHLQ $4, DI
0x0054 00084 (<autogenerated>:1) MOVQ 8(CX)(DI*1), AX
0x0059 00089 (<autogenerated>:1) MOVQ (CX)(DI*1), R8
0x005d 00093 (<autogenerated>:1) MOVQ R8, (CX)(DX*1)
0x0061 00097 (<autogenerated>:1) MOVQ AX, 8(CX)(DX*1)
0x0066 00102 (<autogenerated>:1) MOVQ SI, (CX)(DI*1)
0x006a 00106 (<autogenerated>:1) MOVQ BX, 8(CX)(DI*1)
0x006f 00111 (<autogenerated>:1) MOVQ (SP), BP
0x0073 00115 (<autogenerated>:1) ADDQ $8, SP
0x0077 00119 (<autogenerated>:1) RET
0x0078 00120 (<autogenerated>:1) PCDATA $0, $1
0x0078 00120 (<autogenerated>:1) CALL runtime.panicindex(SB)
0x007d 00125 (<autogenerated>:1) UNDEF
0x007f 00127 (<autogenerated>:1) PCDATA $0, $1
0x007f 00127 (<autogenerated>:1) CALL runtime.panicwrap(SB)
0x0084 00132 (<autogenerated>:1) UNDEF
0x0086 00134 (<autogenerated>:1) LEAQ 16(SP), DI
0x008b 00139 (<autogenerated>:1) CMPQ (BX), DI
0x008e 00142 (<autogenerated>:1) JNE 30
0x0090 00144 (<autogenerated>:1) MOVQ SP, (BX)
0x0093 00147 (<autogenerated>:1) JMP 30
Change-Id: Ie8c37f384bba10fbacaa754bb0a6b0a7e520ef01
Reviewed-on: https://go-review.googlesource.com/36893
Reviewed-by: Keith Randall <khr@golang.org>
2017-02-10 15:26:47 -08:00
|
|
|
jne.As = AJNE
|
|
|
|
jne.To.Type = obj.TYPE_BRANCH
|
|
|
|
|
|
|
|
// end:
|
|
|
|
// NOP
|
2017-04-04 14:31:55 -07:00
|
|
|
end := obj.Appendp(jne, newprog)
|
cmd/internal/obj/x86: improve static branch prediction for wrapper prologue
Static branch prediction assumes that forward branches are not taken.
The existing wrapper prologue almost always takes the first forward
branch.
Move the rare case to the end of the function.
This CL is amd64 only. Other architectures will be done in separate CLs.
Updates #19042.
Package sort benchmarks:
SearchWrappers-8 104ns ± 2% 104ns ± 0% -0.41% (p=0.006 n=30+41)
SortString1K-8 128µs ± 1% 128µs ± 1% -0.25% (p=0.045 n=30+56)
SortString1K_Slice-8 117µs ± 1% 117µs ± 1% ~ (p=0.855 n=30+59)
StableString1K-8 18.6µs ± 1% 18.6µs ± 1% ~ (p=0.599 n=29+60)
SortInt1K-8 61.0µs ± 1% 56.5µs ± 1% -7.36% (p=0.000 n=29+58)
StableInt1K-8 74.6µs ± 1% 70.4µs ± 3% -5.54% (p=0.000 n=28+60)
StableInt1K_Slice-8 59.9µs ± 1% 58.3µs ± 4% -2.64% (p=0.000 n=29+60)
SortInt64K-8 6.02ms ± 2% 5.98ms ± 2% -0.60% (p=0.000 n=29+59)
SortInt64K_Slice-8 5.07ms ± 2% 5.05ms ± 2% -0.38% (p=0.006 n=30+58)
StableInt64K-8 6.41ms ± 1% 6.22ms ± 1% -3.00% (p=0.000 n=27+58)
Sort1e2-8 37.4µs ± 1% 37.1µs ± 1% -0.91% (p=0.000 n=30+57)
Stable1e2-8 74.8µs ± 1% 75.2µs ± 1% +0.52% (p=0.000 n=30+57)
Sort1e4-8 8.11ms ± 1% 8.01ms ± 1% -1.20% (p=0.000 n=30+59)
Stable1e4-8 24.3ms ± 1% 24.3ms ± 1% ~ (p=0.157 n=30+60)
Sort1e6-8 1.25s ± 1% 1.23s ± 1% -1.43% (p=0.000 n=29+58)
Stable1e6-8 4.93s ± 1% 4.90s ± 1% -0.56% (p=0.000 n=29+59)
[Geo mean] 720µs 709µs -1.52%
Assembly for sort.(*intPairs).Swap:
Before:
"".(*intPairs).Swap t=1 size=147 args=0x18 locals=0x8
0x0000 00000 (<autogenerated>:1) TEXT "".(*intPairs).Swap(SB), $8-24
0x0000 00000 (<autogenerated>:1) MOVQ (TLS), CX
0x0009 00009 (<autogenerated>:1) SUBQ $8, SP
0x000d 00013 (<autogenerated>:1) MOVQ BP, (SP)
0x0011 00017 (<autogenerated>:1) LEAQ (SP), BP
0x0015 00021 (<autogenerated>:1) MOVQ 32(CX), BX
0x0019 00025 (<autogenerated>:1) TESTQ BX, BX
0x001c 00028 (<autogenerated>:1) JEQ 43
0x001e 00030 (<autogenerated>:1) LEAQ 16(SP), DI
0x0023 00035 (<autogenerated>:1) CMPQ (BX), DI
0x0026 00038 (<autogenerated>:1) JNE 43
0x0028 00040 (<autogenerated>:1) MOVQ SP, (BX)
0x002b 00043 (<autogenerated>:1) NOP
0x002b 00043 (<autogenerated>:1) FUNCDATA $0, gclocals·e6397a44f8e1b6e77d0f200b4fba5269(SB)
0x002b 00043 (<autogenerated>:1) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x002b 00043 (<autogenerated>:1) MOVQ ""..this+16(FP), AX
0x0030 00048 (<autogenerated>:1) TESTQ AX, AX
0x0033 00051 (<autogenerated>:1) JEQ $0, 140
0x0035 00053 (<autogenerated>:1) MOVQ (AX), CX
0x0038 00056 (<autogenerated>:1) MOVQ 8(AX), AX
0x003c 00060 (<autogenerated>:1) MOVQ "".i+24(FP), DX
0x0041 00065 (<autogenerated>:1) CMPQ DX, AX
0x0044 00068 (<autogenerated>:1) JCC $0, 133
0x0046 00070 (<autogenerated>:1) SHLQ $4, DX
0x004a 00074 (<autogenerated>:1) MOVQ 8(CX)(DX*1), BX
0x004f 00079 (<autogenerated>:1) MOVQ (CX)(DX*1), SI
0x0053 00083 (<autogenerated>:1) MOVQ "".j+32(FP), DI
0x0058 00088 (<autogenerated>:1) CMPQ DI, AX
0x005b 00091 (<autogenerated>:1) JCC $0, 133
0x005d 00093 (<autogenerated>:1) SHLQ $4, DI
0x0061 00097 (<autogenerated>:1) MOVQ 8(CX)(DI*1), AX
0x0066 00102 (<autogenerated>:1) MOVQ (CX)(DI*1), R8
0x006a 00106 (<autogenerated>:1) MOVQ R8, (CX)(DX*1)
0x006e 00110 (<autogenerated>:1) MOVQ AX, 8(CX)(DX*1)
0x0073 00115 (<autogenerated>:1) MOVQ SI, (CX)(DI*1)
0x0077 00119 (<autogenerated>:1) MOVQ BX, 8(CX)(DI*1)
0x007c 00124 (<autogenerated>:1) MOVQ (SP), BP
0x0080 00128 (<autogenerated>:1) ADDQ $8, SP
0x0084 00132 (<autogenerated>:1) RET
0x0085 00133 (<autogenerated>:1) PCDATA $0, $1
0x0085 00133 (<autogenerated>:1) CALL runtime.panicindex(SB)
0x008a 00138 (<autogenerated>:1) UNDEF
0x008c 00140 (<autogenerated>:1) PCDATA $0, $1
0x008c 00140 (<autogenerated>:1) CALL runtime.panicwrap(SB)
0x0091 00145 (<autogenerated>:1) UNDEF
After:
"".(*intPairs).Swap t=1 size=149 args=0x18 locals=0x8
0x0000 00000 (<autogenerated>:1) TEXT "".(*intPairs).Swap(SB), $8-24
0x0000 00000 (<autogenerated>:1) MOVQ (TLS), CX
0x0009 00009 (<autogenerated>:1) SUBQ $8, SP
0x000d 00013 (<autogenerated>:1) MOVQ BP, (SP)
0x0011 00017 (<autogenerated>:1) LEAQ (SP), BP
0x0015 00021 (<autogenerated>:1) MOVQ 32(CX), BX
0x0019 00025 (<autogenerated>:1) TESTQ BX, BX
0x001c 00028 (<autogenerated>:1) JNE 134
0x001e 00030 (<autogenerated>:1) NOP
0x001e 00030 (<autogenerated>:1) FUNCDATA $0, gclocals·e6397a44f8e1b6e77d0f200b4fba5269(SB)
0x001e 00030 (<autogenerated>:1) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x001e 00030 (<autogenerated>:1) MOVQ ""..this+16(FP), AX
0x0023 00035 (<autogenerated>:1) TESTQ AX, AX
0x0026 00038 (<autogenerated>:1) JEQ $0, 127
0x0028 00040 (<autogenerated>:1) MOVQ (AX), CX
0x002b 00043 (<autogenerated>:1) MOVQ 8(AX), AX
0x002f 00047 (<autogenerated>:1) MOVQ "".i+24(FP), DX
0x0034 00052 (<autogenerated>:1) CMPQ DX, AX
0x0037 00055 (<autogenerated>:1) JCC $0, 120
0x0039 00057 (<autogenerated>:1) SHLQ $4, DX
0x003d 00061 (<autogenerated>:1) MOVQ 8(CX)(DX*1), BX
0x0042 00066 (<autogenerated>:1) MOVQ (CX)(DX*1), SI
0x0046 00070 (<autogenerated>:1) MOVQ "".j+32(FP), DI
0x004b 00075 (<autogenerated>:1) CMPQ DI, AX
0x004e 00078 (<autogenerated>:1) JCC $0, 120
0x0050 00080 (<autogenerated>:1) SHLQ $4, DI
0x0054 00084 (<autogenerated>:1) MOVQ 8(CX)(DI*1), AX
0x0059 00089 (<autogenerated>:1) MOVQ (CX)(DI*1), R8
0x005d 00093 (<autogenerated>:1) MOVQ R8, (CX)(DX*1)
0x0061 00097 (<autogenerated>:1) MOVQ AX, 8(CX)(DX*1)
0x0066 00102 (<autogenerated>:1) MOVQ SI, (CX)(DI*1)
0x006a 00106 (<autogenerated>:1) MOVQ BX, 8(CX)(DI*1)
0x006f 00111 (<autogenerated>:1) MOVQ (SP), BP
0x0073 00115 (<autogenerated>:1) ADDQ $8, SP
0x0077 00119 (<autogenerated>:1) RET
0x0078 00120 (<autogenerated>:1) PCDATA $0, $1
0x0078 00120 (<autogenerated>:1) CALL runtime.panicindex(SB)
0x007d 00125 (<autogenerated>:1) UNDEF
0x007f 00127 (<autogenerated>:1) PCDATA $0, $1
0x007f 00127 (<autogenerated>:1) CALL runtime.panicwrap(SB)
0x0084 00132 (<autogenerated>:1) UNDEF
0x0086 00134 (<autogenerated>:1) LEAQ 16(SP), DI
0x008b 00139 (<autogenerated>:1) CMPQ (BX), DI
0x008e 00142 (<autogenerated>:1) JNE 30
0x0090 00144 (<autogenerated>:1) MOVQ SP, (BX)
0x0093 00147 (<autogenerated>:1) JMP 30
Change-Id: Ie8c37f384bba10fbacaa754bb0a6b0a7e520ef01
Reviewed-on: https://go-review.googlesource.com/36893
Reviewed-by: Keith Randall <khr@golang.org>
2017-02-10 15:26:47 -08:00
|
|
|
end.As = obj.ANOP
|
|
|
|
|
|
|
|
// Fast forward to end of function.
|
|
|
|
var last *obj.Prog
|
|
|
|
for last = end; last.Link != nil; last = last.Link {
|
|
|
|
}
|
2015-01-19 14:34:58 -05:00
|
|
|
|
2017-02-10 14:56:05 -08:00
|
|
|
// LEAQ (autoffset+8)(SP), DI
|
2017-04-04 14:31:55 -07:00
|
|
|
p = obj.Appendp(last, newprog)
|
2015-01-19 14:34:58 -05:00
|
|
|
p.As = ALEAQ
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
p.From.Type = obj.TYPE_MEM
|
|
|
|
p.From.Reg = REG_SP
|
2016-04-06 12:01:40 -07:00
|
|
|
p.From.Offset = int64(autoffset) + int64(ctxt.Arch.RegSize)
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
p.To.Type = obj.TYPE_REG
|
|
|
|
p.To.Reg = REG_DI
|
2019-10-09 16:22:47 +00:00
|
|
|
if ctxt.Arch.Family == sys.I386 {
|
2015-01-19 14:34:58 -05:00
|
|
|
p.As = ALEAL
|
|
|
|
}
|
|
|
|
|
cmd/internal/obj/x86: improve static branch prediction for wrapper prologue
Static branch prediction assumes that forward branches are not taken.
The existing wrapper prologue almost always takes the first forward
branch.
Move the rare case to the end of the function.
This CL is amd64 only. Other architectures will be done in separate CLs.
Updates #19042.
Package sort benchmarks:
SearchWrappers-8 104ns ± 2% 104ns ± 0% -0.41% (p=0.006 n=30+41)
SortString1K-8 128µs ± 1% 128µs ± 1% -0.25% (p=0.045 n=30+56)
SortString1K_Slice-8 117µs ± 1% 117µs ± 1% ~ (p=0.855 n=30+59)
StableString1K-8 18.6µs ± 1% 18.6µs ± 1% ~ (p=0.599 n=29+60)
SortInt1K-8 61.0µs ± 1% 56.5µs ± 1% -7.36% (p=0.000 n=29+58)
StableInt1K-8 74.6µs ± 1% 70.4µs ± 3% -5.54% (p=0.000 n=28+60)
StableInt1K_Slice-8 59.9µs ± 1% 58.3µs ± 4% -2.64% (p=0.000 n=29+60)
SortInt64K-8 6.02ms ± 2% 5.98ms ± 2% -0.60% (p=0.000 n=29+59)
SortInt64K_Slice-8 5.07ms ± 2% 5.05ms ± 2% -0.38% (p=0.006 n=30+58)
StableInt64K-8 6.41ms ± 1% 6.22ms ± 1% -3.00% (p=0.000 n=27+58)
Sort1e2-8 37.4µs ± 1% 37.1µs ± 1% -0.91% (p=0.000 n=30+57)
Stable1e2-8 74.8µs ± 1% 75.2µs ± 1% +0.52% (p=0.000 n=30+57)
Sort1e4-8 8.11ms ± 1% 8.01ms ± 1% -1.20% (p=0.000 n=30+59)
Stable1e4-8 24.3ms ± 1% 24.3ms ± 1% ~ (p=0.157 n=30+60)
Sort1e6-8 1.25s ± 1% 1.23s ± 1% -1.43% (p=0.000 n=29+58)
Stable1e6-8 4.93s ± 1% 4.90s ± 1% -0.56% (p=0.000 n=29+59)
[Geo mean] 720µs 709µs -1.52%
Assembly for sort.(*intPairs).Swap:
Before:
"".(*intPairs).Swap t=1 size=147 args=0x18 locals=0x8
0x0000 00000 (<autogenerated>:1) TEXT "".(*intPairs).Swap(SB), $8-24
0x0000 00000 (<autogenerated>:1) MOVQ (TLS), CX
0x0009 00009 (<autogenerated>:1) SUBQ $8, SP
0x000d 00013 (<autogenerated>:1) MOVQ BP, (SP)
0x0011 00017 (<autogenerated>:1) LEAQ (SP), BP
0x0015 00021 (<autogenerated>:1) MOVQ 32(CX), BX
0x0019 00025 (<autogenerated>:1) TESTQ BX, BX
0x001c 00028 (<autogenerated>:1) JEQ 43
0x001e 00030 (<autogenerated>:1) LEAQ 16(SP), DI
0x0023 00035 (<autogenerated>:1) CMPQ (BX), DI
0x0026 00038 (<autogenerated>:1) JNE 43
0x0028 00040 (<autogenerated>:1) MOVQ SP, (BX)
0x002b 00043 (<autogenerated>:1) NOP
0x002b 00043 (<autogenerated>:1) FUNCDATA $0, gclocals·e6397a44f8e1b6e77d0f200b4fba5269(SB)
0x002b 00043 (<autogenerated>:1) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x002b 00043 (<autogenerated>:1) MOVQ ""..this+16(FP), AX
0x0030 00048 (<autogenerated>:1) TESTQ AX, AX
0x0033 00051 (<autogenerated>:1) JEQ $0, 140
0x0035 00053 (<autogenerated>:1) MOVQ (AX), CX
0x0038 00056 (<autogenerated>:1) MOVQ 8(AX), AX
0x003c 00060 (<autogenerated>:1) MOVQ "".i+24(FP), DX
0x0041 00065 (<autogenerated>:1) CMPQ DX, AX
0x0044 00068 (<autogenerated>:1) JCC $0, 133
0x0046 00070 (<autogenerated>:1) SHLQ $4, DX
0x004a 00074 (<autogenerated>:1) MOVQ 8(CX)(DX*1), BX
0x004f 00079 (<autogenerated>:1) MOVQ (CX)(DX*1), SI
0x0053 00083 (<autogenerated>:1) MOVQ "".j+32(FP), DI
0x0058 00088 (<autogenerated>:1) CMPQ DI, AX
0x005b 00091 (<autogenerated>:1) JCC $0, 133
0x005d 00093 (<autogenerated>:1) SHLQ $4, DI
0x0061 00097 (<autogenerated>:1) MOVQ 8(CX)(DI*1), AX
0x0066 00102 (<autogenerated>:1) MOVQ (CX)(DI*1), R8
0x006a 00106 (<autogenerated>:1) MOVQ R8, (CX)(DX*1)
0x006e 00110 (<autogenerated>:1) MOVQ AX, 8(CX)(DX*1)
0x0073 00115 (<autogenerated>:1) MOVQ SI, (CX)(DI*1)
0x0077 00119 (<autogenerated>:1) MOVQ BX, 8(CX)(DI*1)
0x007c 00124 (<autogenerated>:1) MOVQ (SP), BP
0x0080 00128 (<autogenerated>:1) ADDQ $8, SP
0x0084 00132 (<autogenerated>:1) RET
0x0085 00133 (<autogenerated>:1) PCDATA $0, $1
0x0085 00133 (<autogenerated>:1) CALL runtime.panicindex(SB)
0x008a 00138 (<autogenerated>:1) UNDEF
0x008c 00140 (<autogenerated>:1) PCDATA $0, $1
0x008c 00140 (<autogenerated>:1) CALL runtime.panicwrap(SB)
0x0091 00145 (<autogenerated>:1) UNDEF
After:
"".(*intPairs).Swap t=1 size=149 args=0x18 locals=0x8
0x0000 00000 (<autogenerated>:1) TEXT "".(*intPairs).Swap(SB), $8-24
0x0000 00000 (<autogenerated>:1) MOVQ (TLS), CX
0x0009 00009 (<autogenerated>:1) SUBQ $8, SP
0x000d 00013 (<autogenerated>:1) MOVQ BP, (SP)
0x0011 00017 (<autogenerated>:1) LEAQ (SP), BP
0x0015 00021 (<autogenerated>:1) MOVQ 32(CX), BX
0x0019 00025 (<autogenerated>:1) TESTQ BX, BX
0x001c 00028 (<autogenerated>:1) JNE 134
0x001e 00030 (<autogenerated>:1) NOP
0x001e 00030 (<autogenerated>:1) FUNCDATA $0, gclocals·e6397a44f8e1b6e77d0f200b4fba5269(SB)
0x001e 00030 (<autogenerated>:1) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x001e 00030 (<autogenerated>:1) MOVQ ""..this+16(FP), AX
0x0023 00035 (<autogenerated>:1) TESTQ AX, AX
0x0026 00038 (<autogenerated>:1) JEQ $0, 127
0x0028 00040 (<autogenerated>:1) MOVQ (AX), CX
0x002b 00043 (<autogenerated>:1) MOVQ 8(AX), AX
0x002f 00047 (<autogenerated>:1) MOVQ "".i+24(FP), DX
0x0034 00052 (<autogenerated>:1) CMPQ DX, AX
0x0037 00055 (<autogenerated>:1) JCC $0, 120
0x0039 00057 (<autogenerated>:1) SHLQ $4, DX
0x003d 00061 (<autogenerated>:1) MOVQ 8(CX)(DX*1), BX
0x0042 00066 (<autogenerated>:1) MOVQ (CX)(DX*1), SI
0x0046 00070 (<autogenerated>:1) MOVQ "".j+32(FP), DI
0x004b 00075 (<autogenerated>:1) CMPQ DI, AX
0x004e 00078 (<autogenerated>:1) JCC $0, 120
0x0050 00080 (<autogenerated>:1) SHLQ $4, DI
0x0054 00084 (<autogenerated>:1) MOVQ 8(CX)(DI*1), AX
0x0059 00089 (<autogenerated>:1) MOVQ (CX)(DI*1), R8
0x005d 00093 (<autogenerated>:1) MOVQ R8, (CX)(DX*1)
0x0061 00097 (<autogenerated>:1) MOVQ AX, 8(CX)(DX*1)
0x0066 00102 (<autogenerated>:1) MOVQ SI, (CX)(DI*1)
0x006a 00106 (<autogenerated>:1) MOVQ BX, 8(CX)(DI*1)
0x006f 00111 (<autogenerated>:1) MOVQ (SP), BP
0x0073 00115 (<autogenerated>:1) ADDQ $8, SP
0x0077 00119 (<autogenerated>:1) RET
0x0078 00120 (<autogenerated>:1) PCDATA $0, $1
0x0078 00120 (<autogenerated>:1) CALL runtime.panicindex(SB)
0x007d 00125 (<autogenerated>:1) UNDEF
0x007f 00127 (<autogenerated>:1) PCDATA $0, $1
0x007f 00127 (<autogenerated>:1) CALL runtime.panicwrap(SB)
0x0084 00132 (<autogenerated>:1) UNDEF
0x0086 00134 (<autogenerated>:1) LEAQ 16(SP), DI
0x008b 00139 (<autogenerated>:1) CMPQ (BX), DI
0x008e 00142 (<autogenerated>:1) JNE 30
0x0090 00144 (<autogenerated>:1) MOVQ SP, (BX)
0x0093 00147 (<autogenerated>:1) JMP 30
Change-Id: Ie8c37f384bba10fbacaa754bb0a6b0a7e520ef01
Reviewed-on: https://go-review.googlesource.com/36893
Reviewed-by: Keith Randall <khr@golang.org>
2017-02-10 15:26:47 -08:00
|
|
|
// Set jne branch target.
|
2020-08-28 17:10:32 +00:00
|
|
|
jne.To.SetTarget(p)
|
cmd/internal/obj/x86: improve static branch prediction for wrapper prologue
Static branch prediction assumes that forward branches are not taken.
The existing wrapper prologue almost always takes the first forward
branch.
Move the rare case to the end of the function.
This CL is amd64 only. Other architectures will be done in separate CLs.
Updates #19042.
Package sort benchmarks:
SearchWrappers-8 104ns ± 2% 104ns ± 0% -0.41% (p=0.006 n=30+41)
SortString1K-8 128µs ± 1% 128µs ± 1% -0.25% (p=0.045 n=30+56)
SortString1K_Slice-8 117µs ± 1% 117µs ± 1% ~ (p=0.855 n=30+59)
StableString1K-8 18.6µs ± 1% 18.6µs ± 1% ~ (p=0.599 n=29+60)
SortInt1K-8 61.0µs ± 1% 56.5µs ± 1% -7.36% (p=0.000 n=29+58)
StableInt1K-8 74.6µs ± 1% 70.4µs ± 3% -5.54% (p=0.000 n=28+60)
StableInt1K_Slice-8 59.9µs ± 1% 58.3µs ± 4% -2.64% (p=0.000 n=29+60)
SortInt64K-8 6.02ms ± 2% 5.98ms ± 2% -0.60% (p=0.000 n=29+59)
SortInt64K_Slice-8 5.07ms ± 2% 5.05ms ± 2% -0.38% (p=0.006 n=30+58)
StableInt64K-8 6.41ms ± 1% 6.22ms ± 1% -3.00% (p=0.000 n=27+58)
Sort1e2-8 37.4µs ± 1% 37.1µs ± 1% -0.91% (p=0.000 n=30+57)
Stable1e2-8 74.8µs ± 1% 75.2µs ± 1% +0.52% (p=0.000 n=30+57)
Sort1e4-8 8.11ms ± 1% 8.01ms ± 1% -1.20% (p=0.000 n=30+59)
Stable1e4-8 24.3ms ± 1% 24.3ms ± 1% ~ (p=0.157 n=30+60)
Sort1e6-8 1.25s ± 1% 1.23s ± 1% -1.43% (p=0.000 n=29+58)
Stable1e6-8 4.93s ± 1% 4.90s ± 1% -0.56% (p=0.000 n=29+59)
[Geo mean] 720µs 709µs -1.52%
Assembly for sort.(*intPairs).Swap:
Before:
"".(*intPairs).Swap t=1 size=147 args=0x18 locals=0x8
0x0000 00000 (<autogenerated>:1) TEXT "".(*intPairs).Swap(SB), $8-24
0x0000 00000 (<autogenerated>:1) MOVQ (TLS), CX
0x0009 00009 (<autogenerated>:1) SUBQ $8, SP
0x000d 00013 (<autogenerated>:1) MOVQ BP, (SP)
0x0011 00017 (<autogenerated>:1) LEAQ (SP), BP
0x0015 00021 (<autogenerated>:1) MOVQ 32(CX), BX
0x0019 00025 (<autogenerated>:1) TESTQ BX, BX
0x001c 00028 (<autogenerated>:1) JEQ 43
0x001e 00030 (<autogenerated>:1) LEAQ 16(SP), DI
0x0023 00035 (<autogenerated>:1) CMPQ (BX), DI
0x0026 00038 (<autogenerated>:1) JNE 43
0x0028 00040 (<autogenerated>:1) MOVQ SP, (BX)
0x002b 00043 (<autogenerated>:1) NOP
0x002b 00043 (<autogenerated>:1) FUNCDATA $0, gclocals·e6397a44f8e1b6e77d0f200b4fba5269(SB)
0x002b 00043 (<autogenerated>:1) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x002b 00043 (<autogenerated>:1) MOVQ ""..this+16(FP), AX
0x0030 00048 (<autogenerated>:1) TESTQ AX, AX
0x0033 00051 (<autogenerated>:1) JEQ $0, 140
0x0035 00053 (<autogenerated>:1) MOVQ (AX), CX
0x0038 00056 (<autogenerated>:1) MOVQ 8(AX), AX
0x003c 00060 (<autogenerated>:1) MOVQ "".i+24(FP), DX
0x0041 00065 (<autogenerated>:1) CMPQ DX, AX
0x0044 00068 (<autogenerated>:1) JCC $0, 133
0x0046 00070 (<autogenerated>:1) SHLQ $4, DX
0x004a 00074 (<autogenerated>:1) MOVQ 8(CX)(DX*1), BX
0x004f 00079 (<autogenerated>:1) MOVQ (CX)(DX*1), SI
0x0053 00083 (<autogenerated>:1) MOVQ "".j+32(FP), DI
0x0058 00088 (<autogenerated>:1) CMPQ DI, AX
0x005b 00091 (<autogenerated>:1) JCC $0, 133
0x005d 00093 (<autogenerated>:1) SHLQ $4, DI
0x0061 00097 (<autogenerated>:1) MOVQ 8(CX)(DI*1), AX
0x0066 00102 (<autogenerated>:1) MOVQ (CX)(DI*1), R8
0x006a 00106 (<autogenerated>:1) MOVQ R8, (CX)(DX*1)
0x006e 00110 (<autogenerated>:1) MOVQ AX, 8(CX)(DX*1)
0x0073 00115 (<autogenerated>:1) MOVQ SI, (CX)(DI*1)
0x0077 00119 (<autogenerated>:1) MOVQ BX, 8(CX)(DI*1)
0x007c 00124 (<autogenerated>:1) MOVQ (SP), BP
0x0080 00128 (<autogenerated>:1) ADDQ $8, SP
0x0084 00132 (<autogenerated>:1) RET
0x0085 00133 (<autogenerated>:1) PCDATA $0, $1
0x0085 00133 (<autogenerated>:1) CALL runtime.panicindex(SB)
0x008a 00138 (<autogenerated>:1) UNDEF
0x008c 00140 (<autogenerated>:1) PCDATA $0, $1
0x008c 00140 (<autogenerated>:1) CALL runtime.panicwrap(SB)
0x0091 00145 (<autogenerated>:1) UNDEF
After:
"".(*intPairs).Swap t=1 size=149 args=0x18 locals=0x8
0x0000 00000 (<autogenerated>:1) TEXT "".(*intPairs).Swap(SB), $8-24
0x0000 00000 (<autogenerated>:1) MOVQ (TLS), CX
0x0009 00009 (<autogenerated>:1) SUBQ $8, SP
0x000d 00013 (<autogenerated>:1) MOVQ BP, (SP)
0x0011 00017 (<autogenerated>:1) LEAQ (SP), BP
0x0015 00021 (<autogenerated>:1) MOVQ 32(CX), BX
0x0019 00025 (<autogenerated>:1) TESTQ BX, BX
0x001c 00028 (<autogenerated>:1) JNE 134
0x001e 00030 (<autogenerated>:1) NOP
0x001e 00030 (<autogenerated>:1) FUNCDATA $0, gclocals·e6397a44f8e1b6e77d0f200b4fba5269(SB)
0x001e 00030 (<autogenerated>:1) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x001e 00030 (<autogenerated>:1) MOVQ ""..this+16(FP), AX
0x0023 00035 (<autogenerated>:1) TESTQ AX, AX
0x0026 00038 (<autogenerated>:1) JEQ $0, 127
0x0028 00040 (<autogenerated>:1) MOVQ (AX), CX
0x002b 00043 (<autogenerated>:1) MOVQ 8(AX), AX
0x002f 00047 (<autogenerated>:1) MOVQ "".i+24(FP), DX
0x0034 00052 (<autogenerated>:1) CMPQ DX, AX
0x0037 00055 (<autogenerated>:1) JCC $0, 120
0x0039 00057 (<autogenerated>:1) SHLQ $4, DX
0x003d 00061 (<autogenerated>:1) MOVQ 8(CX)(DX*1), BX
0x0042 00066 (<autogenerated>:1) MOVQ (CX)(DX*1), SI
0x0046 00070 (<autogenerated>:1) MOVQ "".j+32(FP), DI
0x004b 00075 (<autogenerated>:1) CMPQ DI, AX
0x004e 00078 (<autogenerated>:1) JCC $0, 120
0x0050 00080 (<autogenerated>:1) SHLQ $4, DI
0x0054 00084 (<autogenerated>:1) MOVQ 8(CX)(DI*1), AX
0x0059 00089 (<autogenerated>:1) MOVQ (CX)(DI*1), R8
0x005d 00093 (<autogenerated>:1) MOVQ R8, (CX)(DX*1)
0x0061 00097 (<autogenerated>:1) MOVQ AX, 8(CX)(DX*1)
0x0066 00102 (<autogenerated>:1) MOVQ SI, (CX)(DI*1)
0x006a 00106 (<autogenerated>:1) MOVQ BX, 8(CX)(DI*1)
0x006f 00111 (<autogenerated>:1) MOVQ (SP), BP
0x0073 00115 (<autogenerated>:1) ADDQ $8, SP
0x0077 00119 (<autogenerated>:1) RET
0x0078 00120 (<autogenerated>:1) PCDATA $0, $1
0x0078 00120 (<autogenerated>:1) CALL runtime.panicindex(SB)
0x007d 00125 (<autogenerated>:1) UNDEF
0x007f 00127 (<autogenerated>:1) PCDATA $0, $1
0x007f 00127 (<autogenerated>:1) CALL runtime.panicwrap(SB)
0x0084 00132 (<autogenerated>:1) UNDEF
0x0086 00134 (<autogenerated>:1) LEAQ 16(SP), DI
0x008b 00139 (<autogenerated>:1) CMPQ (BX), DI
0x008e 00142 (<autogenerated>:1) JNE 30
0x0090 00144 (<autogenerated>:1) MOVQ SP, (BX)
0x0093 00147 (<autogenerated>:1) JMP 30
Change-Id: Ie8c37f384bba10fbacaa754bb0a6b0a7e520ef01
Reviewed-on: https://go-review.googlesource.com/36893
Reviewed-by: Keith Randall <khr@golang.org>
2017-02-10 15:26:47 -08:00
|
|
|
|
2017-02-10 14:56:05 -08:00
|
|
|
// CMPQ panic_argp(BX), DI
|
2017-04-04 14:31:55 -07:00
|
|
|
p = obj.Appendp(p, newprog)
|
2015-01-19 14:34:58 -05:00
|
|
|
p.As = ACMPQ
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
p.From.Type = obj.TYPE_MEM
|
|
|
|
p.From.Reg = REG_BX
|
2015-01-19 14:34:58 -05:00
|
|
|
p.From.Offset = 0 // Panic.argp
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
p.To.Type = obj.TYPE_REG
|
|
|
|
p.To.Reg = REG_DI
|
2017-03-26 08:05:40 -07:00
|
|
|
if ctxt.Arch.Family == sys.I386 {
|
cmd/internal/obj/x86: take over i386 duty, clean up PINSRQ, CMPSD
Make cmd/internal/obj/x86 support 32-bit mode and use
instead of cmd/internal/obj/i386. Delete cmd/internal/obj/i386.
Clean up encoding of PINSRQ, CMPSD to use explicit third arg
instead of jamming it into an unused slot of a different arg.
Also fix bug in old6a, which declared the wrong grammar.
The accepted (and encoded) arguments to CMPSD etc are mem,reg not reg,mem.
Code that did try to use mem,reg before would be rejected by liblink,
so only reg,reg ever worked, so existing code is not affected.
After this change, code can use mem,reg successfully.
The real bug here is that the encoding tables inverted the argument
order, making the comparisons all backward from what they say on the page.
It's too late to swap them, though: people have already written code that
expects the inverted comparisons (like in package math, and likely externally).
The best we can do is make the argument that should and can take a
memory operand accept it.
Bit-for-bit compatibility checked against tree without this CL.
Change-Id: Ife5685bc98c95001f64407f35066b34b4dae11c1
Reviewed-on: https://go-review.googlesource.com/6810
Reviewed-by: Rob Pike <r@golang.org>
2015-03-04 15:46:52 -05:00
|
|
|
p.As = ACMPL
|
|
|
|
}
|
2015-01-19 14:34:58 -05:00
|
|
|
|
2017-02-10 14:56:05 -08:00
|
|
|
// JNE end
|
2017-04-04 14:31:55 -07:00
|
|
|
p = obj.Appendp(p, newprog)
|
2015-01-19 14:34:58 -05:00
|
|
|
p.As = AJNE
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
p.To.Type = obj.TYPE_BRANCH
|
2020-08-28 17:10:32 +00:00
|
|
|
p.To.SetTarget(end)
|
2015-01-19 14:34:58 -05:00
|
|
|
|
2017-02-10 14:56:05 -08:00
|
|
|
// MOVQ SP, panic_argp(BX)
|
2017-04-04 14:31:55 -07:00
|
|
|
p = obj.Appendp(p, newprog)
|
2015-01-19 14:34:58 -05:00
|
|
|
p.As = AMOVQ
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
p.From.Type = obj.TYPE_REG
|
|
|
|
p.From.Reg = REG_SP
|
|
|
|
p.To.Type = obj.TYPE_MEM
|
|
|
|
p.To.Reg = REG_BX
|
2015-01-19 14:34:58 -05:00
|
|
|
p.To.Offset = 0 // Panic.argp
|
2017-03-26 08:05:40 -07:00
|
|
|
if ctxt.Arch.Family == sys.I386 {
|
cmd/internal/obj/x86: take over i386 duty, clean up PINSRQ, CMPSD
Make cmd/internal/obj/x86 support 32-bit mode and use
instead of cmd/internal/obj/i386. Delete cmd/internal/obj/i386.
Clean up encoding of PINSRQ, CMPSD to use explicit third arg
instead of jamming it into an unused slot of a different arg.
Also fix bug in old6a, which declared the wrong grammar.
The accepted (and encoded) arguments to CMPSD etc are mem,reg not reg,mem.
Code that did try to use mem,reg before would be rejected by liblink,
so only reg,reg ever worked, so existing code is not affected.
After this change, code can use mem,reg successfully.
The real bug here is that the encoding tables inverted the argument
order, making the comparisons all backward from what they say on the page.
It's too late to swap them, though: people have already written code that
expects the inverted comparisons (like in package math, and likely externally).
The best we can do is make the argument that should and can take a
memory operand accept it.
Bit-for-bit compatibility checked against tree without this CL.
Change-Id: Ife5685bc98c95001f64407f35066b34b4dae11c1
Reviewed-on: https://go-review.googlesource.com/6810
Reviewed-by: Rob Pike <r@golang.org>
2015-03-04 15:46:52 -05:00
|
|
|
p.As = AMOVL
|
|
|
|
}
|
2015-01-19 14:34:58 -05:00
|
|
|
|
cmd/internal/obj/x86: improve static branch prediction for wrapper prologue
Static branch prediction assumes that forward branches are not taken.
The existing wrapper prologue almost always takes the first forward
branch.
Move the rare case to the end of the function.
This CL is amd64 only. Other architectures will be done in separate CLs.
Updates #19042.
Package sort benchmarks:
SearchWrappers-8 104ns ± 2% 104ns ± 0% -0.41% (p=0.006 n=30+41)
SortString1K-8 128µs ± 1% 128µs ± 1% -0.25% (p=0.045 n=30+56)
SortString1K_Slice-8 117µs ± 1% 117µs ± 1% ~ (p=0.855 n=30+59)
StableString1K-8 18.6µs ± 1% 18.6µs ± 1% ~ (p=0.599 n=29+60)
SortInt1K-8 61.0µs ± 1% 56.5µs ± 1% -7.36% (p=0.000 n=29+58)
StableInt1K-8 74.6µs ± 1% 70.4µs ± 3% -5.54% (p=0.000 n=28+60)
StableInt1K_Slice-8 59.9µs ± 1% 58.3µs ± 4% -2.64% (p=0.000 n=29+60)
SortInt64K-8 6.02ms ± 2% 5.98ms ± 2% -0.60% (p=0.000 n=29+59)
SortInt64K_Slice-8 5.07ms ± 2% 5.05ms ± 2% -0.38% (p=0.006 n=30+58)
StableInt64K-8 6.41ms ± 1% 6.22ms ± 1% -3.00% (p=0.000 n=27+58)
Sort1e2-8 37.4µs ± 1% 37.1µs ± 1% -0.91% (p=0.000 n=30+57)
Stable1e2-8 74.8µs ± 1% 75.2µs ± 1% +0.52% (p=0.000 n=30+57)
Sort1e4-8 8.11ms ± 1% 8.01ms ± 1% -1.20% (p=0.000 n=30+59)
Stable1e4-8 24.3ms ± 1% 24.3ms ± 1% ~ (p=0.157 n=30+60)
Sort1e6-8 1.25s ± 1% 1.23s ± 1% -1.43% (p=0.000 n=29+58)
Stable1e6-8 4.93s ± 1% 4.90s ± 1% -0.56% (p=0.000 n=29+59)
[Geo mean] 720µs 709µs -1.52%
Assembly for sort.(*intPairs).Swap:
Before:
"".(*intPairs).Swap t=1 size=147 args=0x18 locals=0x8
0x0000 00000 (<autogenerated>:1) TEXT "".(*intPairs).Swap(SB), $8-24
0x0000 00000 (<autogenerated>:1) MOVQ (TLS), CX
0x0009 00009 (<autogenerated>:1) SUBQ $8, SP
0x000d 00013 (<autogenerated>:1) MOVQ BP, (SP)
0x0011 00017 (<autogenerated>:1) LEAQ (SP), BP
0x0015 00021 (<autogenerated>:1) MOVQ 32(CX), BX
0x0019 00025 (<autogenerated>:1) TESTQ BX, BX
0x001c 00028 (<autogenerated>:1) JEQ 43
0x001e 00030 (<autogenerated>:1) LEAQ 16(SP), DI
0x0023 00035 (<autogenerated>:1) CMPQ (BX), DI
0x0026 00038 (<autogenerated>:1) JNE 43
0x0028 00040 (<autogenerated>:1) MOVQ SP, (BX)
0x002b 00043 (<autogenerated>:1) NOP
0x002b 00043 (<autogenerated>:1) FUNCDATA $0, gclocals·e6397a44f8e1b6e77d0f200b4fba5269(SB)
0x002b 00043 (<autogenerated>:1) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x002b 00043 (<autogenerated>:1) MOVQ ""..this+16(FP), AX
0x0030 00048 (<autogenerated>:1) TESTQ AX, AX
0x0033 00051 (<autogenerated>:1) JEQ $0, 140
0x0035 00053 (<autogenerated>:1) MOVQ (AX), CX
0x0038 00056 (<autogenerated>:1) MOVQ 8(AX), AX
0x003c 00060 (<autogenerated>:1) MOVQ "".i+24(FP), DX
0x0041 00065 (<autogenerated>:1) CMPQ DX, AX
0x0044 00068 (<autogenerated>:1) JCC $0, 133
0x0046 00070 (<autogenerated>:1) SHLQ $4, DX
0x004a 00074 (<autogenerated>:1) MOVQ 8(CX)(DX*1), BX
0x004f 00079 (<autogenerated>:1) MOVQ (CX)(DX*1), SI
0x0053 00083 (<autogenerated>:1) MOVQ "".j+32(FP), DI
0x0058 00088 (<autogenerated>:1) CMPQ DI, AX
0x005b 00091 (<autogenerated>:1) JCC $0, 133
0x005d 00093 (<autogenerated>:1) SHLQ $4, DI
0x0061 00097 (<autogenerated>:1) MOVQ 8(CX)(DI*1), AX
0x0066 00102 (<autogenerated>:1) MOVQ (CX)(DI*1), R8
0x006a 00106 (<autogenerated>:1) MOVQ R8, (CX)(DX*1)
0x006e 00110 (<autogenerated>:1) MOVQ AX, 8(CX)(DX*1)
0x0073 00115 (<autogenerated>:1) MOVQ SI, (CX)(DI*1)
0x0077 00119 (<autogenerated>:1) MOVQ BX, 8(CX)(DI*1)
0x007c 00124 (<autogenerated>:1) MOVQ (SP), BP
0x0080 00128 (<autogenerated>:1) ADDQ $8, SP
0x0084 00132 (<autogenerated>:1) RET
0x0085 00133 (<autogenerated>:1) PCDATA $0, $1
0x0085 00133 (<autogenerated>:1) CALL runtime.panicindex(SB)
0x008a 00138 (<autogenerated>:1) UNDEF
0x008c 00140 (<autogenerated>:1) PCDATA $0, $1
0x008c 00140 (<autogenerated>:1) CALL runtime.panicwrap(SB)
0x0091 00145 (<autogenerated>:1) UNDEF
After:
"".(*intPairs).Swap t=1 size=149 args=0x18 locals=0x8
0x0000 00000 (<autogenerated>:1) TEXT "".(*intPairs).Swap(SB), $8-24
0x0000 00000 (<autogenerated>:1) MOVQ (TLS), CX
0x0009 00009 (<autogenerated>:1) SUBQ $8, SP
0x000d 00013 (<autogenerated>:1) MOVQ BP, (SP)
0x0011 00017 (<autogenerated>:1) LEAQ (SP), BP
0x0015 00021 (<autogenerated>:1) MOVQ 32(CX), BX
0x0019 00025 (<autogenerated>:1) TESTQ BX, BX
0x001c 00028 (<autogenerated>:1) JNE 134
0x001e 00030 (<autogenerated>:1) NOP
0x001e 00030 (<autogenerated>:1) FUNCDATA $0, gclocals·e6397a44f8e1b6e77d0f200b4fba5269(SB)
0x001e 00030 (<autogenerated>:1) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x001e 00030 (<autogenerated>:1) MOVQ ""..this+16(FP), AX
0x0023 00035 (<autogenerated>:1) TESTQ AX, AX
0x0026 00038 (<autogenerated>:1) JEQ $0, 127
0x0028 00040 (<autogenerated>:1) MOVQ (AX), CX
0x002b 00043 (<autogenerated>:1) MOVQ 8(AX), AX
0x002f 00047 (<autogenerated>:1) MOVQ "".i+24(FP), DX
0x0034 00052 (<autogenerated>:1) CMPQ DX, AX
0x0037 00055 (<autogenerated>:1) JCC $0, 120
0x0039 00057 (<autogenerated>:1) SHLQ $4, DX
0x003d 00061 (<autogenerated>:1) MOVQ 8(CX)(DX*1), BX
0x0042 00066 (<autogenerated>:1) MOVQ (CX)(DX*1), SI
0x0046 00070 (<autogenerated>:1) MOVQ "".j+32(FP), DI
0x004b 00075 (<autogenerated>:1) CMPQ DI, AX
0x004e 00078 (<autogenerated>:1) JCC $0, 120
0x0050 00080 (<autogenerated>:1) SHLQ $4, DI
0x0054 00084 (<autogenerated>:1) MOVQ 8(CX)(DI*1), AX
0x0059 00089 (<autogenerated>:1) MOVQ (CX)(DI*1), R8
0x005d 00093 (<autogenerated>:1) MOVQ R8, (CX)(DX*1)
0x0061 00097 (<autogenerated>:1) MOVQ AX, 8(CX)(DX*1)
0x0066 00102 (<autogenerated>:1) MOVQ SI, (CX)(DI*1)
0x006a 00106 (<autogenerated>:1) MOVQ BX, 8(CX)(DI*1)
0x006f 00111 (<autogenerated>:1) MOVQ (SP), BP
0x0073 00115 (<autogenerated>:1) ADDQ $8, SP
0x0077 00119 (<autogenerated>:1) RET
0x0078 00120 (<autogenerated>:1) PCDATA $0, $1
0x0078 00120 (<autogenerated>:1) CALL runtime.panicindex(SB)
0x007d 00125 (<autogenerated>:1) UNDEF
0x007f 00127 (<autogenerated>:1) PCDATA $0, $1
0x007f 00127 (<autogenerated>:1) CALL runtime.panicwrap(SB)
0x0084 00132 (<autogenerated>:1) UNDEF
0x0086 00134 (<autogenerated>:1) LEAQ 16(SP), DI
0x008b 00139 (<autogenerated>:1) CMPQ (BX), DI
0x008e 00142 (<autogenerated>:1) JNE 30
0x0090 00144 (<autogenerated>:1) MOVQ SP, (BX)
0x0093 00147 (<autogenerated>:1) JMP 30
Change-Id: Ie8c37f384bba10fbacaa754bb0a6b0a7e520ef01
Reviewed-on: https://go-review.googlesource.com/36893
Reviewed-by: Keith Randall <khr@golang.org>
2017-02-10 15:26:47 -08:00
|
|
|
// JMP end
|
2017-04-04 14:31:55 -07:00
|
|
|
p = obj.Appendp(p, newprog)
|
cmd/internal/obj/x86: improve static branch prediction for wrapper prologue
Static branch prediction assumes that forward branches are not taken.
The existing wrapper prologue almost always takes the first forward
branch.
Move the rare case to the end of the function.
This CL is amd64 only. Other architectures will be done in separate CLs.
Updates #19042.
Package sort benchmarks:
SearchWrappers-8 104ns ± 2% 104ns ± 0% -0.41% (p=0.006 n=30+41)
SortString1K-8 128µs ± 1% 128µs ± 1% -0.25% (p=0.045 n=30+56)
SortString1K_Slice-8 117µs ± 1% 117µs ± 1% ~ (p=0.855 n=30+59)
StableString1K-8 18.6µs ± 1% 18.6µs ± 1% ~ (p=0.599 n=29+60)
SortInt1K-8 61.0µs ± 1% 56.5µs ± 1% -7.36% (p=0.000 n=29+58)
StableInt1K-8 74.6µs ± 1% 70.4µs ± 3% -5.54% (p=0.000 n=28+60)
StableInt1K_Slice-8 59.9µs ± 1% 58.3µs ± 4% -2.64% (p=0.000 n=29+60)
SortInt64K-8 6.02ms ± 2% 5.98ms ± 2% -0.60% (p=0.000 n=29+59)
SortInt64K_Slice-8 5.07ms ± 2% 5.05ms ± 2% -0.38% (p=0.006 n=30+58)
StableInt64K-8 6.41ms ± 1% 6.22ms ± 1% -3.00% (p=0.000 n=27+58)
Sort1e2-8 37.4µs ± 1% 37.1µs ± 1% -0.91% (p=0.000 n=30+57)
Stable1e2-8 74.8µs ± 1% 75.2µs ± 1% +0.52% (p=0.000 n=30+57)
Sort1e4-8 8.11ms ± 1% 8.01ms ± 1% -1.20% (p=0.000 n=30+59)
Stable1e4-8 24.3ms ± 1% 24.3ms ± 1% ~ (p=0.157 n=30+60)
Sort1e6-8 1.25s ± 1% 1.23s ± 1% -1.43% (p=0.000 n=29+58)
Stable1e6-8 4.93s ± 1% 4.90s ± 1% -0.56% (p=0.000 n=29+59)
[Geo mean] 720µs 709µs -1.52%
Assembly for sort.(*intPairs).Swap:
Before:
"".(*intPairs).Swap t=1 size=147 args=0x18 locals=0x8
0x0000 00000 (<autogenerated>:1) TEXT "".(*intPairs).Swap(SB), $8-24
0x0000 00000 (<autogenerated>:1) MOVQ (TLS), CX
0x0009 00009 (<autogenerated>:1) SUBQ $8, SP
0x000d 00013 (<autogenerated>:1) MOVQ BP, (SP)
0x0011 00017 (<autogenerated>:1) LEAQ (SP), BP
0x0015 00021 (<autogenerated>:1) MOVQ 32(CX), BX
0x0019 00025 (<autogenerated>:1) TESTQ BX, BX
0x001c 00028 (<autogenerated>:1) JEQ 43
0x001e 00030 (<autogenerated>:1) LEAQ 16(SP), DI
0x0023 00035 (<autogenerated>:1) CMPQ (BX), DI
0x0026 00038 (<autogenerated>:1) JNE 43
0x0028 00040 (<autogenerated>:1) MOVQ SP, (BX)
0x002b 00043 (<autogenerated>:1) NOP
0x002b 00043 (<autogenerated>:1) FUNCDATA $0, gclocals·e6397a44f8e1b6e77d0f200b4fba5269(SB)
0x002b 00043 (<autogenerated>:1) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x002b 00043 (<autogenerated>:1) MOVQ ""..this+16(FP), AX
0x0030 00048 (<autogenerated>:1) TESTQ AX, AX
0x0033 00051 (<autogenerated>:1) JEQ $0, 140
0x0035 00053 (<autogenerated>:1) MOVQ (AX), CX
0x0038 00056 (<autogenerated>:1) MOVQ 8(AX), AX
0x003c 00060 (<autogenerated>:1) MOVQ "".i+24(FP), DX
0x0041 00065 (<autogenerated>:1) CMPQ DX, AX
0x0044 00068 (<autogenerated>:1) JCC $0, 133
0x0046 00070 (<autogenerated>:1) SHLQ $4, DX
0x004a 00074 (<autogenerated>:1) MOVQ 8(CX)(DX*1), BX
0x004f 00079 (<autogenerated>:1) MOVQ (CX)(DX*1), SI
0x0053 00083 (<autogenerated>:1) MOVQ "".j+32(FP), DI
0x0058 00088 (<autogenerated>:1) CMPQ DI, AX
0x005b 00091 (<autogenerated>:1) JCC $0, 133
0x005d 00093 (<autogenerated>:1) SHLQ $4, DI
0x0061 00097 (<autogenerated>:1) MOVQ 8(CX)(DI*1), AX
0x0066 00102 (<autogenerated>:1) MOVQ (CX)(DI*1), R8
0x006a 00106 (<autogenerated>:1) MOVQ R8, (CX)(DX*1)
0x006e 00110 (<autogenerated>:1) MOVQ AX, 8(CX)(DX*1)
0x0073 00115 (<autogenerated>:1) MOVQ SI, (CX)(DI*1)
0x0077 00119 (<autogenerated>:1) MOVQ BX, 8(CX)(DI*1)
0x007c 00124 (<autogenerated>:1) MOVQ (SP), BP
0x0080 00128 (<autogenerated>:1) ADDQ $8, SP
0x0084 00132 (<autogenerated>:1) RET
0x0085 00133 (<autogenerated>:1) PCDATA $0, $1
0x0085 00133 (<autogenerated>:1) CALL runtime.panicindex(SB)
0x008a 00138 (<autogenerated>:1) UNDEF
0x008c 00140 (<autogenerated>:1) PCDATA $0, $1
0x008c 00140 (<autogenerated>:1) CALL runtime.panicwrap(SB)
0x0091 00145 (<autogenerated>:1) UNDEF
After:
"".(*intPairs).Swap t=1 size=149 args=0x18 locals=0x8
0x0000 00000 (<autogenerated>:1) TEXT "".(*intPairs).Swap(SB), $8-24
0x0000 00000 (<autogenerated>:1) MOVQ (TLS), CX
0x0009 00009 (<autogenerated>:1) SUBQ $8, SP
0x000d 00013 (<autogenerated>:1) MOVQ BP, (SP)
0x0011 00017 (<autogenerated>:1) LEAQ (SP), BP
0x0015 00021 (<autogenerated>:1) MOVQ 32(CX), BX
0x0019 00025 (<autogenerated>:1) TESTQ BX, BX
0x001c 00028 (<autogenerated>:1) JNE 134
0x001e 00030 (<autogenerated>:1) NOP
0x001e 00030 (<autogenerated>:1) FUNCDATA $0, gclocals·e6397a44f8e1b6e77d0f200b4fba5269(SB)
0x001e 00030 (<autogenerated>:1) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x001e 00030 (<autogenerated>:1) MOVQ ""..this+16(FP), AX
0x0023 00035 (<autogenerated>:1) TESTQ AX, AX
0x0026 00038 (<autogenerated>:1) JEQ $0, 127
0x0028 00040 (<autogenerated>:1) MOVQ (AX), CX
0x002b 00043 (<autogenerated>:1) MOVQ 8(AX), AX
0x002f 00047 (<autogenerated>:1) MOVQ "".i+24(FP), DX
0x0034 00052 (<autogenerated>:1) CMPQ DX, AX
0x0037 00055 (<autogenerated>:1) JCC $0, 120
0x0039 00057 (<autogenerated>:1) SHLQ $4, DX
0x003d 00061 (<autogenerated>:1) MOVQ 8(CX)(DX*1), BX
0x0042 00066 (<autogenerated>:1) MOVQ (CX)(DX*1), SI
0x0046 00070 (<autogenerated>:1) MOVQ "".j+32(FP), DI
0x004b 00075 (<autogenerated>:1) CMPQ DI, AX
0x004e 00078 (<autogenerated>:1) JCC $0, 120
0x0050 00080 (<autogenerated>:1) SHLQ $4, DI
0x0054 00084 (<autogenerated>:1) MOVQ 8(CX)(DI*1), AX
0x0059 00089 (<autogenerated>:1) MOVQ (CX)(DI*1), R8
0x005d 00093 (<autogenerated>:1) MOVQ R8, (CX)(DX*1)
0x0061 00097 (<autogenerated>:1) MOVQ AX, 8(CX)(DX*1)
0x0066 00102 (<autogenerated>:1) MOVQ SI, (CX)(DI*1)
0x006a 00106 (<autogenerated>:1) MOVQ BX, 8(CX)(DI*1)
0x006f 00111 (<autogenerated>:1) MOVQ (SP), BP
0x0073 00115 (<autogenerated>:1) ADDQ $8, SP
0x0077 00119 (<autogenerated>:1) RET
0x0078 00120 (<autogenerated>:1) PCDATA $0, $1
0x0078 00120 (<autogenerated>:1) CALL runtime.panicindex(SB)
0x007d 00125 (<autogenerated>:1) UNDEF
0x007f 00127 (<autogenerated>:1) PCDATA $0, $1
0x007f 00127 (<autogenerated>:1) CALL runtime.panicwrap(SB)
0x0084 00132 (<autogenerated>:1) UNDEF
0x0086 00134 (<autogenerated>:1) LEAQ 16(SP), DI
0x008b 00139 (<autogenerated>:1) CMPQ (BX), DI
0x008e 00142 (<autogenerated>:1) JNE 30
0x0090 00144 (<autogenerated>:1) MOVQ SP, (BX)
0x0093 00147 (<autogenerated>:1) JMP 30
Change-Id: Ie8c37f384bba10fbacaa754bb0a6b0a7e520ef01
Reviewed-on: https://go-review.googlesource.com/36893
Reviewed-by: Keith Randall <khr@golang.org>
2017-02-10 15:26:47 -08:00
|
|
|
p.As = obj.AJMP
|
|
|
|
p.To.Type = obj.TYPE_BRANCH
|
2020-08-28 17:10:32 +00:00
|
|
|
p.To.SetTarget(end)
|
2017-02-10 14:56:05 -08:00
|
|
|
|
cmd/internal/obj/x86: improve static branch prediction for wrapper prologue
Static branch prediction assumes that forward branches are not taken.
The existing wrapper prologue almost always takes the first forward
branch.
Move the rare case to the end of the function.
This CL is amd64 only. Other architectures will be done in separate CLs.
Updates #19042.
Package sort benchmarks:
SearchWrappers-8 104ns ± 2% 104ns ± 0% -0.41% (p=0.006 n=30+41)
SortString1K-8 128µs ± 1% 128µs ± 1% -0.25% (p=0.045 n=30+56)
SortString1K_Slice-8 117µs ± 1% 117µs ± 1% ~ (p=0.855 n=30+59)
StableString1K-8 18.6µs ± 1% 18.6µs ± 1% ~ (p=0.599 n=29+60)
SortInt1K-8 61.0µs ± 1% 56.5µs ± 1% -7.36% (p=0.000 n=29+58)
StableInt1K-8 74.6µs ± 1% 70.4µs ± 3% -5.54% (p=0.000 n=28+60)
StableInt1K_Slice-8 59.9µs ± 1% 58.3µs ± 4% -2.64% (p=0.000 n=29+60)
SortInt64K-8 6.02ms ± 2% 5.98ms ± 2% -0.60% (p=0.000 n=29+59)
SortInt64K_Slice-8 5.07ms ± 2% 5.05ms ± 2% -0.38% (p=0.006 n=30+58)
StableInt64K-8 6.41ms ± 1% 6.22ms ± 1% -3.00% (p=0.000 n=27+58)
Sort1e2-8 37.4µs ± 1% 37.1µs ± 1% -0.91% (p=0.000 n=30+57)
Stable1e2-8 74.8µs ± 1% 75.2µs ± 1% +0.52% (p=0.000 n=30+57)
Sort1e4-8 8.11ms ± 1% 8.01ms ± 1% -1.20% (p=0.000 n=30+59)
Stable1e4-8 24.3ms ± 1% 24.3ms ± 1% ~ (p=0.157 n=30+60)
Sort1e6-8 1.25s ± 1% 1.23s ± 1% -1.43% (p=0.000 n=29+58)
Stable1e6-8 4.93s ± 1% 4.90s ± 1% -0.56% (p=0.000 n=29+59)
[Geo mean] 720µs 709µs -1.52%
Assembly for sort.(*intPairs).Swap:
Before:
"".(*intPairs).Swap t=1 size=147 args=0x18 locals=0x8
0x0000 00000 (<autogenerated>:1) TEXT "".(*intPairs).Swap(SB), $8-24
0x0000 00000 (<autogenerated>:1) MOVQ (TLS), CX
0x0009 00009 (<autogenerated>:1) SUBQ $8, SP
0x000d 00013 (<autogenerated>:1) MOVQ BP, (SP)
0x0011 00017 (<autogenerated>:1) LEAQ (SP), BP
0x0015 00021 (<autogenerated>:1) MOVQ 32(CX), BX
0x0019 00025 (<autogenerated>:1) TESTQ BX, BX
0x001c 00028 (<autogenerated>:1) JEQ 43
0x001e 00030 (<autogenerated>:1) LEAQ 16(SP), DI
0x0023 00035 (<autogenerated>:1) CMPQ (BX), DI
0x0026 00038 (<autogenerated>:1) JNE 43
0x0028 00040 (<autogenerated>:1) MOVQ SP, (BX)
0x002b 00043 (<autogenerated>:1) NOP
0x002b 00043 (<autogenerated>:1) FUNCDATA $0, gclocals·e6397a44f8e1b6e77d0f200b4fba5269(SB)
0x002b 00043 (<autogenerated>:1) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x002b 00043 (<autogenerated>:1) MOVQ ""..this+16(FP), AX
0x0030 00048 (<autogenerated>:1) TESTQ AX, AX
0x0033 00051 (<autogenerated>:1) JEQ $0, 140
0x0035 00053 (<autogenerated>:1) MOVQ (AX), CX
0x0038 00056 (<autogenerated>:1) MOVQ 8(AX), AX
0x003c 00060 (<autogenerated>:1) MOVQ "".i+24(FP), DX
0x0041 00065 (<autogenerated>:1) CMPQ DX, AX
0x0044 00068 (<autogenerated>:1) JCC $0, 133
0x0046 00070 (<autogenerated>:1) SHLQ $4, DX
0x004a 00074 (<autogenerated>:1) MOVQ 8(CX)(DX*1), BX
0x004f 00079 (<autogenerated>:1) MOVQ (CX)(DX*1), SI
0x0053 00083 (<autogenerated>:1) MOVQ "".j+32(FP), DI
0x0058 00088 (<autogenerated>:1) CMPQ DI, AX
0x005b 00091 (<autogenerated>:1) JCC $0, 133
0x005d 00093 (<autogenerated>:1) SHLQ $4, DI
0x0061 00097 (<autogenerated>:1) MOVQ 8(CX)(DI*1), AX
0x0066 00102 (<autogenerated>:1) MOVQ (CX)(DI*1), R8
0x006a 00106 (<autogenerated>:1) MOVQ R8, (CX)(DX*1)
0x006e 00110 (<autogenerated>:1) MOVQ AX, 8(CX)(DX*1)
0x0073 00115 (<autogenerated>:1) MOVQ SI, (CX)(DI*1)
0x0077 00119 (<autogenerated>:1) MOVQ BX, 8(CX)(DI*1)
0x007c 00124 (<autogenerated>:1) MOVQ (SP), BP
0x0080 00128 (<autogenerated>:1) ADDQ $8, SP
0x0084 00132 (<autogenerated>:1) RET
0x0085 00133 (<autogenerated>:1) PCDATA $0, $1
0x0085 00133 (<autogenerated>:1) CALL runtime.panicindex(SB)
0x008a 00138 (<autogenerated>:1) UNDEF
0x008c 00140 (<autogenerated>:1) PCDATA $0, $1
0x008c 00140 (<autogenerated>:1) CALL runtime.panicwrap(SB)
0x0091 00145 (<autogenerated>:1) UNDEF
After:
"".(*intPairs).Swap t=1 size=149 args=0x18 locals=0x8
0x0000 00000 (<autogenerated>:1) TEXT "".(*intPairs).Swap(SB), $8-24
0x0000 00000 (<autogenerated>:1) MOVQ (TLS), CX
0x0009 00009 (<autogenerated>:1) SUBQ $8, SP
0x000d 00013 (<autogenerated>:1) MOVQ BP, (SP)
0x0011 00017 (<autogenerated>:1) LEAQ (SP), BP
0x0015 00021 (<autogenerated>:1) MOVQ 32(CX), BX
0x0019 00025 (<autogenerated>:1) TESTQ BX, BX
0x001c 00028 (<autogenerated>:1) JNE 134
0x001e 00030 (<autogenerated>:1) NOP
0x001e 00030 (<autogenerated>:1) FUNCDATA $0, gclocals·e6397a44f8e1b6e77d0f200b4fba5269(SB)
0x001e 00030 (<autogenerated>:1) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x001e 00030 (<autogenerated>:1) MOVQ ""..this+16(FP), AX
0x0023 00035 (<autogenerated>:1) TESTQ AX, AX
0x0026 00038 (<autogenerated>:1) JEQ $0, 127
0x0028 00040 (<autogenerated>:1) MOVQ (AX), CX
0x002b 00043 (<autogenerated>:1) MOVQ 8(AX), AX
0x002f 00047 (<autogenerated>:1) MOVQ "".i+24(FP), DX
0x0034 00052 (<autogenerated>:1) CMPQ DX, AX
0x0037 00055 (<autogenerated>:1) JCC $0, 120
0x0039 00057 (<autogenerated>:1) SHLQ $4, DX
0x003d 00061 (<autogenerated>:1) MOVQ 8(CX)(DX*1), BX
0x0042 00066 (<autogenerated>:1) MOVQ (CX)(DX*1), SI
0x0046 00070 (<autogenerated>:1) MOVQ "".j+32(FP), DI
0x004b 00075 (<autogenerated>:1) CMPQ DI, AX
0x004e 00078 (<autogenerated>:1) JCC $0, 120
0x0050 00080 (<autogenerated>:1) SHLQ $4, DI
0x0054 00084 (<autogenerated>:1) MOVQ 8(CX)(DI*1), AX
0x0059 00089 (<autogenerated>:1) MOVQ (CX)(DI*1), R8
0x005d 00093 (<autogenerated>:1) MOVQ R8, (CX)(DX*1)
0x0061 00097 (<autogenerated>:1) MOVQ AX, 8(CX)(DX*1)
0x0066 00102 (<autogenerated>:1) MOVQ SI, (CX)(DI*1)
0x006a 00106 (<autogenerated>:1) MOVQ BX, 8(CX)(DI*1)
0x006f 00111 (<autogenerated>:1) MOVQ (SP), BP
0x0073 00115 (<autogenerated>:1) ADDQ $8, SP
0x0077 00119 (<autogenerated>:1) RET
0x0078 00120 (<autogenerated>:1) PCDATA $0, $1
0x0078 00120 (<autogenerated>:1) CALL runtime.panicindex(SB)
0x007d 00125 (<autogenerated>:1) UNDEF
0x007f 00127 (<autogenerated>:1) PCDATA $0, $1
0x007f 00127 (<autogenerated>:1) CALL runtime.panicwrap(SB)
0x0084 00132 (<autogenerated>:1) UNDEF
0x0086 00134 (<autogenerated>:1) LEAQ 16(SP), DI
0x008b 00139 (<autogenerated>:1) CMPQ (BX), DI
0x008e 00142 (<autogenerated>:1) JNE 30
0x0090 00144 (<autogenerated>:1) MOVQ SP, (BX)
0x0093 00147 (<autogenerated>:1) JMP 30
Change-Id: Ie8c37f384bba10fbacaa754bb0a6b0a7e520ef01
Reviewed-on: https://go-review.googlesource.com/36893
Reviewed-by: Keith Randall <khr@golang.org>
2017-02-10 15:26:47 -08:00
|
|
|
// Reset p for following code.
|
|
|
|
p = end
|
2015-01-19 14:34:58 -05:00
|
|
|
}
|
|
|
|
|
cmd/internal/obj/x86: correct pcsp for ADJSP
The x86 assembler supports an "ADJSP" pseudo-op that compiles to an
ADD/SUB from SP. Unfortunately, while this seems perfect for an
instruction that would allow obj to continue to track the SP/FP delta,
obj currently doesn't do that. As a result, FP-relative references
won't work and, perhaps worse, the pcsp table will have the wrong
frame size.
We don't currently use this instruction in any assembly or generate it
in the compiler, but this is a perfect instruction for solving a
problem in #24543.
This CL makes ADJSP useful by incorporating it into the SP delta
logic.
One subtlety is that we do generate ADJSP in obj itself to open a
function's stack frame. Currently, when preprocess enters the loop to
compute the SP delta, it may or may not start at this ADJSP
instruction depending on various factors. We clean this up by instead
always starting the SP delta at 0 and always starting this loop at the
entry to the function.
Why not just recognize ADD/SUB of SP? The danger is that could change
the meaning of existing code. For example, walltime1 in
sys_linux_amd64.s saves SP, SUBs from it, and aligns it. Later, it
restores the saved copy and then does a few FP-relative references.
Currently obj doesn't know any of this is happening, but that's fine
once it gets to the FP-relative references. If we taught obj to
recognize the SUB, it would start to miscompile this code. An
alternative would be to recognize unknown instructions that write to
SP and refuse subsequent FP-relative references, but that's kind of
annoying.
This passes toolstash -cmp for std on both amd64 and 386.
Change-Id: Ic6c6a7cbf980bca904576676c07b44c0aaa9c82d
Reviewed-on: https://go-review.googlesource.com/c/go/+/200877
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
2019-10-12 18:35:49 -04:00
|
|
|
var deltasp int32
|
|
|
|
for p = cursym.Func.Text; p != nil; p = p.Link {
|
2017-03-26 08:05:40 -07:00
|
|
|
pcsize := ctxt.Arch.RegSize
|
2016-07-20 10:18:23 -07:00
|
|
|
switch p.From.Name {
|
|
|
|
case obj.NAME_AUTO:
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
p.From.Offset += int64(deltasp) - int64(bpsize)
|
2016-07-20 10:18:23 -07:00
|
|
|
case obj.NAME_PARAM:
|
2015-01-19 14:34:58 -05:00
|
|
|
p.From.Offset += int64(deltasp) + int64(pcsize)
|
|
|
|
}
|
2017-09-13 14:32:08 +03:00
|
|
|
if p.GetFrom3() != nil {
|
|
|
|
switch p.GetFrom3().Name {
|
2016-07-20 10:18:23 -07:00
|
|
|
case obj.NAME_AUTO:
|
2017-09-13 14:32:08 +03:00
|
|
|
p.GetFrom3().Offset += int64(deltasp) - int64(bpsize)
|
2016-07-20 10:18:23 -07:00
|
|
|
case obj.NAME_PARAM:
|
2017-09-13 14:32:08 +03:00
|
|
|
p.GetFrom3().Offset += int64(deltasp) + int64(pcsize)
|
2015-05-27 15:01:44 -04:00
|
|
|
}
|
2015-03-05 00:50:38 -05:00
|
|
|
}
|
2016-07-20 10:18:23 -07:00
|
|
|
switch p.To.Name {
|
|
|
|
case obj.NAME_AUTO:
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
p.To.Offset += int64(deltasp) - int64(bpsize)
|
2016-07-20 10:18:23 -07:00
|
|
|
case obj.NAME_PARAM:
|
2015-01-19 14:34:58 -05:00
|
|
|
p.To.Offset += int64(deltasp) + int64(pcsize)
|
|
|
|
}
|
|
|
|
|
|
|
|
switch p.As {
|
|
|
|
default:
|
|
|
|
continue
|
|
|
|
|
2015-04-01 09:38:44 -07:00
|
|
|
case APUSHL, APUSHFL:
|
2015-01-19 14:34:58 -05:00
|
|
|
deltasp += 4
|
|
|
|
p.Spadj = 4
|
|
|
|
continue
|
|
|
|
|
2015-04-01 09:38:44 -07:00
|
|
|
case APUSHQ, APUSHFQ:
|
2015-01-19 14:34:58 -05:00
|
|
|
deltasp += 8
|
|
|
|
p.Spadj = 8
|
|
|
|
continue
|
|
|
|
|
2015-04-01 09:38:44 -07:00
|
|
|
case APUSHW, APUSHFW:
|
2015-01-19 14:34:58 -05:00
|
|
|
deltasp += 2
|
|
|
|
p.Spadj = 2
|
|
|
|
continue
|
|
|
|
|
2015-04-01 09:38:44 -07:00
|
|
|
case APOPL, APOPFL:
|
2015-01-19 14:34:58 -05:00
|
|
|
deltasp -= 4
|
|
|
|
p.Spadj = -4
|
|
|
|
continue
|
|
|
|
|
2015-04-01 09:38:44 -07:00
|
|
|
case APOPQ, APOPFQ:
|
2015-01-19 14:34:58 -05:00
|
|
|
deltasp -= 8
|
|
|
|
p.Spadj = -8
|
|
|
|
continue
|
|
|
|
|
2015-04-01 09:38:44 -07:00
|
|
|
case APOPW, APOPFW:
|
2015-01-19 14:34:58 -05:00
|
|
|
deltasp -= 2
|
|
|
|
p.Spadj = -2
|
|
|
|
continue
|
|
|
|
|
cmd/internal/obj/x86: correct pcsp for ADJSP
The x86 assembler supports an "ADJSP" pseudo-op that compiles to an
ADD/SUB from SP. Unfortunately, while this seems perfect for an
instruction that would allow obj to continue to track the SP/FP delta,
obj currently doesn't do that. As a result, FP-relative references
won't work and, perhaps worse, the pcsp table will have the wrong
frame size.
We don't currently use this instruction in any assembly or generate it
in the compiler, but this is a perfect instruction for solving a
problem in #24543.
This CL makes ADJSP useful by incorporating it into the SP delta
logic.
One subtlety is that we do generate ADJSP in obj itself to open a
function's stack frame. Currently, when preprocess enters the loop to
compute the SP delta, it may or may not start at this ADJSP
instruction depending on various factors. We clean this up by instead
always starting the SP delta at 0 and always starting this loop at the
entry to the function.
Why not just recognize ADD/SUB of SP? The danger is that could change
the meaning of existing code. For example, walltime1 in
sys_linux_amd64.s saves SP, SUBs from it, and aligns it. Later, it
restores the saved copy and then does a few FP-relative references.
Currently obj doesn't know any of this is happening, but that's fine
once it gets to the FP-relative references. If we taught obj to
recognize the SUB, it would start to miscompile this code. An
alternative would be to recognize unknown instructions that write to
SP and refuse subsequent FP-relative references, but that's kind of
annoying.
This passes toolstash -cmp for std on both amd64 and 386.
Change-Id: Ic6c6a7cbf980bca904576676c07b44c0aaa9c82d
Reviewed-on: https://go-review.googlesource.com/c/go/+/200877
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
2019-10-12 18:35:49 -04:00
|
|
|
case AADJSP:
|
|
|
|
p.Spadj = int32(p.From.Offset)
|
|
|
|
deltasp += int32(p.From.Offset)
|
|
|
|
continue
|
|
|
|
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
case obj.ARET:
|
2016-07-20 10:18:23 -07:00
|
|
|
// do nothing
|
2015-01-19 14:34:58 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
if autoffset != deltasp {
|
|
|
|
ctxt.Diag("unbalanced PUSH/POP")
|
|
|
|
}
|
|
|
|
|
|
|
|
if autoffset != 0 {
|
cmd/internal/obj/x86: adjust SP correctly for tail calls
Currently, tail calls on x86 don't adjust the SP on return, so it's
important that the compiler produce a zero-sized frame and disable the
frame pointer. However, these constraints aren't necessary. For
example, on other architectures it's generally necessary to restore
the saved LR before a tail call, so obj simply makes this work.
Likewise, on x86, there's no reason we can't simply make this work.
Hence, this CL adjusts the compiler to use the same tail call
convention for x86 that we use on LR machines by producing a RET with
a target, rather than a JMP with a target. In fact, obj already
understands this convention for x86 except that it's buggy with
non-zero frame sizes. So we also fix this bug obj. As a result of
these fixes, the compiler no longer needs to mark wrappers as
NoFramePointer since it's now perfectly fine to save the frame
pointer.
In fact, this eliminates the only use of NoFramePointer in the
compiler, which will enable further cleanups.
This also fixes what is very nearly, but not quite, a code generation
bug. NoFramePointer becomes obj.NOFRAME in the object file, which on
ppc64 and s390x means to omit the saved LR. Hence, on these
architectures, NoFramePointer (and NOFRAME) is only safe to set on
leaf functions. However, on *most* architectures, wrappers aren't
necessarily leaf functions because they may call DUFFZERO. We're saved
on ppc64 and s390x only because the compiler doesn't have the rules to
produce DUFFZERO calls on these architectures. Hence, this only works
because the set of LR architectures that implement NOFRAME is disjoint
from the set where the compiler produces DUFFZERO operations. (I
discovered this whole mess when I attempted to add NOFRAME support to
arm.)
Change-Id: Icc589aeb86beacb850d0a6a80bd3024974a33947
Reviewed-on: https://go-review.googlesource.com/92035
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
2018-01-25 11:35:27 -05:00
|
|
|
to := p.To // Keep To attached to RET for retjmp below
|
|
|
|
p.To = obj.Addr{}
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
if bpsize > 0 {
|
|
|
|
// Restore caller's BP
|
|
|
|
p.As = AMOVQ
|
|
|
|
|
|
|
|
p.From.Type = obj.TYPE_MEM
|
|
|
|
p.From.Reg = REG_SP
|
|
|
|
p.From.Scale = 1
|
|
|
|
p.From.Offset = int64(autoffset) - int64(bpsize)
|
|
|
|
p.To.Type = obj.TYPE_REG
|
|
|
|
p.To.Reg = REG_BP
|
2017-04-04 14:31:55 -07:00
|
|
|
p = obj.Appendp(p, newprog)
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
}
|
|
|
|
|
2015-01-19 14:34:58 -05:00
|
|
|
p.As = AADJSP
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
p.From.Type = obj.TYPE_CONST
|
2015-01-19 14:34:58 -05:00
|
|
|
p.From.Offset = int64(-autoffset)
|
|
|
|
p.Spadj = -autoffset
|
2017-04-04 14:31:55 -07:00
|
|
|
p = obj.Appendp(p, newprog)
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
p.As = obj.ARET
|
cmd/internal/obj/x86: adjust SP correctly for tail calls
Currently, tail calls on x86 don't adjust the SP on return, so it's
important that the compiler produce a zero-sized frame and disable the
frame pointer. However, these constraints aren't necessary. For
example, on other architectures it's generally necessary to restore
the saved LR before a tail call, so obj simply makes this work.
Likewise, on x86, there's no reason we can't simply make this work.
Hence, this CL adjusts the compiler to use the same tail call
convention for x86 that we use on LR machines by producing a RET with
a target, rather than a JMP with a target. In fact, obj already
understands this convention for x86 except that it's buggy with
non-zero frame sizes. So we also fix this bug obj. As a result of
these fixes, the compiler no longer needs to mark wrappers as
NoFramePointer since it's now perfectly fine to save the frame
pointer.
In fact, this eliminates the only use of NoFramePointer in the
compiler, which will enable further cleanups.
This also fixes what is very nearly, but not quite, a code generation
bug. NoFramePointer becomes obj.NOFRAME in the object file, which on
ppc64 and s390x means to omit the saved LR. Hence, on these
architectures, NoFramePointer (and NOFRAME) is only safe to set on
leaf functions. However, on *most* architectures, wrappers aren't
necessarily leaf functions because they may call DUFFZERO. We're saved
on ppc64 and s390x only because the compiler doesn't have the rules to
produce DUFFZERO calls on these architectures. Hence, this only works
because the set of LR architectures that implement NOFRAME is disjoint
from the set where the compiler produces DUFFZERO operations. (I
discovered this whole mess when I attempted to add NOFRAME support to
arm.)
Change-Id: Icc589aeb86beacb850d0a6a80bd3024974a33947
Reviewed-on: https://go-review.googlesource.com/92035
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
2018-01-25 11:35:27 -05:00
|
|
|
p.To = to
|
2015-01-19 14:34:58 -05:00
|
|
|
|
|
|
|
// If there are instructions following
|
|
|
|
// this ARET, they come from a branch
|
|
|
|
// with the same stackframe, so undo
|
|
|
|
// the cleanup.
|
|
|
|
p.Spadj = +autoffset
|
|
|
|
}
|
|
|
|
|
|
|
|
if p.To.Sym != nil { // retjmp
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
p.As = obj.AJMP
|
2015-01-19 14:34:58 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
cmd/compile/internal/obj/x86: eliminate some function prologues
The standard sort swap method
func (t T) Swap(i, j int) {
t[i], t[j] = t[j], t[i]
}
uses no stack space on architectures for which
FixedFrameSize == 0, currently 386 and amd64.
Nevertheless, we insert a stack check prologue.
This is because it contains a call to
runtime.panicindex.
However, for a few common runtime functions,
we know at compile time that they require
no arguments. Allow them to pass unnoticed.
Triggers for 380 functions during make.bash.
Cuts 4k off cmd/go.
encoding/binary benchmarks:
ReadSlice1000Int32s-8 9.49µs ± 3% 9.41µs ± 5% ~ (p=0.075 n=29+27)
ReadStruct-8 1.50µs ± 3% 1.48µs ± 2% -1.49% (p=0.000 n=30+28)
ReadInts-8 599ns ± 3% 600ns ± 3% ~ (p=0.471 n=30+29)
WriteInts-8 836ns ± 4% 841ns ± 3% ~ (p=0.371 n=30+29)
WriteSlice1000Int32s-8 8.84µs ± 3% 8.69µs ± 5% -1.71% (p=0.001 n=30+30)
PutUvarint32-8 29.6ns ± 1% 28.1ns ± 3% -5.21% (p=0.000 n=28+28)
PutUvarint64-8 82.6ns ± 5% 82.3ns ±10% -0.43% (p=0.014 n=27+30)
Swap assembly before:
"".T.Swap t=1 size=74 args=0x28 locals=0x0
0x0000 00000 (swap.go:5) TEXT "".T.Swap(SB), $0-40
0x0000 00000 (swap.go:5) MOVQ (TLS), CX
0x0009 00009 (swap.go:5) CMPQ SP, 16(CX)
0x000d 00013 (swap.go:5) JLS 67
0x000f 00015 (swap.go:5) FUNCDATA $0, gclocals·3cadd97b66f25a3a642be35e9362338f(SB)
0x000f 00015 (swap.go:5) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x000f 00015 (swap.go:5) MOVQ "".i+32(FP), AX
0x0014 00020 (swap.go:5) MOVQ "".t+16(FP), CX
0x0019 00025 (swap.go:5) CMPQ AX, CX
0x001c 00028 (swap.go:5) JCC $0, 60
0x001e 00030 (swap.go:5) MOVQ "".t+8(FP), DX
0x0023 00035 (swap.go:5) MOVBLZX (DX)(AX*1), BX
0x0027 00039 (swap.go:5) MOVQ "".j+40(FP), SI
0x002c 00044 (swap.go:5) CMPQ SI, CX
0x002f 00047 (swap.go:5) JCC $0, 60
0x0031 00049 (swap.go:5) MOVBLZX (DX)(SI*1), CX
0x0035 00053 (swap.go:5) MOVB CL, (DX)(AX*1)
0x0038 00056 (swap.go:5) MOVB BL, (DX)(SI*1)
0x003b 00059 (swap.go:5) RET
0x003c 00060 (swap.go:5) PCDATA $0, $1
0x003c 00060 (swap.go:5) CALL runtime.panicindex(SB)
0x0041 00065 (swap.go:5) UNDEF
0x0043 00067 (swap.go:5) NOP
0x0043 00067 (swap.go:5) CALL runtime.morestack_noctxt(SB)
0x0048 00072 (swap.go:5) JMP 0
Swap assembly after:
"".T.Swap t=1 size=52 args=0x28 locals=0x0
0x0000 00000 (swap.go:5) TEXT "".T.Swap(SB), $0-40
0x0000 00000 (swap.go:5) FUNCDATA $0, gclocals·3cadd97b66f25a3a642be35e9362338f(SB)
0x0000 00000 (swap.go:5) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x0000 00000 (swap.go:5) MOVQ "".i+32(FP), AX
0x0005 00005 (swap.go:5) MOVQ "".t+16(FP), CX
0x000a 00010 (swap.go:5) CMPQ AX, CX
0x000d 00013 (swap.go:5) JCC $0, 45
0x000f 00015 (swap.go:5) MOVQ "".t+8(FP), DX
0x0014 00020 (swap.go:5) MOVBLZX (DX)(AX*1), BX
0x0018 00024 (swap.go:5) MOVQ "".j+40(FP), SI
0x001d 00029 (swap.go:5) CMPQ SI, CX
0x0020 00032 (swap.go:5) JCC $0, 45
0x0022 00034 (swap.go:5) MOVBLZX (DX)(SI*1), CX
0x0026 00038 (swap.go:5) MOVB CL, (DX)(AX*1)
0x0029 00041 (swap.go:5) MOVB BL, (DX)(SI*1)
0x002c 00044 (swap.go:5) RET
0x002d 00045 (swap.go:5) PCDATA $0, $1
0x002d 00045 (swap.go:5) CALL runtime.panicindex(SB)
0x0032 00050 (swap.go:5) UNDEF
Change-Id: I57dad14af8aaa5e6112deac407cfadc2bfaf1f54
Reviewed-on: https://go-review.googlesource.com/24814
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
2016-07-07 16:50:46 -07:00
|
|
|
func isZeroArgRuntimeCall(s *obj.LSym) bool {
|
|
|
|
if s == nil {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
switch s.Name {
|
2019-04-03 13:16:58 -07:00
|
|
|
case "runtime.panicdivide", "runtime.panicwrap", "runtime.panicshift":
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
if strings.HasPrefix(s.Name, "runtime.panicIndex") || strings.HasPrefix(s.Name, "runtime.panicSlice") {
|
|
|
|
// These functions do take arguments (in registers),
|
|
|
|
// but use no stack before they do a stack check. We
|
|
|
|
// should include them. See issue 31219.
|
cmd/compile/internal/obj/x86: eliminate some function prologues
The standard sort swap method
func (t T) Swap(i, j int) {
t[i], t[j] = t[j], t[i]
}
uses no stack space on architectures for which
FixedFrameSize == 0, currently 386 and amd64.
Nevertheless, we insert a stack check prologue.
This is because it contains a call to
runtime.panicindex.
However, for a few common runtime functions,
we know at compile time that they require
no arguments. Allow them to pass unnoticed.
Triggers for 380 functions during make.bash.
Cuts 4k off cmd/go.
encoding/binary benchmarks:
ReadSlice1000Int32s-8 9.49µs ± 3% 9.41µs ± 5% ~ (p=0.075 n=29+27)
ReadStruct-8 1.50µs ± 3% 1.48µs ± 2% -1.49% (p=0.000 n=30+28)
ReadInts-8 599ns ± 3% 600ns ± 3% ~ (p=0.471 n=30+29)
WriteInts-8 836ns ± 4% 841ns ± 3% ~ (p=0.371 n=30+29)
WriteSlice1000Int32s-8 8.84µs ± 3% 8.69µs ± 5% -1.71% (p=0.001 n=30+30)
PutUvarint32-8 29.6ns ± 1% 28.1ns ± 3% -5.21% (p=0.000 n=28+28)
PutUvarint64-8 82.6ns ± 5% 82.3ns ±10% -0.43% (p=0.014 n=27+30)
Swap assembly before:
"".T.Swap t=1 size=74 args=0x28 locals=0x0
0x0000 00000 (swap.go:5) TEXT "".T.Swap(SB), $0-40
0x0000 00000 (swap.go:5) MOVQ (TLS), CX
0x0009 00009 (swap.go:5) CMPQ SP, 16(CX)
0x000d 00013 (swap.go:5) JLS 67
0x000f 00015 (swap.go:5) FUNCDATA $0, gclocals·3cadd97b66f25a3a642be35e9362338f(SB)
0x000f 00015 (swap.go:5) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x000f 00015 (swap.go:5) MOVQ "".i+32(FP), AX
0x0014 00020 (swap.go:5) MOVQ "".t+16(FP), CX
0x0019 00025 (swap.go:5) CMPQ AX, CX
0x001c 00028 (swap.go:5) JCC $0, 60
0x001e 00030 (swap.go:5) MOVQ "".t+8(FP), DX
0x0023 00035 (swap.go:5) MOVBLZX (DX)(AX*1), BX
0x0027 00039 (swap.go:5) MOVQ "".j+40(FP), SI
0x002c 00044 (swap.go:5) CMPQ SI, CX
0x002f 00047 (swap.go:5) JCC $0, 60
0x0031 00049 (swap.go:5) MOVBLZX (DX)(SI*1), CX
0x0035 00053 (swap.go:5) MOVB CL, (DX)(AX*1)
0x0038 00056 (swap.go:5) MOVB BL, (DX)(SI*1)
0x003b 00059 (swap.go:5) RET
0x003c 00060 (swap.go:5) PCDATA $0, $1
0x003c 00060 (swap.go:5) CALL runtime.panicindex(SB)
0x0041 00065 (swap.go:5) UNDEF
0x0043 00067 (swap.go:5) NOP
0x0043 00067 (swap.go:5) CALL runtime.morestack_noctxt(SB)
0x0048 00072 (swap.go:5) JMP 0
Swap assembly after:
"".T.Swap t=1 size=52 args=0x28 locals=0x0
0x0000 00000 (swap.go:5) TEXT "".T.Swap(SB), $0-40
0x0000 00000 (swap.go:5) FUNCDATA $0, gclocals·3cadd97b66f25a3a642be35e9362338f(SB)
0x0000 00000 (swap.go:5) FUNCDATA $1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
0x0000 00000 (swap.go:5) MOVQ "".i+32(FP), AX
0x0005 00005 (swap.go:5) MOVQ "".t+16(FP), CX
0x000a 00010 (swap.go:5) CMPQ AX, CX
0x000d 00013 (swap.go:5) JCC $0, 45
0x000f 00015 (swap.go:5) MOVQ "".t+8(FP), DX
0x0014 00020 (swap.go:5) MOVBLZX (DX)(AX*1), BX
0x0018 00024 (swap.go:5) MOVQ "".j+40(FP), SI
0x001d 00029 (swap.go:5) CMPQ SI, CX
0x0020 00032 (swap.go:5) JCC $0, 45
0x0022 00034 (swap.go:5) MOVBLZX (DX)(SI*1), CX
0x0026 00038 (swap.go:5) MOVB CL, (DX)(AX*1)
0x0029 00041 (swap.go:5) MOVB BL, (DX)(SI*1)
0x002c 00044 (swap.go:5) RET
0x002d 00045 (swap.go:5) PCDATA $0, $1
0x002d 00045 (swap.go:5) CALL runtime.panicindex(SB)
0x0032 00050 (swap.go:5) UNDEF
Change-Id: I57dad14af8aaa5e6112deac407cfadc2bfaf1f54
Reviewed-on: https://go-review.googlesource.com/24814
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
2016-07-07 16:50:46 -07:00
|
|
|
return true
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2018-03-23 22:02:03 +00:00
|
|
|
func indir_cx(ctxt *obj.Link, a *obj.Addr) {
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
a.Type = obj.TYPE_MEM
|
|
|
|
a.Reg = REG_CX
|
2015-01-19 14:34:58 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// Append code to p to load g into cx.
|
|
|
|
// Overwrites p with the first instruction (no first appendp).
|
|
|
|
// Overwriting p is unusual but it lets use this in both the
|
|
|
|
// prologue (caller must call appendp first) and in the epilogue.
|
|
|
|
// Returns last new instruction.
|
2017-04-04 14:31:55 -07:00
|
|
|
func load_g_cx(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) *obj.Prog {
|
2015-01-19 14:34:58 -05:00
|
|
|
p.As = AMOVQ
|
2016-04-06 12:01:40 -07:00
|
|
|
if ctxt.Arch.PtrSize == 4 {
|
2015-01-19 14:34:58 -05:00
|
|
|
p.As = AMOVL
|
|
|
|
}
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
p.From.Type = obj.TYPE_MEM
|
|
|
|
p.From.Reg = REG_TLS
|
2015-01-19 14:34:58 -05:00
|
|
|
p.From.Offset = 0
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
p.To.Type = obj.TYPE_REG
|
|
|
|
p.To.Reg = REG_CX
|
2015-01-19 14:34:58 -05:00
|
|
|
|
2015-03-02 12:35:15 -05:00
|
|
|
next := p.Link
|
2017-04-04 14:31:55 -07:00
|
|
|
progedit(ctxt, p, newprog)
|
2015-01-19 14:34:58 -05:00
|
|
|
for p.Link != next {
|
|
|
|
p = p.Link
|
2019-03-28 13:11:53 +01:00
|
|
|
progedit(ctxt, p, newprog)
|
2015-01-19 14:34:58 -05:00
|
|
|
}
|
|
|
|
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
if p.From.Index == REG_TLS {
|
2015-01-19 14:34:58 -05:00
|
|
|
p.From.Scale = 2
|
|
|
|
}
|
|
|
|
|
|
|
|
return p
|
|
|
|
}
|
|
|
|
|
|
|
|
// Append code to p to check for stack split.
|
|
|
|
// Appends to (does not overwrite) p.
|
|
|
|
// Assumes g is in CX.
|
|
|
|
// Returns last new instruction.
|
2017-04-04 14:31:55 -07:00
|
|
|
func stacksplit(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, newprog obj.ProgAlloc, framesize int32, textarg int32) *obj.Prog {
|
2015-03-02 12:35:15 -05:00
|
|
|
cmp := ACMPQ
|
|
|
|
lea := ALEAQ
|
|
|
|
mov := AMOVQ
|
|
|
|
sub := ASUBQ
|
2015-01-19 14:34:58 -05:00
|
|
|
|
2019-10-09 16:22:47 +00:00
|
|
|
if ctxt.Arch.Family == sys.I386 {
|
2015-01-19 14:34:58 -05:00
|
|
|
cmp = ACMPL
|
|
|
|
lea = ALEAL
|
|
|
|
mov = AMOVL
|
|
|
|
sub = ASUBL
|
|
|
|
}
|
|
|
|
|
2015-03-02 14:22:05 -05:00
|
|
|
var q1 *obj.Prog
|
2017-04-18 12:53:25 -07:00
|
|
|
if framesize <= objabi.StackSmall {
|
2015-01-19 14:34:58 -05:00
|
|
|
// small stack: SP <= stackguard
|
|
|
|
// CMPQ SP, stackguard
|
2017-04-04 14:31:55 -07:00
|
|
|
p = obj.Appendp(p, newprog)
|
2015-01-19 14:34:58 -05:00
|
|
|
|
2016-03-07 18:00:08 -08:00
|
|
|
p.As = cmp
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
p.From.Type = obj.TYPE_REG
|
|
|
|
p.From.Reg = REG_SP
|
2018-03-23 22:02:03 +00:00
|
|
|
indir_cx(ctxt, &p.To)
|
2016-04-06 12:01:40 -07:00
|
|
|
p.To.Offset = 2 * int64(ctxt.Arch.PtrSize) // G.stackguard0
|
2017-03-26 07:46:30 -07:00
|
|
|
if cursym.CFunc() {
|
2016-04-06 12:01:40 -07:00
|
|
|
p.To.Offset = 3 * int64(ctxt.Arch.PtrSize) // G.stackguard1
|
2015-01-19 14:34:58 -05:00
|
|
|
}
|
cmd/internal/obj: mark split-stack prologue nonpreemptible
When there are both a synchronous preemption request (by
clobbering the stack guard) and an asynchronous one (by signal),
the running goroutine may observe the synchronous request first
in stack bounds check, and go to the path of calling morestack.
If the preemption signal arrives at this point before the call to
morestack, the goroutine will be asynchronously preempted,
entering the scheduler. When it is resumed, the scheduler clears
the preemption request, unclobbers the stack guard. But the
resumed goroutine will still call morestack, as it is already on
its way. morestack will, as there is no preemption request,
double the stack unnecessarily. If this happens multiple times,
the stack may grow too big, although only a small amount is
actually used.
To fix this, we mark the stack bounds check and the call to
morestack async-nonpreemptible, starting after the memory
instruction (mostly a load, on x86 CMP with memory).
Not done for Wasm as it does not support async preemption.
Fixes #35470.
Change-Id: Ibd7f3d935a3649b80f47539116ec9b9556680cf2
Reviewed-on: https://go-review.googlesource.com/c/go/+/207350
Reviewed-by: David Chase <drchase@google.com>
2019-11-14 20:23:17 -05:00
|
|
|
|
|
|
|
// Mark the stack bound check and morestack call async nonpreemptible.
|
|
|
|
// If we get preempted here, when resumed the preemption request is
|
|
|
|
// cleared, but we'll still call morestack, which will double the stack
|
|
|
|
// unnecessarily. See issue #35470.
|
|
|
|
p = ctxt.StartUnsafePoint(p, newprog)
|
2017-04-18 12:53:25 -07:00
|
|
|
} else if framesize <= objabi.StackBig {
|
2015-01-19 14:34:58 -05:00
|
|
|
// large stack: SP-framesize <= stackguard-StackSmall
|
|
|
|
// LEAQ -xxx(SP), AX
|
|
|
|
// CMPQ AX, stackguard
|
2017-04-04 14:31:55 -07:00
|
|
|
p = obj.Appendp(p, newprog)
|
2015-01-19 14:34:58 -05:00
|
|
|
|
2016-03-07 18:00:08 -08:00
|
|
|
p.As = lea
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
p.From.Type = obj.TYPE_MEM
|
|
|
|
p.From.Reg = REG_SP
|
2017-04-18 12:53:25 -07:00
|
|
|
p.From.Offset = -(int64(framesize) - objabi.StackSmall)
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
p.To.Type = obj.TYPE_REG
|
|
|
|
p.To.Reg = REG_AX
|
2015-01-19 14:34:58 -05:00
|
|
|
|
2017-04-04 14:31:55 -07:00
|
|
|
p = obj.Appendp(p, newprog)
|
2016-03-07 18:00:08 -08:00
|
|
|
p.As = cmp
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
p.From.Type = obj.TYPE_REG
|
|
|
|
p.From.Reg = REG_AX
|
2018-03-23 22:02:03 +00:00
|
|
|
indir_cx(ctxt, &p.To)
|
2016-04-06 12:01:40 -07:00
|
|
|
p.To.Offset = 2 * int64(ctxt.Arch.PtrSize) // G.stackguard0
|
2017-03-26 07:46:30 -07:00
|
|
|
if cursym.CFunc() {
|
2016-04-06 12:01:40 -07:00
|
|
|
p.To.Offset = 3 * int64(ctxt.Arch.PtrSize) // G.stackguard1
|
2015-01-19 14:34:58 -05:00
|
|
|
}
|
cmd/internal/obj: mark split-stack prologue nonpreemptible
When there are both a synchronous preemption request (by
clobbering the stack guard) and an asynchronous one (by signal),
the running goroutine may observe the synchronous request first
in stack bounds check, and go to the path of calling morestack.
If the preemption signal arrives at this point before the call to
morestack, the goroutine will be asynchronously preempted,
entering the scheduler. When it is resumed, the scheduler clears
the preemption request, unclobbers the stack guard. But the
resumed goroutine will still call morestack, as it is already on
its way. morestack will, as there is no preemption request,
double the stack unnecessarily. If this happens multiple times,
the stack may grow too big, although only a small amount is
actually used.
To fix this, we mark the stack bounds check and the call to
morestack async-nonpreemptible, starting after the memory
instruction (mostly a load, on x86 CMP with memory).
Not done for Wasm as it does not support async preemption.
Fixes #35470.
Change-Id: Ibd7f3d935a3649b80f47539116ec9b9556680cf2
Reviewed-on: https://go-review.googlesource.com/c/go/+/207350
Reviewed-by: David Chase <drchase@google.com>
2019-11-14 20:23:17 -05:00
|
|
|
|
|
|
|
p = ctxt.StartUnsafePoint(p, newprog) // see the comment above
|
2015-01-19 14:34:58 -05:00
|
|
|
} else {
|
|
|
|
// Such a large stack we need to protect against wraparound.
|
|
|
|
// If SP is close to zero:
|
|
|
|
// SP-stackguard+StackGuard <= framesize + (StackGuard-StackSmall)
|
|
|
|
// The +StackGuard on both sides is required to keep the left side positive:
|
|
|
|
// SP is allowed to be slightly below stackguard. See stack.h.
|
|
|
|
//
|
|
|
|
// Preemption sets stackguard to StackPreempt, a very large value.
|
|
|
|
// That breaks the math above, so we have to check for that explicitly.
|
cmd/internal/obj: mark split-stack prologue nonpreemptible
When there are both a synchronous preemption request (by
clobbering the stack guard) and an asynchronous one (by signal),
the running goroutine may observe the synchronous request first
in stack bounds check, and go to the path of calling morestack.
If the preemption signal arrives at this point before the call to
morestack, the goroutine will be asynchronously preempted,
entering the scheduler. When it is resumed, the scheduler clears
the preemption request, unclobbers the stack guard. But the
resumed goroutine will still call morestack, as it is already on
its way. morestack will, as there is no preemption request,
double the stack unnecessarily. If this happens multiple times,
the stack may grow too big, although only a small amount is
actually used.
To fix this, we mark the stack bounds check and the call to
morestack async-nonpreemptible, starting after the memory
instruction (mostly a load, on x86 CMP with memory).
Not done for Wasm as it does not support async preemption.
Fixes #35470.
Change-Id: Ibd7f3d935a3649b80f47539116ec9b9556680cf2
Reviewed-on: https://go-review.googlesource.com/c/go/+/207350
Reviewed-by: David Chase <drchase@google.com>
2019-11-14 20:23:17 -05:00
|
|
|
// MOVQ stackguard, SI
|
|
|
|
// CMPQ SI, $StackPreempt
|
2015-01-19 14:34:58 -05:00
|
|
|
// JEQ label-of-call-to-morestack
|
|
|
|
// LEAQ StackGuard(SP), AX
|
cmd/internal/obj: mark split-stack prologue nonpreemptible
When there are both a synchronous preemption request (by
clobbering the stack guard) and an asynchronous one (by signal),
the running goroutine may observe the synchronous request first
in stack bounds check, and go to the path of calling morestack.
If the preemption signal arrives at this point before the call to
morestack, the goroutine will be asynchronously preempted,
entering the scheduler. When it is resumed, the scheduler clears
the preemption request, unclobbers the stack guard. But the
resumed goroutine will still call morestack, as it is already on
its way. morestack will, as there is no preemption request,
double the stack unnecessarily. If this happens multiple times,
the stack may grow too big, although only a small amount is
actually used.
To fix this, we mark the stack bounds check and the call to
morestack async-nonpreemptible, starting after the memory
instruction (mostly a load, on x86 CMP with memory).
Not done for Wasm as it does not support async preemption.
Fixes #35470.
Change-Id: Ibd7f3d935a3649b80f47539116ec9b9556680cf2
Reviewed-on: https://go-review.googlesource.com/c/go/+/207350
Reviewed-by: David Chase <drchase@google.com>
2019-11-14 20:23:17 -05:00
|
|
|
// SUBQ SI, AX
|
2015-01-19 14:34:58 -05:00
|
|
|
// CMPQ AX, $(framesize+(StackGuard-StackSmall))
|
|
|
|
|
2017-04-04 14:31:55 -07:00
|
|
|
p = obj.Appendp(p, newprog)
|
2015-01-19 14:34:58 -05:00
|
|
|
|
2016-03-07 18:00:08 -08:00
|
|
|
p.As = mov
|
2018-03-23 22:02:03 +00:00
|
|
|
indir_cx(ctxt, &p.From)
|
2016-04-06 12:01:40 -07:00
|
|
|
p.From.Offset = 2 * int64(ctxt.Arch.PtrSize) // G.stackguard0
|
2017-03-26 07:46:30 -07:00
|
|
|
if cursym.CFunc() {
|
2016-04-06 12:01:40 -07:00
|
|
|
p.From.Offset = 3 * int64(ctxt.Arch.PtrSize) // G.stackguard1
|
2015-01-19 14:34:58 -05:00
|
|
|
}
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
p.To.Type = obj.TYPE_REG
|
|
|
|
p.To.Reg = REG_SI
|
2015-01-19 14:34:58 -05:00
|
|
|
|
cmd/internal/obj: mark split-stack prologue nonpreemptible
When there are both a synchronous preemption request (by
clobbering the stack guard) and an asynchronous one (by signal),
the running goroutine may observe the synchronous request first
in stack bounds check, and go to the path of calling morestack.
If the preemption signal arrives at this point before the call to
morestack, the goroutine will be asynchronously preempted,
entering the scheduler. When it is resumed, the scheduler clears
the preemption request, unclobbers the stack guard. But the
resumed goroutine will still call morestack, as it is already on
its way. morestack will, as there is no preemption request,
double the stack unnecessarily. If this happens multiple times,
the stack may grow too big, although only a small amount is
actually used.
To fix this, we mark the stack bounds check and the call to
morestack async-nonpreemptible, starting after the memory
instruction (mostly a load, on x86 CMP with memory).
Not done for Wasm as it does not support async preemption.
Fixes #35470.
Change-Id: Ibd7f3d935a3649b80f47539116ec9b9556680cf2
Reviewed-on: https://go-review.googlesource.com/c/go/+/207350
Reviewed-by: David Chase <drchase@google.com>
2019-11-14 20:23:17 -05:00
|
|
|
p = ctxt.StartUnsafePoint(p, newprog) // see the comment above
|
|
|
|
|
2017-04-04 14:31:55 -07:00
|
|
|
p = obj.Appendp(p, newprog)
|
2016-03-07 18:00:08 -08:00
|
|
|
p.As = cmp
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
p.From.Type = obj.TYPE_REG
|
|
|
|
p.From.Reg = REG_SI
|
|
|
|
p.To.Type = obj.TYPE_CONST
|
2017-04-18 12:53:25 -07:00
|
|
|
p.To.Offset = objabi.StackPreempt
|
2017-03-26 08:05:40 -07:00
|
|
|
if ctxt.Arch.Family == sys.I386 {
|
2017-04-18 12:53:25 -07:00
|
|
|
p.To.Offset = int64(uint32(objabi.StackPreempt & (1<<32 - 1)))
|
cmd/internal/obj/x86: take over i386 duty, clean up PINSRQ, CMPSD
Make cmd/internal/obj/x86 support 32-bit mode and use
instead of cmd/internal/obj/i386. Delete cmd/internal/obj/i386.
Clean up encoding of PINSRQ, CMPSD to use explicit third arg
instead of jamming it into an unused slot of a different arg.
Also fix bug in old6a, which declared the wrong grammar.
The accepted (and encoded) arguments to CMPSD etc are mem,reg not reg,mem.
Code that did try to use mem,reg before would be rejected by liblink,
so only reg,reg ever worked, so existing code is not affected.
After this change, code can use mem,reg successfully.
The real bug here is that the encoding tables inverted the argument
order, making the comparisons all backward from what they say on the page.
It's too late to swap them, though: people have already written code that
expects the inverted comparisons (like in package math, and likely externally).
The best we can do is make the argument that should and can take a
memory operand accept it.
Bit-for-bit compatibility checked against tree without this CL.
Change-Id: Ife5685bc98c95001f64407f35066b34b4dae11c1
Reviewed-on: https://go-review.googlesource.com/6810
Reviewed-by: Rob Pike <r@golang.org>
2015-03-04 15:46:52 -05:00
|
|
|
}
|
2015-01-19 14:34:58 -05:00
|
|
|
|
2017-04-04 14:31:55 -07:00
|
|
|
p = obj.Appendp(p, newprog)
|
2015-01-19 14:34:58 -05:00
|
|
|
p.As = AJEQ
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
p.To.Type = obj.TYPE_BRANCH
|
2015-01-19 14:34:58 -05:00
|
|
|
q1 = p
|
|
|
|
|
2017-04-04 14:31:55 -07:00
|
|
|
p = obj.Appendp(p, newprog)
|
2016-03-07 18:00:08 -08:00
|
|
|
p.As = lea
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
p.From.Type = obj.TYPE_MEM
|
|
|
|
p.From.Reg = REG_SP
|
2019-01-09 14:05:17 +01:00
|
|
|
p.From.Offset = int64(objabi.StackGuard)
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
p.To.Type = obj.TYPE_REG
|
|
|
|
p.To.Reg = REG_AX
|
2015-01-19 14:34:58 -05:00
|
|
|
|
2017-04-04 14:31:55 -07:00
|
|
|
p = obj.Appendp(p, newprog)
|
2016-03-07 18:00:08 -08:00
|
|
|
p.As = sub
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
p.From.Type = obj.TYPE_REG
|
|
|
|
p.From.Reg = REG_SI
|
|
|
|
p.To.Type = obj.TYPE_REG
|
|
|
|
p.To.Reg = REG_AX
|
2015-01-19 14:34:58 -05:00
|
|
|
|
2017-04-04 14:31:55 -07:00
|
|
|
p = obj.Appendp(p, newprog)
|
2016-03-07 18:00:08 -08:00
|
|
|
p.As = cmp
|
[dev.cc] cmd/internal/obj: reconvert from liblink
cmd/internal/obj reconverted using rsc.io/c2go rev 2a95256.
- Brings in new, more regular Prog, Addr definitions
- Add Prog* argument to oclass in liblink/asm[68].c, for c2go conversion.
- Update objwriter for change in TEXT size encoding.
- Merge 5a, 6a, 8a, 9a changes into new5a, new6a, new8a, new9a (by hand).
- Add +build ignore to cmd/asm/internal/{addr,arch,asm}, cmd/asm.
They need to be updated for the changes.
- Reenable verifyAsm in cmd/go.
- Reenable GOOBJ=2 mode by default in liblink.
All architectures build successfully again.
Change-Id: I2c845c5d365aa484b570476898171bee657b626d
Reviewed-on: https://go-review.googlesource.com/3963
Reviewed-by: Rob Pike <r@golang.org>
2015-02-05 03:57:44 -05:00
|
|
|
p.From.Type = obj.TYPE_REG
|
|
|
|
p.From.Reg = REG_AX
|
|
|
|
p.To.Type = obj.TYPE_CONST
|
2019-01-09 14:05:17 +01:00
|
|
|
p.To.Offset = int64(framesize) + (int64(objabi.StackGuard) - objabi.StackSmall)
|
2015-01-19 14:34:58 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// common
|
2017-04-04 14:31:55 -07:00
|
|
|
jls := obj.Appendp(p, newprog)
|
cmd/internal/obj/x86: make function prologue more predictable
Static branch prediction guesses that forward branches aren't taken.
Since stacks are rarely grown, make the forward branch mean grow.
Sample disassembly for
func f() {
_ = [128]byte{}
}
Before:
TEXT main.f(SB) x.go
x.go:3 0x2000 65488b0c25a0080000 GS MOVQ GS:0x8a0, CX
x.go:3 0x2009 483b6110 CMPQ 0x10(CX), SP
x.go:3 0x200d 7707 JA 0x2016
x.go:3 0x200f e88c410400 CALL runtime.morestack_noctxt(SB)
x.go:3 0x2014 ebea JMP main.f(SB)
x.go:3 0x2016 4881ec80000000 SUBQ $0x80, SP
x.go:4 0x201d 488d3c24 LEAQ 0(SP), DI
x.go:4 0x2021 31c0 XORL AX, AX
x.go:4 0x2023 e8cc640400 CALL 0x484f4
x.go:5 0x2028 4881c480000000 ADDQ $0x80, SP
x.go:5 0x202f c3 RET
After:
TEXT main.f(SB) x.go
x.go:3 0x2000 65488b0c25a0080000 GS MOVQ GS:0x8a0, CX
x.go:3 0x2009 483b6110 CMPQ 0x10(CX), SP
x.go:3 0x200d 761a JBE 0x2029
x.go:3 0x200f 4881ec80000000 SUBQ $0x80, SP
x.go:4 0x2016 488d3c24 LEAQ 0(SP), DI
x.go:4 0x201a 31c0 XORL AX, AX
x.go:4 0x201c e813740400 CALL 0x49434
x.go:5 0x2021 4881c480000000 ADDQ $0x80, SP
x.go:5 0x2028 c3 RET
x.go:3 0x2029 e8224f0400 CALL runtime.morestack_noctxt(SB)
x.go:3 0x202e ebd0 JMP main.f(SB)
Updates #10587.
Sample benchmarks on a 2.8 GHz Intel Core i7:
package sort
name old mean new mean delta
SearchWrappers 134ns × (0.99,1.01) 132ns × (0.99,1.01) -1.73% (p=0.000 n=15+14)
SortString1K 215µs × (0.99,1.01) 213µs × (0.99,1.01) -0.61% (p=0.020 n=14+15)
StableString1K 311µs × (0.99,1.02) 309µs × (0.99,1.02) ~ (p=0.077 n=14+15)
SortInt1K 103µs × (0.99,1.02) 100µs × (0.98,1.01) -3.34% (p=0.000 n=15+15)
StableInt1K 102µs × (0.99,1.01) 98µs × (0.97,1.04) -3.53% (p=0.000 n=15+15)
SortInt64K 10.1ms × (0.98,1.02) 9.7ms × (0.99,1.01) -3.86% (p=0.000 n=14+15)
StableInt64K 8.70ms × (0.99,1.01) 8.44ms × (0.99,1.03) -2.93% (p=0.000 n=14+15)
Sort1e2 51.2µs × (1.00,1.01) 48.9µs × (0.99,1.02) -4.48% (p=0.000 n=13+15)
Stable1e2 100µs × (0.99,1.02) 99µs × (0.99,1.01) -1.15% (p=0.000 n=14+13)
Sort1e4 11.1ms × (0.99,1.02) 10.4ms × (0.99,1.01) -6.02% (p=0.000 n=15+14)
Stable1e4 30.6ms × (0.99,1.01) 30.3ms × (0.99,1.02) -1.02% (p=0.001 n=15+14)
Sort1e6 1.75s × (0.99,1.02) 1.66s × (0.98,1.03) -4.95% (p=0.000 n=14+15)
Stable1e6 6.31s × (0.99,1.01) 6.26s × (0.99,1.01) -0.79% (p=0.002 n=15+15)
package regexp
name old mean new mean delta
Literal 131ns × (0.99,1.01) 130ns × (0.99,1.03) -1.07% (p=0.004 n=14+15)
NotLiteral 2.13µs × (0.99,1.01) 2.01µs × (0.99,1.03) -5.71% (p=0.000 n=14+14)
MatchClass 3.15µs × (0.99,1.01) 3.04µs × (0.99,1.02) -3.40% (p=0.000 n=15+15)
MatchClass_InRange 2.92µs × (0.99,1.01) 2.77µs × (0.99,1.02) -5.05% (p=0.000 n=13+15)
ReplaceAll 2.17µs × (0.99,1.02) 2.06µs × (0.99,1.01) -5.19% (p=0.000 n=15+13)
AnchoredLiteralShortNonMatch 116ns × (0.99,1.02) 113ns × (0.99,1.01) -2.75% (p=0.000 n=15+14)
AnchoredLiteralLongNonMatch 125ns × (0.99,1.01) 127ns × (0.98,1.02) +1.49% (p=0.000 n=15+15)
AnchoredShortMatch 178ns × (0.99,1.02) 175ns × (0.99,1.01) -1.62% (p=0.000 n=15+13)
AnchoredLongMatch 328ns × (0.99,1.00) 341ns × (0.99,1.01) +3.73% (p=0.000 n=12+15)
OnePassShortA 773ns × (0.99,1.02) 752ns × (0.99,1.01) -2.78% (p=0.000 n=15+13)
NotOnePassShortA 794ns × (0.99,1.03) 780ns × (0.99,1.02) -1.75% (p=0.001 n=15+15)
OnePassShortB 608ns × (0.99,1.01) 591ns × (0.99,1.02) -2.86% (p=0.000 n=15+14)
NotOnePassShortB 576ns × (0.99,1.01) 571ns × (0.99,1.02) -0.74% (p=0.035 n=15+15)
OnePassLongPrefix 131ns × (0.99,1.02) 130ns × (0.99,1.02) -1.32% (p=0.003 n=15+15)
OnePassLongNotPrefix 503ns × (0.99,1.02) 481ns × (0.99,1.01) -4.34% (p=0.000 n=15+13)
MatchEasy0_32 102ns × (0.98,1.01) 101ns × (0.99,1.02) ~ (p=0.907 n=15+14)
MatchEasy0_1K 617ns × (0.99,1.02) 634ns × (0.98,1.02) +2.77% (p=0.000 n=15+15)
MatchEasy0_32K 10.9µs × (0.99,1.01) 11.1µs × (0.99,1.01) +1.59% (p=0.000 n=15+15)
MatchEasy0_1M 406µs × (0.99,1.02) 410µs × (0.99,1.02) +1.01% (p=0.000 n=14+15)
MatchEasy0_32M 13.4ms × (0.99,1.01) 13.7ms × (0.99,1.02) +1.64% (p=0.000 n=12+15)
MatchEasy1_32 83.7ns × (0.98,1.02) 83.0ns × (0.98,1.02) ~ (p=0.190 n=15+15)
MatchEasy1_1K 1.46µs × (0.99,1.02) 1.39µs × (0.99,1.02) -4.83% (p=0.000 n=15+15)
MatchEasy1_32K 49.4µs × (0.99,1.01) 49.4µs × (0.99,1.01) ~ (p=0.205 n=15+15)
MatchEasy1_1M 1.72ms × (0.99,1.02) 1.75ms × (0.99,1.01) +1.34% (p=0.000 n=15+15)
MatchEasy1_32M 55.5ms × (0.99,1.01) 56.1ms × (0.99,1.02) +1.10% (p=0.002 n=15+15)
MatchMedium_32 1.37µs × (0.99,1.04) 1.33µs × (0.99,1.01) -2.87% (p=0.000 n=15+15)
MatchMedium_1K 41.1µs × (0.99,1.02) 40.4µs × (0.99,1.02) -1.59% (p=0.000 n=15+15)
MatchMedium_32K 1.71ms × (0.99,1.01) 1.75ms × (0.99,1.02) +2.36% (p=0.000 n=14+15)
MatchMedium_1M 54.5ms × (0.99,1.01) 56.1ms × (0.99,1.01) +2.94% (p=0.000 n=13+15)
MatchMedium_32M 1.75s × (0.99,1.01) 1.80s × (0.99,1.01) +2.77% (p=0.000 n=15+15)
MatchHard_32 2.12µs × (0.99,1.02) 2.06µs × (0.99,1.01) -2.60% (p=0.000 n=15+14)
MatchHard_1K 64.4µs × (0.98,1.02) 62.2µs × (0.99,1.01) -3.33% (p=0.000 n=15+15)
MatchHard_32K 2.74ms × (0.99,1.01) 2.75ms × (0.99,1.01) ~ (p=0.310 n=15+14)
MatchHard_1M 87.1ms × (0.99,1.02) 88.2ms × (0.99,1.01) +1.36% (p=0.000 n=14+15)
MatchHard_32M 2.79s × (0.99,1.02) 2.83s × (0.99,1.02) +1.26% (p=0.004 n=15+14)
go1 benchmarks
name old time/op new time/op delta
BinaryTree17 3.34s ± 3% 3.28s ± 2% -1.86% (p=0.000 n=67+66)
Fannkuch11 2.50s ± 1% 2.51s ± 1% +0.24% (p=0.016 n=63+66)
FmtFprintfEmpty 50.3ns ± 1% 50.2ns ± 2% -0.30% (p=0.001 n=62+67)
FmtFprintfString 178ns ± 1% 166ns ± 1% -7.10% (p=0.000 n=62+59)
FmtFprintfInt 168ns ± 1% 161ns ± 2% -4.41% (p=0.000 n=66+64)
FmtFprintfIntInt 292ns ± 1% 282ns ± 2% -3.55% (p=0.000 n=62+60)
FmtFprintfPrefixedInt 245ns ± 2% 239ns ± 2% -2.24% (p=0.000 n=66+65)
FmtFprintfFloat 338ns ± 2% 326ns ± 1% -3.42% (p=0.000 n=64+59)
FmtManyArgs 1.14µs ± 1% 1.10µs ± 2% -3.55% (p=0.000 n=62+62)
GobDecode 8.88ms ± 2% 8.74ms ± 1% -1.55% (p=0.000 n=66+62)
GobEncode 6.84ms ± 2% 6.61ms ± 2% -3.32% (p=0.000 n=61+67)
Gzip 356ms ± 2% 352ms ± 2% -1.07% (p=0.000 n=67+66)
Gunzip 90.6ms ± 2% 89.8ms ± 1% -0.83% (p=0.000 n=65+64)
HTTPClientServer 82.6µs ± 2% 82.5µs ± 2% ~ (p=0.832 n=65+63)
JSONEncode 17.5ms ± 2% 16.8ms ± 2% -3.77% (p=0.000 n=63+63)
JSONDecode 63.3ms ± 2% 59.0ms ± 2% -6.85% (p=0.000 n=64+63)
Mandelbrot200 3.85ms ± 1% 3.85ms ± 1% ~ (p=0.127 n=65+62)
GoParse 3.75ms ± 2% 3.66ms ± 2% -2.39% (p=0.000 n=66+64)
RegexpMatchEasy0_32 100ns ± 2% 100ns ± 1% -0.65% (p=0.000 n=62+64)
RegexpMatchEasy0_1K 342ns ± 1% 341ns ± 1% -0.43% (p=0.000 n=65+64)
RegexpMatchEasy1_32 82.8ns ± 2% 82.8ns ± 2% ~ (p=0.977 n=63+64)
RegexpMatchEasy1_1K 511ns ± 2% 506ns ± 2% -1.01% (p=0.000 n=63+64)
RegexpMatchMedium_32 139ns ± 1% 134ns ± 3% -3.27% (p=0.000 n=59+60)
RegexpMatchMedium_1K 41.8µs ± 2% 40.5µs ± 2% -3.05% (p=0.000 n=62+64)
RegexpMatchHard_32 2.13µs ± 1% 2.09µs ± 1% -2.22% (p=0.000 n=60+65)
RegexpMatchHard_1K 64.4µs ± 3% 62.8µs ± 2% -2.58% (p=0.000 n=65+59)
Revcomp 531ms ± 2% 529ms ± 1% -0.28% (p=0.022 n=61+61)
Template 73.2ms ± 1% 73.1ms ± 1% ~ (p=0.794 n=66+63)
TimeParse 369ns ± 1% 352ns ± 1% -4.68% (p=0.000 n=65+66)
TimeFormat 374ns ± 2% 348ns ± 2% -7.01% (p=0.000 n=66+64)
Change-Id: Ib190b5bb48a3e9087711d9e3383621d3103dd342
Reviewed-on: https://go-review.googlesource.com/10367
Reviewed-by: Russ Cox <rsc@golang.org>
2015-05-28 17:31:24 -07:00
|
|
|
jls.As = AJLS
|
|
|
|
jls.To.Type = obj.TYPE_BRANCH
|
|
|
|
|
cmd/internal/obj: mark split-stack prologue nonpreemptible
When there are both a synchronous preemption request (by
clobbering the stack guard) and an asynchronous one (by signal),
the running goroutine may observe the synchronous request first
in stack bounds check, and go to the path of calling morestack.
If the preemption signal arrives at this point before the call to
morestack, the goroutine will be asynchronously preempted,
entering the scheduler. When it is resumed, the scheduler clears
the preemption request, unclobbers the stack guard. But the
resumed goroutine will still call morestack, as it is already on
its way. morestack will, as there is no preemption request,
double the stack unnecessarily. If this happens multiple times,
the stack may grow too big, although only a small amount is
actually used.
To fix this, we mark the stack bounds check and the call to
morestack async-nonpreemptible, starting after the memory
instruction (mostly a load, on x86 CMP with memory).
Not done for Wasm as it does not support async preemption.
Fixes #35470.
Change-Id: Ibd7f3d935a3649b80f47539116ec9b9556680cf2
Reviewed-on: https://go-review.googlesource.com/c/go/+/207350
Reviewed-by: David Chase <drchase@google.com>
2019-11-14 20:23:17 -05:00
|
|
|
end := ctxt.EndUnsafePoint(jls, newprog, -1)
|
|
|
|
|
cmd/internal/obj/x86: make function prologue more predictable
Static branch prediction guesses that forward branches aren't taken.
Since stacks are rarely grown, make the forward branch mean grow.
Sample disassembly for
func f() {
_ = [128]byte{}
}
Before:
TEXT main.f(SB) x.go
x.go:3 0x2000 65488b0c25a0080000 GS MOVQ GS:0x8a0, CX
x.go:3 0x2009 483b6110 CMPQ 0x10(CX), SP
x.go:3 0x200d 7707 JA 0x2016
x.go:3 0x200f e88c410400 CALL runtime.morestack_noctxt(SB)
x.go:3 0x2014 ebea JMP main.f(SB)
x.go:3 0x2016 4881ec80000000 SUBQ $0x80, SP
x.go:4 0x201d 488d3c24 LEAQ 0(SP), DI
x.go:4 0x2021 31c0 XORL AX, AX
x.go:4 0x2023 e8cc640400 CALL 0x484f4
x.go:5 0x2028 4881c480000000 ADDQ $0x80, SP
x.go:5 0x202f c3 RET
After:
TEXT main.f(SB) x.go
x.go:3 0x2000 65488b0c25a0080000 GS MOVQ GS:0x8a0, CX
x.go:3 0x2009 483b6110 CMPQ 0x10(CX), SP
x.go:3 0x200d 761a JBE 0x2029
x.go:3 0x200f 4881ec80000000 SUBQ $0x80, SP
x.go:4 0x2016 488d3c24 LEAQ 0(SP), DI
x.go:4 0x201a 31c0 XORL AX, AX
x.go:4 0x201c e813740400 CALL 0x49434
x.go:5 0x2021 4881c480000000 ADDQ $0x80, SP
x.go:5 0x2028 c3 RET
x.go:3 0x2029 e8224f0400 CALL runtime.morestack_noctxt(SB)
x.go:3 0x202e ebd0 JMP main.f(SB)
Updates #10587.
Sample benchmarks on a 2.8 GHz Intel Core i7:
package sort
name old mean new mean delta
SearchWrappers 134ns × (0.99,1.01) 132ns × (0.99,1.01) -1.73% (p=0.000 n=15+14)
SortString1K 215µs × (0.99,1.01) 213µs × (0.99,1.01) -0.61% (p=0.020 n=14+15)
StableString1K 311µs × (0.99,1.02) 309µs × (0.99,1.02) ~ (p=0.077 n=14+15)
SortInt1K 103µs × (0.99,1.02) 100µs × (0.98,1.01) -3.34% (p=0.000 n=15+15)
StableInt1K 102µs × (0.99,1.01) 98µs × (0.97,1.04) -3.53% (p=0.000 n=15+15)
SortInt64K 10.1ms × (0.98,1.02) 9.7ms × (0.99,1.01) -3.86% (p=0.000 n=14+15)
StableInt64K 8.70ms × (0.99,1.01) 8.44ms × (0.99,1.03) -2.93% (p=0.000 n=14+15)
Sort1e2 51.2µs × (1.00,1.01) 48.9µs × (0.99,1.02) -4.48% (p=0.000 n=13+15)
Stable1e2 100µs × (0.99,1.02) 99µs × (0.99,1.01) -1.15% (p=0.000 n=14+13)
Sort1e4 11.1ms × (0.99,1.02) 10.4ms × (0.99,1.01) -6.02% (p=0.000 n=15+14)
Stable1e4 30.6ms × (0.99,1.01) 30.3ms × (0.99,1.02) -1.02% (p=0.001 n=15+14)
Sort1e6 1.75s × (0.99,1.02) 1.66s × (0.98,1.03) -4.95% (p=0.000 n=14+15)
Stable1e6 6.31s × (0.99,1.01) 6.26s × (0.99,1.01) -0.79% (p=0.002 n=15+15)
package regexp
name old mean new mean delta
Literal 131ns × (0.99,1.01) 130ns × (0.99,1.03) -1.07% (p=0.004 n=14+15)
NotLiteral 2.13µs × (0.99,1.01) 2.01µs × (0.99,1.03) -5.71% (p=0.000 n=14+14)
MatchClass 3.15µs × (0.99,1.01) 3.04µs × (0.99,1.02) -3.40% (p=0.000 n=15+15)
MatchClass_InRange 2.92µs × (0.99,1.01) 2.77µs × (0.99,1.02) -5.05% (p=0.000 n=13+15)
ReplaceAll 2.17µs × (0.99,1.02) 2.06µs × (0.99,1.01) -5.19% (p=0.000 n=15+13)
AnchoredLiteralShortNonMatch 116ns × (0.99,1.02) 113ns × (0.99,1.01) -2.75% (p=0.000 n=15+14)
AnchoredLiteralLongNonMatch 125ns × (0.99,1.01) 127ns × (0.98,1.02) +1.49% (p=0.000 n=15+15)
AnchoredShortMatch 178ns × (0.99,1.02) 175ns × (0.99,1.01) -1.62% (p=0.000 n=15+13)
AnchoredLongMatch 328ns × (0.99,1.00) 341ns × (0.99,1.01) +3.73% (p=0.000 n=12+15)
OnePassShortA 773ns × (0.99,1.02) 752ns × (0.99,1.01) -2.78% (p=0.000 n=15+13)
NotOnePassShortA 794ns × (0.99,1.03) 780ns × (0.99,1.02) -1.75% (p=0.001 n=15+15)
OnePassShortB 608ns × (0.99,1.01) 591ns × (0.99,1.02) -2.86% (p=0.000 n=15+14)
NotOnePassShortB 576ns × (0.99,1.01) 571ns × (0.99,1.02) -0.74% (p=0.035 n=15+15)
OnePassLongPrefix 131ns × (0.99,1.02) 130ns × (0.99,1.02) -1.32% (p=0.003 n=15+15)
OnePassLongNotPrefix 503ns × (0.99,1.02) 481ns × (0.99,1.01) -4.34% (p=0.000 n=15+13)
MatchEasy0_32 102ns × (0.98,1.01) 101ns × (0.99,1.02) ~ (p=0.907 n=15+14)
MatchEasy0_1K 617ns × (0.99,1.02) 634ns × (0.98,1.02) +2.77% (p=0.000 n=15+15)
MatchEasy0_32K 10.9µs × (0.99,1.01) 11.1µs × (0.99,1.01) +1.59% (p=0.000 n=15+15)
MatchEasy0_1M 406µs × (0.99,1.02) 410µs × (0.99,1.02) +1.01% (p=0.000 n=14+15)
MatchEasy0_32M 13.4ms × (0.99,1.01) 13.7ms × (0.99,1.02) +1.64% (p=0.000 n=12+15)
MatchEasy1_32 83.7ns × (0.98,1.02) 83.0ns × (0.98,1.02) ~ (p=0.190 n=15+15)
MatchEasy1_1K 1.46µs × (0.99,1.02) 1.39µs × (0.99,1.02) -4.83% (p=0.000 n=15+15)
MatchEasy1_32K 49.4µs × (0.99,1.01) 49.4µs × (0.99,1.01) ~ (p=0.205 n=15+15)
MatchEasy1_1M 1.72ms × (0.99,1.02) 1.75ms × (0.99,1.01) +1.34% (p=0.000 n=15+15)
MatchEasy1_32M 55.5ms × (0.99,1.01) 56.1ms × (0.99,1.02) +1.10% (p=0.002 n=15+15)
MatchMedium_32 1.37µs × (0.99,1.04) 1.33µs × (0.99,1.01) -2.87% (p=0.000 n=15+15)
MatchMedium_1K 41.1µs × (0.99,1.02) 40.4µs × (0.99,1.02) -1.59% (p=0.000 n=15+15)
MatchMedium_32K 1.71ms × (0.99,1.01) 1.75ms × (0.99,1.02) +2.36% (p=0.000 n=14+15)
MatchMedium_1M 54.5ms × (0.99,1.01) 56.1ms × (0.99,1.01) +2.94% (p=0.000 n=13+15)
MatchMedium_32M 1.75s × (0.99,1.01) 1.80s × (0.99,1.01) +2.77% (p=0.000 n=15+15)
MatchHard_32 2.12µs × (0.99,1.02) 2.06µs × (0.99,1.01) -2.60% (p=0.000 n=15+14)
MatchHard_1K 64.4µs × (0.98,1.02) 62.2µs × (0.99,1.01) -3.33% (p=0.000 n=15+15)
MatchHard_32K 2.74ms × (0.99,1.01) 2.75ms × (0.99,1.01) ~ (p=0.310 n=15+14)
MatchHard_1M 87.1ms × (0.99,1.02) 88.2ms × (0.99,1.01) +1.36% (p=0.000 n=14+15)
MatchHard_32M 2.79s × (0.99,1.02) 2.83s × (0.99,1.02) +1.26% (p=0.004 n=15+14)
go1 benchmarks
name old time/op new time/op delta
BinaryTree17 3.34s ± 3% 3.28s ± 2% -1.86% (p=0.000 n=67+66)
Fannkuch11 2.50s ± 1% 2.51s ± 1% +0.24% (p=0.016 n=63+66)
FmtFprintfEmpty 50.3ns ± 1% 50.2ns ± 2% -0.30% (p=0.001 n=62+67)
FmtFprintfString 178ns ± 1% 166ns ± 1% -7.10% (p=0.000 n=62+59)
FmtFprintfInt 168ns ± 1% 161ns ± 2% -4.41% (p=0.000 n=66+64)
FmtFprintfIntInt 292ns ± 1% 282ns ± 2% -3.55% (p=0.000 n=62+60)
FmtFprintfPrefixedInt 245ns ± 2% 239ns ± 2% -2.24% (p=0.000 n=66+65)
FmtFprintfFloat 338ns ± 2% 326ns ± 1% -3.42% (p=0.000 n=64+59)
FmtManyArgs 1.14µs ± 1% 1.10µs ± 2% -3.55% (p=0.000 n=62+62)
GobDecode 8.88ms ± 2% 8.74ms ± 1% -1.55% (p=0.000 n=66+62)
GobEncode 6.84ms ± 2% 6.61ms ± 2% -3.32% (p=0.000 n=61+67)
Gzip 356ms ± 2% 352ms ± 2% -1.07% (p=0.000 n=67+66)
Gunzip 90.6ms ± 2% 89.8ms ± 1% -0.83% (p=0.000 n=65+64)
HTTPClientServer 82.6µs ± 2% 82.5µs ± 2% ~ (p=0.832 n=65+63)
JSONEncode 17.5ms ± 2% 16.8ms ± 2% -3.77% (p=0.000 n=63+63)
JSONDecode 63.3ms ± 2% 59.0ms ± 2% -6.85% (p=0.000 n=64+63)
Mandelbrot200 3.85ms ± 1% 3.85ms ± 1% ~ (p=0.127 n=65+62)
GoParse 3.75ms ± 2% 3.66ms ± 2% -2.39% (p=0.000 n=66+64)
RegexpMatchEasy0_32 100ns ± 2% 100ns ± 1% -0.65% (p=0.000 n=62+64)
RegexpMatchEasy0_1K 342ns ± 1% 341ns ± 1% -0.43% (p=0.000 n=65+64)
RegexpMatchEasy1_32 82.8ns ± 2% 82.8ns ± 2% ~ (p=0.977 n=63+64)
RegexpMatchEasy1_1K 511ns ± 2% 506ns ± 2% -1.01% (p=0.000 n=63+64)
RegexpMatchMedium_32 139ns ± 1% 134ns ± 3% -3.27% (p=0.000 n=59+60)
RegexpMatchMedium_1K 41.8µs ± 2% 40.5µs ± 2% -3.05% (p=0.000 n=62+64)
RegexpMatchHard_32 2.13µs ± 1% 2.09µs ± 1% -2.22% (p=0.000 n=60+65)
RegexpMatchHard_1K 64.4µs ± 3% 62.8µs ± 2% -2.58% (p=0.000 n=65+59)
Revcomp 531ms ± 2% 529ms ± 1% -0.28% (p=0.022 n=61+61)
Template 73.2ms ± 1% 73.1ms ± 1% ~ (p=0.794 n=66+63)
TimeParse 369ns ± 1% 352ns ± 1% -4.68% (p=0.000 n=65+66)
TimeFormat 374ns ± 2% 348ns ± 2% -7.01% (p=0.000 n=66+64)
Change-Id: Ib190b5bb48a3e9087711d9e3383621d3103dd342
Reviewed-on: https://go-review.googlesource.com/10367
Reviewed-by: Russ Cox <rsc@golang.org>
2015-05-28 17:31:24 -07:00
|
|
|
var last *obj.Prog
|
2017-04-18 10:18:34 -07:00
|
|
|
for last = cursym.Func.Text; last.Link != nil; last = last.Link {
|
cmd/internal/obj/x86: make function prologue more predictable
Static branch prediction guesses that forward branches aren't taken.
Since stacks are rarely grown, make the forward branch mean grow.
Sample disassembly for
func f() {
_ = [128]byte{}
}
Before:
TEXT main.f(SB) x.go
x.go:3 0x2000 65488b0c25a0080000 GS MOVQ GS:0x8a0, CX
x.go:3 0x2009 483b6110 CMPQ 0x10(CX), SP
x.go:3 0x200d 7707 JA 0x2016
x.go:3 0x200f e88c410400 CALL runtime.morestack_noctxt(SB)
x.go:3 0x2014 ebea JMP main.f(SB)
x.go:3 0x2016 4881ec80000000 SUBQ $0x80, SP
x.go:4 0x201d 488d3c24 LEAQ 0(SP), DI
x.go:4 0x2021 31c0 XORL AX, AX
x.go:4 0x2023 e8cc640400 CALL 0x484f4
x.go:5 0x2028 4881c480000000 ADDQ $0x80, SP
x.go:5 0x202f c3 RET
After:
TEXT main.f(SB) x.go
x.go:3 0x2000 65488b0c25a0080000 GS MOVQ GS:0x8a0, CX
x.go:3 0x2009 483b6110 CMPQ 0x10(CX), SP
x.go:3 0x200d 761a JBE 0x2029
x.go:3 0x200f 4881ec80000000 SUBQ $0x80, SP
x.go:4 0x2016 488d3c24 LEAQ 0(SP), DI
x.go:4 0x201a 31c0 XORL AX, AX
x.go:4 0x201c e813740400 CALL 0x49434
x.go:5 0x2021 4881c480000000 ADDQ $0x80, SP
x.go:5 0x2028 c3 RET
x.go:3 0x2029 e8224f0400 CALL runtime.morestack_noctxt(SB)
x.go:3 0x202e ebd0 JMP main.f(SB)
Updates #10587.
Sample benchmarks on a 2.8 GHz Intel Core i7:
package sort
name old mean new mean delta
SearchWrappers 134ns × (0.99,1.01) 132ns × (0.99,1.01) -1.73% (p=0.000 n=15+14)
SortString1K 215µs × (0.99,1.01) 213µs × (0.99,1.01) -0.61% (p=0.020 n=14+15)
StableString1K 311µs × (0.99,1.02) 309µs × (0.99,1.02) ~ (p=0.077 n=14+15)
SortInt1K 103µs × (0.99,1.02) 100µs × (0.98,1.01) -3.34% (p=0.000 n=15+15)
StableInt1K 102µs × (0.99,1.01) 98µs × (0.97,1.04) -3.53% (p=0.000 n=15+15)
SortInt64K 10.1ms × (0.98,1.02) 9.7ms × (0.99,1.01) -3.86% (p=0.000 n=14+15)
StableInt64K 8.70ms × (0.99,1.01) 8.44ms × (0.99,1.03) -2.93% (p=0.000 n=14+15)
Sort1e2 51.2µs × (1.00,1.01) 48.9µs × (0.99,1.02) -4.48% (p=0.000 n=13+15)
Stable1e2 100µs × (0.99,1.02) 99µs × (0.99,1.01) -1.15% (p=0.000 n=14+13)
Sort1e4 11.1ms × (0.99,1.02) 10.4ms × (0.99,1.01) -6.02% (p=0.000 n=15+14)
Stable1e4 30.6ms × (0.99,1.01) 30.3ms × (0.99,1.02) -1.02% (p=0.001 n=15+14)
Sort1e6 1.75s × (0.99,1.02) 1.66s × (0.98,1.03) -4.95% (p=0.000 n=14+15)
Stable1e6 6.31s × (0.99,1.01) 6.26s × (0.99,1.01) -0.79% (p=0.002 n=15+15)
package regexp
name old mean new mean delta
Literal 131ns × (0.99,1.01) 130ns × (0.99,1.03) -1.07% (p=0.004 n=14+15)
NotLiteral 2.13µs × (0.99,1.01) 2.01µs × (0.99,1.03) -5.71% (p=0.000 n=14+14)
MatchClass 3.15µs × (0.99,1.01) 3.04µs × (0.99,1.02) -3.40% (p=0.000 n=15+15)
MatchClass_InRange 2.92µs × (0.99,1.01) 2.77µs × (0.99,1.02) -5.05% (p=0.000 n=13+15)
ReplaceAll 2.17µs × (0.99,1.02) 2.06µs × (0.99,1.01) -5.19% (p=0.000 n=15+13)
AnchoredLiteralShortNonMatch 116ns × (0.99,1.02) 113ns × (0.99,1.01) -2.75% (p=0.000 n=15+14)
AnchoredLiteralLongNonMatch 125ns × (0.99,1.01) 127ns × (0.98,1.02) +1.49% (p=0.000 n=15+15)
AnchoredShortMatch 178ns × (0.99,1.02) 175ns × (0.99,1.01) -1.62% (p=0.000 n=15+13)
AnchoredLongMatch 328ns × (0.99,1.00) 341ns × (0.99,1.01) +3.73% (p=0.000 n=12+15)
OnePassShortA 773ns × (0.99,1.02) 752ns × (0.99,1.01) -2.78% (p=0.000 n=15+13)
NotOnePassShortA 794ns × (0.99,1.03) 780ns × (0.99,1.02) -1.75% (p=0.001 n=15+15)
OnePassShortB 608ns × (0.99,1.01) 591ns × (0.99,1.02) -2.86% (p=0.000 n=15+14)
NotOnePassShortB 576ns × (0.99,1.01) 571ns × (0.99,1.02) -0.74% (p=0.035 n=15+15)
OnePassLongPrefix 131ns × (0.99,1.02) 130ns × (0.99,1.02) -1.32% (p=0.003 n=15+15)
OnePassLongNotPrefix 503ns × (0.99,1.02) 481ns × (0.99,1.01) -4.34% (p=0.000 n=15+13)
MatchEasy0_32 102ns × (0.98,1.01) 101ns × (0.99,1.02) ~ (p=0.907 n=15+14)
MatchEasy0_1K 617ns × (0.99,1.02) 634ns × (0.98,1.02) +2.77% (p=0.000 n=15+15)
MatchEasy0_32K 10.9µs × (0.99,1.01) 11.1µs × (0.99,1.01) +1.59% (p=0.000 n=15+15)
MatchEasy0_1M 406µs × (0.99,1.02) 410µs × (0.99,1.02) +1.01% (p=0.000 n=14+15)
MatchEasy0_32M 13.4ms × (0.99,1.01) 13.7ms × (0.99,1.02) +1.64% (p=0.000 n=12+15)
MatchEasy1_32 83.7ns × (0.98,1.02) 83.0ns × (0.98,1.02) ~ (p=0.190 n=15+15)
MatchEasy1_1K 1.46µs × (0.99,1.02) 1.39µs × (0.99,1.02) -4.83% (p=0.000 n=15+15)
MatchEasy1_32K 49.4µs × (0.99,1.01) 49.4µs × (0.99,1.01) ~ (p=0.205 n=15+15)
MatchEasy1_1M 1.72ms × (0.99,1.02) 1.75ms × (0.99,1.01) +1.34% (p=0.000 n=15+15)
MatchEasy1_32M 55.5ms × (0.99,1.01) 56.1ms × (0.99,1.02) +1.10% (p=0.002 n=15+15)
MatchMedium_32 1.37µs × (0.99,1.04) 1.33µs × (0.99,1.01) -2.87% (p=0.000 n=15+15)
MatchMedium_1K 41.1µs × (0.99,1.02) 40.4µs × (0.99,1.02) -1.59% (p=0.000 n=15+15)
MatchMedium_32K 1.71ms × (0.99,1.01) 1.75ms × (0.99,1.02) +2.36% (p=0.000 n=14+15)
MatchMedium_1M 54.5ms × (0.99,1.01) 56.1ms × (0.99,1.01) +2.94% (p=0.000 n=13+15)
MatchMedium_32M 1.75s × (0.99,1.01) 1.80s × (0.99,1.01) +2.77% (p=0.000 n=15+15)
MatchHard_32 2.12µs × (0.99,1.02) 2.06µs × (0.99,1.01) -2.60% (p=0.000 n=15+14)
MatchHard_1K 64.4µs × (0.98,1.02) 62.2µs × (0.99,1.01) -3.33% (p=0.000 n=15+15)
MatchHard_32K 2.74ms × (0.99,1.01) 2.75ms × (0.99,1.01) ~ (p=0.310 n=15+14)
MatchHard_1M 87.1ms × (0.99,1.02) 88.2ms × (0.99,1.01) +1.36% (p=0.000 n=14+15)
MatchHard_32M 2.79s × (0.99,1.02) 2.83s × (0.99,1.02) +1.26% (p=0.004 n=15+14)
go1 benchmarks
name old time/op new time/op delta
BinaryTree17 3.34s ± 3% 3.28s ± 2% -1.86% (p=0.000 n=67+66)
Fannkuch11 2.50s ± 1% 2.51s ± 1% +0.24% (p=0.016 n=63+66)
FmtFprintfEmpty 50.3ns ± 1% 50.2ns ± 2% -0.30% (p=0.001 n=62+67)
FmtFprintfString 178ns ± 1% 166ns ± 1% -7.10% (p=0.000 n=62+59)
FmtFprintfInt 168ns ± 1% 161ns ± 2% -4.41% (p=0.000 n=66+64)
FmtFprintfIntInt 292ns ± 1% 282ns ± 2% -3.55% (p=0.000 n=62+60)
FmtFprintfPrefixedInt 245ns ± 2% 239ns ± 2% -2.24% (p=0.000 n=66+65)
FmtFprintfFloat 338ns ± 2% 326ns ± 1% -3.42% (p=0.000 n=64+59)
FmtManyArgs 1.14µs ± 1% 1.10µs ± 2% -3.55% (p=0.000 n=62+62)
GobDecode 8.88ms ± 2% 8.74ms ± 1% -1.55% (p=0.000 n=66+62)
GobEncode 6.84ms ± 2% 6.61ms ± 2% -3.32% (p=0.000 n=61+67)
Gzip 356ms ± 2% 352ms ± 2% -1.07% (p=0.000 n=67+66)
Gunzip 90.6ms ± 2% 89.8ms ± 1% -0.83% (p=0.000 n=65+64)
HTTPClientServer 82.6µs ± 2% 82.5µs ± 2% ~ (p=0.832 n=65+63)
JSONEncode 17.5ms ± 2% 16.8ms ± 2% -3.77% (p=0.000 n=63+63)
JSONDecode 63.3ms ± 2% 59.0ms ± 2% -6.85% (p=0.000 n=64+63)
Mandelbrot200 3.85ms ± 1% 3.85ms ± 1% ~ (p=0.127 n=65+62)
GoParse 3.75ms ± 2% 3.66ms ± 2% -2.39% (p=0.000 n=66+64)
RegexpMatchEasy0_32 100ns ± 2% 100ns ± 1% -0.65% (p=0.000 n=62+64)
RegexpMatchEasy0_1K 342ns ± 1% 341ns ± 1% -0.43% (p=0.000 n=65+64)
RegexpMatchEasy1_32 82.8ns ± 2% 82.8ns ± 2% ~ (p=0.977 n=63+64)
RegexpMatchEasy1_1K 511ns ± 2% 506ns ± 2% -1.01% (p=0.000 n=63+64)
RegexpMatchMedium_32 139ns ± 1% 134ns ± 3% -3.27% (p=0.000 n=59+60)
RegexpMatchMedium_1K 41.8µs ± 2% 40.5µs ± 2% -3.05% (p=0.000 n=62+64)
RegexpMatchHard_32 2.13µs ± 1% 2.09µs ± 1% -2.22% (p=0.000 n=60+65)
RegexpMatchHard_1K 64.4µs ± 3% 62.8µs ± 2% -2.58% (p=0.000 n=65+59)
Revcomp 531ms ± 2% 529ms ± 1% -0.28% (p=0.022 n=61+61)
Template 73.2ms ± 1% 73.1ms ± 1% ~ (p=0.794 n=66+63)
TimeParse 369ns ± 1% 352ns ± 1% -4.68% (p=0.000 n=65+66)
TimeFormat 374ns ± 2% 348ns ± 2% -7.01% (p=0.000 n=66+64)
Change-Id: Ib190b5bb48a3e9087711d9e3383621d3103dd342
Reviewed-on: https://go-review.googlesource.com/10367
Reviewed-by: Russ Cox <rsc@golang.org>
2015-05-28 17:31:24 -07:00
|
|
|
}
|
|
|
|
|
2016-10-02 17:10:13 -04:00
|
|
|
// Now we are at the end of the function, but logically
|
|
|
|
// we are still in function prologue. We need to fix the
|
|
|
|
// SP data and PCDATA.
|
2017-04-04 14:31:55 -07:00
|
|
|
spfix := obj.Appendp(last, newprog)
|
2015-12-30 15:19:54 -08:00
|
|
|
spfix.As = obj.ANOP
|
|
|
|
spfix.Spadj = -framesize
|
|
|
|
|
cmd/internal/obj: mark split-stack prologue nonpreemptible
When there are both a synchronous preemption request (by
clobbering the stack guard) and an asynchronous one (by signal),
the running goroutine may observe the synchronous request first
in stack bounds check, and go to the path of calling morestack.
If the preemption signal arrives at this point before the call to
morestack, the goroutine will be asynchronously preempted,
entering the scheduler. When it is resumed, the scheduler clears
the preemption request, unclobbers the stack guard. But the
resumed goroutine will still call morestack, as it is already on
its way. morestack will, as there is no preemption request,
double the stack unnecessarily. If this happens multiple times,
the stack may grow too big, although only a small amount is
actually used.
To fix this, we mark the stack bounds check and the call to
morestack async-nonpreemptible, starting after the memory
instruction (mostly a load, on x86 CMP with memory).
Not done for Wasm as it does not support async preemption.
Fixes #35470.
Change-Id: Ibd7f3d935a3649b80f47539116ec9b9556680cf2
Reviewed-on: https://go-review.googlesource.com/c/go/+/207350
Reviewed-by: David Chase <drchase@google.com>
2019-11-14 20:23:17 -05:00
|
|
|
pcdata := ctxt.EmitEntryStackMap(cursym, spfix, newprog)
|
|
|
|
pcdata = ctxt.StartUnsafePoint(pcdata, newprog)
|
2016-10-02 17:10:13 -04:00
|
|
|
|
2017-04-04 14:31:55 -07:00
|
|
|
call := obj.Appendp(pcdata, newprog)
|
2017-04-18 10:18:34 -07:00
|
|
|
call.Pos = cursym.Func.Text.Pos
|
cmd/internal/obj/x86: make function prologue more predictable
Static branch prediction guesses that forward branches aren't taken.
Since stacks are rarely grown, make the forward branch mean grow.
Sample disassembly for
func f() {
_ = [128]byte{}
}
Before:
TEXT main.f(SB) x.go
x.go:3 0x2000 65488b0c25a0080000 GS MOVQ GS:0x8a0, CX
x.go:3 0x2009 483b6110 CMPQ 0x10(CX), SP
x.go:3 0x200d 7707 JA 0x2016
x.go:3 0x200f e88c410400 CALL runtime.morestack_noctxt(SB)
x.go:3 0x2014 ebea JMP main.f(SB)
x.go:3 0x2016 4881ec80000000 SUBQ $0x80, SP
x.go:4 0x201d 488d3c24 LEAQ 0(SP), DI
x.go:4 0x2021 31c0 XORL AX, AX
x.go:4 0x2023 e8cc640400 CALL 0x484f4
x.go:5 0x2028 4881c480000000 ADDQ $0x80, SP
x.go:5 0x202f c3 RET
After:
TEXT main.f(SB) x.go
x.go:3 0x2000 65488b0c25a0080000 GS MOVQ GS:0x8a0, CX
x.go:3 0x2009 483b6110 CMPQ 0x10(CX), SP
x.go:3 0x200d 761a JBE 0x2029
x.go:3 0x200f 4881ec80000000 SUBQ $0x80, SP
x.go:4 0x2016 488d3c24 LEAQ 0(SP), DI
x.go:4 0x201a 31c0 XORL AX, AX
x.go:4 0x201c e813740400 CALL 0x49434
x.go:5 0x2021 4881c480000000 ADDQ $0x80, SP
x.go:5 0x2028 c3 RET
x.go:3 0x2029 e8224f0400 CALL runtime.morestack_noctxt(SB)
x.go:3 0x202e ebd0 JMP main.f(SB)
Updates #10587.
Sample benchmarks on a 2.8 GHz Intel Core i7:
package sort
name old mean new mean delta
SearchWrappers 134ns × (0.99,1.01) 132ns × (0.99,1.01) -1.73% (p=0.000 n=15+14)
SortString1K 215µs × (0.99,1.01) 213µs × (0.99,1.01) -0.61% (p=0.020 n=14+15)
StableString1K 311µs × (0.99,1.02) 309µs × (0.99,1.02) ~ (p=0.077 n=14+15)
SortInt1K 103µs × (0.99,1.02) 100µs × (0.98,1.01) -3.34% (p=0.000 n=15+15)
StableInt1K 102µs × (0.99,1.01) 98µs × (0.97,1.04) -3.53% (p=0.000 n=15+15)
SortInt64K 10.1ms × (0.98,1.02) 9.7ms × (0.99,1.01) -3.86% (p=0.000 n=14+15)
StableInt64K 8.70ms × (0.99,1.01) 8.44ms × (0.99,1.03) -2.93% (p=0.000 n=14+15)
Sort1e2 51.2µs × (1.00,1.01) 48.9µs × (0.99,1.02) -4.48% (p=0.000 n=13+15)
Stable1e2 100µs × (0.99,1.02) 99µs × (0.99,1.01) -1.15% (p=0.000 n=14+13)
Sort1e4 11.1ms × (0.99,1.02) 10.4ms × (0.99,1.01) -6.02% (p=0.000 n=15+14)
Stable1e4 30.6ms × (0.99,1.01) 30.3ms × (0.99,1.02) -1.02% (p=0.001 n=15+14)
Sort1e6 1.75s × (0.99,1.02) 1.66s × (0.98,1.03) -4.95% (p=0.000 n=14+15)
Stable1e6 6.31s × (0.99,1.01) 6.26s × (0.99,1.01) -0.79% (p=0.002 n=15+15)
package regexp
name old mean new mean delta
Literal 131ns × (0.99,1.01) 130ns × (0.99,1.03) -1.07% (p=0.004 n=14+15)
NotLiteral 2.13µs × (0.99,1.01) 2.01µs × (0.99,1.03) -5.71% (p=0.000 n=14+14)
MatchClass 3.15µs × (0.99,1.01) 3.04µs × (0.99,1.02) -3.40% (p=0.000 n=15+15)
MatchClass_InRange 2.92µs × (0.99,1.01) 2.77µs × (0.99,1.02) -5.05% (p=0.000 n=13+15)
ReplaceAll 2.17µs × (0.99,1.02) 2.06µs × (0.99,1.01) -5.19% (p=0.000 n=15+13)
AnchoredLiteralShortNonMatch 116ns × (0.99,1.02) 113ns × (0.99,1.01) -2.75% (p=0.000 n=15+14)
AnchoredLiteralLongNonMatch 125ns × (0.99,1.01) 127ns × (0.98,1.02) +1.49% (p=0.000 n=15+15)
AnchoredShortMatch 178ns × (0.99,1.02) 175ns × (0.99,1.01) -1.62% (p=0.000 n=15+13)
AnchoredLongMatch 328ns × (0.99,1.00) 341ns × (0.99,1.01) +3.73% (p=0.000 n=12+15)
OnePassShortA 773ns × (0.99,1.02) 752ns × (0.99,1.01) -2.78% (p=0.000 n=15+13)
NotOnePassShortA 794ns × (0.99,1.03) 780ns × (0.99,1.02) -1.75% (p=0.001 n=15+15)
OnePassShortB 608ns × (0.99,1.01) 591ns × (0.99,1.02) -2.86% (p=0.000 n=15+14)
NotOnePassShortB 576ns × (0.99,1.01) 571ns × (0.99,1.02) -0.74% (p=0.035 n=15+15)
OnePassLongPrefix 131ns × (0.99,1.02) 130ns × (0.99,1.02) -1.32% (p=0.003 n=15+15)
OnePassLongNotPrefix 503ns × (0.99,1.02) 481ns × (0.99,1.01) -4.34% (p=0.000 n=15+13)
MatchEasy0_32 102ns × (0.98,1.01) 101ns × (0.99,1.02) ~ (p=0.907 n=15+14)
MatchEasy0_1K 617ns × (0.99,1.02) 634ns × (0.98,1.02) +2.77% (p=0.000 n=15+15)
MatchEasy0_32K 10.9µs × (0.99,1.01) 11.1µs × (0.99,1.01) +1.59% (p=0.000 n=15+15)
MatchEasy0_1M 406µs × (0.99,1.02) 410µs × (0.99,1.02) +1.01% (p=0.000 n=14+15)
MatchEasy0_32M 13.4ms × (0.99,1.01) 13.7ms × (0.99,1.02) +1.64% (p=0.000 n=12+15)
MatchEasy1_32 83.7ns × (0.98,1.02) 83.0ns × (0.98,1.02) ~ (p=0.190 n=15+15)
MatchEasy1_1K 1.46µs × (0.99,1.02) 1.39µs × (0.99,1.02) -4.83% (p=0.000 n=15+15)
MatchEasy1_32K 49.4µs × (0.99,1.01) 49.4µs × (0.99,1.01) ~ (p=0.205 n=15+15)
MatchEasy1_1M 1.72ms × (0.99,1.02) 1.75ms × (0.99,1.01) +1.34% (p=0.000 n=15+15)
MatchEasy1_32M 55.5ms × (0.99,1.01) 56.1ms × (0.99,1.02) +1.10% (p=0.002 n=15+15)
MatchMedium_32 1.37µs × (0.99,1.04) 1.33µs × (0.99,1.01) -2.87% (p=0.000 n=15+15)
MatchMedium_1K 41.1µs × (0.99,1.02) 40.4µs × (0.99,1.02) -1.59% (p=0.000 n=15+15)
MatchMedium_32K 1.71ms × (0.99,1.01) 1.75ms × (0.99,1.02) +2.36% (p=0.000 n=14+15)
MatchMedium_1M 54.5ms × (0.99,1.01) 56.1ms × (0.99,1.01) +2.94% (p=0.000 n=13+15)
MatchMedium_32M 1.75s × (0.99,1.01) 1.80s × (0.99,1.01) +2.77% (p=0.000 n=15+15)
MatchHard_32 2.12µs × (0.99,1.02) 2.06µs × (0.99,1.01) -2.60% (p=0.000 n=15+14)
MatchHard_1K 64.4µs × (0.98,1.02) 62.2µs × (0.99,1.01) -3.33% (p=0.000 n=15+15)
MatchHard_32K 2.74ms × (0.99,1.01) 2.75ms × (0.99,1.01) ~ (p=0.310 n=15+14)
MatchHard_1M 87.1ms × (0.99,1.02) 88.2ms × (0.99,1.01) +1.36% (p=0.000 n=14+15)
MatchHard_32M 2.79s × (0.99,1.02) 2.83s × (0.99,1.02) +1.26% (p=0.004 n=15+14)
go1 benchmarks
name old time/op new time/op delta
BinaryTree17 3.34s ± 3% 3.28s ± 2% -1.86% (p=0.000 n=67+66)
Fannkuch11 2.50s ± 1% 2.51s ± 1% +0.24% (p=0.016 n=63+66)
FmtFprintfEmpty 50.3ns ± 1% 50.2ns ± 2% -0.30% (p=0.001 n=62+67)
FmtFprintfString 178ns ± 1% 166ns ± 1% -7.10% (p=0.000 n=62+59)
FmtFprintfInt 168ns ± 1% 161ns ± 2% -4.41% (p=0.000 n=66+64)
FmtFprintfIntInt 292ns ± 1% 282ns ± 2% -3.55% (p=0.000 n=62+60)
FmtFprintfPrefixedInt 245ns ± 2% 239ns ± 2% -2.24% (p=0.000 n=66+65)
FmtFprintfFloat 338ns ± 2% 326ns ± 1% -3.42% (p=0.000 n=64+59)
FmtManyArgs 1.14µs ± 1% 1.10µs ± 2% -3.55% (p=0.000 n=62+62)
GobDecode 8.88ms ± 2% 8.74ms ± 1% -1.55% (p=0.000 n=66+62)
GobEncode 6.84ms ± 2% 6.61ms ± 2% -3.32% (p=0.000 n=61+67)
Gzip 356ms ± 2% 352ms ± 2% -1.07% (p=0.000 n=67+66)
Gunzip 90.6ms ± 2% 89.8ms ± 1% -0.83% (p=0.000 n=65+64)
HTTPClientServer 82.6µs ± 2% 82.5µs ± 2% ~ (p=0.832 n=65+63)
JSONEncode 17.5ms ± 2% 16.8ms ± 2% -3.77% (p=0.000 n=63+63)
JSONDecode 63.3ms ± 2% 59.0ms ± 2% -6.85% (p=0.000 n=64+63)
Mandelbrot200 3.85ms ± 1% 3.85ms ± 1% ~ (p=0.127 n=65+62)
GoParse 3.75ms ± 2% 3.66ms ± 2% -2.39% (p=0.000 n=66+64)
RegexpMatchEasy0_32 100ns ± 2% 100ns ± 1% -0.65% (p=0.000 n=62+64)
RegexpMatchEasy0_1K 342ns ± 1% 341ns ± 1% -0.43% (p=0.000 n=65+64)
RegexpMatchEasy1_32 82.8ns ± 2% 82.8ns ± 2% ~ (p=0.977 n=63+64)
RegexpMatchEasy1_1K 511ns ± 2% 506ns ± 2% -1.01% (p=0.000 n=63+64)
RegexpMatchMedium_32 139ns ± 1% 134ns ± 3% -3.27% (p=0.000 n=59+60)
RegexpMatchMedium_1K 41.8µs ± 2% 40.5µs ± 2% -3.05% (p=0.000 n=62+64)
RegexpMatchHard_32 2.13µs ± 1% 2.09µs ± 1% -2.22% (p=0.000 n=60+65)
RegexpMatchHard_1K 64.4µs ± 3% 62.8µs ± 2% -2.58% (p=0.000 n=65+59)
Revcomp 531ms ± 2% 529ms ± 1% -0.28% (p=0.022 n=61+61)
Template 73.2ms ± 1% 73.1ms ± 1% ~ (p=0.794 n=66+63)
TimeParse 369ns ± 1% 352ns ± 1% -4.68% (p=0.000 n=65+66)
TimeFormat 374ns ± 2% 348ns ± 2% -7.01% (p=0.000 n=66+64)
Change-Id: Ib190b5bb48a3e9087711d9e3383621d3103dd342
Reviewed-on: https://go-review.googlesource.com/10367
Reviewed-by: Russ Cox <rsc@golang.org>
2015-05-28 17:31:24 -07:00
|
|
|
call.As = obj.ACALL
|
|
|
|
call.To.Type = obj.TYPE_BRANCH
|
2016-06-02 11:07:55 +12:00
|
|
|
call.To.Name = obj.NAME_EXTERN
|
cmd/internal/obj/x86: make function prologue more predictable
Static branch prediction guesses that forward branches aren't taken.
Since stacks are rarely grown, make the forward branch mean grow.
Sample disassembly for
func f() {
_ = [128]byte{}
}
Before:
TEXT main.f(SB) x.go
x.go:3 0x2000 65488b0c25a0080000 GS MOVQ GS:0x8a0, CX
x.go:3 0x2009 483b6110 CMPQ 0x10(CX), SP
x.go:3 0x200d 7707 JA 0x2016
x.go:3 0x200f e88c410400 CALL runtime.morestack_noctxt(SB)
x.go:3 0x2014 ebea JMP main.f(SB)
x.go:3 0x2016 4881ec80000000 SUBQ $0x80, SP
x.go:4 0x201d 488d3c24 LEAQ 0(SP), DI
x.go:4 0x2021 31c0 XORL AX, AX
x.go:4 0x2023 e8cc640400 CALL 0x484f4
x.go:5 0x2028 4881c480000000 ADDQ $0x80, SP
x.go:5 0x202f c3 RET
After:
TEXT main.f(SB) x.go
x.go:3 0x2000 65488b0c25a0080000 GS MOVQ GS:0x8a0, CX
x.go:3 0x2009 483b6110 CMPQ 0x10(CX), SP
x.go:3 0x200d 761a JBE 0x2029
x.go:3 0x200f 4881ec80000000 SUBQ $0x80, SP
x.go:4 0x2016 488d3c24 LEAQ 0(SP), DI
x.go:4 0x201a 31c0 XORL AX, AX
x.go:4 0x201c e813740400 CALL 0x49434
x.go:5 0x2021 4881c480000000 ADDQ $0x80, SP
x.go:5 0x2028 c3 RET
x.go:3 0x2029 e8224f0400 CALL runtime.morestack_noctxt(SB)
x.go:3 0x202e ebd0 JMP main.f(SB)
Updates #10587.
Sample benchmarks on a 2.8 GHz Intel Core i7:
package sort
name old mean new mean delta
SearchWrappers 134ns × (0.99,1.01) 132ns × (0.99,1.01) -1.73% (p=0.000 n=15+14)
SortString1K 215µs × (0.99,1.01) 213µs × (0.99,1.01) -0.61% (p=0.020 n=14+15)
StableString1K 311µs × (0.99,1.02) 309µs × (0.99,1.02) ~ (p=0.077 n=14+15)
SortInt1K 103µs × (0.99,1.02) 100µs × (0.98,1.01) -3.34% (p=0.000 n=15+15)
StableInt1K 102µs × (0.99,1.01) 98µs × (0.97,1.04) -3.53% (p=0.000 n=15+15)
SortInt64K 10.1ms × (0.98,1.02) 9.7ms × (0.99,1.01) -3.86% (p=0.000 n=14+15)
StableInt64K 8.70ms × (0.99,1.01) 8.44ms × (0.99,1.03) -2.93% (p=0.000 n=14+15)
Sort1e2 51.2µs × (1.00,1.01) 48.9µs × (0.99,1.02) -4.48% (p=0.000 n=13+15)
Stable1e2 100µs × (0.99,1.02) 99µs × (0.99,1.01) -1.15% (p=0.000 n=14+13)
Sort1e4 11.1ms × (0.99,1.02) 10.4ms × (0.99,1.01) -6.02% (p=0.000 n=15+14)
Stable1e4 30.6ms × (0.99,1.01) 30.3ms × (0.99,1.02) -1.02% (p=0.001 n=15+14)
Sort1e6 1.75s × (0.99,1.02) 1.66s × (0.98,1.03) -4.95% (p=0.000 n=14+15)
Stable1e6 6.31s × (0.99,1.01) 6.26s × (0.99,1.01) -0.79% (p=0.002 n=15+15)
package regexp
name old mean new mean delta
Literal 131ns × (0.99,1.01) 130ns × (0.99,1.03) -1.07% (p=0.004 n=14+15)
NotLiteral 2.13µs × (0.99,1.01) 2.01µs × (0.99,1.03) -5.71% (p=0.000 n=14+14)
MatchClass 3.15µs × (0.99,1.01) 3.04µs × (0.99,1.02) -3.40% (p=0.000 n=15+15)
MatchClass_InRange 2.92µs × (0.99,1.01) 2.77µs × (0.99,1.02) -5.05% (p=0.000 n=13+15)
ReplaceAll 2.17µs × (0.99,1.02) 2.06µs × (0.99,1.01) -5.19% (p=0.000 n=15+13)
AnchoredLiteralShortNonMatch 116ns × (0.99,1.02) 113ns × (0.99,1.01) -2.75% (p=0.000 n=15+14)
AnchoredLiteralLongNonMatch 125ns × (0.99,1.01) 127ns × (0.98,1.02) +1.49% (p=0.000 n=15+15)
AnchoredShortMatch 178ns × (0.99,1.02) 175ns × (0.99,1.01) -1.62% (p=0.000 n=15+13)
AnchoredLongMatch 328ns × (0.99,1.00) 341ns × (0.99,1.01) +3.73% (p=0.000 n=12+15)
OnePassShortA 773ns × (0.99,1.02) 752ns × (0.99,1.01) -2.78% (p=0.000 n=15+13)
NotOnePassShortA 794ns × (0.99,1.03) 780ns × (0.99,1.02) -1.75% (p=0.001 n=15+15)
OnePassShortB 608ns × (0.99,1.01) 591ns × (0.99,1.02) -2.86% (p=0.000 n=15+14)
NotOnePassShortB 576ns × (0.99,1.01) 571ns × (0.99,1.02) -0.74% (p=0.035 n=15+15)
OnePassLongPrefix 131ns × (0.99,1.02) 130ns × (0.99,1.02) -1.32% (p=0.003 n=15+15)
OnePassLongNotPrefix 503ns × (0.99,1.02) 481ns × (0.99,1.01) -4.34% (p=0.000 n=15+13)
MatchEasy0_32 102ns × (0.98,1.01) 101ns × (0.99,1.02) ~ (p=0.907 n=15+14)
MatchEasy0_1K 617ns × (0.99,1.02) 634ns × (0.98,1.02) +2.77% (p=0.000 n=15+15)
MatchEasy0_32K 10.9µs × (0.99,1.01) 11.1µs × (0.99,1.01) +1.59% (p=0.000 n=15+15)
MatchEasy0_1M 406µs × (0.99,1.02) 410µs × (0.99,1.02) +1.01% (p=0.000 n=14+15)
MatchEasy0_32M 13.4ms × (0.99,1.01) 13.7ms × (0.99,1.02) +1.64% (p=0.000 n=12+15)
MatchEasy1_32 83.7ns × (0.98,1.02) 83.0ns × (0.98,1.02) ~ (p=0.190 n=15+15)
MatchEasy1_1K 1.46µs × (0.99,1.02) 1.39µs × (0.99,1.02) -4.83% (p=0.000 n=15+15)
MatchEasy1_32K 49.4µs × (0.99,1.01) 49.4µs × (0.99,1.01) ~ (p=0.205 n=15+15)
MatchEasy1_1M 1.72ms × (0.99,1.02) 1.75ms × (0.99,1.01) +1.34% (p=0.000 n=15+15)
MatchEasy1_32M 55.5ms × (0.99,1.01) 56.1ms × (0.99,1.02) +1.10% (p=0.002 n=15+15)
MatchMedium_32 1.37µs × (0.99,1.04) 1.33µs × (0.99,1.01) -2.87% (p=0.000 n=15+15)
MatchMedium_1K 41.1µs × (0.99,1.02) 40.4µs × (0.99,1.02) -1.59% (p=0.000 n=15+15)
MatchMedium_32K 1.71ms × (0.99,1.01) 1.75ms × (0.99,1.02) +2.36% (p=0.000 n=14+15)
MatchMedium_1M 54.5ms × (0.99,1.01) 56.1ms × (0.99,1.01) +2.94% (p=0.000 n=13+15)
MatchMedium_32M 1.75s × (0.99,1.01) 1.80s × (0.99,1.01) +2.77% (p=0.000 n=15+15)
MatchHard_32 2.12µs × (0.99,1.02) 2.06µs × (0.99,1.01) -2.60% (p=0.000 n=15+14)
MatchHard_1K 64.4µs × (0.98,1.02) 62.2µs × (0.99,1.01) -3.33% (p=0.000 n=15+15)
MatchHard_32K 2.74ms × (0.99,1.01) 2.75ms × (0.99,1.01) ~ (p=0.310 n=15+14)
MatchHard_1M 87.1ms × (0.99,1.02) 88.2ms × (0.99,1.01) +1.36% (p=0.000 n=14+15)
MatchHard_32M 2.79s × (0.99,1.02) 2.83s × (0.99,1.02) +1.26% (p=0.004 n=15+14)
go1 benchmarks
name old time/op new time/op delta
BinaryTree17 3.34s ± 3% 3.28s ± 2% -1.86% (p=0.000 n=67+66)
Fannkuch11 2.50s ± 1% 2.51s ± 1% +0.24% (p=0.016 n=63+66)
FmtFprintfEmpty 50.3ns ± 1% 50.2ns ± 2% -0.30% (p=0.001 n=62+67)
FmtFprintfString 178ns ± 1% 166ns ± 1% -7.10% (p=0.000 n=62+59)
FmtFprintfInt 168ns ± 1% 161ns ± 2% -4.41% (p=0.000 n=66+64)
FmtFprintfIntInt 292ns ± 1% 282ns ± 2% -3.55% (p=0.000 n=62+60)
FmtFprintfPrefixedInt 245ns ± 2% 239ns ± 2% -2.24% (p=0.000 n=66+65)
FmtFprintfFloat 338ns ± 2% 326ns ± 1% -3.42% (p=0.000 n=64+59)
FmtManyArgs 1.14µs ± 1% 1.10µs ± 2% -3.55% (p=0.000 n=62+62)
GobDecode 8.88ms ± 2% 8.74ms ± 1% -1.55% (p=0.000 n=66+62)
GobEncode 6.84ms ± 2% 6.61ms ± 2% -3.32% (p=0.000 n=61+67)
Gzip 356ms ± 2% 352ms ± 2% -1.07% (p=0.000 n=67+66)
Gunzip 90.6ms ± 2% 89.8ms ± 1% -0.83% (p=0.000 n=65+64)
HTTPClientServer 82.6µs ± 2% 82.5µs ± 2% ~ (p=0.832 n=65+63)
JSONEncode 17.5ms ± 2% 16.8ms ± 2% -3.77% (p=0.000 n=63+63)
JSONDecode 63.3ms ± 2% 59.0ms ± 2% -6.85% (p=0.000 n=64+63)
Mandelbrot200 3.85ms ± 1% 3.85ms ± 1% ~ (p=0.127 n=65+62)
GoParse 3.75ms ± 2% 3.66ms ± 2% -2.39% (p=0.000 n=66+64)
RegexpMatchEasy0_32 100ns ± 2% 100ns ± 1% -0.65% (p=0.000 n=62+64)
RegexpMatchEasy0_1K 342ns ± 1% 341ns ± 1% -0.43% (p=0.000 n=65+64)
RegexpMatchEasy1_32 82.8ns ± 2% 82.8ns ± 2% ~ (p=0.977 n=63+64)
RegexpMatchEasy1_1K 511ns ± 2% 506ns ± 2% -1.01% (p=0.000 n=63+64)
RegexpMatchMedium_32 139ns ± 1% 134ns ± 3% -3.27% (p=0.000 n=59+60)
RegexpMatchMedium_1K 41.8µs ± 2% 40.5µs ± 2% -3.05% (p=0.000 n=62+64)
RegexpMatchHard_32 2.13µs ± 1% 2.09µs ± 1% -2.22% (p=0.000 n=60+65)
RegexpMatchHard_1K 64.4µs ± 3% 62.8µs ± 2% -2.58% (p=0.000 n=65+59)
Revcomp 531ms ± 2% 529ms ± 1% -0.28% (p=0.022 n=61+61)
Template 73.2ms ± 1% 73.1ms ± 1% ~ (p=0.794 n=66+63)
TimeParse 369ns ± 1% 352ns ± 1% -4.68% (p=0.000 n=65+66)
TimeFormat 374ns ± 2% 348ns ± 2% -7.01% (p=0.000 n=66+64)
Change-Id: Ib190b5bb48a3e9087711d9e3383621d3103dd342
Reviewed-on: https://go-review.googlesource.com/10367
Reviewed-by: Russ Cox <rsc@golang.org>
2015-05-28 17:31:24 -07:00
|
|
|
morestack := "runtime.morestack"
|
|
|
|
switch {
|
2017-03-26 07:46:30 -07:00
|
|
|
case cursym.CFunc():
|
cmd/internal/obj/x86: make function prologue more predictable
Static branch prediction guesses that forward branches aren't taken.
Since stacks are rarely grown, make the forward branch mean grow.
Sample disassembly for
func f() {
_ = [128]byte{}
}
Before:
TEXT main.f(SB) x.go
x.go:3 0x2000 65488b0c25a0080000 GS MOVQ GS:0x8a0, CX
x.go:3 0x2009 483b6110 CMPQ 0x10(CX), SP
x.go:3 0x200d 7707 JA 0x2016
x.go:3 0x200f e88c410400 CALL runtime.morestack_noctxt(SB)
x.go:3 0x2014 ebea JMP main.f(SB)
x.go:3 0x2016 4881ec80000000 SUBQ $0x80, SP
x.go:4 0x201d 488d3c24 LEAQ 0(SP), DI
x.go:4 0x2021 31c0 XORL AX, AX
x.go:4 0x2023 e8cc640400 CALL 0x484f4
x.go:5 0x2028 4881c480000000 ADDQ $0x80, SP
x.go:5 0x202f c3 RET
After:
TEXT main.f(SB) x.go
x.go:3 0x2000 65488b0c25a0080000 GS MOVQ GS:0x8a0, CX
x.go:3 0x2009 483b6110 CMPQ 0x10(CX), SP
x.go:3 0x200d 761a JBE 0x2029
x.go:3 0x200f 4881ec80000000 SUBQ $0x80, SP
x.go:4 0x2016 488d3c24 LEAQ 0(SP), DI
x.go:4 0x201a 31c0 XORL AX, AX
x.go:4 0x201c e813740400 CALL 0x49434
x.go:5 0x2021 4881c480000000 ADDQ $0x80, SP
x.go:5 0x2028 c3 RET
x.go:3 0x2029 e8224f0400 CALL runtime.morestack_noctxt(SB)
x.go:3 0x202e ebd0 JMP main.f(SB)
Updates #10587.
Sample benchmarks on a 2.8 GHz Intel Core i7:
package sort
name old mean new mean delta
SearchWrappers 134ns × (0.99,1.01) 132ns × (0.99,1.01) -1.73% (p=0.000 n=15+14)
SortString1K 215µs × (0.99,1.01) 213µs × (0.99,1.01) -0.61% (p=0.020 n=14+15)
StableString1K 311µs × (0.99,1.02) 309µs × (0.99,1.02) ~ (p=0.077 n=14+15)
SortInt1K 103µs × (0.99,1.02) 100µs × (0.98,1.01) -3.34% (p=0.000 n=15+15)
StableInt1K 102µs × (0.99,1.01) 98µs × (0.97,1.04) -3.53% (p=0.000 n=15+15)
SortInt64K 10.1ms × (0.98,1.02) 9.7ms × (0.99,1.01) -3.86% (p=0.000 n=14+15)
StableInt64K 8.70ms × (0.99,1.01) 8.44ms × (0.99,1.03) -2.93% (p=0.000 n=14+15)
Sort1e2 51.2µs × (1.00,1.01) 48.9µs × (0.99,1.02) -4.48% (p=0.000 n=13+15)
Stable1e2 100µs × (0.99,1.02) 99µs × (0.99,1.01) -1.15% (p=0.000 n=14+13)
Sort1e4 11.1ms × (0.99,1.02) 10.4ms × (0.99,1.01) -6.02% (p=0.000 n=15+14)
Stable1e4 30.6ms × (0.99,1.01) 30.3ms × (0.99,1.02) -1.02% (p=0.001 n=15+14)
Sort1e6 1.75s × (0.99,1.02) 1.66s × (0.98,1.03) -4.95% (p=0.000 n=14+15)
Stable1e6 6.31s × (0.99,1.01) 6.26s × (0.99,1.01) -0.79% (p=0.002 n=15+15)
package regexp
name old mean new mean delta
Literal 131ns × (0.99,1.01) 130ns × (0.99,1.03) -1.07% (p=0.004 n=14+15)
NotLiteral 2.13µs × (0.99,1.01) 2.01µs × (0.99,1.03) -5.71% (p=0.000 n=14+14)
MatchClass 3.15µs × (0.99,1.01) 3.04µs × (0.99,1.02) -3.40% (p=0.000 n=15+15)
MatchClass_InRange 2.92µs × (0.99,1.01) 2.77µs × (0.99,1.02) -5.05% (p=0.000 n=13+15)
ReplaceAll 2.17µs × (0.99,1.02) 2.06µs × (0.99,1.01) -5.19% (p=0.000 n=15+13)
AnchoredLiteralShortNonMatch 116ns × (0.99,1.02) 113ns × (0.99,1.01) -2.75% (p=0.000 n=15+14)
AnchoredLiteralLongNonMatch 125ns × (0.99,1.01) 127ns × (0.98,1.02) +1.49% (p=0.000 n=15+15)
AnchoredShortMatch 178ns × (0.99,1.02) 175ns × (0.99,1.01) -1.62% (p=0.000 n=15+13)
AnchoredLongMatch 328ns × (0.99,1.00) 341ns × (0.99,1.01) +3.73% (p=0.000 n=12+15)
OnePassShortA 773ns × (0.99,1.02) 752ns × (0.99,1.01) -2.78% (p=0.000 n=15+13)
NotOnePassShortA 794ns × (0.99,1.03) 780ns × (0.99,1.02) -1.75% (p=0.001 n=15+15)
OnePassShortB 608ns × (0.99,1.01) 591ns × (0.99,1.02) -2.86% (p=0.000 n=15+14)
NotOnePassShortB 576ns × (0.99,1.01) 571ns × (0.99,1.02) -0.74% (p=0.035 n=15+15)
OnePassLongPrefix 131ns × (0.99,1.02) 130ns × (0.99,1.02) -1.32% (p=0.003 n=15+15)
OnePassLongNotPrefix 503ns × (0.99,1.02) 481ns × (0.99,1.01) -4.34% (p=0.000 n=15+13)
MatchEasy0_32 102ns × (0.98,1.01) 101ns × (0.99,1.02) ~ (p=0.907 n=15+14)
MatchEasy0_1K 617ns × (0.99,1.02) 634ns × (0.98,1.02) +2.77% (p=0.000 n=15+15)
MatchEasy0_32K 10.9µs × (0.99,1.01) 11.1µs × (0.99,1.01) +1.59% (p=0.000 n=15+15)
MatchEasy0_1M 406µs × (0.99,1.02) 410µs × (0.99,1.02) +1.01% (p=0.000 n=14+15)
MatchEasy0_32M 13.4ms × (0.99,1.01) 13.7ms × (0.99,1.02) +1.64% (p=0.000 n=12+15)
MatchEasy1_32 83.7ns × (0.98,1.02) 83.0ns × (0.98,1.02) ~ (p=0.190 n=15+15)
MatchEasy1_1K 1.46µs × (0.99,1.02) 1.39µs × (0.99,1.02) -4.83% (p=0.000 n=15+15)
MatchEasy1_32K 49.4µs × (0.99,1.01) 49.4µs × (0.99,1.01) ~ (p=0.205 n=15+15)
MatchEasy1_1M 1.72ms × (0.99,1.02) 1.75ms × (0.99,1.01) +1.34% (p=0.000 n=15+15)
MatchEasy1_32M 55.5ms × (0.99,1.01) 56.1ms × (0.99,1.02) +1.10% (p=0.002 n=15+15)
MatchMedium_32 1.37µs × (0.99,1.04) 1.33µs × (0.99,1.01) -2.87% (p=0.000 n=15+15)
MatchMedium_1K 41.1µs × (0.99,1.02) 40.4µs × (0.99,1.02) -1.59% (p=0.000 n=15+15)
MatchMedium_32K 1.71ms × (0.99,1.01) 1.75ms × (0.99,1.02) +2.36% (p=0.000 n=14+15)
MatchMedium_1M 54.5ms × (0.99,1.01) 56.1ms × (0.99,1.01) +2.94% (p=0.000 n=13+15)
MatchMedium_32M 1.75s × (0.99,1.01) 1.80s × (0.99,1.01) +2.77% (p=0.000 n=15+15)
MatchHard_32 2.12µs × (0.99,1.02) 2.06µs × (0.99,1.01) -2.60% (p=0.000 n=15+14)
MatchHard_1K 64.4µs × (0.98,1.02) 62.2µs × (0.99,1.01) -3.33% (p=0.000 n=15+15)
MatchHard_32K 2.74ms × (0.99,1.01) 2.75ms × (0.99,1.01) ~ (p=0.310 n=15+14)
MatchHard_1M 87.1ms × (0.99,1.02) 88.2ms × (0.99,1.01) +1.36% (p=0.000 n=14+15)
MatchHard_32M 2.79s × (0.99,1.02) 2.83s × (0.99,1.02) +1.26% (p=0.004 n=15+14)
go1 benchmarks
name old time/op new time/op delta
BinaryTree17 3.34s ± 3% 3.28s ± 2% -1.86% (p=0.000 n=67+66)
Fannkuch11 2.50s ± 1% 2.51s ± 1% +0.24% (p=0.016 n=63+66)
FmtFprintfEmpty 50.3ns ± 1% 50.2ns ± 2% -0.30% (p=0.001 n=62+67)
FmtFprintfString 178ns ± 1% 166ns ± 1% -7.10% (p=0.000 n=62+59)
FmtFprintfInt 168ns ± 1% 161ns ± 2% -4.41% (p=0.000 n=66+64)
FmtFprintfIntInt 292ns ± 1% 282ns ± 2% -3.55% (p=0.000 n=62+60)
FmtFprintfPrefixedInt 245ns ± 2% 239ns ± 2% -2.24% (p=0.000 n=66+65)
FmtFprintfFloat 338ns ± 2% 326ns ± 1% -3.42% (p=0.000 n=64+59)
FmtManyArgs 1.14µs ± 1% 1.10µs ± 2% -3.55% (p=0.000 n=62+62)
GobDecode 8.88ms ± 2% 8.74ms ± 1% -1.55% (p=0.000 n=66+62)
GobEncode 6.84ms ± 2% 6.61ms ± 2% -3.32% (p=0.000 n=61+67)
Gzip 356ms ± 2% 352ms ± 2% -1.07% (p=0.000 n=67+66)
Gunzip 90.6ms ± 2% 89.8ms ± 1% -0.83% (p=0.000 n=65+64)
HTTPClientServer 82.6µs ± 2% 82.5µs ± 2% ~ (p=0.832 n=65+63)
JSONEncode 17.5ms ± 2% 16.8ms ± 2% -3.77% (p=0.000 n=63+63)
JSONDecode 63.3ms ± 2% 59.0ms ± 2% -6.85% (p=0.000 n=64+63)
Mandelbrot200 3.85ms ± 1% 3.85ms ± 1% ~ (p=0.127 n=65+62)
GoParse 3.75ms ± 2% 3.66ms ± 2% -2.39% (p=0.000 n=66+64)
RegexpMatchEasy0_32 100ns ± 2% 100ns ± 1% -0.65% (p=0.000 n=62+64)
RegexpMatchEasy0_1K 342ns ± 1% 341ns ± 1% -0.43% (p=0.000 n=65+64)
RegexpMatchEasy1_32 82.8ns ± 2% 82.8ns ± 2% ~ (p=0.977 n=63+64)
RegexpMatchEasy1_1K 511ns ± 2% 506ns ± 2% -1.01% (p=0.000 n=63+64)
RegexpMatchMedium_32 139ns ± 1% 134ns ± 3% -3.27% (p=0.000 n=59+60)
RegexpMatchMedium_1K 41.8µs ± 2% 40.5µs ± 2% -3.05% (p=0.000 n=62+64)
RegexpMatchHard_32 2.13µs ± 1% 2.09µs ± 1% -2.22% (p=0.000 n=60+65)
RegexpMatchHard_1K 64.4µs ± 3% 62.8µs ± 2% -2.58% (p=0.000 n=65+59)
Revcomp 531ms ± 2% 529ms ± 1% -0.28% (p=0.022 n=61+61)
Template 73.2ms ± 1% 73.1ms ± 1% ~ (p=0.794 n=66+63)
TimeParse 369ns ± 1% 352ns ± 1% -4.68% (p=0.000 n=65+66)
TimeFormat 374ns ± 2% 348ns ± 2% -7.01% (p=0.000 n=66+64)
Change-Id: Ib190b5bb48a3e9087711d9e3383621d3103dd342
Reviewed-on: https://go-review.googlesource.com/10367
Reviewed-by: Russ Cox <rsc@golang.org>
2015-05-28 17:31:24 -07:00
|
|
|
morestack = "runtime.morestackc"
|
2017-04-18 10:18:34 -07:00
|
|
|
case !cursym.Func.Text.From.Sym.NeedCtxt():
|
cmd/internal/obj/x86: make function prologue more predictable
Static branch prediction guesses that forward branches aren't taken.
Since stacks are rarely grown, make the forward branch mean grow.
Sample disassembly for
func f() {
_ = [128]byte{}
}
Before:
TEXT main.f(SB) x.go
x.go:3 0x2000 65488b0c25a0080000 GS MOVQ GS:0x8a0, CX
x.go:3 0x2009 483b6110 CMPQ 0x10(CX), SP
x.go:3 0x200d 7707 JA 0x2016
x.go:3 0x200f e88c410400 CALL runtime.morestack_noctxt(SB)
x.go:3 0x2014 ebea JMP main.f(SB)
x.go:3 0x2016 4881ec80000000 SUBQ $0x80, SP
x.go:4 0x201d 488d3c24 LEAQ 0(SP), DI
x.go:4 0x2021 31c0 XORL AX, AX
x.go:4 0x2023 e8cc640400 CALL 0x484f4
x.go:5 0x2028 4881c480000000 ADDQ $0x80, SP
x.go:5 0x202f c3 RET
After:
TEXT main.f(SB) x.go
x.go:3 0x2000 65488b0c25a0080000 GS MOVQ GS:0x8a0, CX
x.go:3 0x2009 483b6110 CMPQ 0x10(CX), SP
x.go:3 0x200d 761a JBE 0x2029
x.go:3 0x200f 4881ec80000000 SUBQ $0x80, SP
x.go:4 0x2016 488d3c24 LEAQ 0(SP), DI
x.go:4 0x201a 31c0 XORL AX, AX
x.go:4 0x201c e813740400 CALL 0x49434
x.go:5 0x2021 4881c480000000 ADDQ $0x80, SP
x.go:5 0x2028 c3 RET
x.go:3 0x2029 e8224f0400 CALL runtime.morestack_noctxt(SB)
x.go:3 0x202e ebd0 JMP main.f(SB)
Updates #10587.
Sample benchmarks on a 2.8 GHz Intel Core i7:
package sort
name old mean new mean delta
SearchWrappers 134ns × (0.99,1.01) 132ns × (0.99,1.01) -1.73% (p=0.000 n=15+14)
SortString1K 215µs × (0.99,1.01) 213µs × (0.99,1.01) -0.61% (p=0.020 n=14+15)
StableString1K 311µs × (0.99,1.02) 309µs × (0.99,1.02) ~ (p=0.077 n=14+15)
SortInt1K 103µs × (0.99,1.02) 100µs × (0.98,1.01) -3.34% (p=0.000 n=15+15)
StableInt1K 102µs × (0.99,1.01) 98µs × (0.97,1.04) -3.53% (p=0.000 n=15+15)
SortInt64K 10.1ms × (0.98,1.02) 9.7ms × (0.99,1.01) -3.86% (p=0.000 n=14+15)
StableInt64K 8.70ms × (0.99,1.01) 8.44ms × (0.99,1.03) -2.93% (p=0.000 n=14+15)
Sort1e2 51.2µs × (1.00,1.01) 48.9µs × (0.99,1.02) -4.48% (p=0.000 n=13+15)
Stable1e2 100µs × (0.99,1.02) 99µs × (0.99,1.01) -1.15% (p=0.000 n=14+13)
Sort1e4 11.1ms × (0.99,1.02) 10.4ms × (0.99,1.01) -6.02% (p=0.000 n=15+14)
Stable1e4 30.6ms × (0.99,1.01) 30.3ms × (0.99,1.02) -1.02% (p=0.001 n=15+14)
Sort1e6 1.75s × (0.99,1.02) 1.66s × (0.98,1.03) -4.95% (p=0.000 n=14+15)
Stable1e6 6.31s × (0.99,1.01) 6.26s × (0.99,1.01) -0.79% (p=0.002 n=15+15)
package regexp
name old mean new mean delta
Literal 131ns × (0.99,1.01) 130ns × (0.99,1.03) -1.07% (p=0.004 n=14+15)
NotLiteral 2.13µs × (0.99,1.01) 2.01µs × (0.99,1.03) -5.71% (p=0.000 n=14+14)
MatchClass 3.15µs × (0.99,1.01) 3.04µs × (0.99,1.02) -3.40% (p=0.000 n=15+15)
MatchClass_InRange 2.92µs × (0.99,1.01) 2.77µs × (0.99,1.02) -5.05% (p=0.000 n=13+15)
ReplaceAll 2.17µs × (0.99,1.02) 2.06µs × (0.99,1.01) -5.19% (p=0.000 n=15+13)
AnchoredLiteralShortNonMatch 116ns × (0.99,1.02) 113ns × (0.99,1.01) -2.75% (p=0.000 n=15+14)
AnchoredLiteralLongNonMatch 125ns × (0.99,1.01) 127ns × (0.98,1.02) +1.49% (p=0.000 n=15+15)
AnchoredShortMatch 178ns × (0.99,1.02) 175ns × (0.99,1.01) -1.62% (p=0.000 n=15+13)
AnchoredLongMatch 328ns × (0.99,1.00) 341ns × (0.99,1.01) +3.73% (p=0.000 n=12+15)
OnePassShortA 773ns × (0.99,1.02) 752ns × (0.99,1.01) -2.78% (p=0.000 n=15+13)
NotOnePassShortA 794ns × (0.99,1.03) 780ns × (0.99,1.02) -1.75% (p=0.001 n=15+15)
OnePassShortB 608ns × (0.99,1.01) 591ns × (0.99,1.02) -2.86% (p=0.000 n=15+14)
NotOnePassShortB 576ns × (0.99,1.01) 571ns × (0.99,1.02) -0.74% (p=0.035 n=15+15)
OnePassLongPrefix 131ns × (0.99,1.02) 130ns × (0.99,1.02) -1.32% (p=0.003 n=15+15)
OnePassLongNotPrefix 503ns × (0.99,1.02) 481ns × (0.99,1.01) -4.34% (p=0.000 n=15+13)
MatchEasy0_32 102ns × (0.98,1.01) 101ns × (0.99,1.02) ~ (p=0.907 n=15+14)
MatchEasy0_1K 617ns × (0.99,1.02) 634ns × (0.98,1.02) +2.77% (p=0.000 n=15+15)
MatchEasy0_32K 10.9µs × (0.99,1.01) 11.1µs × (0.99,1.01) +1.59% (p=0.000 n=15+15)
MatchEasy0_1M 406µs × (0.99,1.02) 410µs × (0.99,1.02) +1.01% (p=0.000 n=14+15)
MatchEasy0_32M 13.4ms × (0.99,1.01) 13.7ms × (0.99,1.02) +1.64% (p=0.000 n=12+15)
MatchEasy1_32 83.7ns × (0.98,1.02) 83.0ns × (0.98,1.02) ~ (p=0.190 n=15+15)
MatchEasy1_1K 1.46µs × (0.99,1.02) 1.39µs × (0.99,1.02) -4.83% (p=0.000 n=15+15)
MatchEasy1_32K 49.4µs × (0.99,1.01) 49.4µs × (0.99,1.01) ~ (p=0.205 n=15+15)
MatchEasy1_1M 1.72ms × (0.99,1.02) 1.75ms × (0.99,1.01) +1.34% (p=0.000 n=15+15)
MatchEasy1_32M 55.5ms × (0.99,1.01) 56.1ms × (0.99,1.02) +1.10% (p=0.002 n=15+15)
MatchMedium_32 1.37µs × (0.99,1.04) 1.33µs × (0.99,1.01) -2.87% (p=0.000 n=15+15)
MatchMedium_1K 41.1µs × (0.99,1.02) 40.4µs × (0.99,1.02) -1.59% (p=0.000 n=15+15)
MatchMedium_32K 1.71ms × (0.99,1.01) 1.75ms × (0.99,1.02) +2.36% (p=0.000 n=14+15)
MatchMedium_1M 54.5ms × (0.99,1.01) 56.1ms × (0.99,1.01) +2.94% (p=0.000 n=13+15)
MatchMedium_32M 1.75s × (0.99,1.01) 1.80s × (0.99,1.01) +2.77% (p=0.000 n=15+15)
MatchHard_32 2.12µs × (0.99,1.02) 2.06µs × (0.99,1.01) -2.60% (p=0.000 n=15+14)
MatchHard_1K 64.4µs × (0.98,1.02) 62.2µs × (0.99,1.01) -3.33% (p=0.000 n=15+15)
MatchHard_32K 2.74ms × (0.99,1.01) 2.75ms × (0.99,1.01) ~ (p=0.310 n=15+14)
MatchHard_1M 87.1ms × (0.99,1.02) 88.2ms × (0.99,1.01) +1.36% (p=0.000 n=14+15)
MatchHard_32M 2.79s × (0.99,1.02) 2.83s × (0.99,1.02) +1.26% (p=0.004 n=15+14)
go1 benchmarks
name old time/op new time/op delta
BinaryTree17 3.34s ± 3% 3.28s ± 2% -1.86% (p=0.000 n=67+66)
Fannkuch11 2.50s ± 1% 2.51s ± 1% +0.24% (p=0.016 n=63+66)
FmtFprintfEmpty 50.3ns ± 1% 50.2ns ± 2% -0.30% (p=0.001 n=62+67)
FmtFprintfString 178ns ± 1% 166ns ± 1% -7.10% (p=0.000 n=62+59)
FmtFprintfInt 168ns ± 1% 161ns ± 2% -4.41% (p=0.000 n=66+64)
FmtFprintfIntInt 292ns ± 1% 282ns ± 2% -3.55% (p=0.000 n=62+60)
FmtFprintfPrefixedInt 245ns ± 2% 239ns ± 2% -2.24% (p=0.000 n=66+65)
FmtFprintfFloat 338ns ± 2% 326ns ± 1% -3.42% (p=0.000 n=64+59)
FmtManyArgs 1.14µs ± 1% 1.10µs ± 2% -3.55% (p=0.000 n=62+62)
GobDecode 8.88ms ± 2% 8.74ms ± 1% -1.55% (p=0.000 n=66+62)
GobEncode 6.84ms ± 2% 6.61ms ± 2% -3.32% (p=0.000 n=61+67)
Gzip 356ms ± 2% 352ms ± 2% -1.07% (p=0.000 n=67+66)
Gunzip 90.6ms ± 2% 89.8ms ± 1% -0.83% (p=0.000 n=65+64)
HTTPClientServer 82.6µs ± 2% 82.5µs ± 2% ~ (p=0.832 n=65+63)
JSONEncode 17.5ms ± 2% 16.8ms ± 2% -3.77% (p=0.000 n=63+63)
JSONDecode 63.3ms ± 2% 59.0ms ± 2% -6.85% (p=0.000 n=64+63)
Mandelbrot200 3.85ms ± 1% 3.85ms ± 1% ~ (p=0.127 n=65+62)
GoParse 3.75ms ± 2% 3.66ms ± 2% -2.39% (p=0.000 n=66+64)
RegexpMatchEasy0_32 100ns ± 2% 100ns ± 1% -0.65% (p=0.000 n=62+64)
RegexpMatchEasy0_1K 342ns ± 1% 341ns ± 1% -0.43% (p=0.000 n=65+64)
RegexpMatchEasy1_32 82.8ns ± 2% 82.8ns ± 2% ~ (p=0.977 n=63+64)
RegexpMatchEasy1_1K 511ns ± 2% 506ns ± 2% -1.01% (p=0.000 n=63+64)
RegexpMatchMedium_32 139ns ± 1% 134ns ± 3% -3.27% (p=0.000 n=59+60)
RegexpMatchMedium_1K 41.8µs ± 2% 40.5µs ± 2% -3.05% (p=0.000 n=62+64)
RegexpMatchHard_32 2.13µs ± 1% 2.09µs ± 1% -2.22% (p=0.000 n=60+65)
RegexpMatchHard_1K 64.4µs ± 3% 62.8µs ± 2% -2.58% (p=0.000 n=65+59)
Revcomp 531ms ± 2% 529ms ± 1% -0.28% (p=0.022 n=61+61)
Template 73.2ms ± 1% 73.1ms ± 1% ~ (p=0.794 n=66+63)
TimeParse 369ns ± 1% 352ns ± 1% -4.68% (p=0.000 n=65+66)
TimeFormat 374ns ± 2% 348ns ± 2% -7.01% (p=0.000 n=66+64)
Change-Id: Ib190b5bb48a3e9087711d9e3383621d3103dd342
Reviewed-on: https://go-review.googlesource.com/10367
Reviewed-by: Russ Cox <rsc@golang.org>
2015-05-28 17:31:24 -07:00
|
|
|
morestack = "runtime.morestack_noctxt"
|
|
|
|
}
|
2017-04-20 07:13:02 -07:00
|
|
|
call.To.Sym = ctxt.Lookup(morestack)
|
2016-06-02 11:07:55 +12:00
|
|
|
// When compiling 386 code for dynamic linking, the call needs to be adjusted
|
|
|
|
// to follow PIC rules. This in turn can insert more instructions, so we need
|
|
|
|
// to keep track of the start of the call (where the jump will be to) and the
|
|
|
|
// end (which following instructions are appended to).
|
|
|
|
callend := call
|
2017-04-04 14:31:55 -07:00
|
|
|
progedit(ctxt, callend, newprog)
|
2016-06-02 11:07:55 +12:00
|
|
|
for ; callend.Link != nil; callend = callend.Link {
|
2017-04-04 14:31:55 -07:00
|
|
|
progedit(ctxt, callend.Link, newprog)
|
2016-06-02 11:07:55 +12:00
|
|
|
}
|
cmd/internal/obj/x86: make function prologue more predictable
Static branch prediction guesses that forward branches aren't taken.
Since stacks are rarely grown, make the forward branch mean grow.
Sample disassembly for
func f() {
_ = [128]byte{}
}
Before:
TEXT main.f(SB) x.go
x.go:3 0x2000 65488b0c25a0080000 GS MOVQ GS:0x8a0, CX
x.go:3 0x2009 483b6110 CMPQ 0x10(CX), SP
x.go:3 0x200d 7707 JA 0x2016
x.go:3 0x200f e88c410400 CALL runtime.morestack_noctxt(SB)
x.go:3 0x2014 ebea JMP main.f(SB)
x.go:3 0x2016 4881ec80000000 SUBQ $0x80, SP
x.go:4 0x201d 488d3c24 LEAQ 0(SP), DI
x.go:4 0x2021 31c0 XORL AX, AX
x.go:4 0x2023 e8cc640400 CALL 0x484f4
x.go:5 0x2028 4881c480000000 ADDQ $0x80, SP
x.go:5 0x202f c3 RET
After:
TEXT main.f(SB) x.go
x.go:3 0x2000 65488b0c25a0080000 GS MOVQ GS:0x8a0, CX
x.go:3 0x2009 483b6110 CMPQ 0x10(CX), SP
x.go:3 0x200d 761a JBE 0x2029
x.go:3 0x200f 4881ec80000000 SUBQ $0x80, SP
x.go:4 0x2016 488d3c24 LEAQ 0(SP), DI
x.go:4 0x201a 31c0 XORL AX, AX
x.go:4 0x201c e813740400 CALL 0x49434
x.go:5 0x2021 4881c480000000 ADDQ $0x80, SP
x.go:5 0x2028 c3 RET
x.go:3 0x2029 e8224f0400 CALL runtime.morestack_noctxt(SB)
x.go:3 0x202e ebd0 JMP main.f(SB)
Updates #10587.
Sample benchmarks on a 2.8 GHz Intel Core i7:
package sort
name old mean new mean delta
SearchWrappers 134ns × (0.99,1.01) 132ns × (0.99,1.01) -1.73% (p=0.000 n=15+14)
SortString1K 215µs × (0.99,1.01) 213µs × (0.99,1.01) -0.61% (p=0.020 n=14+15)
StableString1K 311µs × (0.99,1.02) 309µs × (0.99,1.02) ~ (p=0.077 n=14+15)
SortInt1K 103µs × (0.99,1.02) 100µs × (0.98,1.01) -3.34% (p=0.000 n=15+15)
StableInt1K 102µs × (0.99,1.01) 98µs × (0.97,1.04) -3.53% (p=0.000 n=15+15)
SortInt64K 10.1ms × (0.98,1.02) 9.7ms × (0.99,1.01) -3.86% (p=0.000 n=14+15)
StableInt64K 8.70ms × (0.99,1.01) 8.44ms × (0.99,1.03) -2.93% (p=0.000 n=14+15)
Sort1e2 51.2µs × (1.00,1.01) 48.9µs × (0.99,1.02) -4.48% (p=0.000 n=13+15)
Stable1e2 100µs × (0.99,1.02) 99µs × (0.99,1.01) -1.15% (p=0.000 n=14+13)
Sort1e4 11.1ms × (0.99,1.02) 10.4ms × (0.99,1.01) -6.02% (p=0.000 n=15+14)
Stable1e4 30.6ms × (0.99,1.01) 30.3ms × (0.99,1.02) -1.02% (p=0.001 n=15+14)
Sort1e6 1.75s × (0.99,1.02) 1.66s × (0.98,1.03) -4.95% (p=0.000 n=14+15)
Stable1e6 6.31s × (0.99,1.01) 6.26s × (0.99,1.01) -0.79% (p=0.002 n=15+15)
package regexp
name old mean new mean delta
Literal 131ns × (0.99,1.01) 130ns × (0.99,1.03) -1.07% (p=0.004 n=14+15)
NotLiteral 2.13µs × (0.99,1.01) 2.01µs × (0.99,1.03) -5.71% (p=0.000 n=14+14)
MatchClass 3.15µs × (0.99,1.01) 3.04µs × (0.99,1.02) -3.40% (p=0.000 n=15+15)
MatchClass_InRange 2.92µs × (0.99,1.01) 2.77µs × (0.99,1.02) -5.05% (p=0.000 n=13+15)
ReplaceAll 2.17µs × (0.99,1.02) 2.06µs × (0.99,1.01) -5.19% (p=0.000 n=15+13)
AnchoredLiteralShortNonMatch 116ns × (0.99,1.02) 113ns × (0.99,1.01) -2.75% (p=0.000 n=15+14)
AnchoredLiteralLongNonMatch 125ns × (0.99,1.01) 127ns × (0.98,1.02) +1.49% (p=0.000 n=15+15)
AnchoredShortMatch 178ns × (0.99,1.02) 175ns × (0.99,1.01) -1.62% (p=0.000 n=15+13)
AnchoredLongMatch 328ns × (0.99,1.00) 341ns × (0.99,1.01) +3.73% (p=0.000 n=12+15)
OnePassShortA 773ns × (0.99,1.02) 752ns × (0.99,1.01) -2.78% (p=0.000 n=15+13)
NotOnePassShortA 794ns × (0.99,1.03) 780ns × (0.99,1.02) -1.75% (p=0.001 n=15+15)
OnePassShortB 608ns × (0.99,1.01) 591ns × (0.99,1.02) -2.86% (p=0.000 n=15+14)
NotOnePassShortB 576ns × (0.99,1.01) 571ns × (0.99,1.02) -0.74% (p=0.035 n=15+15)
OnePassLongPrefix 131ns × (0.99,1.02) 130ns × (0.99,1.02) -1.32% (p=0.003 n=15+15)
OnePassLongNotPrefix 503ns × (0.99,1.02) 481ns × (0.99,1.01) -4.34% (p=0.000 n=15+13)
MatchEasy0_32 102ns × (0.98,1.01) 101ns × (0.99,1.02) ~ (p=0.907 n=15+14)
MatchEasy0_1K 617ns × (0.99,1.02) 634ns × (0.98,1.02) +2.77% (p=0.000 n=15+15)
MatchEasy0_32K 10.9µs × (0.99,1.01) 11.1µs × (0.99,1.01) +1.59% (p=0.000 n=15+15)
MatchEasy0_1M 406µs × (0.99,1.02) 410µs × (0.99,1.02) +1.01% (p=0.000 n=14+15)
MatchEasy0_32M 13.4ms × (0.99,1.01) 13.7ms × (0.99,1.02) +1.64% (p=0.000 n=12+15)
MatchEasy1_32 83.7ns × (0.98,1.02) 83.0ns × (0.98,1.02) ~ (p=0.190 n=15+15)
MatchEasy1_1K 1.46µs × (0.99,1.02) 1.39µs × (0.99,1.02) -4.83% (p=0.000 n=15+15)
MatchEasy1_32K 49.4µs × (0.99,1.01) 49.4µs × (0.99,1.01) ~ (p=0.205 n=15+15)
MatchEasy1_1M 1.72ms × (0.99,1.02) 1.75ms × (0.99,1.01) +1.34% (p=0.000 n=15+15)
MatchEasy1_32M 55.5ms × (0.99,1.01) 56.1ms × (0.99,1.02) +1.10% (p=0.002 n=15+15)
MatchMedium_32 1.37µs × (0.99,1.04) 1.33µs × (0.99,1.01) -2.87% (p=0.000 n=15+15)
MatchMedium_1K 41.1µs × (0.99,1.02) 40.4µs × (0.99,1.02) -1.59% (p=0.000 n=15+15)
MatchMedium_32K 1.71ms × (0.99,1.01) 1.75ms × (0.99,1.02) +2.36% (p=0.000 n=14+15)
MatchMedium_1M 54.5ms × (0.99,1.01) 56.1ms × (0.99,1.01) +2.94% (p=0.000 n=13+15)
MatchMedium_32M 1.75s × (0.99,1.01) 1.80s × (0.99,1.01) +2.77% (p=0.000 n=15+15)
MatchHard_32 2.12µs × (0.99,1.02) 2.06µs × (0.99,1.01) -2.60% (p=0.000 n=15+14)
MatchHard_1K 64.4µs × (0.98,1.02) 62.2µs × (0.99,1.01) -3.33% (p=0.000 n=15+15)
MatchHard_32K 2.74ms × (0.99,1.01) 2.75ms × (0.99,1.01) ~ (p=0.310 n=15+14)
MatchHard_1M 87.1ms × (0.99,1.02) 88.2ms × (0.99,1.01) +1.36% (p=0.000 n=14+15)
MatchHard_32M 2.79s × (0.99,1.02) 2.83s × (0.99,1.02) +1.26% (p=0.004 n=15+14)
go1 benchmarks
name old time/op new time/op delta
BinaryTree17 3.34s ± 3% 3.28s ± 2% -1.86% (p=0.000 n=67+66)
Fannkuch11 2.50s ± 1% 2.51s ± 1% +0.24% (p=0.016 n=63+66)
FmtFprintfEmpty 50.3ns ± 1% 50.2ns ± 2% -0.30% (p=0.001 n=62+67)
FmtFprintfString 178ns ± 1% 166ns ± 1% -7.10% (p=0.000 n=62+59)
FmtFprintfInt 168ns ± 1% 161ns ± 2% -4.41% (p=0.000 n=66+64)
FmtFprintfIntInt 292ns ± 1% 282ns ± 2% -3.55% (p=0.000 n=62+60)
FmtFprintfPrefixedInt 245ns ± 2% 239ns ± 2% -2.24% (p=0.000 n=66+65)
FmtFprintfFloat 338ns ± 2% 326ns ± 1% -3.42% (p=0.000 n=64+59)
FmtManyArgs 1.14µs ± 1% 1.10µs ± 2% -3.55% (p=0.000 n=62+62)
GobDecode 8.88ms ± 2% 8.74ms ± 1% -1.55% (p=0.000 n=66+62)
GobEncode 6.84ms ± 2% 6.61ms ± 2% -3.32% (p=0.000 n=61+67)
Gzip 356ms ± 2% 352ms ± 2% -1.07% (p=0.000 n=67+66)
Gunzip 90.6ms ± 2% 89.8ms ± 1% -0.83% (p=0.000 n=65+64)
HTTPClientServer 82.6µs ± 2% 82.5µs ± 2% ~ (p=0.832 n=65+63)
JSONEncode 17.5ms ± 2% 16.8ms ± 2% -3.77% (p=0.000 n=63+63)
JSONDecode 63.3ms ± 2% 59.0ms ± 2% -6.85% (p=0.000 n=64+63)
Mandelbrot200 3.85ms ± 1% 3.85ms ± 1% ~ (p=0.127 n=65+62)
GoParse 3.75ms ± 2% 3.66ms ± 2% -2.39% (p=0.000 n=66+64)
RegexpMatchEasy0_32 100ns ± 2% 100ns ± 1% -0.65% (p=0.000 n=62+64)
RegexpMatchEasy0_1K 342ns ± 1% 341ns ± 1% -0.43% (p=0.000 n=65+64)
RegexpMatchEasy1_32 82.8ns ± 2% 82.8ns ± 2% ~ (p=0.977 n=63+64)
RegexpMatchEasy1_1K 511ns ± 2% 506ns ± 2% -1.01% (p=0.000 n=63+64)
RegexpMatchMedium_32 139ns ± 1% 134ns ± 3% -3.27% (p=0.000 n=59+60)
RegexpMatchMedium_1K 41.8µs ± 2% 40.5µs ± 2% -3.05% (p=0.000 n=62+64)
RegexpMatchHard_32 2.13µs ± 1% 2.09µs ± 1% -2.22% (p=0.000 n=60+65)
RegexpMatchHard_1K 64.4µs ± 3% 62.8µs ± 2% -2.58% (p=0.000 n=65+59)
Revcomp 531ms ± 2% 529ms ± 1% -0.28% (p=0.022 n=61+61)
Template 73.2ms ± 1% 73.1ms ± 1% ~ (p=0.794 n=66+63)
TimeParse 369ns ± 1% 352ns ± 1% -4.68% (p=0.000 n=65+66)
TimeFormat 374ns ± 2% 348ns ± 2% -7.01% (p=0.000 n=66+64)
Change-Id: Ib190b5bb48a3e9087711d9e3383621d3103dd342
Reviewed-on: https://go-review.googlesource.com/10367
Reviewed-by: Russ Cox <rsc@golang.org>
2015-05-28 17:31:24 -07:00
|
|
|
|
cmd/internal/obj: mark split-stack prologue nonpreemptible
When there are both a synchronous preemption request (by
clobbering the stack guard) and an asynchronous one (by signal),
the running goroutine may observe the synchronous request first
in stack bounds check, and go to the path of calling morestack.
If the preemption signal arrives at this point before the call to
morestack, the goroutine will be asynchronously preempted,
entering the scheduler. When it is resumed, the scheduler clears
the preemption request, unclobbers the stack guard. But the
resumed goroutine will still call morestack, as it is already on
its way. morestack will, as there is no preemption request,
double the stack unnecessarily. If this happens multiple times,
the stack may grow too big, although only a small amount is
actually used.
To fix this, we mark the stack bounds check and the call to
morestack async-nonpreemptible, starting after the memory
instruction (mostly a load, on x86 CMP with memory).
Not done for Wasm as it does not support async preemption.
Fixes #35470.
Change-Id: Ibd7f3d935a3649b80f47539116ec9b9556680cf2
Reviewed-on: https://go-review.googlesource.com/c/go/+/207350
Reviewed-by: David Chase <drchase@google.com>
2019-11-14 20:23:17 -05:00
|
|
|
pcdata = ctxt.EndUnsafePoint(callend, newprog, -1)
|
|
|
|
|
|
|
|
jmp := obj.Appendp(pcdata, newprog)
|
cmd/internal/obj/x86: make function prologue more predictable
Static branch prediction guesses that forward branches aren't taken.
Since stacks are rarely grown, make the forward branch mean grow.
Sample disassembly for
func f() {
_ = [128]byte{}
}
Before:
TEXT main.f(SB) x.go
x.go:3 0x2000 65488b0c25a0080000 GS MOVQ GS:0x8a0, CX
x.go:3 0x2009 483b6110 CMPQ 0x10(CX), SP
x.go:3 0x200d 7707 JA 0x2016
x.go:3 0x200f e88c410400 CALL runtime.morestack_noctxt(SB)
x.go:3 0x2014 ebea JMP main.f(SB)
x.go:3 0x2016 4881ec80000000 SUBQ $0x80, SP
x.go:4 0x201d 488d3c24 LEAQ 0(SP), DI
x.go:4 0x2021 31c0 XORL AX, AX
x.go:4 0x2023 e8cc640400 CALL 0x484f4
x.go:5 0x2028 4881c480000000 ADDQ $0x80, SP
x.go:5 0x202f c3 RET
After:
TEXT main.f(SB) x.go
x.go:3 0x2000 65488b0c25a0080000 GS MOVQ GS:0x8a0, CX
x.go:3 0x2009 483b6110 CMPQ 0x10(CX), SP
x.go:3 0x200d 761a JBE 0x2029
x.go:3 0x200f 4881ec80000000 SUBQ $0x80, SP
x.go:4 0x2016 488d3c24 LEAQ 0(SP), DI
x.go:4 0x201a 31c0 XORL AX, AX
x.go:4 0x201c e813740400 CALL 0x49434
x.go:5 0x2021 4881c480000000 ADDQ $0x80, SP
x.go:5 0x2028 c3 RET
x.go:3 0x2029 e8224f0400 CALL runtime.morestack_noctxt(SB)
x.go:3 0x202e ebd0 JMP main.f(SB)
Updates #10587.
Sample benchmarks on a 2.8 GHz Intel Core i7:
package sort
name old mean new mean delta
SearchWrappers 134ns × (0.99,1.01) 132ns × (0.99,1.01) -1.73% (p=0.000 n=15+14)
SortString1K 215µs × (0.99,1.01) 213µs × (0.99,1.01) -0.61% (p=0.020 n=14+15)
StableString1K 311µs × (0.99,1.02) 309µs × (0.99,1.02) ~ (p=0.077 n=14+15)
SortInt1K 103µs × (0.99,1.02) 100µs × (0.98,1.01) -3.34% (p=0.000 n=15+15)
StableInt1K 102µs × (0.99,1.01) 98µs × (0.97,1.04) -3.53% (p=0.000 n=15+15)
SortInt64K 10.1ms × (0.98,1.02) 9.7ms × (0.99,1.01) -3.86% (p=0.000 n=14+15)
StableInt64K 8.70ms × (0.99,1.01) 8.44ms × (0.99,1.03) -2.93% (p=0.000 n=14+15)
Sort1e2 51.2µs × (1.00,1.01) 48.9µs × (0.99,1.02) -4.48% (p=0.000 n=13+15)
Stable1e2 100µs × (0.99,1.02) 99µs × (0.99,1.01) -1.15% (p=0.000 n=14+13)
Sort1e4 11.1ms × (0.99,1.02) 10.4ms × (0.99,1.01) -6.02% (p=0.000 n=15+14)
Stable1e4 30.6ms × (0.99,1.01) 30.3ms × (0.99,1.02) -1.02% (p=0.001 n=15+14)
Sort1e6 1.75s × (0.99,1.02) 1.66s × (0.98,1.03) -4.95% (p=0.000 n=14+15)
Stable1e6 6.31s × (0.99,1.01) 6.26s × (0.99,1.01) -0.79% (p=0.002 n=15+15)
package regexp
name old mean new mean delta
Literal 131ns × (0.99,1.01) 130ns × (0.99,1.03) -1.07% (p=0.004 n=14+15)
NotLiteral 2.13µs × (0.99,1.01) 2.01µs × (0.99,1.03) -5.71% (p=0.000 n=14+14)
MatchClass 3.15µs × (0.99,1.01) 3.04µs × (0.99,1.02) -3.40% (p=0.000 n=15+15)
MatchClass_InRange 2.92µs × (0.99,1.01) 2.77µs × (0.99,1.02) -5.05% (p=0.000 n=13+15)
ReplaceAll 2.17µs × (0.99,1.02) 2.06µs × (0.99,1.01) -5.19% (p=0.000 n=15+13)
AnchoredLiteralShortNonMatch 116ns × (0.99,1.02) 113ns × (0.99,1.01) -2.75% (p=0.000 n=15+14)
AnchoredLiteralLongNonMatch 125ns × (0.99,1.01) 127ns × (0.98,1.02) +1.49% (p=0.000 n=15+15)
AnchoredShortMatch 178ns × (0.99,1.02) 175ns × (0.99,1.01) -1.62% (p=0.000 n=15+13)
AnchoredLongMatch 328ns × (0.99,1.00) 341ns × (0.99,1.01) +3.73% (p=0.000 n=12+15)
OnePassShortA 773ns × (0.99,1.02) 752ns × (0.99,1.01) -2.78% (p=0.000 n=15+13)
NotOnePassShortA 794ns × (0.99,1.03) 780ns × (0.99,1.02) -1.75% (p=0.001 n=15+15)
OnePassShortB 608ns × (0.99,1.01) 591ns × (0.99,1.02) -2.86% (p=0.000 n=15+14)
NotOnePassShortB 576ns × (0.99,1.01) 571ns × (0.99,1.02) -0.74% (p=0.035 n=15+15)
OnePassLongPrefix 131ns × (0.99,1.02) 130ns × (0.99,1.02) -1.32% (p=0.003 n=15+15)
OnePassLongNotPrefix 503ns × (0.99,1.02) 481ns × (0.99,1.01) -4.34% (p=0.000 n=15+13)
MatchEasy0_32 102ns × (0.98,1.01) 101ns × (0.99,1.02) ~ (p=0.907 n=15+14)
MatchEasy0_1K 617ns × (0.99,1.02) 634ns × (0.98,1.02) +2.77% (p=0.000 n=15+15)
MatchEasy0_32K 10.9µs × (0.99,1.01) 11.1µs × (0.99,1.01) +1.59% (p=0.000 n=15+15)
MatchEasy0_1M 406µs × (0.99,1.02) 410µs × (0.99,1.02) +1.01% (p=0.000 n=14+15)
MatchEasy0_32M 13.4ms × (0.99,1.01) 13.7ms × (0.99,1.02) +1.64% (p=0.000 n=12+15)
MatchEasy1_32 83.7ns × (0.98,1.02) 83.0ns × (0.98,1.02) ~ (p=0.190 n=15+15)
MatchEasy1_1K 1.46µs × (0.99,1.02) 1.39µs × (0.99,1.02) -4.83% (p=0.000 n=15+15)
MatchEasy1_32K 49.4µs × (0.99,1.01) 49.4µs × (0.99,1.01) ~ (p=0.205 n=15+15)
MatchEasy1_1M 1.72ms × (0.99,1.02) 1.75ms × (0.99,1.01) +1.34% (p=0.000 n=15+15)
MatchEasy1_32M 55.5ms × (0.99,1.01) 56.1ms × (0.99,1.02) +1.10% (p=0.002 n=15+15)
MatchMedium_32 1.37µs × (0.99,1.04) 1.33µs × (0.99,1.01) -2.87% (p=0.000 n=15+15)
MatchMedium_1K 41.1µs × (0.99,1.02) 40.4µs × (0.99,1.02) -1.59% (p=0.000 n=15+15)
MatchMedium_32K 1.71ms × (0.99,1.01) 1.75ms × (0.99,1.02) +2.36% (p=0.000 n=14+15)
MatchMedium_1M 54.5ms × (0.99,1.01) 56.1ms × (0.99,1.01) +2.94% (p=0.000 n=13+15)
MatchMedium_32M 1.75s × (0.99,1.01) 1.80s × (0.99,1.01) +2.77% (p=0.000 n=15+15)
MatchHard_32 2.12µs × (0.99,1.02) 2.06µs × (0.99,1.01) -2.60% (p=0.000 n=15+14)
MatchHard_1K 64.4µs × (0.98,1.02) 62.2µs × (0.99,1.01) -3.33% (p=0.000 n=15+15)
MatchHard_32K 2.74ms × (0.99,1.01) 2.75ms × (0.99,1.01) ~ (p=0.310 n=15+14)
MatchHard_1M 87.1ms × (0.99,1.02) 88.2ms × (0.99,1.01) +1.36% (p=0.000 n=14+15)
MatchHard_32M 2.79s × (0.99,1.02) 2.83s × (0.99,1.02) +1.26% (p=0.004 n=15+14)
go1 benchmarks
name old time/op new time/op delta
BinaryTree17 3.34s ± 3% 3.28s ± 2% -1.86% (p=0.000 n=67+66)
Fannkuch11 2.50s ± 1% 2.51s ± 1% +0.24% (p=0.016 n=63+66)
FmtFprintfEmpty 50.3ns ± 1% 50.2ns ± 2% -0.30% (p=0.001 n=62+67)
FmtFprintfString 178ns ± 1% 166ns ± 1% -7.10% (p=0.000 n=62+59)
FmtFprintfInt 168ns ± 1% 161ns ± 2% -4.41% (p=0.000 n=66+64)
FmtFprintfIntInt 292ns ± 1% 282ns ± 2% -3.55% (p=0.000 n=62+60)
FmtFprintfPrefixedInt 245ns ± 2% 239ns ± 2% -2.24% (p=0.000 n=66+65)
FmtFprintfFloat 338ns ± 2% 326ns ± 1% -3.42% (p=0.000 n=64+59)
FmtManyArgs 1.14µs ± 1% 1.10µs ± 2% -3.55% (p=0.000 n=62+62)
GobDecode 8.88ms ± 2% 8.74ms ± 1% -1.55% (p=0.000 n=66+62)
GobEncode 6.84ms ± 2% 6.61ms ± 2% -3.32% (p=0.000 n=61+67)
Gzip 356ms ± 2% 352ms ± 2% -1.07% (p=0.000 n=67+66)
Gunzip 90.6ms ± 2% 89.8ms ± 1% -0.83% (p=0.000 n=65+64)
HTTPClientServer 82.6µs ± 2% 82.5µs ± 2% ~ (p=0.832 n=65+63)
JSONEncode 17.5ms ± 2% 16.8ms ± 2% -3.77% (p=0.000 n=63+63)
JSONDecode 63.3ms ± 2% 59.0ms ± 2% -6.85% (p=0.000 n=64+63)
Mandelbrot200 3.85ms ± 1% 3.85ms ± 1% ~ (p=0.127 n=65+62)
GoParse 3.75ms ± 2% 3.66ms ± 2% -2.39% (p=0.000 n=66+64)
RegexpMatchEasy0_32 100ns ± 2% 100ns ± 1% -0.65% (p=0.000 n=62+64)
RegexpMatchEasy0_1K 342ns ± 1% 341ns ± 1% -0.43% (p=0.000 n=65+64)
RegexpMatchEasy1_32 82.8ns ± 2% 82.8ns ± 2% ~ (p=0.977 n=63+64)
RegexpMatchEasy1_1K 511ns ± 2% 506ns ± 2% -1.01% (p=0.000 n=63+64)
RegexpMatchMedium_32 139ns ± 1% 134ns ± 3% -3.27% (p=0.000 n=59+60)
RegexpMatchMedium_1K 41.8µs ± 2% 40.5µs ± 2% -3.05% (p=0.000 n=62+64)
RegexpMatchHard_32 2.13µs ± 1% 2.09µs ± 1% -2.22% (p=0.000 n=60+65)
RegexpMatchHard_1K 64.4µs ± 3% 62.8µs ± 2% -2.58% (p=0.000 n=65+59)
Revcomp 531ms ± 2% 529ms ± 1% -0.28% (p=0.022 n=61+61)
Template 73.2ms ± 1% 73.1ms ± 1% ~ (p=0.794 n=66+63)
TimeParse 369ns ± 1% 352ns ± 1% -4.68% (p=0.000 n=65+66)
TimeFormat 374ns ± 2% 348ns ± 2% -7.01% (p=0.000 n=66+64)
Change-Id: Ib190b5bb48a3e9087711d9e3383621d3103dd342
Reviewed-on: https://go-review.googlesource.com/10367
Reviewed-by: Russ Cox <rsc@golang.org>
2015-05-28 17:31:24 -07:00
|
|
|
jmp.As = obj.AJMP
|
|
|
|
jmp.To.Type = obj.TYPE_BRANCH
|
2020-08-28 17:10:32 +00:00
|
|
|
jmp.To.SetTarget(cursym.Func.Text.Link)
|
2015-12-30 15:19:54 -08:00
|
|
|
jmp.Spadj = +framesize
|
cmd/internal/obj/x86: make function prologue more predictable
Static branch prediction guesses that forward branches aren't taken.
Since stacks are rarely grown, make the forward branch mean grow.
Sample disassembly for
func f() {
_ = [128]byte{}
}
Before:
TEXT main.f(SB) x.go
x.go:3 0x2000 65488b0c25a0080000 GS MOVQ GS:0x8a0, CX
x.go:3 0x2009 483b6110 CMPQ 0x10(CX), SP
x.go:3 0x200d 7707 JA 0x2016
x.go:3 0x200f e88c410400 CALL runtime.morestack_noctxt(SB)
x.go:3 0x2014 ebea JMP main.f(SB)
x.go:3 0x2016 4881ec80000000 SUBQ $0x80, SP
x.go:4 0x201d 488d3c24 LEAQ 0(SP), DI
x.go:4 0x2021 31c0 XORL AX, AX
x.go:4 0x2023 e8cc640400 CALL 0x484f4
x.go:5 0x2028 4881c480000000 ADDQ $0x80, SP
x.go:5 0x202f c3 RET
After:
TEXT main.f(SB) x.go
x.go:3 0x2000 65488b0c25a0080000 GS MOVQ GS:0x8a0, CX
x.go:3 0x2009 483b6110 CMPQ 0x10(CX), SP
x.go:3 0x200d 761a JBE 0x2029
x.go:3 0x200f 4881ec80000000 SUBQ $0x80, SP
x.go:4 0x2016 488d3c24 LEAQ 0(SP), DI
x.go:4 0x201a 31c0 XORL AX, AX
x.go:4 0x201c e813740400 CALL 0x49434
x.go:5 0x2021 4881c480000000 ADDQ $0x80, SP
x.go:5 0x2028 c3 RET
x.go:3 0x2029 e8224f0400 CALL runtime.morestack_noctxt(SB)
x.go:3 0x202e ebd0 JMP main.f(SB)
Updates #10587.
Sample benchmarks on a 2.8 GHz Intel Core i7:
package sort
name old mean new mean delta
SearchWrappers 134ns × (0.99,1.01) 132ns × (0.99,1.01) -1.73% (p=0.000 n=15+14)
SortString1K 215µs × (0.99,1.01) 213µs × (0.99,1.01) -0.61% (p=0.020 n=14+15)
StableString1K 311µs × (0.99,1.02) 309µs × (0.99,1.02) ~ (p=0.077 n=14+15)
SortInt1K 103µs × (0.99,1.02) 100µs × (0.98,1.01) -3.34% (p=0.000 n=15+15)
StableInt1K 102µs × (0.99,1.01) 98µs × (0.97,1.04) -3.53% (p=0.000 n=15+15)
SortInt64K 10.1ms × (0.98,1.02) 9.7ms × (0.99,1.01) -3.86% (p=0.000 n=14+15)
StableInt64K 8.70ms × (0.99,1.01) 8.44ms × (0.99,1.03) -2.93% (p=0.000 n=14+15)
Sort1e2 51.2µs × (1.00,1.01) 48.9µs × (0.99,1.02) -4.48% (p=0.000 n=13+15)
Stable1e2 100µs × (0.99,1.02) 99µs × (0.99,1.01) -1.15% (p=0.000 n=14+13)
Sort1e4 11.1ms × (0.99,1.02) 10.4ms × (0.99,1.01) -6.02% (p=0.000 n=15+14)
Stable1e4 30.6ms × (0.99,1.01) 30.3ms × (0.99,1.02) -1.02% (p=0.001 n=15+14)
Sort1e6 1.75s × (0.99,1.02) 1.66s × (0.98,1.03) -4.95% (p=0.000 n=14+15)
Stable1e6 6.31s × (0.99,1.01) 6.26s × (0.99,1.01) -0.79% (p=0.002 n=15+15)
package regexp
name old mean new mean delta
Literal 131ns × (0.99,1.01) 130ns × (0.99,1.03) -1.07% (p=0.004 n=14+15)
NotLiteral 2.13µs × (0.99,1.01) 2.01µs × (0.99,1.03) -5.71% (p=0.000 n=14+14)
MatchClass 3.15µs × (0.99,1.01) 3.04µs × (0.99,1.02) -3.40% (p=0.000 n=15+15)
MatchClass_InRange 2.92µs × (0.99,1.01) 2.77µs × (0.99,1.02) -5.05% (p=0.000 n=13+15)
ReplaceAll 2.17µs × (0.99,1.02) 2.06µs × (0.99,1.01) -5.19% (p=0.000 n=15+13)
AnchoredLiteralShortNonMatch 116ns × (0.99,1.02) 113ns × (0.99,1.01) -2.75% (p=0.000 n=15+14)
AnchoredLiteralLongNonMatch 125ns × (0.99,1.01) 127ns × (0.98,1.02) +1.49% (p=0.000 n=15+15)
AnchoredShortMatch 178ns × (0.99,1.02) 175ns × (0.99,1.01) -1.62% (p=0.000 n=15+13)
AnchoredLongMatch 328ns × (0.99,1.00) 341ns × (0.99,1.01) +3.73% (p=0.000 n=12+15)
OnePassShortA 773ns × (0.99,1.02) 752ns × (0.99,1.01) -2.78% (p=0.000 n=15+13)
NotOnePassShortA 794ns × (0.99,1.03) 780ns × (0.99,1.02) -1.75% (p=0.001 n=15+15)
OnePassShortB 608ns × (0.99,1.01) 591ns × (0.99,1.02) -2.86% (p=0.000 n=15+14)
NotOnePassShortB 576ns × (0.99,1.01) 571ns × (0.99,1.02) -0.74% (p=0.035 n=15+15)
OnePassLongPrefix 131ns × (0.99,1.02) 130ns × (0.99,1.02) -1.32% (p=0.003 n=15+15)
OnePassLongNotPrefix 503ns × (0.99,1.02) 481ns × (0.99,1.01) -4.34% (p=0.000 n=15+13)
MatchEasy0_32 102ns × (0.98,1.01) 101ns × (0.99,1.02) ~ (p=0.907 n=15+14)
MatchEasy0_1K 617ns × (0.99,1.02) 634ns × (0.98,1.02) +2.77% (p=0.000 n=15+15)
MatchEasy0_32K 10.9µs × (0.99,1.01) 11.1µs × (0.99,1.01) +1.59% (p=0.000 n=15+15)
MatchEasy0_1M 406µs × (0.99,1.02) 410µs × (0.99,1.02) +1.01% (p=0.000 n=14+15)
MatchEasy0_32M 13.4ms × (0.99,1.01) 13.7ms × (0.99,1.02) +1.64% (p=0.000 n=12+15)
MatchEasy1_32 83.7ns × (0.98,1.02) 83.0ns × (0.98,1.02) ~ (p=0.190 n=15+15)
MatchEasy1_1K 1.46µs × (0.99,1.02) 1.39µs × (0.99,1.02) -4.83% (p=0.000 n=15+15)
MatchEasy1_32K 49.4µs × (0.99,1.01) 49.4µs × (0.99,1.01) ~ (p=0.205 n=15+15)
MatchEasy1_1M 1.72ms × (0.99,1.02) 1.75ms × (0.99,1.01) +1.34% (p=0.000 n=15+15)
MatchEasy1_32M 55.5ms × (0.99,1.01) 56.1ms × (0.99,1.02) +1.10% (p=0.002 n=15+15)
MatchMedium_32 1.37µs × (0.99,1.04) 1.33µs × (0.99,1.01) -2.87% (p=0.000 n=15+15)
MatchMedium_1K 41.1µs × (0.99,1.02) 40.4µs × (0.99,1.02) -1.59% (p=0.000 n=15+15)
MatchMedium_32K 1.71ms × (0.99,1.01) 1.75ms × (0.99,1.02) +2.36% (p=0.000 n=14+15)
MatchMedium_1M 54.5ms × (0.99,1.01) 56.1ms × (0.99,1.01) +2.94% (p=0.000 n=13+15)
MatchMedium_32M 1.75s × (0.99,1.01) 1.80s × (0.99,1.01) +2.77% (p=0.000 n=15+15)
MatchHard_32 2.12µs × (0.99,1.02) 2.06µs × (0.99,1.01) -2.60% (p=0.000 n=15+14)
MatchHard_1K 64.4µs × (0.98,1.02) 62.2µs × (0.99,1.01) -3.33% (p=0.000 n=15+15)
MatchHard_32K 2.74ms × (0.99,1.01) 2.75ms × (0.99,1.01) ~ (p=0.310 n=15+14)
MatchHard_1M 87.1ms × (0.99,1.02) 88.2ms × (0.99,1.01) +1.36% (p=0.000 n=14+15)
MatchHard_32M 2.79s × (0.99,1.02) 2.83s × (0.99,1.02) +1.26% (p=0.004 n=15+14)
go1 benchmarks
name old time/op new time/op delta
BinaryTree17 3.34s ± 3% 3.28s ± 2% -1.86% (p=0.000 n=67+66)
Fannkuch11 2.50s ± 1% 2.51s ± 1% +0.24% (p=0.016 n=63+66)
FmtFprintfEmpty 50.3ns ± 1% 50.2ns ± 2% -0.30% (p=0.001 n=62+67)
FmtFprintfString 178ns ± 1% 166ns ± 1% -7.10% (p=0.000 n=62+59)
FmtFprintfInt 168ns ± 1% 161ns ± 2% -4.41% (p=0.000 n=66+64)
FmtFprintfIntInt 292ns ± 1% 282ns ± 2% -3.55% (p=0.000 n=62+60)
FmtFprintfPrefixedInt 245ns ± 2% 239ns ± 2% -2.24% (p=0.000 n=66+65)
FmtFprintfFloat 338ns ± 2% 326ns ± 1% -3.42% (p=0.000 n=64+59)
FmtManyArgs 1.14µs ± 1% 1.10µs ± 2% -3.55% (p=0.000 n=62+62)
GobDecode 8.88ms ± 2% 8.74ms ± 1% -1.55% (p=0.000 n=66+62)
GobEncode 6.84ms ± 2% 6.61ms ± 2% -3.32% (p=0.000 n=61+67)
Gzip 356ms ± 2% 352ms ± 2% -1.07% (p=0.000 n=67+66)
Gunzip 90.6ms ± 2% 89.8ms ± 1% -0.83% (p=0.000 n=65+64)
HTTPClientServer 82.6µs ± 2% 82.5µs ± 2% ~ (p=0.832 n=65+63)
JSONEncode 17.5ms ± 2% 16.8ms ± 2% -3.77% (p=0.000 n=63+63)
JSONDecode 63.3ms ± 2% 59.0ms ± 2% -6.85% (p=0.000 n=64+63)
Mandelbrot200 3.85ms ± 1% 3.85ms ± 1% ~ (p=0.127 n=65+62)
GoParse 3.75ms ± 2% 3.66ms ± 2% -2.39% (p=0.000 n=66+64)
RegexpMatchEasy0_32 100ns ± 2% 100ns ± 1% -0.65% (p=0.000 n=62+64)
RegexpMatchEasy0_1K 342ns ± 1% 341ns ± 1% -0.43% (p=0.000 n=65+64)
RegexpMatchEasy1_32 82.8ns ± 2% 82.8ns ± 2% ~ (p=0.977 n=63+64)
RegexpMatchEasy1_1K 511ns ± 2% 506ns ± 2% -1.01% (p=0.000 n=63+64)
RegexpMatchMedium_32 139ns ± 1% 134ns ± 3% -3.27% (p=0.000 n=59+60)
RegexpMatchMedium_1K 41.8µs ± 2% 40.5µs ± 2% -3.05% (p=0.000 n=62+64)
RegexpMatchHard_32 2.13µs ± 1% 2.09µs ± 1% -2.22% (p=0.000 n=60+65)
RegexpMatchHard_1K 64.4µs ± 3% 62.8µs ± 2% -2.58% (p=0.000 n=65+59)
Revcomp 531ms ± 2% 529ms ± 1% -0.28% (p=0.022 n=61+61)
Template 73.2ms ± 1% 73.1ms ± 1% ~ (p=0.794 n=66+63)
TimeParse 369ns ± 1% 352ns ± 1% -4.68% (p=0.000 n=65+66)
TimeFormat 374ns ± 2% 348ns ± 2% -7.01% (p=0.000 n=66+64)
Change-Id: Ib190b5bb48a3e9087711d9e3383621d3103dd342
Reviewed-on: https://go-review.googlesource.com/10367
Reviewed-by: Russ Cox <rsc@golang.org>
2015-05-28 17:31:24 -07:00
|
|
|
|
2020-08-28 17:10:32 +00:00
|
|
|
jls.To.SetTarget(call)
|
2015-01-19 14:34:58 -05:00
|
|
|
if q1 != nil {
|
2020-08-28 17:10:32 +00:00
|
|
|
q1.To.SetTarget(call)
|
2015-01-19 14:34:58 -05:00
|
|
|
}
|
|
|
|
|
cmd/internal/obj: mark split-stack prologue nonpreemptible
When there are both a synchronous preemption request (by
clobbering the stack guard) and an asynchronous one (by signal),
the running goroutine may observe the synchronous request first
in stack bounds check, and go to the path of calling morestack.
If the preemption signal arrives at this point before the call to
morestack, the goroutine will be asynchronously preempted,
entering the scheduler. When it is resumed, the scheduler clears
the preemption request, unclobbers the stack guard. But the
resumed goroutine will still call morestack, as it is already on
its way. morestack will, as there is no preemption request,
double the stack unnecessarily. If this happens multiple times,
the stack may grow too big, although only a small amount is
actually used.
To fix this, we mark the stack bounds check and the call to
morestack async-nonpreemptible, starting after the memory
instruction (mostly a load, on x86 CMP with memory).
Not done for Wasm as it does not support async preemption.
Fixes #35470.
Change-Id: Ibd7f3d935a3649b80f47539116ec9b9556680cf2
Reviewed-on: https://go-review.googlesource.com/c/go/+/207350
Reviewed-by: David Chase <drchase@google.com>
2019-11-14 20:23:17 -05:00
|
|
|
return end
|
2015-01-19 14:34:58 -05:00
|
|
|
}
|
|
|
|
|
2016-03-07 18:00:08 -08:00
|
|
|
var unaryDst = map[obj.As]bool{
|
cmd/internal/obj/x86: add missing legacy insts
Minimizes the amount of "TODO" stuff in test suite
of cmd/asm/internal/asm/testdata/amd64enc.s.
Some instructions were already implemented, but
test cases for them were commented-out.
Does not enable MMX instructions, calls/jumps and some
segment registers instructions.
-- Affected instructions --
BLENDVPD, BLENDVPS
BSWAPW
CBW
CDQE
CLAC
CLFLUSHOPT
CMPXCHG16B
CRC32B, CRC32L, CRC32W
CWDE
FBLD
FBSTP
FCMOVB
FCMOVBE
FCMOVE
FCMOVNB
FCMOVNBE
FCMOVU
FCOMI
FCOMIP
IMUL3L, IMUL3Q, IMUL3W
ICEBP, INT
INVPCID
LARQ
LGDT, LIDT, LLDT
LMSW
LTR
LZCNTL, LZCNTQ, LZCNTW
MONITOR
MOVBELL, MOVBEQQ, MOVBEWW
MOVBQZX
MOVQ
MOVSWW, MOVZWW
MWAIT
NOPL, NOPW
PBLENDVB
PEXTRW
RDPKRU
RDRANDL, RDRANDQ, RDRANDW
RDSEEDL, RDSEEDQ, RDSEEDW
RDTSCP
SAHF
SGDT, SIDT
SLDTL, SLDTQ, SLDTW
SMSWL, SMSWQ, SMSWW
STAC
STRL, STRQ, STRW
SYSENTER, SYSENTER64
SYSEXIT, SYSEXIT64
SHA256RNDS2
TZCNTL, TZCNTQ, TZCNTW
UD1, UD2
WRPKRU
XRSTOR, XRSTOR64
XRSTORS, XRSTORS64
XSAVE, XSAVE64
XSAVEC, XSAVEC64
XSAVEOPT, XSAVEOPT64
XSAVES, XSAVES64
XSETBV
Fixes #6739
Change-Id: I8b125d9a5ea39bb4b9da7e66a63a16f609cef376
Reviewed-on: https://go-review.googlesource.com/97235
Run-TryBot: Iskander Sharipov <iskander.sharipov@intel.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
2018-02-26 22:23:37 +03:00
|
|
|
ABSWAPL: true,
|
|
|
|
ABSWAPQ: true,
|
2019-06-21 11:15:21 +03:00
|
|
|
ACLDEMOTE: true,
|
cmd/internal/obj/x86: add missing legacy insts
Minimizes the amount of "TODO" stuff in test suite
of cmd/asm/internal/asm/testdata/amd64enc.s.
Some instructions were already implemented, but
test cases for them were commented-out.
Does not enable MMX instructions, calls/jumps and some
segment registers instructions.
-- Affected instructions --
BLENDVPD, BLENDVPS
BSWAPW
CBW
CDQE
CLAC
CLFLUSHOPT
CMPXCHG16B
CRC32B, CRC32L, CRC32W
CWDE
FBLD
FBSTP
FCMOVB
FCMOVBE
FCMOVE
FCMOVNB
FCMOVNBE
FCMOVU
FCOMI
FCOMIP
IMUL3L, IMUL3Q, IMUL3W
ICEBP, INT
INVPCID
LARQ
LGDT, LIDT, LLDT
LMSW
LTR
LZCNTL, LZCNTQ, LZCNTW
MONITOR
MOVBELL, MOVBEQQ, MOVBEWW
MOVBQZX
MOVQ
MOVSWW, MOVZWW
MWAIT
NOPL, NOPW
PBLENDVB
PEXTRW
RDPKRU
RDRANDL, RDRANDQ, RDRANDW
RDSEEDL, RDSEEDQ, RDSEEDW
RDTSCP
SAHF
SGDT, SIDT
SLDTL, SLDTQ, SLDTW
SMSWL, SMSWQ, SMSWW
STAC
STRL, STRQ, STRW
SYSENTER, SYSENTER64
SYSEXIT, SYSEXIT64
SHA256RNDS2
TZCNTL, TZCNTQ, TZCNTW
UD1, UD2
WRPKRU
XRSTOR, XRSTOR64
XRSTORS, XRSTORS64
XSAVE, XSAVE64
XSAVEC, XSAVEC64
XSAVEOPT, XSAVEOPT64
XSAVES, XSAVES64
XSETBV
Fixes #6739
Change-Id: I8b125d9a5ea39bb4b9da7e66a63a16f609cef376
Reviewed-on: https://go-review.googlesource.com/97235
Run-TryBot: Iskander Sharipov <iskander.sharipov@intel.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
2018-02-26 22:23:37 +03:00
|
|
|
ACLFLUSH: true,
|
|
|
|
ACLFLUSHOPT: true,
|
2019-06-21 11:15:21 +03:00
|
|
|
ACLWB: true,
|
cmd/internal/obj/x86: add missing legacy insts
Minimizes the amount of "TODO" stuff in test suite
of cmd/asm/internal/asm/testdata/amd64enc.s.
Some instructions were already implemented, but
test cases for them were commented-out.
Does not enable MMX instructions, calls/jumps and some
segment registers instructions.
-- Affected instructions --
BLENDVPD, BLENDVPS
BSWAPW
CBW
CDQE
CLAC
CLFLUSHOPT
CMPXCHG16B
CRC32B, CRC32L, CRC32W
CWDE
FBLD
FBSTP
FCMOVB
FCMOVBE
FCMOVE
FCMOVNB
FCMOVNBE
FCMOVU
FCOMI
FCOMIP
IMUL3L, IMUL3Q, IMUL3W
ICEBP, INT
INVPCID
LARQ
LGDT, LIDT, LLDT
LMSW
LTR
LZCNTL, LZCNTQ, LZCNTW
MONITOR
MOVBELL, MOVBEQQ, MOVBEWW
MOVBQZX
MOVQ
MOVSWW, MOVZWW
MWAIT
NOPL, NOPW
PBLENDVB
PEXTRW
RDPKRU
RDRANDL, RDRANDQ, RDRANDW
RDSEEDL, RDSEEDQ, RDSEEDW
RDTSCP
SAHF
SGDT, SIDT
SLDTL, SLDTQ, SLDTW
SMSWL, SMSWQ, SMSWW
STAC
STRL, STRQ, STRW
SYSENTER, SYSENTER64
SYSEXIT, SYSEXIT64
SHA256RNDS2
TZCNTL, TZCNTQ, TZCNTW
UD1, UD2
WRPKRU
XRSTOR, XRSTOR64
XRSTORS, XRSTORS64
XSAVE, XSAVE64
XSAVEC, XSAVEC64
XSAVEOPT, XSAVEOPT64
XSAVES, XSAVES64
XSETBV
Fixes #6739
Change-Id: I8b125d9a5ea39bb4b9da7e66a63a16f609cef376
Reviewed-on: https://go-review.googlesource.com/97235
Run-TryBot: Iskander Sharipov <iskander.sharipov@intel.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
2018-02-26 22:23:37 +03:00
|
|
|
ACMPXCHG16B: true,
|
|
|
|
ACMPXCHG8B: true,
|
|
|
|
ADECB: true,
|
|
|
|
ADECL: true,
|
|
|
|
ADECQ: true,
|
|
|
|
ADECW: true,
|
|
|
|
AFBSTP: true,
|
|
|
|
AFFREE: true,
|
|
|
|
AFLDENV: true,
|
|
|
|
AFSAVE: true,
|
|
|
|
AFSTCW: true,
|
|
|
|
AFSTENV: true,
|
|
|
|
AFSTSW: true,
|
|
|
|
AFXSAVE64: true,
|
|
|
|
AFXSAVE: true,
|
|
|
|
AINCB: true,
|
|
|
|
AINCL: true,
|
|
|
|
AINCQ: true,
|
|
|
|
AINCW: true,
|
|
|
|
ANEGB: true,
|
|
|
|
ANEGL: true,
|
|
|
|
ANEGQ: true,
|
|
|
|
ANEGW: true,
|
|
|
|
ANOTB: true,
|
|
|
|
ANOTL: true,
|
|
|
|
ANOTQ: true,
|
|
|
|
ANOTW: true,
|
|
|
|
APOPL: true,
|
|
|
|
APOPQ: true,
|
|
|
|
APOPW: true,
|
|
|
|
ARDFSBASEL: true,
|
|
|
|
ARDFSBASEQ: true,
|
|
|
|
ARDGSBASEL: true,
|
|
|
|
ARDGSBASEQ: true,
|
|
|
|
ARDRANDL: true,
|
|
|
|
ARDRANDQ: true,
|
|
|
|
ARDRANDW: true,
|
|
|
|
ARDSEEDL: true,
|
|
|
|
ARDSEEDQ: true,
|
|
|
|
ARDSEEDW: true,
|
|
|
|
ASETCC: true,
|
|
|
|
ASETCS: true,
|
|
|
|
ASETEQ: true,
|
|
|
|
ASETGE: true,
|
|
|
|
ASETGT: true,
|
|
|
|
ASETHI: true,
|
|
|
|
ASETLE: true,
|
|
|
|
ASETLS: true,
|
|
|
|
ASETLT: true,
|
|
|
|
ASETMI: true,
|
|
|
|
ASETNE: true,
|
|
|
|
ASETOC: true,
|
|
|
|
ASETOS: true,
|
|
|
|
ASETPC: true,
|
|
|
|
ASETPL: true,
|
|
|
|
ASETPS: true,
|
|
|
|
ASGDT: true,
|
|
|
|
ASIDT: true,
|
|
|
|
ASLDTL: true,
|
|
|
|
ASLDTQ: true,
|
|
|
|
ASLDTW: true,
|
|
|
|
ASMSWL: true,
|
|
|
|
ASMSWQ: true,
|
|
|
|
ASMSWW: true,
|
|
|
|
ASTMXCSR: true,
|
|
|
|
ASTRL: true,
|
|
|
|
ASTRQ: true,
|
|
|
|
ASTRW: true,
|
|
|
|
AXSAVE64: true,
|
|
|
|
AXSAVE: true,
|
|
|
|
AXSAVEC64: true,
|
|
|
|
AXSAVEC: true,
|
|
|
|
AXSAVEOPT64: true,
|
|
|
|
AXSAVEOPT: true,
|
|
|
|
AXSAVES64: true,
|
|
|
|
AXSAVES: true,
|
2015-03-02 11:04:06 -08:00
|
|
|
}
|
|
|
|
|
2015-01-19 14:34:58 -05:00
|
|
|
var Linkamd64 = obj.LinkArch{
|
[dev.debug] cmd/compile: better DWARF with optimizations on
Debuggers use DWARF information to find local variables on the
stack and in registers. Prior to this CL, the DWARF information for
functions claimed that all variables were on the stack at all times.
That's incorrect when optimizations are enabled, and results in
debuggers showing data that is out of date or complete gibberish.
After this CL, the compiler is capable of representing variable
locations more accurately, and attempts to do so. Due to limitations of
the SSA backend, it's not possible to be completely correct.
There are a number of problems in the current design. One of the easier
to understand is that variable names currently must be attached to an
SSA value, but not all assignments in the source code actually result
in machine code. For example:
type myint int
var a int
b := myint(int)
and
b := (*uint64)(unsafe.Pointer(a))
don't generate machine code because the underlying representation is the
same, so the correct value of b will not be set when the user would
expect.
Generating the more precise debug information is behind a flag,
dwarflocationlists. Because of the issues described above, setting the
flag may not make the debugging experience much better, and may actually
make it worse in cases where the variable actually is on the stack and
the more complicated analysis doesn't realize it.
A number of changes are included:
- Add a new pseudo-instruction, RegKill, which indicates that the value
in the register has been clobbered.
- Adjust regalloc to emit RegKills in the right places. Significantly,
this means that phis are mixed with StoreReg and RegKills after
regalloc.
- Track variable decomposition in ssa.LocalSlots.
- After the SSA backend is done, analyze the result and build location
lists for each LocalSlot.
- After assembly is done, update the location lists with the assembled
PC offsets, recompose variables, and build DWARF location lists. Emit the
list as a new linker symbol, one per function.
- In the linker, aggregate the location lists into a .debug_loc section.
TODO:
- currently disabled for non-X86/AMD64 because there are no data tables.
go build -toolexec 'toolstash -cmp' -a std succeeds.
With -dwarflocationlists false:
before: f02812195637909ff675782c0b46836a8ff01976
after: 06f61e8112a42ac34fb80e0c818b3cdb84a5e7ec
benchstat -geomean /tmp/220352263 /tmp/621364410
completed 15 of 15, estimated time remaining 0s (eta 3:52PM)
name old time/op new time/op delta
Template 199ms ± 3% 198ms ± 2% ~ (p=0.400 n=15+14)
Unicode 96.6ms ± 5% 96.4ms ± 5% ~ (p=0.838 n=15+15)
GoTypes 653ms ± 2% 647ms ± 2% ~ (p=0.102 n=15+14)
Flate 133ms ± 6% 129ms ± 3% -2.62% (p=0.041 n=15+15)
GoParser 164ms ± 5% 159ms ± 3% -3.05% (p=0.000 n=15+15)
Reflect 428ms ± 4% 422ms ± 3% ~ (p=0.156 n=15+13)
Tar 123ms ±10% 124ms ± 8% ~ (p=0.461 n=15+15)
XML 228ms ± 3% 224ms ± 3% -1.57% (p=0.045 n=15+15)
[Geo mean] 206ms 377ms +82.86%
name old user-time/op new user-time/op delta
Template 292ms ±10% 301ms ±12% ~ (p=0.189 n=15+15)
Unicode 166ms ±37% 158ms ±14% ~ (p=0.418 n=15+14)
GoTypes 962ms ± 6% 963ms ± 7% ~ (p=0.976 n=15+15)
Flate 207ms ±19% 200ms ±14% ~ (p=0.345 n=14+15)
GoParser 246ms ±22% 240ms ±15% ~ (p=0.587 n=15+15)
Reflect 611ms ±13% 587ms ±14% ~ (p=0.085 n=15+13)
Tar 211ms ±12% 217ms ±14% ~ (p=0.355 n=14+15)
XML 335ms ±15% 320ms ±18% ~ (p=0.169 n=15+15)
[Geo mean] 317ms 583ms +83.72%
name old alloc/op new alloc/op delta
Template 40.2MB ± 0% 40.2MB ± 0% -0.15% (p=0.000 n=14+15)
Unicode 29.2MB ± 0% 29.3MB ± 0% ~ (p=0.624 n=15+15)
GoTypes 114MB ± 0% 114MB ± 0% -0.15% (p=0.000 n=15+14)
Flate 25.7MB ± 0% 25.6MB ± 0% -0.18% (p=0.000 n=13+15)
GoParser 32.2MB ± 0% 32.2MB ± 0% -0.14% (p=0.003 n=15+15)
Reflect 77.8MB ± 0% 77.9MB ± 0% ~ (p=0.061 n=15+15)
Tar 27.1MB ± 0% 27.0MB ± 0% -0.11% (p=0.029 n=15+15)
XML 42.7MB ± 0% 42.5MB ± 0% -0.29% (p=0.000 n=15+15)
[Geo mean] 42.1MB 75.0MB +78.05%
name old allocs/op new allocs/op delta
Template 402k ± 1% 398k ± 0% -0.91% (p=0.000 n=15+15)
Unicode 344k ± 1% 344k ± 0% ~ (p=0.715 n=15+14)
GoTypes 1.18M ± 0% 1.17M ± 0% -0.91% (p=0.000 n=15+14)
Flate 243k ± 0% 240k ± 1% -1.05% (p=0.000 n=13+15)
GoParser 327k ± 1% 324k ± 1% -0.96% (p=0.000 n=15+15)
Reflect 984k ± 1% 982k ± 0% ~ (p=0.050 n=15+15)
Tar 261k ± 1% 259k ± 1% -0.77% (p=0.000 n=15+15)
XML 411k ± 0% 404k ± 1% -1.55% (p=0.000 n=15+15)
[Geo mean] 439k 755k +72.01%
name old text-bytes new text-bytes delta
HelloSize 694kB ± 0% 694kB ± 0% -0.00% (p=0.000 n=15+15)
name old data-bytes new data-bytes delta
HelloSize 5.55kB ± 0% 5.55kB ± 0% ~ (all equal)
name old bss-bytes new bss-bytes delta
HelloSize 133kB ± 0% 133kB ± 0% ~ (all equal)
name old exe-bytes new exe-bytes delta
HelloSize 1.04MB ± 0% 1.04MB ± 0% ~ (all equal)
Change-Id: I991fc553ef175db46bb23b2128317bbd48de70d8
Reviewed-on: https://go-review.googlesource.com/41770
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
2017-07-21 18:30:19 -04:00
|
|
|
Arch: sys.ArchAMD64,
|
|
|
|
Init: instinit,
|
|
|
|
Preprocess: preprocess,
|
|
|
|
Assemble: span6,
|
|
|
|
Progedit: progedit,
|
|
|
|
UnaryDst: unaryDst,
|
|
|
|
DWARFRegisters: AMD64DWARFRegisters,
|
2015-01-19 14:34:58 -05:00
|
|
|
}
|
|
|
|
|
cmd/internal/obj/x86: take over i386 duty, clean up PINSRQ, CMPSD
Make cmd/internal/obj/x86 support 32-bit mode and use
instead of cmd/internal/obj/i386. Delete cmd/internal/obj/i386.
Clean up encoding of PINSRQ, CMPSD to use explicit third arg
instead of jamming it into an unused slot of a different arg.
Also fix bug in old6a, which declared the wrong grammar.
The accepted (and encoded) arguments to CMPSD etc are mem,reg not reg,mem.
Code that did try to use mem,reg before would be rejected by liblink,
so only reg,reg ever worked, so existing code is not affected.
After this change, code can use mem,reg successfully.
The real bug here is that the encoding tables inverted the argument
order, making the comparisons all backward from what they say on the page.
It's too late to swap them, though: people have already written code that
expects the inverted comparisons (like in package math, and likely externally).
The best we can do is make the argument that should and can take a
memory operand accept it.
Bit-for-bit compatibility checked against tree without this CL.
Change-Id: Ife5685bc98c95001f64407f35066b34b4dae11c1
Reviewed-on: https://go-review.googlesource.com/6810
Reviewed-by: Rob Pike <r@golang.org>
2015-03-04 15:46:52 -05:00
|
|
|
var Link386 = obj.LinkArch{
|
[dev.debug] cmd/compile: better DWARF with optimizations on
Debuggers use DWARF information to find local variables on the
stack and in registers. Prior to this CL, the DWARF information for
functions claimed that all variables were on the stack at all times.
That's incorrect when optimizations are enabled, and results in
debuggers showing data that is out of date or complete gibberish.
After this CL, the compiler is capable of representing variable
locations more accurately, and attempts to do so. Due to limitations of
the SSA backend, it's not possible to be completely correct.
There are a number of problems in the current design. One of the easier
to understand is that variable names currently must be attached to an
SSA value, but not all assignments in the source code actually result
in machine code. For example:
type myint int
var a int
b := myint(int)
and
b := (*uint64)(unsafe.Pointer(a))
don't generate machine code because the underlying representation is the
same, so the correct value of b will not be set when the user would
expect.
Generating the more precise debug information is behind a flag,
dwarflocationlists. Because of the issues described above, setting the
flag may not make the debugging experience much better, and may actually
make it worse in cases where the variable actually is on the stack and
the more complicated analysis doesn't realize it.
A number of changes are included:
- Add a new pseudo-instruction, RegKill, which indicates that the value
in the register has been clobbered.
- Adjust regalloc to emit RegKills in the right places. Significantly,
this means that phis are mixed with StoreReg and RegKills after
regalloc.
- Track variable decomposition in ssa.LocalSlots.
- After the SSA backend is done, analyze the result and build location
lists for each LocalSlot.
- After assembly is done, update the location lists with the assembled
PC offsets, recompose variables, and build DWARF location lists. Emit the
list as a new linker symbol, one per function.
- In the linker, aggregate the location lists into a .debug_loc section.
TODO:
- currently disabled for non-X86/AMD64 because there are no data tables.
go build -toolexec 'toolstash -cmp' -a std succeeds.
With -dwarflocationlists false:
before: f02812195637909ff675782c0b46836a8ff01976
after: 06f61e8112a42ac34fb80e0c818b3cdb84a5e7ec
benchstat -geomean /tmp/220352263 /tmp/621364410
completed 15 of 15, estimated time remaining 0s (eta 3:52PM)
name old time/op new time/op delta
Template 199ms ± 3% 198ms ± 2% ~ (p=0.400 n=15+14)
Unicode 96.6ms ± 5% 96.4ms ± 5% ~ (p=0.838 n=15+15)
GoTypes 653ms ± 2% 647ms ± 2% ~ (p=0.102 n=15+14)
Flate 133ms ± 6% 129ms ± 3% -2.62% (p=0.041 n=15+15)
GoParser 164ms ± 5% 159ms ± 3% -3.05% (p=0.000 n=15+15)
Reflect 428ms ± 4% 422ms ± 3% ~ (p=0.156 n=15+13)
Tar 123ms ±10% 124ms ± 8% ~ (p=0.461 n=15+15)
XML 228ms ± 3% 224ms ± 3% -1.57% (p=0.045 n=15+15)
[Geo mean] 206ms 377ms +82.86%
name old user-time/op new user-time/op delta
Template 292ms ±10% 301ms ±12% ~ (p=0.189 n=15+15)
Unicode 166ms ±37% 158ms ±14% ~ (p=0.418 n=15+14)
GoTypes 962ms ± 6% 963ms ± 7% ~ (p=0.976 n=15+15)
Flate 207ms ±19% 200ms ±14% ~ (p=0.345 n=14+15)
GoParser 246ms ±22% 240ms ±15% ~ (p=0.587 n=15+15)
Reflect 611ms ±13% 587ms ±14% ~ (p=0.085 n=15+13)
Tar 211ms ±12% 217ms ±14% ~ (p=0.355 n=14+15)
XML 335ms ±15% 320ms ±18% ~ (p=0.169 n=15+15)
[Geo mean] 317ms 583ms +83.72%
name old alloc/op new alloc/op delta
Template 40.2MB ± 0% 40.2MB ± 0% -0.15% (p=0.000 n=14+15)
Unicode 29.2MB ± 0% 29.3MB ± 0% ~ (p=0.624 n=15+15)
GoTypes 114MB ± 0% 114MB ± 0% -0.15% (p=0.000 n=15+14)
Flate 25.7MB ± 0% 25.6MB ± 0% -0.18% (p=0.000 n=13+15)
GoParser 32.2MB ± 0% 32.2MB ± 0% -0.14% (p=0.003 n=15+15)
Reflect 77.8MB ± 0% 77.9MB ± 0% ~ (p=0.061 n=15+15)
Tar 27.1MB ± 0% 27.0MB ± 0% -0.11% (p=0.029 n=15+15)
XML 42.7MB ± 0% 42.5MB ± 0% -0.29% (p=0.000 n=15+15)
[Geo mean] 42.1MB 75.0MB +78.05%
name old allocs/op new allocs/op delta
Template 402k ± 1% 398k ± 0% -0.91% (p=0.000 n=15+15)
Unicode 344k ± 1% 344k ± 0% ~ (p=0.715 n=15+14)
GoTypes 1.18M ± 0% 1.17M ± 0% -0.91% (p=0.000 n=15+14)
Flate 243k ± 0% 240k ± 1% -1.05% (p=0.000 n=13+15)
GoParser 327k ± 1% 324k ± 1% -0.96% (p=0.000 n=15+15)
Reflect 984k ± 1% 982k ± 0% ~ (p=0.050 n=15+15)
Tar 261k ± 1% 259k ± 1% -0.77% (p=0.000 n=15+15)
XML 411k ± 0% 404k ± 1% -1.55% (p=0.000 n=15+15)
[Geo mean] 439k 755k +72.01%
name old text-bytes new text-bytes delta
HelloSize 694kB ± 0% 694kB ± 0% -0.00% (p=0.000 n=15+15)
name old data-bytes new data-bytes delta
HelloSize 5.55kB ± 0% 5.55kB ± 0% ~ (all equal)
name old bss-bytes new bss-bytes delta
HelloSize 133kB ± 0% 133kB ± 0% ~ (all equal)
name old exe-bytes new exe-bytes delta
HelloSize 1.04MB ± 0% 1.04MB ± 0% ~ (all equal)
Change-Id: I991fc553ef175db46bb23b2128317bbd48de70d8
Reviewed-on: https://go-review.googlesource.com/41770
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
2017-07-21 18:30:19 -04:00
|
|
|
Arch: sys.Arch386,
|
|
|
|
Init: instinit,
|
|
|
|
Preprocess: preprocess,
|
|
|
|
Assemble: span6,
|
|
|
|
Progedit: progedit,
|
|
|
|
UnaryDst: unaryDst,
|
2017-11-15 13:45:31 -05:00
|
|
|
DWARFRegisters: X86DWARFRegisters,
|
cmd/internal/obj/x86: take over i386 duty, clean up PINSRQ, CMPSD
Make cmd/internal/obj/x86 support 32-bit mode and use
instead of cmd/internal/obj/i386. Delete cmd/internal/obj/i386.
Clean up encoding of PINSRQ, CMPSD to use explicit third arg
instead of jamming it into an unused slot of a different arg.
Also fix bug in old6a, which declared the wrong grammar.
The accepted (and encoded) arguments to CMPSD etc are mem,reg not reg,mem.
Code that did try to use mem,reg before would be rejected by liblink,
so only reg,reg ever worked, so existing code is not affected.
After this change, code can use mem,reg successfully.
The real bug here is that the encoding tables inverted the argument
order, making the comparisons all backward from what they say on the page.
It's too late to swap them, though: people have already written code that
expects the inverted comparisons (like in package math, and likely externally).
The best we can do is make the argument that should and can take a
memory operand accept it.
Bit-for-bit compatibility checked against tree without this CL.
Change-Id: Ife5685bc98c95001f64407f35066b34b4dae11c1
Reviewed-on: https://go-review.googlesource.com/6810
Reviewed-by: Rob Pike <r@golang.org>
2015-03-04 15:46:52 -05:00
|
|
|
}
|