]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile/internal/ssa: simplify nil checks in opt.
authorAlexandru Moșoi <mosoi@google.com>
Mon, 7 Mar 2016 18:29:15 +0000 (19:29 +0100)
committerAlexandru Moșoi <alexandru@mosoi.ro>
Tue, 8 Mar 2016 22:17:47 +0000 (22:17 +0000)
* Simplify the nilcheck generated by
for _, e := range a {}
* No effect on the generated code because these nil checks
don't end up in the generated code.
* Useful for other analysis, e.g. it'll remove one dependecy
on the induction variable.

Change-Id: I6ee66ddfdc010ae22aea8dca48163303d93de7a9
Reviewed-on: https://go-review.googlesource.com/20307
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 994e880bc6972d4190c0bb75d48716991cc0c483..57ab70339a7449dc9dc2ae933df8e78638a7e892 100644 (file)
 // succ* fields must be variables
 // For now, the generated successors must be a permutation of the matched successors.
 
+// Simplify nil checks.
+// These are inserted by for _, e := range a {}
+(NilCheck (Phi x (Add64 (Const64 [c]) y)) mem) && c > 0 && v.Args[0] == y -> (NilCheck x mem)
+
 // constant folding
 (Trunc16to8 (Const16 [c])) -> (Const8 [int64(int8(c))])
 (Trunc32to8 (Const32 [c])) -> (Const8 [int64(int8(c))])
index 79dcf9a716e10710f8338198e6f98a6f80c23430..cde60c1bcd288d329d901f74c7d04258aff9165c 100644 (file)
@@ -206,6 +206,8 @@ func rewriteValuegeneric(v *Value, config *Config) bool {
                return rewriteValuegeneric_OpNeqPtr(v, config)
        case OpNeqSlice:
                return rewriteValuegeneric_OpNeqSlice(v, config)
+       case OpNilCheck:
+               return rewriteValuegeneric_OpNilCheck(v, config)
        case OpOffPtr:
                return rewriteValuegeneric_OpOffPtr(v, config)
        case OpOr16:
@@ -4823,6 +4825,39 @@ func rewriteValuegeneric_OpNeqSlice(v *Value, config *Config) bool {
        }
        return false
 }
+func rewriteValuegeneric_OpNilCheck(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (NilCheck (Phi x (Add64 (Const64 [c]) y)) mem)
+       // cond: c > 0 && v.Args[0] == y
+       // result: (NilCheck x mem)
+       for {
+               if v.Args[0].Op != OpPhi {
+                       break
+               }
+               x := v.Args[0].Args[0]
+               if v.Args[0].Args[1].Op != OpAdd64 {
+                       break
+               }
+               if v.Args[0].Args[1].Args[0].Op != OpConst64 {
+                       break
+               }
+               c := v.Args[0].Args[1].Args[0].AuxInt
+               y := v.Args[0].Args[1].Args[1]
+               if len(v.Args[0].Args) != 2 {
+                       break
+               }
+               mem := v.Args[1]
+               if !(c > 0 && v.Args[0] == y) {
+                       break
+               }
+               v.reset(OpNilCheck)
+               v.AddArg(x)
+               v.AddArg(mem)
+               return true
+       }
+       return false
+}
 func rewriteValuegeneric_OpOffPtr(v *Value, config *Config) bool {
        b := v.Block
        _ = b