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

import (
	"cmd/compile/internal/abi"
	"cmd/compile/internal/ir"
	"cmd/compile/internal/types"
	"cmd/internal/dwarf"
	"cmd/internal/obj"
	"cmd/internal/src"
	"encoding/hex"
	"fmt"
	"internal/buildcfg"
	"math/bits"
	"sort"
	"strings"
)

type SlotID int32
type VarID int32

// 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 []LocalSlot
	// The user variables, indexed by VarID.
	Vars []*ir.Name
	// The slots that make up each variable, indexed by VarID.
	VarSlots [][]SlotID
	// The location list data, indexed by VarID. Must be processed by PutLocationList.
	LocationLists [][]byte
	// Register-resident output parameters for the function. This is filled in at
	// SSA generation time.
	RegOutputParams []*ir.Name

	// Filled in by the user. Translates Block and Value ID to PC.
	GetPC func(ID, ID) int64
}

type BlockDebug struct {
	// Whether the block had any changes to user variables at all.
	relevant bool
	// State at the end of the block if it's fully processed. Immutable once initialized.
	endState []liveSlot
}

// A liveSlot is a slot that's live in loc at entry/exit of a block.
type liveSlot struct {
	// An inlined VarLoc, so it packs into 16 bytes instead of 20.
	Registers RegisterSet
	StackOffset

	slot SlotID
}

func (loc liveSlot) absent() bool {
	return loc.Registers == 0 && !loc.onStack()
}

// StackOffset encodes whether a value is on the stack and if so, where. It is
// a 31-bit integer followed by a presence flag at the low-order bit.
type StackOffset int32

func (s StackOffset) onStack() bool {
	return s != 0
}

func (s StackOffset) stackOffsetValue() int32 {
	return int32(s) >> 1
}

// stateAtPC is the current state of all variables at some point.
type stateAtPC struct {
	// The location of each known slot, indexed by SlotID.
	slots []VarLoc
	// The slots present in each register, indexed by register number.
	registers [][]SlotID
}

// reset fills state with the live variables from live.
func (state *stateAtPC) reset(live []liveSlot) {
	slots, registers := state.slots, state.registers
	for i := range slots {
		slots[i] = VarLoc{}
	}
	for i := range registers {
		registers[i] = registers[i][:0]
	}
	for _, live := range live {
		slots[live.slot] = VarLoc{live.Registers, live.StackOffset}
		if live.Registers == 0 {
			continue
		}

		mask := uint64(live.Registers)
		for {
			if mask == 0 {
				break
			}
			reg := uint8(bits.TrailingZeros64(mask))
			mask &^= 1 << reg

			registers[reg] = append(registers[reg], live.slot)
		}
	}
	state.slots, state.registers = slots, registers
}

func (s *debugState) LocString(loc VarLoc) string {
	if loc.absent() {
		return "<nil>"
	}

	var storage []string
	if loc.onStack() {
		storage = append(storage, "stack")
	}

	mask := uint64(loc.Registers)
	for {
		if mask == 0 {
			break
		}
		reg := uint8(bits.TrailingZeros64(mask))
		mask &^= 1 << reg

		storage = append(storage, s.registers[reg].String())
	}
	return strings.Join(storage, ",")
}

// A VarLoc describes the storage for part of a user variable.
type VarLoc struct {
	// The registers this variable is available in. There can be more than
	// one in various situations, e.g. it's being moved between registers.
	Registers RegisterSet

	StackOffset
}

func (loc VarLoc) absent() bool {
	return loc.Registers == 0 && !loc.onStack()
}

var BlockStart = &Value{
	ID:  -10000,
	Op:  OpInvalid,
	Aux: StringToAux("BlockStart"),
}

var BlockEnd = &Value{
	ID:  -20000,
	Op:  OpInvalid,
	Aux: StringToAux("BlockEnd"),
}

var FuncEnd = &Value{
	ID:  -30000,
	Op:  OpInvalid,
	Aux: StringToAux("FuncEnd"),
}

// RegisterSet is a bitmap of registers, indexed by Register.num.
type RegisterSet uint64

// logf prints debug-specific logging to stdout (always stdout) if the current
// function is tagged by GOSSAFUNC (for ssa output directed either to stdout or html).
func (s *debugState) logf(msg string, args ...interface{}) {
	if s.f.PrintOrHtmlSSA {
		fmt.Printf(msg, args...)
	}
}

type debugState struct {
	// See FuncDebug.
	slots    []LocalSlot
	vars     []*ir.Name
	varSlots [][]SlotID
	lists    [][]byte

	// The user variable that each slot rolls up to, indexed by SlotID.
	slotVars []VarID

	f              *Func
	loggingEnabled bool
	registers      []Register
	stackOffset    func(LocalSlot) int32
	ctxt           *obj.Link

	// The names (slots) associated with each value, indexed by Value ID.
	valueNames [][]SlotID

	// The current state of whatever analysis is running.
	currentState stateAtPC
	liveCount    []int
	changedVars  *sparseSet

	// The pending location list entry for each user variable, indexed by VarID.
	pendingEntries []pendingEntry

	varParts           map[*ir.Name][]SlotID
	blockDebug         []BlockDebug
	pendingSlotLocs    []VarLoc
	liveSlots          []liveSlot
	liveSlotSliceBegin int
	partsByVarOffset   sort.Interface
}

func (state *debugState) initializeCache(f *Func, numVars, numSlots int) {
	// One blockDebug per block. Initialized in allocBlock.
	if cap(state.blockDebug) < f.NumBlocks() {
		state.blockDebug = make([]BlockDebug, f.NumBlocks())
	} else {
		// This local variable, and the ones like it below, enable compiler
		// optimizations. Don't inline them.
		b := state.blockDebug[:f.NumBlocks()]
		for i := range b {
			b[i] = BlockDebug{}
		}
	}

	// A list of slots per Value. Reuse the previous child slices.
	if cap(state.valueNames) < f.NumValues() {
		old := state.valueNames
		state.valueNames = make([][]SlotID, f.NumValues())
		copy(state.valueNames, old)
	}
	vn := state.valueNames[:f.NumValues()]
	for i := range vn {
		vn[i] = vn[i][:0]
	}

	// Slot and register contents for currentState. Cleared by reset().
	if cap(state.currentState.slots) < numSlots {
		state.currentState.slots = make([]VarLoc, numSlots)
	} else {
		state.currentState.slots = state.currentState.slots[:numSlots]
	}
	if cap(state.currentState.registers) < len(state.registers) {
		state.currentState.registers = make([][]SlotID, len(state.registers))
	} else {
		state.currentState.registers = state.currentState.registers[:len(state.registers)]
	}

	// Used many times by mergePredecessors.
	if cap(state.liveCount) < numSlots {
		state.liveCount = make([]int, numSlots)
	} else {
		state.liveCount = state.liveCount[:numSlots]
	}

	// A relatively small slice, but used many times as the return from processValue.
	state.changedVars = newSparseSet(numVars)

	// A pending entry per user variable, with space to track each of its pieces.
	numPieces := 0
	for i := range state.varSlots {
		numPieces += len(state.varSlots[i])
	}
	if cap(state.pendingSlotLocs) < numPieces {
		state.pendingSlotLocs = make([]VarLoc, numPieces)
	} else {
		psl := state.pendingSlotLocs[:numPieces]
		for i := range psl {
			psl[i] = VarLoc{}
		}
	}
	if cap(state.pendingEntries) < numVars {
		state.pendingEntries = make([]pendingEntry, numVars)
	}
	pe := state.pendingEntries[:numVars]
	freePieceIdx := 0
	for varID, slots := range state.varSlots {
		pe[varID] = pendingEntry{
			pieces: state.pendingSlotLocs[freePieceIdx : freePieceIdx+len(slots)],
		}
		freePieceIdx += len(slots)
	}
	state.pendingEntries = pe

	if cap(state.lists) < numVars {
		state.lists = make([][]byte, numVars)
	} else {
		state.lists = state.lists[:numVars]
		for i := range state.lists {
			state.lists[i] = nil
		}
	}

	state.liveSlots = state.liveSlots[:0]
	state.liveSlotSliceBegin = 0
}

func (state *debugState) allocBlock(b *Block) *BlockDebug {
	return &state.blockDebug[b.ID]
}

func (state *debugState) appendLiveSlot(ls liveSlot) {
	state.liveSlots = append(state.liveSlots, ls)
}

func (state *debugState) getLiveSlotSlice() []liveSlot {
	s := state.liveSlots[state.liveSlotSliceBegin:]
	state.liveSlotSliceBegin = len(state.liveSlots)
	return s
}

func (s *debugState) blockEndStateString(b *BlockDebug) string {
	endState := stateAtPC{slots: make([]VarLoc, len(s.slots)), registers: make([][]SlotID, len(s.registers))}
	endState.reset(b.endState)
	return s.stateString(endState)
}

func (s *debugState) stateString(state stateAtPC) string {
	var strs []string
	for slotID, loc := range state.slots {
		if !loc.absent() {
			strs = append(strs, fmt.Sprintf("\t%v = %v\n", s.slots[slotID], s.LocString(loc)))
		}
	}

	strs = append(strs, "\n")
	for reg, slots := range state.registers {
		if len(slots) != 0 {
			var slotStrs []string
			for _, slot := range slots {
				slotStrs = append(slotStrs, s.slots[slot].String())
			}
			strs = append(strs, fmt.Sprintf("\t%v = %v\n", &s.registers[reg], slotStrs))
		}
	}

	if len(strs) == 1 {
		return "(no vars)\n"
	}
	return strings.Join(strs, "")
}

// 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 []LocalSlot
}

