1
0
mirror of https://github.com/golang/go synced 2024-11-23 18:50:05 -07:00

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>
This commit is contained in:
Giovanni Bajo 2019-09-16 10:23:54 +02:00
parent fd5ba54f7c
commit 9740b60e14

View 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