// Copyright 2009 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 staticinit

import (
	"fmt"
	"go/constant"
	"go/token"
	"os"

	"cmd/compile/internal/base"
	"cmd/compile/internal/ir"
	"cmd/compile/internal/reflectdata"
	"cmd/compile/internal/staticdata"
	"cmd/compile/internal/typecheck"
	"cmd/compile/internal/types"
	"cmd/internal/obj"
	"cmd/internal/objabi"
	"cmd/internal/src"
)

type Entry struct {
	Xoffset int64   // struct, array only
	Expr    ir.Node // bytes of run-time computed expressions
}

type Plan struct {
	E []Entry
}

// An Schedule is used to decompose assignment statements into
// static and dynamic initialization parts. Static initializations are
// handled by populating variables' linker symbol data, while dynamic
// initializations are accumulated to be executed in order.
type Schedule struct {
	// Out is the ordered list of dynamic initialization
	// statements.
	Out []ir.Node

	Plans map[ir.Node]*Plan
	Temps map[ir.Node]*ir.Name
}

func (s *Schedule) append(n ir.Node) {
	s.Out = append(s.Out, n)
}

// StaticInit adds an initialization statement n to the schedule.
func (s *Schedule) StaticInit(n ir.Node) {
	if !s.tryStaticInit(n) {
		if base.Flag.Percent != 0 {
			ir.Dump("StaticInit failed", n)
		}
		s.append(n)
	}
}

// varToMapInit holds book-keeping state for global map initialization;
// it records the init function created by the compiler to host the
// initialization code for the map in question.
var varToMapInit map[*ir.Name]*ir.Func

// MapInitToVar is the inverse of VarToMapInit; it maintains a mapping
// from a compiler-generated init function to the map the function is
// initializing.
var MapInitToVar map[*ir.Func]*ir.Name

// recordFuncForVar establishes a mapping between global map var "v" and
// outlined init function "fn" (and vice versa); so that we can use
// the mappings later on to update relocations.
func recordFuncForVar(v *ir.Name, fn *ir.Func) {
	if varToMapInit == nil {
		varToMapInit = make(map[*ir.Name]*ir.Func)
		MapInitToVar = make(map[*ir.Func]*ir.Name)
	}
	varToMapInit[v] = fn
	MapInitToVar[fn] = v
}

// tryStaticInit attempts to statically execute an initialization
// statement and reports whether it succeeded.
func (s *Schedule) tryStaticInit(nn ir.Node) bool {
	// Only worry about simple "l = r" assignments. Multiple
	// variable/expression OAS2 assignments have already been
	// replaced by multiple simple OAS assignments, and the other
	// OAS2* assignments mostly necessitate dynamic execution
	// anyway.
	if nn.Op() != ir.OAS {
		return false
	}
	n := nn.(*ir.AssignStmt)
	if ir.IsBlank(n.X) && !AnySideEffects(n.Y) {
		// Discard.
		return true
	}
	lno := ir.SetPos(n)
	defer func() { base.Pos = lno }()
	nam := n.X.(*ir.Name)
	return s.StaticAssign(nam, 0, n.Y, nam.Type())
}

