mirror of
https://github.com/golang/go
synced 2024-11-23 15:50:07 -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:
parent
fd5ba54f7c
commit
9740b60e14
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user