diff options
| author | Josh Bleecher Snyder <josharian@gmail.com> | 2017-04-04 14:31:55 -0700 |
|---|---|---|
| committer | Josh Bleecher Snyder <josharian@gmail.com> | 2017-04-06 02:07:21 +0000 |
| commit | 5b59b32c97c83b6b89bca9cfb0cc6eaaa1d19d55 (patch) | |
| tree | dde665b4bbb790e5f5573675a310cc574315a6d2 /src/cmd/internal/obj/arm64 | |
| parent | 7e068895c37167f07cf0d70bc90e31854925784d (diff) | |
| download | go-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.go | 30 | ||||
| -rw-r--r-- | src/cmd/internal/obj/arm64/obj7.go | 90 |
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 |
