// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package ssacompile

import (
	"fmt"

	"cmd/compile/internal/base"
	"cmd/compile/internal/ssa"
	"cmd/compile/internal/ssa/block"
	"cmd/compile/internal/ssa/ssaop"
	"cmd/compile/internal/types"
)

type indVarFlags uint8

const (
	indVarMinExc indVarFlags = 1 << iota // minimum value is exclusive (default: inclusive)
	indVarMaxInc                         // maximum value is inclusive (default: exclusive)
)

type indVar struct {
	ind   *ssa.Value // induction variable
	nxt   *ssa.Value // the incremented variable
	min   *ssa.Value // minimum value, inclusive/exclusive depends on flags
	max   *ssa.Value // maximum value, inclusive/exclusive depends on flags
	entry *ssa.Block // the block where the edge from the succeeded comparison of the induction variable goes to, means when the bound check has passed.
	step  int64      // it will always be positive.
	flags indVarFlags
	// Invariant: for all blocks dominated by entry:
	//	min <= ind <  max    [if flags == 0]
	//	min <  ind <  max    [if flags == indVarMinExc]
	//	min <= ind <= max    [if flags == 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)
//   - the header's edge returning from the body
//
// 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 *ssa.Value) (min, inc, nxt *ssa.Value, loopReturn ssa.Edge) {
	if ind.Op != ssaop.OpPhi {
		return
	}

	if n := ind.Args[0]; (n.Op == ssaop.OpAdd64 || n.Op == ssaop.OpAdd32 || n.Op == ssaop.OpAdd16 || n.Op == ssaop.OpAdd8) && (n.Args[0] == ind || n.Args[1] == ind) {
		min, nxt, loopReturn = ind.Args[1], n, ind.Block.Preds[0]
	} else if n := ind.Args[1]; (n.Op == ssaop.OpAdd64 || n.Op == ssaop.OpAdd32 || n.Op == ssaop.OpAdd16 || n.Op == ssaop.OpAdd8) && (n.Args[0] == ind || n.Args[1] == ind) {
		min, nxt, loopReturn = ind.Args[0], n, ind.Block.Preds[1]
	} 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
//
//	 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:
//
// We may have more than one induction variables, the loop in the go
// source code may looks like this:
//
//	for i >= 0 && j >= 0 {
//		// use i and j
//		i--
//		j--
//	}
//
// So, also look for variables and blocks that satisfy the following
//
//	loop:
//	  i = (Phi maxi nxti)
//	  j = (Phi maxj nxtj)
//	  if i >= mini
//	    then goto check_j
//	    else goto exit_loop
//
//	check_j:
//	  if j >= minj
//	    then goto enter_loop
//	    else goto exit_loop
//
//	enter_loop:
//	  do something
//	  nxti = i - di
//	  nxtj = j - dj
//	  goto loop
//
//	exit_loop:
func findIndVar(f *ssa.Func) []indVar {
	var iv []indVar
	sdom := f.Sdom()

nextblock:
	for _, b := range f.Blocks {
		if b.Kind != block.BlockIf {
			continue
		}
		c := b.Controls[0]
		for idx := range 2 {
			// Check that the control if it either ind </<= limit or limit </<= ind.
			// TODO: Handle unsigned comparisons?
			inclusive := false
			switch c.Op {
			case ssaop.OpLeq64, ssaop.OpLeq32, ssaop.OpLeq16, ssaop.OpLeq8:
				inclusive = true
			case ssaop.OpLess64, ssaop.OpLess32, ssaop.OpLess16, ssaop.OpLess8:
			default:
				continue nextblock
			}

			less := idx == 0
			// induction variable, ending value
			ind, limit := c.Args[idx], c.Args[1-idx]
			// starting value, increment value, next value, loop return edge
			init, inc, nxt, loopReturn := parseIndVar(ind)
			if init == nil {
				continue // this is not an induction variable
			}

			// This is ind.Block.Preds, not b.Preds. That's a restriction on the loop header,
			// not the comparison block.
			if len(ind.Block.Preds) != 2 {
				continue
			}

			// Expect the increment to be a nonzero constant.
			if !inc.IsGenericIntConst() {
				continue
			}
			step := inc.AuxInt
			if step == 0 {
				continue
			}
			// step == minInt64 cannot be safely negated below, because -step
			// overflows back to minInt64. The later underflow checks need a
			// positive magnitude, so reject this case here.
			if step == minSignedValue(ind.Type) {
				continue
			}

			// startBody is the edge that eventually returns to the loop header.
			var startBody ssa.Edge
			switch {
			case sdom.IsAncestorEq(b.Succs[0].B, loopReturn.B):
				startBody = b.Succs[0]
			case sdom.IsAncestorEq(b.Succs[1].B, loopReturn.B):
				// if x { goto exit } else { goto entry } is identical to if !x { goto entry } else { goto exit }
				startBody = b.Succs[1]
				less = !less
				inclusive = !inclusive
			default:
				continue
			}

			// Increment sign must match comparison direction.
			// When incrementing, the termination comparison must be ind </<= limit.
			// When decrementing, the termination comparison must be ind >/>= limit.
			// See issue 26116.
			if step > 0 && !less {
				continue
			}
			if step < 0 && less {
				continue
			}

			// Up to now we extracted the induction variable (ind),
			// the increment delta (inc), the temporary sum (nxt),
			// the initial value (init) and the limiting value (limit).
			//
			// We also know that ind has the form (Phi init nxt) where
			// nxt is (Add inc nxt) which means: 1) inc dominates nxt
			// and 2) there is a loop starting at inc and containing nxt.
			//
			// We need to prove that the induction variable is incremented
			// only when it's smaller than the limiting value.
			// Two conditions must happen listed below to accept ind
			// as an induction variable.

			// First condition: the entry block has a single predecessor.
			// The entry now means the in-loop edge where the induction variable
			// comparison succeeded. Its predecessor is not necessarily the header
			// block. This implies that b.Succs[0] is reached iff ind < limit.
			if len(startBody.B.Preds) != 1 {
				// the other successor must exit the loop.
				continue
			}

			// Second condition: startBody.b dominates nxt so that
			// nxt is computed when inc < limit.
			if !sdom.IsAncestorEq(startBody.B, nxt.Block) {
				// inc+ind can only be reached through the branch that confirmed the
				// induction variable is in bounds.
				continue
			}

			// Check for overflow/underflow. We need to make sure that inc never causes
			// the induction variable to wrap around.
			// We use a function wrapper here for easy return true / return false / keep going logic.
			// This function returns true if the increment will never overflow/underflow.
			ok := func() bool {
				if step > 0 {
					if limit.IsGenericIntConst() {
						// Figure out the actual largest value.
						v := limit.AuxInt
						if !inclusive {
							if v == minSignedValue(limit.Type) {
								return false // < minint is never satisfiable.
							}
							v--
						}
						if init.IsGenericIntConst() {
							// Use stride to compute a better lower limit.
							if init.AuxInt > v {
								return false
							}
							// TODO(1.27): investigate passing a smaller-magnitude overflow limit to addU
							// for addWillOverflow.
							v = addU(init.AuxInt, diff(v, init.AuxInt)/uint64(step)*uint64(step))
						}
						if addWillOverflow(v, step, maxSignedValue(ind.Type)) {
							return false
						}
						if inclusive && v != limit.AuxInt || !inclusive && v+1 != limit.AuxInt {
							// We know a better limit than the programmer did. Use our limit instead.
							limit = f.ConstVal(limit.Op, limit.Type, v, true)
							inclusive = true
						}
						return true
					}
					if step == 1 && !inclusive {
						// Can't overflow because maxint is never a possible value.
						return true
					}
					// If the limit is not a constant, check to see if it is a
					// negative offset from a known non-negative value.
					knn, k := findKNN(limit)
					if knn == nil || k < 0 {
						return false
					}
					// limit == (something nonnegative) - k. That subtraction can't underflow, so
					// we can trust it.
					if inclusive {
						// ind <= knn - k cannot overflow if step is at most k
						return step <= k
					}
					// ind < knn - k cannot overflow if step is at most k+1
					return step <= k+1 && k != maxSignedValue(limit.Type)

					// TODO: other unrolling idioms
					// for i := 0; i < KNN - KNN % k ; i += k
					// for i := 0; i < KNN&^(k-1) ; i += k // k a power of 2
					// for i := 0; i < KNN&(-k) ; i += k // k a power of 2
				} else { // step < 0
					if limit.IsGenericIntConst() {
						// Figure out the actual smallest value.
						v := limit.AuxInt
						if !inclusive {
							if v == maxSignedValue(limit.Type) {
								return false // > maxint is never satisfiable.
							}
							v++
						}
						if init.IsGenericIntConst() {
							// Use stride to compute a better lower limit.
							if init.AuxInt < v {
								return false
							}
							// TODO(1.27): investigate passing a smaller-magnitude underflow limit to subU
							// for subWillUnderflow.
							v = subU(init.AuxInt, diff(init.AuxInt, v)/uint64(-step)*uint64(-step))
						}
						if subWillUnderflow(v, -step, minSignedValue(ind.Type)) {
							return false
						}
						if inclusive && v != limit.AuxInt || !inclusive && v-1 != limit.AuxInt {
							// We know a better limit than the programmer did. Use our limit instead.
							limit = f.ConstVal(limit.Op, limit.Type, v, true)
							inclusive = true
						}
						return true
					}
					if step == -1 && !inclusive {
						// Can't underflow because minint is never a possible value.
						return true
					}
				}
				return false
			}

			if ok() {
				flags := indVarFlags(0)
				var min, max *ssa.Value
				if step > 0 {
					min = init
					max = limit
					if inclusive {
						flags |= indVarMaxInc
					}
				} else {
					min = limit
					max = init
					flags |= indVarMaxInc
					if !inclusive {
						flags |= indVarMinExc
					}
					step = -step
				}
				if f.Pass.Debug >= 1 {
					printIndVar(b, ind, min, max, step, flags)
				}

				iv = append(iv, indVar{
					ind: ind,
					nxt: nxt,
					min: min,
					max: max,
					// This is startBody.b, where startBody is the edge from the comparison for the
					// induction variable, not necessarily the in-loop edge from the loop header.
					// Induction variable bounds are not valid in the loop before this edge.
					entry: startBody.B,
					step:  step,
					flags: flags,
				})
				b.Logf("found induction variable %v (inc = %v, min = %v, max = %v)\n", ind, inc, min, max)
			}
		}
	}

	return iv
}

// subWillUnderflow checks if x - y underflows the min value.
// y must be positive.
func subWillUnderflow(x, y int64, min int64) bool {
	if y < 0 {
		base.Fatalf("expecting positive value")
	}
	return x < min+y
}

// addWillOverflow checks if x + y overflows the max value.
// y must be positive.
func addWillOverflow(x, y int64, max int64) bool {
	if y < 0 {
		base.Fatalf("expecting positive value")
	}
	return x > max-y
}

// diff returns x-y as a uint64. Requires x>=y.
func diff(x, y int64) uint64 {
	if x < y {
		base.Fatalf("diff %d - %d underflowed", x, y)
	}
	return uint64(x - y)
}

// addU returns x+y. Requires that x+y does not overflow an int64.
func addU(x int64, y uint64) int64 {
	if y >= 1<<63 {
		if x >= 0 {
			base.Fatalf("addU overflowed %d + %d", x, y)
		}
		x += 1<<63 - 1
		x += 1
		y -= 1 << 63
	}
	// TODO(1.27): investigate passing a smaller-magnitude overflow limit in here.
	if addWillOverflow(x, int64(y), maxSignedValue(types.Types[types.TINT64])) {
		base.Fatalf("addU overflowed %d + %d", x, y)
	}
	return x + int64(y)
}

// subU returns x-y. Requires that x-y does not underflow an int64.
func subU(x int64, y uint64) int64 {
	if y >= 1<<63 {
		if x < 0 {
			base.Fatalf("subU underflowed %d - %d", x, y)
		}
		x -= 1<<63 - 1
		x -= 1
		y -= 1 << 63
	}
	// TODO(1.27): investigate passing a smaller-magnitude underflow limit in here.
	if subWillUnderflow(x, int64(y), minSignedValue(types.Types[types.TINT64])) {
		base.Fatalf("subU underflowed %d - %d", x, y)
	}
	return x - int64(y)
}

// 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 *ssa.Value) (*ssa.Value, int64) {
	var x, y *ssa.Value
	x = v
	switch v.Op {
	case ssaop.OpSub64, ssaop.OpSub32, ssaop.OpSub16, ssaop.OpSub8:
		x = v.Args[0]
		y = v.Args[1]

	case ssaop.OpAdd64, ssaop.OpAdd32, ssaop.OpAdd16, ssaop.OpAdd8:
		x = v.Args[0]
		y = v.Args[1]
		if x.IsGenericIntConst() {
			x, y = y, x
		}
	}
	switch x.Op {
	case ssaop.OpSliceLen, ssaop.OpStringLen, ssaop.OpSliceCap:
	default:
		return nil, 0
	}
	if y == nil {
		return x, 0
	}
	if !y.IsGenericIntConst() {
		return nil, 0
	}
	if v.Op == ssaop.OpAdd64 || v.Op == ssaop.OpAdd32 || v.Op == ssaop.OpAdd16 || v.Op == ssaop.OpAdd8 {
		return x, -y.AuxInt
	}
	return x, y.AuxInt
}

