// Copyright 2015 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 ssa

import (
	"fmt"
	"math"
	"strings"

	"cmd/compile/internal/abi"
	"cmd/compile/internal/base"
	"cmd/compile/internal/ir"
	"cmd/compile/internal/ssa/block"
	"cmd/compile/internal/ssa/ssabase"
	"cmd/compile/internal/ssa/ssaop"
	"cmd/compile/internal/typecheck"
	"cmd/compile/internal/types"
	"cmd/internal/obj"
	"cmd/internal/src"
)

// A Func represents a Go func declaration (or function literal) and its body.
// This package compiles each Func independently.
// Funcs are single-use; a new Func must be created for every compiled function.
type Func struct {
	Config *Config     // architecture information
	Cache  *Cache      // re-usable cache
	Fe     Frontend    // frontend state associated with this Func, callbacks into compiler frontend
	Pass   *Pass       // current pass information (name, options, etc.)
	Name   string      // e.g. NewFunc or (*Func).NumBlocks (no package prefix)
	Type   *types.Type // type signature of the function.
	Blocks []*Block    // unordered set of all basic blocks (note: not indexable by ID)
	Entry  *Block      // the entry basic block

	bid IDAlloc // block ID allocator
	vid IDAlloc // value ID allocator

	HTMLWriter     HTMLWriter
	FatalCleanup   func()         // cleanup function to run before reporting a fatal error
	PrintOrHtmlSSA bool           // true if GOSSAFUNC matches, true even if fe.Log() (spew phase results to stdout) is false.  There's an odd dependence on this in debug.go for method logf.
	RuleMatches    map[string]int // number of times countRule was called during compilation for any given string
	ABI0           *abi.ABIConfig // ABI configuration for ABI0
	ABI1           *abi.ABIConfig // ABI configuration for ABIInternal
	ABISelf        *abi.ABIConfig // ABI for function being compiled
	ABIDefault     *abi.ABIConfig // ABI for rtcall and other no-parsed-signature/pragma functions.

	MaxCPUFeatures CPUfeatures // union of all the CPU features in all the blocks.

	Scheduled   bool  // Values in Blocks are in final order
	Laidout     bool  // Blocks are ordered
	NoSplit     bool  // true if function is marked as nosplit.  Used by schedule check pass.
	dumpFileSeq uint8 // the sequence numbers of dump file. (%s_%02d__%s.dump", funcname, dumpFileSeq, phaseName)
	IsPgoHot    bool
	DeferReturn *Block // avoid creating more than one deferreturn if there's multiple calls to deferproc-etc.

	// when register allocation is done, maps value ids to locations
	RegAlloc []Location

	// temporary registers allocated to rare instructions
	TempRegs map[ID]*ssabase.Register

	// map from LocalSlot to set of Values that we want to store in that slot.
	NamedValues map[LocalSlot][]*Value
	// Names is a copy of NamedValues.Keys. We keep a separate list
	// of keys to make iteration order deterministic.
	Names []LocalSlot
	// Canonicalize root/top-level local slots, and canonicalize their pieces.
	// Because LocalSlot pieces refer to their parents with a pointer, this ensures that equivalent slots really are equal.
	CanonicalLocalSlots  map[LocalSlot]*LocalSlot
	CanonicalLocalSplits map[LocalSlotSplitKey]*LocalSlot

	// RegArgs is a slice of register-memory pairs that must be spilled and unspilled in the uncommon path of function entry.
	RegArgs []Spill
	// OwnAux describes parameters and results for this function.
	OwnAux *AuxCall
	// CloSlot holds the compiler-synthesized name (".closureptr")
	// where we spill the closure pointer for range func bodies.
	CloSlot *ir.Name

	FreeValues *Value // free Values linked by argstorage[0].  All other fields except ID are 0/nil.
	FreeBlocks *Block // free Blocks linked by succstorage[0].b.  All other fields except ID are 0/nil.

	cachedPostorder  []*Block   // cached postorder traversal
	cachedIdom       []*Block   // cached immediate dominators
	cachedSdom       SparseTree // cached dominator tree
	cachedLoopnest   *LoopNest  // cached loop nest information
	CachedLineStarts *XPosMap   // cached map/set of xpos to integers

	Auxmap    AuxMap             // map from aux values to opaque ids used by CSE
	constants map[int64][]*Value // constants cache, keyed by constant value; users must check value's Op and Type
}

