// Copyright 2017 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 ssadebug

import (
	"cmp"
	"internal/buildcfg"
	"slices"

	"cmd/compile/internal/abi"
	"cmd/compile/internal/ir"
	"cmd/compile/internal/ssa"
	"cmd/compile/internal/ssa/ssabase"
	"cmd/compile/internal/ssa/ssaop"
	"cmd/compile/internal/types"
	"cmd/internal/dwarf"
	"cmd/internal/obj"
	"cmd/internal/src"
)

// A FuncDebug contains all the debug information for the variables in a
// function. Variables are identified by their LocalSlot, which may be
// the result of decomposing a larger variable.
type FuncDebug struct {
	// Slots is all the slots used in the debug info, indexed by their SlotID.
	Slots []ssa.LocalSlot
	// The user variables, indexed by VarID.
	Vars []*ir.Name
	// The slots that make up each variable, indexed by VarID.
	VarSlots [][]ssa.SlotID
	// The location list data, indexed by VarID. Must be processed by PutLocationList.
	LocationLists [][]ssa.LocListEntry
	// Register-resident output parameters for the function. This is filled in at
	// SSA generation time.
	RegOutputParams []*ir.Name
	// Variable declarations that were removed during optimization
	OptDcl []*ir.Name
	// The ssa.Func.EntryID value, used to build location lists for
	// return values promoted to heap in later DWARF generation.
	EntryID ssa.ID

	// Filled in by the user. Translates Block and Value ID to PC.
	//
	// NOTE: block is only used if value is BlockStart.ID or BlockEnd.ID.
	// Otherwise, it is ignored.
	GetPC func(block, value ssa.ID) int64
}

// slotCanonicalizer is a table used to lookup and canonicalize
// LocalSlot's in a type insensitive way (e.g. taking into account the
// base name, offset, and width of the slot, but ignoring the slot
// type).
type slotCanonicalizer struct {
	slmap  map[slotKey]SlKeyIdx
	slkeys []ssa.LocalSlot
}

func newSlotCanonicalizer() *slotCanonicalizer {
	return &slotCanonicalizer{
		slmap:  make(map[slotKey]SlKeyIdx),
		slkeys: []ssa.LocalSlot{ssa.LocalSlot{N: nil}},
	}
}

type SlKeyIdx uint32

const noSlot = SlKeyIdx(0)

// slotKey is a type-insensitive encapsulation of a LocalSlot; it
// is used to key a map within slotCanonicalizer.
type slotKey struct {
	name        *ir.Name
	offset      int64
	width       int64
	splitOf     SlKeyIdx // idx in slkeys slice in slotCanonicalizer
	splitOffset int64
}

// lookup looks up a LocalSlot in the slot canonicalizer "sc", returning
// a canonical index for the slot, and adding it to the table if need
// be. Return value is the canonical slot index, and a boolean indicating
// whether the slot was found in the table already (TRUE => found).
func (sc *slotCanonicalizer) lookup(ls ssa.LocalSlot) (SlKeyIdx, bool) {
	split := noSlot
	if ls.SplitOf != nil {
		split, _ = sc.lookup(*ls.SplitOf)
	}
	k := slotKey{
		name: ls.N, offset: ls.Off, width: ls.Type.Size(),
		splitOf: split, splitOffset: ls.SplitOffset,
	}
	if idx, ok := sc.slmap[k]; ok {
		return idx, true
	}
	rv := SlKeyIdx(len(sc.slkeys))
	sc.slkeys = append(sc.slkeys, ls)
	sc.slmap[k] = rv
	return rv, false
}

func (sc *slotCanonicalizer) canonSlot(idx SlKeyIdx) ssa.LocalSlot {
	return sc.slkeys[idx]
}

// PopulateABIInRegArgOps examines the entry block of the function
// and looks for incoming parameters that have missing or partial
// OpArg{Int,Float}Reg values, inserting additional values in
// cases where they are missing. Example:
//
//	func foo(s string, used int, notused int) int {
//	  return len(s) + used
//	}
//
// In the function above, the incoming parameter "used" is fully live,
// "notused" is not live, and "s" is partially live (only the length
// field of the string is used). At the point where debug value
// analysis runs, we might expect to see an entry block with:
//
//	b1:
//	  v4 = ArgIntReg <uintptr> {s+8} [0] : BX
//	  v5 = ArgIntReg <int> {used} [0] : CX
//
// While this is an accurate picture of the live incoming params,
// we also want to have debug locations for non-live params (or
// their non-live pieces), e.g. something like
//
//	b1:
//	  v9 = ArgIntReg <*uint8> {s+0} [0] : AX
//	  v4 = ArgIntReg <uintptr> {s+8} [0] : BX
//	  v5 = ArgIntReg <int> {used} [0] : CX
//	  v10 = ArgIntReg <int> {unused} [0] : DI
//
// This function examines the live OpArg{Int,Float}Reg values and
// synthesizes new (dead) values for the non-live params or the
// non-live pieces of partially live params.
func PopulateABIInRegArgOps(f *ssa.Func) {
	pri := f.ABISelf.ABIAnalyzeFuncType(f.Type)

	// When manufacturing new slots that correspond to splits of
	// composite parameters, we want to avoid creating a new sub-slot
	// that differs from some existing sub-slot only by type, since
	// the debug location analysis will treat that slot as a separate
	// entity. To achieve this, create a lookup table of existing
	// slots that is type-insenstitive.
	sc := newSlotCanonicalizer()
	for _, sl := range f.Names {
		sc.lookup(sl)
	}

	// Add slot -> value entry to f.NamedValues if not already present.
	addToNV := func(v *ssa.Value, sl ssa.LocalSlot) {
		values, ok := f.NamedValues[sl]
		if !ok {
			// Haven't seen this slot yet.
			f.Names = append(f.Names, sl)
		} else {
			for _, ev := range values {
				if v == ev {
					return
				}
			}
		}
		values = append(values, v)
		f.NamedValues[sl] = values
	}

	newValues := []*ssa.Value{}

	abiRegIndexToRegister := func(reg abi.RegIndex) int8 {
		i := f.ABISelf.FloatIndexFor(reg)
		if i >= 0 { // float PR
			return f.Config.FloatParamRegs[i]
		} else {
			return f.Config.IntParamRegs[reg]
		}
	}

	// Helper to construct a new OpArg{Float,Int}Reg op value.
	var pos src.XPos
	if len(f.Entry.Values) != 0 {
		pos = f.Entry.Values[0].Pos
	}
	synthesizeOpIntFloatArg := func(n *ir.Name, t *types.Type, reg abi.RegIndex, sl ssa.LocalSlot) *ssa.Value {
		aux := &ssa.AuxNameOffset{Name: n, Offset: sl.Off}
		op, auxInt := ssa.ArgOpAndRegisterFor(reg, f.ABISelf)
		v := f.NewValueNoBlock(op, t, pos)
		v.AuxInt = auxInt
		v.Aux = aux
		v.Args = nil
		v.Block = f.Entry
		newValues = append(newValues, v)
		addToNV(v, sl)
		f.SetHome(v, &f.Config.Registers[abiRegIndexToRegister(reg)])
		return v
	}

	// Make a pass through the entry block looking for
	// OpArg{Int,Float}Reg ops. Record the slots they use in a table
	// ("sc"). We use a type-insensitive lookup for the slot table,
	// since the type we get from the ABI analyzer won't always match
	// what the compiler uses when creating OpArg{Int,Float}Reg ops.
	for _, v := range f.Entry.Values {
		if v.Op == ssaop.OpArgIntReg || v.Op == ssaop.OpArgFloatReg {
			aux := v.Aux.(*ssa.AuxNameOffset)
			sl := ssa.LocalSlot{N: aux.Name, Type: v.Type, Off: aux.Offset}
			// install slot in lookup table
			idx, _ := sc.lookup(sl)
			// add to f.NamedValues if not already present
			addToNV(v, sc.canonSlot(idx))
		} else if v.Op.IsCall() {
			// if we hit a call, we've gone too far.
			break
		}
	}

	// Now make a pass through the ABI in-params, looking for params
	// or pieces of params that we didn't encounter in the loop above.
	for _, inp := range pri.InParams() {
		if !isNamedRegParam(inp) {
			continue
		}
		n := inp.Name

		// Param is spread across one or more registers. Walk through
		// each piece to see whether we've seen an arg reg op for it.
		types, offsets := inp.RegisterTypesAndOffsets()
		for k, t := range types {
			// Note: this recipe for creating a LocalSlot is designed
			// to be compatible with the one used in expand_calls.go
			// as opposed to decompose.go. The expand calls code just
			// takes the base name and creates an offset into it,
			// without using the SplitOf/SplitOffset fields. The code
			// in decompose.go does the opposite -- it creates a
			// LocalSlot object with "Off" set to zero, but with
			// SplitOf pointing to a parent slot, and SplitOffset
			// holding the offset into the parent object.
			pieceSlot := ssa.LocalSlot{N: n, Type: t, Off: offsets[k]}

			// Look up this piece to see if we've seen a reg op
			// for it. If not, create one.
			_, found := sc.lookup(pieceSlot)
			if !found {
				// This slot doesn't appear in the map, meaning it
				// corresponds to an in-param that is not live, or
				// a portion of an in-param that is not live/used.
				// Add a new dummy OpArg{Int,Float}Reg for it.
				synthesizeOpIntFloatArg(n, t, inp.Registers[k],
					pieceSlot)
			}
		}
	}

	// Insert the new values into the head of the block.
	f.Entry.Values = append(newValues, f.Entry.Values...)
}

// BuildFuncDebug builds debug information for f, placing the results
// in "rval". f must be fully processed, so that each Value is where it
// will be when machine code is emitted.
func BuildFuncDebug(ctxt *obj.Link, f *ssa.Func, loggingLevel int, stackOffset func(ssa.LocalSlot) int32, rval *FuncDebug) {
	if f.RegAlloc == nil {
		f.Fatalf("BuildFuncDebug on func %v that has not been fully processed", f)
	}
	state := &f.Cache.DebugState
	state.LoggingLevel = loggingLevel % 1000

	// A specific number demands exactly that many iterations. Under
	// particular circumstances it make require more than the total of
	// 2 passes implied by a single run through liveness and a single
	// run through location list generation.
	state.ConvergeCount = loggingLevel / 1000
	state.F = f
	state.Registers = f.Config.Registers
	state.StackOffset = stackOffset
	state.Ctxt = ctxt

	if buildcfg.Experiment.RegabiArgs {
		PopulateABIInRegArgOps(f)
	}

	if state.LoggingLevel > 0 {
		state.Logf("Generating location lists for function %q\n", f.Name)
	}

	if state.VarParts == nil {
		state.VarParts = make(map[*ir.Name][]ssa.SlotID)
	} else {
		clear(state.VarParts)
	}

	// Recompose any decomposed variables, and establish the canonical
	// IDs for each var and slot by filling out state.vars and state.slots.

	state.Slots = state.Slots[:0]
	state.Vars = state.Vars[:0]
	for i, slot := range f.Names {
		state.Slots = append(state.Slots, slot)
		if ir.IsSynthetic(slot.N) || !ssa.IsVarWantedForDebug(slot.N) {
			continue
		}

		topSlot := slot
		for topSlot.SplitOf != nil {
			topSlot = *topSlot.SplitOf
		}
		if _, ok := state.VarParts[topSlot.N]; !ok {
			state.Vars = append(state.Vars, topSlot.N)
		}
		state.VarParts[topSlot.N] = append(state.VarParts[topSlot.N], ssa.SlotID(i))
	}

	// Recreate the LocalSlot for each stack-only variable.
	// This would probably be better as an output from stackframe.
	for _, b := range f.Blocks {
		for _, v := range b.Values {
			if v.Op == ssaop.OpVarDef {
				n := v.Aux.(*ir.Name)
				if ir.IsSynthetic(n) || !ssa.IsVarWantedForDebug(n) {
					continue
				}

				if _, ok := state.VarParts[n]; !ok {
					slot := ssa.LocalSlot{N: n, Type: v.Type, Off: 0}
					state.Slots = append(state.Slots, slot)
					state.VarParts[n] = []ssa.SlotID{ssa.SlotID(len(state.Slots) - 1)}
					state.Vars = append(state.Vars, n)
				}
			}
		}
	}

	// Fill in the var<->slot mappings.
	if cap(state.VarSlots) < len(state.Vars) {
		state.VarSlots = make([][]ssa.SlotID, len(state.Vars))
	} else {
		state.VarSlots = state.VarSlots[:len(state.Vars)]
		for i := range state.VarSlots {
			state.VarSlots[i] = state.VarSlots[i][:0]
		}
	}
	if cap(state.SlotVars) < len(state.Slots) {
		state.SlotVars = make([]ssa.VarID, len(state.Slots))
	} else {
		state.SlotVars = state.SlotVars[:len(state.Slots)]
	}

	for varID, n := range state.Vars {
		parts := state.VarParts[n]
		slices.SortFunc(parts, func(a, b ssa.SlotID) int {
			return cmp.Compare(varOffset(state.Slots[a]), varOffset(state.Slots[b]))
		})

		state.VarSlots[varID] = parts
		for _, slotID := range parts {
			state.SlotVars[slotID] = ssa.VarID(varID)
		}
	}

	state.InitializeCache(f, len(state.VarParts), len(state.Slots))

	for i, slot := range f.Names {
		if ir.IsSynthetic(slot.N) || !ssa.IsVarWantedForDebug(slot.N) {
			continue
		}
		for _, value := range f.NamedValues[slot] {
			state.ValueNames[value.ID] = append(state.ValueNames[value.ID], ssa.SlotID(i))
		}
	}

	blockLocs := state.Liveness()
	state.BuildLocationLists(blockLocs)

	// Populate "rval" with what we've computed.
	rval.Slots = state.Slots
	rval.VarSlots = state.VarSlots
	rval.Vars = state.Vars
	rval.LocationLists = state.Lists
}

// varOffset returns the offset of slot within the user variable it was
// decomposed from. This has nothing to do with its stack offset.
func varOffset(slot ssa.LocalSlot) int64 {
	offset := slot.Off
	s := &slot
	for ; s.SplitOf != nil; s = s.SplitOf {
		offset += s.SplitOffset
	}
	return offset
}

// PutLocationList adds entries (a location list in structured form)
// to listSym, encoding it in the appropriate DWARF format.
func (debugInfo *FuncDebug) PutLocationList(entries []ssa.LocListEntry, ctxt *obj.Link, listSym, startPC *obj.LSym) {
	if buildcfg.Experiment.Dwarf5 {
		debugInfo.PutLocationListDwarf5(entries, ctxt, listSym, startPC)
	} else {
		debugInfo.PutLocationListDwarf4(entries, ctxt, listSym, startPC)
	}
}

// PutLocationListDwarf5 adds entries (a location list in structured form)
// to listSym in DWARF 5 format.
func (debugInfo *FuncDebug) PutLocationListDwarf5(entries []ssa.LocListEntry, ctxt *obj.Link, listSym, startPC *obj.LSym) {
	getPC := debugInfo.GetPC

	// base address entry
	listSym.WriteInt(ctxt, listSym.Size, 1, dwarf.DW_LLE_base_addressx)
	listSym.WriteDwTxtAddrx(ctxt, listSym.Size, startPC, ctxt.DwTextCount*2)

	var stbuf, enbuf [10]byte
	for _, entry := range entries {
		begin := getPC(entry.StartBlock, entry.StartValue)
		end := getPC(entry.EndBlock, entry.EndValue)

		// Write LLE_offset_pair tag followed by payload (ULEB for start
		// and then end).
		listSym.WriteInt(ctxt, listSym.Size, 1, dwarf.DW_LLE_offset_pair)
		stb := stbuf[:0]
		enb := enbuf[:0]
		stb = dwarf.AppendUleb128(stb, uint64(begin))
		enb = dwarf.AppendUleb128(enb, uint64(end))
		listSym.WriteBytes(ctxt, listSym.Size, stb)
		listSym.WriteBytes(ctxt, listSym.Size, enb)

		// DWARF5 uses ULEB128-encoded length for the location expression.
		stb = stbuf[:0]
		stb = dwarf.AppendUleb128(stb, uint64(len(entry.Expr)))
		listSym.WriteBytes(ctxt, listSym.Size, stb)
		listSym.WriteBytes(ctxt, listSym.Size, entry.Expr)
	}

	// Terminator
	listSym.WriteInt(ctxt, listSym.Size, 1, dwarf.DW_LLE_end_of_list)
}