// like staticassign but we are copying an already
// initialized value r.
func (s *Schedule) staticcopy(l *ir.Name, loff int64, rn *ir.Name, typ *types.Type) bool {
	if rn.Class == ir.PFUNC {
		// TODO if roff != 0 { panic }
		staticdata.InitAddr(l, loff, staticdata.FuncLinksym(rn))
		return true
	}
	if rn.Class != ir.PEXTERN || rn.Sym().Pkg != types.LocalPkg {
		return false
	}
	if rn.Defn.Op() != ir.OAS {
		return false
	}
	if rn.Type().IsString() { // perhaps overwritten by cmd/link -X (#34675)
		return false
	}
	if rn.Embed != nil {
		return false
	}
	orig := rn
	r := rn.Defn.(*ir.AssignStmt).Y
	if r == nil {
		// No explicit initialization value. Probably zeroed but perhaps
		// supplied externally and of unknown value.
		return false
	}

	for r.Op() == ir.OCONVNOP && !types.Identical(r.Type(), typ) {
		r = r.(*ir.ConvExpr).X
	}

	switch r.Op() {
	case ir.OMETHEXPR:
		r = r.(*ir.SelectorExpr).FuncName()
		fallthrough
	case ir.ONAME:
		r := r.(*ir.Name)
		if s.staticcopy(l, loff, r, typ) {
			return true
		}
		// We may have skipped past one or more OCONVNOPs, so
		// use conv to ensure r is assignable to l (#13263).
		dst := ir.Node(l)
		if loff != 0 || !types.Identical(typ, l.Type()) {
			dst = ir.NewNameOffsetExpr(base.Pos, l, loff, typ)
		}
		s.append(ir.NewAssignStmt(base.Pos, dst, typecheck.Conv(r, typ)))
		return true

	case ir.ONIL:
		return true

	case ir.OLITERAL:
		if ir.IsZero(r) {
			return true
		}
		staticdata.InitConst(l, loff, r, int(typ.Size()))
		return true

	case ir.OADDR:
		r := r.(*ir.AddrExpr)
		if a, ok := r.X.(*ir.Name); ok && a.Op() == ir.ONAME {
			staticdata.InitAddr(l, loff, staticdata.GlobalLinksym(a))
			return true
		}

	case ir.OPTRLIT:
		r := r.(*ir.AddrExpr)
		switch r.X.Op() {
		case ir.OARRAYLIT, ir.OSLICELIT, ir.OSTRUCTLIT, ir.OMAPLIT:
			// copy pointer
			staticdata.InitAddr(l, loff, staticdata.GlobalLinksym(s.Temps[r]))
			return true
		}

	case ir.OSLICELIT:
		r := r.(*ir.CompLitExpr)
		// copy slice
		staticdata.InitSlice(l, loff, staticdata.GlobalLinksym(s.Temps[r]), r.Len)
		return true

	case ir.OARRAYLIT, ir.OSTRUCTLIT:
		r := r.(*ir.CompLitExpr)
		p := s.Plans[r]
		for i := range p.E {
			e := &p.E[i]
			typ := e.Expr.Type()
			if e.Expr.Op() == ir.OLITERAL || e.Expr.Op() == ir.ONIL {
				staticdata.InitConst(l, loff+e.Xoffset, e.Expr, int(typ.Size()))
				continue
			}
			x := e.Expr
			if x.Op() == ir.OMETHEXPR {
				x = x.(*ir.SelectorExpr).FuncName()
			}
			if x.Op() == ir.ONAME && s.staticcopy(l, loff+e.Xoffset, x.(*ir.Name), typ) {
				continue
			}
			// Requires computation, but we're
			// copying someone else's computation.
			ll := ir.NewNameOffsetExpr(base.Pos, l, loff+e.Xoffset, typ)
			rr := ir.NewNameOffsetExpr(base.Pos, orig, e.Xoffset, typ)
			ir.SetPos(rr)
			s.append(ir.NewAssignStmt(base.Pos, ll, rr))
		}

		return true
	}

	return false
}

func (s *Schedule) StaticAssign(l *ir.Name, loff int64, r ir.Node, typ *types.Type) bool {
	if r == nil {
		// No explicit initialization value. Either zero or supplied
		// externally.
		return true
	}
	for r.Op() == ir.OCONVNOP {
		r = r.(*ir.ConvExpr).X
	}

	assign := func(pos src.XPos, a *ir.Name, aoff int64, v ir.Node) {
		if s.StaticAssign(a, aoff, v, v.Type()) {
			return
		}
		var lhs ir.Node
		if ir.IsBlank(a) {
			// Don't use NameOffsetExpr with blank (#43677).
			lhs = ir.BlankNode
		} else {
			lhs = ir.NewNameOffsetExpr(pos, a, aoff, v.Type())
		}
		s.append(ir.NewAssignStmt(pos, lhs, v))
	}

	switch r.Op() {
	case ir.ONAME:
		r := r.(*ir.Name)
		return s.staticcopy(l, loff, r, typ)

	case ir.OMETHEXPR:
		r := r.(*ir.SelectorExpr)
		return s.staticcopy(l, loff, r.FuncName(), typ)

	case ir.ONIL:
		return true

	case ir.OLITERAL:
		if ir.IsZero(r) {
			return true
		}
		staticdata.InitConst(l, loff, r, int(typ.Size()))
		return true

	case ir.OADDR:
		r := r.(*ir.AddrExpr)
		if name, offset, ok := StaticLoc(r.X); ok && name.Class == ir.PEXTERN {
			staticdata.InitAddrOffset(l, loff, name.Linksym(), offset)
			return true
		}
		fallthrough

	case ir.OPTRLIT:
		r := r.(*ir.AddrExpr)
		switch r.X.Op() {
		case ir.OARRAYLIT, ir.OSLICELIT, ir.OMAPLIT, ir.OSTRUCTLIT:
			// Init pointer.
			a := StaticName(r.X.Type())

			s.Temps[r] = a
			staticdata.InitAddr(l, loff, a.Linksym())

			// Init underlying literal.
			assign(base.Pos, a, 0, r.X)
			return true
		}
		//dump("not static ptrlit", r);

	case ir.OSTR2BYTES:
		r := r.(*ir.ConvExpr)
		if l.Class == ir.PEXTERN && r.X.Op() == ir.OLITERAL {
			sval := ir.StringVal(r.X)
			staticdata.InitSliceBytes(l, loff, sval)
			return true
		}

	case ir.OSLICELIT:
		r := r.(*ir.CompLitExpr)
		s.initplan(r)
		// Init slice.
		ta := types.NewArray(r.Type().Elem(), r.Len)
		ta.SetNoalg(true)
		a := StaticName(ta)
		s.Temps[r] = a
		staticdata.InitSlice(l, loff, a.Linksym(), r.Len)
		// Fall through to init underlying array.
		l = a
		loff = 0
		fallthrough

	case ir.OARRAYLIT, ir.OSTRUCTLIT:
		r := r.(*ir.CompLitExpr)
		s.initplan(r)

		p := s.Plans[r]
		for i := range p.E {
			e := &p.E[i]
			if e.Expr.Op() == ir.OLITERAL || e.Expr.Op() == ir.ONIL {
				staticdata.InitConst(l, loff+e.Xoffset, e.Expr, int(e.Expr.Type().Size()))
				continue
			}
			ir.SetPos(e.Expr)
			assign(base.Pos, l, loff+e.Xoffset, e.Expr)
		}

		return true

	case ir.OMAPLIT:
		break

	case ir.OCLOSURE:
		r := r.(*ir.ClosureExpr)
		if ir.IsTrivialClosure(r) {
			if base.Debug.Closure > 0 {
				base.WarnfAt(r.Pos(), "closure converted to global")
			}
			// Closures with no captured variables are globals,
			// so the assignment can be done at link time.
			// TODO if roff != 0 { panic }
			staticdata.InitAddr(l, loff, staticdata.FuncLinksym(r.Func.Nname))
			return true
		}
		ir.ClosureDebugRuntimeCheck(r)

	case ir.OCONVIFACE:
		// This logic is mirrored in isStaticCompositeLiteral.
		// If you change something here, change it there, and vice versa.

		// Determine the underlying concrete type and value we are converting from.
		r := r.(*ir.ConvExpr)
		val := ir.Node(r)
		for val.Op() == ir.OCONVIFACE {
			val = val.(*ir.ConvExpr).X
		}

		if val.Type().IsInterface() {
			// val is an interface type.
			// If val is nil, we can statically initialize l;
			// both words are zero and so there no work to do, so report success.
			// If val is non-nil, we have no concrete type to record,
			// and we won't be able to statically initialize its value, so report failure.
			return val.Op() == ir.ONIL
		}

		if val.Type().HasShape() {
			// See comment in cmd/compile/internal/walk/convert.go:walkConvInterface
			return false
		}

		reflectdata.MarkTypeUsedInInterface(val.Type(), l.Linksym())

		var itab *ir.AddrExpr
		if typ.IsEmptyInterface() {
			itab = reflectdata.TypePtr(val.Type())
		} else {
			itab = reflectdata.ITabAddr(val.Type(), typ)
		}

		// Create a copy of l to modify while we emit data.

		// Emit itab, advance offset.
		staticdata.InitAddr(l, loff, itab.X.(*ir.LinksymOffsetExpr).Linksym)

		// Emit data.
		if types.IsDirectIface(val.Type()) {
			if val.Op() == ir.ONIL {
				// Nil is zero, nothing to do.
				return true
			}
			// Copy val directly into n.
			ir.SetPos(val)
			assign(base.Pos, l, loff+int64(types.PtrSize), val)
		} else {
			// Construct temp to hold val, write pointer to temp into n.
			a := StaticName(val.Type())
			s.Temps[val] = a
			assign(base.Pos, a, 0, val)
			staticdata.InitAddr(l, loff+int64(types.PtrSize), a.Linksym())
		}

		return true

	case ir.OINLCALL:
		r := r.(*ir.InlinedCallExpr)
		return s.staticAssignInlinedCall(l, loff, r, typ)
	}

	if base.Flag.Percent != 0 {
		ir.Dump("not static", r)
	}
	return false
}

