]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: refactor some code in loopbce.go
authorGiovanni Bajo <rasky@develer.com>
Mon, 16 Sep 2019 08:23:54 +0000 (10:23 +0200)
committerGiovanni Bajo <rasky@develer.com>
Thu, 26 Sep 2019 18:46:30 +0000 (18:46 +0000)
This CL extracts the logic for pattern-matching an induction
variable into a separate function, in preparation for next CL
where we would need to call it multiple times.

No functional changes, passes toolstash -cmp.

Change-Id: Ic52391e6c1b2e72bae32a0f3f65dfea321caaf4f
Reviewed-on: https://go-review.googlesource.com/c/go/+/195737
Reviewed-by: David Chase <drchase@google.com>
src/cmd/compile/internal/ssa/loopbce.go

index 092e7aa35ba36e7ff9eaef8a83a74f511e439c3f..2ce687822a04b961f586e8e87a9e5b6732523f6b 100644 (file)
@@ -29,6 +29,39 @@ type indVar struct {
        //      min <  ind <= max    [if flags == indVarMinExc|indVarMaxInc]
 }
 
+// parseIndVar checks whether the SSA value passed as argument is a valid induction
+// variable, and, if so, extracts:
+//   * the minimum bound
+//   * the increment value
+//   * the "next" value (SSA value that is Phi'd into the induction variable every loop)
+// Currently, we detect induction variables that match (Phi min nxt),
+// with nxt being (Add inc ind).
+// If it can't parse the induction variable correctly, it returns (nil, nil, nil).
+func parseIndVar(ind *Value) (min, inc, nxt *Value) {
+       if ind.Op != OpPhi {
+               return
+       }
+
+       if n := ind.Args[0]; n.Op == OpAdd64 && (n.Args[0] == ind || n.Args[1] == ind) {
+               min, nxt = ind.Args[1], n
+       } else if n := ind.Args[1]; n.Op == OpAdd64 && (n.Args[0] == ind || n.Args[1] == ind) {
+               min, nxt = ind.Args[0], n
+       } else {
+               // Not a recognized induction variable.
+               return
+       }
+
+       if nxt.Args[0] == ind { // nxt = ind + inc
+               inc = nxt.Args[1]
+       } else if nxt.Args[1] == ind { // nxt = inc + ind
+               inc = nxt.Args[0]
+       } else {
+               panic("unreachable") // one of the cases must be true from the above.
+       }
+
+       return
+}
+
 // findIndVar finds induction variables in a function.
 //
 // Look for variables and blocks that satisfy the following
@@ -85,31 +118,12 @@ func findIndVar(f *Func) []indVar {
                        less = false
                }
 
-               // Check that the induction variable is a phi that depends on itself.
-               if ind.Op != OpPhi {
+               // See if this is really an induction variable
+               min, inc, nxt := parseIndVar(ind)
+               if min == nil {
                        continue
                }
 
-               // Extract min and nxt knowing that nxt is an addition (e.g. Add64).
-               var min, nxt *Value // minimum, and next value
-               if n := ind.Args[0]; n.Op == OpAdd64 && (n.Args[0] == ind || n.Args[1] == ind) {
-                       min, nxt = ind.Args[1], n
-               } else if n := ind.Args[1]; n.Op == OpAdd64 && (n.Args[0] == ind || n.Args[1] == ind) {
-                       min, nxt = ind.Args[0], n
-               } else {
-                       // Not a recognized induction variable.
-                       continue
-               }
-
-               var inc *Value
-               if nxt.Args[0] == ind { // nxt = ind + inc
-                       inc = nxt.Args[1]
-               } else if nxt.Args[1] == ind { // nxt = inc + ind
-                       inc = nxt.Args[0]
-               } else {
-                       panic("unreachable") // one of the cases must be true from the above.
-               }
-
                // Expect the increment to be a nonzero constant.
                if inc.Op != OpConst64 {
                        continue