From: Giovanni Bajo Date: Mon, 16 Sep 2019 08:23:54 +0000 (+0200) Subject: cmd/compile: refactor some code in loopbce.go X-Git-Tag: go1.14beta1~949 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=9740b60e140433c6ab2230ca4f53935818221445;p=gostls13.git cmd/compile: refactor some code in loopbce.go 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 --- diff --git a/src/cmd/compile/internal/ssa/loopbce.go b/src/cmd/compile/internal/ssa/loopbce.go index 092e7aa35b..2ce687822a 100644 --- a/src/cmd/compile/internal/ssa/loopbce.go +++ b/src/cmd/compile/internal/ssa/loopbce.go @@ -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