// PutLocationListDwarf4 adds entries (a location list in structured form)
// to listSym in DWARF 4 format.
func (debugInfo *FuncDebug) PutLocationListDwarf4(entries []ssa.LocListEntry, ctxt *obj.Link, listSym, startPC *obj.LSym) {
	getPC := debugInfo.GetPC

	if ctxt.UseBASEntries {
		listSym.WriteInt(ctxt, listSym.Size, ctxt.Arch.PtrSize, ^0)
		listSym.WriteAddr(ctxt, listSym.Size, ctxt.Arch.PtrSize, startPC, 0)
	}

	for _, entry := range entries {
		begin := getPC(entry.StartBlock, entry.StartValue)
		end := getPC(entry.EndBlock, entry.EndValue)

		// Horrible hack. If a range contains only zero-width
		// instructions, e.g. an Arg, and it's at the beginning of the
		// function, this would be indistinguishable from an
		// end entry. Fudge it.
		if begin == 0 && end == 0 {
			end = 1
		}

		if ctxt.UseBASEntries {
			listSym.WriteInt(ctxt, listSym.Size, ctxt.Arch.PtrSize, begin)
			listSym.WriteInt(ctxt, listSym.Size, ctxt.Arch.PtrSize, end)
		} else {
			listSym.WriteCURelativeAddr(ctxt, listSym.Size, startPC, begin)
			listSym.WriteCURelativeAddr(ctxt, listSym.Size, startPC, end)
		}

		// Write 2-byte length prefix followed by the location expression.
		listSym.WriteInt(ctxt, listSym.Size, 2, int64(len(entry.Expr)))
		listSym.WriteBytes(ctxt, listSym.Size, entry.Expr)
	}

	// End entry.
	listSym.WriteInt(ctxt, listSym.Size, ctxt.Arch.PtrSize, 0)
	listSym.WriteInt(ctxt, listSym.Size, ctxt.Arch.PtrSize, 0)
}

// locatePrologEnd walks the entry block of a function with incoming
// register arguments and locates the last instruction in the prolog
// that spills a register arg. It returns the ID of that instruction,
// and (where appropriate) the prolog's lowered closure ptr store inst.
//
// Example:
//
//	b1:
//	    v3 = ArgIntReg <int> {p1+0} [0] : AX
//	    ... more arg regs ..
//	    v4 = ArgFloatReg <float32> {f1+0} [0] : X0
//	    v52 = MOVQstore <mem> {p1} v2 v3 v1
//	    ... more stores ...
//	    v68 = MOVSSstore <mem> {f4} v2 v67 v66
//	    v38 = MOVQstoreconst <mem> {blob} [val=0,off=0] v2 v32
//
// Important: locatePrologEnd is expected to work properly only with
// optimization turned off (e.g. "-N"). If optimization is enabled
// we can't be assured of finding all input arguments spilled in the
// entry block prolog.
func locatePrologEnd(f *ssa.Func, needCloCtx bool) (ssa.ID, *ssa.Value) {

	// returns true if this instruction looks like it moves an ABI
	// register (or context register for rangefunc bodies) to the
	// stack, along with the value being stored.
	isRegMoveLike := func(v *ssa.Value) (bool, ssa.ID) {
		n, ok := v.Aux.(*ir.Name)
		var r ssa.ID
		if (!ok || n.Class != ir.PPARAM) && !needCloCtx {
			return false, r
		}
		regInputs, memInputs, spInputs := 0, 0, 0
		for _, a := range v.Args {
			if a.Op == ssaop.OpArgIntReg || a.Op == ssaop.OpArgFloatReg ||
				(needCloCtx && a.Op.IsLoweredGetClosurePtr()) {
				regInputs++
				r = a.ID
			} else if a.Type.IsMemory() {
				memInputs++
			} else if a.Op == ssaop.OpSP {
				spInputs++
			} else {
				return false, r
			}
		}
		return v.Type.IsMemory() && memInputs == 1 &&
			regInputs == 1 && spInputs == 1, r
	}

	// OpArg*Reg values we've seen so far on our forward walk,
	// for which we have not yet seen a corresponding spill.
	regArgs := make([]ssa.ID, 0, 32)

	// removeReg tries to remove a value from regArgs, returning true
	// if found and removed, or false otherwise.
	removeReg := func(r ssa.ID) bool {
		for i := 0; i < len(regArgs); i++ {
			if regArgs[i] == r {
				regArgs = slices.Delete(regArgs, i, i+1)
				return true
			}
		}
		return false
	}

	// Walk forwards through the block. When we see OpArg*Reg, record
	// the value it produces in the regArgs list. When see a store that uses
	// the value, remove the entry. When we hit the last store (use)
	// then we've arrived at the end of the prolog.
	var cloRegStore *ssa.Value
	for k, v := range f.Entry.Values {
		if v.Op == ssaop.OpArgIntReg || v.Op == ssaop.OpArgFloatReg {
			regArgs = append(regArgs, v.ID)
			continue
		}
		if needCloCtx && v.Op.IsLoweredGetClosurePtr() {
			regArgs = append(regArgs, v.ID)
			cloRegStore = v
			continue
		}
		if ok, r := isRegMoveLike(v); ok {
			if removed := removeReg(r); removed {
				if len(regArgs) == 0 {
					// Found our last spill; return the value after
					// it. Note that it is possible that this spill is
					// the last instruction in the block. If so, then
					// return the "end of block" sentinel.
					if k < len(f.Entry.Values)-1 {
						return f.Entry.Values[k+1].ID, cloRegStore
					}
					return ssa.BlockEnd.ID, cloRegStore
				}
			}
		}
		if v.Op.IsCall() {
			// if we hit a call, we've gone too far.
			return v.ID, cloRegStore
		}
	}
	// nothing found
	return ssa.ID(-1), cloRegStore
}

