mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/internal/obj: change Prog.From3 to RestArgs ([]Addr)
This change makes it easier to express instructions
with arbitrary number of operands.
Rationale: previous approach with operand "hiding" does
not scale well, AVX and especially AVX512 have many
instructions with 3+ operands.
x86 asm backend is updated to handle up to 6 explicit operands.
It also fixes issue with 4-th immediate operand type checks.
All `ytab` tables are updated accordingly.
Changes to non-x86 backends only include these patterns:
`p.From3 = X` => `p.SetFrom3(X)`
`p.From3.X = Y` => `p.GetFrom3().X = Y`
Over time, other backends can adapt Prog.RestArgs
and reduce the amount of workarounds.
-- Performance --
x/benchmark/build:
$ benchstat upstream.bench patched.bench
name old time/op new time/op delta
Build-48 21.7s ± 2% 21.8s ± 2% ~ (p=0.218 n=10+10)
name old binary-size new binary-size delta
Build-48 10.3M ± 0% 10.3M ± 0% ~ (all equal)
name old build-time/op new build-time/op delta
Build-48 21.7s ± 2% 21.8s ± 2% ~ (p=0.218 n=10+10)
name old build-peak-RSS-bytes new build-peak-RSS-bytes delta
Build-48 145MB ± 5% 148MB ± 5% ~ (p=0.218 n=10+10)
name old build-user+sys-time/op new build-user+sys-time/op delta
Build-48 21.0s ± 2% 21.2s ± 2% ~ (p=0.075 n=10+10)
Microbenchmark shows a slight slowdown.
name old time/op new time/op delta
AMD64asm-4 49.5ms ± 1% 49.9ms ± 1% +0.67% (p=0.001 n=23+15)
func BenchmarkAMD64asm(b *testing.B) {
for i := 0; i < b.N; i++ {
TestAMD64EndToEnd(nil)
TestAMD64Encoder(nil)
}
}
Change-Id: I4f1d37b5c2c966da3f2127705ccac9bff0038183
Reviewed-on: https://go-review.googlesource.com/63490
Run-TryBot: Iskander Sharipov <iskander.sharipov@intel.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
parent
e1cf2be7a8
commit
8c67f210a1
21 changed files with 513 additions and 481 deletions
|
|
@ -201,8 +201,8 @@ func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
|
|||
}
|
||||
|
||||
if ctxt.Headtype == objabi.Hnacl && ctxt.Arch.Family == sys.AMD64 {
|
||||
if p.From3 != nil {
|
||||
nacladdr(ctxt, p, p.From3)
|
||||
if p.GetFrom3() != nil {
|
||||
nacladdr(ctxt, p, p.GetFrom3())
|
||||
}
|
||||
nacladdr(ctxt, p, &p.From)
|
||||
nacladdr(ctxt, p, &p.To)
|
||||
|
|
@ -398,7 +398,7 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
|
|||
q.From.Reg = reg
|
||||
}
|
||||
}
|
||||
if p.From3 != nil && p.From3.Name == obj.NAME_EXTERN {
|
||||
if p.GetFrom3() != nil && p.GetFrom3().Name == obj.NAME_EXTERN {
|
||||
ctxt.Diag("don't know how to handle %v with -dynlink", p)
|
||||
}
|
||||
var source *obj.Addr
|
||||
|
|
@ -436,7 +436,9 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
|
|||
p2.As = p.As
|
||||
p2.Scond = p.Scond
|
||||
p2.From = p.From
|
||||
p2.From3 = p.From3
|
||||
if p.RestArgs != nil {
|
||||
p2.RestArgs = append(p2.RestArgs, p.RestArgs...)
|
||||
}
|
||||
p2.Reg = p.Reg
|
||||
p2.To = p.To
|
||||
// p.To.Type was set to TYPE_BRANCH above, but that makes checkaddr
|
||||
|
|
@ -522,7 +524,7 @@ func rewriteToPcrel(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
|
|||
}
|
||||
}
|
||||
|
||||
if !isName(&p.From) && !isName(&p.To) && (p.From3 == nil || !isName(p.From3)) {
|
||||
if !isName(&p.From) && !isName(&p.To) && (p.GetFrom3() == nil || !isName(p.GetFrom3())) {
|
||||
return
|
||||
}
|
||||
var dst int16 = REG_CX
|
||||
|
|
@ -543,7 +545,7 @@ func rewriteToPcrel(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
|
|||
r.As = p.As
|
||||
r.Scond = p.Scond
|
||||
r.From = p.From
|
||||
r.From3 = p.From3
|
||||
r.RestArgs = p.RestArgs
|
||||
r.Reg = p.Reg
|
||||
r.To = p.To
|
||||
if isName(&p.From) {
|
||||
|
|
@ -552,8 +554,8 @@ func rewriteToPcrel(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
|
|||
if isName(&p.To) {
|
||||
r.To.Reg = dst
|
||||
}
|
||||
if p.From3 != nil && isName(p.From3) {
|
||||
r.From3.Reg = dst
|
||||
if p.GetFrom3() != nil && isName(p.GetFrom3()) {
|
||||
r.GetFrom3().Reg = dst
|
||||
}
|
||||
obj.Nopout(p)
|
||||
}
|
||||
|
|
@ -857,12 +859,12 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||
case obj.NAME_PARAM:
|
||||
p.From.Offset += int64(deltasp) + int64(pcsize)
|
||||
}
|
||||
if p.From3 != nil {
|
||||
switch p.From3.Name {
|
||||
if p.GetFrom3() != nil {
|
||||
switch p.GetFrom3().Name {
|
||||
case obj.NAME_AUTO:
|
||||
p.From3.Offset += int64(deltasp) - int64(bpsize)
|
||||
p.GetFrom3().Offset += int64(deltasp) - int64(bpsize)
|
||||
case obj.NAME_PARAM:
|
||||
p.From3.Offset += int64(deltasp) + int64(pcsize)
|
||||
p.GetFrom3().Offset += int64(deltasp) + int64(pcsize)
|
||||
}
|
||||
}
|
||||
switch p.To.Name {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue