diff options
author | Keith Randall <khr@google.com> | 2018-01-03 14:38:55 -0800 |
---|---|---|
committer | Keith Randall <khr@golang.org> | 2018-02-26 23:49:44 +0000 |
commit | 4b00d3f4a2d1379377a0f2312564ae405b946d65 (patch) | |
tree | 47f957045026cb93fff0ef2a2c893245f4a9f767 /src/cmd/compile/internal/ssa/func.go | |
parent | 30673769ed7409da0ba1046e874371bf4f07d352 (diff) | |
download | go-4b00d3f4a2d1379377a0f2312564ae405b946d65.tar.gz go-4b00d3f4a2d1379377a0f2312564ae405b946d65.zip |
cmd/compile: implement comparisons directly with memory
Allow the compiler to generate code like CMPQ 16(AX), $7
It's tricky because it's difficult to spill such a comparison during
flagalloc, because the same memory state might not be available at
the restore locations.
Solve this problem by decomposing the compare+load back into its parts
if it needs to be spilled.
The big win is that the write barrier test goes from:
MOVL runtime.writeBarrier(SB), CX
TESTL CX, CX
JNE 60
to
CMPL runtime.writeBarrier(SB), $0
JNE 59
It's one instruction and one byte smaller.
Fixes #19485
Fixes #15245
Update #22460
Binaries are about 0.15% smaller.
Change-Id: I4fd8d1111b6b9924d52f9a0901ca1b2e5cce0836
Reviewed-on: https://go-review.googlesource.com/86035
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Reviewed-by: Ilya Tocar <ilya.tocar@intel.com>
Diffstat (limited to 'src/cmd/compile/internal/ssa/func.go')
-rw-r--r-- | src/cmd/compile/internal/ssa/func.go | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/ssa/func.go b/src/cmd/compile/internal/ssa/func.go index 62550df0cc..7e8f68bf87 100644 --- a/src/cmd/compile/internal/ssa/func.go +++ b/src/cmd/compile/internal/ssa/func.go @@ -350,6 +350,19 @@ func (b *Block) NewValue2I(pos src.XPos, op Op, t *types.Type, auxint int64, arg return v } +// NewValue2IA returns a new value in the block with two arguments and both an auxint and aux values. +func (b *Block) NewValue2IA(pos src.XPos, op Op, t *types.Type, auxint int64, aux interface{}, arg0, arg1 *Value) *Value { + v := b.Func.newValue(op, t, b, pos) + v.AuxInt = auxint + v.Aux = aux + v.Args = v.argstorage[:2] + v.argstorage[0] = arg0 + v.argstorage[1] = arg1 + arg0.Uses++ + arg1.Uses++ + return v +} + // NewValue3 returns a new value in the block with three arguments and zero aux values. func (b *Block) NewValue3(pos src.XPos, op Op, t *types.Type, arg0, arg1, arg2 *Value) *Value { v := b.Func.newValue(op, t, b, pos) |