diff options
Diffstat (limited to 'src/cmd/compile/internal/gc/alg.go')
-rw-r--r-- | src/cmd/compile/internal/gc/alg.go | 384 |
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() { |