// Copyright 2023 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 inlheur

import (
	"cmd/compile/internal/base"
	"cmd/compile/internal/ir"
	"cmd/compile/internal/types"
	"fmt"
	"os"
)

// funcFlagsAnalyzer computes the "Flags" value for the FuncProps
// object we're computing. The main item of interest here is "nstate",
// which stores the disposition of a given ir Node with respect to the
// flags/properties we're trying to compute.
type funcFlagsAnalyzer struct {
	fn     *ir.Func
	nstate map[ir.Node]pstate
	noInfo bool // set if we see something inscrutable/un-analyzable
}

// pstate keeps track of the disposition of a given node and its
// children with respect to panic/exit calls.
type pstate int

const (
	psNoInfo     pstate = iota // nothing interesting about this node
	psCallsPanic               // node causes call to panic or os.Exit
	psMayReturn                // executing node may trigger a "return" stmt
	psTop                      // dataflow lattice "top" element
)

func makeFuncFlagsAnalyzer(fn *ir.Func) *funcFlagsAnalyzer {
	return &funcFlagsAnalyzer{
		fn:     fn,
		nstate: make(map[ir.Node]pstate),
	}
}

// setResults transfers func flag results to 'funcProps'.
func (ffa *funcFlagsAnalyzer) setResults(funcProps *FuncProps) {
	var rv FuncPropBits
	if !ffa.noInfo && ffa.stateForList(ffa.fn.Body) == psCallsPanic {
		rv = FuncPropNeverReturns
	}
	// This is slightly hacky and not at all required, but include a
	// special case for main.main, which often ends in a call to
	// os.Exit. People who write code like this (very common I
	// imagine)
	//
	//   func main() {
	//     rc = perform()
	//     ...
	//     foo()
	//     os.Exit(rc)
	//   }
	//
	// will be constantly surprised when foo() is inlined in many
	// other spots in the program but not in main().
	if isMainMain(ffa.fn) {
		rv &^= FuncPropNeverReturns
	}
	funcProps.Flags = rv
}

func (ffa *funcFlagsAnalyzer) getState(n ir.Node) pstate {
	return ffa.nstate[n]
}

func (ffa *funcFlagsAnalyzer) setState(n ir.Node, st pstate) {
	if st != psNoInfo {
		ffa.nstate[n] = st
	}
}

func (ffa *funcFlagsAnalyzer) updateState(n ir.Node, st pstate) {
	if st == psNoInfo {
		delete(ffa.nstate, n)
	} else {
		ffa.nstate[n] = st
	}
}

func (ffa *funcFlagsAnalyzer) panicPathTable() map[ir.Node]pstate {
	return ffa.nstate
}

// blockCombine merges together states as part of a linear sequence of
// statements, where 'pred' and 'succ' are analysis results for a pair
// of consecutive statements. Examples:
//
//	case 1:             case 2:
//	    panic("foo")      if q { return x }        <-pred
//	    return x          panic("boo")             <-succ
//
// In case 1, since the pred state is "always panic" it doesn't matter
// what the succ state is, hence the state for the combination of the
// two blocks is "always panics". In case 2, because there is a path
// to return that avoids the panic in succ, the state for the
// combination of the two statements is "may return".
func blockCombine(pred, succ pstate) pstate {
	switch succ {
	case psTop:
		return pred
	case psMayReturn:
		if pred == psCallsPanic {
			return psCallsPanic
		}
		return psMayReturn
	case psNoInfo:
		return pred
	case psCallsPanic:
		if pred == psMayReturn {
			return psMayReturn
		}
		return psCallsPanic
	}
	panic("should never execute")
}

// branchCombine combines two states at a control flow branch point where
// either p1 or p2 executes (as in an "if" statement).
func branchCombine(p1, p2 pstate) pstate {
	if p1 == psCallsPanic && p2 == psCallsPanic {
		return psCallsPanic
	}
	if p1 == psMayReturn || p2 == psMayReturn {
		return psMayReturn
	}
	return psNoInfo
}

