We use *24 a lot for pointer arithmetic when accessing slices
of slices ([][]T). Rewrite to use an LEA and a shift.
The shift will likely be free, as it often gets folded into
an indexed load/store.
Update #14606
Change-Id: Ie0bf6dc1093876efd57e88ce5f62c26a9bf21cec
Reviewed-on: https://go-review.googlesource.com/20567
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Todd Neal <todd@tneal.org>
(MULQconst [3] x) -> (LEAQ2 x x)
(MULQconst [5] x) -> (LEAQ4 x x)
(MULQconst [9] x) -> (LEAQ8 x x)
+(MULQconst [24] x) -> (SHLQconst [3] (LEAQ2 <v.Type> x x)) // Useful for [][]T accesses
(MULQconst [c] x) && isPowerOfTwo(c) -> (SHLQconst [log2(c)] x)
// combine add/shift into LEAQ
v.AddArg(x)
return true
}
+ // match: (MULQconst [24] x)
+ // cond:
+ // result: (SHLQconst [3] (LEAQ2 <v.Type> x x))
+ for {
+ if v.AuxInt != 24 {
+ break
+ }
+ x := v.Args[0]
+ v.reset(OpAMD64SHLQconst)
+ v.AuxInt = 3
+ v0 := b.NewValue0(v.Line, OpAMD64LEAQ2, v.Type)
+ v0.AddArg(x)
+ v0.AddArg(x)
+ v.AddArg(v0)
+ return true
+ }
// match: (MULQconst [c] x)
// cond: isPowerOfTwo(c)
// result: (SHLQconst [log2(c)] x)