// Copyright 2022 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 compare contains code for generating comparison
// routines for structs, strings and interfaces.
package compare

import (
	"cmd/compile/internal/base"
	"cmd/compile/internal/ir"
	"cmd/compile/internal/typecheck"
	"cmd/compile/internal/types"
	"fmt"
	"math/bits"
	"sort"
)

// IsRegularMemory reports whether t can be compared/hashed as regular memory.
func IsRegularMemory(t *types.Type) bool {
	return types.AlgType(t) == types.AMEM
}

// Memrun finds runs of struct fields for which memory-only algs are appropriate.
// t is the parent struct type, and start is the field index at which to start the run.
// size is the length in bytes of the memory included in the run.
// next is the index just after the end of the memory run.
func Memrun(t *types.Type, start int) (size int64, next int) {
	next = start
	for {
		next++
		if next == t.NumFields() {
			break
		}
		// Stop run after a padded field.
		if types.IsPaddedField(t, next-1) {
			break
		}
		// Also, stop before a blank or non-memory field.
		if f := t.Field(next); f.Sym.IsBlank() || !IsRegularMemory(f.Type) {
			break
		}
		// For issue 46283, don't combine fields if the resulting load would
		// require a larger alignment than the component fields.
		if base.Ctxt.Arch.Alignment > 1 {
			align := t.Alignment()
			if off := t.Field(start).Offset; off&(align-1) != 0 {
				// Offset is less aligned than the containing type.
				// Use offset to determine alignment.
				align = 1 << uint(bits.TrailingZeros64(uint64(off)))
			}
			size := t.Field(next).End() - t.Field(start).Offset
			if size > align {
				break
			}
		}
	}
	return t.Field(next-1).End() - t.Field(start).Offset, next
}

// EqCanPanic reports whether == on type t could panic (has an interface somewhere).
// t must be comparable.
func EqCanPanic(t *types.Type) bool {
	switch t.Kind() {
	default:
		return false
	case types.TINTER:
		return true
	case types.TARRAY:
		return EqCanPanic(t.Elem())
	case types.TSTRUCT:
		for _, f := range t.Fields() {
			if !f.Sym.IsBlank() && EqCanPanic(f.Type) {
				return true
			}
		}
		return false
	}
}

// EqStructCost returns the cost of an equality comparison of two structs.
//
// The cost is determined using an algorithm which takes into consideration
// the size of the registers in the current architecture and the size of the
// memory-only fields in the struct.
func EqStructCost(t *types.Type) int64 {
	cost := int64(0)

	for i, fields := 0, t.Fields(); i < len(fields); {
		f := fields[i]

		// Skip blank-named fields.
		if f.Sym.IsBlank() {
			i++
			continue
		}

		n, _, next := eqStructFieldCost(t, i)

		cost += n
		i = next
	}

	return cost
}

// eqStructFieldCost returns the cost of an equality comparison of two struct fields.
// t is the parent struct type, and i is the index of the field in the parent struct type.
// eqStructFieldCost may compute the cost of several adjacent fields at once. It returns
// the cost, the size of the set of fields it computed the cost for (in bytes), and the
// index of the first field not part of the set of fields for which the cost
// has already been calculated.
func eqStructFieldCost(t *types.Type, i int) (int64, int64, int) {
	var (
		cost    = int64(0)
		regSize = int64(types.RegSize)

		size int64
		next int
	)

	if base.Ctxt.Arch.CanMergeLoads {
		// If we can merge adjacent loads then we can calculate the cost of the
		// comparison using the size of the memory run and the size of the registers.
		size, next = Memrun(t, i)
		cost = size / regSize
		if size%regSize != 0 {
			cost++
		}
		return cost, size, next
	}

	// If we cannot merge adjacent loads then we have to use the size of the
	// field and take into account the type to determine how many loads and compares
	// are needed.
	ft := t.Field(i).Type
	size = ft.Size()
	next = i + 1

	return calculateCostForType(ft), size, next
}

func calculateCostForType(t *types.Type) int64 {
	var cost int64
	switch t.Kind() {
	case types.TSTRUCT:
		return EqStructCost(t)
	case types.TSLICE:
		// Slices are not comparable.
		base.Fatalf("calculateCostForType: unexpected slice type")
	case types.TARRAY:
		elemCost := calculateCostForType(t.Elem())
		cost = t.NumElem() * elemCost
	case types.TSTRING, types.TINTER, types.TCOMPLEX64, types.TCOMPLEX128:
		cost = 2
	case types.TINT64, types.TUINT64:
		cost = 8 / int64(types.RegSize)
	default:
		cost = 1
	}
	return cost
}