// stateForList walks through a list of statements and computes the
// state/diposition for the entire list as a whole, as well
// as updating disposition of intermediate nodes.
func (ffa *funcFlagsAnalyzer) stateForList(list ir.Nodes) pstate {
	st := psTop
	// Walk the list backwards so that we can update the state for
	// earlier list elements based on what we find out about their
	// successors. Example:
	//
	//        if ... {
	//  L10:    foo()
	//  L11:    <stmt>
	//  L12:    panic(...)
	//        }
	//
	// After combining the dispositions for line 11 and 12, we want to
	// update the state for the call at line 10 based on that combined
	// disposition (if L11 has no path to "return", then the call at
	// line 10 will be on a panic path).
	for i := len(list) - 1; i >= 0; i-- {
		n := list[i]
		psi := ffa.getState(n)
		if debugTrace&debugTraceFuncFlags != 0 {
			fmt.Fprintf(os.Stderr, "=-= %v: stateForList n=%s ps=%s\n",
				ir.Line(n), n.Op().String(), psi.String())
		}
		st = blockCombine(psi, st)
		ffa.updateState(n, st)
	}
	if st == psTop {
		st = psNoInfo
	}
	return st
}

func isMainMain(fn *ir.Func) bool {
	s := fn.Sym()
	return (s.Pkg.Name == "main" && s.Name == "main")
}

func isWellKnownFunc(s *types.Sym, pkg, name string) bool {
	return s.Pkg.Path == pkg && s.Name == name
}

// isExitCall reports TRUE if the node itself is an unconditional
// call to os.Exit(), a panic, or a function that does likewise.
func isExitCall(n ir.Node) bool {
	if n.Op() != ir.OCALLFUNC {
		return false
	}
	cx := n.(*ir.CallExpr)
	name := ir.StaticCalleeName(cx.Fun)
	if name == nil {
		return false
	}
	s := name.Sym()
	if isWellKnownFunc(s, "os", "Exit") ||
		isWellKnownFunc(s, "runtime", "throw") {
		return true
	}
	if funcProps := propsForFunc(name.Func); funcProps != nil {
		if funcProps.Flags&FuncPropNeverReturns != 0 {
			return true
		}
	}
	return name.Func.NeverReturns()
}

// pessimize is called to record the fact that we saw something in the
// function that renders it entirely impossible to analyze.
func (ffa *funcFlagsAnalyzer) pessimize() {
	ffa.noInfo = true
}

// shouldVisit reports TRUE if this is an interesting node from the
// perspective of computing function flags. NB: due to the fact that
// ir.CallExpr implements the Stmt interface, we wind up visiting
// a lot of nodes that we don't really need to, but these can
// simply be screened out as part of the visit.
func shouldVisit(n ir.Node) bool {
	_, isStmt := n.(ir.Stmt)
	return n.Op() != ir.ODCL &&
		(isStmt || n.Op() == ir.OCALLFUNC || n.Op() == ir.OPANIC)
}

