Commit 9916feed authored by Ilya Tocar's avatar Ilya Tocar

cmd/compile/internal/ssa: don't spill register offsets on amd64

Transform (ADDQconst SP) into (LEA SP), because lea is rematerializeable,
so this avoids register spill. We can't mark ADDQconst as rematerializeable,
because it clobbers flags. This makes go binary ~2kb smaller.

For reference here is generated code for function from bug report.
Before:
        CALL    "".g(SB)
        MOVBLZX (SP), AX
        LEAQ    8(SP), DI
        TESTB   AX, AX
        JEQ     15
        MOVQ    "".p(SP), SI
        DUFFCOPY        $196
        MOVQ    $0, (SP)
        PCDATA  $0, $1
        CALL    "".h(SB)
        RET
        MOVQ    DI, ""..autotmp_2-8(SP) // extra spill
        PCDATA  $0, $2
        CALL    "".g(SB)
        MOVQ    ""..autotmp_2-8(SP), DI // extra register fill
        MOVQ    "".p(SP), SI
        DUFFCOPY        $196
        MOVQ    $1, (SP)
        PCDATA  $0, $1
        CALL    "".h(SB)
        JMP     14
        END

After:
        CALL    "".g(SB)
        MOVBLZX (SP), AX
        TESTB   AX, AX
        JEQ     15
        LEAQ    8(SP), DI
        MOVQ    "".p(SP), SI
        DUFFCOPY        $196
        MOVQ    $0, (SP)
        PCDATA  $0, $1
        CALL    "".h(SB)
        RET
        PCDATA  $0, $0  // no spill
        CALL    "".g(SB)
        LEAQ    8(SP), DI // rematerialized instead
        MOVQ    "".p(SP), SI
        DUFFCOPY        $196
        MOVQ    $1, (SP)
        PCDATA  $0, $1
        CALL    "".h(SB)
        JMP     14
        END

Fixes #22947

Change-Id: I8f33b860dc6c8828373477171b172ca2ce30074f
Reviewed-on: https://go-review.googlesource.com/81815
Run-TryBot: Ilya Tocar <ilya.tocar@intel.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: 's avatarKeith Randall <khr@golang.org>
parent de4edf3d
......@@ -2662,3 +2662,7 @@
(MOVLf2i <t> (Arg [off] {sym})) -> @b.Func.Entry (Arg <t> [off] {sym})
(MOVQi2f <t> (Arg [off] {sym})) -> @b.Func.Entry (Arg <t> [off] {sym})
(MOVLi2f <t> (Arg [off] {sym})) -> @b.Func.Entry (Arg <t> [off] {sym})
// LEAQ is rematerializeable, so this helps to avoid register spill.
// See isuue 22947 for details
(ADDQconst [off] x:(SP)) -> (LEAQ [off] x)
......@@ -2054,6 +2054,20 @@ func rewriteValueAMD64_OpAMD64ADDQconst_0(v *Value) bool {
v.AddArg(x)
return true
}
// match: (ADDQconst [off] x:(SP))
// cond:
// result: (LEAQ [off] x)
for {
off := v.AuxInt
x := v.Args[0]
if x.Op != OpSP {
break
}
v.reset(OpAMD64LEAQ)
v.AuxInt = off
v.AddArg(x)
return true
}
return false
}
func rewriteValueAMD64_OpAMD64ADDQconstmem_0(v *Value) bool {
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment