From 1f6e9e36b0aba3d2459c80b2c8e905d9cc57f7ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexandru=20Mo=C8=99oi?= Date: Tue, 1 Mar 2016 13:39:47 +0100 Subject: [PATCH] [dev.ssa] cmd/compile/internal/ssa: distribute multiplication into addition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 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 TryBot-Result: Gobot Gobot Reviewed-by: Keith Randall --- .../compile/internal/ssa/gen/generic.rules | 5 ++ .../compile/internal/ssa/rewritegeneric.go | 70 +++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/src/cmd/compile/internal/ssa/gen/generic.rules b/src/cmd/compile/internal/ssa/gen/generic.rules index ac243379205..11c7b9d7a19 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 [c])) && x.Op != OpConst16 -> (Xor16 (Const16 [c]) x) (Xor8 x (Const8 [c])) && x.Op != OpConst8 -> (Xor8 (Const8 [c]) x) +// Distribute multiplication c * (d+x) -> c*d + c*x. Useful for: +// a[i].b = ...; a[i+1].b = ... +(Mul64 (Const64 [c]) (Add64 (Const64 [d]) x)) -> (Add64 (Const64 [c*d]) (Mul64 (Const64 [c]) x)) +(Mul32 (Const32 [c]) (Add32 (Const32 [d]) x)) -> (Add32 (Const32 [c*d]) (Mul32 (Const32 [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 x (Const32 [c])) -> (Lsh64x64 x (Const64 [int64(uint32(c))])) diff --git a/src/cmd/compile/internal/ssa/rewritegeneric.go b/src/cmd/compile/internal/ssa/rewritegeneric.go index 4f29cf53481..0c71b2c8840 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 [c]) (Add32 (Const32 [d]) x)) + // cond: + // result: (Add32 (Const32 [c*d]) (Mul32 (Const32 [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 [c]) (Add64 (Const64 [d]) x)) + // cond: + // result: (Add64 (Const64 [c*d]) (Mul64 (Const64 [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])