]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: fold IsInBounds with small index
authorAlexandru Moșoi <mosoi@google.com>
Sun, 20 Mar 2016 21:15:27 +0000 (22:15 +0100)
committerAlexandru Moșoi <alexandru@mosoi.ro>
Mon, 21 Mar 2016 23:15:25 +0000 (23:15 +0000)
For the following example, but there are a few more in the stdlib:
func histogram(b []byte, h *[256]int32) {
        for _, t := range b {
                h[t]++
        }
}

Change-Id: I56615f341ae52e02ef34025588dc6d1c52122295
Reviewed-on: https://go-review.googlesource.com/20924
Reviewed-by: Keith Randall <khr@golang.org>
Run-TryBot: Alexandru Moșoi <alexandru@mosoi.ro>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/cmd/compile/internal/ssa/gen/generic.rules
src/cmd/compile/internal/ssa/rewritegeneric.go

index 8458619bf2c16b2ce1faf0cb3642f8230307235c..99fc75df6a43667bd4be4d3c8dc4baa929cdc426 100644 (file)
 (Lsh16x16 (Rsh16Ux16 (Lsh16x16 x (Const16 [c1])) (Const16 [c2])) (Const16 [c3])) && c1 >= c2 && c3 >= c2 ->  (Lsh16x16 x (Const16 <config.fe.TypeUInt16()> [c1-c2+c3]))
 (Lsh8x8 (Rsh8Ux8 (Lsh8x8 x (Const8 [c1])) (Const8 [c2])) (Const8 [c3])) && c1 >= c2 && c3 >= c2 ->  (Lsh8x8 x (Const8 <config.fe.TypeUInt8()> [c1-c2+c3]))
 
+// Fold IsInBounds when the range of the index cannot exceed the limt.
+(IsInBounds (ZeroExt8to32 _) (Const32 [c])) && (1 << 8) <= int32(c) -> (ConstBool [1])
+(IsInBounds (ZeroExt8to64 _) (Const64 [c])) && (1 << 8) <= c -> (ConstBool [1])
+(IsInBounds (ZeroExt16to32 _) (Const32 [c])) && (1 << 16) <= int32(c) -> (ConstBool [1])
+(IsInBounds (ZeroExt16to64 _) (Const64 [c])) && (1 << 16) <= c -> (ConstBool [1])
+
 (IsInBounds x x) -> (ConstBool [0])
 (IsInBounds (And32 (Const32 [c]) _) (Const32 [d])) && inBounds32(c, d) -> (ConstBool [1])
 (IsInBounds (And64 (Const64 [c]) _) (Const64 [d])) && inBounds64(c, d) -> (ConstBool [1])
index 9b304d8acf67a71a4304062255bef780e96197b7..ebc241ef63dd9417ac29894a5ec4d1a0c31ec97f 100644 (file)
@@ -2602,6 +2602,78 @@ func rewriteValuegeneric_OpITab(v *Value, config *Config) bool {
 func rewriteValuegeneric_OpIsInBounds(v *Value, config *Config) bool {
        b := v.Block
        _ = b
+       // match: (IsInBounds (ZeroExt8to32 _) (Const32 [c]))
+       // cond: (1 << 8) <= int32(c)
+       // result: (ConstBool [1])
+       for {
+               if v.Args[0].Op != OpZeroExt8to32 {
+                       break
+               }
+               if v.Args[1].Op != OpConst32 {
+                       break
+               }
+               c := v.Args[1].AuxInt
+               if !((1 << 8) <= int32(c)) {
+                       break
+               }
+               v.reset(OpConstBool)
+               v.AuxInt = 1
+               return true
+       }
+       // match: (IsInBounds (ZeroExt8to64 _) (Const64 [c]))
+       // cond: (1 << 8) <= c
+       // result: (ConstBool [1])
+       for {
+               if v.Args[0].Op != OpZeroExt8to64 {
+                       break
+               }
+               if v.Args[1].Op != OpConst64 {
+                       break
+               }
+               c := v.Args[1].AuxInt
+               if !((1 << 8) <= c) {
+                       break
+               }
+               v.reset(OpConstBool)
+               v.AuxInt = 1
+               return true
+       }
+       // match: (IsInBounds (ZeroExt16to32 _) (Const32 [c]))
+       // cond: (1 << 16) <= int32(c)
+       // result: (ConstBool [1])
+       for {
+               if v.Args[0].Op != OpZeroExt16to32 {
+                       break
+               }
+               if v.Args[1].Op != OpConst32 {
+                       break
+               }
+               c := v.Args[1].AuxInt
+               if !((1 << 16) <= int32(c)) {
+                       break
+               }
+               v.reset(OpConstBool)
+               v.AuxInt = 1
+               return true
+       }
+       // match: (IsInBounds (ZeroExt16to64 _) (Const64 [c]))
+       // cond: (1 << 16) <= c
+       // result: (ConstBool [1])
+       for {
+               if v.Args[0].Op != OpZeroExt16to64 {
+                       break
+               }
+               if v.Args[1].Op != OpConst64 {
+                       break
+               }
+               c := v.Args[1].AuxInt
+               if !((1 << 16) <= c) {
+                       break
+               }
+               v.reset(OpConstBool)
+               v.AuxInt = 1
+               return true
+       }
        // match: (IsInBounds x x)
        // cond:
        // result: (ConstBool [0])