// FuncNameABI returns n followed by a comma and the value of a.
// This is a separate function to allow a single point encoding
// of the format, which is used in places where there's not a Func yet.
func FuncNameABI(n string, a obj.ABI) string {
	return fmt.Sprintf("%s,%d", n, a)
}

type LocalSlotSplitKey struct {
	parent *LocalSlot
	Off    int64       // offset of slot in N
	Type   *types.Type // type of slot
}

// These magic auxint values let us easily cache non-numeric constants
// using the same constants map while making collisions unlikely.
// These values are unlikely to occur in regular code and
// are easy to grep for in case of bugs.
const (
	constSliceMagic       = 1122334455
	constInterfaceMagic   = 2233445566
	constNilMagic         = 3344556677
	constEmptyStringMagic = 4455667788
)

// IsMergeCandidate returns true if variable n could participate in
// stack slot merging. For now we're restricting the set to things to
// items larger than what CanSSA would allow (approximateky, we disallow things
// marked as open defer slots so as to avoid complicating liveness
// analysis.
func IsMergeCandidate(n *ir.Name) bool {
	if base.Debug.MergeLocals == 0 ||
		base.Flag.N != 0 ||
		n.Class != ir.PAUTO ||
		n.Type().Size() <= int64(3*types.PtrSize) ||
		n.Addrtaken() ||
		n.NonMergeable() ||
		n.OpenDeferSlot() {
		return false
	}
	return true
}

// NewFunc returns a new, empty function object.
// Caller must reset cache before calling NewFunc.
func (c *Config) NewFunc(fe Frontend, cache *Cache) *Func {
	return &Func{
		Fe:     fe,
		Config: c,
		Cache:  cache,

		NamedValues:          make(map[LocalSlot][]*Value),
		CanonicalLocalSlots:  make(map[LocalSlot]*LocalSlot),
		CanonicalLocalSplits: make(map[LocalSlotSplitKey]*LocalSlot),
		OwnAux:               &AuxCall{},
	}
}

// NumBlocks returns an integer larger than the id of any Block in the Func.
func (f *Func) NumBlocks() int {
	return f.bid.Num()
}

// NumValues returns an integer larger than the id of any Value in the Func.
func (f *Func) NumValues() int {
	return f.vid.Num()
}

// NameABI returns the function name followed by comma and the ABI number.
// This is intended for use with GOSSAFUNC and HTML dumps, and differs from
// the linker's "<1>" convention because "<" and ">" require shell quoting
// and are not legal file names (for use with GOSSADIR) on Windows.
func (f *Func) NameABI() string {
	return FuncNameABI(f.Name, f.ABISelf.Which())
}

// NewSparseSet returns a sparse set that can store at least up to n integers.
func (f *Func) NewSparseSet(n int) *SparseSet {
	return f.Cache.AllocSparseSet(n)
}

// RetSparseSet returns a sparse set to the config's cache of sparse
// sets to be reused by f.newSparseSet.
func (f *Func) RetSparseSet(ss *SparseSet) {
	f.Cache.FreeSparseSet(ss)
}

// NewSparseMap returns a sparse map that can store at least up to n integers.
func (f *Func) NewSparseMap(n int) *sparseMap {
	return f.Cache.AllocSparseMap(n)
}

// RetSparseMap returns a sparse map to the config's cache of sparse
// sets to be reused by f.newSparseMap.
func (f *Func) RetSparseMap(ss *sparseMap) {
	f.Cache.FreeSparseMap(ss)
}

// NewSparseMapPos returns a sparse map that can store at least up to n integers.
func (f *Func) NewSparseMapPos(n int) *SparseMapPos {
	return f.Cache.AllocSparseMapPos(n)
}

// RetSparseMapPos returns a sparse map to the config's cache of sparse
// sets to be reused by f.newSparseMapPos.
func (f *Func) RetSparseMapPos(ss *SparseMapPos) {
	f.Cache.FreeSparseMapPos(ss)
}

// NewPoset returns a new poset from the internal cache
func (f *Func) NewPoset() *Poset {
	if len(f.Cache.scrPoset) > 0 {
		po := f.Cache.scrPoset[len(f.Cache.scrPoset)-1]
		f.Cache.scrPoset = f.Cache.scrPoset[:len(f.Cache.scrPoset)-1]
		return po
	}
	return newPoset()
}