// nodeVisitPost helps implement the propAnalyzer interface; when
// called on a given node, it decides the disposition of that node
// based on the state(s) of the node's children.
func (ffa *funcFlagsAnalyzer) nodeVisitPost(n ir.Node) {
	if debugTrace&debugTraceFuncFlags != 0 {
		fmt.Fprintf(os.Stderr, "=+= nodevis %v %s should=%v\n",
			ir.Line(n), n.Op().String(), shouldVisit(n))
	}
	if !shouldVisit(n) {
		return
	}
	var st pstate
	switch n.Op() {
	case ir.OCALLFUNC:
		if isExitCall(n) {
			st = psCallsPanic
		}
	case ir.OPANIC:
		st = psCallsPanic
	case ir.ORETURN:
		st = psMayReturn
	case ir.OBREAK, ir.OCONTINUE:
		// FIXME: this handling of break/continue is sub-optimal; we
		// have them as "mayReturn" in order to help with this case:
		//
		//   for {
		//     if q() { break }
		//     panic(...)
		//   }
		//
		// where the effect of the 'break' is to cause the subsequent
		// panic to be skipped. One possible improvement would be to
		// track whether the currently enclosing loop is a "for {" or
		// a for/range with condition, then use mayReturn only for the
		// former. Note also that "break X" or "continue X" is treated
		// the same as "goto", since we don't have a good way to track
		// the target of the branch.
		st = psMayReturn
		n := n.(*ir.BranchStmt)
		if n.Label != nil {
			ffa.pessimize()
		}
	case ir.OBLOCK:
		n := n.(*ir.BlockStmt)
		st = ffa.stateForList(n.List)
	case ir.OCASE:
		if ccst, ok := n.(*ir.CaseClause); ok {
			st = ffa.stateForList(ccst.Body)
		} else if ccst, ok := n.(*ir.CommClause); ok {
			st = ffa.stateForList(ccst.Body)
		} else {
			panic("unexpected")
		}
	case ir.OIF:
		n := n.(*ir.IfStmt)
		st = branchCombine(ffa.stateForList(n.Body), ffa.stateForList(n.Else))
	case ir.OFOR:
		// Treat for { XXX } like a block.
		// Treat for <cond> { XXX } like an if statement with no else.
		n := n.(*ir.ForStmt)
		bst := ffa.stateForList(n.Body)
		if n.Cond == nil {
			st = bst
		} else {
			if bst == psMayReturn {
				st = psMayReturn
			}
		}
	case ir.ORANGE:
		// Treat for range { XXX } like an if statement with no else.
		n := n.(*ir.RangeStmt)
		if ffa.stateForList(n.Body) == psMayReturn {
			st = psMayReturn
		}
	case ir.OGOTO:
		// punt if we see even one goto. if we built a control
		// flow graph we could do more, but this is just a tree walk.
		ffa.pessimize()
	case ir.OSELECT:
		// process selects for "may return" but not "always panics",
		// the latter case seems very improbable.
		n := n.(*ir.SelectStmt)
		if len(n.Cases) != 0 {
			st = psTop
			for _, c := range n.Cases {
				st = branchCombine(ffa.stateForList(c.Body), st)
			}
		}
	case ir.OSWITCH:
		n := n.(*ir.SwitchStmt)
		if len(n.Cases) != 0 {
			st = psTop
			for _, c := range n.Cases {
				st = branchCombine(ffa.stateForList(c.Body), st)
			}
		}

		st, fall := psTop, psNoInfo
		for i := len(n.Cases) - 1; i >= 0; i-- {
			cas := n.Cases[i]
			cst := ffa.stateForList(cas.Body)
			endsInFallthrough := false
			if len(cas.Body) != 0 {
				endsInFallthrough = cas.Body[0].Op() == ir.OFALL
			}
			if endsInFallthrough {
				cst = blockCombine(cst, fall)
			}
			st = branchCombine(st, cst)
			fall = cst
		}
	case ir.OFALL:
		// Not important.
	case ir.ODCLFUNC, ir.ORECOVER, ir.OAS, ir.OAS2, ir.OAS2FUNC, ir.OASOP,
		ir.OPRINTLN, ir.OPRINT, ir.OLABEL, ir.OCALLINTER, ir.ODEFER,
		ir.OSEND, ir.ORECV, ir.OSELRECV2, ir.OGO, ir.OAPPEND, ir.OAS2DOTTYPE,
		ir.OAS2MAPR, ir.OGETG, ir.ODELETE, ir.OINLMARK, ir.OAS2RECV,
		ir.OMIN, ir.OMAX, ir.OMAKE, ir.ORECOVERFP, ir.OGETCALLERSP:
		// these should all be benign/uninteresting
	case ir.OTAILCALL, ir.OJUMPTABLE, ir.OTYPESW:
		// don't expect to see these at all.
		base.Fatalf("unexpected op %s in func %s",
			n.Op().String(), ir.FuncName(ffa.fn))
	default:
		base.Fatalf("%v: unhandled op %s in func %v",
			ir.Line(n), n.Op().String(), ir.FuncName(ffa.fn))
	}
	if debugTrace&debugTraceFuncFlags != 0 {
		fmt.Fprintf(os.Stderr, "=-= %v: visit n=%s returns %s\n",
			ir.Line(n), n.Op().String(), st.String())
	}
	ffa.setState(n, st)
}

func (ffa *funcFlagsAnalyzer) nodeVisitPre(n ir.Node) {
}