func (s *Schedule) initplan(n ir.Node) {
	if s.Plans[n] != nil {
		return
	}
	p := new(Plan)
	s.Plans[n] = p
	switch n.Op() {
	default:
		base.Fatalf("initplan")

	case ir.OARRAYLIT, ir.OSLICELIT:
		n := n.(*ir.CompLitExpr)
		var k int64
		for _, a := range n.List {
			if a.Op() == ir.OKEY {
				kv := a.(*ir.KeyExpr)
				k = typecheck.IndexConst(kv.Key)
				if k < 0 {
					base.Fatalf("initplan arraylit: invalid index %v", kv.Key)
				}
				a = kv.Value
			}
			s.addvalue(p, k*n.Type().Elem().Size(), a)
			k++
		}

	case ir.OSTRUCTLIT:
		n := n.(*ir.CompLitExpr)
		for _, a := range n.List {
			if a.Op() != ir.OSTRUCTKEY {
				base.Fatalf("initplan structlit")
			}
			a := a.(*ir.StructKeyExpr)
			if a.Sym().IsBlank() {
				continue
			}
			s.addvalue(p, a.Field.Offset, a.Value)
		}

	case ir.OMAPLIT:
		n := n.(*ir.CompLitExpr)
		for _, a := range n.List {
			if a.Op() != ir.OKEY {
				base.Fatalf("initplan maplit")
			}
			a := a.(*ir.KeyExpr)
			s.addvalue(p, -1, a.Value)
		}
	}
}

func (s *Schedule) addvalue(p *Plan, xoffset int64, n ir.Node) {
	// special case: zero can be dropped entirely
	if ir.IsZero(n) {
		return
	}

	// special case: inline struct and array (not slice) literals
	if isvaluelit(n) {
		s.initplan(n)
		q := s.Plans[n]
		for _, qe := range q.E {
			// qe is a copy; we are not modifying entries in q.E
			qe.Xoffset += xoffset
			p.E = append(p.E, qe)
		}
		return
	}

	// add to plan
	p.E = append(p.E, Entry{Xoffset: xoffset, Expr: n})
}

func (s *Schedule) staticAssignInlinedCall(l *ir.Name, loff int64, call *ir.InlinedCallExpr, typ *types.Type) bool {
	if base.Debug.InlStaticInit == 0 {
		return false
	}

	// Handle the special case of an inlined call of
	// a function body with a single return statement,
	// which turns into a single assignment plus a goto.
	//
	// For example code like this:
	//
	//	type T struct{ x int }
	//	func F(x int) *T { return &T{x} }
	//	var Global = F(400)
	//
	// turns into IR like this:
	//
	// 	INLCALL-init
	// 	.   AS2-init
	// 	.   .   DCL # x.go:18:13
	// 	.   .   .   NAME-p.x Class:PAUTO Offset:0 InlFormal OnStack Used int tc(1) # x.go:14:9,x.go:18:13
	// 	.   AS2 Def tc(1) # x.go:18:13
	// 	.   AS2-Lhs
	// 	.   .   NAME-p.x Class:PAUTO Offset:0 InlFormal OnStack Used int tc(1) # x.go:14:9,x.go:18:13
	// 	.   AS2-Rhs
	// 	.   .   LITERAL-400 int tc(1) # x.go:18:14
	// 	.   INLMARK Index:1 # +x.go:18:13
	// 	INLCALL PTR-*T tc(1) # x.go:18:13
	// 	INLCALL-Body
	// 	.   BLOCK tc(1) # x.go:18:13
	// 	.   BLOCK-List
	// 	.   .   DCL tc(1) # x.go:18:13
	// 	.   .   .   NAME-p.~R0 Class:PAUTO Offset:0 OnStack Used PTR-*T tc(1) # x.go:18:13
	// 	.   .   AS2 tc(1) # x.go:18:13
	// 	.   .   AS2-Lhs
	// 	.   .   .   NAME-p.~R0 Class:PAUTO Offset:0 OnStack Used PTR-*T tc(1) # x.go:18:13
	// 	.   .   AS2-Rhs
	// 	.   .   .   INLINED RETURN ARGUMENT HERE
	// 	.   .   GOTO p..i1 tc(1) # x.go:18:13
	// 	.   LABEL p..i1 # x.go:18:13
	// 	INLCALL-ReturnVars
	// 	.   NAME-p.~R0 Class:PAUTO Offset:0 OnStack Used PTR-*T tc(1) # x.go:18:13
	//
	// In non-unified IR, the tree is slightly different:
	//  - if there are no arguments to the inlined function,
	//    the INLCALL-init omits the AS2.
	//  - the DCL inside BLOCK is on the AS2's init list,
	//    not its own statement in the top level of the BLOCK.
	//
	// If the init values are side-effect-free and each either only
	// appears once in the function body or is safely repeatable,
	// then we inline the value expressions into the return argument
	// and then call StaticAssign to handle that copy.
	//
	// This handles simple cases like
	//
	//	var myError = errors.New("mine")
	//
	// where errors.New is
	//
	//	func New(text string) error {
	//		return &errorString{text}
	//	}
	//
	// We could make things more sophisticated but this kind of initializer
	// is the most important case for us to get right.

	init := call.Init()
	var as2init *ir.AssignListStmt
	if len(init) == 2 && init[0].Op() == ir.OAS2 && init[1].Op() == ir.OINLMARK {
		as2init = init[0].(*ir.AssignListStmt)
	} else if len(init) == 1 && init[0].Op() == ir.OINLMARK {
		as2init = new(ir.AssignListStmt)
	} else {
		return false
	}
	if len(call.Body) != 2 || call.Body[0].Op() != ir.OBLOCK || call.Body[1].Op() != ir.OLABEL {
		return false
	}
	label := call.Body[1].(*ir.LabelStmt).Label
	block := call.Body[0].(*ir.BlockStmt)
	list := block.List
	var dcl *ir.Decl
	if len(list) == 3 && list[0].Op() == ir.ODCL {
		dcl = list[0].(*ir.Decl)
		list = list[1:]
	}
	if len(list) != 2 ||
		list[0].Op() != ir.OAS2 ||
		list[1].Op() != ir.OGOTO ||
		list[1].(*ir.BranchStmt).Label != label {
		return false
	}
	as2body := list[0].(*ir.AssignListStmt)
	if dcl == nil {
		ainit := as2body.Init()
		if len(ainit) != 1 || ainit[0].Op() != ir.ODCL {
			return false
		}
		dcl = ainit[0].(*ir.Decl)
	}
	if len(as2body.Lhs) != 1 || as2body.Lhs[0] != dcl.X {
		return false
	}

	// Can't remove the parameter variables if an address is taken.
	for _, v := range as2init.Lhs {
		if v.(*ir.Name).Addrtaken() {
			return false
		}
	}
	// Can't move the computation of the args if they have side effects.
	for _, r := range as2init.Rhs {
		if AnySideEffects(r) {
			return false
		}
	}

	// Can only substitute arg for param if param is used
	// at most once or is repeatable.
	count := make(map[*ir.Name]int)
	for _, x := range as2init.Lhs {
		count[x.(*ir.Name)] = 0
	}

	hasNonTrivialClosure := false
	ir.Visit(as2body.Rhs[0], func(n ir.Node) {
		if name, ok := n.(*ir.Name); ok {
			if c, ok := count[name]; ok {
				count[name] = c + 1
			}
		}
		if clo, ok := n.(*ir.ClosureExpr); ok {
			hasNonTrivialClosure = hasNonTrivialClosure || !ir.IsTrivialClosure(clo)
		}
	})

	// If there's a non-trivial closure, it has captured the param,
	// so we can't substitute arg for param.
	if hasNonTrivialClosure {
		return false
	}

	for name, c := range count {
		if c > 1 {
			// Check whether corresponding initializer can be repeated.
			// Something like 1 can be; make(chan int) or &T{} cannot,
			// because they need to evaluate to the same result in each use.
			for i, n := range as2init.Lhs {
				if n == name && !canRepeat(as2init.Rhs[i]) {
					return false
				}
			}
		}
	}

	// Possible static init.
	// Build tree with args substituted for params and try it.
	args := make(map[*ir.Name]ir.Node)
	for i, v := range as2init.Lhs {
		if ir.IsBlank(v) {
			continue
		}
		args[v.(*ir.Name)] = as2init.Rhs[i]
	}
	r, ok := subst(as2body.Rhs[0], args)
	if !ok {
		return false
	}
	ok = s.StaticAssign(l, loff, r, typ)

	if ok && base.Flag.Percent != 0 {
		ir.Dump("static inlined-LEFT", l)
		ir.Dump("static inlined-ORIG", call)
		ir.Dump("static inlined-RIGHT", r)
	}
	return ok
}

// from here down is the walk analysis
// of composite literals.
// most of the work is to generate
// data statements for the constant
// part of the composite literal.

var statuniqgen int // name generator for static temps