// RetPoset returns a poset to the internal cache
func (f *Func) RetPoset(po *Poset) {
	f.Cache.scrPoset = append(f.Cache.scrPoset, po)
}

// LocalSlotAddr returns a stable canonical *LocalSlot for slot, created on
// first use. SplitOf parents need it: f.Names holds values, not pointers.
func (f *Func) LocalSlotAddr(slot LocalSlot) *LocalSlot {
	a, ok := f.CanonicalLocalSlots[slot]
	if !ok {
		a = new(LocalSlot)
		*a = slot // don't escape slot
		f.CanonicalLocalSlots[slot] = a
	}
	return a
}

func (f *Func) SplitString(name *LocalSlot) (*LocalSlot, *LocalSlot) {
	ptrType := types.NewPtr(types.Types[types.TUINT8])
	lenType := types.Types[types.TINT]
	// Split this string up into two separate variables.
	p := f.SplitSlot(name, ".ptr", 0, ptrType)
	l := f.SplitSlot(name, ".len", ptrType.Size(), lenType)
	return p, l
}

func (f *Func) SplitInterface(name *LocalSlot) (*LocalSlot, *LocalSlot) {
	n := name.N
	u := types.Types[types.TUINTPTR]
	t := types.NewPtr(types.Types[types.TUINT8])
	// Split this interface up into two separate variables.
	sfx := ".itab"
	if n.Type().IsEmptyInterface() {
		sfx = ".type"
	}
	c := f.SplitSlot(name, sfx, 0, u) // see comment in typebits.Set
	d := f.SplitSlot(name, ".data", u.Size(), t)
	return c, d
}

func (f *Func) SplitSlice(name *LocalSlot) (*LocalSlot, *LocalSlot, *LocalSlot) {
	ptrType := types.NewPtr(name.Type.Elem())
	lenType := types.Types[types.TINT]
	p := f.SplitSlot(name, ".ptr", 0, ptrType)
	l := f.SplitSlot(name, ".len", ptrType.Size(), lenType)
	c := f.SplitSlot(name, ".cap", ptrType.Size()+lenType.Size(), lenType)
	return p, l, c
}

func (f *Func) SplitComplex(name *LocalSlot) (*LocalSlot, *LocalSlot) {
	s := name.Type.Size() / 2
	var t *types.Type
	if s == 8 {
		t = types.Types[types.TFLOAT64]
	} else {
		t = types.Types[types.TFLOAT32]
	}
	r := f.SplitSlot(name, ".real", 0, t)
	i := f.SplitSlot(name, ".imag", t.Size(), t)
	return r, i
}

func (f *Func) SplitInt64(name *LocalSlot) (*LocalSlot, *LocalSlot) {
	var t *types.Type
	if name.Type.IsSigned() {
		t = types.Types[types.TINT32]
	} else {
		t = types.Types[types.TUINT32]
	}
	if f.Config.BigEndian {
		return f.SplitSlot(name, ".hi", 0, t), f.SplitSlot(name, ".lo", t.Size(), types.Types[types.TUINT32])
	}
	return f.SplitSlot(name, ".hi", t.Size(), t), f.SplitSlot(name, ".lo", 0, types.Types[types.TUINT32])
}

func (f *Func) SplitStruct(name *LocalSlot, i int) *LocalSlot {
	st := name.Type
	return f.SplitSlot(name, st.FieldName(i), st.FieldOff(i), st.FieldType(i))
}

func (f *Func) SplitArray(name *LocalSlot) *LocalSlot {
	n := name.N
	at := name.Type
	if at.NumElem() != 1 {
		base.FatalfAt(n.Pos(), "bad array size")
	}
	et := at.Elem()
	return f.SplitSlot(name, "[0]", 0, et)
}

func (f *Func) SplitSlot(name *LocalSlot, sfx string, offset int64, t *types.Type) *LocalSlot {
	lssk := LocalSlotSplitKey{name, offset, t}
	if als, ok := f.CanonicalLocalSplits[lssk]; ok {
		return als
	}
	// Note: the _ field may appear several times.  But
	// have no fear, identically-named but distinct Autos are
	// ok, albeit maybe confusing for a debugger.
	ls := f.Fe.SplitSlot(name, sfx, offset, t)
	f.CanonicalLocalSplits[lssk] = &ls
	return &ls
}

// NewValue allocates a new Value with the given fields and places it at the end of b.Values.
func (f *Func) NewValue(op ssaop.Op, t *types.Type, b *Block, pos src.XPos) *Value {
	var v *Value
	if f.FreeValues != nil {
		v = f.FreeValues
		f.FreeValues = v.Argstorage[0]
		v.Argstorage[0] = nil
	} else {
		ID := f.vid.Get()
		if int(ID) < len(f.Cache.values) {
			v = &f.Cache.values[ID]
			v.ID = ID
		} else {
			v = &Value{ID: ID}
		}
	}
	v.Op = op
	v.Type = t
	v.Block = b
	if NotStmtBoundary(op) {
		pos = pos.WithNotStmt()
	}
	v.Pos = pos
	b.Values = append(b.Values, v)
	return v
}

// NewValueNoBlock allocates a new Value with the given fields.
// The returned value is not placed in any block.  Once the caller
// decides on a block b, it must set b.Block and append
// the returned value to b.Values.
func (f *Func) NewValueNoBlock(op ssaop.Op, t *types.Type, pos src.XPos) *Value {
	var v *Value
	if f.FreeValues != nil {
		v = f.FreeValues
		f.FreeValues = v.Argstorage[0]
		v.Argstorage[0] = nil
	} else {
		ID := f.vid.Get()
		if int(ID) < len(f.Cache.values) {
			v = &f.Cache.values[ID]
			v.ID = ID
		} else {
			v = &Value{ID: ID}
		}
	}
	v.Op = op
	v.Type = t
	v.Block = nil // caller must fix this.
	if NotStmtBoundary(op) {
		pos = pos.WithNotStmt()
	}
	v.Pos = pos
	return v
}

// LogStat writes a string key and int value as a warning in a
// tab-separated format easily handled by spreadsheets or awk.
// file names, lines, and function names are included to provide enough (?)
// context to allow item-by-item comparisons across runs.
// For example:
// awk 'BEGIN {FS="\t"} $3~/TIME/{sum+=$4} END{print "t(ns)=",sum}' t.log
func (f *Func) LogStat(key string, args ...any) {
	value := ""
	for _, a := range args {
		value += fmt.Sprintf("\t%v", a)
	}
	n := "missing_pass"
	if f.Pass != nil {
		n = strings.ReplaceAll(f.Pass.Name, " ", "_")
	}
	f.Warnl(f.Entry.Pos, "\t%s\t%s%s\t%s", n, key, value, f.Name)
}

// unCacheLine removes v from f's constant cache "line" for aux,
// resets v.InCache when it is found (and removed),
// and returns whether v was found in that line.
func (f *Func) unCacheLine(v *Value, aux int64) bool {
	vv := f.constants[aux]
	for i, cv := range vv {
		if v == cv {
			vv[i] = vv[len(vv)-1]
			vv[len(vv)-1] = nil
			f.constants[aux] = vv[0 : len(vv)-1]
			v.InCache = false
			return true
		}
	}
	return false
}

// UnCache removes v from f's constant cache.
func (f *Func) UnCache(v *Value) {
	if v.InCache {
		aux := v.AuxInt
		if f.unCacheLine(v, aux) {
			return
		}
		if aux == 0 {
			switch v.Op {
			case ssaop.OpConstNil:
				aux = constNilMagic
			case ssaop.OpConstSlice:
				aux = constSliceMagic
			case ssaop.OpConstString:
				aux = constEmptyStringMagic
			case ssaop.OpConstInterface:
				aux = constInterfaceMagic
			}
			if aux != 0 && f.unCacheLine(v, aux) {
				return
			}
		}
		f.Fatalf("unCached value %s not found in cache, auxInt=0x%x, adjusted aux=0x%x", v.LongString(), v.AuxInt, aux)
	}
}

// FreeValue frees a value. It must no longer be referenced or have any args.
func (f *Func) FreeValue(v *Value) {
	if v.Block == nil {
		f.Fatalf("trying to free an already freed value")
	}
	if v.Uses != 0 {
		f.Fatalf("value %s still has %d uses", v, v.Uses)
	}
	if len(v.Args) != 0 {
		f.Fatalf("value %s still has %d args", v, len(v.Args))
	}
	// Clear everything but ID (which we reuse).
	id := v.ID
	if v.InCache {
		f.UnCache(v)
	}
	*v = Value{}
	v.ID = id
	v.Argstorage[0] = f.FreeValues
	f.FreeValues = v
}

// NewBlock allocates a new Block of the given kind and places it at the end of f.Blocks.
func (f *Func) NewBlock(kind block.BlockKind) *Block {
	var b *Block
	if f.FreeBlocks != nil {
		b = f.FreeBlocks
		f.FreeBlocks = b.Succstorage[0].B
		b.Succstorage[0].B = nil
	} else {
		ID := f.bid.Get()
		if int(ID) < len(f.Cache.blocks) {
			b = &f.Cache.blocks[ID]
			b.ID = ID
		} else {
			b = &Block{ID: ID}
		}
	}
	b.Kind = kind
	b.Func = f
	b.Preds = b.Predstorage[:0]
	b.Succs = b.Succstorage[:0]
	b.Values = b.Valstorage[:0]
	f.Blocks = append(f.Blocks, b)
	f.InvalidateCFG()
	return b
}

func (f *Func) FreeBlock(b *Block) {
	if b.Func == nil {
		f.Fatalf("trying to free an already freed block")
	}
	// Clear everything but ID (which we reuse).
	id := b.ID
	*b = Block{}
	b.ID = id
	b.Succstorage[0].B = f.FreeBlocks
	f.FreeBlocks = b
}

// NewValue0 returns a new value in the block with no arguments and zero aux values.
func (b *Block) NewValue0(pos src.XPos, op ssaop.Op, t *types.Type) *Value {
	v := b.Func.NewValue(op, t, b, pos)
	v.AuxInt = 0
	v.Args = v.Argstorage[:0]
	return v
}

// NewValue0I returns a new value in the block with no arguments and an auxint value.
func (b *Block) NewValue0I(pos src.XPos, op ssaop.Op, t *types.Type, auxint int64) *Value {
	v := b.Func.NewValue(op, t, b, pos)
	v.AuxInt = auxint
	v.Args = v.Argstorage[:0]
	return v
}

// NewValue0A returns a new value in the block with no arguments and an aux value.
func (b *Block) NewValue0A(pos src.XPos, op ssaop.Op, t *types.Type, aux Aux) *Value {
	v := b.Func.NewValue(op, t, b, pos)
	v.AuxInt = 0
	v.Aux = aux
	v.Args = v.Argstorage[:0]
	return v
}

// NewValue0IA returns a new value in the block with no arguments and both an auxint and aux values.
func (b *Block) NewValue0IA(pos src.XPos, op ssaop.Op, t *types.Type, auxint int64, aux Aux) *Value {
	v := b.Func.NewValue(op, t, b, pos)
	v.AuxInt = auxint
	v.Aux = aux
	v.Args = v.Argstorage[:0]
	return v
}

// NewValue1 returns a new value in the block with one argument and zero aux values.
func (b *Block) NewValue1(pos src.XPos, op ssaop.Op, t *types.Type, arg *Value) *Value {
	v := b.Func.NewValue(op, t, b, pos)
	v.AuxInt = 0
	v.Args = v.Argstorage[:1]
	v.Argstorage[0] = arg
	arg.Uses++
	return v
}

// NewValue1I returns a new value in the block with one argument and an auxint value.
func (b *Block) NewValue1I(pos src.XPos, op ssaop.Op, t *types.Type, auxint int64, arg *Value) *Value {
	v := b.Func.NewValue(op, t, b, pos)
	v.AuxInt = auxint
	v.Args = v.Argstorage[:1]
	v.Argstorage[0] = arg
	arg.Uses++
	return v
}

// NewValue1A returns a new value in the block with one argument and an aux value.
func (b *Block) NewValue1A(pos src.XPos, op ssaop.Op, t *types.Type, aux Aux, arg *Value) *Value {
	v := b.Func.NewValue(op, t, b, pos)
	v.AuxInt = 0
	v.Aux = aux
	v.Args = v.Argstorage[:1]
	v.Argstorage[0] = arg
	arg.Uses++
	return v
}

// NewValue1IA returns a new value in the block with one argument and both an auxint and aux values.
func (b *Block) NewValue1IA(pos src.XPos, op ssaop.Op, t *types.Type, auxint int64, aux Aux, arg *Value) *Value {
	v := b.Func.NewValue(op, t, b, pos)
	v.AuxInt = auxint
	v.Aux = aux
	v.Args = v.Argstorage[:1]
	v.Argstorage[0] = arg
	arg.Uses++
	return v
}

// NewValue2 returns a new value in the block with two arguments and zero aux values.
func (b *Block) NewValue2(pos src.XPos, op ssaop.Op, t *types.Type, arg0, arg1 *Value) *Value {
	v := b.Func.NewValue(op, t, b, pos)
	v.AuxInt = 0
	v.Args = v.Argstorage[:2]
	v.Argstorage[0] = arg0
	v.Argstorage[1] = arg1
	arg0.Uses++
	arg1.Uses++
	return v
}

// NewValue2A returns a new value in the block with two arguments and one aux values.
func (b *Block) NewValue2A(pos src.XPos, op ssaop.Op, t *types.Type, aux Aux, arg0, arg1 *Value) *Value {
	v := b.Func.NewValue(op, t, b, pos)
	v.AuxInt = 0
	v.Aux = aux
	v.Args = v.Argstorage[:2]
	v.Argstorage[0] = arg0
	v.Argstorage[1] = arg1
	arg0.Uses++
	arg1.Uses++
	return v
}

// NewValue2I returns a new value in the block with two arguments and an auxint value.
func (b *Block) NewValue2I(pos src.XPos, op ssaop.Op, t *types.Type, auxint int64, arg0, arg1 *Value) *Value {
	v := b.Func.NewValue(op, t, b, pos)
	v.AuxInt = auxint
	v.Args = v.Argstorage[:2]
	v.Argstorage[0] = arg0
	v.Argstorage[1] = arg1
	arg0.Uses++
	arg1.Uses++
	return v
}

// NewValue2IA returns a new value in the block with two arguments and both an auxint and aux values.
func (b *Block) NewValue2IA(pos src.XPos, op ssaop.Op, t *types.Type, auxint int64, aux Aux, arg0, arg1 *Value) *Value {
	v := b.Func.NewValue(op, t, b, pos)
	v.AuxInt = auxint
	v.Aux = aux
	v.Args = v.Argstorage[:2]
	v.Argstorage[0] = arg0
	v.Argstorage[1] = arg1
	arg0.Uses++
	arg1.Uses++
	return v
}

// NewValue3 returns a new value in the block with three arguments and zero aux values.
func (b *Block) NewValue3(pos src.XPos, op ssaop.Op, t *types.Type, arg0, arg1, arg2 *Value) *Value {
	v := b.Func.NewValue(op, t, b, pos)
	v.AuxInt = 0
	v.Args = v.Argstorage[:3]
	v.Argstorage[0] = arg0
	v.Argstorage[1] = arg1
	v.Argstorage[2] = arg2
	arg0.Uses++
	arg1.Uses++
	arg2.Uses++
	return v
}

// NewValue3I returns a new value in the block with three arguments and an auxint value.
func (b *Block) NewValue3I(pos src.XPos, op ssaop.Op, t *types.Type, auxint int64, arg0, arg1, arg2 *Value) *Value {
	v := b.Func.NewValue(op, t, b, pos)
	v.AuxInt = auxint
	v.Args = v.Argstorage[:3]
	v.Argstorage[0] = arg0
	v.Argstorage[1] = arg1
	v.Argstorage[2] = arg2
	arg0.Uses++
	arg1.Uses++
	arg2.Uses++
	return v
}

// NewValue3A returns a new value in the block with three argument and an aux value.
func (b *Block) NewValue3A(pos src.XPos, op ssaop.Op, t *types.Type, aux Aux, arg0, arg1, arg2 *Value) *Value {
	v := b.Func.NewValue(op, t, b, pos)
	v.AuxInt = 0
	v.Aux = aux
	v.Args = v.Argstorage[:3]
	v.Argstorage[0] = arg0
	v.Argstorage[1] = arg1
	v.Argstorage[2] = arg2
	arg0.Uses++
	arg1.Uses++
	arg2.Uses++
	return v
}