// EqStruct compares two structs np and nq for equality.
// It works by building a list of boolean conditions to satisfy.
// Conditions must be evaluated in the returned order and
// properly short-circuited by the caller.
// The first return value is the flattened list of conditions,
// the second value is a boolean indicating whether any of the
// comparisons could panic.
func EqStruct(t *types.Type, np, nq ir.Node) ([]ir.Node, bool) {
	// The conditions are a list-of-lists. Conditions are reorderable
	// within each inner list. The outer lists must be evaluated in order.
	var conds [][]ir.Node
	conds = append(conds, []ir.Node{})
	and := func(n ir.Node) {
		i := len(conds) - 1
		conds[i] = append(conds[i], n)
	}

	// Walk the struct using memequal for runs of AMEM
	// and calling specific equality tests for the others.
	for i, fields := 0, t.Fields(); i < len(fields); {
		f := fields[i]

		// Skip blank-named fields.
		if f.Sym.IsBlank() {
			i++
			continue
		}

		typeCanPanic := EqCanPanic(f.Type)

		// Compare non-memory fields with field equality.
		if !IsRegularMemory(f.Type) {
			if typeCanPanic {
				// Enforce ordering by starting a new set of reorderable conditions.
				conds = append(conds, []ir.Node{})
			}
			switch {
			case f.Type.IsString():
				p := typecheck.DotField(base.Pos, typecheck.Expr(np), i)
				q := typecheck.DotField(base.Pos, typecheck.Expr(nq), i)
				eqlen, eqmem := EqString(p, q)
				and(eqlen)
				and(eqmem)
			default:
				and(eqfield(np, nq, i))
			}
			if typeCanPanic {
				// Also enforce ordering after something that can panic.
				conds = append(conds, []ir.Node{})
			}
			i++
			continue
		}

		cost, size, next := eqStructFieldCost(t, i)
		if cost <= 4 {
			// Cost of 4 or less: use plain field equality.
			for j := i; j < next; j++ {
				and(eqfield(np, nq, j))
			}
		} else {
			// Higher cost: use memequal.
			cc := eqmem(np, nq, i, size)
			and(cc)
		}
		i = next
	}

	// Sort conditions to put runtime calls last.
	// Preserve the rest of the ordering.
	var flatConds []ir.Node
	for _, c := range conds {
		isCall := func(n ir.Node) bool {
			return n.Op() == ir.OCALL || n.Op() == ir.OCALLFUNC
		}
		sort.SliceStable(c, func(i, j int) bool {
			return !isCall(c[i]) && isCall(c[j])
		})
		flatConds = append(flatConds, c...)
	}
	return flatConds, len(conds) > 1
}

// EqString returns the nodes
//
//	len(s) == len(t)
//
// and
//
//	memequal(s.ptr, t.ptr, len(s))
//
// which can be used to construct string equality comparison.
// eqlen must be evaluated before eqmem, and shortcircuiting is required.
func EqString(s, t ir.Node) (eqlen *ir.BinaryExpr, eqmem *ir.CallExpr) {
	s = typecheck.Conv(s, types.Types[types.TSTRING])
	t = typecheck.Conv(t, types.Types[types.TSTRING])
	sptr := ir.NewConvExpr(base.Pos, ir.OCONVNOP, types.Types[types.TUNSAFEPTR], ir.NewUnaryExpr(base.Pos, ir.OSPTR, s))
	tptr := ir.NewConvExpr(base.Pos, ir.OCONVNOP, types.Types[types.TUNSAFEPTR], ir.NewUnaryExpr(base.Pos, ir.OSPTR, t))
	slen := typecheck.Conv(ir.NewUnaryExpr(base.Pos, ir.OLEN, s), types.Types[types.TUINTPTR])
	tlen := typecheck.Conv(ir.NewUnaryExpr(base.Pos, ir.OLEN, t), types.Types[types.TUINTPTR])

	// Pick the 3rd arg to memequal. Both slen and tlen are fine to use, because we short
	// circuit the memequal call if they aren't the same. But if one is a constant some
	// memequal optimizations are easier to apply.
	probablyConstant := func(n ir.Node) bool {
		if n.Op() == ir.OCONVNOP {
			n = n.(*ir.ConvExpr).X
		}
		if n.Op() == ir.OLITERAL {
			return true
		}
		if n.Op() != ir.ONAME {
			return false
		}
		name := n.(*ir.Name)
		if name.Class != ir.PAUTO {
			return false
		}
		if def := name.Defn; def == nil {
			// n starts out as the empty string
			return true
		} else if def.Op() == ir.OAS && (def.(*ir.AssignStmt).Y == nil || def.(*ir.AssignStmt).Y.Op() == ir.OLITERAL) {
			// n starts out as a constant string
			return true
		}
		return false
	}
	cmplen := slen
	if probablyConstant(t) && !probablyConstant(s) {
		cmplen = tlen
	}

	fn := typecheck.LookupRuntime("memequal")
	call := typecheck.Call(base.Pos, fn, []ir.Node{sptr, tptr, ir.Copy(cmplen)}, false).(*ir.CallExpr)

	cmp := ir.NewBinaryExpr(base.Pos, ir.OEQ, slen, tlen)
	cmp = typecheck.Expr(cmp).(*ir.BinaryExpr)
	cmp.SetType(types.Types[types.TBOOL])
	return cmp, call
}