// StaticName returns a name backed by a (writable) static data symbol.
// Use readonlystaticname for read-only node.
func StaticName(t *types.Type) *ir.Name {
	// Don't use LookupNum; it interns the resulting string, but these are all unique.
	n := typecheck.NewName(typecheck.Lookup(fmt.Sprintf("%s%d", obj.StaticNamePref, statuniqgen)))
	statuniqgen++
	typecheck.Declare(n, ir.PEXTERN)
	n.SetType(t)
	n.Linksym().Set(obj.AttrStatic, true)
	return n
}

// StaticLoc returns the static address of n, if n has one, or else nil.
func StaticLoc(n ir.Node) (name *ir.Name, offset int64, ok bool) {
	if n == nil {
		return nil, 0, false
	}

	switch n.Op() {
	case ir.ONAME:
		n := n.(*ir.Name)
		return n, 0, true

	case ir.OMETHEXPR:
		n := n.(*ir.SelectorExpr)
		return StaticLoc(n.FuncName())

	case ir.ODOT:
		n := n.(*ir.SelectorExpr)
		if name, offset, ok = StaticLoc(n.X); !ok {
			break
		}
		offset += n.Offset()
		return name, offset, true

	case ir.OINDEX:
		n := n.(*ir.IndexExpr)
		if n.X.Type().IsSlice() {
			break
		}
		if name, offset, ok = StaticLoc(n.X); !ok {
			break
		}
		l := getlit(n.Index)
		if l < 0 {
			break
		}

		// Check for overflow.
		if n.Type().Size() != 0 && types.MaxWidth/n.Type().Size() <= int64(l) {
			break
		}
		offset += int64(l) * n.Type().Size()
		return name, offset, true
	}

	return nil, 0, false
}

func isSideEffect(n ir.Node) bool {
	switch n.Op() {
	// Assume side effects unless we know otherwise.
	default:
		return true

	// No side effects here (arguments are checked separately).
	case ir.ONAME,
		ir.ONONAME,
		ir.OTYPE,
		ir.OLITERAL,
		ir.ONIL,
		ir.OADD,
		ir.OSUB,
		ir.OOR,
		ir.OXOR,
		ir.OADDSTR,
		ir.OADDR,
		ir.OANDAND,
		ir.OBYTES2STR,
		ir.ORUNES2STR,
		ir.OSTR2BYTES,
		ir.OSTR2RUNES,
		ir.OCAP,
		ir.OCOMPLIT,
		ir.OMAPLIT,
		ir.OSTRUCTLIT,
		ir.OARRAYLIT,
		ir.OSLICELIT,
		ir.OPTRLIT,
		ir.OCONV,
		ir.OCONVIFACE,
		ir.OCONVNOP,
		ir.ODOT,
		ir.OEQ,
		ir.ONE,
		ir.OLT,
		ir.OLE,
		ir.OGT,
		ir.OGE,
		ir.OKEY,
		ir.OSTRUCTKEY,
		ir.OLEN,
		ir.OMUL,
		ir.OLSH,
		ir.ORSH,
		ir.OAND,
		ir.OANDNOT,
		ir.ONEW,
		ir.ONOT,
		ir.OBITNOT,
		ir.OPLUS,
		ir.ONEG,
		ir.OOROR,
		ir.OPAREN,
		ir.ORUNESTR,
		ir.OREAL,
		ir.OIMAG,
		ir.OCOMPLEX:
		return false

	// Only possible side effect is division by zero.
	case ir.ODIV, ir.OMOD:
		n := n.(*ir.BinaryExpr)
		if n.Y.Op() != ir.OLITERAL || constant.Sign(n.Y.Val()) == 0 {
			return true
		}

	// Only possible side effect is panic on invalid size,
	// but many makechan and makemap use size zero, which is definitely OK.
	case ir.OMAKECHAN, ir.OMAKEMAP:
		n := n.(*ir.MakeExpr)
		if !ir.IsConst(n.Len, constant.Int) || constant.Sign(n.Len.Val()) != 0 {
			return true
		}

	// Only possible side effect is panic on invalid size.
	// TODO(rsc): Merge with previous case (probably breaks toolstash -cmp).
	case ir.OMAKESLICE, ir.OMAKESLICECOPY:
		return true
	}
	return false
}

// AnySideEffects reports whether n contains any operations that could have observable side effects.
func AnySideEffects(n ir.Node) bool {
	return ir.Any(n, isSideEffect)
}