// NewValue4 returns a new value in the block with four arguments and zero aux values.
func (b *Block) NewValue4(pos src.XPos, op ssaop.Op, t *types.Type, arg0, arg1, arg2, arg3 *Value) *Value {
	v := b.Func.NewValue(op, t, b, pos)
	v.AuxInt = 0
	v.Args = []*Value{arg0, arg1, arg2, arg3}
	arg0.Uses++
	arg1.Uses++
	arg2.Uses++
	arg3.Uses++
	return v
}

// NewValue4A returns a new value in the block with four arguments and zero aux values.
func (b *Block) NewValue4A(pos src.XPos, op ssaop.Op, t *types.Type, aux Aux, arg0, arg1, arg2, arg3 *Value) *Value {
	v := b.Func.NewValue(op, t, b, pos)
	v.AuxInt = 0
	v.Aux = aux
	v.Args = []*Value{arg0, arg1, arg2, arg3}
	arg0.Uses++
	arg1.Uses++
	arg2.Uses++
	arg3.Uses++
	return v
}

// NewValue4I returns a new value in the block with four arguments and auxint value.
func (b *Block) NewValue4I(pos src.XPos, op ssaop.Op, t *types.Type, auxint int64, arg0, arg1, arg2, arg3 *Value) *Value {
	v := b.Func.NewValue(op, t, b, pos)
	v.AuxInt = auxint
	v.Args = []*Value{arg0, arg1, arg2, arg3}
	arg0.Uses++
	arg1.Uses++
	arg2.Uses++
	arg3.Uses++
	return v
}

// ConstVal returns a constant value for c.
func (f *Func) ConstVal(op ssaop.Op, t *types.Type, c int64, setAuxInt bool) *Value {
	if f.constants == nil {
		f.constants = make(map[int64][]*Value)
	}
	vv := f.constants[c]
	for _, v := range vv {
		if v.Op == op && v.Type.Compare(t) == types.CMPeq {
			if setAuxInt && v.AuxInt != c {
				panic(fmt.Sprintf("cached const %s should have AuxInt of %d", v.LongString(), c))
			}
			return v
		}
	}
	var v *Value
	if setAuxInt {
		v = f.Entry.NewValue0I(src.NoXPos, op, t, c)
	} else {
		v = f.Entry.NewValue0(src.NoXPos, op, t)
	}
	f.constants[c] = append(vv, v)
	v.InCache = true
	return v
}

// ConstBool returns an int constant representing its argument.
func (f *Func) ConstBool(t *types.Type, c bool) *Value {
	i := int64(0)
	if c {
		i = 1
	}
	return f.ConstVal(ssaop.OpConstBool, t, i, true)
}

func (f *Func) ConstInt8(t *types.Type, c int8) *Value {
	return f.ConstVal(ssaop.OpConst8, t, int64(c), true)
}

func (f *Func) ConstInt16(t *types.Type, c int16) *Value {
	return f.ConstVal(ssaop.OpConst16, t, int64(c), true)
}

func (f *Func) ConstInt32(t *types.Type, c int32) *Value {
	return f.ConstVal(ssaop.OpConst32, t, int64(c), true)
}

func (f *Func) ConstInt64(t *types.Type, c int64) *Value {
	return f.ConstVal(ssaop.OpConst64, t, c, true)
}

func (f *Func) ConstFloat32(t *types.Type, c float64) *Value {
	return f.ConstVal(ssaop.OpConst32F, t, int64(math.Float64bits(float64(float32(c)))), true)
}

func (f *Func) ConstFloat64(t *types.Type, c float64) *Value {
	return f.ConstVal(ssaop.OpConst64F, t, int64(math.Float64bits(c)), true)
}

func (f *Func) ConstSlice(t *types.Type) *Value {
	return f.ConstVal(ssaop.OpConstSlice, t, constSliceMagic, false)
}

func (f *Func) ConstInterface(t *types.Type) *Value {
	return f.ConstVal(ssaop.OpConstInterface, t, constInterfaceMagic, false)
}

func (f *Func) ConstNil(t *types.Type) *Value {
	return f.ConstVal(ssaop.OpConstNil, t, constNilMagic, false)
}

func (f *Func) ConstEmptyString(t *types.Type) *Value {
	v := f.ConstVal(ssaop.OpConstString, t, constEmptyStringMagic, false)
	v.Aux = StringToAux("")
	return v
}

