func f() int {
var x [4]int
for i := 0; i < 4; i++ {
x[i] = 5
}
return x[3]
}
The compiler generates code like this:
0x0021 00033 (tmp1.go:6) SHLQ $3, AX
0x0025 00037 (ttmp1.go:6) MOVQ $5, "".x(SP)(AX*1)
We can use the (AX*8) indexing mode and get rid of the shift.
There is already code to do this in the compiler. However, it doesn't fire in this case, as the shift amount is in the "wrong" arugment slot.
The SSA representation is (MOVQstoreconstidx1 [5] (SHLQconst [3] v) x y). Normally these rules are written to expect the pointer first, then the shifted index, so it does not fire in this case (shifted index first, then pointer).
We should mark ops like these as commutative on the first two args, so the rewrite engine will detect this correctly. There is even a comment in the rule file:
// TODO: mark the MOVXstoreidx1 ops as commutative. Generates too many rewrite rules at the moment.
I think our rewrite engine now handles commutative ops more efficiently, so possibly not an issue anymore. Investigate, and do it.
The compiler generates code like this:
We can use the
(AX*8)indexing mode and get rid of the shift.There is already code to do this in the compiler. However, it doesn't fire in this case, as the shift amount is in the "wrong" arugment slot.
The SSA representation is (MOVQstoreconstidx1 [5] (SHLQconst [3] v) x y). Normally these rules are written to expect the pointer first, then the shifted index, so it does not fire in this case (shifted index first, then pointer).
We should mark ops like these as commutative on the first two args, so the rewrite engine will detect this correctly. There is even a comment in the rule file:
I think our rewrite engine now handles commutative ops more efficiently, so possibly not an issue anymore. Investigate, and do it.