type indVarFlags … const indVarMinExc … const indVarMaxInc … const indVarCountDown … type indVar … // 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) { … } // findIndVar finds induction variables in a function. // // Look for variables and blocks that satisfy the following // // loop: // ind = (Phi min nxt), // if ind < max // then goto enter_loop // else goto exit_loop // // enter_loop: // do something // nxt = inc + ind // goto loop // // exit_loop: func findIndVar(f *Func) []indVar { … } // addWillOverflow reports whether x+y would result in a value more than maxint. func addWillOverflow(x, y int64) bool { … } // subWillUnderflow reports whether x-y would result in a value less than minint. func subWillUnderflow(x, y int64) bool { … } // diff returns x-y as a uint64. Requires x>=y. func diff(x, y int64) uint64 { … } // addU returns x+y. Requires that x+y does not overflow an int64. func addU(x int64, y uint64) int64 { … } // subU returns x-y. Requires that x-y does not underflow an int64. func subU(x int64, y uint64) int64 { … } // if v is known to be x - c, where x is known to be nonnegative and c is a // constant, return x, c. Otherwise return nil, 0. func findKNN(v *Value) (*Value, int64) { … } func printIndVar(b *Block, i, min, max *Value, inc int64, flags indVarFlags) { … } func minSignedValue(t *types.Type) int64 { … } func maxSignedValue(t *types.Type) int64 { … }