]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.ssa] cmd/compile/internal/ssa: distribute multiplication into addition
authorAlexandru Moșoi <mosoi@google.com>
Tue, 1 Mar 2016 12:39:47 +0000 (13:39 +0100)
committerAlexandru Moșoi <alexandru@mosoi.ro>
Tue, 1 Mar 2016 17:05:13 +0000 (17:05 +0000)
* 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>
src/cmd/compile/internal/ssa/gen/generic.rules
src/cmd/compile/internal/ssa/rewritegeneric.go

index ac243379205458bb7e4e60ae77941fb55ba8322a..11c7b9d7a19cee86dd64c3485ccfba2e1a8a06dd 100644 (file)
 (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))]))
index 4f29cf53481a8416e5118ced599bd97211996b20..0c71b2c8840319d127144537070d0092ec1cffb5 100644 (file)
@@ -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])