diff options
author | Giovanni Bajo <rasky@develer.com> | 2019-09-16 10:23:54 +0200 |
---|---|---|
committer | Giovanni Bajo <rasky@develer.com> | 2019-09-26 18:46:30 +0000 |
commit | 9740b60e140433c6ab2230ca4f53935818221445 (patch) | |
tree | b6208b4dce21da40d5f588f554976b77665db04c | |
parent | fd5ba54f7cb7e4f1b74901b1cf120120adc3b633 (diff) | |
download | go-9740b60e140433c6ab2230ca4f53935818221445.tar.gz go-9740b60e140433c6ab2230ca4f53935818221445.zip |
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 <drchase@google.com>
-rw-r--r-- | src/cmd/compile/internal/ssa/loopbce.go | 58 |
1 files changed, 36 insertions, 22 deletions
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 |