diff options
| author | Alexandru Moșoi <mosoi@google.com> | 2016-03-01 13:39:47 +0100 |
|---|---|---|
| committer | Alexandru Moșoi <alexandru@mosoi.ro> | 2016-03-01 17:05:13 +0000 |
| commit | 1f6e9e36b0aba3d2459c80b2c8e905d9cc57f7ce (patch) | |
| tree | 2127472ddfa265d962071ef674205570bb6b631c /src | |
| parent | e96b232993fa8edb478f32041e08e5cf5c74395d (diff) | |
| download | go-1f6e9e36b0aba3d2459c80b2c8e905d9cc57f7ce.tar.xz | |
[dev.ssa] cmd/compile/internal/ssa: distribute multiplication into addition
* This is a very basic form of straight line strength reduction.
* Removes one multiplication from a[b].c++; a[b+1].c++
* It increases pressure on the register allocator because
CSE creates more copies of the multiplication sizeof(a[0])*b.
Change-Id: I686a18e9c24cc6f8bdfa925713afed034f7d36d0
Reviewed-on: https://go-review.googlesource.com/20091
Run-TryBot: Alexandru Moșoi <alexandru@mosoi.ro>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Diffstat (limited to 'src')
| -rw-r--r-- | src/cmd/compile/internal/ssa/gen/generic.rules | 5 | ||||
| -rw-r--r-- | src/cmd/compile/internal/ssa/rewritegeneric.go | 70 |
2 files changed, 75 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/ssa/gen/generic.rules b/src/cmd/compile/internal/ssa/gen/generic.rules index ac24337920..11c7b9d7a1 100644 --- a/src/cmd/compile/internal/ssa/gen/generic.rules +++ b/src/cmd/compile/internal/ssa/gen/generic.rules @@ -147,6 +147,11 @@ (Xor16 x (Const16 <t> [c])) && x.Op != OpConst16 -> (Xor16 (Const16 <t> [c]) x) (Xor8 x (Const8 <t> [c])) && x.Op != OpConst8 -> (Xor8 (Const8 <t> [c]) x) +// Distribute multiplication c * (d+x) -> c*d + c*x. Useful for: +// a[i].b = ...; a[i+1].b = ... +(Mul64 (Const64 <t> [c]) (Add64 <t> (Const64 <t> [d]) x)) -> (Add64 (Const64 <t> [c*d]) (Mul64 <t> (Const64 <t> [c]) x)) +(Mul32 (Const32 <t> [c]) (Add32 <t> (Const32 <t> [d]) x)) -> (Add32 (Const32 <t> [c*d]) (Mul32 <t> (Const32 <t> [c]) x)) + // rewrite shifts of 8/16/32 bit consts into 64 bit consts to reduce // the number of the other rewrite rules for const shifts (Lsh64x32 <t> x (Const32 [c])) -> (Lsh64x64 x (Const64 <t> [int64(uint32(c))])) diff --git a/src/cmd/compile/internal/ssa/rewritegeneric.go b/src/cmd/compile/internal/ssa/rewritegeneric.go index 4f29cf5348..0c71b2c884 100644 --- a/src/cmd/compile/internal/ssa/rewritegeneric.go +++ b/src/cmd/compile/internal/ssa/rewritegeneric.go @@ -4044,6 +4044,41 @@ func rewriteValuegeneric_OpMul32(v *Value, config *Config) bool { v.AddArg(x) return true } + // match: (Mul32 (Const32 <t> [c]) (Add32 <t> (Const32 <t> [d]) x)) + // cond: + // result: (Add32 (Const32 <t> [c*d]) (Mul32 <t> (Const32 <t> [c]) x)) + for { + if v.Args[0].Op != OpConst32 { + break + } + t := v.Args[0].Type + c := v.Args[0].AuxInt + if v.Args[1].Op != OpAdd32 { + break + } + if v.Args[1].Type != v.Args[0].Type { + break + } + if v.Args[1].Args[0].Op != OpConst32 { + break + } + if v.Args[1].Args[0].Type != v.Args[0].Type { + break + } + d := v.Args[1].Args[0].AuxInt + x := v.Args[1].Args[1] + v.reset(OpAdd32) + v0 := b.NewValue0(v.Line, OpConst32, t) + v0.AuxInt = c * d + v.AddArg(v0) + v1 := b.NewValue0(v.Line, OpMul32, t) + v2 := b.NewValue0(v.Line, OpConst32, t) + v2.AuxInt = c + v1.AddArg(v2) + v1.AddArg(x) + v.AddArg(v1) + return true + } // match: (Mul32 (Const32 [0]) _) // cond: // result: (Const32 [0]) @@ -4099,6 +4134,41 @@ func rewriteValuegeneric_OpMul64(v *Value, config *Config) bool { v.AddArg(x) return true } + // match: (Mul64 (Const64 <t> [c]) (Add64 <t> (Const64 <t> [d]) x)) + // cond: + // result: (Add64 (Const64 <t> [c*d]) (Mul64 <t> (Const64 <t> [c]) x)) + for { + if v.Args[0].Op != OpConst64 { + break + } + t := v.Args[0].Type + c := v.Args[0].AuxInt + if v.Args[1].Op != OpAdd64 { + break + } + if v.Args[1].Type != v.Args[0].Type { + break + } + if v.Args[1].Args[0].Op != OpConst64 { + break + } + if v.Args[1].Args[0].Type != v.Args[0].Type { + break + } + d := v.Args[1].Args[0].AuxInt + x := v.Args[1].Args[1] + v.reset(OpAdd64) + v0 := b.NewValue0(v.Line, OpConst64, t) + v0.AuxInt = c * d + v.AddArg(v0) + v1 := b.NewValue0(v.Line, OpMul64, t) + v2 := b.NewValue0(v.Line, OpConst64, t) + v2.AuxInt = c + v1.AddArg(v2) + v1.AddArg(x) + v.AddArg(v1) + return true + } // match: (Mul64 (Const64 [0]) _) // cond: // result: (Const64 [0]) |