// EqInterface returns the nodes
//
//	s.tab == t.tab (or s.typ == t.typ, as appropriate)
//
// and
//
//	ifaceeq(s.tab, s.data, t.data) (or efaceeq(s.typ, s.data, t.data), as appropriate)
//
// which can be used to construct interface equality comparison.
// eqtab must be evaluated before eqdata, and shortcircuiting is required.
func EqInterface(s, t ir.Node) (eqtab *ir.BinaryExpr, eqdata *ir.CallExpr) {
	if !types.Identical(s.Type(), t.Type()) {
		base.Fatalf("EqInterface %v %v", s.Type(), t.Type())
	}
	// func ifaceeq(tab *uintptr, x, y unsafe.Pointer) (ret bool)
	// func efaceeq(typ *uintptr, x, y unsafe.Pointer) (ret bool)
	var fn ir.Node
	if s.Type().IsEmptyInterface() {
		fn = typecheck.LookupRuntime("efaceeq")
	} else {
		fn = typecheck.LookupRuntime("ifaceeq")
	}

	stab := ir.NewUnaryExpr(base.Pos, ir.OITAB, s)
	ttab := ir.NewUnaryExpr(base.Pos, ir.OITAB, t)
	sdata := ir.NewUnaryExpr(base.Pos, ir.OIDATA, s)
	tdata := ir.NewUnaryExpr(base.Pos, ir.OIDATA, t)
	sdata.SetType(types.Types[types.TUNSAFEPTR])
	tdata.SetType(types.Types[types.TUNSAFEPTR])
	sdata.SetTypecheck(1)
	tdata.SetTypecheck(1)

	call := typecheck.Call(base.Pos, fn, []ir.Node{stab, sdata, tdata}, false).(*ir.CallExpr)

	cmp := ir.NewBinaryExpr(base.Pos, ir.OEQ, stab, ttab)
	cmp = typecheck.Expr(cmp).(*ir.BinaryExpr)
	cmp.SetType(types.Types[types.TBOOL])
	return cmp, call
}

// eqfield returns the node
//
//	p.field == q.field
func eqfield(p, q ir.Node, field int) ir.Node {
	nx := typecheck.DotField(base.Pos, typecheck.Expr(p), field)
	ny := typecheck.DotField(base.Pos, typecheck.Expr(q), field)
	return typecheck.Expr(ir.NewBinaryExpr(base.Pos, ir.OEQ, nx, ny))
}

// eqmem returns the node
//
//	memequal(&p.field, &q.field, size)
func eqmem(p, q ir.Node, field int, size int64) ir.Node {
	nx := typecheck.Expr(typecheck.NodAddr(typecheck.DotField(base.Pos, p, field)))
	ny := typecheck.Expr(typecheck.NodAddr(typecheck.DotField(base.Pos, q, field)))

	fn, needsize := eqmemfunc(size, nx.Type().Elem())
	call := ir.NewCallExpr(base.Pos, ir.OCALL, fn, nil)
	call.Args.Append(nx)
	call.Args.Append(ny)
	if needsize {
		call.Args.Append(ir.NewInt(base.Pos, size))
	}

	return call
}

func eqmemfunc(size int64, t *types.Type) (fn *ir.Name, needsize bool) {
	if !base.Ctxt.Arch.CanMergeLoads && t.Alignment() < int64(base.Ctxt.Arch.Alignment) && t.Alignment() < t.Size() {
		// We can't use larger comparisons if the value might not be aligned
		// enough for the larger comparison. See issues 46283 and 67160.
		size = 0
	}
	switch size {
	case 1, 2, 4, 8, 16:
		buf := fmt.Sprintf("memequal%d", int(size)*8)
		return typecheck.LookupRuntime(buf, t, t), false
	}

	return typecheck.LookupRuntime("memequal", t, t), true
}
