aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiovanni Bajo <rasky@develer.com>2019-09-16 10:23:54 +0200
committerGiovanni Bajo <rasky@develer.com>2019-09-26 18:46:30 +0000
commit9740b60e140433c6ab2230ca4f53935818221445 (patch)
treeb6208b4dce21da40d5f588f554976b77665db04c
parentfd5ba54f7cb7e4f1b74901b1cf120120adc3b633 (diff)
downloadgo-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.go58
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