// canRepeat reports whether executing n multiple times has the same effect as
// assigning n to a single variable and using that variable multiple times.
func canRepeat(n ir.Node) bool {
	bad := func(n ir.Node) bool {
		if isSideEffect(n) {
			return true
		}
		switch n.Op() {
		case ir.OMAKECHAN,
			ir.OMAKEMAP,
			ir.OMAKESLICE,
			ir.OMAKESLICECOPY,
			ir.OMAPLIT,
			ir.ONEW,
			ir.OPTRLIT,
			ir.OSLICELIT,
			ir.OSTR2BYTES,
			ir.OSTR2RUNES:
			return true
		}
		return false
	}
	return !ir.Any(n, bad)
}

func getlit(lit ir.Node) int {
	if ir.IsSmallIntConst(lit) {
		return int(ir.Int64Val(lit))
	}
	return -1
}

func isvaluelit(n ir.Node) bool {
	return n.Op() == ir.OARRAYLIT || n.Op() == ir.OSTRUCTLIT
}

func subst(n ir.Node, m map[*ir.Name]ir.Node) (ir.Node, bool) {
	valid := true
	var edit func(ir.Node) ir.Node
	edit = func(x ir.Node) ir.Node {
		switch x.Op() {
		case ir.ONAME:
			x := x.(*ir.Name)
			if v, ok := m[x]; ok {
				return ir.DeepCopy(v.Pos(), v)
			}
			return x
		case ir.ONONAME, ir.OLITERAL, ir.ONIL, ir.OTYPE:
			return x
		}
		x = ir.Copy(x)
		ir.EditChildrenWithHidden(x, edit)
		if x, ok := x.(*ir.ConvExpr); ok && x.X.Op() == ir.OLITERAL {
			if x, ok := truncate(x.X, x.Type()); ok {
				return x
			}
			valid = false
			return x
		}
		return typecheck.EvalConst(x)
	}
	n = edit(n)
	return n, valid
}

// truncate returns the result of force converting c to type t,
// truncating its value as needed, like a conversion of a variable.
// If the conversion is too difficult, truncate returns nil, false.
func truncate(c ir.Node, t *types.Type) (ir.Node, bool) {
	ct := c.Type()
	cv := c.Val()
	if ct.Kind() != t.Kind() {
		switch {
		default:
			// Note: float -> float/integer and complex -> complex are valid but subtle.
			// For example a float32(float64 1e300) evaluates to +Inf at runtime
			// and the compiler doesn't have any concept of +Inf, so that would
			// have to be left for runtime code evaluation.
			// For now
			return nil, false

		case ct.IsInteger() && t.IsInteger():
			// truncate or sign extend
			bits := t.Size() * 8
			cv = constant.BinaryOp(cv, token.AND, constant.MakeUint64(1<<bits-1))
			if t.IsSigned() && constant.Compare(cv, token.GEQ, constant.MakeUint64(1<<(bits-1))) {
				cv = constant.BinaryOp(cv, token.OR, constant.MakeInt64(-1<<(bits-1)))
			}
		}
	}
	c = ir.NewConstExpr(cv, c)
	c.SetType(t)
	return c, true
}

const wrapGlobalMapInitSizeThreshold = 20

