aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/internal/obj/arm64
diff options
context:
space:
mode:
authorJosh Bleecher Snyder <josharian@gmail.com>2017-04-04 14:31:55 -0700
committerJosh Bleecher Snyder <josharian@gmail.com>2017-04-06 02:07:21 +0000
commit5b59b32c97c83b6b89bca9cfb0cc6eaaa1d19d55 (patch)
treedde665b4bbb790e5f5573675a310cc574315a6d2 /src/cmd/internal/obj/arm64
parent7e068895c37167f07cf0d70bc90e31854925784d (diff)
downloadgo-5b59b32c97c83b6b89bca9cfb0cc6eaaa1d19d55.tar.xz
cmd/compile: teach assemblers to accept a Prog allocator
The existing bulk Prog allocator is not concurrency-safe. To allow for concurrency-safe bulk allocation of Progs, I want to move Prog allocation and caching upstream, to the clients of cmd/internal/obj. This is a preliminary enabling refactoring. After this CL, instead of calling Ctxt.NewProg throughout the assemblers, we thread through a newprog function that returns a new Prog. That function is set up to be Ctxt.NewProg, so there are no real changes in this CL; this CL only establishes the plumbing. Passes toolstash-check -all. Negligible compiler performance impact. Updates #15756 name old time/op new time/op delta Template 213ms ± 3% 214ms ± 4% ~ (p=0.574 n=49+47) Unicode 90.1ms ± 5% 89.9ms ± 4% ~ (p=0.417 n=50+49) GoTypes 585ms ± 4% 584ms ± 3% ~ (p=0.466 n=49+49) SSA 6.50s ± 3% 6.52s ± 2% ~ (p=0.251 n=49+49) Flate 128ms ± 4% 128ms ± 4% ~ (p=0.673 n=49+50) GoParser 152ms ± 3% 152ms ± 3% ~ (p=0.810 n=48+49) Reflect 372ms ± 4% 372ms ± 5% ~ (p=0.778 n=49+50) Tar 113ms ± 5% 111ms ± 4% -0.98% (p=0.016 n=50+49) XML 208ms ± 3% 208ms ± 2% ~ (p=0.483 n=47+49) [Geo mean] 285ms 285ms -0.17% name old user-ns/op new user-ns/op delta Template 253M ± 8% 254M ± 9% ~ (p=0.899 n=50+50) Unicode 106M ± 9% 106M ±11% ~ (p=0.642 n=50+50) GoTypes 736M ± 4% 740M ± 4% ~ (p=0.121 n=50+49) SSA 8.82G ± 3% 8.88G ± 2% +0.65% (p=0.006 n=49+48) Flate 147M ± 4% 147M ± 5% ~ (p=0.844 n=47+48) GoParser 179M ± 4% 178M ± 6% ~ (p=0.785 n=50+50) Reflect 443M ± 6% 441M ± 5% ~ (p=0.850 n=48+47) Tar 126M ± 5% 126M ± 5% ~ (p=0.734 n=50+50) XML 244M ± 5% 244M ± 5% ~ (p=0.594 n=49+50) [Geo mean] 341M 341M +0.11% Change-Id: Ice962f61eb3a524c2db00a166cb582c22caa7d68 Reviewed-on: https://go-review.googlesource.com/39633 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
Diffstat (limited to 'src/cmd/internal/obj/arm64')
-rw-r--r--src/cmd/internal/obj/arm64/asm7.go30
-rw-r--r--src/cmd/internal/obj/arm64/obj7.go90
2 files changed, 60 insertions, 60 deletions
diff --git a/src/cmd/internal/obj/arm64/asm7.go b/src/cmd/internal/obj/arm64/asm7.go
index ad9b0e7cd8..66a324943d 100644
--- a/src/cmd/internal/obj/arm64/asm7.go
+++ b/src/cmd/internal/obj/arm64/asm7.go
@@ -524,7 +524,7 @@ var pool struct {
size uint32
}
-func span7(ctxt *obj.Link, cursym *obj.LSym) {
+func span7(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
p := cursym.Text
if p == nil || p.Link == nil { // handle external functions and ELF section symbols
return
@@ -557,19 +557,19 @@ func span7(ctxt *obj.Link, cursym *obj.LSym) {
switch o.flag & (LFROM | LTO) {
case LFROM:
- addpool(ctxt, p, &p.From)
+ addpool(ctxt, newprog, p, &p.From)
case LTO:
- addpool(ctxt, p, &p.To)
+ addpool(ctxt, newprog, p, &p.To)
break
}
if p.As == AB || p.As == obj.ARET || p.As == AERET { /* TODO: other unconditional operations */
- checkpool(ctxt, p, 0)
+ checkpool(ctxt, newprog, p, 0)
}
c += int64(m)
if ctxt.Blitrl != nil {
- checkpool(ctxt, p, 1)
+ checkpool(ctxt, newprog, p, 1)
}
}
@@ -598,14 +598,14 @@ func span7(ctxt *obj.Link, cursym *obj.LSym) {
if (o.type_ == 7 || o.type_ == 39) && p.Pcond != nil { // 7: BEQ and like, 39: CBZ and like
otxt := p.Pcond.Pc - c
if otxt <= -(1<<18)+10 || otxt >= (1<<18)-10 {
- q := ctxt.NewProg()
+ q := newprog()
q.Link = p.Link
p.Link = q
q.As = AB
q.To.Type = obj.TYPE_BRANCH
q.Pcond = p.Pcond
p.Pcond = q
- q = ctxt.NewProg()
+ q = newprog()
q.Link = p.Link
p.Link = q
q.As = AB
@@ -670,21 +670,21 @@ func span7(ctxt *obj.Link, cursym *obj.LSym) {
* to go out of range of a 1Mb PC-relative offset
* drop the pool now, and branch round it.
*/
-func checkpool(ctxt *obj.Link, p *obj.Prog, skip int) {
+func checkpool(ctxt *obj.Link, newprog obj.ProgAlloc, p *obj.Prog, skip int) {
if pool.size >= 0xffff0 || !ispcdisp(int32(p.Pc+4+int64(pool.size)-int64(pool.start)+8)) {
- flushpool(ctxt, p, skip)
+ flushpool(ctxt, newprog, p, skip)
} else if p.Link == nil {
- flushpool(ctxt, p, 2)
+ flushpool(ctxt, newprog, p, 2)
}
}
-func flushpool(ctxt *obj.Link, p *obj.Prog, skip int) {
+func flushpool(ctxt *obj.Link, newprog obj.ProgAlloc, p *obj.Prog, skip int) {
if ctxt.Blitrl != nil {
if skip != 0 {
if ctxt.Debugvlog && skip == 1 {
fmt.Printf("note: flush literal pool at %#x: len=%d ref=%x\n", uint64(p.Pc+4), pool.size, pool.start)
}
- q := ctxt.NewProg()
+ q := newprog()
q.As = AB
q.To.Type = obj.TYPE_BRANCH
q.Pcond = p.Link
@@ -715,10 +715,10 @@ func flushpool(ctxt *obj.Link, p *obj.Prog, skip int) {
/*
* TODO: hash
*/
-func addpool(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) {
+func addpool(ctxt *obj.Link, newprog obj.ProgAlloc, p *obj.Prog, a *obj.Addr) {
c := aclass(ctxt, a)
lit := ctxt.Instoffset
- t := *ctxt.NewProg()
+ t := *newprog()
t.As = AWORD
sz := 4
@@ -789,7 +789,7 @@ func addpool(ctxt *obj.Link, p *obj.Prog, a *obj.Addr) {
}
}
- q := ctxt.NewProg()
+ q := newprog()
*q = t
q.Pc = int64(pool.size)
if ctxt.Blitrl == nil {
diff --git a/src/cmd/internal/obj/arm64/obj7.go b/src/cmd/internal/obj/arm64/obj7.go
index 020b6e05c1..70cf880680 100644
--- a/src/cmd/internal/obj/arm64/obj7.go
+++ b/src/cmd/internal/obj/arm64/obj7.go
@@ -48,9 +48,9 @@ var complements = []obj.As{
ACMNW: ACMPW,
}
-func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
+func stacksplit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc, framesize int32) *obj.Prog {
// MOV g_stackguard(g), R1
- p = obj.Appendp(ctxt, p)
+ p = obj.Appendp(p, newprog)
p.As = AMOVD
p.From.Type = obj.TYPE_MEM
@@ -67,7 +67,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
// small stack: SP < stackguard
// MOV SP, R2
// CMP stackguard, R2
- p = obj.Appendp(ctxt, p)
+ p = obj.Appendp(p, newprog)
p.As = AMOVD
p.From.Type = obj.TYPE_REG
@@ -75,7 +75,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R2
- p = obj.Appendp(ctxt, p)
+ p = obj.Appendp(p, newprog)
p.As = ACMP
p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R1
@@ -84,7 +84,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
// large stack: SP-framesize < stackguard-StackSmall
// SUB $(framesize-StackSmall), SP, R2
// CMP stackguard, R2
- p = obj.Appendp(ctxt, p)
+ p = obj.Appendp(p, newprog)
p.As = ASUB
p.From.Type = obj.TYPE_CONST
@@ -93,7 +93,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R2
- p = obj.Appendp(ctxt, p)
+ p = obj.Appendp(p, newprog)
p.As = ACMP
p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R1
@@ -110,19 +110,19 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
// SUB R1, R2
// MOV $(framesize+(StackGuard-StackSmall)), R3
// CMP R3, R2
- p = obj.Appendp(ctxt, p)
+ p = obj.Appendp(p, newprog)
p.As = ACMP
p.From.Type = obj.TYPE_CONST
p.From.Offset = obj.StackPreempt
p.Reg = REG_R1
- p = obj.Appendp(ctxt, p)
+ p = obj.Appendp(p, newprog)
q = p
p.As = ABEQ
p.To.Type = obj.TYPE_BRANCH
- p = obj.Appendp(ctxt, p)
+ p = obj.Appendp(p, newprog)
p.As = AADD
p.From.Type = obj.TYPE_CONST
p.From.Offset = obj.StackGuard
@@ -130,21 +130,21 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R2
- p = obj.Appendp(ctxt, p)
+ p = obj.Appendp(p, newprog)
p.As = ASUB
p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R1
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R2
- p = obj.Appendp(ctxt, p)
+ p = obj.Appendp(p, newprog)
p.As = AMOVD
p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(framesize) + (obj.StackGuard - obj.StackSmall)
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R3
- p = obj.Appendp(ctxt, p)
+ p = obj.Appendp(p, newprog)
p.As = ACMP
p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R3
@@ -152,7 +152,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
}
// BLS do-morestack
- bls := obj.Appendp(ctxt, p)
+ bls := obj.Appendp(p, newprog)
bls.As = ABLS
bls.To.Type = obj.TYPE_BRANCH
@@ -163,11 +163,11 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
// 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.
- spfix := obj.Appendp(ctxt, last)
+ spfix := obj.Appendp(last, newprog)
spfix.As = obj.ANOP
spfix.Spadj = -framesize
- pcdata := obj.Appendp(ctxt, spfix)
+ pcdata := obj.Appendp(spfix, newprog)
pcdata.Pos = ctxt.Cursym.Text.Pos
pcdata.As = obj.APCDATA
pcdata.From.Type = obj.TYPE_CONST
@@ -176,7 +176,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
pcdata.To.Offset = -1 // pcdata starts at -1 at function entry
// MOV LR, R3
- movlr := obj.Appendp(ctxt, pcdata)
+ movlr := obj.Appendp(pcdata, newprog)
movlr.As = AMOVD
movlr.From.Type = obj.TYPE_REG
movlr.From.Reg = REGLINK
@@ -189,7 +189,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
debug := movlr
if false {
- debug = obj.Appendp(ctxt, debug)
+ debug = obj.Appendp(debug, newprog)
debug.As = AMOVD
debug.From.Type = obj.TYPE_CONST
debug.From.Offset = int64(framesize)
@@ -198,7 +198,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
}
// BL runtime.morestack(SB)
- call := obj.Appendp(ctxt, debug)
+ call := obj.Appendp(debug, newprog)
call.As = ABL
call.To.Type = obj.TYPE_BRANCH
morestack := "runtime.morestack"
@@ -211,7 +211,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
call.To.Sym = obj.Linklookup(ctxt, morestack, 0)
// B start
- jmp := obj.Appendp(ctxt, call)
+ jmp := obj.Appendp(call, newprog)
jmp.As = AB
jmp.To.Type = obj.TYPE_BRANCH
jmp.Pcond = ctxt.Cursym.Text.Link
@@ -224,7 +224,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, framesize int32) *obj.Prog {
return bls
}
-func progedit(ctxt *obj.Link, p *obj.Prog) {
+func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
p.From.Class = 0
p.To.Class = 0
@@ -326,12 +326,12 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
}
if ctxt.Flag_dynlink {
- rewriteToUseGot(ctxt, p)
+ rewriteToUseGot(ctxt, p, newprog)
}
}
// Rewrite p, if necessary, to access global data via the global offset table.
-func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
+func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
if p.As == obj.ADUFFCOPY || p.As == obj.ADUFFZERO {
// ADUFFxxx $offset
// becomes
@@ -354,13 +354,13 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
p.To.Name = obj.NAME_NONE
p.To.Offset = 0
p.To.Sym = nil
- p1 := obj.Appendp(ctxt, p)
+ p1 := obj.Appendp(p, newprog)
p1.As = AADD
p1.From.Type = obj.TYPE_CONST
p1.From.Offset = offset
p1.To.Type = obj.TYPE_REG
p1.To.Reg = REGTMP
- p2 := obj.Appendp(ctxt, p1)
+ p2 := obj.Appendp(p1, newprog)
p2.As = obj.ACALL
p2.To.Type = obj.TYPE_REG
p2.To.Reg = REGTMP
@@ -381,7 +381,7 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
p.From.Type = obj.TYPE_MEM
p.From.Name = obj.NAME_GOTREF
if p.From.Offset != 0 {
- q := obj.Appendp(ctxt, p)
+ q := obj.Appendp(p, newprog)
q.As = AADD
q.From.Type = obj.TYPE_CONST
q.From.Offset = p.From.Offset
@@ -415,8 +415,8 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
if source.Type != obj.TYPE_MEM {
ctxt.Diag("don't know how to handle %v with -dynlink", p)
}
- p1 := obj.Appendp(ctxt, p)
- p2 := obj.Appendp(ctxt, p1)
+ p1 := obj.Appendp(p, newprog)
+ p2 := obj.Appendp(p1, newprog)
p1.As = AMOVD
p1.From.Type = obj.TYPE_MEM
p1.From.Sym = source.Sym
@@ -441,7 +441,7 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
obj.Nopout(p)
}
-func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
+func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
ctxt.Cursym = cursym
if cursym.Text == nil || cursym.Text.Link == nil {
@@ -561,7 +561,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
}
if !(p.From3.Offset&obj.NOSPLIT != 0) {
- p = stacksplit(ctxt, p, ctxt.Autosize) // emit split check
+ p = stacksplit(ctxt, p, newprog, ctxt.Autosize) // emit split check
}
aoffset = ctxt.Autosize
@@ -583,7 +583,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
// Store link register before decrementing SP, so if a signal comes
// during the execution of the function prologue, the traceback
// code will not see a half-updated stack frame.
- q = obj.Appendp(ctxt, q)
+ q = obj.Appendp(q, newprog)
q.Pos = p.Pos
q.As = ASUB
q.From.Type = obj.TYPE_CONST
@@ -592,7 +592,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q.To.Type = obj.TYPE_REG
q.To.Reg = REGTMP
- q = obj.Appendp(ctxt, q)
+ q = obj.Appendp(q, newprog)
q.Pos = p.Pos
q.As = AMOVD
q.From.Type = obj.TYPE_REG
@@ -600,7 +600,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q.To.Type = obj.TYPE_MEM
q.To.Reg = REGTMP
- q1 = obj.Appendp(ctxt, q)
+ q1 = obj.Appendp(q, newprog)
q1.Pos = p.Pos
q1.As = AMOVD
q1.From.Type = obj.TYPE_REG
@@ -610,7 +610,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q1.Spadj = ctxt.Autosize
} else {
// small frame, update SP and save LR in a single MOVD.W instruction
- q1 = obj.Appendp(ctxt, q)
+ q1 = obj.Appendp(q, newprog)
q1.As = AMOVD
q1.Pos = p.Pos
q1.From.Type = obj.TYPE_REG
@@ -641,7 +641,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
// It is a liblink NOP, not a ARM64 NOP: it encodes to 0 instruction bytes.
q = q1
- q = obj.Appendp(ctxt, q)
+ q = obj.Appendp(q, newprog)
q.As = AMOVD
q.From.Type = obj.TYPE_MEM
q.From.Reg = REGG
@@ -649,18 +649,18 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R1
- q = obj.Appendp(ctxt, q)
+ q = obj.Appendp(q, newprog)
q.As = ACMP
q.From.Type = obj.TYPE_REG
q.From.Reg = REGZERO
q.Reg = REG_R1
- q = obj.Appendp(ctxt, q)
+ q = obj.Appendp(q, newprog)
q.As = ABEQ
q.To.Type = obj.TYPE_BRANCH
q1 = q
- q = obj.Appendp(ctxt, q)
+ q = obj.Appendp(q, newprog)
q.As = AMOVD
q.From.Type = obj.TYPE_MEM
q.From.Reg = REG_R1
@@ -668,7 +668,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R2
- q = obj.Appendp(ctxt, q)
+ q = obj.Appendp(q, newprog)
q.As = AADD
q.From.Type = obj.TYPE_CONST
q.From.Offset = int64(ctxt.Autosize) + 8
@@ -676,18 +676,18 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R3
- q = obj.Appendp(ctxt, q)
+ q = obj.Appendp(q, newprog)
q.As = ACMP
q.From.Type = obj.TYPE_REG
q.From.Reg = REG_R2
q.Reg = REG_R3
- q = obj.Appendp(ctxt, q)
+ q = obj.Appendp(q, newprog)
q.As = ABNE
q.To.Type = obj.TYPE_BRANCH
q2 = q
- q = obj.Appendp(ctxt, q)
+ q = obj.Appendp(q, newprog)
q.As = AADD
q.From.Type = obj.TYPE_CONST
q.From.Offset = 8
@@ -695,7 +695,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R4
- q = obj.Appendp(ctxt, q)
+ q = obj.Appendp(q, newprog)
q.As = AMOVD
q.From.Type = obj.TYPE_REG
q.From.Reg = REG_R4
@@ -703,7 +703,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
q.To.Reg = REG_R1
q.To.Offset = 0 // Panic.argp
- q = obj.Appendp(ctxt, q)
+ q = obj.Appendp(q, newprog)
q.As = obj.ANOP
q1.Pcond = q
@@ -744,7 +744,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
p.To.Reg = REGLINK
p.Spadj = -aoffset
if ctxt.Autosize > aoffset {
- q = ctxt.NewProg()
+ q = newprog()
q.As = AADD
q.From.Type = obj.TYPE_CONST
q.From.Offset = int64(ctxt.Autosize) - int64(aoffset)
@@ -759,7 +759,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym) {
}
if p.As != obj.ARET {
- q = ctxt.NewProg()
+ q = newprog()
q.Pos = p.Pos
q.Link = p.Link
p.Link = q