mirror of
https://github.com/golang/go
synced 2024-11-23 20:40: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]
|
// 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.
|
// findIndVar finds induction variables in a function.
|
||||||
//
|
//
|
||||||
// Look for variables and blocks that satisfy the following
|
// Look for variables and blocks that satisfy the following
|
||||||
@ -85,31 +118,12 @@ func findIndVar(f *Func) []indVar {
|
|||||||
less = false
|
less = false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that the induction variable is a phi that depends on itself.
|
// See if this is really an induction variable
|
||||||
if ind.Op != OpPhi {
|
min, inc, nxt := parseIndVar(ind)
|
||||||
|
if min == nil {
|
||||||
continue
|
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.
|
// Expect the increment to be a nonzero constant.
|
||||||
if inc.Op != OpConst64 {
|
if inc.Op != OpConst64 {
|
||||||
continue
|
continue
|
||||||
|
Loading…
Reference in New Issue
Block a user