From: Alexandru Moșoi Date: Sun, 20 Mar 2016 21:15:27 +0000 (+0100) Subject: cmd/compile: fold IsInBounds with small index X-Git-Tag: go1.7beta1~1169 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=9549c06ce6e379de4554a911ffe8470af8d70daa;p=gostls13.git cmd/compile: fold IsInBounds with small index 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 Run-TryBot: Alexandru Moșoi TryBot-Result: Gobot Gobot --- diff --git a/src/cmd/compile/internal/ssa/gen/generic.rules b/src/cmd/compile/internal/ssa/gen/generic.rules index 8458619bf2..99fc75df6a 100644 --- a/src/cmd/compile/internal/ssa/gen/generic.rules +++ b/src/cmd/compile/internal/ssa/gen/generic.rules @@ -104,6 +104,12 @@ (Lsh16x16 (Rsh16Ux16 (Lsh16x16 x (Const16 [c1])) (Const16 [c2])) (Const16 [c3])) && c1 >= c2 && c3 >= c2 -> (Lsh16x16 x (Const16 [c1-c2+c3])) (Lsh8x8 (Rsh8Ux8 (Lsh8x8 x (Const8 [c1])) (Const8 [c2])) (Const8 [c3])) && c1 >= c2 && c3 >= c2 -> (Lsh8x8 x (Const8 [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]) diff --git a/src/cmd/compile/internal/ssa/rewritegeneric.go b/src/cmd/compile/internal/ssa/rewritegeneric.go index 9b304d8acf..ebc241ef63 100644 --- a/src/cmd/compile/internal/ssa/rewritegeneric.go +++ b/src/cmd/compile/internal/ssa/rewritegeneric.go @@ -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])