// tryWrapGlobalMapInit examines the node 'n' to see if it is a map
// variable initialization, and if so, possibly returns the mapvar
// being assigned, a new function containing the init code, and a call
// to the function passing the mapvar. Returns will be nil if the
// assignment is not to a map, or the map init is not big enough,
// or if the expression being assigned to the map has side effects.
func tryWrapGlobalMapInit(n ir.Node) (mapvar *ir.Name, genfn *ir.Func, call ir.Node) {
	// Look for "X = ..." where X has map type.
	// FIXME: might also be worth trying to look for cases where
	// the LHS is of interface type but RHS is map type.
	if n.Op() != ir.OAS {
		return nil, nil, nil
	}
	as := n.(*ir.AssignStmt)
	if ir.IsBlank(as.X) || as.X.Op() != ir.ONAME {
		return nil, nil, nil
	}
	nm := as.X.(*ir.Name)
	if !nm.Type().IsMap() {
		return nil, nil, nil
	}

	// Determine size of RHS.
	rsiz := 0
	ir.Any(as.Y, func(n ir.Node) bool {
		rsiz++
		return false
	})
	if base.Debug.WrapGlobalMapDbg > 0 {
		fmt.Fprintf(os.Stderr, "=-= mapassign %s %v rhs size %d\n",
			base.Ctxt.Pkgpath, n, rsiz)
	}

	// Reject smaller candidates if not in stress mode.
	if rsiz < wrapGlobalMapInitSizeThreshold && base.Debug.WrapGlobalMapStress == 0 {
		if base.Debug.WrapGlobalMapDbg > 1 {
			fmt.Fprintf(os.Stderr, "=-= skipping %v size too small at %d\n",
				nm, rsiz)
		}
		return nil, nil, nil
	}

	// Reject right hand sides with side effects.
	if AnySideEffects(as.Y) {
		if base.Debug.WrapGlobalMapDbg > 0 {
			fmt.Fprintf(os.Stderr, "=-= rejected %v due to side effects\n", nm)
		}
		return nil, nil, nil
	}

	if base.Debug.WrapGlobalMapDbg > 1 {
		fmt.Fprintf(os.Stderr, "=-= committed for: %+v\n", n)
	}

	// Create a new function that will (eventually) have this form:
	//
	//    func map.init.%d() {
	//      globmapvar = <map initialization>
	//    }
	//
	minitsym := typecheck.LookupNum("map.init.", mapinitgen)
	mapinitgen++
	newfn := typecheck.DeclFunc(minitsym, nil, nil, nil)
	if base.Debug.WrapGlobalMapDbg > 0 {
		fmt.Fprintf(os.Stderr, "=-= generated func is %v\n", newfn)
	}

	// NB: we're relying on this phase being run before inlining;
	// if for some reason we need to move it after inlining, we'll
	// need code here that relocates or duplicates inline temps.

	// Insert assignment into function body; mark body finished.
	newfn.Body = append(newfn.Body, as)
	typecheck.FinishFuncBody()

	typecheck.Func(newfn)

	const no = `
	// Register new function with decls.
	typecheck.Target.Decls = append(typecheck.Target.Decls, newfn)
`

	// Create call to function, passing mapvar.
	fncall := ir.NewCallExpr(n.Pos(), ir.OCALL, newfn.Nname, nil)

	if base.Debug.WrapGlobalMapDbg > 1 {
		fmt.Fprintf(os.Stderr, "=-= mapvar is %v\n", nm)
		fmt.Fprintf(os.Stderr, "=-= newfunc is %+v\n", newfn)
		fmt.Fprintf(os.Stderr, "=-= call is %+v\n", fncall)
	}

	return nm, newfn, typecheck.Stmt(fncall)
}

// mapinitgen is a counter used to uniquify compiler-generated
// map init functions.
var mapinitgen int

// AddKeepRelocations adds a dummy "R_KEEP" relocation from each
// global map variable V to its associated outlined init function.
// These relocation ensure that if the map var itself is determined to
// be reachable at link time, we also mark the init function as
// reachable.
func AddKeepRelocations() {
	if varToMapInit == nil {
		return
	}
	for k, v := range varToMapInit {
		// Add R_KEEP relocation from map to init function.
		fs := v.Linksym()
		if fs == nil {
			base.Fatalf("bad: func %v has no linksym", v)
		}
		vs := k.Linksym()
		if vs == nil {
			base.Fatalf("bad: mapvar %v has no linksym", k)
		}
		r := obj.Addrel(vs)
		r.Sym = fs
		r.Type = objabi.R_KEEP
		if base.Debug.WrapGlobalMapDbg > 1 {
			fmt.Fprintf(os.Stderr, "=-= add R_KEEP relo from %s to %s\n",
				vs.Name, fs.Name)
		}
	}
	varToMapInit = nil
}

// OutlineMapInits walks through a list of init statements (candidates
// for inclusion in the package "init" function) and returns an
// updated list in which items corresponding to map variable
// initializations have been replaced with calls to outline "map init"
// functions (if legal/profitable). Return value is an updated list
// and a list of any newly generated "map init" functions.
func OutlineMapInits(stmts []ir.Node) ([]ir.Node, []*ir.Func) {
	if !base.Flag.WrapGlobalMapInit {
		return stmts, nil
	}
	newfuncs := []*ir.Func{}
	for i := range stmts {
		s := stmts[i]
		// Call the helper tryWrapGlobalMapInit to see if the LHS of
		// this assignment is to a map var, and if so whether the RHS
		// should be outlined into a separate init function. If the
		// outline goes through, then replace the original init
		// statement with the call to the outlined func, and append
		// the new outlined func to our return list.
		if mapvar, genfn, call := tryWrapGlobalMapInit(s); call != nil {
			stmts[i] = call
			newfuncs = append(newfuncs, genfn)
			recordFuncForVar(mapvar, genfn)
		}
	}

	return stmts, newfuncs
}