func newSlotCanonicalizer() *slotCanonicalizer {
	return &slotCanonicalizer{
		slmap:  make(map[slotKey]SlKeyIdx),
		slkeys: []LocalSlot{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 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) 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 *Func) {
	pri := f.ABISelf.ABIAnalyzeFuncType(f.Type.FuncType())

	// 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 *Value, sl LocalSlot) {
		values, ok := f.NamedValues[sl]
		if !ok {
			// Haven't seen this slot yet.
			sla := f.localSlotAddr(sl)
			f.Names = append(f.Names, sla)
		} else {
			for _, ev := range values {
				if v == ev {
					return
				}
			}
		}
		values = append(values, v)
		f.NamedValues[sl] = values
	}

	newValues := []*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 LocalSlot) *Value {
		aux := &AuxNameOffset{n, sl.Off}
		op, auxInt := 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 == OpArgIntReg || v.Op == OpArgFloatReg {
			aux := v.Aux.(*AuxNameOffset)
			sl := 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.(*ir.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 := 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 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 *Func, loggingEnabled bool, stackOffset func(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.loggingEnabled = loggingEnabled
	state.f = f
	state.registers = f.Config.registers
	state.stackOffset = stackOffset
	state.ctxt = ctxt

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

	if state.loggingEnabled {
		state.logf("Generating location lists for function %q\n", f.Name)
	}

	if state.varParts == nil {
		state.varParts = make(map[*ir.Name][]SlotID)
	} else {
		for n := range state.varParts {
			delete(state.varParts, n)
		}
	}

	// 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) {
			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], 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 == OpVarDef || v.Op == OpVarKill {
				n := v.Aux.(*ir.Name)
				if ir.IsSynthetic(n) {
					continue
				}

				if _, ok := state.varParts[n]; !ok {
					slot := LocalSlot{N: n, Type: v.Type, Off: 0}
					state.slots = append(state.slots, slot)
					state.varParts[n] = []SlotID{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([][]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([]VarID, len(state.slots))
	} else {
		state.slotVars = state.slotVars[:len(state.slots)]
	}

	if state.partsByVarOffset == nil {
		state.partsByVarOffset = &partsByVarOffset{}
	}
	for varID, n := range state.vars {
		parts := state.varParts[n]
		state.varSlots[varID] = parts
		for _, slotID := range parts {
			state.slotVars[slotID] = VarID(varID)
		}
		*state.partsByVarOffset.(*partsByVarOffset) = partsByVarOffset{parts, state.slots}
		sort.Sort(state.partsByVarOffset)
	}

	state.initializeCache(f, len(state.varParts), len(state.slots))

	for i, slot := range f.Names {
		if ir.IsSynthetic(slot.N) {
			continue
		}
		for _, value := range f.NamedValues[*slot] {
			state.valueNames[value.ID] = append(state.valueNames[value.ID], 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
}

// liveness walks the function in control flow order, calculating the start
// and end state of each block.
func (state *debugState) liveness() []*BlockDebug {
	blockLocs := make([]*BlockDebug, state.f.NumBlocks())

	// Reverse postorder: visit a block after as many as possible of its
	// predecessors have been visited.
	po := state.f.Postorder()
	for i := len(po) - 1; i >= 0; i-- {
		b := po[i]

		// Build the starting state for the block from the final
		// state of its predecessors.
		startState, startValid := state.mergePredecessors(b, blockLocs, nil)
		changed := false
		if state.loggingEnabled {
			state.logf("Processing %v, initial state:\n%v", b, state.stateString(state.currentState))
		}

		// Update locs/registers with the effects of each Value.
		for _, v := range b.Values {
			slots := state.valueNames[v.ID]

			// Loads and stores inherit the names of their sources.
			var source *Value
			switch v.Op {
			case OpStoreReg:
				source = v.Args[0]
			case OpLoadReg:
				switch a := v.Args[0]; a.Op {
				case OpArg, OpPhi:
					source = a
				case OpStoreReg:
					source = a.Args[0]
				default:
					if state.loggingEnabled {
						state.logf("at %v: load with unexpected source op: %v (%v)\n", v, a.Op, a)
					}
				}
			}
			// Update valueNames with the source so that later steps
			// don't need special handling.
			if source != nil {
				slots = append(slots, state.valueNames[source.ID]...)
				state.valueNames[v.ID] = slots
			}

			reg, _ := state.f.getHome(v.ID).(*Register)
			c := state.processValue(v, slots, reg)
			changed = changed || c
		}

		if state.loggingEnabled {
			state.f.Logf("Block %v done, locs:\n%v", b, state.stateString(state.currentState))
		}

		locs := state.allocBlock(b)
		locs.relevant = changed
		if !changed && startValid {
			locs.endState = startState
		} else {
			for slotID, slotLoc := range state.currentState.slots {
				if slotLoc.absent() {
					continue
				}
				state.appendLiveSlot(liveSlot{slot: SlotID(slotID), Registers: slotLoc.Registers, StackOffset: slotLoc.StackOffset})
			}
			locs.endState = state.getLiveSlotSlice()
		}
		blockLocs[b.ID] = locs
	}
	return blockLocs
}

// mergePredecessors takes the end state of each of b's predecessors and
// intersects them to form the starting state for b. It puts that state in
// blockLocs, and fills state.currentState with it. If convenient, it returns
// a reused []liveSlot, true that represents the starting state.
// If previousBlock is non-nil, it registers changes vs. that block's end
// state in state.changedVars. Note that previousBlock will often not be a
// predecessor.
func (state *debugState) mergePredecessors(b *Block, blockLocs []*BlockDebug, previousBlock *Block) ([]liveSlot, bool) {
	// Filter out back branches.
	var predsBuf [10]*Block
	preds := predsBuf[:0]
	for _, pred := range b.Preds {
		if blockLocs[pred.b.ID] != nil {
			preds = append(preds, pred.b)
		}
	}

	if state.loggingEnabled {
		// The logf below would cause preds to be heap-allocated if
		// it were passed directly.
		preds2 := make([]*Block, len(preds))
		copy(preds2, preds)
		state.logf("Merging %v into %v\n", preds2, b)
	}

	// TODO all the calls to this are overkill; only need to do this for slots that are not present in the merge.
	markChangedVars := func(slots []liveSlot) {
		for _, live := range slots {
			state.changedVars.add(ID(state.slotVars[live.slot]))
		}
	}

	if len(preds) == 0 {
		if previousBlock != nil {
			// Mark everything in previous block as changed because it is not a predecessor.
			markChangedVars(blockLocs[previousBlock.ID].endState)
		}
		state.currentState.reset(nil)
		return nil, true
	}

	p0 := blockLocs[preds[0].ID].endState
	if len(preds) == 1 {
		if previousBlock != nil && preds[0].ID != previousBlock.ID {
			// Mark everything in previous block as changed because it is not a predecessor.
			markChangedVars(blockLocs[previousBlock.ID].endState)
		}
		state.currentState.reset(p0)
		return p0, true
	}

	baseID := preds[0].ID
	baseState := p0

	// If previous block is not a predecessor, its location information changes at boundary with this block.
	previousBlockIsNotPredecessor := previousBlock != nil // If it's nil, no info to change.

	if previousBlock != nil {
		// Try to use previousBlock as the base state
		// if possible.
		for _, pred := range preds[1:] {
			if pred.ID == previousBlock.ID {
				baseID = pred.ID
				baseState = blockLocs[pred.ID].endState
				previousBlockIsNotPredecessor = false
				break
			}
		}
	}

	if state.loggingEnabled {
		state.logf("Starting %v with state from b%v:\n%v", b, baseID, state.blockEndStateString(blockLocs[baseID]))
	}

	slotLocs := state.currentState.slots
	for _, predSlot := range baseState {
		slotLocs[predSlot.slot] = VarLoc{predSlot.Registers, predSlot.StackOffset}
		state.liveCount[predSlot.slot] = 1
	}
	for _, pred := range preds {
		if pred.ID == baseID {
			continue
		}
		if state.loggingEnabled {
			state.logf("Merging in state from %v:\n%v", pred, state.blockEndStateString(blockLocs[pred.ID]))
		}
		for _, predSlot := range blockLocs[pred.ID].endState {
			state.liveCount[predSlot.slot]++
			liveLoc := slotLocs[predSlot.slot]
			if !liveLoc.onStack() || !predSlot.onStack() || liveLoc.StackOffset != predSlot.StackOffset {
				liveLoc.StackOffset = 0
			}
			liveLoc.Registers &= predSlot.Registers
			slotLocs[predSlot.slot] = liveLoc
		}
	}

	// Check if the final state is the same as the first predecessor's
	// final state, and reuse it if so. In principle it could match any,
	// but it's probably not worth checking more than the first.
	unchanged := true
	for _, predSlot := range baseState {
		if state.liveCount[predSlot.slot] != len(preds) ||
			slotLocs[predSlot.slot].Registers != predSlot.Registers ||
			slotLocs[predSlot.slot].StackOffset != predSlot.StackOffset {
			unchanged = false
			break
		}
	}
	if unchanged {
		if state.loggingEnabled {
			state.logf("After merge, %v matches b%v exactly.\n", b, baseID)
		}
		if previousBlockIsNotPredecessor {
			// Mark everything in previous block as changed because it is not a predecessor.
			markChangedVars(blockLocs[previousBlock.ID].endState)
		}
		state.currentState.reset(baseState)
		return baseState, true
	}

	for reg := range state.currentState.registers {
		state.currentState.registers[reg] = state.currentState.registers[reg][:0]
	}

	// A slot is live if it was seen in all predecessors, and they all had
	// some storage in common.
	for _, predSlot := range baseState {
		slotLoc := slotLocs[predSlot.slot]

		if state.liveCount[predSlot.slot] != len(preds) {
			// Seen in only some predecessors. Clear it out.
			slotLocs[predSlot.slot] = VarLoc{}
			continue
		}

		// Present in all predecessors.
		mask := uint64(slotLoc.Registers)
		for {
			if mask == 0 {
				break
			}
			reg := uint8(bits.TrailingZeros64(mask))
			mask &^= 1 << reg
			state.currentState.registers[reg] = append(state.currentState.registers[reg], predSlot.slot)
		}
	}

	if previousBlockIsNotPredecessor {
		// Mark everything in previous block as changed because it is not a predecessor.
		markChangedVars(blockLocs[previousBlock.ID].endState)

	}
	return nil, false
}

// processValue updates locs and state.registerContents to reflect v, a value with
// the names in vSlots and homed in vReg.  "v" becomes visible after execution of
// the instructions evaluating it. It returns which VarIDs were modified by the
// Value's execution.
func (state *debugState) processValue(v *Value, vSlots []SlotID, vReg *Register) bool {
	locs := state.currentState
	changed := false
	setSlot := func(slot SlotID, loc VarLoc) {
		changed = true
		state.changedVars.add(ID(state.slotVars[slot]))
		state.currentState.slots[slot] = loc
	}

	// Handle any register clobbering. Call operations, for example,
	// clobber all registers even though they don't explicitly write to
	// them.
	clobbers := uint64(opcodeTable[v.Op].reg.clobbers)
	for {
		if clobbers == 0 {
			break
		}
		reg := uint8(bits.TrailingZeros64(clobbers))
		clobbers &^= 1 << reg

		for _, slot := range locs.registers[reg] {
			if state.loggingEnabled {
				state.logf("at %v: %v clobbered out of %v\n", v, state.slots[slot], &state.registers[reg])
			}

			last := locs.slots[slot]
			if last.absent() {
				state.f.Fatalf("at %v: slot %v in register %v with no location entry", v, state.slots[slot], &state.registers[reg])
				continue
			}
			regs := last.Registers &^ (1 << reg)
			setSlot(slot, VarLoc{regs, last.StackOffset})
		}

		locs.registers[reg] = locs.registers[reg][:0]
	}

	switch {
	case v.Op == OpVarDef, v.Op == OpVarKill:
		n := v.Aux.(*ir.Name)
		if ir.IsSynthetic(n) {
			break
		}

		slotID := state.varParts[n][0]
		var stackOffset StackOffset
		if v.Op == OpVarDef {
			stackOffset = StackOffset(state.stackOffset(state.slots[slotID])<<1 | 1)
		}
		setSlot(slotID, VarLoc{0, stackOffset})
		if state.loggingEnabled {
			if v.Op == OpVarDef {
				state.logf("at %v: stack-only var %v now live\n", v, state.slots[slotID])
			} else {
				state.logf("at %v: stack-only var %v now dead\n", v, state.slots[slotID])
			}
		}

	case v.Op == OpArg:
		home := state.f.getHome(v.ID).(LocalSlot)
		stackOffset := state.stackOffset(home)<<1 | 1
		for _, slot := range vSlots {
			if state.loggingEnabled {
				state.logf("at %v: arg %v now on stack in location %v\n", v, state.slots[slot], home)
				if last := locs.slots[slot]; !last.absent() {
					state.logf("at %v: unexpected arg op on already-live slot %v\n", v, state.slots[slot])
				}
			}

			setSlot(slot, VarLoc{0, StackOffset(stackOffset)})
		}

	case v.Op == OpStoreReg:
		home := state.f.getHome(v.ID).(LocalSlot)
		stackOffset := state.stackOffset(home)<<1 | 1
		for _, slot := range vSlots {
			last := locs.slots[slot]
			if last.absent() {
				if state.loggingEnabled {
					state.logf("at %v: unexpected spill of unnamed register %s\n", v, vReg)
				}
				break
			}

			setSlot(slot, VarLoc{last.Registers, StackOffset(stackOffset)})
			if state.loggingEnabled {
				state.logf("at %v: %v spilled to stack location %v\n", v, state.slots[slot], home)
			}
		}

	case vReg != nil:
		if state.loggingEnabled {
			newSlots := make([]bool, len(state.slots))
			for _, slot := range vSlots {
				newSlots[slot] = true
			}

			for _, slot := range locs.registers[vReg.num] {
				if !newSlots[slot] {
					state.logf("at %v: overwrote %v in register %v\n", v, state.slots[slot], vReg)
				}
			}
		}

		for _, slot := range locs.registers[vReg.num] {
			last := locs.slots[slot]
			setSlot(slot, VarLoc{last.Registers &^ (1 << uint8(vReg.num)), last.StackOffset})
		}
		locs.registers[vReg.num] = locs.registers[vReg.num][:0]
		locs.registers[vReg.num] = append(locs.registers[vReg.num], vSlots...)
		for _, slot := range vSlots {
			if state.loggingEnabled {
				state.logf("at %v: %v now in %s\n", v, state.slots[slot], vReg)
			}

			last := locs.slots[slot]
			setSlot(slot, VarLoc{1<<uint8(vReg.num) | last.Registers, last.StackOffset})
		}
	}
	return changed
}

// 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 LocalSlot) int64 {
	offset := slot.Off
	s := &slot
	for ; s.SplitOf != nil; s = s.SplitOf {
		offset += s.SplitOffset
	}
	return offset
}

type partsByVarOffset struct {
	slotIDs []SlotID
	slots   []LocalSlot
}

func (a partsByVarOffset) Len() int { return len(a.slotIDs) }
func (a partsByVarOffset) Less(i, j int) bool {
	return varOffset(a.slots[a.slotIDs[i]]) < varOffset(a.slots[a.slotIDs[j]])
}
func (a partsByVarOffset) Swap(i, j int) { a.slotIDs[i], a.slotIDs[j] = a.slotIDs[j], a.slotIDs[i] }

// A pendingEntry represents the beginning of a location list entry, missing
// only its end coordinate.
type pendingEntry struct {
	present                bool
	startBlock, startValue ID
	// The location of each piece of the variable, in the same order as the
	// SlotIDs in varParts.
	pieces []VarLoc
}

func (e *pendingEntry) clear() {
	e.present = false
	e.startBlock = 0
	e.startValue = 0
	for i := range e.pieces {
		e.pieces[i] = VarLoc{}
	}
}

// canMerge reports whether the location description for new is the same as
// pending.
func canMerge(pending, new VarLoc) bool {
	if pending.absent() && new.absent() {
		return true
	}
	if pending.absent() || new.absent() {
		return false
	}
	if pending.onStack() {
		return pending.StackOffset == new.StackOffset
	}
	if pending.Registers != 0 && new.Registers != 0 {
		return firstReg(pending.Registers) == firstReg(new.Registers)
	}
	return false
}

// firstReg returns the first register in set that is present.
func firstReg(set RegisterSet) uint8 {
	if set == 0 {
		// This is wrong, but there seem to be some situations where we
		// produce locations with no storage.
		return 0
	}
	return uint8(bits.TrailingZeros64(uint64(set)))
}

// buildLocationLists builds location lists for all the user variables in
// state.f, using the information about block state in blockLocs.
// The returned location lists are not fully complete. They are in terms of
// SSA values rather than PCs, and have no base address/end entries. They will
// be finished by PutLocationList.
func (state *debugState) buildLocationLists(blockLocs []*BlockDebug) {
	// Run through the function in program text order, building up location
	// lists as we go. The heavy lifting has mostly already been done.

	var prevBlock *Block
	for _, b := range state.f.Blocks {
		state.mergePredecessors(b, blockLocs, prevBlock)

		if !blockLocs[b.ID].relevant {
			// Handle any differences among predecessor blocks and previous block (perhaps not a predecessor)
			for _, varID := range state.changedVars.contents() {
				state.updateVar(VarID(varID), b, BlockStart)
			}
			continue
		}

		mustBeFirst := func(v *Value) bool {
			return v.Op == OpPhi || v.Op.isLoweredGetClosurePtr() ||
				v.Op == OpArgIntReg || v.Op == OpArgFloatReg
		}

		blockPrologComplete := func(v *Value) bool {
			if b.ID != state.f.Entry.ID {
				return !opcodeTable[v.Op].zeroWidth
			} else {
				return v.Op == OpInitMem
			}
		}

		// Examine the prolog portion of the block to process special
		// zero-width ops such as Arg, Phi, LoweredGetClosurePtr (etc)
		// whose lifetimes begin at the block starting point. In an
		// entry block, allow for the possibility that we may see Arg
		// ops that appear _after_ other non-zero-width operations.
		// Example:
		//
		//   v33 = ArgIntReg <uintptr> {foo+0} [0] : AX (foo)
		//   v34 = ArgIntReg <uintptr> {bar+0} [0] : BX (bar)
		//   ...
		//   v77 = StoreReg <unsafe.Pointer> v67 : ctx+8[unsafe.Pointer]
		//   v78 = StoreReg <unsafe.Pointer> v68 : ctx[unsafe.Pointer]
		//   v79 = Arg <*uint8> {args} : args[*uint8] (args[*uint8])
		//   v80 = Arg <int> {args} [8] : args+8[int] (args+8[int])
		//   ...
		//   v1 = InitMem <mem>
		//
		// We can stop scanning the initial portion of the block when
		// we either see the InitMem op (for entry blocks) or the
		// first non-zero-width op (for other blocks).
		for idx := 0; idx < len(b.Values); idx++ {
			v := b.Values[idx]
			if blockPrologComplete(v) {
				break
			}
			// Consider only "lifetime begins at block start" ops.
			if !mustBeFirst(v) && v.Op != OpArg {
				continue
			}
			slots := state.valueNames[v.ID]
			reg, _ := state.f.getHome(v.ID).(*Register)
			changed := state.processValue(v, slots, reg) // changed == added to state.changedVars
			if changed {
				for _, varID := range state.changedVars.contents() {
					state.updateVar(VarID(varID), v.Block, BlockStart)
				}
				state.changedVars.clear()
			}
		}

		// Now examine the block again, handling things other than the
		// "begins at block start" lifetimes.
		zeroWidthPending := false
		prologComplete := false
		// expect to see values in pattern (apc)* (zerowidth|real)*
		for _, v := range b.Values {
			if blockPrologComplete(v) {
				prologComplete = true
			}
			slots := state.valueNames[v.ID]
			reg, _ := state.f.getHome(v.ID).(*Register)
			changed := state.processValue(v, slots, reg) // changed == added to state.changedVars

			if opcodeTable[v.Op].zeroWidth {
				if prologComplete && mustBeFirst(v) {
					panic(fmt.Errorf("Unexpected placement of op '%s' appearing after non-pseudo-op at beginning of block %s in %s\n%s", v.LongString(), b, b.Func.Name, b.Func))
				}
				if changed {
					if mustBeFirst(v) || v.Op == OpArg {
						// already taken care of above
						continue
					}
					zeroWidthPending = true
				}
				continue
			}
			if !changed && !zeroWidthPending {
				continue
			}

			// Not zero-width; i.e., a "real" instruction.
			zeroWidthPending = false
			for _, varID := range state.changedVars.contents() {
				state.updateVar(VarID(varID), v.Block, v)
			}
			state.changedVars.clear()
		}
		for _, varID := range state.changedVars.contents() {
			state.updateVar(VarID(varID), b, BlockEnd)
		}

		prevBlock = b
	}

	if state.loggingEnabled {
		state.logf("location lists:\n")
	}

	// Flush any leftover entries live at the end of the last block.
	for varID := range state.lists {
		state.writePendingEntry(VarID(varID), state.f.Blocks[len(state.f.Blocks)-1].ID, FuncEnd.ID)
		list := state.lists[varID]
		if state.loggingEnabled {
			if len(list) == 0 {
				state.logf("\t%v : empty list\n", state.vars[varID])
			} else {
				state.logf("\t%v : %q\n", state.vars[varID], hex.EncodeToString(state.lists[varID]))
			}
		}
	}
}

// updateVar updates the pending location list entry for varID to
// reflect the new locations in curLoc, beginning at v in block b.
// v may be one of the special values indicating block start or end.
func (state *debugState) updateVar(varID VarID, b *Block, v *Value) {
	curLoc := state.currentState.slots
	// Assemble the location list entry with whatever's live.
	empty := true
	for _, slotID := range state.varSlots[varID] {
		if !curLoc[slotID].absent() {
			empty = false
			break
		}
	}
	pending := &state.pendingEntries[varID]
	if empty {
		state.writePendingEntry(varID, b.ID, v.ID)
		pending.clear()
		return
	}

	// Extend the previous entry if possible.
	if pending.present {
		merge := true
		for i, slotID := range state.varSlots[varID] {
			if !canMerge(pending.pieces[i], curLoc[slotID]) {
				merge = false
				break
			}
		}
		if merge {
			return
		}
	}

	state.writePendingEntry(varID, b.ID, v.ID)
	pending.present = true
	pending.startBlock = b.ID
	pending.startValue = v.ID
	for i, slot := range state.varSlots[varID] {
		pending.pieces[i] = curLoc[slot]
	}
}

// writePendingEntry writes out the pending entry for varID, if any,
// terminated at endBlock/Value.
func (state *debugState) writePendingEntry(varID VarID, endBlock, endValue ID) {
	pending := state.pendingEntries[varID]
	if !pending.present {
		return
	}

	// Pack the start/end coordinates into the start/end addresses
	// of the entry, for decoding by PutLocationList.
	start, startOK := encodeValue(state.ctxt, pending.startBlock, pending.startValue)
	end, endOK := encodeValue(state.ctxt, endBlock, endValue)
	if !startOK || !endOK {
		// If someone writes a function that uses >65K values,
		// they get incomplete debug info on 32-bit platforms.
		return
	}
	if start == end {
		if state.loggingEnabled {
			// Printf not logf so not gated by GOSSAFUNC; this should fire very rarely.
			fmt.Printf("Skipping empty location list for %v in %s\n", state.vars[varID], state.f.Name)
		}
		return
	}

	list := state.lists[varID]
	list = appendPtr(state.ctxt, list, start)
	list = appendPtr(state.ctxt, list, end)
	// Where to write the length of the location description once
	// we know how big it is.
	sizeIdx := len(list)
	list = list[:len(list)+2]

	if state.loggingEnabled {
		var partStrs []string
		for i, slot := range state.varSlots[varID] {
			partStrs = append(partStrs, fmt.Sprintf("%v@%v", state.slots[slot], state.LocString(pending.pieces[i])))
		}
		state.logf("Add entry for %v: \tb%vv%v-b%vv%v = \t%v\n", state.vars[varID], pending.startBlock, pending.startValue, endBlock, endValue, strings.Join(partStrs, " "))
	}

	for i, slotID := range state.varSlots[varID] {
		loc := pending.pieces[i]
		slot := state.slots[slotID]

		if !loc.absent() {
			if loc.onStack() {
				if loc.stackOffsetValue() == 0 {
					list = append(list, dwarf.DW_OP_call_frame_cfa)
				} else {
					list = append(list, dwarf.DW_OP_fbreg)
					list = dwarf.AppendSleb128(list, int64(loc.stackOffsetValue()))
				}
			} else {
				regnum := state.ctxt.Arch.DWARFRegisters[state.registers[firstReg(loc.Registers)].ObjNum()]
				if regnum < 32 {
					list = append(list, dwarf.DW_OP_reg0+byte(regnum))
				} else {
					list = append(list, dwarf.DW_OP_regx)
					list = dwarf.AppendUleb128(list, uint64(regnum))
				}
			}
		}

		if len(state.varSlots[varID]) > 1 {
			list = append(list, dwarf.DW_OP_piece)
			list = dwarf.AppendUleb128(list, uint64(slot.Type.Size()))
		}
	}
	state.ctxt.Arch.ByteOrder.PutUint16(list[sizeIdx:], uint16(len(list)-sizeIdx-2))
	state.lists[varID] = list
}

// PutLocationList adds list (a location list in its intermediate representation) to listSym.
func (debugInfo *FuncDebug) PutLocationList(list []byte, 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)
	}

	// Re-read list, translating its address from block/value ID to PC.
	for i := 0; i < len(list); {
		begin := getPC(decodeValue(ctxt, readPtr(ctxt, list[i:])))
		end := getPC(decodeValue(ctxt, readPtr(ctxt, list[i+ctxt.Arch.PtrSize:])))

		// 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, int64(begin))
			listSym.WriteInt(ctxt, listSym.Size, ctxt.Arch.PtrSize, int64(end))
		} else {
			listSym.WriteCURelativeAddr(ctxt, listSym.Size, startPC, int64(begin))
			listSym.WriteCURelativeAddr(ctxt, listSym.Size, startPC, int64(end))
		}

		i += 2 * ctxt.Arch.PtrSize
		datalen := 2 + int(ctxt.Arch.ByteOrder.Uint16(list[i:]))
		listSym.WriteBytes(ctxt, listSym.Size, list[i:i+datalen]) // copy datalen and location encoding
		i += datalen
	}

	// Location list contents, now with real PCs.
	// End entry.
	listSym.WriteInt(ctxt, listSym.Size, ctxt.Arch.PtrSize, 0)
	listSym.WriteInt(ctxt, listSym.Size, ctxt.Arch.PtrSize, 0)
}

// Pack a value and block ID into an address-sized uint, returning encoded
// value and boolean indicating whether the encoding succeeded.  For
// 32-bit architectures the process may fail for very large procedures
// (the theory being that it's ok to have degraded debug quality in
// this case).
func encodeValue(ctxt *obj.Link, b, v ID) (uint64, bool) {
	if ctxt.Arch.PtrSize == 8 {
		result := uint64(b)<<32 | uint64(uint32(v))
		//ctxt.Logf("b %#x (%d) v %#x (%d) -> %#x\n", b, b, v, v, result)
		return result, true
	}
	if ctxt.Arch.PtrSize != 4 {
		panic("unexpected pointer size")
	}
	if ID(int16(b)) != b || ID(int16(v)) != v {
		return 0, false
	}
	return uint64(b)<<16 | uint64(uint16(v)), true
}

// Unpack a value and block ID encoded by encodeValue.
func decodeValue(ctxt *obj.Link, word uint64) (ID, ID) {
	if ctxt.Arch.PtrSize == 8 {
		b, v := ID(word>>32), ID(word)
		//ctxt.Logf("%#x -> b %#x (%d) v %#x (%d)\n", word, b, b, v, v)
		return b, v
	}
	if ctxt.Arch.PtrSize != 4 {
		panic("unexpected pointer size")
	}
	return ID(word >> 16), ID(int16(word))
}

// Append a pointer-sized uint to buf.
func appendPtr(ctxt *obj.Link, buf []byte, word uint64) []byte {
	if cap(buf) < len(buf)+20 {
		b := make([]byte, len(buf), 20+cap(buf)*2)
		copy(b, buf)
		buf = b
	}
	writeAt := len(buf)
	buf = buf[0 : len(buf)+ctxt.Arch.PtrSize]
	writePtr(ctxt, buf[writeAt:], word)
	return buf
}

// Write a pointer-sized uint to the beginning of buf.
func writePtr(ctxt *obj.Link, buf []byte, word uint64) {
	switch ctxt.Arch.PtrSize {
	case 4:
		ctxt.Arch.ByteOrder.PutUint32(buf, uint32(word))
	case 8:
		ctxt.Arch.ByteOrder.PutUint64(buf, word)
	default:
		panic("unexpected pointer size")
	}

}

// Read a pointer-sized uint from the beginning of buf.
func readPtr(ctxt *obj.Link, buf []byte) uint64 {
	switch ctxt.Arch.PtrSize {
	case 4:
		return uint64(ctxt.Arch.ByteOrder.Uint32(buf))
	case 8:
		return ctxt.Arch.ByteOrder.Uint64(buf)
	default:
		panic("unexpected pointer size")
	}

}

// setupLocList creates the initial portion of a location list for a
// user variable. It emits the encoded start/end of the range and a
// placeholder for the size. Return value is the new list plus the
// slot in the list holding the size (to be updated later).
func setupLocList(ctxt *obj.Link, f *Func, list []byte, st, en ID) ([]byte, int) {
	start, startOK := encodeValue(ctxt, f.Entry.ID, st)
	end, endOK := encodeValue(ctxt, f.Entry.ID, en)
	if !startOK || !endOK {
		// This could happen if someone writes a function that uses
		// >65K values on a 32-bit platform. Hopefully a degraded debugging
		// experience is ok in that case.
		return nil, 0
	}
	list = appendPtr(ctxt, list, start)
	list = appendPtr(ctxt, list, end)

	// Where to write the length of the location description once
	// we know how big it is.
	sizeIdx := len(list)
	list = list[:len(list)+2]
	return list, sizeIdx
}

// 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
// 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 *Func) ID {

	// returns true if this instruction looks like it moves an ABI
	// register to the stack, along with the value being stored.
	isRegMoveLike := func(v *Value) (bool, ID) {
		n, ok := v.Aux.(*ir.Name)
		var r ID
		if !ok || n.Class != ir.PPARAM {
			return false, r
		}
		regInputs, memInputs, spInputs := 0, 0, 0
		for _, a := range v.Args {
			if a.Op == OpArgIntReg || a.Op == OpArgFloatReg {
				regInputs++
				r = a.ID
			} else if a.Type.IsMemory() {
				memInputs++
			} else if a.Op == 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([]ID, 0, 32)

	// removeReg tries to remove a value from regArgs, returning true
	// if found and removed, or false otherwise.
	removeReg := func(r ID) bool {
		for i := 0; i < len(regArgs); i++ {
			if regArgs[i] == r {
				regArgs = append(regArgs[:i], regArgs[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.
	for k, v := range f.Entry.Values {
		if v.Op == OpArgIntReg || v.Op == OpArgFloatReg {
			regArgs = append(regArgs, v.ID)
			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
					}
					return BlockEnd.ID
				}
			}
		}
		if v.Op.IsCall() {
			// if we hit a call, we've gone too far.
			return v.ID
		}
	}
	// nothing found
	return ID(-1)
}

// 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.(*ir.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.
func BuildFuncDebugNoOptimized(ctxt *obj.Link, f *Func, loggingEnabled bool, stackOffset func(LocalSlot) int32, rval *FuncDebug) {

	pri := f.ABISelf.ABIAnalyzeFuncType(f.Type.FuncType())

	// Look to see if we have any named register-promoted parameters.
	// If there are none, 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 {
		return
	}

	state := debugState{f: f}

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

	// Allocate location lists.
	rval.LocationLists = make([][]byte, numRegParams)

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

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

		n := inp.Name.(*ir.Name)
		sl := LocalSlot{N: n, Type: inp.Type, Off: 0}
		rval.Vars = append(rval.Vars, n)
		rval.Slots = append(rval.Slots, sl)
		slid := len(rval.VarSlots)
		rval.VarSlots = append(rval.VarSlots, []SlotID{SlotID(slid)})

		if afterPrologVal == 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.
		list, sizeIdx := setupLocList(ctxt, f, rval.LocationLists[pidx],
			BlockStart.ID, afterPrologVal)
		if list == nil {
			pidx++
			continue
		}
		if loggingEnabled {
			state.logf("param %v:\n  [<entry>, %d]:\n", n, afterPrologVal)
		}
		rtypes, _ := inp.RegisterTypesAndOffsets()
		padding := make([]uint64, 0, 32)
		padding = inp.ComputePadding(padding)
		for k, r := range inp.Registers {
			reg := ObjRegForAbiReg(r, f.Config)
			dwreg := ctxt.Arch.DWARFRegisters[reg]
			if dwreg < 32 {
				list = append(list, dwarf.DW_OP_reg0+byte(dwreg))
			} else {
				list = append(list, dwarf.DW_OP_regx)
				list = dwarf.AppendUleb128(list, uint64(dwreg))
			}
			if loggingEnabled {
				state.logf("    piece %d -> dwreg %d", k, dwreg)
			}
			if len(inp.Registers) > 1 {
				list = append(list, dwarf.DW_OP_piece)
				ts := rtypes[k].Size()
				list = dwarf.AppendUleb128(list, uint64(ts))
				if padding[k] > 0 {
					if loggingEnabled {
						state.logf(" [pad %d bytes]", padding[k])
					}
					list = append(list, dwarf.DW_OP_piece)
					list = dwarf.AppendUleb128(list, padding[k])
				}
			}
			if loggingEnabled {
				state.logf("\n")
			}
		}
		// fill in length of location expression element
		ctxt.Arch.ByteOrder.PutUint16(list[sizeIdx:], uint16(len(list)-sizeIdx-2))

		// Second entry in the location list will be the stack home
		// of the param, once it has been spilled.  Emit that now.
		list, sizeIdx = setupLocList(ctxt, f, list,
			afterPrologVal, FuncEnd.ID)
		if list == nil {
			pidx++
			continue
		}
		soff := stackOffset(sl)
		if soff == 0 {
			list = append(list, dwarf.DW_OP_call_frame_cfa)
		} else {
			list = append(list, dwarf.DW_OP_fbreg)
			list = dwarf.AppendSleb128(list, int64(soff))
		}
		if loggingEnabled {
			state.logf("  [%d, <end>): stackOffset=%d\n", afterPrologVal, soff)
		}

		// fill in size
		ctxt.Arch.ByteOrder.PutUint16(list[sizeIdx:], uint16(len(list)-sizeIdx-2))

		rval.LocationLists[pidx] = list
		pidx++
	}
}