// isNamedRegParam returns true if the param corresponding to "p"
// is a named, non-blank input parameter assigned to one or more
// registers.
func isNamedRegParam(p abi.ABIParamAssignment) bool {
	if p.Name == nil {
		return false
	}
	n := p.Name
	if n.Sym() == nil || n.Sym().IsBlank() {
		return false
	}
	if len(p.Registers) == 0 {
		return false
	}
	return true
}

// BuildFuncDebugNoOptimized populates a FuncDebug object "rval" with
// entries corresponding to the register-resident input parameters for
// the function "f"; it is used when we are compiling without
// optimization but the register ABI is enabled. For each reg param,
// it constructs a 2-element location list: the first element holds
// the input register, and the second element holds the stack location
// of the param (the assumption being that when optimization is off,
// each input param reg will be spilled in the prolog). In addition
// to the register params, here we also build location lists (where
// appropriate for the ".closureptr" compiler-synthesized variable
// needed by the debugger for range func bodies.
func BuildFuncDebugNoOptimized(ctxt *obj.Link, f *ssa.Func, loggingEnabled bool, stackOffset func(ssa.LocalSlot) int32, rval *FuncDebug) {
	needCloCtx := f.CloSlot != nil
	pri := f.ABISelf.ABIAnalyzeFuncType(f.Type)

	// Look to see if we have any named register-promoted parameters,
	// and/or whether we need location info for the ".closureptr"
	// synthetic variable; if not bail early and let the caller sort
	// things out for the remainder of the params/locals.
	numRegParams := 0
	for _, inp := range pri.InParams() {
		if isNamedRegParam(inp) {
			numRegParams++
		}
	}
	if numRegParams == 0 && !needCloCtx {
		return
	}

	state := ssa.DebugState{F: f}

	if loggingEnabled {
		state.Logf("generating -N reg param loc lists for func %q\n", f.Name)
	}

	// cloReg stores the obj register num that the context register
	// appears in within the function prolog, where appropriate.
	var cloReg int16

	extraForCloCtx := 0
	if needCloCtx {
		extraForCloCtx = 1
	}

	// Allocate location lists.
	rval.LocationLists = make([][]ssa.LocListEntry, numRegParams+extraForCloCtx)

	// Locate the value corresponding to the last spill of
	// an input register.
	afterPrologVal, cloRegStore := locatePrologEnd(f, needCloCtx)

	if needCloCtx {
		reg, _ := state.F.GetHome(cloRegStore.ID).(*ssabase.Register)
		cloReg = reg.ObjNum
		if loggingEnabled {
			state.Logf("needCloCtx is true for func %q, cloreg=%v\n",
				f.Name, reg)
		}
	}

	addVarSlot := func(name *ir.Name, typ *types.Type) {
		sl := ssa.LocalSlot{N: name, Type: typ, Off: 0}
		rval.Vars = append(rval.Vars, name)
		rval.Slots = append(rval.Slots, sl)
		slid := len(rval.VarSlots)
		rval.VarSlots = append(rval.VarSlots, []ssa.SlotID{ssa.SlotID(slid)})
	}

	// Make an initial pass to populate the vars/slots for our return
	// value, covering first the input parameters and then (if needed)
	// the special ".closureptr" var for rangefunc bodies.
	params := []abi.ABIParamAssignment{}
	for _, inp := range pri.InParams() {
		if !isNamedRegParam(inp) {
			// will be sorted out elsewhere
			continue
		}
		if !ssa.IsVarWantedForDebug(inp.Name) {
			continue
		}
		addVarSlot(inp.Name, inp.Type)
		params = append(params, inp)
	}
	if needCloCtx {
		addVarSlot(f.CloSlot, f.CloSlot.Type())
		cloAssign := abi.ABIParamAssignment{
			Type:      f.CloSlot.Type(),
			Name:      f.CloSlot,
			Registers: []abi.RegIndex{0}, // dummy
		}
		params = append(params, cloAssign)
	}

	// Walk the input params again and process the register-resident elements.
	pidx := 0
	for _, inp := range params {
		if !isNamedRegParam(inp) {
			// will be sorted out elsewhere
			continue
		}
		if !ssa.IsVarWantedForDebug(inp.Name) {
			continue
		}

		sl := rval.Slots[pidx]
		n := rval.Vars[pidx]

		if afterPrologVal == ssa.ID(-1) {
			// This can happen for degenerate functions with infinite
			// loops such as that in issue 45948. In such cases, leave
			// the var/slot set up for the param, but don't try to
			// emit a location list.
			if loggingEnabled {
				state.Logf("locatePrologEnd failed, skipping %v\n", n)
			}
			pidx++
			continue
		}

		// Param is arriving in one or more registers. We need a 2-element
		// location expression for it. First entry in location list
		// will correspond to lifetime in input registers.
		if loggingEnabled {
			state.Logf("param %v:\n  [<entry>, %d]:\n", n, afterPrologVal)
		}
		var regExpr []byte
		rtypes, _ := inp.RegisterTypesAndOffsets()
		padding := make([]uint64, 0, 32)
		padding = inp.ComputePadding(padding)
		for k, r := range inp.Registers {
			var reg int16
			if n == f.CloSlot {
				reg = cloReg
			} else {
				reg = ssa.ObjRegForAbiReg(r, f.Config)
			}
			dwreg := ctxt.Arch.DWARFRegisters[reg]
			if dwreg < 32 {
				regExpr = append(regExpr, dwarf.DW_OP_reg0+byte(dwreg))
			} else {
				regExpr = append(regExpr, dwarf.DW_OP_regx)
				regExpr = dwarf.AppendUleb128(regExpr, uint64(dwreg))
			}
			if loggingEnabled {
				state.Logf("    piece %d -> dwreg %d", k, dwreg)
			}
			if len(inp.Registers) > 1 {
				regExpr = append(regExpr, dwarf.DW_OP_piece)
				ts := rtypes[k].Size()
				regExpr = dwarf.AppendUleb128(regExpr, uint64(ts))
				if padding[k] > 0 {
					if loggingEnabled {
						state.Logf(" [pad %d bytes]", padding[k])
					}
					regExpr = append(regExpr, dwarf.DW_OP_piece)
					regExpr = dwarf.AppendUleb128(regExpr, padding[k])
				}
			}
			if loggingEnabled {
				state.Logf("\n")
			}
		}
		rval.LocationLists[pidx] = append(rval.LocationLists[pidx], ssa.LocListEntry{
			StartBlock: f.Entry.ID,
			StartValue: ssa.BlockStart.ID,
			EndBlock:   f.Entry.ID,
			EndValue:   afterPrologVal,
			Expr:       regExpr,
		})

		// Second entry in the location list will be the stack home
		// of the param, once it has been spilled.  Emit that now.
		var stackExpr []byte
		soff := stackOffset(sl)
		if soff == 0 {
			stackExpr = append(stackExpr, dwarf.DW_OP_call_frame_cfa)
		} else {
			stackExpr = append(stackExpr, dwarf.DW_OP_fbreg)
			stackExpr = dwarf.AppendSleb128(stackExpr, int64(soff))
		}
		if loggingEnabled {
			state.Logf("  [%d, <end>): stackOffset=%d\n", afterPrologVal, soff)
		}

		rval.LocationLists[pidx] = append(rval.LocationLists[pidx], ssa.LocListEntry{
			StartBlock: f.Entry.ID,
			StartValue: afterPrologVal,
			EndBlock:   f.Entry.ID,
			EndValue:   ssa.FuncEnd.ID,
			Expr:       stackExpr,
		})

		pidx++
	}
}