func printIndVar(b *ssa.Block, i, min, max *ssa.Value, inc int64, flags indVarFlags) {
	mb1, mb2 := "[", "]"
	if flags&indVarMinExc != 0 {
		mb1 = "("
	}
	if flags&indVarMaxInc == 0 {
		mb2 = ")"
	}

	mlim1, mlim2 := fmt.Sprint(min.AuxInt), fmt.Sprint(max.AuxInt)
	if !min.IsGenericIntConst() {
		if b.Func.Pass.Debug >= 2 {
			mlim1 = fmt.Sprint(min)
		} else {
			mlim1 = "?"
		}
	}
	if !max.IsGenericIntConst() {
		if b.Func.Pass.Debug >= 2 {
			mlim2 = fmt.Sprint(max)
		} else {
			mlim2 = "?"
		}
	}
	extra := ""
	if b.Func.Pass.Debug >= 2 {
		extra = fmt.Sprintf(" (%s)", i)
	}
	b.Func.Warnl(b.Pos, "Induction variable: limits %v%v,%v%v, increment %d%s", mb1, mlim1, mlim2, mb2, inc, extra)
}

func minSignedValue(t *types.Type) int64 {
	return -1 << (t.Size()*8 - 1)
}

func maxSignedValue(t *types.Type) int64 {
	return 1<<((t.Size()*8)-1) - 1
}
