aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/gc/alg.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/compile/internal/gc/alg.go')
-rw-r--r--src/cmd/compile/internal/gc/alg.go384
1 files changed, 193 insertions, 191 deletions
diff --git a/src/cmd/compile/internal/gc/alg.go b/src/cmd/compile/internal/gc/alg.go
index 2f7fa27bb9..d2762126ad 100644
--- a/src/cmd/compile/internal/gc/alg.go
+++ b/src/cmd/compile/internal/gc/alg.go
@@ -5,6 +5,8 @@
package gc
import (
+ "cmd/compile/internal/base"
+ "cmd/compile/internal/ir"
"cmd/compile/internal/types"
"cmd/internal/obj"
"fmt"
@@ -69,11 +71,11 @@ func EqCanPanic(t *types.Type) bool {
switch t.Etype {
default:
return false
- case TINTER:
+ case types.TINTER:
return true
- case TARRAY:
+ case types.TARRAY:
return EqCanPanic(t.Elem())
- case TSTRUCT:
+ case types.TSTRUCT:
for _, f := range t.FieldSlice() {
if !f.Sym.IsBlank() && EqCanPanic(f.Type) {
return true
@@ -119,45 +121,45 @@ func algtype1(t *types.Type) (AlgKind, *types.Type) {
}
switch t.Etype {
- case TANY, TFORW:
+ case types.TANY, types.TFORW:
// will be defined later.
return ANOEQ, t
- case TINT8, TUINT8, TINT16, TUINT16,
- TINT32, TUINT32, TINT64, TUINT64,
- TINT, TUINT, TUINTPTR,
- TBOOL, TPTR,
- TCHAN, TUNSAFEPTR:
+ case types.TINT8, types.TUINT8, types.TINT16, types.TUINT16,
+ types.TINT32, types.TUINT32, types.TINT64, types.TUINT64,
+ types.TINT, types.TUINT, types.TUINTPTR,
+ types.TBOOL, types.TPTR,
+ types.TCHAN, types.TUNSAFEPTR:
return AMEM, nil
- case TFUNC, TMAP:
+ case types.TFUNC, types.TMAP:
return ANOEQ, t
- case TFLOAT32:
+ case types.TFLOAT32:
return AFLOAT32, nil
- case TFLOAT64:
+ case types.TFLOAT64:
return AFLOAT64, nil
- case TCOMPLEX64:
+ case types.TCOMPLEX64:
return ACPLX64, nil
- case TCOMPLEX128:
+ case types.TCOMPLEX128:
return ACPLX128, nil
- case TSTRING:
+ case types.TSTRING:
return ASTRING, nil
- case TINTER:
+ case types.TINTER:
if t.IsEmptyInterface() {
return ANILINTER, nil
}
return AINTER, nil
- case TSLICE:
+ case types.TSLICE:
return ANOEQ, t
- case TARRAY:
+ case types.TARRAY:
a, bad := algtype1(t.Elem())
switch a {
case AMEM:
@@ -177,7 +179,7 @@ func algtype1(t *types.Type) (AlgKind, *types.Type) {
return ASPECIAL, nil
- case TSTRUCT:
+ case types.TSTRUCT:
fields := t.FieldSlice()
// One-field struct is same as that one field alone.
@@ -203,7 +205,7 @@ func algtype1(t *types.Type) (AlgKind, *types.Type) {
return ret, nil
}
- Fatalf("algtype1: unexpected type %v", t)
+ base.Fatalf("algtype1: unexpected type %v", t)
return 0, nil
}
@@ -214,7 +216,7 @@ func genhash(t *types.Type) *obj.LSym {
switch algtype(t) {
default:
// genhash is only called for types that have equality
- Fatalf("genhash %v", t)
+ base.Fatalf("genhash %v", t)
case AMEM0:
return sysClosure("memhash0")
case AMEM8:
@@ -282,24 +284,24 @@ func genhash(t *types.Type) *obj.LSym {
}
sym := typesymprefix(".hash", t)
- if Debug.r != 0 {
+ if base.Flag.LowerR != 0 {
fmt.Printf("genhash %v %v %v\n", closure, sym, t)
}
- lineno = autogeneratedPos // less confusing than end of input
- dclcontext = PEXTERN
+ base.Pos = autogeneratedPos // less confusing than end of input
+ dclcontext = ir.PEXTERN
// func sym(p *T, h uintptr) uintptr
- tfn := nod(OTFUNC, nil, nil)
- tfn.List.Set2(
+ tfn := ir.Nod(ir.OTFUNC, nil, nil)
+ tfn.PtrList().Set2(
namedfield("p", types.NewPtr(t)),
- namedfield("h", types.Types[TUINTPTR]),
+ namedfield("h", types.Types[types.TUINTPTR]),
)
- tfn.Rlist.Set1(anonfield(types.Types[TUINTPTR]))
+ tfn.PtrRlist().Set1(anonfield(types.Types[types.TUINTPTR]))
fn := dclfunc(sym, tfn)
- np := asNode(tfn.Type.Params().Field(0).Nname)
- nh := asNode(tfn.Type.Params().Field(1).Nname)
+ np := ir.AsNode(tfn.Type().Params().Field(0).Nname)
+ nh := ir.AsNode(tfn.Type().Params().Field(1).Nname)
switch t.Etype {
case types.TARRAY:
@@ -308,25 +310,25 @@ func genhash(t *types.Type) *obj.LSym {
// pure memory.
hashel := hashfor(t.Elem())
- n := nod(ORANGE, nil, nod(ODEREF, np, nil))
- ni := newname(lookup("i"))
- ni.Type = types.Types[TINT]
- n.List.Set1(ni)
+ n := ir.Nod(ir.ORANGE, nil, ir.Nod(ir.ODEREF, np, nil))
+ ni := NewName(lookup("i"))
+ ni.SetType(types.Types[types.TINT])
+ n.PtrList().Set1(ni)
n.SetColas(true)
- colasdefn(n.List.Slice(), n)
- ni = n.List.First()
+ colasdefn(n.List().Slice(), n)
+ ni = n.List().First()
// h = hashel(&p[i], h)
- call := nod(OCALL, hashel, nil)
+ call := ir.Nod(ir.OCALL, hashel, nil)
- nx := nod(OINDEX, np, ni)
+ nx := ir.Nod(ir.OINDEX, np, ni)
nx.SetBounded(true)
- na := nod(OADDR, nx, nil)
- call.List.Append(na)
- call.List.Append(nh)
- n.Nbody.Append(nod(OAS, nh, call))
+ na := ir.Nod(ir.OADDR, nx, nil)
+ call.PtrList().Append(na)
+ call.PtrList().Append(nh)
+ n.PtrBody().Append(ir.Nod(ir.OAS, nh, call))
- fn.Nbody.Append(n)
+ fn.PtrBody().Append(n)
case types.TSTRUCT:
// Walk the struct using memhash for runs of AMEM
@@ -343,12 +345,12 @@ func genhash(t *types.Type) *obj.LSym {
// Hash non-memory fields with appropriate hash function.
if !IsRegularMemory(f.Type) {
hashel := hashfor(f.Type)
- call := nod(OCALL, hashel, nil)
- nx := nodSym(OXDOT, np, f.Sym) // TODO: fields from other packages?
- na := nod(OADDR, nx, nil)
- call.List.Append(na)
- call.List.Append(nh)
- fn.Nbody.Append(nod(OAS, nh, call))
+ call := ir.Nod(ir.OCALL, hashel, nil)
+ nx := nodSym(ir.OXDOT, np, f.Sym) // TODO: fields from other packages?
+ na := ir.Nod(ir.OADDR, nx, nil)
+ call.PtrList().Append(na)
+ call.PtrList().Append(nh)
+ fn.PtrBody().Append(ir.Nod(ir.OAS, nh, call))
i++
continue
}
@@ -358,40 +360,40 @@ func genhash(t *types.Type) *obj.LSym {
// h = hashel(&p.first, size, h)
hashel := hashmem(f.Type)
- call := nod(OCALL, hashel, nil)
- nx := nodSym(OXDOT, np, f.Sym) // TODO: fields from other packages?
- na := nod(OADDR, nx, nil)
- call.List.Append(na)
- call.List.Append(nh)
- call.List.Append(nodintconst(size))
- fn.Nbody.Append(nod(OAS, nh, call))
+ call := ir.Nod(ir.OCALL, hashel, nil)
+ nx := nodSym(ir.OXDOT, np, f.Sym) // TODO: fields from other packages?
+ na := ir.Nod(ir.OADDR, nx, nil)
+ call.PtrList().Append(na)
+ call.PtrList().Append(nh)
+ call.PtrList().Append(nodintconst(size))
+ fn.PtrBody().Append(ir.Nod(ir.OAS, nh, call))
i = next
}
}
- r := nod(ORETURN, nil, nil)
- r.List.Append(nh)
- fn.Nbody.Append(r)
+ r := ir.Nod(ir.ORETURN, nil, nil)
+ r.PtrList().Append(nh)
+ fn.PtrBody().Append(r)
- if Debug.r != 0 {
- dumplist("genhash body", fn.Nbody)
+ if base.Flag.LowerR != 0 {
+ ir.DumpList("genhash body", fn.Body())
}
funcbody()
- fn.Func.SetDupok(true)
+ fn.Func().SetDupok(true)
fn = typecheck(fn, ctxStmt)
Curfn = fn
- typecheckslice(fn.Nbody.Slice(), ctxStmt)
+ typecheckslice(fn.Body().Slice(), ctxStmt)
Curfn = nil
- if debug_dclstack != 0 {
+ if base.Debug.DclStack != 0 {
testdclstack()
}
- fn.Func.SetNilCheckDisabled(true)
+ fn.Func().SetNilCheckDisabled(true)
xtop = append(xtop, fn)
// Build closure. It doesn't close over any variables, so
@@ -402,12 +404,12 @@ func genhash(t *types.Type) *obj.LSym {
return closure
}
-func hashfor(t *types.Type) *Node {
+func hashfor(t *types.Type) ir.Node {
var sym *types.Sym
switch a, _ := algtype1(t); a {
case AMEM:
- Fatalf("hashfor with AMEM type")
+ base.Fatalf("hashfor with AMEM type")
case AINTER:
sym = Runtimepkg.Lookup("interhash")
case ANILINTER:
@@ -428,14 +430,14 @@ func hashfor(t *types.Type) *Node {
sym = typesymprefix(".hash", t)
}
- n := newname(sym)
+ n := NewName(sym)
setNodeNameFunc(n)
- n.Type = functype(nil, []*Node{
+ n.SetType(functype(nil, []ir.Node{
anonfield(types.NewPtr(t)),
- anonfield(types.Types[TUINTPTR]),
- }, []*Node{
- anonfield(types.Types[TUINTPTR]),
- })
+ anonfield(types.Types[types.TUINTPTR]),
+ }, []ir.Node{
+ anonfield(types.Types[types.TUINTPTR]),
+ }))
return n
}
@@ -509,27 +511,27 @@ func geneq(t *types.Type) *obj.LSym {
return closure
}
sym := typesymprefix(".eq", t)
- if Debug.r != 0 {
+ if base.Flag.LowerR != 0 {
fmt.Printf("geneq %v\n", t)
}
// Autogenerate code for equality of structs and arrays.
- lineno = autogeneratedPos // less confusing than end of input
- dclcontext = PEXTERN
+ base.Pos = autogeneratedPos // less confusing than end of input
+ dclcontext = ir.PEXTERN
// func sym(p, q *T) bool
- tfn := nod(OTFUNC, nil, nil)
- tfn.List.Set2(
+ tfn := ir.Nod(ir.OTFUNC, nil, nil)
+ tfn.PtrList().Set2(
namedfield("p", types.NewPtr(t)),
namedfield("q", types.NewPtr(t)),
)
- tfn.Rlist.Set1(namedfield("r", types.Types[TBOOL]))
+ tfn.PtrRlist().Set1(namedfield("r", types.Types[types.TBOOL]))
fn := dclfunc(sym, tfn)
- np := asNode(tfn.Type.Params().Field(0).Nname)
- nq := asNode(tfn.Type.Params().Field(1).Nname)
- nr := asNode(tfn.Type.Results().Field(0).Nname)
+ np := ir.AsNode(tfn.Type().Params().Field(0).Nname)
+ nq := ir.AsNode(tfn.Type().Params().Field(1).Nname)
+ nr := ir.AsNode(tfn.Type().Results().Field(0).Nname)
// Label to jump to if an equality test fails.
neq := autolabel(".neq")
@@ -539,9 +541,9 @@ func geneq(t *types.Type) *obj.LSym {
// so t must be either an array or a struct.
switch t.Etype {
default:
- Fatalf("geneq %v", t)
+ base.Fatalf("geneq %v", t)
- case TARRAY:
+ case types.TARRAY:
nelem := t.NumElem()
// checkAll generates code to check the equality of all array elements.
@@ -565,17 +567,17 @@ func geneq(t *types.Type) *obj.LSym {
//
// TODO(josharian): consider doing some loop unrolling
// for larger nelem as well, processing a few elements at a time in a loop.
- checkAll := func(unroll int64, last bool, eq func(pi, qi *Node) *Node) {
+ checkAll := func(unroll int64, last bool, eq func(pi, qi ir.Node) ir.Node) {
// checkIdx generates a node to check for equality at index i.
- checkIdx := func(i *Node) *Node {
+ checkIdx := func(i ir.Node) ir.Node {
// pi := p[i]
- pi := nod(OINDEX, np, i)
+ pi := ir.Nod(ir.OINDEX, np, i)
pi.SetBounded(true)
- pi.Type = t.Elem()
+ pi.SetType(t.Elem())
// qi := q[i]
- qi := nod(OINDEX, nq, i)
+ qi := ir.Nod(ir.OINDEX, nq, i)
qi.SetBounded(true)
- qi.Type = t.Elem()
+ qi.SetType(t.Elem())
return eq(pi, qi)
}
@@ -587,68 +589,68 @@ func geneq(t *types.Type) *obj.LSym {
// Generate a series of checks.
for i := int64(0); i < nelem; i++ {
// if check {} else { goto neq }
- nif := nod(OIF, checkIdx(nodintconst(i)), nil)
- nif.Rlist.Append(nodSym(OGOTO, nil, neq))
- fn.Nbody.Append(nif)
+ nif := ir.Nod(ir.OIF, checkIdx(nodintconst(i)), nil)
+ nif.PtrRlist().Append(nodSym(ir.OGOTO, nil, neq))
+ fn.PtrBody().Append(nif)
}
if last {
- fn.Nbody.Append(nod(OAS, nr, checkIdx(nodintconst(nelem))))
+ fn.PtrBody().Append(ir.Nod(ir.OAS, nr, checkIdx(nodintconst(nelem))))
}
} else {
// Generate a for loop.
// for i := 0; i < nelem; i++
- i := temp(types.Types[TINT])
- init := nod(OAS, i, nodintconst(0))
- cond := nod(OLT, i, nodintconst(nelem))
- post := nod(OAS, i, nod(OADD, i, nodintconst(1)))
- loop := nod(OFOR, cond, post)
- loop.Ninit.Append(init)
+ i := temp(types.Types[types.TINT])
+ init := ir.Nod(ir.OAS, i, nodintconst(0))
+ cond := ir.Nod(ir.OLT, i, nodintconst(nelem))
+ post := ir.Nod(ir.OAS, i, ir.Nod(ir.OADD, i, nodintconst(1)))
+ loop := ir.Nod(ir.OFOR, cond, post)
+ loop.PtrInit().Append(init)
// if eq(pi, qi) {} else { goto neq }
- nif := nod(OIF, checkIdx(i), nil)
- nif.Rlist.Append(nodSym(OGOTO, nil, neq))
- loop.Nbody.Append(nif)
- fn.Nbody.Append(loop)
+ nif := ir.Nod(ir.OIF, checkIdx(i), nil)
+ nif.PtrRlist().Append(nodSym(ir.OGOTO, nil, neq))
+ loop.PtrBody().Append(nif)
+ fn.PtrBody().Append(loop)
if last {
- fn.Nbody.Append(nod(OAS, nr, nodbool(true)))
+ fn.PtrBody().Append(ir.Nod(ir.OAS, nr, nodbool(true)))
}
}
}
switch t.Elem().Etype {
- case TSTRING:
+ case types.TSTRING:
// Do two loops. First, check that all the lengths match (cheap).
// Second, check that all the contents match (expensive).
// TODO: when the array size is small, unroll the length match checks.
- checkAll(3, false, func(pi, qi *Node) *Node {
+ checkAll(3, false, func(pi, qi ir.Node) ir.Node {
// Compare lengths.
eqlen, _ := eqstring(pi, qi)
return eqlen
})
- checkAll(1, true, func(pi, qi *Node) *Node {
+ checkAll(1, true, func(pi, qi ir.Node) ir.Node {
// Compare contents.
_, eqmem := eqstring(pi, qi)
return eqmem
})
- case TFLOAT32, TFLOAT64:
- checkAll(2, true, func(pi, qi *Node) *Node {
+ case types.TFLOAT32, types.TFLOAT64:
+ checkAll(2, true, func(pi, qi ir.Node) ir.Node {
// p[i] == q[i]
- return nod(OEQ, pi, qi)
+ return ir.Nod(ir.OEQ, pi, qi)
})
// TODO: pick apart structs, do them piecemeal too
default:
- checkAll(1, true, func(pi, qi *Node) *Node {
+ checkAll(1, true, func(pi, qi ir.Node) ir.Node {
// p[i] == q[i]
- return nod(OEQ, pi, qi)
+ return ir.Nod(ir.OEQ, pi, qi)
})
}
- case TSTRUCT:
+ case types.TSTRUCT:
// Build a list of conditions to satisfy.
// The conditions are a list-of-lists. Conditions are reorderable
// within each inner list. The outer lists must be evaluated in order.
- var conds [][]*Node
- conds = append(conds, []*Node{})
- and := func(n *Node) {
+ var conds [][]ir.Node
+ conds = append(conds, []ir.Node{})
+ and := func(n ir.Node) {
i := len(conds) - 1
conds[i] = append(conds[i], n)
}
@@ -668,21 +670,21 @@ func geneq(t *types.Type) *obj.LSym {
if !IsRegularMemory(f.Type) {
if EqCanPanic(f.Type) {
// Enforce ordering by starting a new set of reorderable conditions.
- conds = append(conds, []*Node{})
+ conds = append(conds, []ir.Node{})
}
- p := nodSym(OXDOT, np, f.Sym)
- q := nodSym(OXDOT, nq, f.Sym)
+ p := nodSym(ir.OXDOT, np, f.Sym)
+ q := nodSym(ir.OXDOT, nq, f.Sym)
switch {
case f.Type.IsString():
eqlen, eqmem := eqstring(p, q)
and(eqlen)
and(eqmem)
default:
- and(nod(OEQ, p, q))
+ and(ir.Nod(ir.OEQ, p, q))
}
if EqCanPanic(f.Type) {
// Also enforce ordering after something that can panic.
- conds = append(conds, []*Node{})
+ conds = append(conds, []ir.Node{})
}
i++
continue
@@ -707,10 +709,10 @@ func geneq(t *types.Type) *obj.LSym {
// Sort conditions to put runtime calls last.
// Preserve the rest of the ordering.
- var flatConds []*Node
+ var flatConds []ir.Node
for _, c := range conds {
- isCall := func(n *Node) bool {
- return n.Op == OCALL || n.Op == OCALLFUNC
+ 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])
@@ -719,54 +721,54 @@ func geneq(t *types.Type) *obj.LSym {
}
if len(flatConds) == 0 {
- fn.Nbody.Append(nod(OAS, nr, nodbool(true)))
+ fn.PtrBody().Append(ir.Nod(ir.OAS, nr, nodbool(true)))
} else {
for _, c := range flatConds[:len(flatConds)-1] {
// if cond {} else { goto neq }
- n := nod(OIF, c, nil)
- n.Rlist.Append(nodSym(OGOTO, nil, neq))
- fn.Nbody.Append(n)
+ n := ir.Nod(ir.OIF, c, nil)
+ n.PtrRlist().Append(nodSym(ir.OGOTO, nil, neq))
+ fn.PtrBody().Append(n)
}
- fn.Nbody.Append(nod(OAS, nr, flatConds[len(flatConds)-1]))
+ fn.PtrBody().Append(ir.Nod(ir.OAS, nr, flatConds[len(flatConds)-1]))
}
}
// ret:
// return
ret := autolabel(".ret")
- fn.Nbody.Append(nodSym(OLABEL, nil, ret))
- fn.Nbody.Append(nod(ORETURN, nil, nil))
+ fn.PtrBody().Append(nodSym(ir.OLABEL, nil, ret))
+ fn.PtrBody().Append(ir.Nod(ir.ORETURN, nil, nil))
// neq:
// r = false
// return (or goto ret)
- fn.Nbody.Append(nodSym(OLABEL, nil, neq))
- fn.Nbody.Append(nod(OAS, nr, nodbool(false)))
+ fn.PtrBody().Append(nodSym(ir.OLABEL, nil, neq))
+ fn.PtrBody().Append(ir.Nod(ir.OAS, nr, nodbool(false)))
if EqCanPanic(t) || hasCall(fn) {
// Epilogue is large, so share it with the equal case.
- fn.Nbody.Append(nodSym(OGOTO, nil, ret))
+ fn.PtrBody().Append(nodSym(ir.OGOTO, nil, ret))
} else {
// Epilogue is small, so don't bother sharing.
- fn.Nbody.Append(nod(ORETURN, nil, nil))
+ fn.PtrBody().Append(ir.Nod(ir.ORETURN, nil, nil))
}
// TODO(khr): the epilogue size detection condition above isn't perfect.
// We should really do a generic CL that shares epilogues across
// the board. See #24936.
- if Debug.r != 0 {
- dumplist("geneq body", fn.Nbody)
+ if base.Flag.LowerR != 0 {
+ ir.DumpList("geneq body", fn.Body())
}
funcbody()
- fn.Func.SetDupok(true)
+ fn.Func().SetDupok(true)
fn = typecheck(fn, ctxStmt)
Curfn = fn
- typecheckslice(fn.Nbody.Slice(), ctxStmt)
+ typecheckslice(fn.Body().Slice(), ctxStmt)
Curfn = nil
- if debug_dclstack != 0 {
+ if base.Debug.DclStack != 0 {
testdclstack()
}
@@ -774,7 +776,7 @@ func geneq(t *types.Type) *obj.LSym {
// We are comparing a struct or an array,
// neither of which can be nil, and our comparisons
// are shallow.
- fn.Func.SetNilCheckDisabled(true)
+ fn.Func().SetNilCheckDisabled(true)
xtop = append(xtop, fn)
// Generate a closure which points at the function we just generated.
@@ -783,32 +785,32 @@ func geneq(t *types.Type) *obj.LSym {
return closure
}
-func hasCall(n *Node) bool {
- if n.Op == OCALL || n.Op == OCALLFUNC {
+func hasCall(n ir.Node) bool {
+ if n.Op() == ir.OCALL || n.Op() == ir.OCALLFUNC {
return true
}
- if n.Left != nil && hasCall(n.Left) {
+ if n.Left() != nil && hasCall(n.Left()) {
return true
}
- if n.Right != nil && hasCall(n.Right) {
+ if n.Right() != nil && hasCall(n.Right()) {
return true
}
- for _, x := range n.Ninit.Slice() {
+ for _, x := range n.Init().Slice() {
if hasCall(x) {
return true
}
}
- for _, x := range n.Nbody.Slice() {
+ for _, x := range n.Body().Slice() {
if hasCall(x) {
return true
}
}
- for _, x := range n.List.Slice() {
+ for _, x := range n.List().Slice() {
if hasCall(x) {
return true
}
}
- for _, x := range n.Rlist.Slice() {
+ for _, x := range n.Rlist().Slice() {
if hasCall(x) {
return true
}
@@ -818,10 +820,10 @@ func hasCall(n *Node) bool {
// eqfield returns the node
// p.field == q.field
-func eqfield(p *Node, q *Node, field *types.Sym) *Node {
- nx := nodSym(OXDOT, p, field)
- ny := nodSym(OXDOT, q, field)
- ne := nod(OEQ, nx, ny)
+func eqfield(p ir.Node, q ir.Node, field *types.Sym) ir.Node {
+ nx := nodSym(ir.OXDOT, p, field)
+ ny := nodSym(ir.OXDOT, q, field)
+ ne := ir.Nod(ir.OEQ, nx, ny)
return ne
}
@@ -831,23 +833,23 @@ func eqfield(p *Node, q *Node, field *types.Sym) *Node {
// 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 *Node) (eqlen, eqmem *Node) {
- s = conv(s, types.Types[TSTRING])
- t = conv(t, types.Types[TSTRING])
- sptr := nod(OSPTR, s, nil)
- tptr := nod(OSPTR, t, nil)
- slen := conv(nod(OLEN, s, nil), types.Types[TUINTPTR])
- tlen := conv(nod(OLEN, t, nil), types.Types[TUINTPTR])
+func eqstring(s, t ir.Node) (eqlen, eqmem ir.Node) {
+ s = conv(s, types.Types[types.TSTRING])
+ t = conv(t, types.Types[types.TSTRING])
+ sptr := ir.Nod(ir.OSPTR, s, nil)
+ tptr := ir.Nod(ir.OSPTR, t, nil)
+ slen := conv(ir.Nod(ir.OLEN, s, nil), types.Types[types.TUINTPTR])
+ tlen := conv(ir.Nod(ir.OLEN, t, nil), types.Types[types.TUINTPTR])
fn := syslook("memequal")
- fn = substArgTypes(fn, types.Types[TUINT8], types.Types[TUINT8])
- call := nod(OCALL, fn, nil)
- call.List.Append(sptr, tptr, slen.copy())
+ fn = substArgTypes(fn, types.Types[types.TUINT8], types.Types[types.TUINT8])
+ call := ir.Nod(ir.OCALL, fn, nil)
+ call.PtrList().Append(sptr, tptr, ir.Copy(slen))
call = typecheck(call, ctxExpr|ctxMultiOK)
- cmp := nod(OEQ, slen, tlen)
+ cmp := ir.Nod(ir.OEQ, slen, tlen)
cmp = typecheck(cmp, ctxExpr)
- cmp.Type = types.Types[TBOOL]
+ cmp.SetType(types.Types[types.TBOOL])
return cmp, call
}
@@ -857,58 +859,58 @@ func eqstring(s, t *Node) (eqlen, eqmem *Node) {
// 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 *Node) (eqtab, eqdata *Node) {
- if !types.Identical(s.Type, t.Type) {
- Fatalf("eqinterface %v %v", s.Type, t.Type)
+func eqinterface(s, t ir.Node) (eqtab, eqdata ir.Node) {
+ 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 *Node
- if s.Type.IsEmptyInterface() {
+ var fn ir.Node
+ if s.Type().IsEmptyInterface() {
fn = syslook("efaceeq")
} else {
fn = syslook("ifaceeq")
}
- stab := nod(OITAB, s, nil)
- ttab := nod(OITAB, t, nil)
- sdata := nod(OIDATA, s, nil)
- tdata := nod(OIDATA, t, nil)
- sdata.Type = types.Types[TUNSAFEPTR]
- tdata.Type = types.Types[TUNSAFEPTR]
+ stab := ir.Nod(ir.OITAB, s, nil)
+ ttab := ir.Nod(ir.OITAB, t, nil)
+ sdata := ir.Nod(ir.OIDATA, s, nil)
+ tdata := ir.Nod(ir.OIDATA, t, nil)
+ sdata.SetType(types.Types[types.TUNSAFEPTR])
+ tdata.SetType(types.Types[types.TUNSAFEPTR])
sdata.SetTypecheck(1)
tdata.SetTypecheck(1)
- call := nod(OCALL, fn, nil)
- call.List.Append(stab, sdata, tdata)
+ call := ir.Nod(ir.OCALL, fn, nil)
+ call.PtrList().Append(stab, sdata, tdata)
call = typecheck(call, ctxExpr|ctxMultiOK)
- cmp := nod(OEQ, stab, ttab)
+ cmp := ir.Nod(ir.OEQ, stab, ttab)
cmp = typecheck(cmp, ctxExpr)
- cmp.Type = types.Types[TBOOL]
+ cmp.SetType(types.Types[types.TBOOL])
return cmp, call
}
// eqmem returns the node
// memequal(&p.field, &q.field [, size])
-func eqmem(p *Node, q *Node, field *types.Sym, size int64) *Node {
- nx := nod(OADDR, nodSym(OXDOT, p, field), nil)
- ny := nod(OADDR, nodSym(OXDOT, q, field), nil)
+func eqmem(p ir.Node, q ir.Node, field *types.Sym, size int64) ir.Node {
+ nx := ir.Nod(ir.OADDR, nodSym(ir.OXDOT, p, field), nil)
+ ny := ir.Nod(ir.OADDR, nodSym(ir.OXDOT, q, field), nil)
nx = typecheck(nx, ctxExpr)
ny = typecheck(ny, ctxExpr)
- fn, needsize := eqmemfunc(size, nx.Type.Elem())
- call := nod(OCALL, fn, nil)
- call.List.Append(nx)
- call.List.Append(ny)
+ fn, needsize := eqmemfunc(size, nx.Type().Elem())
+ call := ir.Nod(ir.OCALL, fn, nil)
+ call.PtrList().Append(nx)
+ call.PtrList().Append(ny)
if needsize {
- call.List.Append(nodintconst(size))
+ call.PtrList().Append(nodintconst(size))
}
return call
}
-func eqmemfunc(size int64, t *types.Type) (fn *Node, needsize bool) {
+func eqmemfunc(size int64, t *types.Type) (fn ir.Node, needsize bool) {
switch size {
default:
fn = syslook("memequal")
@@ -949,7 +951,7 @@ func memrun(t *types.Type, start int) (size int64, next int) {
// by padding.
func ispaddedfield(t *types.Type, i int) bool {
if !t.IsStruct() {
- Fatalf("ispaddedfield called non-struct %v", t)
+ base.Fatalf("ispaddedfield called non-struct %v", t)
}
end := t.Width
if i+1 < t.NumFields() {