mirror of
https://github.com/golang/go
synced 2024-11-19 17:04:41 -07:00
cmd/internal/obj/arm64: improve arm64 wrapper prologue
Improve static branch prediction in arm64 wrapper prologue by making the unusual case branch forwards. (Most other architectures implement this optimization.) Additionally, replace a CMP+BNE pair with a CBNZ to save one instruction. Change-Id: Id970038b34b4aaec18c101d62e2ee00f3e32a761 Reviewed-on: https://go-review.googlesource.com/54070 Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
parent
e6cbf98d69
commit
4282ba0a65
@ -515,7 +515,6 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||||||
q = p
|
q = p
|
||||||
}
|
}
|
||||||
|
|
||||||
var q2 *obj.Prog
|
|
||||||
var retjmp *obj.LSym
|
var retjmp *obj.LSym
|
||||||
for p := c.cursym.Func.Text; p != nil; p = p.Link {
|
for p := c.cursym.Func.Text; p != nil; p = p.Link {
|
||||||
o := p.As
|
o := p.As
|
||||||
@ -619,21 +618,24 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||||||
// if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
|
// if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
|
||||||
//
|
//
|
||||||
// MOV g_panic(g), R1
|
// MOV g_panic(g), R1
|
||||||
// CMP ZR, R1
|
// CBNZ checkargp
|
||||||
// BEQ end
|
// end:
|
||||||
|
// NOP
|
||||||
|
// ... function body ...
|
||||||
|
// checkargp:
|
||||||
// MOV panic_argp(R1), R2
|
// MOV panic_argp(R1), R2
|
||||||
// ADD $(autosize+8), RSP, R3
|
// ADD $(autosize+8), RSP, R3
|
||||||
// CMP R2, R3
|
// CMP R2, R3
|
||||||
// BNE end
|
// BNE end
|
||||||
// ADD $8, RSP, R4
|
// ADD $8, RSP, R4
|
||||||
// MOVD R4, panic_argp(R1)
|
// MOVD R4, panic_argp(R1)
|
||||||
// end:
|
// B end
|
||||||
// NOP
|
|
||||||
//
|
//
|
||||||
// The NOP is needed to give the jumps somewhere to land.
|
// The NOP is needed to give the jumps somewhere to land.
|
||||||
// It is a liblink NOP, not a ARM64 NOP: it encodes to 0 instruction bytes.
|
// It is a liblink NOP, not a ARM64 NOP: it encodes to 0 instruction bytes.
|
||||||
q = q1
|
q = q1
|
||||||
|
|
||||||
|
// MOV g_panic(g), R1
|
||||||
q = obj.Appendp(q, c.newprog)
|
q = obj.Appendp(q, c.newprog)
|
||||||
q.As = AMOVD
|
q.As = AMOVD
|
||||||
q.From.Type = obj.TYPE_MEM
|
q.From.Type = obj.TYPE_MEM
|
||||||
@ -642,26 +644,36 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||||||
q.To.Type = obj.TYPE_REG
|
q.To.Type = obj.TYPE_REG
|
||||||
q.To.Reg = REG_R1
|
q.To.Reg = REG_R1
|
||||||
|
|
||||||
q = obj.Appendp(q, c.newprog)
|
// CBNZ R1, checkargp
|
||||||
q.As = ACMP
|
cbnz := obj.Appendp(q, c.newprog)
|
||||||
q.From.Type = obj.TYPE_REG
|
cbnz.As = ACBNZ
|
||||||
q.From.Reg = REGZERO
|
cbnz.From.Type = obj.TYPE_REG
|
||||||
q.Reg = REG_R1
|
cbnz.From.Reg = REG_R1
|
||||||
|
cbnz.To.Type = obj.TYPE_BRANCH
|
||||||
|
|
||||||
q = obj.Appendp(q, c.newprog)
|
// Empty branch target at the top of the function body
|
||||||
q.As = ABEQ
|
end := obj.Appendp(cbnz, c.newprog)
|
||||||
q.To.Type = obj.TYPE_BRANCH
|
end.As = obj.ANOP
|
||||||
q1 = q
|
|
||||||
|
|
||||||
q = obj.Appendp(q, c.newprog)
|
// find the end of the function
|
||||||
q.As = AMOVD
|
var last *obj.Prog
|
||||||
q.From.Type = obj.TYPE_MEM
|
for last = end; last.Link != nil; last = last.Link {
|
||||||
q.From.Reg = REG_R1
|
}
|
||||||
q.From.Offset = 0 // Panic.argp
|
|
||||||
q.To.Type = obj.TYPE_REG
|
|
||||||
q.To.Reg = REG_R2
|
|
||||||
|
|
||||||
q = obj.Appendp(q, c.newprog)
|
// MOV panic_argp(R1), R2
|
||||||
|
mov := obj.Appendp(last, c.newprog)
|
||||||
|
mov.As = AMOVD
|
||||||
|
mov.From.Type = obj.TYPE_MEM
|
||||||
|
mov.From.Reg = REG_R1
|
||||||
|
mov.From.Offset = 0 // Panic.argp
|
||||||
|
mov.To.Type = obj.TYPE_REG
|
||||||
|
mov.To.Reg = REG_R2
|
||||||
|
|
||||||
|
// CBNZ branches to the MOV above
|
||||||
|
cbnz.Pcond = mov
|
||||||
|
|
||||||
|
// ADD $(autosize+8), SP, R3
|
||||||
|
q = obj.Appendp(mov, c.newprog)
|
||||||
q.As = AADD
|
q.As = AADD
|
||||||
q.From.Type = obj.TYPE_CONST
|
q.From.Type = obj.TYPE_CONST
|
||||||
q.From.Offset = int64(c.autosize) + 8
|
q.From.Offset = int64(c.autosize) + 8
|
||||||
@ -669,17 +681,20 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||||||
q.To.Type = obj.TYPE_REG
|
q.To.Type = obj.TYPE_REG
|
||||||
q.To.Reg = REG_R3
|
q.To.Reg = REG_R3
|
||||||
|
|
||||||
|
// CMP R2, R3
|
||||||
q = obj.Appendp(q, c.newprog)
|
q = obj.Appendp(q, c.newprog)
|
||||||
q.As = ACMP
|
q.As = ACMP
|
||||||
q.From.Type = obj.TYPE_REG
|
q.From.Type = obj.TYPE_REG
|
||||||
q.From.Reg = REG_R2
|
q.From.Reg = REG_R2
|
||||||
q.Reg = REG_R3
|
q.Reg = REG_R3
|
||||||
|
|
||||||
|
// BNE end
|
||||||
q = obj.Appendp(q, c.newprog)
|
q = obj.Appendp(q, c.newprog)
|
||||||
q.As = ABNE
|
q.As = ABNE
|
||||||
q.To.Type = obj.TYPE_BRANCH
|
q.To.Type = obj.TYPE_BRANCH
|
||||||
q2 = q
|
q.Pcond = end
|
||||||
|
|
||||||
|
// ADD $8, SP, R4
|
||||||
q = obj.Appendp(q, c.newprog)
|
q = obj.Appendp(q, c.newprog)
|
||||||
q.As = AADD
|
q.As = AADD
|
||||||
q.From.Type = obj.TYPE_CONST
|
q.From.Type = obj.TYPE_CONST
|
||||||
@ -688,6 +703,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||||||
q.To.Type = obj.TYPE_REG
|
q.To.Type = obj.TYPE_REG
|
||||||
q.To.Reg = REG_R4
|
q.To.Reg = REG_R4
|
||||||
|
|
||||||
|
// MOV R4, panic_argp(R1)
|
||||||
q = obj.Appendp(q, c.newprog)
|
q = obj.Appendp(q, c.newprog)
|
||||||
q.As = AMOVD
|
q.As = AMOVD
|
||||||
q.From.Type = obj.TYPE_REG
|
q.From.Type = obj.TYPE_REG
|
||||||
@ -696,11 +712,11 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||||||
q.To.Reg = REG_R1
|
q.To.Reg = REG_R1
|
||||||
q.To.Offset = 0 // Panic.argp
|
q.To.Offset = 0 // Panic.argp
|
||||||
|
|
||||||
|
// B end
|
||||||
q = obj.Appendp(q, c.newprog)
|
q = obj.Appendp(q, c.newprog)
|
||||||
|
q.As = AB
|
||||||
q.As = obj.ANOP
|
q.To.Type = obj.TYPE_BRANCH
|
||||||
q1.Pcond = q
|
q.Pcond = end
|
||||||
q2.Pcond = q
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case obj.ARET:
|
case obj.ARET:
|
||||||
|
Loading…
Reference in New Issue
Block a user