func (f *Func) ConstOffPtrSP(t *types.Type, c int64, sp *Value) *Value {
	v := f.ConstVal(ssaop.OpOffPtr, t, c, true)
	if len(v.Args) == 0 {
		v.AddArg(sp)
	}
	return v
}

func (f *Func) Frontend() Frontend { return f.Fe }

func (f *Func) Warnl(pos src.XPos, msg string, args ...any) { f.Fe.Warnl(pos, msg, args...) }

func (f *Func) Logf(msg string, args ...any) { f.Fe.Logf(msg, args...) }

func (f *Func) Log() bool { return f.Fe.Log() }

func (f *Func) Fatalf(msg string, args ...any) { f.FatalfWithPos(f.Entry.Pos, msg, args...) }

func (f *Func) FatalfWithPos(pos src.XPos, msg string, args ...any) {
	if f.Log() {
		f.Logf("  pass %s end crashed\n", f.Pass.Name)
		PrintFunc(f)
	}
	if f.FatalCleanup != nil {
		f.FatalCleanup()
	}
	f.Fe.Fatalf(pos, msg, args...)
}

// postorder returns the reachable blocks in f in a postorder traversal.
func (f *Func) postorder() []*Block {
	if f.cachedPostorder == nil {
		f.cachedPostorder = postorder(f)
	}
	return f.cachedPostorder
}

func (f *Func) Postorder() []*Block {
	return f.postorder()
}

// Idom returns a map from block ID to the immediate dominator of that block.
// f.Entry.ID maps to nil. Unreachable blocks map to nil as well.
func (f *Func) Idom() []*Block {
	if f.cachedIdom == nil {
		f.cachedIdom = Dominators(f)
	}
	return f.cachedIdom
}

// Sdom returns a sparse tree representing the dominator relationships
// among the blocks of f.
func (f *Func) Sdom() SparseTree {
	if f.cachedSdom == nil {
		f.cachedSdom = NewSparseTree(f, f.Idom())
	}
	return f.cachedSdom
}

// Loopnest returns the loop nest information for f.
func (f *Func) Loopnest() *LoopNest {
	if f.cachedLoopnest == nil {
		f.cachedLoopnest = Loopnestfor(f)
	}
	return f.cachedLoopnest
}

// InvalidateCFG tells f that its CFG has changed.
func (f *Func) InvalidateCFG() {
	f.cachedPostorder = nil
	f.cachedIdom = nil
	f.cachedSdom = nil
	f.cachedLoopnest = nil
}

// DebugHashMatch returns
//
//	base.DebugHashMatch(this function's package.name)
//
// for use in bug isolation.  The return value is true unless
// environment variable GOCOMPILEDEBUG=gossahash=X is set, in which case "it depends on X".
// See [base.DebugHashMatch] for more information.
func (f *Func) DebugHashMatch() bool {
	if !base.HasDebugHash() {
		return true
	}
	sym := f.Fe.Func().Sym()
	return base.DebugHashMatchPkgFunc(sym.Pkg.Path, sym.Name)
}

func (f *Func) SpSb() (sp, sb *Value) {
	initpos := src.NoXPos // These are originally created with no position in ssa.go; if they are optimized out then recreated, should be the same.
	for _, v := range f.Entry.Values {
		if v.Op == ssaop.OpSB {
			sb = v
		}
		if v.Op == ssaop.OpSP {
			sp = v
		}
		if sb != nil && sp != nil {
			return
		}
	}
	if sb == nil {
		sb = f.Entry.NewValue0(initpos.WithNotStmt(), ssaop.OpSB, f.Config.Types.Uintptr)
	}
	if sp == nil {
		sp = f.Entry.NewValue0(initpos.WithNotStmt(), ssaop.OpSP, f.Config.Types.Uintptr)
	}
	return
}

// UseFMA allows targeted debugging w/ GOFMAHASH
// If you have an architecture-dependent FP glitch, this will help you find it.
func (f *Func) UseFMA(v *Value) bool {
	if base.FmaHash == nil {
		return true
	}
	return base.FmaHash.MatchPos(v.Pos, nil)
}

// NewLocal returns a new anonymous local variable of the given type.
func (f *Func) NewLocal(pos src.XPos, typ *types.Type) *ir.Name {
	nn := typecheck.TempAt(pos, f.Fe.Func(), typ) // Note: adds new auto to fn.Dcl list
	nn.SetNonMergeable(true)
	return nn
}
