]> Cypherpunks.ru repositories - gostls13.git/commitdiff
[dev.regabi] cmd/compile: introduce cmd/compile/internal/ir [generated]
authorRuss Cox <rsc@golang.org>
Fri, 20 Nov 2020 02:09:22 +0000 (21:09 -0500)
committerRuss Cox <rsc@golang.org>
Wed, 25 Nov 2020 16:53:33 +0000 (16:53 +0000)
If we want to break up package gc at all, we will need to move
the compiler IR it defines into a separate package that can be
imported by packages that gc itself imports. This CL does that.
It also removes the TINT8 etc aliases so that all code is clear
about which package things are coming from.

This CL is automatically generated by the script below.
See the comments in the script for details about the changes.

[git-generate]
cd src/cmd/compile/internal/gc

rf '
        # These names were never fully qualified
        # when the types package was added.
        # Do it now, to avoid confusion about where they live.
        inline -rm \
                Txxx \
                TINT8 \
                TUINT8 \
                TINT16 \
                TUINT16 \
                TINT32 \
                TUINT32 \
                TINT64 \
                TUINT64 \
                TINT \
                TUINT \
                TUINTPTR \
                TCOMPLEX64 \
                TCOMPLEX128 \
                TFLOAT32 \
                TFLOAT64 \
                TBOOL \
                TPTR \
                TFUNC \
                TSLICE \
                TARRAY \
                TSTRUCT \
                TCHAN \
                TMAP \
                TINTER \
                TFORW \
                TANY \
                TSTRING \
                TUNSAFEPTR \
                TIDEAL \
                TNIL \
                TBLANK \
                TFUNCARGS \
                TCHANARGS \
                NTYPE \
                BADWIDTH

        # esc.go and escape.go do not need to be split.
        # Append esc.go onto the end of escape.go.
        mv esc.go escape.go

        # Pull out the type format installation from func Main,
        # so it can be carried into package ir.
        mv Main:/Sconv.=/-0,/TypeLinkSym/-1 InstallTypeFormats

        # Names that need to be exported for use by code left in gc.
        mv Isconst IsConst
        mv asNode AsNode
        mv asNodes AsNodes
        mv asTypesNode AsTypesNode
        mv basicnames BasicTypeNames
        mv builtinpkg BuiltinPkg
        mv consttype ConstType
        mv dumplist DumpList
        mv fdumplist FDumpList
        mv fmtMode FmtMode
        mv goopnames OpNames
        mv inspect Inspect
        mv inspectList InspectList
        mv localpkg LocalPkg
        mv nblank BlankNode
        mv numImport NumImport
        mv opprec OpPrec
        mv origSym OrigSym
        mv stmtwithinit StmtWithInit
        mv dump DumpAny
        mv fdump FDumpAny
        mv nod Nod
        mv nodl NodAt
        mv newname NewName
        mv newnamel NewNameAt
        mv assertRepresents AssertValidTypeForConst
        mv represents ValidTypeForConst
        mv nodlit NewLiteral

        # Types and fields that need to be exported for use by gc.
        mv nowritebarrierrecCallSym SymAndPos
        mv SymAndPos.lineno SymAndPos.Pos
        mv SymAndPos.target SymAndPos.Sym

        mv Func.lsym Func.LSym
        mv Func.setWBPos Func.SetWBPos
        mv Func.numReturns Func.NumReturns
        mv Func.numDefers Func.NumDefers
        mv Func.nwbrCalls Func.NWBRCalls

        # initLSym is an algorithm left behind in gc,
        # not an operation on Func itself.
        mv Func.initLSym initLSym

        mv nodeQueue NodeQueue
        mv NodeQueue.empty NodeQueue.Empty
        mv NodeQueue.popLeft NodeQueue.PopLeft
        mv NodeQueue.pushRight NodeQueue.PushRight

        # Many methods on Node are actually algorithms that
        # would apply to any node implementation.
        # Those become plain functions.
        mv Node.funcname FuncName
        mv Node.isBlank IsBlank
        mv Node.isGoConst isGoConst
        mv Node.isNil IsNil
        mv Node.isParamHeapCopy isParamHeapCopy
        mv Node.isParamStackCopy isParamStackCopy
        mv Node.isSimpleName isSimpleName
        mv Node.mayBeShared MayBeShared
        mv Node.pkgFuncName PkgFuncName
        mv Node.backingArrayPtrLen backingArrayPtrLen
        mv Node.isterminating isTermNode
        mv Node.labeledControl labeledControl
        mv Nodes.isterminating isTermNodes
        mv Nodes.sigerr fmtSignature
        mv Node.MethodName methodExprName
        mv Node.MethodFunc methodExprFunc
        mv Node.IsMethod IsMethod

        # Every node will need to implement RawCopy;
        # Copy and SepCopy algorithms will use it.
        mv Node.rawcopy Node.RawCopy
        mv Node.copy Copy
        mv Node.sepcopy SepCopy

        # Extract Node.Format method body into func FmtNode,
        # but leave method wrapper behind.
        mv Node.Format:0,$ FmtNode

        # Formatting helpers that will apply to all node implementations.
        mv Node.Line Line
        mv Node.exprfmt exprFmt
        mv Node.jconv jconvFmt
        mv Node.modeString modeString
        mv Node.nconv nconvFmt
        mv Node.nodedump nodeDumpFmt
        mv Node.nodefmt nodeFmt
        mv Node.stmtfmt stmtFmt

# Constant support needed for code moving to ir.
        mv okforconst OKForConst
        mv vconv FmtConst
        mv int64Val Int64Val
        mv float64Val Float64Val
        mv Node.ValueInterface ConstValue

        # Organize code into files.
        mv LocalPkg BuiltinPkg ir.go
        mv NumImport InstallTypeFormats Line fmt.go
        mv syntax.go Nod NodAt NewNameAt Class Pxxx PragmaFlag Nointerface SymAndPos \
                AsNode AsTypesNode BlankNode OrigSym \
                Node.SliceBounds Node.SetSliceBounds Op.IsSlice3 \
                IsConst Node.Int64Val Node.CanInt64 Node.Uint64Val Node.BoolVal Node.StringVal \
                Node.RawCopy SepCopy Copy \
                IsNil IsBlank IsMethod \
                Node.Typ Node.StorageClass node.go
        mv ConstType ConstValue Int64Val Float64Val AssertValidTypeForConst ValidTypeForConst NewLiteral idealType OKForConst val.go

        # Move files to new ir package.
        mv bitset.go class_string.go dump.go fmt.go \
                ir.go node.go op_string.go val.go \
                sizeof_test.go cmd/compile/internal/ir
'

: # fix mkbuiltin.go to generate the changes made to builtin.go during rf
sed -i '' '
        s/\[T/[types.T/g
        s/\*Node/*ir.Node/g
        /internal\/types/c \
                fmt.Fprintln(&b, `import (`) \
                fmt.Fprintln(&b, `      "cmd/compile/internal/ir"`) \
                fmt.Fprintln(&b, `      "cmd/compile/internal/types"`) \
                fmt.Fprintln(&b, `)`)
' mkbuiltin.go
gofmt -w mkbuiltin.go

: # update cmd/dist to add internal/ir
cd ../../../dist
sed -i '' '/compile.internal.gc/a\
        "cmd/compile/internal/ir",
' buildtool.go
gofmt -w buildtool.go

: # update cmd/compile TestFormats
cd ../..
go install std cmd
cd cmd/compile
go test -u || go test  # first one updates but fails; second passes

Change-Id: I5f7caf6b20629b51970279e81231a3574d5b51db
Reviewed-on: https://go-review.googlesource.com/c/go/+/273008
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
65 files changed:
src/cmd/compile/fmtmap_test.go
src/cmd/compile/internal/arm/ssa.go
src/cmd/compile/internal/arm64/ssa.go
src/cmd/compile/internal/gc/alg.go
src/cmd/compile/internal/gc/align.go
src/cmd/compile/internal/gc/bexport.go
src/cmd/compile/internal/gc/bimport.go
src/cmd/compile/internal/gc/builtin.go
src/cmd/compile/internal/gc/closure.go
src/cmd/compile/internal/gc/const.go
src/cmd/compile/internal/gc/dcl.go
src/cmd/compile/internal/gc/embed.go
src/cmd/compile/internal/gc/esc.go [deleted file]
src/cmd/compile/internal/gc/escape.go
src/cmd/compile/internal/gc/export.go
src/cmd/compile/internal/gc/gen.go
src/cmd/compile/internal/gc/go.go
src/cmd/compile/internal/gc/gsubr.go
src/cmd/compile/internal/gc/iexport.go
src/cmd/compile/internal/gc/iimport.go
src/cmd/compile/internal/gc/init.go
src/cmd/compile/internal/gc/initorder.go
src/cmd/compile/internal/gc/inl.go
src/cmd/compile/internal/gc/lex.go
src/cmd/compile/internal/gc/main.go
src/cmd/compile/internal/gc/mkbuiltin.go
src/cmd/compile/internal/gc/noder.go
src/cmd/compile/internal/gc/obj.go
src/cmd/compile/internal/gc/order.go
src/cmd/compile/internal/gc/pgen.go
src/cmd/compile/internal/gc/pgen_test.go
src/cmd/compile/internal/gc/phi.go
src/cmd/compile/internal/gc/plive.go
src/cmd/compile/internal/gc/racewalk.go
src/cmd/compile/internal/gc/range.go
src/cmd/compile/internal/gc/reflect.go
src/cmd/compile/internal/gc/scc.go
src/cmd/compile/internal/gc/scope.go
src/cmd/compile/internal/gc/select.go
src/cmd/compile/internal/gc/sinit.go
src/cmd/compile/internal/gc/ssa.go
src/cmd/compile/internal/gc/subr.go
src/cmd/compile/internal/gc/swt.go
src/cmd/compile/internal/gc/typecheck.go
src/cmd/compile/internal/gc/types.go
src/cmd/compile/internal/gc/types_acc.go
src/cmd/compile/internal/gc/universe.go
src/cmd/compile/internal/gc/unsafe.go
src/cmd/compile/internal/gc/util.go
src/cmd/compile/internal/gc/walk.go
src/cmd/compile/internal/ir/bitset.go [moved from src/cmd/compile/internal/gc/bitset.go with 99% similarity]
src/cmd/compile/internal/ir/class_string.go [moved from src/cmd/compile/internal/gc/class_string.go with 98% similarity]
src/cmd/compile/internal/ir/dump.go [moved from src/cmd/compile/internal/gc/dump.go with 96% similarity]
src/cmd/compile/internal/ir/fmt.go [moved from src/cmd/compile/internal/gc/fmt.go with 87% similarity]
src/cmd/compile/internal/ir/ir.go [new file with mode: 0644]
src/cmd/compile/internal/ir/node.go [moved from src/cmd/compile/internal/gc/syntax.go with 82% similarity]
src/cmd/compile/internal/ir/op_string.go [moved from src/cmd/compile/internal/gc/op_string.go with 99% similarity]
src/cmd/compile/internal/ir/sizeof_test.go [moved from src/cmd/compile/internal/gc/sizeof_test.go with 98% similarity]
src/cmd/compile/internal/ir/val.go [new file with mode: 0644]
src/cmd/compile/internal/mips/ssa.go
src/cmd/compile/internal/mips64/ssa.go
src/cmd/compile/internal/ppc64/ssa.go
src/cmd/compile/internal/riscv64/ssa.go
src/cmd/compile/internal/wasm/ssa.go
src/cmd/dist/buildtool.go

index e32233bcaf80221797a9640ea826214a39cd3fa9..404e89d0f26026c90848a1054bc5dc09b0333fa5 100644 (file)
@@ -22,14 +22,14 @@ package main_test
 var knownFormats = map[string]string{
        "*bytes.Buffer %s":                                "",
        "*cmd/compile/internal/gc.EscLocation %v":         "",
-       "*cmd/compile/internal/gc.Node %#v":               "",
-       "*cmd/compile/internal/gc.Node %+S":               "",
-       "*cmd/compile/internal/gc.Node %+v":               "",
-       "*cmd/compile/internal/gc.Node %L":                "",
-       "*cmd/compile/internal/gc.Node %S":                "",
-       "*cmd/compile/internal/gc.Node %j":                "",
-       "*cmd/compile/internal/gc.Node %p":                "",
-       "*cmd/compile/internal/gc.Node %v":                "",
+       "*cmd/compile/internal/ir.Node %#v":               "",
+       "*cmd/compile/internal/ir.Node %+S":               "",
+       "*cmd/compile/internal/ir.Node %+v":               "",
+       "*cmd/compile/internal/ir.Node %L":                "",
+       "*cmd/compile/internal/ir.Node %S":                "",
+       "*cmd/compile/internal/ir.Node %j":                "",
+       "*cmd/compile/internal/ir.Node %p":                "",
+       "*cmd/compile/internal/ir.Node %v":                "",
        "*cmd/compile/internal/ssa.Block %s":              "",
        "*cmd/compile/internal/ssa.Block %v":              "",
        "*cmd/compile/internal/ssa.Func %s":               "",
@@ -78,18 +78,18 @@ var knownFormats = map[string]string{
        "byte %q":                                         "",
        "byte %v":                                         "",
        "cmd/compile/internal/arm.shift %d":               "",
-       "cmd/compile/internal/gc.Class %d":                "",
-       "cmd/compile/internal/gc.Class %s":                "",
-       "cmd/compile/internal/gc.Class %v":                "",
-       "cmd/compile/internal/gc.Nodes %#v":               "",
-       "cmd/compile/internal/gc.Nodes %+v":               "",
-       "cmd/compile/internal/gc.Nodes %.v":               "",
-       "cmd/compile/internal/gc.Nodes %v":                "",
-       "cmd/compile/internal/gc.Op %#v":                  "",
-       "cmd/compile/internal/gc.Op %v":                   "",
-       "cmd/compile/internal/gc.fmtMode %d":              "",
        "cmd/compile/internal/gc.initKind %d":             "",
        "cmd/compile/internal/gc.itag %v":                 "",
+       "cmd/compile/internal/ir.Class %d":                "",
+       "cmd/compile/internal/ir.Class %s":                "",
+       "cmd/compile/internal/ir.Class %v":                "",
+       "cmd/compile/internal/ir.FmtMode %d":              "",
+       "cmd/compile/internal/ir.Nodes %#v":               "",
+       "cmd/compile/internal/ir.Nodes %+v":               "",
+       "cmd/compile/internal/ir.Nodes %.v":               "",
+       "cmd/compile/internal/ir.Nodes %v":                "",
+       "cmd/compile/internal/ir.Op %#v":                  "",
+       "cmd/compile/internal/ir.Op %v":                   "",
        "cmd/compile/internal/ssa.BranchPrediction %d":    "",
        "cmd/compile/internal/ssa.Edge %v":                "",
        "cmd/compile/internal/ssa.GCNode %v":              "",
@@ -162,8 +162,8 @@ var knownFormats = map[string]string{
        "interface{} %q":                                  "",
        "interface{} %s":                                  "",
        "interface{} %v":                                  "",
-       "map[*cmd/compile/internal/gc.Node]*cmd/compile/internal/ssa.Value %v": "",
-       "map[*cmd/compile/internal/gc.Node][]*cmd/compile/internal/gc.Node %v": "",
+       "map[*cmd/compile/internal/ir.Node]*cmd/compile/internal/ssa.Value %v": "",
+       "map[*cmd/compile/internal/ir.Node][]*cmd/compile/internal/ir.Node %v": "",
        "map[cmd/compile/internal/ssa.ID]uint32 %v":                            "",
        "map[int64]uint32 %v":  "",
        "math/big.Accuracy %s": "",
index 7d34cc517005f7d9ef958121d6821841a27367d3..ff1dd8869e211fcd67ffa81b62b9ad528cfa1709 100644 (file)
@@ -11,6 +11,7 @@ import (
 
        "cmd/compile/internal/base"
        "cmd/compile/internal/gc"
+       "cmd/compile/internal/ir"
        "cmd/compile/internal/logopt"
        "cmd/compile/internal/ssa"
        "cmd/compile/internal/types"
@@ -545,7 +546,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                case *obj.LSym:
                        wantreg = "SB"
                        gc.AddAux(&p.From, v)
-               case *gc.Node:
+               case *ir.Node:
                        wantreg = "SP"
                        gc.AddAux(&p.From, v)
                case nil:
index 5e6f607708df21e577d613e9a64aeb81a6abb182..58c00dc3bd14c426236f61024fad58a7cbab3363 100644 (file)
@@ -9,6 +9,7 @@ import (
 
        "cmd/compile/internal/base"
        "cmd/compile/internal/gc"
+       "cmd/compile/internal/ir"
        "cmd/compile/internal/logopt"
        "cmd/compile/internal/ssa"
        "cmd/compile/internal/types"
@@ -395,7 +396,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                case *obj.LSym:
                        wantreg = "SB"
                        gc.AddAux(&p.From, v)
-               case *gc.Node:
+               case *ir.Node:
                        wantreg = "SP"
                        gc.AddAux(&p.From, v)
                case nil:
index 517aaa4b814cfac23e12fa954a62eedab2609b93..cf82b9d5916e0c50cee12b2cbb4278cec5de6242 100644 (file)
@@ -6,6 +6,7 @@ package gc
 
 import (
        "cmd/compile/internal/base"
+       "cmd/compile/internal/ir"
        "cmd/compile/internal/types"
        "cmd/internal/obj"
        "fmt"
@@ -70,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
@@ -120,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:
@@ -178,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.
@@ -288,19 +289,19 @@ func genhash(t *types.Type) *obj.LSym {
        }
 
        base.Pos = autogeneratedPos // less confusing than end of input
-       dclcontext = PEXTERN
+       dclcontext = ir.PEXTERN
 
        // func sym(p *T, h uintptr) uintptr
-       tfn := nod(OTFUNC, nil, nil)
+       tfn := ir.Nod(ir.OTFUNC, nil, nil)
        tfn.List.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.Rlist.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:
@@ -309,23 +310,23 @@ 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 := ir.Nod(ir.ORANGE, nil, ir.Nod(ir.ODEREF, np, nil))
+               ni := NewName(lookup("i"))
+               ni.Type = types.Types[types.TINT]
                n.List.Set1(ni)
                n.SetColas(true)
                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)
+               na := ir.Nod(ir.OADDR, nx, nil)
                call.List.Append(na)
                call.List.Append(nh)
-               n.Nbody.Append(nod(OAS, nh, call))
+               n.Nbody.Append(ir.Nod(ir.OAS, nh, call))
 
                fn.Nbody.Append(n)
 
@@ -344,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 := 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.List.Append(na)
                                call.List.Append(nh)
-                               fn.Nbody.Append(nod(OAS, nh, call))
+                               fn.Nbody.Append(ir.Nod(ir.OAS, nh, call))
                                i++
                                continue
                        }
@@ -359,24 +360,24 @@ 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 := 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.List.Append(na)
                        call.List.Append(nh)
                        call.List.Append(nodintconst(size))
-                       fn.Nbody.Append(nod(OAS, nh, call))
+                       fn.Nbody.Append(ir.Nod(ir.OAS, nh, call))
 
                        i = next
                }
        }
 
-       r := nod(ORETURN, nil, nil)
+       r := ir.Nod(ir.ORETURN, nil, nil)
        r.List.Append(nh)
        fn.Nbody.Append(r)
 
        if base.Flag.LowerR != 0 {
-               dumplist("genhash body", fn.Nbody)
+               ir.DumpList("genhash body", fn.Nbody)
        }
 
        funcbody()
@@ -403,7 +404,7 @@ 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 {
@@ -429,13 +430,13 @@ func hashfor(t *types.Type) *Node {
                sym = typesymprefix(".hash", t)
        }
 
-       n := newname(sym)
+       n := NewName(sym)
        setNodeNameFunc(n)
-       n.Type = functype(nil, []*Node{
+       n.Type = 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
 }
@@ -517,20 +518,20 @@ func geneq(t *types.Type) *obj.LSym {
        // Autogenerate code for equality of structs and arrays.
 
        base.Pos = autogeneratedPos // less confusing than end of input
-       dclcontext = PEXTERN
+       dclcontext = ir.PEXTERN
 
        // func sym(p, q *T) bool
-       tfn := nod(OTFUNC, nil, nil)
+       tfn := ir.Nod(ir.OTFUNC, nil, nil)
        tfn.List.Set2(
                namedfield("p", types.NewPtr(t)),
                namedfield("q", types.NewPtr(t)),
        )
-       tfn.Rlist.Set1(namedfield("r", types.Types[TBOOL]))
+       tfn.Rlist.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")
@@ -542,7 +543,7 @@ func geneq(t *types.Type) *obj.LSym {
        default:
                base.Fatalf("geneq %v", t)
 
-       case TARRAY:
+       case types.TARRAY:
                nelem := t.NumElem()
 
                // checkAll generates code to check the equality of all array elements.
@@ -566,15 +567,15 @@ 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()
                                // qi := q[i]
-                               qi := nod(OINDEX, nq, i)
+                               qi := ir.Nod(ir.OINDEX, nq, i)
                                qi.SetBounded(true)
                                qi.Type = t.Elem()
                                return eq(pi, qi)
@@ -588,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))
+                                       nif := ir.Nod(ir.OIF, checkIdx(nodintconst(i)), nil)
+                                       nif.Rlist.Append(nodSym(ir.OGOTO, nil, neq))
                                        fn.Nbody.Append(nif)
                                }
                                if last {
-                                       fn.Nbody.Append(nod(OAS, nr, checkIdx(nodintconst(nelem))))
+                                       fn.Nbody.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)
+                               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.Ninit.Append(init)
                                // if eq(pi, qi) {} else { goto neq }
-                               nif := nod(OIF, checkIdx(i), nil)
-                               nif.Rlist.Append(nodSym(OGOTO, nil, neq))
+                               nif := ir.Nod(ir.OIF, checkIdx(i), nil)
+                               nif.Rlist.Append(nodSym(ir.OGOTO, nil, neq))
                                loop.Nbody.Append(nif)
                                fn.Nbody.Append(loop)
                                if last {
-                                       fn.Nbody.Append(nod(OAS, nr, nodbool(true)))
+                                       fn.Nbody.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)
                }
@@ -669,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
@@ -708,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])
@@ -720,42 +721,42 @@ func geneq(t *types.Type) *obj.LSym {
                }
 
                if len(flatConds) == 0 {
-                       fn.Nbody.Append(nod(OAS, nr, nodbool(true)))
+                       fn.Nbody.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))
+                               n := ir.Nod(ir.OIF, c, nil)
+                               n.Rlist.Append(nodSym(ir.OGOTO, nil, neq))
                                fn.Nbody.Append(n)
                        }
-                       fn.Nbody.Append(nod(OAS, nr, flatConds[len(flatConds)-1]))
+                       fn.Nbody.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.Nbody.Append(nodSym(ir.OLABEL, nil, ret))
+       fn.Nbody.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.Nbody.Append(nodSym(ir.OLABEL, nil, neq))
+       fn.Nbody.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.Nbody.Append(nodSym(ir.OGOTO, nil, ret))
        } else {
                // Epilogue is small, so don't bother sharing.
-               fn.Nbody.Append(nod(ORETURN, nil, nil))
+               fn.Nbody.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 base.Flag.LowerR != 0 {
-               dumplist("geneq body", fn.Nbody)
+               ir.DumpList("geneq body", fn.Nbody)
        }
 
        funcbody()
@@ -784,8 +785,8 @@ 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) {
@@ -819,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
 }
 
@@ -832,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.List.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.Type = types.Types[types.TBOOL]
        return cmp, call
 }
 
@@ -858,48 +859,48 @@ 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) {
+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
+       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.Type = types.Types[types.TUNSAFEPTR]
+       tdata.Type = types.Types[types.TUNSAFEPTR]
        sdata.SetTypecheck(1)
        tdata.SetTypecheck(1)
 
-       call := nod(OCALL, fn, nil)
+       call := ir.Nod(ir.OCALL, fn, nil)
        call.List.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.Type = 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 := ir.Nod(ir.OCALL, fn, nil)
        call.List.Append(nx)
        call.List.Append(ny)
        if needsize {
@@ -909,7 +910,7 @@ func eqmem(p *Node, q *Node, field *types.Sym, size int64) *Node {
        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")
index a8cbbfd322ccfe93b12dcd8c649ff7ee1ae746be..1bc8bf238f74ee6da9dec93fba23c1559d30f2cb 100644 (file)
@@ -7,6 +7,7 @@ package gc
 import (
        "bytes"
        "cmd/compile/internal/base"
+       "cmd/compile/internal/ir"
        "cmd/compile/internal/types"
        "fmt"
        "sort"
@@ -117,7 +118,7 @@ func widstruct(errtype *types.Type, t *types.Type, o int64, flag int) int64 {
                        o = Rnd(o, int64(f.Type.Align))
                }
                f.Offset = o
-               if n := asNode(f.Nname); n != nil {
+               if n := ir.AsNode(f.Nname); n != nil {
                        // addrescapes has similar code to update these offsets.
                        // Usually addrescapes runs after widstruct,
                        // in which case we could drop this,
@@ -197,7 +198,7 @@ func findTypeLoop(t *types.Type, path *[]*types.Type) bool {
                }
 
                *path = append(*path, t)
-               if p := asNode(t.Nod).Name.Param; p != nil && findTypeLoop(p.Ntype.Type, path) {
+               if p := ir.AsNode(t.Nod).Name.Param; p != nil && findTypeLoop(p.Ntype.Type, path) {
                        return true
                }
                *path = (*path)[:len(*path)-1]
@@ -205,17 +206,17 @@ func findTypeLoop(t *types.Type, path *[]*types.Type) bool {
                // Anonymous type. Recurse on contained types.
 
                switch t.Etype {
-               case TARRAY:
+               case types.TARRAY:
                        if findTypeLoop(t.Elem(), path) {
                                return true
                        }
-               case TSTRUCT:
+               case types.TSTRUCT:
                        for _, f := range t.Fields().Slice() {
                                if findTypeLoop(f.Type, path) {
                                        return true
                                }
                        }
-               case TINTER:
+               case types.TINTER:
                        for _, m := range t.Methods().Slice() {
                                if m.Type.IsInterface() { // embedded interface
                                        if findTypeLoop(m.Type, path) {
@@ -306,8 +307,8 @@ func dowidth(t *types.Type) {
        defercheckwidth()
 
        lno := base.Pos
-       if asNode(t.Nod) != nil {
-               base.Pos = asNode(t.Nod).Pos
+       if ir.AsNode(t.Nod) != nil {
+               base.Pos = ir.AsNode(t.Nod).Pos
        }
 
        t.Width = -2
@@ -315,7 +316,7 @@ func dowidth(t *types.Type) {
 
        et := t.Etype
        switch et {
-       case TFUNC, TCHAN, TMAP, TSTRING:
+       case types.TFUNC, types.TCHAN, types.TMAP, types.TSTRING:
                break
 
        // simtype == 0 during bootstrap
@@ -331,41 +332,41 @@ func dowidth(t *types.Type) {
                base.Fatalf("dowidth: unknown type: %v", t)
 
        // compiler-specific stuff
-       case TINT8, TUINT8, TBOOL:
+       case types.TINT8, types.TUINT8, types.TBOOL:
                // bool is int8
                w = 1
 
-       case TINT16, TUINT16:
+       case types.TINT16, types.TUINT16:
                w = 2
 
-       case TINT32, TUINT32, TFLOAT32:
+       case types.TINT32, types.TUINT32, types.TFLOAT32:
                w = 4
 
-       case TINT64, TUINT64, TFLOAT64:
+       case types.TINT64, types.TUINT64, types.TFLOAT64:
                w = 8
                t.Align = uint8(Widthreg)
 
-       case TCOMPLEX64:
+       case types.TCOMPLEX64:
                w = 8
                t.Align = 4
 
-       case TCOMPLEX128:
+       case types.TCOMPLEX128:
                w = 16
                t.Align = uint8(Widthreg)
 
-       case TPTR:
+       case types.TPTR:
                w = int64(Widthptr)
                checkwidth(t.Elem())
 
-       case TUNSAFEPTR:
+       case types.TUNSAFEPTR:
                w = int64(Widthptr)
 
-       case TINTER: // implemented as 2 pointers
+       case types.TINTER: // implemented as 2 pointers
                w = 2 * int64(Widthptr)
                t.Align = uint8(Widthptr)
                expandiface(t)
 
-       case TCHAN: // implemented as pointer
+       case types.TCHAN: // implemented as pointer
                w = int64(Widthptr)
 
                checkwidth(t.Elem())
@@ -375,7 +376,7 @@ func dowidth(t *types.Type) {
                t1 := types.NewChanArgs(t)
                checkwidth(t1)
 
-       case TCHANARGS:
+       case types.TCHANARGS:
                t1 := t.ChanArgs()
                dowidth(t1) // just in case
                if t1.Elem().Width >= 1<<16 {
@@ -383,27 +384,27 @@ func dowidth(t *types.Type) {
                }
                w = 1 // anything will do
 
-       case TMAP: // implemented as pointer
+       case types.TMAP: // implemented as pointer
                w = int64(Widthptr)
                checkwidth(t.Elem())
                checkwidth(t.Key())
 
-       case TFORW: // should have been filled in
+       case types.TFORW: // should have been filled in
                reportTypeLoop(t)
                w = 1 // anything will do
 
-       case TANY:
+       case types.TANY:
                // not a real type; should be replaced before use.
                base.Fatalf("dowidth any")
 
-       case TSTRING:
+       case types.TSTRING:
                if sizeofString == 0 {
                        base.Fatalf("early dowidth string")
                }
                w = sizeofString
                t.Align = uint8(Widthptr)
 
-       case TARRAY:
+       case types.TARRAY:
                if t.Elem() == nil {
                        break
                }
@@ -418,7 +419,7 @@ func dowidth(t *types.Type) {
                w = t.NumElem() * t.Elem().Width
                t.Align = t.Elem().Align
 
-       case TSLICE:
+       case types.TSLICE:
                if t.Elem() == nil {
                        break
                }
@@ -426,7 +427,7 @@ func dowidth(t *types.Type) {
                checkwidth(t.Elem())
                t.Align = uint8(Widthptr)
 
-       case TSTRUCT:
+       case types.TSTRUCT:
                if t.IsFuncArgStruct() {
                        base.Fatalf("dowidth fn struct %v", t)
                }
@@ -434,14 +435,14 @@ func dowidth(t *types.Type) {
 
        // make fake type to check later to
        // trigger function argument computation.
-       case TFUNC:
+       case types.TFUNC:
                t1 := types.NewFuncArgs(t)
                checkwidth(t1)
                w = int64(Widthptr) // width of func type is pointer
 
        // function is 3 cated structures;
        // compute their widths as side-effect.
-       case TFUNCARGS:
+       case types.TFUNCARGS:
                t1 := t.FuncArgs()
                w = widstruct(t1, t1.Recvs(), 0, 0)
                w = widstruct(t1, t1.Params(), w, Widthreg)
index 6564024a0c8ddeae4992e34498b7d567cd208ae2..ff33c6b5fcf73fd700cdf6f4b9bd29c30477065e 100644 (file)
@@ -5,6 +5,7 @@
 package gc
 
 import (
+       "cmd/compile/internal/ir"
        "cmd/compile/internal/types"
 )
 
@@ -13,8 +14,8 @@ type exporter struct {
 }
 
 // markObject visits a reachable object.
-func (p *exporter) markObject(n *Node) {
-       if n.Op == ONAME && n.Class() == PFUNC {
+func (p *exporter) markObject(n *ir.Node) {
+       if n.Op == ir.ONAME && n.Class() == ir.PFUNC {
                inlFlood(n)
        }
 
@@ -34,10 +35,10 @@ func (p *exporter) markType(t *types.Type) {
        // only their unexpanded method set (i.e., exclusive of
        // interface embeddings), and the switch statement below
        // handles their full method set.
-       if t.Sym != nil && t.Etype != TINTER {
+       if t.Sym != nil && t.Etype != types.TINTER {
                for _, m := range t.Methods().Slice() {
                        if types.IsExported(m.Sym.Name) {
-                               p.markObject(asNode(m.Nname))
+                               p.markObject(ir.AsNode(m.Nname))
                        }
                }
        }
@@ -52,31 +53,31 @@ func (p *exporter) markType(t *types.Type) {
        // the user already needs some way to construct values of
        // those types.
        switch t.Etype {
-       case TPTR, TARRAY, TSLICE:
+       case types.TPTR, types.TARRAY, types.TSLICE:
                p.markType(t.Elem())
 
-       case TCHAN:
+       case types.TCHAN:
                if t.ChanDir().CanRecv() {
                        p.markType(t.Elem())
                }
 
-       case TMAP:
+       case types.TMAP:
                p.markType(t.Key())
                p.markType(t.Elem())
 
-       case TSTRUCT:
+       case types.TSTRUCT:
                for _, f := range t.FieldSlice() {
                        if types.IsExported(f.Sym.Name) || f.Embedded != 0 {
                                p.markType(f.Type)
                        }
                }
 
-       case TFUNC:
+       case types.TFUNC:
                for _, f := range t.Results().FieldSlice() {
                        p.markType(f.Type)
                }
 
-       case TINTER:
+       case types.TINTER:
                for _, f := range t.FieldSlice() {
                        if types.IsExported(f.Sym.Name) {
                                p.markType(f.Type)
@@ -133,23 +134,23 @@ func predeclared() []*types.Type {
                // elements have been initialized before
                predecl = []*types.Type{
                        // basic types
-                       types.Types[TBOOL],
-                       types.Types[TINT],
-                       types.Types[TINT8],
-                       types.Types[TINT16],
-                       types.Types[TINT32],
-                       types.Types[TINT64],
-                       types.Types[TUINT],
-                       types.Types[TUINT8],
-                       types.Types[TUINT16],
-                       types.Types[TUINT32],
-                       types.Types[TUINT64],
-                       types.Types[TUINTPTR],
-                       types.Types[TFLOAT32],
-                       types.Types[TFLOAT64],
-                       types.Types[TCOMPLEX64],
-                       types.Types[TCOMPLEX128],
-                       types.Types[TSTRING],
+                       types.Types[types.TBOOL],
+                       types.Types[types.TINT],
+                       types.Types[types.TINT8],
+                       types.Types[types.TINT16],
+                       types.Types[types.TINT32],
+                       types.Types[types.TINT64],
+                       types.Types[types.TUINT],
+                       types.Types[types.TUINT8],
+                       types.Types[types.TUINT16],
+                       types.Types[types.TUINT32],
+                       types.Types[types.TUINT64],
+                       types.Types[types.TUINTPTR],
+                       types.Types[types.TFLOAT32],
+                       types.Types[types.TFLOAT64],
+                       types.Types[types.TCOMPLEX64],
+                       types.Types[types.TCOMPLEX128],
+                       types.Types[types.TSTRING],
 
                        // basic type aliases
                        types.Bytetype,
@@ -165,16 +166,16 @@ func predeclared() []*types.Type {
                        types.UntypedFloat,
                        types.UntypedComplex,
                        types.UntypedString,
-                       types.Types[TNIL],
+                       types.Types[types.TNIL],
 
                        // package unsafe
-                       types.Types[TUNSAFEPTR],
+                       types.Types[types.TUNSAFEPTR],
 
                        // invalid type (package contains errors)
-                       types.Types[Txxx],
+                       types.Types[types.Txxx],
 
                        // any type, for builtin export data
-                       types.Types[TANY],
+                       types.Types[types.TANY],
                }
        }
        return predecl
index 911ac4c0dc7b6d83e9a5c5cb1b4d5ee67d37673e..e2dd276f46165018f6c768e0f2b521ab810c8048 100644 (file)
@@ -5,20 +5,15 @@
 package gc
 
 import (
+       "cmd/compile/internal/ir"
        "cmd/internal/src"
 )
 
-// numImport tracks how often a package with a given name is imported.
-// It is used to provide a better error message (by using the package
-// path to disambiguate) if a package that appears multiple times with
-// the same name appears in an error message.
-var numImport = make(map[string]int)
-
-func npos(pos src.XPos, n *Node) *Node {
+func npos(pos src.XPos, n *ir.Node) *ir.Node {
        n.Pos = pos
        return n
 }
 
-func builtinCall(op Op) *Node {
-       return nod(OCALL, mkname(builtinpkg.Lookup(goopnames[op])), nil)
+func builtinCall(op ir.Op) *ir.Node {
+       return ir.Nod(ir.OCALL, mkname(ir.BuiltinPkg.Lookup(ir.OpNames[op])), nil)
 }
index fd95b657b26621504abd70bd4ddcf0c7d984fafd..5016905f225d3d72a18a28254ac8098e9935246c 100644 (file)
@@ -2,7 +2,10 @@
 
 package gc
 
-import "cmd/compile/internal/types"
+import (
+       "cmd/compile/internal/ir"
+       "cmd/compile/internal/types"
+)
 
 var runtimeDecls = [...]struct {
        name string
@@ -205,134 +208,134 @@ func runtimeTypes() []*types.Type {
        var typs [131]*types.Type
        typs[0] = types.Bytetype
        typs[1] = types.NewPtr(typs[0])
-       typs[2] = types.Types[TANY]
+       typs[2] = types.Types[types.TANY]
        typs[3] = types.NewPtr(typs[2])
-       typs[4] = functype(nil, []*Node{anonfield(typs[1])}, []*Node{anonfield(typs[3])})
-       typs[5] = types.Types[TUINTPTR]
-       typs[6] = types.Types[TBOOL]
-       typs[7] = types.Types[TUNSAFEPTR]
-       typs[8] = functype(nil, []*Node{anonfield(typs[5]), anonfield(typs[1]), anonfield(typs[6])}, []*Node{anonfield(typs[7])})
+       typs[4] = functype(nil, []*ir.Node{anonfield(typs[1])}, []*ir.Node{anonfield(typs[3])})
+       typs[5] = types.Types[types.TUINTPTR]
+       typs[6] = types.Types[types.TBOOL]
+       typs[7] = types.Types[types.TUNSAFEPTR]
+       typs[8] = functype(nil, []*ir.Node{anonfield(typs[5]), anonfield(typs[1]), anonfield(typs[6])}, []*ir.Node{anonfield(typs[7])})
        typs[9] = functype(nil, nil, nil)
-       typs[10] = types.Types[TINTER]
-       typs[11] = functype(nil, []*Node{anonfield(typs[10])}, nil)
-       typs[12] = types.Types[TINT32]
+       typs[10] = types.Types[types.TINTER]
+       typs[11] = functype(nil, []*ir.Node{anonfield(typs[10])}, nil)
+       typs[12] = types.Types[types.TINT32]
        typs[13] = types.NewPtr(typs[12])
-       typs[14] = functype(nil, []*Node{anonfield(typs[13])}, []*Node{anonfield(typs[10])})
-       typs[15] = types.Types[TINT]
-       typs[16] = functype(nil, []*Node{anonfield(typs[15]), anonfield(typs[15])}, nil)
-       typs[17] = types.Types[TUINT]
-       typs[18] = functype(nil, []*Node{anonfield(typs[17]), anonfield(typs[15])}, nil)
-       typs[19] = functype(nil, []*Node{anonfield(typs[6])}, nil)
-       typs[20] = types.Types[TFLOAT64]
-       typs[21] = functype(nil, []*Node{anonfield(typs[20])}, nil)
-       typs[22] = types.Types[TINT64]
-       typs[23] = functype(nil, []*Node{anonfield(typs[22])}, nil)
-       typs[24] = types.Types[TUINT64]
-       typs[25] = functype(nil, []*Node{anonfield(typs[24])}, nil)
-       typs[26] = types.Types[TCOMPLEX128]
-       typs[27] = functype(nil, []*Node{anonfield(typs[26])}, nil)
-       typs[28] = types.Types[TSTRING]
-       typs[29] = functype(nil, []*Node{anonfield(typs[28])}, nil)
-       typs[30] = functype(nil, []*Node{anonfield(typs[2])}, nil)
-       typs[31] = functype(nil, []*Node{anonfield(typs[5])}, nil)
+       typs[14] = functype(nil, []*ir.Node{anonfield(typs[13])}, []*ir.Node{anonfield(typs[10])})
+       typs[15] = types.Types[types.TINT]
+       typs[16] = functype(nil, []*ir.Node{anonfield(typs[15]), anonfield(typs[15])}, nil)
+       typs[17] = types.Types[types.TUINT]
+       typs[18] = functype(nil, []*ir.Node{anonfield(typs[17]), anonfield(typs[15])}, nil)
+       typs[19] = functype(nil, []*ir.Node{anonfield(typs[6])}, nil)
+       typs[20] = types.Types[types.TFLOAT64]
+       typs[21] = functype(nil, []*ir.Node{anonfield(typs[20])}, nil)
+       typs[22] = types.Types[types.TINT64]
+       typs[23] = functype(nil, []*ir.Node{anonfield(typs[22])}, nil)
+       typs[24] = types.Types[types.TUINT64]
+       typs[25] = functype(nil, []*ir.Node{anonfield(typs[24])}, nil)
+       typs[26] = types.Types[types.TCOMPLEX128]
+       typs[27] = functype(nil, []*ir.Node{anonfield(typs[26])}, nil)
+       typs[28] = types.Types[types.TSTRING]
+       typs[29] = functype(nil, []*ir.Node{anonfield(typs[28])}, nil)
+       typs[30] = functype(nil, []*ir.Node{anonfield(typs[2])}, nil)
+       typs[31] = functype(nil, []*ir.Node{anonfield(typs[5])}, nil)
        typs[32] = types.NewArray(typs[0], 32)
        typs[33] = types.NewPtr(typs[32])
-       typs[34] = functype(nil, []*Node{anonfield(typs[33]), anonfield(typs[28]), anonfield(typs[28])}, []*Node{anonfield(typs[28])})
-       typs[35] = functype(nil, []*Node{anonfield(typs[33]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28])}, []*Node{anonfield(typs[28])})
-       typs[36] = functype(nil, []*Node{anonfield(typs[33]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28])}, []*Node{anonfield(typs[28])})
-       typs[37] = functype(nil, []*Node{anonfield(typs[33]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28])}, []*Node{anonfield(typs[28])})
+       typs[34] = functype(nil, []*ir.Node{anonfield(typs[33]), anonfield(typs[28]), anonfield(typs[28])}, []*ir.Node{anonfield(typs[28])})
+       typs[35] = functype(nil, []*ir.Node{anonfield(typs[33]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28])}, []*ir.Node{anonfield(typs[28])})
+       typs[36] = functype(nil, []*ir.Node{anonfield(typs[33]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28])}, []*ir.Node{anonfield(typs[28])})
+       typs[37] = functype(nil, []*ir.Node{anonfield(typs[33]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28]), anonfield(typs[28])}, []*ir.Node{anonfield(typs[28])})
        typs[38] = types.NewSlice(typs[28])
-       typs[39] = functype(nil, []*Node{anonfield(typs[33]), anonfield(typs[38])}, []*Node{anonfield(typs[28])})
-       typs[40] = functype(nil, []*Node{anonfield(typs[28]), anonfield(typs[28])}, []*Node{anonfield(typs[15])})
+       typs[39] = functype(nil, []*ir.Node{anonfield(typs[33]), anonfield(typs[38])}, []*ir.Node{anonfield(typs[28])})
+       typs[40] = functype(nil, []*ir.Node{anonfield(typs[28]), anonfield(typs[28])}, []*ir.Node{anonfield(typs[15])})
        typs[41] = types.NewArray(typs[0], 4)
        typs[42] = types.NewPtr(typs[41])
-       typs[43] = functype(nil, []*Node{anonfield(typs[42]), anonfield(typs[22])}, []*Node{anonfield(typs[28])})
-       typs[44] = functype(nil, []*Node{anonfield(typs[33]), anonfield(typs[1]), anonfield(typs[15])}, []*Node{anonfield(typs[28])})
-       typs[45] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15])}, []*Node{anonfield(typs[28])})
+       typs[43] = functype(nil, []*ir.Node{anonfield(typs[42]), anonfield(typs[22])}, []*ir.Node{anonfield(typs[28])})
+       typs[44] = functype(nil, []*ir.Node{anonfield(typs[33]), anonfield(typs[1]), anonfield(typs[15])}, []*ir.Node{anonfield(typs[28])})
+       typs[45] = functype(nil, []*ir.Node{anonfield(typs[1]), anonfield(typs[15])}, []*ir.Node{anonfield(typs[28])})
        typs[46] = types.Runetype
        typs[47] = types.NewSlice(typs[46])
-       typs[48] = functype(nil, []*Node{anonfield(typs[33]), anonfield(typs[47])}, []*Node{anonfield(typs[28])})
+       typs[48] = functype(nil, []*ir.Node{anonfield(typs[33]), anonfield(typs[47])}, []*ir.Node{anonfield(typs[28])})
        typs[49] = types.NewSlice(typs[0])
-       typs[50] = functype(nil, []*Node{anonfield(typs[33]), anonfield(typs[28])}, []*Node{anonfield(typs[49])})
+       typs[50] = functype(nil, []*ir.Node{anonfield(typs[33]), anonfield(typs[28])}, []*ir.Node{anonfield(typs[49])})
        typs[51] = types.NewArray(typs[46], 32)
        typs[52] = types.NewPtr(typs[51])
-       typs[53] = functype(nil, []*Node{anonfield(typs[52]), anonfield(typs[28])}, []*Node{anonfield(typs[47])})
-       typs[54] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[15]), anonfield(typs[3]), anonfield(typs[15]), anonfield(typs[5])}, []*Node{anonfield(typs[15])})
-       typs[55] = functype(nil, []*Node{anonfield(typs[28]), anonfield(typs[15])}, []*Node{anonfield(typs[46]), anonfield(typs[15])})
-       typs[56] = functype(nil, []*Node{anonfield(typs[28])}, []*Node{anonfield(typs[15])})
-       typs[57] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2])}, []*Node{anonfield(typs[2])})
-       typs[58] = functype(nil, []*Node{anonfield(typs[2])}, []*Node{anonfield(typs[7])})
-       typs[59] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3])}, []*Node{anonfield(typs[2])})
-       typs[60] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[2])}, []*Node{anonfield(typs[2]), anonfield(typs[6])})
-       typs[61] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[1]), anonfield(typs[1])}, nil)
-       typs[62] = functype(nil, []*Node{anonfield(typs[1])}, nil)
+       typs[53] = functype(nil, []*ir.Node{anonfield(typs[52]), anonfield(typs[28])}, []*ir.Node{anonfield(typs[47])})
+       typs[54] = functype(nil, []*ir.Node{anonfield(typs[3]), anonfield(typs[15]), anonfield(typs[3]), anonfield(typs[15]), anonfield(typs[5])}, []*ir.Node{anonfield(typs[15])})
+       typs[55] = functype(nil, []*ir.Node{anonfield(typs[28]), anonfield(typs[15])}, []*ir.Node{anonfield(typs[46]), anonfield(typs[15])})
+       typs[56] = functype(nil, []*ir.Node{anonfield(typs[28])}, []*ir.Node{anonfield(typs[15])})
+       typs[57] = functype(nil, []*ir.Node{anonfield(typs[1]), anonfield(typs[2])}, []*ir.Node{anonfield(typs[2])})
+       typs[58] = functype(nil, []*ir.Node{anonfield(typs[2])}, []*ir.Node{anonfield(typs[7])})
+       typs[59] = functype(nil, []*ir.Node{anonfield(typs[1]), anonfield(typs[3])}, []*ir.Node{anonfield(typs[2])})
+       typs[60] = functype(nil, []*ir.Node{anonfield(typs[1]), anonfield(typs[2])}, []*ir.Node{anonfield(typs[2]), anonfield(typs[6])})
+       typs[61] = functype(nil, []*ir.Node{anonfield(typs[1]), anonfield(typs[1]), anonfield(typs[1])}, nil)
+       typs[62] = functype(nil, []*ir.Node{anonfield(typs[1])}, nil)
        typs[63] = types.NewPtr(typs[5])
-       typs[64] = functype(nil, []*Node{anonfield(typs[63]), anonfield(typs[7]), anonfield(typs[7])}, []*Node{anonfield(typs[6])})
-       typs[65] = types.Types[TUINT32]
-       typs[66] = functype(nil, nil, []*Node{anonfield(typs[65])})
+       typs[64] = functype(nil, []*ir.Node{anonfield(typs[63]), anonfield(typs[7]), anonfield(typs[7])}, []*ir.Node{anonfield(typs[6])})
+       typs[65] = types.Types[types.TUINT32]
+       typs[66] = functype(nil, nil, []*ir.Node{anonfield(typs[65])})
        typs[67] = types.NewMap(typs[2], typs[2])
-       typs[68] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[22]), anonfield(typs[3])}, []*Node{anonfield(typs[67])})
-       typs[69] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[3])}, []*Node{anonfield(typs[67])})
-       typs[70] = functype(nil, nil, []*Node{anonfield(typs[67])})
-       typs[71] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3])}, []*Node{anonfield(typs[3])})
-       typs[72] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[2])}, []*Node{anonfield(typs[3])})
-       typs[73] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3]), anonfield(typs[1])}, []*Node{anonfield(typs[3])})
-       typs[74] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3])}, []*Node{anonfield(typs[3]), anonfield(typs[6])})
-       typs[75] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[2])}, []*Node{anonfield(typs[3]), anonfield(typs[6])})
-       typs[76] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3]), anonfield(typs[1])}, []*Node{anonfield(typs[3]), anonfield(typs[6])})
-       typs[77] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3])}, nil)
-       typs[78] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[2])}, nil)
-       typs[79] = functype(nil, []*Node{anonfield(typs[3])}, nil)
-       typs[80] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[67])}, nil)
+       typs[68] = functype(nil, []*ir.Node{anonfield(typs[1]), anonfield(typs[22]), anonfield(typs[3])}, []*ir.Node{anonfield(typs[67])})
+       typs[69] = functype(nil, []*ir.Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[3])}, []*ir.Node{anonfield(typs[67])})
+       typs[70] = functype(nil, nil, []*ir.Node{anonfield(typs[67])})
+       typs[71] = functype(nil, []*ir.Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3])}, []*ir.Node{anonfield(typs[3])})
+       typs[72] = functype(nil, []*ir.Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[2])}, []*ir.Node{anonfield(typs[3])})
+       typs[73] = functype(nil, []*ir.Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3]), anonfield(typs[1])}, []*ir.Node{anonfield(typs[3])})
+       typs[74] = functype(nil, []*ir.Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3])}, []*ir.Node{anonfield(typs[3]), anonfield(typs[6])})
+       typs[75] = functype(nil, []*ir.Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[2])}, []*ir.Node{anonfield(typs[3]), anonfield(typs[6])})
+       typs[76] = functype(nil, []*ir.Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3]), anonfield(typs[1])}, []*ir.Node{anonfield(typs[3]), anonfield(typs[6])})
+       typs[77] = functype(nil, []*ir.Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[3])}, nil)
+       typs[78] = functype(nil, []*ir.Node{anonfield(typs[1]), anonfield(typs[67]), anonfield(typs[2])}, nil)
+       typs[79] = functype(nil, []*ir.Node{anonfield(typs[3])}, nil)
+       typs[80] = functype(nil, []*ir.Node{anonfield(typs[1]), anonfield(typs[67])}, nil)
        typs[81] = types.NewChan(typs[2], types.Cboth)
-       typs[82] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[22])}, []*Node{anonfield(typs[81])})
-       typs[83] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15])}, []*Node{anonfield(typs[81])})
+       typs[82] = functype(nil, []*ir.Node{anonfield(typs[1]), anonfield(typs[22])}, []*ir.Node{anonfield(typs[81])})
+       typs[83] = functype(nil, []*ir.Node{anonfield(typs[1]), anonfield(typs[15])}, []*ir.Node{anonfield(typs[81])})
        typs[84] = types.NewChan(typs[2], types.Crecv)
-       typs[85] = functype(nil, []*Node{anonfield(typs[84]), anonfield(typs[3])}, nil)
-       typs[86] = functype(nil, []*Node{anonfield(typs[84]), anonfield(typs[3])}, []*Node{anonfield(typs[6])})
+       typs[85] = functype(nil, []*ir.Node{anonfield(typs[84]), anonfield(typs[3])}, nil)
+       typs[86] = functype(nil, []*ir.Node{anonfield(typs[84]), anonfield(typs[3])}, []*ir.Node{anonfield(typs[6])})
        typs[87] = types.NewChan(typs[2], types.Csend)
-       typs[88] = functype(nil, []*Node{anonfield(typs[87]), anonfield(typs[3])}, nil)
+       typs[88] = functype(nil, []*ir.Node{anonfield(typs[87]), anonfield(typs[3])}, nil)
        typs[89] = types.NewArray(typs[0], 3)
-       typs[90] = tostruct([]*Node{namedfield("enabled", typs[6]), namedfield("pad", typs[89]), namedfield("needed", typs[6]), namedfield("cgo", typs[6]), namedfield("alignme", typs[24])})
-       typs[91] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3]), anonfield(typs[3])}, nil)
-       typs[92] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3])}, nil)
-       typs[93] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[3]), anonfield(typs[15]), anonfield(typs[3]), anonfield(typs[15])}, []*Node{anonfield(typs[15])})
-       typs[94] = functype(nil, []*Node{anonfield(typs[87]), anonfield(typs[3])}, []*Node{anonfield(typs[6])})
-       typs[95] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[84])}, []*Node{anonfield(typs[6])})
+       typs[90] = tostruct([]*ir.Node{namedfield("enabled", typs[6]), namedfield("pad", typs[89]), namedfield("needed", typs[6]), namedfield("cgo", typs[6]), namedfield("alignme", typs[24])})
+       typs[91] = functype(nil, []*ir.Node{anonfield(typs[1]), anonfield(typs[3]), anonfield(typs[3])}, nil)
+       typs[92] = functype(nil, []*ir.Node{anonfield(typs[1]), anonfield(typs[3])}, nil)
+       typs[93] = functype(nil, []*ir.Node{anonfield(typs[1]), anonfield(typs[3]), anonfield(typs[15]), anonfield(typs[3]), anonfield(typs[15])}, []*ir.Node{anonfield(typs[15])})
+       typs[94] = functype(nil, []*ir.Node{anonfield(typs[87]), anonfield(typs[3])}, []*ir.Node{anonfield(typs[6])})
+       typs[95] = functype(nil, []*ir.Node{anonfield(typs[3]), anonfield(typs[84])}, []*ir.Node{anonfield(typs[6])})
        typs[96] = types.NewPtr(typs[6])
-       typs[97] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[96]), anonfield(typs[84])}, []*Node{anonfield(typs[6])})
-       typs[98] = functype(nil, []*Node{anonfield(typs[63])}, nil)
-       typs[99] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[1]), anonfield(typs[63]), anonfield(typs[15]), anonfield(typs[15]), anonfield(typs[6])}, []*Node{anonfield(typs[15]), anonfield(typs[6])})
-       typs[100] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[15])}, []*Node{anonfield(typs[7])})
-       typs[101] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[22]), anonfield(typs[22])}, []*Node{anonfield(typs[7])})
-       typs[102] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[15]), anonfield(typs[7])}, []*Node{anonfield(typs[7])})
+       typs[97] = functype(nil, []*ir.Node{anonfield(typs[3]), anonfield(typs[96]), anonfield(typs[84])}, []*ir.Node{anonfield(typs[6])})
+       typs[98] = functype(nil, []*ir.Node{anonfield(typs[63])}, nil)
+       typs[99] = functype(nil, []*ir.Node{anonfield(typs[1]), anonfield(typs[1]), anonfield(typs[63]), anonfield(typs[15]), anonfield(typs[15]), anonfield(typs[6])}, []*ir.Node{anonfield(typs[15]), anonfield(typs[6])})
+       typs[100] = functype(nil, []*ir.Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[15])}, []*ir.Node{anonfield(typs[7])})
+       typs[101] = functype(nil, []*ir.Node{anonfield(typs[1]), anonfield(typs[22]), anonfield(typs[22])}, []*ir.Node{anonfield(typs[7])})
+       typs[102] = functype(nil, []*ir.Node{anonfield(typs[1]), anonfield(typs[15]), anonfield(typs[15]), anonfield(typs[7])}, []*ir.Node{anonfield(typs[7])})
        typs[103] = types.NewSlice(typs[2])
-       typs[104] = functype(nil, []*Node{anonfield(typs[1]), anonfield(typs[103]), anonfield(typs[15])}, []*Node{anonfield(typs[103])})
-       typs[105] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[5])}, nil)
-       typs[106] = functype(nil, []*Node{anonfield(typs[7]), anonfield(typs[5])}, nil)
-       typs[107] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[5])}, []*Node{anonfield(typs[6])})
-       typs[108] = functype(nil, []*Node{anonfield(typs[3]), anonfield(typs[3])}, []*Node{anonfield(typs[6])})
-       typs[109] = functype(nil, []*Node{anonfield(typs[7]), anonfield(typs[7])}, []*Node{anonfield(typs[6])})
-       typs[110] = functype(nil, []*Node{anonfield(typs[7]), anonfield(typs[5]), anonfield(typs[5])}, []*Node{anonfield(typs[5])})
-       typs[111] = functype(nil, []*Node{anonfield(typs[7]), anonfield(typs[5])}, []*Node{anonfield(typs[5])})
-       typs[112] = functype(nil, []*Node{anonfield(typs[22]), anonfield(typs[22])}, []*Node{anonfield(typs[22])})
-       typs[113] = functype(nil, []*Node{anonfield(typs[24]), anonfield(typs[24])}, []*Node{anonfield(typs[24])})
-       typs[114] = functype(nil, []*Node{anonfield(typs[20])}, []*Node{anonfield(typs[22])})
-       typs[115] = functype(nil, []*Node{anonfield(typs[20])}, []*Node{anonfield(typs[24])})
-       typs[116] = functype(nil, []*Node{anonfield(typs[20])}, []*Node{anonfield(typs[65])})
-       typs[117] = functype(nil, []*Node{anonfield(typs[22])}, []*Node{anonfield(typs[20])})
-       typs[118] = functype(nil, []*Node{anonfield(typs[24])}, []*Node{anonfield(typs[20])})
-       typs[119] = functype(nil, []*Node{anonfield(typs[65])}, []*Node{anonfield(typs[20])})
-       typs[120] = functype(nil, []*Node{anonfield(typs[26]), anonfield(typs[26])}, []*Node{anonfield(typs[26])})
-       typs[121] = functype(nil, []*Node{anonfield(typs[5]), anonfield(typs[5])}, nil)
-       typs[122] = functype(nil, []*Node{anonfield(typs[7]), anonfield(typs[1]), anonfield(typs[5])}, nil)
+       typs[104] = functype(nil, []*ir.Node{anonfield(typs[1]), anonfield(typs[103]), anonfield(typs[15])}, []*ir.Node{anonfield(typs[103])})
+       typs[105] = functype(nil, []*ir.Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[5])}, nil)
+       typs[106] = functype(nil, []*ir.Node{anonfield(typs[7]), anonfield(typs[5])}, nil)
+       typs[107] = functype(nil, []*ir.Node{anonfield(typs[3]), anonfield(typs[3]), anonfield(typs[5])}, []*ir.Node{anonfield(typs[6])})
+       typs[108] = functype(nil, []*ir.Node{anonfield(typs[3]), anonfield(typs[3])}, []*ir.Node{anonfield(typs[6])})
+       typs[109] = functype(nil, []*ir.Node{anonfield(typs[7]), anonfield(typs[7])}, []*ir.Node{anonfield(typs[6])})
+       typs[110] = functype(nil, []*ir.Node{anonfield(typs[7]), anonfield(typs[5]), anonfield(typs[5])}, []*ir.Node{anonfield(typs[5])})
+       typs[111] = functype(nil, []*ir.Node{anonfield(typs[7]), anonfield(typs[5])}, []*ir.Node{anonfield(typs[5])})
+       typs[112] = functype(nil, []*ir.Node{anonfield(typs[22]), anonfield(typs[22])}, []*ir.Node{anonfield(typs[22])})
+       typs[113] = functype(nil, []*ir.Node{anonfield(typs[24]), anonfield(typs[24])}, []*ir.Node{anonfield(typs[24])})
+       typs[114] = functype(nil, []*ir.Node{anonfield(typs[20])}, []*ir.Node{anonfield(typs[22])})
+       typs[115] = functype(nil, []*ir.Node{anonfield(typs[20])}, []*ir.Node{anonfield(typs[24])})
+       typs[116] = functype(nil, []*ir.Node{anonfield(typs[20])}, []*ir.Node{anonfield(typs[65])})
+       typs[117] = functype(nil, []*ir.Node{anonfield(typs[22])}, []*ir.Node{anonfield(typs[20])})
+       typs[118] = functype(nil, []*ir.Node{anonfield(typs[24])}, []*ir.Node{anonfield(typs[20])})
+       typs[119] = functype(nil, []*ir.Node{anonfield(typs[65])}, []*ir.Node{anonfield(typs[20])})
+       typs[120] = functype(nil, []*ir.Node{anonfield(typs[26]), anonfield(typs[26])}, []*ir.Node{anonfield(typs[26])})
+       typs[121] = functype(nil, []*ir.Node{anonfield(typs[5]), anonfield(typs[5])}, nil)
+       typs[122] = functype(nil, []*ir.Node{anonfield(typs[7]), anonfield(typs[1]), anonfield(typs[5])}, nil)
        typs[123] = types.NewSlice(typs[7])
-       typs[124] = functype(nil, []*Node{anonfield(typs[7]), anonfield(typs[123])}, nil)
-       typs[125] = types.Types[TUINT8]
-       typs[126] = functype(nil, []*Node{anonfield(typs[125]), anonfield(typs[125])}, nil)
-       typs[127] = types.Types[TUINT16]
-       typs[128] = functype(nil, []*Node{anonfield(typs[127]), anonfield(typs[127])}, nil)
-       typs[129] = functype(nil, []*Node{anonfield(typs[65]), anonfield(typs[65])}, nil)
-       typs[130] = functype(nil, []*Node{anonfield(typs[24]), anonfield(typs[24])}, nil)
+       typs[124] = functype(nil, []*ir.Node{anonfield(typs[7]), anonfield(typs[123])}, nil)
+       typs[125] = types.Types[types.TUINT8]
+       typs[126] = functype(nil, []*ir.Node{anonfield(typs[125]), anonfield(typs[125])}, nil)
+       typs[127] = types.Types[types.TUINT16]
+       typs[128] = functype(nil, []*ir.Node{anonfield(typs[127]), anonfield(typs[127])}, nil)
+       typs[129] = functype(nil, []*ir.Node{anonfield(typs[65]), anonfield(typs[65])}, nil)
+       typs[130] = functype(nil, []*ir.Node{anonfield(typs[24]), anonfield(typs[24])}, nil)
        return typs[:]
 }
index ad255c9c06a6c17024d624f3baf4ac2fa8e58529..e68d7103637fa5e94115cff88cd0d1d34980bfd3 100644 (file)
@@ -6,24 +6,25 @@ package gc
 
 import (
        "cmd/compile/internal/base"
+       "cmd/compile/internal/ir"
        "cmd/compile/internal/syntax"
        "cmd/compile/internal/types"
        "cmd/internal/src"
        "fmt"
 )
 
-func (p *noder) funcLit(expr *syntax.FuncLit) *Node {
+func (p *noder) funcLit(expr *syntax.FuncLit) *ir.Node {
        xtype := p.typeExpr(expr.Type)
        ntype := p.typeExpr(expr.Type)
 
-       dcl := p.nod(expr, ODCLFUNC, nil, nil)
+       dcl := p.nod(expr, ir.ODCLFUNC, nil, nil)
        fn := dcl.Func
        fn.SetIsHiddenClosure(Curfn != nil)
-       fn.Nname = newfuncnamel(p.pos(expr), nblank.Sym, fn) // filled in by typecheckclosure
+       fn.Nname = newfuncnamel(p.pos(expr), ir.BlankNode.Sym, fn) // filled in by typecheckclosure
        fn.Nname.Name.Param.Ntype = xtype
        fn.Nname.Name.Defn = dcl
 
-       clo := p.nod(expr, OCLOSURE, nil, nil)
+       clo := p.nod(expr, ir.OCLOSURE, nil, nil)
        clo.Func = fn
        fn.ClosureType = ntype
        fn.OClosure = clo
@@ -77,7 +78,7 @@ func (p *noder) funcLit(expr *syntax.FuncLit) *Node {
 // function associated with the closure.
 // TODO: This creation of the named function should probably really be done in a
 // separate pass from type-checking.
-func typecheckclosure(clo *Node, top int) {
+func typecheckclosure(clo *ir.Node, top int) {
        fn := clo.Func
        dcl := fn.Decl
        // Set current associated iota value, so iota can be used inside
@@ -139,7 +140,7 @@ var globClosgen int
 
 // closurename generates a new unique name for a closure within
 // outerfunc.
-func closurename(outerfunc *Node) *types.Sym {
+func closurename(outerfunc *ir.Node) *types.Sym {
        outer := "glob."
        prefix := "func"
        gen := &globClosgen
@@ -149,12 +150,12 @@ func closurename(outerfunc *Node) *types.Sym {
                        prefix = ""
                }
 
-               outer = outerfunc.funcname()
+               outer = ir.FuncName(outerfunc)
 
                // There may be multiple functions named "_". In those
                // cases, we can't use their individual Closgens as it
                // would lead to name clashes.
-               if !outerfunc.Func.Nname.isBlank() {
+               if !ir.IsBlank(outerfunc.Func.Nname) {
                        gen = &outerfunc.Func.Closgen
                }
        }
@@ -171,7 +172,7 @@ var capturevarscomplete bool
 // by value or by reference.
 // We use value capturing for values <= 128 bytes that are never reassigned
 // after capturing (effectively constant).
-func capturevars(dcl *Node) {
+func capturevars(dcl *ir.Node) {
        lno := base.Pos
        base.Pos = dcl.Pos
        fn := dcl.Func
@@ -197,11 +198,11 @@ func capturevars(dcl *Node) {
                outermost := v.Name.Defn
 
                // out parameters will be assigned to implicitly upon return.
-               if outermost.Class() != PPARAMOUT && !outermost.Name.Addrtaken() && !outermost.Name.Assigned() && v.Type.Width <= 128 {
+               if outermost.Class() != ir.PPARAMOUT && !outermost.Name.Addrtaken() && !outermost.Name.Assigned() && v.Type.Width <= 128 {
                        v.Name.SetByval(true)
                } else {
                        outermost.Name.SetAddrtaken(true)
-                       outer = nod(OADDR, outer, nil)
+                       outer = ir.Nod(ir.OADDR, outer, nil)
                }
 
                if base.Flag.LowerM > 1 {
@@ -226,7 +227,7 @@ func capturevars(dcl *Node) {
 
 // transformclosure is called in a separate phase after escape analysis.
 // It transform closure bodies to properly reference captured variables.
-func transformclosure(dcl *Node) {
+func transformclosure(dcl *ir.Node) {
        lno := base.Pos
        base.Pos = dcl.Pos
        fn := dcl.Func
@@ -252,24 +253,24 @@ func transformclosure(dcl *Node) {
 
                // We are going to insert captured variables before input args.
                var params []*types.Field
-               var decls []*Node
+               var decls []*ir.Node
                for _, v := range fn.ClosureVars.Slice() {
                        if !v.Name.Byval() {
                                // If v of type T is captured by reference,
                                // we introduce function param &v *T
                                // and v remains PAUTOHEAP with &v heapaddr
                                // (accesses will implicitly deref &v).
-                               addr := newname(lookup("&" + v.Sym.Name))
+                               addr := NewName(lookup("&" + v.Sym.Name))
                                addr.Type = types.NewPtr(v.Type)
                                v.Name.Param.Heapaddr = addr
                                v = addr
                        }
 
-                       v.SetClass(PPARAM)
+                       v.SetClass(ir.PPARAM)
                        decls = append(decls, v)
 
                        fld := types.NewField(src.NoXPos, v.Sym, v.Type)
-                       fld.Nname = asTypesNode(v)
+                       fld.Nname = ir.AsTypesNode(v)
                        params = append(params, fld)
                }
 
@@ -283,11 +284,11 @@ func transformclosure(dcl *Node) {
                dcl.Type = f.Type // update type of ODCLFUNC
        } else {
                // The closure is not called, so it is going to stay as closure.
-               var body []*Node
+               var body []*ir.Node
                offset := int64(Widthptr)
                for _, v := range fn.ClosureVars.Slice() {
                        // cv refers to the field inside of closure OSTRUCTLIT.
-                       cv := nod(OCLOSUREVAR, nil, nil)
+                       cv := ir.Nod(ir.OCLOSUREVAR, nil, nil)
 
                        cv.Type = v.Type
                        if !v.Name.Byval() {
@@ -299,23 +300,23 @@ func transformclosure(dcl *Node) {
 
                        if v.Name.Byval() && v.Type.Width <= int64(2*Widthptr) {
                                // If it is a small variable captured by value, downgrade it to PAUTO.
-                               v.SetClass(PAUTO)
+                               v.SetClass(ir.PAUTO)
                                fn.Dcl = append(fn.Dcl, v)
-                               body = append(body, nod(OAS, v, cv))
+                               body = append(body, ir.Nod(ir.OAS, v, cv))
                        } else {
                                // Declare variable holding addresses taken from closure
                                // and initialize in entry prologue.
-                               addr := newname(lookup("&" + v.Sym.Name))
+                               addr := NewName(lookup("&" + v.Sym.Name))
                                addr.Type = types.NewPtr(v.Type)
-                               addr.SetClass(PAUTO)
+                               addr.SetClass(ir.PAUTO)
                                addr.Name.SetUsed(true)
                                addr.Name.Curfn = dcl
                                fn.Dcl = append(fn.Dcl, addr)
                                v.Name.Param.Heapaddr = addr
                                if v.Name.Byval() {
-                                       cv = nod(OADDR, cv, nil)
+                                       cv = ir.Nod(ir.OADDR, cv, nil)
                                }
-                               body = append(body, nod(OAS, addr, cv))
+                               body = append(body, ir.Nod(ir.OAS, addr, cv))
                        }
                }
 
@@ -331,13 +332,13 @@ func transformclosure(dcl *Node) {
 
 // hasemptycvars reports whether closure clo has an
 // empty list of captured vars.
-func hasemptycvars(clo *Node) bool {
+func hasemptycvars(clo *ir.Node) bool {
        return clo.Func.ClosureVars.Len() == 0
 }
 
 // closuredebugruntimecheck applies boilerplate checks for debug flags
 // and compiling runtime
-func closuredebugruntimecheck(clo *Node) {
+func closuredebugruntimecheck(clo *ir.Node) {
        if base.Debug.Closure > 0 {
                if clo.Esc == EscHeap {
                        base.WarnfAt(clo.Pos, "heap closure, captured vars = %v", clo.Func.ClosureVars)
@@ -353,7 +354,7 @@ func closuredebugruntimecheck(clo *Node) {
 // closureType returns the struct type used to hold all the information
 // needed in the closure for clo (clo must be a OCLOSURE node).
 // The address of a variable of the returned type can be cast to a func.
-func closureType(clo *Node) *types.Type {
+func closureType(clo *ir.Node) *types.Type {
        // Create closure in the form of a composite literal.
        // supposing the closure captures an int i and a string s
        // and has one float64 argument and no results,
@@ -367,8 +368,8 @@ func closureType(clo *Node) *types.Type {
        // The information appears in the binary in the form of type descriptors;
        // the struct is unnamed so that closures in multiple packages with the
        // same struct type can share the descriptor.
-       fields := []*Node{
-               namedfield(".F", types.Types[TUINTPTR]),
+       fields := []*ir.Node{
+               namedfield(".F", types.Types[types.TUINTPTR]),
        }
        for _, v := range clo.Func.ClosureVars.Slice() {
                typ := v.Type
@@ -382,7 +383,7 @@ func closureType(clo *Node) *types.Type {
        return typ
 }
 
-func walkclosure(clo *Node, init *Nodes) *Node {
+func walkclosure(clo *ir.Node, init *ir.Nodes) *ir.Node {
        fn := clo.Func
 
        // If no closure vars, don't bother wrapping.
@@ -396,11 +397,11 @@ func walkclosure(clo *Node, init *Nodes) *Node {
 
        typ := closureType(clo)
 
-       clos := nod(OCOMPLIT, nil, typenod(typ))
+       clos := ir.Nod(ir.OCOMPLIT, nil, typenod(typ))
        clos.Esc = clo.Esc
-       clos.List.Set(append([]*Node{nod(OCFUNC, fn.Nname, nil)}, fn.ClosureEnter.Slice()...))
+       clos.List.Set(append([]*ir.Node{ir.Nod(ir.OCFUNC, fn.Nname, nil)}, fn.ClosureEnter.Slice()...))
 
-       clos = nod(OADDR, clos, nil)
+       clos = ir.Nod(ir.OADDR, clos, nil)
        clos.Esc = clo.Esc
 
        // Force type conversion from *struct to the func type.
@@ -418,9 +419,9 @@ func walkclosure(clo *Node, init *Nodes) *Node {
        return walkexpr(clos, init)
 }
 
-func typecheckpartialcall(dot *Node, sym *types.Sym) {
+func typecheckpartialcall(dot *ir.Node, sym *types.Sym) {
        switch dot.Op {
-       case ODOTINTER, ODOTMETH:
+       case ir.ODOTINTER, ir.ODOTMETH:
                break
 
        default:
@@ -430,8 +431,8 @@ func typecheckpartialcall(dot *Node, sym *types.Sym) {
        // Create top-level function.
        dcl := makepartialcall(dot, dot.Type, sym)
        dcl.Func.SetWrapper(true)
-       dot.Op = OCALLPART
-       dot.Right = newname(sym)
+       dot.Op = ir.OCALLPART
+       dot.Right = NewName(sym)
        dot.Type = dcl.Type
        dot.Func = dcl.Func
        dot.SetOpt(nil) // clear types.Field from ODOTMETH
@@ -439,12 +440,12 @@ func typecheckpartialcall(dot *Node, sym *types.Sym) {
 
 // makepartialcall returns a DCLFUNC node representing the wrapper function (*-fm) needed
 // for partial calls.
-func makepartialcall(dot *Node, t0 *types.Type, meth *types.Sym) *Node {
+func makepartialcall(dot *ir.Node, t0 *types.Type, meth *types.Sym) *ir.Node {
        rcvrtype := dot.Left.Type
        sym := methodSymSuffix(rcvrtype, meth, "-fm")
 
        if sym.Uniq() {
-               return asNode(sym.Def)
+               return ir.AsNode(sym.Def)
        }
        sym.SetUniq(true)
 
@@ -463,7 +464,7 @@ func makepartialcall(dot *Node, t0 *types.Type, meth *types.Sym) *Node {
        // number at the use of the method expression in this
        // case. See issue 29389.
 
-       tfn := nod(OTFUNC, nil, nil)
+       tfn := ir.Nod(ir.OTFUNC, nil, nil)
        tfn.List.Set(structargs(t0.Params(), true))
        tfn.Rlist.Set(structargs(t0.Results(), false))
 
@@ -476,27 +477,27 @@ func makepartialcall(dot *Node, t0 *types.Type, meth *types.Sym) *Node {
 
        // Declare and initialize variable holding receiver.
 
-       cv := nod(OCLOSUREVAR, nil, nil)
+       cv := ir.Nod(ir.OCLOSUREVAR, nil, nil)
        cv.Type = rcvrtype
        cv.Xoffset = Rnd(int64(Widthptr), int64(cv.Type.Align))
 
-       ptr := newname(lookup(".this"))
-       declare(ptr, PAUTO)
+       ptr := NewName(lookup(".this"))
+       declare(ptr, ir.PAUTO)
        ptr.Name.SetUsed(true)
-       var body []*Node
+       var body []*ir.Node
        if rcvrtype.IsPtr() || rcvrtype.IsInterface() {
                ptr.Type = rcvrtype
-               body = append(body, nod(OAS, ptr, cv))
+               body = append(body, ir.Nod(ir.OAS, ptr, cv))
        } else {
                ptr.Type = types.NewPtr(rcvrtype)
-               body = append(body, nod(OAS, ptr, nod(OADDR, cv, nil)))
+               body = append(body, ir.Nod(ir.OAS, ptr, ir.Nod(ir.OADDR, cv, nil)))
        }
 
-       call := nod(OCALL, nodSym(OXDOT, ptr, meth), nil)
+       call := ir.Nod(ir.OCALL, nodSym(ir.OXDOT, ptr, meth), nil)
        call.List.Set(paramNnames(tfn.Type))
        call.SetIsDDD(tfn.Type.IsVariadic())
        if t0.NumResults() != 0 {
-               n := nod(ORETURN, nil, nil)
+               n := ir.Nod(ir.ORETURN, nil, nil)
                n.List.Set1(call)
                call = n
        }
@@ -510,7 +511,7 @@ func makepartialcall(dot *Node, t0 *types.Type, meth *types.Sym) *Node {
        // typecheckslice() requires that Curfn is set when processing an ORETURN.
        Curfn = dcl
        typecheckslice(dcl.Nbody.Slice(), ctxStmt)
-       sym.Def = asTypesNode(dcl)
+       sym.Def = ir.AsTypesNode(dcl)
        xtop = append(xtop, dcl)
        Curfn = savecurfn
        base.Pos = saveLineNo
@@ -521,16 +522,16 @@ func makepartialcall(dot *Node, t0 *types.Type, meth *types.Sym) *Node {
 // partialCallType returns the struct type used to hold all the information
 // needed in the closure for n (n must be a OCALLPART node).
 // The address of a variable of the returned type can be cast to a func.
-func partialCallType(n *Node) *types.Type {
-       t := tostruct([]*Node{
-               namedfield("F", types.Types[TUINTPTR]),
+func partialCallType(n *ir.Node) *types.Type {
+       t := tostruct([]*ir.Node{
+               namedfield("F", types.Types[types.TUINTPTR]),
                namedfield("R", n.Left.Type),
        })
        t.SetNoalg(true)
        return t
 }
 
-func walkpartialcall(n *Node, init *Nodes) *Node {
+func walkpartialcall(n *ir.Node, init *ir.Nodes) *ir.Node {
        // Create closure in the form of a composite literal.
        // For x.M with receiver (x) type T, the generated code looks like:
        //
@@ -544,21 +545,21 @@ func walkpartialcall(n *Node, init *Nodes) *Node {
                n.Left = cheapexpr(n.Left, init)
                n.Left = walkexpr(n.Left, nil)
 
-               tab := nod(OITAB, n.Left, nil)
+               tab := ir.Nod(ir.OITAB, n.Left, nil)
                tab = typecheck(tab, ctxExpr)
 
-               c := nod(OCHECKNIL, tab, nil)
+               c := ir.Nod(ir.OCHECKNIL, tab, nil)
                c.SetTypecheck(1)
                init.Append(c)
        }
 
        typ := partialCallType(n)
 
-       clos := nod(OCOMPLIT, nil, typenod(typ))
+       clos := ir.Nod(ir.OCOMPLIT, nil, typenod(typ))
        clos.Esc = n.Esc
-       clos.List.Set2(nod(OCFUNC, n.Func.Nname, nil), n.Left)
+       clos.List.Set2(ir.Nod(ir.OCFUNC, n.Func.Nname, nil), n.Left)
 
-       clos = nod(OADDR, clos, nil)
+       clos = ir.Nod(ir.OADDR, clos, nil)
        clos.Esc = n.Esc
 
        // Force type conversion from *struct to the func type.
@@ -578,8 +579,8 @@ func walkpartialcall(n *Node, init *Nodes) *Node {
 
 // callpartMethod returns the *types.Field representing the method
 // referenced by method value n.
-func callpartMethod(n *Node) *types.Field {
-       if n.Op != OCALLPART {
+func callpartMethod(n *ir.Node) *types.Field {
+       if n.Op != ir.OCALLPART {
                base.Fatalf("expected OCALLPART, got %v", n)
        }
 
index 98473b4cfb0154fcdf3fdf1d3e4d1f9123e648ae..a557e20d46b4dbf35cefdf4885a2d1424292466c 100644 (file)
@@ -6,6 +6,7 @@ package gc
 
 import (
        "cmd/compile/internal/base"
+       "cmd/compile/internal/ir"
        "cmd/compile/internal/types"
        "cmd/internal/src"
        "fmt"
@@ -23,51 +24,6 @@ const (
        Mpprec = 512
 )
 
-// ValueInterface returns the constant value stored in n as an interface{}.
-// It returns int64s for ints and runes, float64s for floats,
-// and complex128s for complex values.
-func (n *Node) ValueInterface() interface{} {
-       switch v := n.Val(); v.Kind() {
-       default:
-               base.Fatalf("unexpected constant: %v", v)
-               panic("unreachable")
-       case constant.Bool:
-               return constant.BoolVal(v)
-       case constant.String:
-               return constant.StringVal(v)
-       case constant.Int:
-               return int64Val(n.Type, v)
-       case constant.Float:
-               return float64Val(v)
-       case constant.Complex:
-               return complex(float64Val(constant.Real(v)), float64Val(constant.Imag(v)))
-       }
-}
-
-// int64Val returns v converted to int64.
-// Note: if t is uint64, very large values will be converted to negative int64.
-func int64Val(t *types.Type, v constant.Value) int64 {
-       if t.IsUnsigned() {
-               if x, ok := constant.Uint64Val(v); ok {
-                       return int64(x)
-               }
-       } else {
-               if x, ok := constant.Int64Val(v); ok {
-                       return x
-               }
-       }
-       base.Fatalf("%v out of range for %v", v, t)
-       panic("unreachable")
-}
-
-func float64Val(v constant.Value) float64 {
-       if x, _ := constant.Float64Val(v); !math.IsInf(x, 0) {
-               return x + 0 // avoid -0 (should not be needed, but be conservative)
-       }
-       base.Fatalf("bad float64 value: %v", v)
-       panic("unreachable")
-}
-
 func bigFloatVal(v constant.Value) *big.Float {
        f := new(big.Float)
        f.SetPrec(Mpprec)
@@ -86,62 +42,6 @@ func bigFloatVal(v constant.Value) *big.Float {
        return f
 }
 
-// Int64Val returns n as an int64.
-// n must be an integer or rune constant.
-func (n *Node) Int64Val() int64 {
-       if !Isconst(n, constant.Int) {
-               base.Fatalf("Int64Val(%v)", n)
-       }
-       x, ok := constant.Int64Val(n.Val())
-       if !ok {
-               base.Fatalf("Int64Val(%v)", n)
-       }
-       return x
-}
-
-// CanInt64 reports whether it is safe to call Int64Val() on n.
-func (n *Node) CanInt64() bool {
-       if !Isconst(n, constant.Int) {
-               return false
-       }
-
-       // if the value inside n cannot be represented as an int64, the
-       // return value of Int64 is undefined
-       _, ok := constant.Int64Val(n.Val())
-       return ok
-}
-
-// Uint64Val returns n as an uint64.
-// n must be an integer or rune constant.
-func (n *Node) Uint64Val() uint64 {
-       if !Isconst(n, constant.Int) {
-               base.Fatalf("Uint64Val(%v)", n)
-       }
-       x, ok := constant.Uint64Val(n.Val())
-       if !ok {
-               base.Fatalf("Uint64Val(%v)", n)
-       }
-       return x
-}
-
-// BoolVal returns n as a bool.
-// n must be a boolean constant.
-func (n *Node) BoolVal() bool {
-       if !Isconst(n, constant.Bool) {
-               base.Fatalf("BoolVal(%v)", n)
-       }
-       return constant.BoolVal(n.Val())
-}
-
-// StringVal returns the value of a literal string Node as a string.
-// n must be a string constant.
-func (n *Node) StringVal() string {
-       if !Isconst(n, constant.String) {
-               base.Fatalf("StringVal(%v)", n)
-       }
-       return constant.StringVal(n.Val())
-}
-
 func roundFloat(v constant.Value, sz int64) constant.Value {
        switch sz {
        case 4:
@@ -184,8 +84,8 @@ func trunccmplxlit(v constant.Value, t *types.Type) constant.Value {
 }
 
 // TODO(mdempsky): Replace these with better APIs.
-func convlit(n *Node, t *types.Type) *Node    { return convlit1(n, t, false, nil) }
-func defaultlit(n *Node, t *types.Type) *Node { return convlit1(n, t, false, nil) }
+func convlit(n *ir.Node, t *types.Type) *ir.Node    { return convlit1(n, t, false, nil) }
+func defaultlit(n *ir.Node, t *types.Type) *ir.Node { return convlit1(n, t, false, nil) }
 
 // convlit1 converts an untyped expression n to type t. If n already
 // has a type, convlit1 has no effect.
@@ -198,7 +98,7 @@ func defaultlit(n *Node, t *types.Type) *Node { return convlit1(n, t, false, nil
 //
 // If there's an error converting n to t, context is used in the error
 // message.
-func convlit1(n *Node, t *types.Type, explicit bool, context func() string) *Node {
+func convlit1(n *ir.Node, t *types.Type, explicit bool, context func() string) *ir.Node {
        if explicit && t == nil {
                base.Fatalf("explicit conversion missing type")
        }
@@ -215,15 +115,15 @@ func convlit1(n *Node, t *types.Type, explicit bool, context func() string) *Nod
                return n
        }
 
-       if n.Op == OLITERAL || n.Op == ONIL {
+       if n.Op == ir.OLITERAL || n.Op == ir.ONIL {
                // Can't always set n.Type directly on OLITERAL nodes.
                // See discussion on CL 20813.
-               n = n.rawcopy()
+               n = n.RawCopy()
        }
 
        // Nil is technically not a constant, so handle it specially.
-       if n.Type.Etype == TNIL {
-               if n.Op != ONIL {
+       if n.Type.Etype == types.TNIL {
+               if n.Op != ir.ONIL {
                        base.Fatalf("unexpected op: %v (%v)", n, n.Op)
                }
                if t == nil {
@@ -242,7 +142,7 @@ func convlit1(n *Node, t *types.Type, explicit bool, context func() string) *Nod
                return n
        }
 
-       if t == nil || !okforconst[t.Etype] {
+       if t == nil || !ir.OKForConst[t.Etype] {
                t = defaultType(n.Type)
        }
 
@@ -250,7 +150,7 @@ func convlit1(n *Node, t *types.Type, explicit bool, context func() string) *Nod
        default:
                base.Fatalf("unexpected untyped expression: %v", n)
 
-       case OLITERAL:
+       case ir.OLITERAL:
                v := convertVal(n.Val(), t, explicit)
                if v.Kind() == constant.Unknown {
                        break
@@ -259,7 +159,7 @@ func convlit1(n *Node, t *types.Type, explicit bool, context func() string) *Nod
                n.SetVal(v)
                return n
 
-       case OPLUS, ONEG, OBITNOT, ONOT, OREAL, OIMAG:
+       case ir.OPLUS, ir.ONEG, ir.OBITNOT, ir.ONOT, ir.OREAL, ir.OIMAG:
                ot := operandType(n.Op, t)
                if ot == nil {
                        n = defaultlit(n, nil)
@@ -274,7 +174,7 @@ func convlit1(n *Node, t *types.Type, explicit bool, context func() string) *Nod
                n.Type = t
                return n
 
-       case OADD, OSUB, OMUL, ODIV, OMOD, OOR, OXOR, OAND, OANDNOT, OOROR, OANDAND, OCOMPLEX:
+       case ir.OADD, ir.OSUB, ir.OMUL, ir.ODIV, ir.OMOD, ir.OOR, ir.OXOR, ir.OAND, ir.OANDNOT, ir.OOROR, ir.OANDAND, ir.OCOMPLEX:
                ot := operandType(n.Op, t)
                if ot == nil {
                        n = defaultlit(n, nil)
@@ -296,14 +196,14 @@ func convlit1(n *Node, t *types.Type, explicit bool, context func() string) *Nod
                n.Type = t
                return n
 
-       case OEQ, ONE, OLT, OLE, OGT, OGE:
+       case ir.OEQ, ir.ONE, ir.OLT, ir.OLE, ir.OGT, ir.OGE:
                if !t.IsBoolean() {
                        break
                }
                n.Type = t
                return n
 
-       case OLSH, ORSH:
+       case ir.OLSH, ir.ORSH:
                n.Left = convlit1(n.Left, t, explicit, nil)
                n.Type = n.Left.Type
                if n.Type != nil && !n.Type.IsInteger() {
@@ -329,13 +229,13 @@ func convlit1(n *Node, t *types.Type, explicit bool, context func() string) *Nod
        return n
 }
 
-func operandType(op Op, t *types.Type) *types.Type {
+func operandType(op ir.Op, t *types.Type) *types.Type {
        switch op {
-       case OCOMPLEX:
+       case ir.OCOMPLEX:
                if t.IsComplex() {
                        return floatForComplex(t)
                }
-       case OREAL, OIMAG:
+       case ir.OREAL, ir.OIMAG:
                if t.IsFloat() {
                        return complexForFloat(t)
                }
@@ -488,7 +388,7 @@ func overflow(v constant.Value, t *types.Type) bool {
                return true
        }
        if doesoverflow(v, t) {
-               base.Errorf("constant %v overflows %v", vconv(v, 0), t)
+               base.Errorf("constant %v overflows %v", ir.FmtConst(v, 0), t)
                return true
        }
        return false
@@ -505,57 +405,46 @@ func tostr(v constant.Value) constant.Value {
        return v
 }
 
-func consttype(n *Node) constant.Kind {
-       if n == nil || n.Op != OLITERAL {
-               return constant.Unknown
-       }
-       return n.Val().Kind()
-}
-
-func Isconst(n *Node, ct constant.Kind) bool {
-       return consttype(n) == ct
-}
-
 var tokenForOp = [...]token.Token{
-       OPLUS:   token.ADD,
-       ONEG:    token.SUB,
-       ONOT:    token.NOT,
-       OBITNOT: token.XOR,
-
-       OADD:    token.ADD,
-       OSUB:    token.SUB,
-       OMUL:    token.MUL,
-       ODIV:    token.QUO,
-       OMOD:    token.REM,
-       OOR:     token.OR,
-       OXOR:    token.XOR,
-       OAND:    token.AND,
-       OANDNOT: token.AND_NOT,
-       OOROR:   token.LOR,
-       OANDAND: token.LAND,
-
-       OEQ: token.EQL,
-       ONE: token.NEQ,
-       OLT: token.LSS,
-       OLE: token.LEQ,
-       OGT: token.GTR,
-       OGE: token.GEQ,
-
-       OLSH: token.SHL,
-       ORSH: token.SHR,
+       ir.OPLUS:   token.ADD,
+       ir.ONEG:    token.SUB,
+       ir.ONOT:    token.NOT,
+       ir.OBITNOT: token.XOR,
+
+       ir.OADD:    token.ADD,
+       ir.OSUB:    token.SUB,
+       ir.OMUL:    token.MUL,
+       ir.ODIV:    token.QUO,
+       ir.OMOD:    token.REM,
+       ir.OOR:     token.OR,
+       ir.OXOR:    token.XOR,
+       ir.OAND:    token.AND,
+       ir.OANDNOT: token.AND_NOT,
+       ir.OOROR:   token.LOR,
+       ir.OANDAND: token.LAND,
+
+       ir.OEQ: token.EQL,
+       ir.ONE: token.NEQ,
+       ir.OLT: token.LSS,
+       ir.OLE: token.LEQ,
+       ir.OGT: token.GTR,
+       ir.OGE: token.GEQ,
+
+       ir.OLSH: token.SHL,
+       ir.ORSH: token.SHR,
 }
 
 // evalConst returns a constant-evaluated expression equivalent to n.
 // If n is not a constant, evalConst returns n.
 // Otherwise, evalConst returns a new OLITERAL with the same value as n,
 // and with .Orig pointing back to n.
-func evalConst(n *Node) *Node {
+func evalConst(n *ir.Node) *ir.Node {
        nl, nr := n.Left, n.Right
 
        // Pick off just the opcodes that can be constant evaluated.
        switch op := n.Op; op {
-       case OPLUS, ONEG, OBITNOT, ONOT:
-               if nl.Op == OLITERAL {
+       case ir.OPLUS, ir.ONEG, ir.OBITNOT, ir.ONOT:
+               if nl.Op == ir.OLITERAL {
                        var prec uint
                        if n.Type.IsUnsigned() {
                                prec = uint(n.Type.Size() * 8)
@@ -563,36 +452,36 @@ func evalConst(n *Node) *Node {
                        return origConst(n, constant.UnaryOp(tokenForOp[op], nl.Val(), prec))
                }
 
-       case OADD, OSUB, OMUL, ODIV, OMOD, OOR, OXOR, OAND, OANDNOT, OOROR, OANDAND:
-               if nl.Op == OLITERAL && nr.Op == OLITERAL {
+       case ir.OADD, ir.OSUB, ir.OMUL, ir.ODIV, ir.OMOD, ir.OOR, ir.OXOR, ir.OAND, ir.OANDNOT, ir.OOROR, ir.OANDAND:
+               if nl.Op == ir.OLITERAL && nr.Op == ir.OLITERAL {
                        rval := nr.Val()
 
                        // check for divisor underflow in complex division (see issue 20227)
-                       if op == ODIV && n.Type.IsComplex() && constant.Sign(square(constant.Real(rval))) == 0 && constant.Sign(square(constant.Imag(rval))) == 0 {
+                       if op == ir.ODIV && n.Type.IsComplex() && constant.Sign(square(constant.Real(rval))) == 0 && constant.Sign(square(constant.Imag(rval))) == 0 {
                                base.Errorf("complex division by zero")
                                n.Type = nil
                                return n
                        }
-                       if (op == ODIV || op == OMOD) && constant.Sign(rval) == 0 {
+                       if (op == ir.ODIV || op == ir.OMOD) && constant.Sign(rval) == 0 {
                                base.Errorf("division by zero")
                                n.Type = nil
                                return n
                        }
 
                        tok := tokenForOp[op]
-                       if op == ODIV && n.Type.IsInteger() {
+                       if op == ir.ODIV && n.Type.IsInteger() {
                                tok = token.QUO_ASSIGN // integer division
                        }
                        return origConst(n, constant.BinaryOp(nl.Val(), tok, rval))
                }
 
-       case OEQ, ONE, OLT, OLE, OGT, OGE:
-               if nl.Op == OLITERAL && nr.Op == OLITERAL {
+       case ir.OEQ, ir.ONE, ir.OLT, ir.OLE, ir.OGT, ir.OGE:
+               if nl.Op == ir.OLITERAL && nr.Op == ir.OLITERAL {
                        return origBoolConst(n, constant.Compare(nl.Val(), tokenForOp[op], nr.Val()))
                }
 
-       case OLSH, ORSH:
-               if nl.Op == OLITERAL && nr.Op == OLITERAL {
+       case ir.OLSH, ir.ORSH:
+               if nl.Op == ir.OLITERAL && nr.Op == ir.OLITERAL {
                        // shiftBound from go/types; "so we can express smallestFloat64"
                        const shiftBound = 1023 - 1 + 52
                        s, ok := constant.Uint64Val(nr.Val())
@@ -604,24 +493,24 @@ func evalConst(n *Node) *Node {
                        return origConst(n, constant.Shift(toint(nl.Val()), tokenForOp[op], uint(s)))
                }
 
-       case OCONV, ORUNESTR:
-               if okforconst[n.Type.Etype] && nl.Op == OLITERAL {
+       case ir.OCONV, ir.ORUNESTR:
+               if ir.OKForConst[n.Type.Etype] && nl.Op == ir.OLITERAL {
                        return origConst(n, convertVal(nl.Val(), n.Type, true))
                }
 
-       case OCONVNOP:
-               if okforconst[n.Type.Etype] && nl.Op == OLITERAL {
+       case ir.OCONVNOP:
+               if ir.OKForConst[n.Type.Etype] && nl.Op == ir.OLITERAL {
                        // set so n.Orig gets OCONV instead of OCONVNOP
-                       n.Op = OCONV
+                       n.Op = ir.OCONV
                        return origConst(n, nl.Val())
                }
 
-       case OADDSTR:
+       case ir.OADDSTR:
                // Merge adjacent constants in the argument list.
                s := n.List.Slice()
                need := 0
                for i := 0; i < len(s); i++ {
-                       if i == 0 || !Isconst(s[i-1], constant.String) || !Isconst(s[i], constant.String) {
+                       if i == 0 || !ir.IsConst(s[i-1], constant.String) || !ir.IsConst(s[i], constant.String) {
                                // Can't merge s[i] into s[i-1]; need a slot in the list.
                                need++
                        }
@@ -636,13 +525,13 @@ func evalConst(n *Node) *Node {
                        }
                        return origConst(n, constant.MakeString(strings.Join(strs, "")))
                }
-               newList := make([]*Node, 0, need)
+               newList := make([]*ir.Node, 0, need)
                for i := 0; i < len(s); i++ {
-                       if Isconst(s[i], constant.String) && i+1 < len(s) && Isconst(s[i+1], constant.String) {
+                       if ir.IsConst(s[i], constant.String) && i+1 < len(s) && ir.IsConst(s[i+1], constant.String) {
                                // merge from i up to but not including i2
                                var strs []string
                                i2 := i
-                               for i2 < len(s) && Isconst(s[i2], constant.String) {
+                               for i2 < len(s) && ir.IsConst(s[i2], constant.String) {
                                        strs = append(strs, s[i2].StringVal())
                                        i2++
                                }
@@ -656,37 +545,37 @@ func evalConst(n *Node) *Node {
                        }
                }
 
-               n = n.copy()
+               n = ir.Copy(n)
                n.List.Set(newList)
                return n
 
-       case OCAP, OLEN:
+       case ir.OCAP, ir.OLEN:
                switch nl.Type.Etype {
-               case TSTRING:
-                       if Isconst(nl, constant.String) {
+               case types.TSTRING:
+                       if ir.IsConst(nl, constant.String) {
                                return origIntConst(n, int64(len(nl.StringVal())))
                        }
-               case TARRAY:
+               case types.TARRAY:
                        if !hascallchan(nl) {
                                return origIntConst(n, nl.Type.NumElem())
                        }
                }
 
-       case OALIGNOF, OOFFSETOF, OSIZEOF:
+       case ir.OALIGNOF, ir.OOFFSETOF, ir.OSIZEOF:
                return origIntConst(n, evalunsafe(n))
 
-       case OREAL:
-               if nl.Op == OLITERAL {
+       case ir.OREAL:
+               if nl.Op == ir.OLITERAL {
                        return origConst(n, constant.Real(nl.Val()))
                }
 
-       case OIMAG:
-               if nl.Op == OLITERAL {
+       case ir.OIMAG:
+               if nl.Op == ir.OLITERAL {
                        return origConst(n, constant.Imag(nl.Val()))
                }
 
-       case OCOMPLEX:
-               if nl.Op == OLITERAL && nr.Op == OLITERAL {
+       case ir.OCOMPLEX:
+               if nl.Op == ir.OLITERAL && nr.Op == ir.OLITERAL {
                        return origConst(n, makeComplex(nl.Val(), nr.Val()))
                }
        }
@@ -721,16 +610,16 @@ func square(x constant.Value) constant.Value {
 // For matching historical "constant OP overflow" error messages.
 // TODO(mdempsky): Replace with error messages like go/types uses.
 var overflowNames = [...]string{
-       OADD:    "addition",
-       OSUB:    "subtraction",
-       OMUL:    "multiplication",
-       OLSH:    "shift",
-       OXOR:    "bitwise XOR",
-       OBITNOT: "bitwise complement",
+       ir.OADD:    "addition",
+       ir.OSUB:    "subtraction",
+       ir.OMUL:    "multiplication",
+       ir.OLSH:    "shift",
+       ir.OXOR:    "bitwise XOR",
+       ir.OBITNOT: "bitwise complement",
 }
 
 // origConst returns an OLITERAL with orig n and value v.
-func origConst(n *Node, v constant.Value) *Node {
+func origConst(n *ir.Node, v constant.Value) *ir.Node {
        lno := setlineno(n)
        v = convertVal(v, n.Type, false)
        base.Pos = lno
@@ -752,81 +641,28 @@ func origConst(n *Node, v constant.Value) *Node {
        }
 
        orig := n
-       n = nodl(orig.Pos, OLITERAL, nil, nil)
+       n = ir.NodAt(orig.Pos, ir.OLITERAL, nil, nil)
        n.Orig = orig
        n.Type = orig.Type
        n.SetVal(v)
        return n
 }
 
-func assertRepresents(t *types.Type, v constant.Value) {
-       if !represents(t, v) {
-               base.Fatalf("%v does not represent %v", t, v)
-       }
-}
-
-func represents(t *types.Type, v constant.Value) bool {
-       switch v.Kind() {
-       case constant.Unknown:
-               return okforconst[t.Etype]
-       case constant.Bool:
-               return t.IsBoolean()
-       case constant.String:
-               return t.IsString()
-       case constant.Int:
-               return t.IsInteger()
-       case constant.Float:
-               return t.IsFloat()
-       case constant.Complex:
-               return t.IsComplex()
-       }
-
-       base.Fatalf("unexpected constant kind: %v", v)
-       panic("unreachable")
-}
-
-func origBoolConst(n *Node, v bool) *Node {
+func origBoolConst(n *ir.Node, v bool) *ir.Node {
        return origConst(n, constant.MakeBool(v))
 }
 
-func origIntConst(n *Node, v int64) *Node {
+func origIntConst(n *ir.Node, v int64) *ir.Node {
        return origConst(n, constant.MakeInt64(v))
 }
 
-// nodlit returns a new untyped constant with value v.
-func nodlit(v constant.Value) *Node {
-       n := nod(OLITERAL, nil, nil)
-       if k := v.Kind(); k != constant.Unknown {
-               n.Type = idealType(k)
-               n.SetVal(v)
-       }
-       return n
-}
-
-func idealType(ct constant.Kind) *types.Type {
-       switch ct {
-       case constant.String:
-               return types.UntypedString
-       case constant.Bool:
-               return types.UntypedBool
-       case constant.Int:
-               return types.UntypedInt
-       case constant.Float:
-               return types.UntypedFloat
-       case constant.Complex:
-               return types.UntypedComplex
-       }
-       base.Fatalf("unexpected Ctype: %v", ct)
-       return nil
-}
-
 // defaultlit on both nodes simultaneously;
 // if they're both ideal going in they better
 // get the same type going out.
 // force means must assign concrete (non-ideal) type.
 // The results of defaultlit2 MUST be assigned back to l and r, e.g.
 //     n.Left, n.Right = defaultlit2(n.Left, n.Right, force)
-func defaultlit2(l *Node, r *Node, force bool) (*Node, *Node) {
+func defaultlit2(l *ir.Node, r *ir.Node, force bool) (*ir.Node, *ir.Node) {
        if l.Type == nil || r.Type == nil {
                return l, r
        }
@@ -851,7 +687,7 @@ func defaultlit2(l *Node, r *Node, force bool) (*Node, *Node) {
        if l.Type.IsString() != r.Type.IsString() {
                return l, r
        }
-       if l.isNil() || r.isNil() {
+       if ir.IsNil(l) || ir.IsNil(r) {
                return l, r
        }
 
@@ -888,31 +724,31 @@ func mixUntyped(t1, t2 *types.Type) *types.Type {
 }
 
 func defaultType(t *types.Type) *types.Type {
-       if !t.IsUntyped() || t.Etype == TNIL {
+       if !t.IsUntyped() || t.Etype == types.TNIL {
                return t
        }
 
        switch t {
        case types.UntypedBool:
-               return types.Types[TBOOL]
+               return types.Types[types.TBOOL]
        case types.UntypedString:
-               return types.Types[TSTRING]
+               return types.Types[types.TSTRING]
        case types.UntypedInt:
-               return types.Types[TINT]
+               return types.Types[types.TINT]
        case types.UntypedRune:
                return types.Runetype
        case types.UntypedFloat:
-               return types.Types[TFLOAT64]
+               return types.Types[types.TFLOAT64]
        case types.UntypedComplex:
-               return types.Types[TCOMPLEX128]
+               return types.Types[types.TCOMPLEX128]
        }
 
        base.Fatalf("bad type %v", t)
        return nil
 }
 
-func smallintconst(n *Node) bool {
-       if n.Op == OLITERAL {
+func smallintconst(n *ir.Node) bool {
+       if n.Op == ir.OLITERAL {
                v, ok := constant.Int64Val(n.Val())
                return ok && int64(int32(v)) == v
        }
@@ -924,11 +760,11 @@ func smallintconst(n *Node) bool {
 // If n is not a constant expression, not representable as an
 // integer, or negative, it returns -1. If n is too large, it
 // returns -2.
-func indexconst(n *Node) int64 {
-       if n.Op != OLITERAL {
+func indexconst(n *ir.Node) int64 {
+       if n.Op != ir.OLITERAL {
                return -1
        }
-       if !n.Type.IsInteger() && n.Type.Etype != TIDEAL {
+       if !n.Type.IsInteger() && n.Type.Etype != types.TIDEAL {
                return -1
        }
 
@@ -936,10 +772,10 @@ func indexconst(n *Node) int64 {
        if v.Kind() != constant.Int || constant.Sign(v) < 0 {
                return -1
        }
-       if doesoverflow(v, types.Types[TINT]) {
+       if doesoverflow(v, types.Types[types.TINT]) {
                return -2
        }
-       return int64Val(types.Types[TINT], v)
+       return ir.Int64Val(types.Types[types.TINT], v)
 }
 
 // isGoConst reports whether n is a Go language constant (as opposed to a
@@ -947,35 +783,35 @@ func indexconst(n *Node) int64 {
 //
 // Expressions derived from nil, like string([]byte(nil)), while they
 // may be known at compile time, are not Go language constants.
-func (n *Node) isGoConst() bool {
-       return n.Op == OLITERAL
+func isGoConst(n *ir.Node) bool {
+       return n.Op == ir.OLITERAL
 }
 
-func hascallchan(n *Node) bool {
+func hascallchan(n *ir.Node) bool {
        if n == nil {
                return false
        }
        switch n.Op {
-       case OAPPEND,
-               OCALL,
-               OCALLFUNC,
-               OCALLINTER,
-               OCALLMETH,
-               OCAP,
-               OCLOSE,
-               OCOMPLEX,
-               OCOPY,
-               ODELETE,
-               OIMAG,
-               OLEN,
-               OMAKE,
-               ONEW,
-               OPANIC,
-               OPRINT,
-               OPRINTN,
-               OREAL,
-               ORECOVER,
-               ORECV:
+       case ir.OAPPEND,
+               ir.OCALL,
+               ir.OCALLFUNC,
+               ir.OCALLINTER,
+               ir.OCALLMETH,
+               ir.OCAP,
+               ir.OCLOSE,
+               ir.OCOMPLEX,
+               ir.OCOPY,
+               ir.ODELETE,
+               ir.OIMAG,
+               ir.OLEN,
+               ir.OMAKE,
+               ir.ONEW,
+               ir.OPANIC,
+               ir.OPRINT,
+               ir.OPRINTN,
+               ir.OREAL,
+               ir.ORECOVER,
+               ir.ORECV:
                return true
        }
 
@@ -1015,12 +851,12 @@ type constSetKey struct {
 // where are used in the error message.
 //
 // n must not be an untyped constant.
-func (s *constSet) add(pos src.XPos, n *Node, what, where string) {
-       if n.Op == OCONVIFACE && n.Implicit() {
+func (s *constSet) add(pos src.XPos, n *ir.Node, what, where string) {
+       if n.Op == ir.OCONVIFACE && n.Implicit() {
                n = n.Left
        }
 
-       if !n.isGoConst() {
+       if !isGoConst(n) {
                return
        }
        if n.Type.IsUntyped() {
@@ -1045,11 +881,11 @@ func (s *constSet) add(pos src.XPos, n *Node, what, where string) {
        typ := n.Type
        switch typ {
        case types.Bytetype:
-               typ = types.Types[TUINT8]
+               typ = types.Types[types.TUINT8]
        case types.Runetype:
-               typ = types.Types[TINT32]
+               typ = types.Types[types.TINT32]
        }
-       k := constSetKey{typ, n.ValueInterface()}
+       k := constSetKey{typ, ir.ConstValue(n)}
 
        if hasUniquePos(n) {
                pos = n.Pos
@@ -1072,9 +908,9 @@ func (s *constSet) add(pos src.XPos, n *Node, what, where string) {
 // the latter is non-obvious.
 //
 // TODO(mdempsky): This could probably be a fmt.go flag.
-func nodeAndVal(n *Node) string {
+func nodeAndVal(n *ir.Node) string {
        show := n.String()
-       val := n.ValueInterface()
+       val := ir.ConstValue(n)
        if s := fmt.Sprintf("%#v", val); show != s {
                show += " (value " + s + ")"
        }
index 63a52a9f364cbc8549be0387b710ba2b0fc572ce..6fee872fd2d4c7b39aaff52d121b25902b57f0ae 100644 (file)
@@ -7,6 +7,7 @@ package gc
 import (
        "bytes"
        "cmd/compile/internal/base"
+       "cmd/compile/internal/ir"
        "cmd/compile/internal/types"
        "cmd/internal/obj"
        "cmd/internal/src"
@@ -17,7 +18,7 @@ import (
 
 // Declaration stack & operations
 
-var externdcl []*Node
+var externdcl []*ir.Node
 
 func testdclstack() {
        if !types.IsDclstackValid() {
@@ -58,25 +59,25 @@ var declare_typegen int
 
 // declare records that Node n declares symbol n.Sym in the specified
 // declaration context.
-func declare(n *Node, ctxt Class) {
-       if n.isBlank() {
+func declare(n *ir.Node, ctxt ir.Class) {
+       if ir.IsBlank(n) {
                return
        }
 
        if n.Name == nil {
                // named OLITERAL needs Name; most OLITERALs don't.
-               n.Name = new(Name)
+               n.Name = new(ir.Name)
        }
 
        s := n.Sym
 
        // kludgy: typecheckok means we're past parsing. Eg genwrapper may declare out of package names later.
-       if !inimport && !typecheckok && s.Pkg != localpkg {
+       if !inimport && !typecheckok && s.Pkg != ir.LocalPkg {
                base.ErrorfAt(n.Pos, "cannot declare name %v", s)
        }
 
        gen := 0
-       if ctxt == PEXTERN {
+       if ctxt == ir.PEXTERN {
                if s.Name == "init" {
                        base.ErrorfAt(n.Pos, "cannot declare init - must be func")
                }
@@ -85,17 +86,17 @@ func declare(n *Node, ctxt Class) {
                }
                externdcl = append(externdcl, n)
        } else {
-               if Curfn == nil && ctxt == PAUTO {
+               if Curfn == nil && ctxt == ir.PAUTO {
                        base.Pos = n.Pos
                        base.Fatalf("automatic outside function")
                }
-               if Curfn != nil && ctxt != PFUNC {
+               if Curfn != nil && ctxt != ir.PFUNC {
                        Curfn.Func.Dcl = append(Curfn.Func.Dcl, n)
                }
-               if n.Op == OTYPE {
+               if n.Op == ir.OTYPE {
                        declare_typegen++
                        gen = declare_typegen
-               } else if n.Op == ONAME && ctxt == PAUTO && !strings.Contains(s.Name, "·") {
+               } else if n.Op == ir.ONAME && ctxt == ir.PAUTO && !strings.Contains(s.Name, "·") {
                        vargen++
                        gen = vargen
                }
@@ -103,58 +104,58 @@ func declare(n *Node, ctxt Class) {
                n.Name.Curfn = Curfn
        }
 
-       if ctxt == PAUTO {
+       if ctxt == ir.PAUTO {
                n.Xoffset = 0
        }
 
        if s.Block == types.Block {
                // functype will print errors about duplicate function arguments.
                // Don't repeat the error here.
-               if ctxt != PPARAM && ctxt != PPARAMOUT {
+               if ctxt != ir.PPARAM && ctxt != ir.PPARAMOUT {
                        redeclare(n.Pos, s, "in this block")
                }
        }
 
        s.Block = types.Block
        s.Lastlineno = base.Pos
-       s.Def = asTypesNode(n)
+       s.Def = ir.AsTypesNode(n)
        n.Name.Vargen = int32(gen)
        n.SetClass(ctxt)
-       if ctxt == PFUNC {
+       if ctxt == ir.PFUNC {
                n.Sym.SetFunc(true)
        }
 
        autoexport(n, ctxt)
 }
 
-func addvar(n *Node, t *types.Type, ctxt Class) {
-       if n == nil || n.Sym == nil || (n.Op != ONAME && n.Op != ONONAME) || t == nil {
+func addvar(n *ir.Node, t *types.Type, ctxt ir.Class) {
+       if n == nil || n.Sym == nil || (n.Op != ir.ONAME && n.Op != ir.ONONAME) || t == nil {
                base.Fatalf("addvar: n=%v t=%v nil", n, t)
        }
 
-       n.Op = ONAME
+       n.Op = ir.ONAME
        declare(n, ctxt)
        n.Type = t
 }
 
 // declare variables from grammar
 // new_name_list (type | [type] = expr_list)
-func variter(vl []*Node, t *Node, el []*Node) []*Node {
-       var init []*Node
+func variter(vl []*ir.Node, t *ir.Node, el []*ir.Node) []*ir.Node {
+       var init []*ir.Node
        doexpr := len(el) > 0
 
        if len(el) == 1 && len(vl) > 1 {
                e := el[0]
-               as2 := nod(OAS2, nil, nil)
+               as2 := ir.Nod(ir.OAS2, nil, nil)
                as2.List.Set(vl)
                as2.Rlist.Set1(e)
                for _, v := range vl {
-                       v.Op = ONAME
+                       v.Op = ir.ONAME
                        declare(v, dclcontext)
                        v.Name.Param.Ntype = t
                        v.Name.Defn = as2
                        if Curfn != nil {
-                               init = append(init, nod(ODCL, v, nil))
+                               init = append(init, ir.Nod(ir.ODCL, v, nil))
                        }
                }
 
@@ -163,7 +164,7 @@ func variter(vl []*Node, t *Node, el []*Node) []*Node {
 
        nel := len(el)
        for _, v := range vl {
-               var e *Node
+               var e *ir.Node
                if doexpr {
                        if len(el) == 0 {
                                base.Errorf("assignment mismatch: %d variables but %d values", len(vl), nel)
@@ -173,15 +174,15 @@ func variter(vl []*Node, t *Node, el []*Node) []*Node {
                        el = el[1:]
                }
 
-               v.Op = ONAME
+               v.Op = ir.ONAME
                declare(v, dclcontext)
                v.Name.Param.Ntype = t
 
-               if e != nil || Curfn != nil || v.isBlank() {
+               if e != nil || Curfn != nil || ir.IsBlank(v) {
                        if Curfn != nil {
-                               init = append(init, nod(ODCL, v, nil))
+                               init = append(init, ir.Nod(ir.ODCL, v, nil))
                        }
-                       e = nod(OAS, v, e)
+                       e = ir.Nod(ir.OAS, v, e)
                        init = append(init, e)
                        if e.Right != nil {
                                v.Name.Defn = e
@@ -196,22 +197,22 @@ func variter(vl []*Node, t *Node, el []*Node) []*Node {
 }
 
 // newnoname returns a new ONONAME Node associated with symbol s.
-func newnoname(s *types.Sym) *Node {
+func newnoname(s *types.Sym) *ir.Node {
        if s == nil {
                base.Fatalf("newnoname nil")
        }
-       n := nod(ONONAME, nil, nil)
+       n := ir.Nod(ir.ONONAME, nil, nil)
        n.Sym = s
        n.Xoffset = 0
        return n
 }
 
 // newfuncnamel generates a new name node for a function or method.
-func newfuncnamel(pos src.XPos, s *types.Sym, fn *Func) *Node {
+func newfuncnamel(pos src.XPos, s *types.Sym, fn *ir.Func) *ir.Node {
        if fn.Nname != nil {
                base.Fatalf("newfuncnamel - already have name")
        }
-       n := newnamel(pos, s)
+       n := ir.NewNameAt(pos, s)
        n.Func = fn
        fn.Nname = n
        return n
@@ -219,39 +220,39 @@ func newfuncnamel(pos src.XPos, s *types.Sym, fn *Func) *Node {
 
 // this generates a new name node for a name
 // being declared.
-func dclname(s *types.Sym) *Node {
-       n := newname(s)
-       n.Op = ONONAME // caller will correct it
+func dclname(s *types.Sym) *ir.Node {
+       n := NewName(s)
+       n.Op = ir.ONONAME // caller will correct it
        return n
 }
 
-func typenod(t *types.Type) *Node {
+func typenod(t *types.Type) *ir.Node {
        return typenodl(src.NoXPos, t)
 }
 
-func typenodl(pos src.XPos, t *types.Type) *Node {
+func typenodl(pos src.XPos, t *types.Type) *ir.Node {
        // if we copied another type with *t = *u
        // then t->nod might be out of date, so
        // check t->nod->type too
-       if asNode(t.Nod) == nil || asNode(t.Nod).Type != t {
-               t.Nod = asTypesNode(nodl(pos, OTYPE, nil, nil))
-               asNode(t.Nod).Type = t
-               asNode(t.Nod).Sym = t.Sym
+       if ir.AsNode(t.Nod) == nil || ir.AsNode(t.Nod).Type != t {
+               t.Nod = ir.AsTypesNode(ir.NodAt(pos, ir.OTYPE, nil, nil))
+               ir.AsNode(t.Nod).Type = t
+               ir.AsNode(t.Nod).Sym = t.Sym
        }
 
-       return asNode(t.Nod)
+       return ir.AsNode(t.Nod)
 }
 
-func anonfield(typ *types.Type) *Node {
+func anonfield(typ *types.Type) *ir.Node {
        return symfield(nil, typ)
 }
 
-func namedfield(s string, typ *types.Type) *Node {
+func namedfield(s string, typ *types.Type) *ir.Node {
        return symfield(lookup(s), typ)
 }
 
-func symfield(s *types.Sym, typ *types.Type) *Node {
-       n := nodSym(ODCLFIELD, nil, s)
+func symfield(s *types.Sym, typ *types.Type) *ir.Node {
+       n := nodSym(ir.ODCLFIELD, nil, s)
        n.Type = typ
        return n
 }
@@ -260,8 +261,8 @@ func symfield(s *types.Sym, typ *types.Type) *Node {
 // If no such Node currently exists, an ONONAME Node is returned instead.
 // Automatically creates a new closure variable if the referenced symbol was
 // declared in a different (containing) function.
-func oldname(s *types.Sym) *Node {
-       n := asNode(s.Def)
+func oldname(s *types.Sym) *ir.Node {
+       n := ir.AsNode(s.Def)
        if n == nil {
                // Maybe a top-level declaration will come along later to
                // define s. resolve will check s.Def again once all input
@@ -269,7 +270,7 @@ func oldname(s *types.Sym) *Node {
                return newnoname(s)
        }
 
-       if Curfn != nil && n.Op == ONAME && n.Name.Curfn != nil && n.Name.Curfn != Curfn {
+       if Curfn != nil && n.Op == ir.ONAME && n.Name.Curfn != nil && n.Name.Curfn != Curfn {
                // Inner func is referring to var in outer func.
                //
                // TODO(rsc): If there is an outer variable x and we
@@ -279,8 +280,8 @@ func oldname(s *types.Sym) *Node {
                c := n.Name.Param.Innermost
                if c == nil || c.Name.Curfn != Curfn {
                        // Do not have a closure var for the active closure yet; make one.
-                       c = newname(s)
-                       c.SetClass(PAUTOHEAP)
+                       c = NewName(s)
+                       c.SetClass(ir.PAUTOHEAP)
                        c.Name.SetIsClosureVar(true)
                        c.SetIsDDD(n.IsDDD())
                        c.Name.Defn = n
@@ -301,9 +302,9 @@ func oldname(s *types.Sym) *Node {
 }
 
 // importName is like oldname, but it reports an error if sym is from another package and not exported.
-func importName(sym *types.Sym) *Node {
+func importName(sym *types.Sym) *ir.Node {
        n := oldname(sym)
-       if !types.IsExported(sym.Name) && sym.Pkg != localpkg {
+       if !types.IsExported(sym.Name) && sym.Pkg != ir.LocalPkg {
                n.SetDiag(true)
                base.Errorf("cannot refer to unexported name %s.%s", sym.Pkg.Name, sym.Name)
        }
@@ -311,20 +312,20 @@ func importName(sym *types.Sym) *Node {
 }
 
 // := declarations
-func colasname(n *Node) bool {
+func colasname(n *ir.Node) bool {
        switch n.Op {
-       case ONAME,
-               ONONAME,
-               OPACK,
-               OTYPE,
-               OLITERAL:
+       case ir.ONAME,
+               ir.ONONAME,
+               ir.OPACK,
+               ir.OTYPE,
+               ir.OLITERAL:
                return n.Sym != nil
        }
 
        return false
 }
 
-func colasdefn(left []*Node, defn *Node) {
+func colasdefn(left []*ir.Node, defn *ir.Node) {
        for _, n := range left {
                if n.Sym != nil {
                        n.Sym.SetUniq(true)
@@ -333,7 +334,7 @@ func colasdefn(left []*Node, defn *Node) {
 
        var nnew, nerr int
        for i, n := range left {
-               if n.isBlank() {
+               if ir.IsBlank(n) {
                        continue
                }
                if !colasname(n) {
@@ -355,10 +356,10 @@ func colasdefn(left []*Node, defn *Node) {
                }
 
                nnew++
-               n = newname(n.Sym)
+               n = NewName(n.Sym)
                declare(n, dclcontext)
                n.Name.Defn = defn
-               defn.Ninit.Append(nod(ODCL, n, nil))
+               defn.Ninit.Append(ir.Nod(ir.ODCL, n, nil))
                left[i] = n
        }
 
@@ -369,8 +370,8 @@ func colasdefn(left []*Node, defn *Node) {
 
 // declare the arguments in an
 // interface field declaration.
-func ifacedcl(n *Node) {
-       if n.Op != ODCLFIELD || n.Left == nil {
+func ifacedcl(n *ir.Node) {
+       if n.Op != ir.ODCLFIELD || n.Left == nil {
                base.Fatalf("ifacedcl")
        }
 
@@ -383,11 +384,11 @@ func ifacedcl(n *Node) {
 // and declare the arguments.
 // called in extern-declaration context
 // returns in auto-declaration context.
-func funchdr(n *Node) {
+func funchdr(n *ir.Node) {
        // change the declaration context from extern to auto
        funcStack = append(funcStack, funcStackEnt{Curfn, dclcontext})
        Curfn = n
-       dclcontext = PAUTO
+       dclcontext = ir.PAUTO
 
        types.Markdcl()
 
@@ -398,8 +399,8 @@ func funchdr(n *Node) {
        }
 }
 
-func funcargs(nt *Node) {
-       if nt.Op != OTFUNC {
+func funcargs(nt *ir.Node) {
+       if nt.Op != ir.OTFUNC {
                base.Fatalf("funcargs %v", nt.Op)
        }
 
@@ -414,10 +415,10 @@ func funcargs(nt *Node) {
 
        // declare the receiver and in arguments.
        if nt.Left != nil {
-               funcarg(nt.Left, PPARAM)
+               funcarg(nt.Left, ir.PPARAM)
        }
        for _, n := range nt.List.Slice() {
-               funcarg(n, PPARAM)
+               funcarg(n, ir.PPARAM)
        }
 
        oldvargen := vargen
@@ -442,21 +443,21 @@ func funcargs(nt *Node) {
                        gen++
                }
 
-               funcarg(n, PPARAMOUT)
+               funcarg(n, ir.PPARAMOUT)
        }
 
        vargen = oldvargen
 }
 
-func funcarg(n *Node, ctxt Class) {
-       if n.Op != ODCLFIELD {
+func funcarg(n *ir.Node, ctxt ir.Class) {
+       if n.Op != ir.ODCLFIELD {
                base.Fatalf("funcarg %v", n.Op)
        }
        if n.Sym == nil {
                return
        }
 
-       n.Right = newnamel(n.Pos, n.Sym)
+       n.Right = ir.NewNameAt(n.Pos, n.Sym)
        n.Right.Name.Param.Ntype = n.Left
        n.Right.SetIsDDD(n.IsDDD())
        declare(n.Right, ctxt)
@@ -469,27 +470,27 @@ func funcarg(n *Node, ctxt Class) {
 // This happens during import, where the hidden_fndcl rule has
 // used functype directly to parse the function's type.
 func funcargs2(t *types.Type) {
-       if t.Etype != TFUNC {
+       if t.Etype != types.TFUNC {
                base.Fatalf("funcargs2 %v", t)
        }
 
        for _, f := range t.Recvs().Fields().Slice() {
-               funcarg2(f, PPARAM)
+               funcarg2(f, ir.PPARAM)
        }
        for _, f := range t.Params().Fields().Slice() {
-               funcarg2(f, PPARAM)
+               funcarg2(f, ir.PPARAM)
        }
        for _, f := range t.Results().Fields().Slice() {
-               funcarg2(f, PPARAMOUT)
+               funcarg2(f, ir.PPARAMOUT)
        }
 }
 
-func funcarg2(f *types.Field, ctxt Class) {
+func funcarg2(f *types.Field, ctxt ir.Class) {
        if f.Sym == nil {
                return
        }
-       n := newnamel(f.Pos, f.Sym)
-       f.Nname = asTypesNode(n)
+       n := ir.NewNameAt(f.Pos, f.Sym)
+       f.Nname = ir.AsTypesNode(n)
        n.Type = f.Type
        n.SetIsDDD(f.IsDDD())
        declare(n, ctxt)
@@ -498,8 +499,8 @@ func funcarg2(f *types.Field, ctxt Class) {
 var funcStack []funcStackEnt // stack of previous values of Curfn/dclcontext
 
 type funcStackEnt struct {
-       curfn      *Node
-       dclcontext Class
+       curfn      *ir.Node
+       dclcontext ir.Class
 }
 
 // finish the body.
@@ -529,16 +530,16 @@ func checkembeddedtype(t *types.Type) {
 
        if t.IsPtr() || t.IsUnsafePtr() {
                base.Errorf("embedded type cannot be a pointer")
-       } else if t.Etype == TFORW && !t.ForwardType().Embedlineno.IsKnown() {
+       } else if t.Etype == types.TFORW && !t.ForwardType().Embedlineno.IsKnown() {
                t.ForwardType().Embedlineno = base.Pos
        }
 }
 
-func structfield(n *Node) *types.Field {
+func structfield(n *ir.Node) *types.Field {
        lno := base.Pos
        base.Pos = n.Pos
 
-       if n.Op != ODCLFIELD {
+       if n.Op != ir.ODCLFIELD {
                base.Fatalf("structfield: oops %v\n", n)
        }
 
@@ -581,8 +582,8 @@ func checkdupfields(what string, fss ...[]*types.Field) {
 
 // convert a parsed id/type list into
 // a type for struct/interface/arglist
-func tostruct(l []*Node) *types.Type {
-       t := types.New(TSTRUCT)
+func tostruct(l []*ir.Node) *types.Type {
+       t := types.New(types.TSTRUCT)
 
        fields := make([]*types.Field, len(l))
        for i, n := range l {
@@ -603,8 +604,8 @@ func tostruct(l []*Node) *types.Type {
        return t
 }
 
-func tofunargs(l []*Node, funarg types.Funarg) *types.Type {
-       t := types.New(TSTRUCT)
+func tofunargs(l []*ir.Node, funarg types.Funarg) *types.Type {
+       t := types.New(types.TSTRUCT)
        t.StructType().Funarg = funarg
 
        fields := make([]*types.Field, len(l))
@@ -613,7 +614,7 @@ func tofunargs(l []*Node, funarg types.Funarg) *types.Type {
                f.SetIsDDD(n.IsDDD())
                if n.Right != nil {
                        n.Right.Type = f.Type
-                       f.Nname = asTypesNode(n.Right)
+                       f.Nname = ir.AsTypesNode(n.Right)
                }
                if f.Broke() {
                        t.SetBroke(true)
@@ -625,17 +626,17 @@ func tofunargs(l []*Node, funarg types.Funarg) *types.Type {
 }
 
 func tofunargsfield(fields []*types.Field, funarg types.Funarg) *types.Type {
-       t := types.New(TSTRUCT)
+       t := types.New(types.TSTRUCT)
        t.StructType().Funarg = funarg
        t.SetFields(fields)
        return t
 }
 
-func interfacefield(n *Node) *types.Field {
+func interfacefield(n *ir.Node) *types.Field {
        lno := base.Pos
        base.Pos = n.Pos
 
-       if n.Op != ODCLFIELD {
+       if n.Op != ir.ODCLFIELD {
                base.Fatalf("interfacefield: oops %v\n", n)
        }
 
@@ -660,11 +661,11 @@ func interfacefield(n *Node) *types.Field {
        return f
 }
 
-func tointerface(l []*Node) *types.Type {
+func tointerface(l []*ir.Node) *types.Type {
        if len(l) == 0 {
-               return types.Types[TINTER]
+               return types.Types[types.TINTER]
        }
-       t := types.New(TINTER)
+       t := types.New(types.TINTER)
        var fields []*types.Field
        for _, n := range l {
                f := interfacefield(n)
@@ -677,7 +678,7 @@ func tointerface(l []*Node) *types.Type {
        return t
 }
 
-func fakeRecv() *Node {
+func fakeRecv() *ir.Node {
        return anonfield(types.FakeRecvType())
 }
 
@@ -693,12 +694,12 @@ func isifacemethod(f *types.Type) bool {
 }
 
 // turn a parsed function declaration into a type
-func functype(this *Node, in, out []*Node) *types.Type {
-       t := types.New(TFUNC)
+func functype(this *ir.Node, in, out []*ir.Node) *types.Type {
+       t := types.New(types.TFUNC)
 
-       var rcvr []*Node
+       var rcvr []*ir.Node
        if this != nil {
-               rcvr = []*Node{this}
+               rcvr = []*ir.Node{this}
        }
        t.FuncType().Receiver = tofunargs(rcvr, types.FunargRcvr)
        t.FuncType().Params = tofunargs(in, types.FunargParams)
@@ -710,13 +711,13 @@ func functype(this *Node, in, out []*Node) *types.Type {
                t.SetBroke(true)
        }
 
-       t.FuncType().Outnamed = t.NumResults() > 0 && origSym(t.Results().Field(0).Sym) != nil
+       t.FuncType().Outnamed = t.NumResults() > 0 && ir.OrigSym(t.Results().Field(0).Sym) != nil
 
        return t
 }
 
 func functypefield(this *types.Field, in, out []*types.Field) *types.Type {
-       t := types.New(TFUNC)
+       t := types.New(types.TFUNC)
 
        var rcvr []*types.Field
        if this != nil {
@@ -726,36 +727,11 @@ func functypefield(this *types.Field, in, out []*types.Field) *types.Type {
        t.FuncType().Params = tofunargsfield(in, types.FunargParams)
        t.FuncType().Results = tofunargsfield(out, types.FunargResults)
 
-       t.FuncType().Outnamed = t.NumResults() > 0 && origSym(t.Results().Field(0).Sym) != nil
+       t.FuncType().Outnamed = t.NumResults() > 0 && ir.OrigSym(t.Results().Field(0).Sym) != nil
 
        return t
 }
 
-// origSym returns the original symbol written by the user.
-func origSym(s *types.Sym) *types.Sym {
-       if s == nil {
-               return nil
-       }
-
-       if len(s.Name) > 1 && s.Name[0] == '~' {
-               switch s.Name[1] {
-               case 'r': // originally an unnamed result
-                       return nil
-               case 'b': // originally the blank identifier _
-                       // TODO(mdempsky): Does s.Pkg matter here?
-                       return nblank.Sym
-               }
-               return s
-       }
-
-       if strings.HasPrefix(s.Name, ".anon") {
-               // originally an unnamed or _ name (see subr.go: structargs)
-               return nil
-       }
-
-       return s
-}
-
 // methodSym returns the method symbol representing a method name
 // associated with a specific receiver type.
 //
@@ -823,7 +799,7 @@ func methodSymSuffix(recv *types.Type, msym *types.Sym, suffix string) *types.Sy
 // - msym is the method symbol
 // - t is function type (with receiver)
 // Returns a pointer to the existing or added Field; or nil if there's an error.
-func addmethod(n *Node, msym *types.Sym, t *types.Type, local, nointerface bool) *types.Field {
+func addmethod(n *ir.Node, msym *types.Sym, t *types.Type, local, nointerface bool) *types.Field {
        if msym == nil {
                base.Fatalf("no method symbol")
        }
@@ -864,7 +840,7 @@ func addmethod(n *Node, msym *types.Sym, t *types.Type, local, nointerface bool)
                return nil
        }
 
-       if local && mt.Sym.Pkg != localpkg {
+       if local && mt.Sym.Pkg != ir.LocalPkg {
                base.Errorf("cannot define new methods on non-local type %v", mt)
                return nil
        }
@@ -896,7 +872,7 @@ func addmethod(n *Node, msym *types.Sym, t *types.Type, local, nointerface bool)
        }
 
        f := types.NewField(base.Pos, msym, t)
-       f.Nname = asTypesNode(n.Func.Nname)
+       f.Nname = ir.AsTypesNode(n.Func.Nname)
        f.SetNointerface(nointerface)
 
        mt.Methods().Append(f)
@@ -959,21 +935,21 @@ func makefuncsym(s *types.Sym) {
 }
 
 // setNodeNameFunc marks a node as a function.
-func setNodeNameFunc(n *Node) {
-       if n.Op != ONAME || n.Class() != Pxxx {
+func setNodeNameFunc(n *ir.Node) {
+       if n.Op != ir.ONAME || n.Class() != ir.Pxxx {
                base.Fatalf("expected ONAME/Pxxx node, got %v", n)
        }
 
-       n.SetClass(PFUNC)
+       n.SetClass(ir.PFUNC)
        n.Sym.SetFunc(true)
 }
 
-func dclfunc(sym *types.Sym, tfn *Node) *Node {
-       if tfn.Op != OTFUNC {
+func dclfunc(sym *types.Sym, tfn *ir.Node) *ir.Node {
+       if tfn.Op != ir.OTFUNC {
                base.Fatalf("expected OTFUNC node, got %v", tfn)
        }
 
-       fn := nod(ODCLFUNC, nil, nil)
+       fn := ir.Nod(ir.ODCLFUNC, nil, nil)
        fn.Func.Nname = newfuncnamel(base.Pos, sym, fn.Func)
        fn.Func.Nname.Name.Defn = fn
        fn.Func.Nname.Name.Param.Ntype = tfn
@@ -987,27 +963,22 @@ type nowritebarrierrecChecker struct {
        // extraCalls contains extra function calls that may not be
        // visible during later analysis. It maps from the ODCLFUNC of
        // the caller to a list of callees.
-       extraCalls map[*Node][]nowritebarrierrecCall
+       extraCalls map[*ir.Node][]nowritebarrierrecCall
 
        // curfn is the current function during AST walks.
-       curfn *Node
+       curfn *ir.Node
 }
 
 type nowritebarrierrecCall struct {
-       target *Node    // ODCLFUNC of caller or callee
+       target *ir.Node // ODCLFUNC of caller or callee
        lineno src.XPos // line of call
 }
 
-type nowritebarrierrecCallSym struct {
-       target *obj.LSym // LSym of callee
-       lineno src.XPos  // line of call
-}
-
 // newNowritebarrierrecChecker creates a nowritebarrierrecChecker. It
 // must be called before transformclosure and walk.
 func newNowritebarrierrecChecker() *nowritebarrierrecChecker {
        c := &nowritebarrierrecChecker{
-               extraCalls: make(map[*Node][]nowritebarrierrecCall),
+               extraCalls: make(map[*ir.Node][]nowritebarrierrecCall),
        }
 
        // Find all systemstack calls and record their targets. In
@@ -1016,39 +987,39 @@ func newNowritebarrierrecChecker() *nowritebarrierrecChecker {
        // directly. This has to happen before transformclosure since
        // it's a lot harder to work out the argument after.
        for _, n := range xtop {
-               if n.Op != ODCLFUNC {
+               if n.Op != ir.ODCLFUNC {
                        continue
                }
                c.curfn = n
-               inspect(n, c.findExtraCalls)
+               ir.Inspect(n, c.findExtraCalls)
        }
        c.curfn = nil
        return c
 }
 
-func (c *nowritebarrierrecChecker) findExtraCalls(n *Node) bool {
-       if n.Op != OCALLFUNC {
+func (c *nowritebarrierrecChecker) findExtraCalls(n *ir.Node) bool {
+       if n.Op != ir.OCALLFUNC {
                return true
        }
        fn := n.Left
-       if fn == nil || fn.Op != ONAME || fn.Class() != PFUNC || fn.Name.Defn == nil {
+       if fn == nil || fn.Op != ir.ONAME || fn.Class() != ir.PFUNC || fn.Name.Defn == nil {
                return true
        }
        if !isRuntimePkg(fn.Sym.Pkg) || fn.Sym.Name != "systemstack" {
                return true
        }
 
-       var callee *Node
+       var callee *ir.Node
        arg := n.List.First()
        switch arg.Op {
-       case ONAME:
+       case ir.ONAME:
                callee = arg.Name.Defn
-       case OCLOSURE:
+       case ir.OCLOSURE:
                callee = arg.Func.Decl
        default:
                base.Fatalf("expected ONAME or OCLOSURE node, got %+v", arg)
        }
-       if callee.Op != ODCLFUNC {
+       if callee.Op != ir.ODCLFUNC {
                base.Fatalf("expected ODCLFUNC node, got %+v", callee)
        }
        c.extraCalls[c.curfn] = append(c.extraCalls[c.curfn], nowritebarrierrecCall{callee, n.Pos})
@@ -1063,17 +1034,17 @@ func (c *nowritebarrierrecChecker) findExtraCalls(n *Node) bool {
 // because that's all we know after we start SSA.
 //
 // This can be called concurrently for different from Nodes.
-func (c *nowritebarrierrecChecker) recordCall(from *Node, to *obj.LSym, pos src.XPos) {
-       if from.Op != ODCLFUNC {
+func (c *nowritebarrierrecChecker) recordCall(from *ir.Node, to *obj.LSym, pos src.XPos) {
+       if from.Op != ir.ODCLFUNC {
                base.Fatalf("expected ODCLFUNC, got %v", from)
        }
        // We record this information on the *Func so this is
        // concurrent-safe.
        fn := from.Func
-       if fn.nwbrCalls == nil {
-               fn.nwbrCalls = new([]nowritebarrierrecCallSym)
+       if fn.NWBRCalls == nil {
+               fn.NWBRCalls = new([]ir.SymAndPos)
        }
-       *fn.nwbrCalls = append(*fn.nwbrCalls, nowritebarrierrecCallSym{to, pos})
+       *fn.NWBRCalls = append(*fn.NWBRCalls, ir.SymAndPos{Sym: to, Pos: pos})
 }
 
 func (c *nowritebarrierrecChecker) check() {
@@ -1081,39 +1052,39 @@ func (c *nowritebarrierrecChecker) check() {
        // capture all calls created by lowering, but this means we
        // only get to see the obj.LSyms of calls. symToFunc lets us
        // get back to the ODCLFUNCs.
-       symToFunc := make(map[*obj.LSym]*Node)
+       symToFunc := make(map[*obj.LSym]*ir.Node)
        // funcs records the back-edges of the BFS call graph walk. It
        // maps from the ODCLFUNC of each function that must not have
        // write barriers to the call that inhibits them. Functions
        // that are directly marked go:nowritebarrierrec are in this
        // map with a zero-valued nowritebarrierrecCall. This also
        // acts as the set of marks for the BFS of the call graph.
-       funcs := make(map[*Node]nowritebarrierrecCall)
+       funcs := make(map[*ir.Node]nowritebarrierrecCall)
        // q is the queue of ODCLFUNC Nodes to visit in BFS order.
-       var q nodeQueue
+       var q ir.NodeQueue
 
        for _, n := range xtop {
-               if n.Op != ODCLFUNC {
+               if n.Op != ir.ODCLFUNC {
                        continue
                }
 
-               symToFunc[n.Func.lsym] = n
+               symToFunc[n.Func.LSym] = n
 
                // Make nowritebarrierrec functions BFS roots.
-               if n.Func.Pragma&Nowritebarrierrec != 0 {
+               if n.Func.Pragma&ir.Nowritebarrierrec != 0 {
                        funcs[n] = nowritebarrierrecCall{}
-                       q.pushRight(n)
+                       q.PushRight(n)
                }
                // Check go:nowritebarrier functions.
-               if n.Func.Pragma&Nowritebarrier != 0 && n.Func.WBPos.IsKnown() {
+               if n.Func.Pragma&ir.Nowritebarrier != 0 && n.Func.WBPos.IsKnown() {
                        base.ErrorfAt(n.Func.WBPos, "write barrier prohibited")
                }
        }
 
        // Perform a BFS of the call graph from all
        // go:nowritebarrierrec functions.
-       enqueue := func(src, target *Node, pos src.XPos) {
-               if target.Func.Pragma&Yeswritebarrierrec != 0 {
+       enqueue := func(src, target *ir.Node, pos src.XPos) {
+               if target.Func.Pragma&ir.Yeswritebarrierrec != 0 {
                        // Don't flow into this function.
                        return
                }
@@ -1124,10 +1095,10 @@ func (c *nowritebarrierrecChecker) check() {
 
                // Record the path.
                funcs[target] = nowritebarrierrecCall{target: src, lineno: pos}
-               q.pushRight(target)
+               q.PushRight(target)
        }
-       for !q.empty() {
-               fn := q.popLeft()
+       for !q.Empty() {
+               fn := q.PopLeft()
 
                // Check fn.
                if fn.Func.WBPos.IsKnown() {
@@ -1145,13 +1116,13 @@ func (c *nowritebarrierrecChecker) check() {
                for _, callee := range c.extraCalls[fn] {
                        enqueue(fn, callee.target, callee.lineno)
                }
-               if fn.Func.nwbrCalls == nil {
+               if fn.Func.NWBRCalls == nil {
                        continue
                }
-               for _, callee := range *fn.Func.nwbrCalls {
-                       target := symToFunc[callee.target]
+               for _, callee := range *fn.Func.NWBRCalls {
+                       target := symToFunc[callee.Sym]
                        if target != nil {
-                               enqueue(fn, target, callee.lineno)
+                               enqueue(fn, target, callee.Pos)
                        }
                }
        }
index f6c1b7cdccf11c5ba4efe2bcb5c8dcdb46e0eb60..636aa4a70edce1ff90f4bba2f0c57537f66ad304 100644 (file)
@@ -6,6 +6,7 @@ package gc
 
 import (
        "cmd/compile/internal/base"
+       "cmd/compile/internal/ir"
        "cmd/compile/internal/syntax"
        "cmd/compile/internal/types"
        "cmd/internal/obj"
@@ -16,7 +17,7 @@ import (
        "strings"
 )
 
-var embedlist []*Node
+var embedlist []*ir.Node
 
 const (
        embedUnknown = iota
@@ -27,7 +28,7 @@ const (
 
 var numLocalEmbed int
 
-func varEmbed(p *noder, names []*Node, typ *Node, exprs []*Node, embeds []PragmaEmbed) (newExprs []*Node) {
+func varEmbed(p *noder, names []*ir.Node, typ *ir.Node, exprs []*ir.Node, embeds []PragmaEmbed) (newExprs []*ir.Node) {
        haveEmbed := false
        for _, decl := range p.file.DeclList {
                imp, ok := decl.(*syntax.ImportDecl)
@@ -110,14 +111,14 @@ func varEmbed(p *noder, names []*Node, typ *Node, exprs []*Node, embeds []Pragma
        }
 
        v := names[0]
-       if dclcontext != PEXTERN {
+       if dclcontext != ir.PEXTERN {
                numLocalEmbed++
-               v = newnamel(v.Pos, lookupN("embed.", numLocalEmbed))
-               v.Sym.Def = asTypesNode(v)
+               v = ir.NewNameAt(v.Pos, lookupN("embed.", numLocalEmbed))
+               v.Sym.Def = ir.AsTypesNode(v)
                v.Name.Param.Ntype = typ
-               v.SetClass(PEXTERN)
+               v.SetClass(ir.PEXTERN)
                externdcl = append(externdcl, v)
-               exprs = []*Node{v}
+               exprs = []*ir.Node{v}
        }
 
        v.Name.Param.SetEmbedFiles(list)
@@ -129,18 +130,18 @@ func varEmbed(p *noder, names []*Node, typ *Node, exprs []*Node, embeds []Pragma
 // The match is approximate because we haven't done scope resolution yet and
 // can't tell whether "string" and "byte" really mean "string" and "byte".
 // The result must be confirmed later, after type checking, using embedKind.
-func embedKindApprox(typ *Node) int {
-       if typ.Sym != nil && typ.Sym.Name == "FS" && (typ.Sym.Pkg.Path == "embed" || (typ.Sym.Pkg == localpkg && base.Ctxt.Pkgpath == "embed")) {
+func embedKindApprox(typ *ir.Node) int {
+       if typ.Sym != nil && typ.Sym.Name == "FS" && (typ.Sym.Pkg.Path == "embed" || (typ.Sym.Pkg == ir.LocalPkg && base.Ctxt.Pkgpath == "embed")) {
                return embedFiles
        }
        // These are not guaranteed to match only string and []byte -
        // maybe the local package has redefined one of those words.
        // But it's the best we can do now during the noder.
        // The stricter check happens later, in initEmbed calling embedKind.
-       if typ.Sym != nil && typ.Sym.Name == "string" && typ.Sym.Pkg == localpkg {
+       if typ.Sym != nil && typ.Sym.Name == "string" && typ.Sym.Pkg == ir.LocalPkg {
                return embedString
        }
-       if typ.Op == OTARRAY && typ.Left == nil && typ.Right.Sym != nil && typ.Right.Sym.Name == "byte" && typ.Right.Sym.Pkg == localpkg {
+       if typ.Op == ir.OTARRAY && typ.Left == nil && typ.Right.Sym != nil && typ.Right.Sym.Name == "byte" && typ.Right.Sym.Pkg == ir.LocalPkg {
                return embedBytes
        }
        return embedUnknown
@@ -148,10 +149,10 @@ func embedKindApprox(typ *Node) int {
 
 // embedKind determines the kind of embedding variable.
 func embedKind(typ *types.Type) int {
-       if typ.Sym != nil && typ.Sym.Name == "FS" && (typ.Sym.Pkg.Path == "embed" || (typ.Sym.Pkg == localpkg && base.Ctxt.Pkgpath == "embed")) {
+       if typ.Sym != nil && typ.Sym.Name == "FS" && (typ.Sym.Pkg.Path == "embed" || (typ.Sym.Pkg == ir.LocalPkg && base.Ctxt.Pkgpath == "embed")) {
                return embedFiles
        }
-       if typ == types.Types[TSTRING] {
+       if typ == types.Types[types.TSTRING] {
                return embedString
        }
        if typ.Sym == nil && typ.IsSlice() && typ.Elem() == types.Bytetype {
@@ -191,7 +192,7 @@ func dumpembeds() {
 
 // initEmbed emits the init data for a //go:embed variable,
 // which is either a string, a []byte, or an embed.FS.
-func initEmbed(v *Node) {
+func initEmbed(v *ir.Node) {
        files := v.Name.Param.EmbedFiles()
        switch kind := embedKind(v.Type); kind {
        case embedUnknown:
diff --git a/src/cmd/compile/internal/gc/esc.go b/src/cmd/compile/internal/gc/esc.go
deleted file mode 100644 (file)
index 5cf8c4a..0000000
+++ /dev/null
@@ -1,474 +0,0 @@
-// Copyright 2011 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 gc
-
-import (
-       "cmd/compile/internal/base"
-       "cmd/compile/internal/types"
-       "fmt"
-)
-
-func escapes(all []*Node) {
-       visitBottomUp(all, escapeFuncs)
-}
-
-const (
-       EscFuncUnknown = 0 + iota
-       EscFuncPlanned
-       EscFuncStarted
-       EscFuncTagged
-)
-
-func min8(a, b int8) int8 {
-       if a < b {
-               return a
-       }
-       return b
-}
-
-func max8(a, b int8) int8 {
-       if a > b {
-               return a
-       }
-       return b
-}
-
-const (
-       EscUnknown = iota
-       EscNone    // Does not escape to heap, result, or parameters.
-       EscHeap    // Reachable from the heap
-       EscNever   // By construction will not escape.
-)
-
-// funcSym returns fn.Func.Nname.Sym if no nils are encountered along the way.
-func funcSym(fn *Node) *types.Sym {
-       if fn == nil || fn.Func.Nname == nil {
-               return nil
-       }
-       return fn.Func.Nname.Sym
-}
-
-// Mark labels that have no backjumps to them as not increasing e.loopdepth.
-// Walk hasn't generated (goto|label).Left.Sym.Label yet, so we'll cheat
-// and set it to one of the following two. Then in esc we'll clear it again.
-var (
-       looping    = nod(OXXX, nil, nil)
-       nonlooping = nod(OXXX, nil, nil)
-)
-
-func isSliceSelfAssign(dst, src *Node) bool {
-       // Detect the following special case.
-       //
-       //      func (b *Buffer) Foo() {
-       //              n, m := ...
-       //              b.buf = b.buf[n:m]
-       //      }
-       //
-       // This assignment is a no-op for escape analysis,
-       // it does not store any new pointers into b that were not already there.
-       // However, without this special case b will escape, because we assign to OIND/ODOTPTR.
-       // Here we assume that the statement will not contain calls,
-       // that is, that order will move any calls to init.
-       // Otherwise base ONAME value could change between the moments
-       // when we evaluate it for dst and for src.
-
-       // dst is ONAME dereference.
-       if dst.Op != ODEREF && dst.Op != ODOTPTR || dst.Left.Op != ONAME {
-               return false
-       }
-       // src is a slice operation.
-       switch src.Op {
-       case OSLICE, OSLICE3, OSLICESTR:
-               // OK.
-       case OSLICEARR, OSLICE3ARR:
-               // Since arrays are embedded into containing object,
-               // slice of non-pointer array will introduce a new pointer into b that was not already there
-               // (pointer to b itself). After such assignment, if b contents escape,
-               // b escapes as well. If we ignore such OSLICEARR, we will conclude
-               // that b does not escape when b contents do.
-               //
-               // Pointer to an array is OK since it's not stored inside b directly.
-               // For slicing an array (not pointer to array), there is an implicit OADDR.
-               // We check that to determine non-pointer array slicing.
-               if src.Left.Op == OADDR {
-                       return false
-               }
-       default:
-               return false
-       }
-       // slice is applied to ONAME dereference.
-       if src.Left.Op != ODEREF && src.Left.Op != ODOTPTR || src.Left.Left.Op != ONAME {
-               return false
-       }
-       // dst and src reference the same base ONAME.
-       return dst.Left == src.Left.Left
-}
-
-// isSelfAssign reports whether assignment from src to dst can
-// be ignored by the escape analysis as it's effectively a self-assignment.
-func isSelfAssign(dst, src *Node) bool {
-       if isSliceSelfAssign(dst, src) {
-               return true
-       }
-
-       // Detect trivial assignments that assign back to the same object.
-       //
-       // It covers these cases:
-       //      val.x = val.y
-       //      val.x[i] = val.y[j]
-       //      val.x1.x2 = val.x1.y2
-       //      ... etc
-       //
-       // These assignments do not change assigned object lifetime.
-
-       if dst == nil || src == nil || dst.Op != src.Op {
-               return false
-       }
-
-       switch dst.Op {
-       case ODOT, ODOTPTR:
-               // Safe trailing accessors that are permitted to differ.
-       case OINDEX:
-               if mayAffectMemory(dst.Right) || mayAffectMemory(src.Right) {
-                       return false
-               }
-       default:
-               return false
-       }
-
-       // The expression prefix must be both "safe" and identical.
-       return samesafeexpr(dst.Left, src.Left)
-}
-
-// mayAffectMemory reports whether evaluation of n may affect the program's
-// memory state. If the expression can't affect memory state, then it can be
-// safely ignored by the escape analysis.
-func mayAffectMemory(n *Node) bool {
-       // We may want to use a list of "memory safe" ops instead of generally
-       // "side-effect free", which would include all calls and other ops that can
-       // allocate or change global state. For now, it's safer to start with the latter.
-       //
-       // We're ignoring things like division by zero, index out of range,
-       // and nil pointer dereference here.
-       switch n.Op {
-       case ONAME, OCLOSUREVAR, OLITERAL, ONIL:
-               return false
-
-       // Left+Right group.
-       case OINDEX, OADD, OSUB, OOR, OXOR, OMUL, OLSH, ORSH, OAND, OANDNOT, ODIV, OMOD:
-               return mayAffectMemory(n.Left) || mayAffectMemory(n.Right)
-
-       // Left group.
-       case ODOT, ODOTPTR, ODEREF, OCONVNOP, OCONV, OLEN, OCAP,
-               ONOT, OBITNOT, OPLUS, ONEG, OALIGNOF, OOFFSETOF, OSIZEOF:
-               return mayAffectMemory(n.Left)
-
-       default:
-               return true
-       }
-}
-
-// heapAllocReason returns the reason the given Node must be heap
-// allocated, or the empty string if it doesn't.
-func heapAllocReason(n *Node) string {
-       if n.Type == nil {
-               return ""
-       }
-
-       // Parameters are always passed via the stack.
-       if n.Op == ONAME && (n.Class() == PPARAM || n.Class() == PPARAMOUT) {
-               return ""
-       }
-
-       if n.Type.Width > maxStackVarSize {
-               return "too large for stack"
-       }
-
-       if (n.Op == ONEW || n.Op == OPTRLIT) && n.Type.Elem().Width >= maxImplicitStackVarSize {
-               return "too large for stack"
-       }
-
-       if n.Op == OCLOSURE && closureType(n).Size() >= maxImplicitStackVarSize {
-               return "too large for stack"
-       }
-       if n.Op == OCALLPART && partialCallType(n).Size() >= maxImplicitStackVarSize {
-               return "too large for stack"
-       }
-
-       if n.Op == OMAKESLICE {
-               r := n.Right
-               if r == nil {
-                       r = n.Left
-               }
-               if !smallintconst(r) {
-                       return "non-constant size"
-               }
-               if t := n.Type; t.Elem().Width != 0 && r.Int64Val() >= maxImplicitStackVarSize/t.Elem().Width {
-                       return "too large for stack"
-               }
-       }
-
-       return ""
-}
-
-// addrescapes tags node n as having had its address taken
-// by "increasing" the "value" of n.Esc to EscHeap.
-// Storage is allocated as necessary to allow the address
-// to be taken.
-func addrescapes(n *Node) {
-       switch n.Op {
-       default:
-               // Unexpected Op, probably due to a previous type error. Ignore.
-
-       case ODEREF, ODOTPTR:
-               // Nothing to do.
-
-       case ONAME:
-               if n == nodfp {
-                       break
-               }
-
-               // if this is a tmpname (PAUTO), it was tagged by tmpname as not escaping.
-               // on PPARAM it means something different.
-               if n.Class() == PAUTO && n.Esc == EscNever {
-                       break
-               }
-
-               // If a closure reference escapes, mark the outer variable as escaping.
-               if n.Name.IsClosureVar() {
-                       addrescapes(n.Name.Defn)
-                       break
-               }
-
-               if n.Class() != PPARAM && n.Class() != PPARAMOUT && n.Class() != PAUTO {
-                       break
-               }
-
-               // This is a plain parameter or local variable that needs to move to the heap,
-               // but possibly for the function outside the one we're compiling.
-               // That is, if we have:
-               //
-               //      func f(x int) {
-               //              func() {
-               //                      global = &x
-               //              }
-               //      }
-               //
-               // then we're analyzing the inner closure but we need to move x to the
-               // heap in f, not in the inner closure. Flip over to f before calling moveToHeap.
-               oldfn := Curfn
-               Curfn = n.Name.Curfn
-               if Curfn.Op == OCLOSURE {
-                       Curfn = Curfn.Func.Decl
-                       panic("can't happen")
-               }
-               ln := base.Pos
-               base.Pos = Curfn.Pos
-               moveToHeap(n)
-               Curfn = oldfn
-               base.Pos = ln
-
-       // ODOTPTR has already been introduced,
-       // so these are the non-pointer ODOT and OINDEX.
-       // In &x[0], if x is a slice, then x does not
-       // escape--the pointer inside x does, but that
-       // is always a heap pointer anyway.
-       case ODOT, OINDEX, OPAREN, OCONVNOP:
-               if !n.Left.Type.IsSlice() {
-                       addrescapes(n.Left)
-               }
-       }
-}
-
-// moveToHeap records the parameter or local variable n as moved to the heap.
-func moveToHeap(n *Node) {
-       if base.Flag.LowerR != 0 {
-               Dump("MOVE", n)
-       }
-       if base.Flag.CompilingRuntime {
-               base.Errorf("%v escapes to heap, not allowed in runtime", n)
-       }
-       if n.Class() == PAUTOHEAP {
-               Dump("n", n)
-               base.Fatalf("double move to heap")
-       }
-
-       // Allocate a local stack variable to hold the pointer to the heap copy.
-       // temp will add it to the function declaration list automatically.
-       heapaddr := temp(types.NewPtr(n.Type))
-       heapaddr.Sym = lookup("&" + n.Sym.Name)
-       heapaddr.Orig.Sym = heapaddr.Sym
-       heapaddr.Pos = n.Pos
-
-       // Unset AutoTemp to persist the &foo variable name through SSA to
-       // liveness analysis.
-       // TODO(mdempsky/drchase): Cleaner solution?
-       heapaddr.Name.SetAutoTemp(false)
-
-       // Parameters have a local stack copy used at function start/end
-       // in addition to the copy in the heap that may live longer than
-       // the function.
-       if n.Class() == PPARAM || n.Class() == PPARAMOUT {
-               if n.Xoffset == BADWIDTH {
-                       base.Fatalf("addrescapes before param assignment")
-               }
-
-               // We rewrite n below to be a heap variable (indirection of heapaddr).
-               // Preserve a copy so we can still write code referring to the original,
-               // and substitute that copy into the function declaration list
-               // so that analyses of the local (on-stack) variables use it.
-               stackcopy := newname(n.Sym)
-               stackcopy.Type = n.Type
-               stackcopy.Xoffset = n.Xoffset
-               stackcopy.SetClass(n.Class())
-               stackcopy.Name.Param.Heapaddr = heapaddr
-               if n.Class() == PPARAMOUT {
-                       // Make sure the pointer to the heap copy is kept live throughout the function.
-                       // The function could panic at any point, and then a defer could recover.
-                       // Thus, we need the pointer to the heap copy always available so the
-                       // post-deferreturn code can copy the return value back to the stack.
-                       // See issue 16095.
-                       heapaddr.Name.SetIsOutputParamHeapAddr(true)
-               }
-               n.Name.Param.Stackcopy = stackcopy
-
-               // Substitute the stackcopy into the function variable list so that
-               // liveness and other analyses use the underlying stack slot
-               // and not the now-pseudo-variable n.
-               found := false
-               for i, d := range Curfn.Func.Dcl {
-                       if d == n {
-                               Curfn.Func.Dcl[i] = stackcopy
-                               found = true
-                               break
-                       }
-                       // Parameters are before locals, so can stop early.
-                       // This limits the search even in functions with many local variables.
-                       if d.Class() == PAUTO {
-                               break
-                       }
-               }
-               if !found {
-                       base.Fatalf("cannot find %v in local variable list", n)
-               }
-               Curfn.Func.Dcl = append(Curfn.Func.Dcl, n)
-       }
-
-       // Modify n in place so that uses of n now mean indirection of the heapaddr.
-       n.SetClass(PAUTOHEAP)
-       n.Xoffset = 0
-       n.Name.Param.Heapaddr = heapaddr
-       n.Esc = EscHeap
-       if base.Flag.LowerM != 0 {
-               base.WarnfAt(n.Pos, "moved to heap: %v", n)
-       }
-}
-
-// This special tag is applied to uintptr variables
-// that we believe may hold unsafe.Pointers for
-// calls into assembly functions.
-const unsafeUintptrTag = "unsafe-uintptr"
-
-// This special tag is applied to uintptr parameters of functions
-// marked go:uintptrescapes.
-const uintptrEscapesTag = "uintptr-escapes"
-
-func (e *Escape) paramTag(fn *Node, narg int, f *types.Field) string {
-       name := func() string {
-               if f.Sym != nil {
-                       return f.Sym.Name
-               }
-               return fmt.Sprintf("arg#%d", narg)
-       }
-
-       if fn.Nbody.Len() == 0 {
-               // Assume that uintptr arguments must be held live across the call.
-               // This is most important for syscall.Syscall.
-               // See golang.org/issue/13372.
-               // This really doesn't have much to do with escape analysis per se,
-               // but we are reusing the ability to annotate an individual function
-               // argument and pass those annotations along to importing code.
-               if f.Type.IsUintptr() {
-                       if base.Flag.LowerM != 0 {
-                               base.WarnfAt(f.Pos, "assuming %v is unsafe uintptr", name())
-                       }
-                       return unsafeUintptrTag
-               }
-
-               if !f.Type.HasPointers() { // don't bother tagging for scalars
-                       return ""
-               }
-
-               var esc EscLeaks
-
-               // External functions are assumed unsafe, unless
-               // //go:noescape is given before the declaration.
-               if fn.Func.Pragma&Noescape != 0 {
-                       if base.Flag.LowerM != 0 && f.Sym != nil {
-                               base.WarnfAt(f.Pos, "%v does not escape", name())
-                       }
-               } else {
-                       if base.Flag.LowerM != 0 && f.Sym != nil {
-                               base.WarnfAt(f.Pos, "leaking param: %v", name())
-                       }
-                       esc.AddHeap(0)
-               }
-
-               return esc.Encode()
-       }
-
-       if fn.Func.Pragma&UintptrEscapes != 0 {
-               if f.Type.IsUintptr() {
-                       if base.Flag.LowerM != 0 {
-                               base.WarnfAt(f.Pos, "marking %v as escaping uintptr", name())
-                       }
-                       return uintptrEscapesTag
-               }
-               if f.IsDDD() && f.Type.Elem().IsUintptr() {
-                       // final argument is ...uintptr.
-                       if base.Flag.LowerM != 0 {
-                               base.WarnfAt(f.Pos, "marking %v as escaping ...uintptr", name())
-                       }
-                       return uintptrEscapesTag
-               }
-       }
-
-       if !f.Type.HasPointers() { // don't bother tagging for scalars
-               return ""
-       }
-
-       // Unnamed parameters are unused and therefore do not escape.
-       if f.Sym == nil || f.Sym.IsBlank() {
-               var esc EscLeaks
-               return esc.Encode()
-       }
-
-       n := asNode(f.Nname)
-       loc := e.oldLoc(n)
-       esc := loc.paramEsc
-       esc.Optimize()
-
-       if base.Flag.LowerM != 0 && !loc.escapes {
-               if esc.Empty() {
-                       base.WarnfAt(f.Pos, "%v does not escape", name())
-               }
-               if x := esc.Heap(); x >= 0 {
-                       if x == 0 {
-                               base.WarnfAt(f.Pos, "leaking param: %v", name())
-                       } else {
-                               // TODO(mdempsky): Mention level=x like below?
-                               base.WarnfAt(f.Pos, "leaking param content: %v", name())
-                       }
-               }
-               for i := 0; i < numEscResults; i++ {
-                       if x := esc.Result(i); x >= 0 {
-                               res := fn.Type.Results().Field(i).Sym
-                               base.WarnfAt(f.Pos, "leaking param: %v to result %v level=%d", name(), res, x)
-                       }
-               }
-       }
-
-       return esc.Encode()
-}
index aaf768d85ab8d72818ee6d4cd4bf2297c9fd1142..a0aa516d9a43a5402f54496327afdc1f95f06c5c 100644 (file)
@@ -6,6 +6,7 @@ package gc
 
 import (
        "cmd/compile/internal/base"
+       "cmd/compile/internal/ir"
        "cmd/compile/internal/logopt"
        "cmd/compile/internal/types"
        "cmd/internal/src"
@@ -85,7 +86,7 @@ import (
 type Escape struct {
        allLocs []*EscLocation
 
-       curfn *Node
+       curfn *ir.Node
 
        // loopDepth counts the current loop nesting depth within
        // curfn. It increments within each "for" loop and at each
@@ -100,8 +101,8 @@ type Escape struct {
 // An EscLocation represents an abstract location that stores a Go
 // variable.
 type EscLocation struct {
-       n         *Node     // represented variable or expression, if any
-       curfn     *Node     // enclosing function
+       n         *ir.Node  // represented variable or expression, if any
+       curfn     *ir.Node  // enclosing function
        edges     []EscEdge // incoming edges
        loopDepth int       // loopDepth at declaration
 
@@ -142,11 +143,11 @@ type EscEdge struct {
 }
 
 func init() {
-       EscFmt = escFmt
+       ir.EscFmt = escFmt
 }
 
 // escFmt is called from node printing to print information about escape analysis results.
-func escFmt(n *Node, short bool) string {
+func escFmt(n *ir.Node, short bool) string {
        text := ""
        switch n.Esc {
        case EscUnknown:
@@ -178,9 +179,9 @@ func escFmt(n *Node, short bool) string {
 
 // escapeFuncs performs escape analysis on a minimal batch of
 // functions.
-func escapeFuncs(fns []*Node, recursive bool) {
+func escapeFuncs(fns []*ir.Node, recursive bool) {
        for _, fn := range fns {
-               if fn.Op != ODCLFUNC {
+               if fn.Op != ir.ODCLFUNC {
                        base.Fatalf("unexpected node: %v", fn)
                }
        }
@@ -201,13 +202,13 @@ func escapeFuncs(fns []*Node, recursive bool) {
        e.finish(fns)
 }
 
-func (e *Escape) initFunc(fn *Node) {
-       if fn.Op != ODCLFUNC || fn.Esc != EscFuncUnknown {
+func (e *Escape) initFunc(fn *ir.Node) {
+       if fn.Op != ir.ODCLFUNC || fn.Esc != EscFuncUnknown {
                base.Fatalf("unexpected node: %v", fn)
        }
        fn.Esc = EscFuncPlanned
        if base.Flag.LowerM > 3 {
-               Dump("escAnalyze", fn)
+               ir.Dump("escAnalyze", fn)
        }
 
        e.curfn = fn
@@ -215,26 +216,26 @@ func (e *Escape) initFunc(fn *Node) {
 
        // Allocate locations for local variables.
        for _, dcl := range fn.Func.Dcl {
-               if dcl.Op == ONAME {
+               if dcl.Op == ir.ONAME {
                        e.newLoc(dcl, false)
                }
        }
 }
 
-func (e *Escape) walkFunc(fn *Node) {
+func (e *Escape) walkFunc(fn *ir.Node) {
        fn.Esc = EscFuncStarted
 
        // Identify labels that mark the head of an unstructured loop.
-       inspectList(fn.Nbody, func(n *Node) bool {
+       ir.InspectList(fn.Nbody, func(n *ir.Node) bool {
                switch n.Op {
-               case OLABEL:
-                       n.Sym.Label = asTypesNode(nonlooping)
+               case ir.OLABEL:
+                       n.Sym.Label = ir.AsTypesNode(nonlooping)
 
-               case OGOTO:
+               case ir.OGOTO:
                        // If we visited the label before the goto,
                        // then this is a looping label.
-                       if n.Sym.Label == asTypesNode(nonlooping) {
-                               n.Sym.Label = asTypesNode(looping)
+                       if n.Sym.Label == ir.AsTypesNode(nonlooping) {
+                               n.Sym.Label = ir.AsTypesNode(looping)
                        }
                }
 
@@ -273,7 +274,7 @@ func (e *Escape) walkFunc(fn *Node) {
 //    }
 
 // stmt evaluates a single Go statement.
-func (e *Escape) stmt(n *Node) {
+func (e *Escape) stmt(n *ir.Node) {
        if n == nil {
                return
        }
@@ -293,23 +294,23 @@ func (e *Escape) stmt(n *Node) {
        default:
                base.Fatalf("unexpected stmt: %v", n)
 
-       case ODCLCONST, ODCLTYPE, OEMPTY, OFALL, OINLMARK:
+       case ir.ODCLCONST, ir.ODCLTYPE, ir.OEMPTY, ir.OFALL, ir.OINLMARK:
                // nop
 
-       case OBREAK, OCONTINUE, OGOTO:
+       case ir.OBREAK, ir.OCONTINUE, ir.OGOTO:
                // TODO(mdempsky): Handle dead code?
 
-       case OBLOCK:
+       case ir.OBLOCK:
                e.stmts(n.List)
 
-       case ODCL:
+       case ir.ODCL:
                // Record loop depth at declaration.
-               if !n.Left.isBlank() {
+               if !ir.IsBlank(n.Left) {
                        e.dcl(n.Left)
                }
 
-       case OLABEL:
-               switch asNode(n.Sym.Label) {
+       case ir.OLABEL:
+               switch ir.AsNode(n.Sym.Label) {
                case nonlooping:
                        if base.Flag.LowerM > 2 {
                                fmt.Printf("%v:%v non-looping label\n", base.FmtPos(base.Pos), n)
@@ -324,19 +325,19 @@ func (e *Escape) stmt(n *Node) {
                }
                n.Sym.Label = nil
 
-       case OIF:
+       case ir.OIF:
                e.discard(n.Left)
                e.block(n.Nbody)
                e.block(n.Rlist)
 
-       case OFOR, OFORUNTIL:
+       case ir.OFOR, ir.OFORUNTIL:
                e.loopDepth++
                e.discard(n.Left)
                e.stmt(n.Right)
                e.block(n.Nbody)
                e.loopDepth--
 
-       case ORANGE:
+       case ir.ORANGE:
                // for List = range Right { Nbody }
                e.loopDepth++
                ks := e.addrs(n.List)
@@ -354,8 +355,8 @@ func (e *Escape) stmt(n *Node) {
                }
                e.expr(e.later(k), n.Right)
 
-       case OSWITCH:
-               typesw := n.Left != nil && n.Left.Op == OTYPESW
+       case ir.OSWITCH:
+               typesw := n.Left != nil && n.Left.Op == ir.OTYPESW
 
                var ks []EscHole
                for _, cas := range n.List.Slice() { // cases
@@ -377,68 +378,68 @@ func (e *Escape) stmt(n *Node) {
                        e.discard(n.Left)
                }
 
-       case OSELECT:
+       case ir.OSELECT:
                for _, cas := range n.List.Slice() {
                        e.stmt(cas.Left)
                        e.block(cas.Nbody)
                }
-       case OSELRECV:
+       case ir.OSELRECV:
                e.assign(n.Left, n.Right, "selrecv", n)
-       case OSELRECV2:
+       case ir.OSELRECV2:
                e.assign(n.Left, n.Right, "selrecv", n)
                e.assign(n.List.First(), nil, "selrecv", n)
-       case ORECV:
+       case ir.ORECV:
                // TODO(mdempsky): Consider e.discard(n.Left).
                e.exprSkipInit(e.discardHole(), n) // already visited n.Ninit
-       case OSEND:
+       case ir.OSEND:
                e.discard(n.Left)
                e.assignHeap(n.Right, "send", n)
 
-       case OAS, OASOP:
+       case ir.OAS, ir.OASOP:
                e.assign(n.Left, n.Right, "assign", n)
 
-       case OAS2:
+       case ir.OAS2:
                for i, nl := range n.List.Slice() {
                        e.assign(nl, n.Rlist.Index(i), "assign-pair", n)
                }
 
-       case OAS2DOTTYPE: // v, ok = x.(type)
+       case ir.OAS2DOTTYPE: // v, ok = x.(type)
                e.assign(n.List.First(), n.Right, "assign-pair-dot-type", n)
                e.assign(n.List.Second(), nil, "assign-pair-dot-type", n)
-       case OAS2MAPR: // v, ok = m[k]
+       case ir.OAS2MAPR: // v, ok = m[k]
                e.assign(n.List.First(), n.Right, "assign-pair-mapr", n)
                e.assign(n.List.Second(), nil, "assign-pair-mapr", n)
-       case OAS2RECV: // v, ok = <-ch
+       case ir.OAS2RECV: // v, ok = <-ch
                e.assign(n.List.First(), n.Right, "assign-pair-receive", n)
                e.assign(n.List.Second(), nil, "assign-pair-receive", n)
 
-       case OAS2FUNC:
+       case ir.OAS2FUNC:
                e.stmts(n.Right.Ninit)
                e.call(e.addrs(n.List), n.Right, nil)
-       case ORETURN:
+       case ir.ORETURN:
                results := e.curfn.Type.Results().FieldSlice()
                for i, v := range n.List.Slice() {
-                       e.assign(asNode(results[i].Nname), v, "return", n)
+                       e.assign(ir.AsNode(results[i].Nname), v, "return", n)
                }
-       case OCALLFUNC, OCALLMETH, OCALLINTER, OCLOSE, OCOPY, ODELETE, OPANIC, OPRINT, OPRINTN, ORECOVER:
+       case ir.OCALLFUNC, ir.OCALLMETH, ir.OCALLINTER, ir.OCLOSE, ir.OCOPY, ir.ODELETE, ir.OPANIC, ir.OPRINT, ir.OPRINTN, ir.ORECOVER:
                e.call(nil, n, nil)
-       case OGO, ODEFER:
+       case ir.OGO, ir.ODEFER:
                e.stmts(n.Left.Ninit)
                e.call(nil, n.Left, n)
 
-       case ORETJMP:
+       case ir.ORETJMP:
                // TODO(mdempsky): What do? esc.go just ignores it.
        }
 }
 
-func (e *Escape) stmts(l Nodes) {
+func (e *Escape) stmts(l ir.Nodes) {
        for _, n := range l.Slice() {
                e.stmt(n)
        }
 }
 
 // block is like stmts, but preserves loopDepth.
-func (e *Escape) block(l Nodes) {
+func (e *Escape) block(l ir.Nodes) {
        old := e.loopDepth
        e.stmts(l)
        e.loopDepth = old
@@ -446,7 +447,7 @@ func (e *Escape) block(l Nodes) {
 
 // expr models evaluating an expression n and flowing the result into
 // hole k.
-func (e *Escape) expr(k EscHole, n *Node) {
+func (e *Escape) expr(k EscHole, n *ir.Node) {
        if n == nil {
                return
        }
@@ -454,7 +455,7 @@ func (e *Escape) expr(k EscHole, n *Node) {
        e.exprSkipInit(k, n)
 }
 
-func (e *Escape) exprSkipInit(k EscHole, n *Node) {
+func (e *Escape) exprSkipInit(k EscHole, n *ir.Node) {
        if n == nil {
                return
        }
@@ -467,7 +468,7 @@ func (e *Escape) exprSkipInit(k EscHole, n *Node) {
        uintptrEscapesHack := k.uintptrEscapesHack
        k.uintptrEscapesHack = false
 
-       if uintptrEscapesHack && n.Op == OCONVNOP && n.Left.Type.IsUnsafePtr() {
+       if uintptrEscapesHack && n.Op == ir.OCONVNOP && n.Left.Type.IsUnsafePtr() {
                // nop
        } else if k.derefs >= 0 && !n.Type.HasPointers() {
                k = e.discardHole()
@@ -477,32 +478,32 @@ func (e *Escape) exprSkipInit(k EscHole, n *Node) {
        default:
                base.Fatalf("unexpected expr: %v", n)
 
-       case OLITERAL, ONIL, OGETG, OCLOSUREVAR, OTYPE, OMETHEXPR:
+       case ir.OLITERAL, ir.ONIL, ir.OGETG, ir.OCLOSUREVAR, ir.OTYPE, ir.OMETHEXPR:
                // nop
 
-       case ONAME:
-               if n.Class() == PFUNC || n.Class() == PEXTERN {
+       case ir.ONAME:
+               if n.Class() == ir.PFUNC || n.Class() == ir.PEXTERN {
                        return
                }
                e.flow(k, e.oldLoc(n))
 
-       case OPLUS, ONEG, OBITNOT, ONOT:
+       case ir.OPLUS, ir.ONEG, ir.OBITNOT, ir.ONOT:
                e.discard(n.Left)
-       case OADD, OSUB, OOR, OXOR, OMUL, ODIV, OMOD, OLSH, ORSH, OAND, OANDNOT, OEQ, ONE, OLT, OLE, OGT, OGE, OANDAND, OOROR:
+       case ir.OADD, ir.OSUB, ir.OOR, ir.OXOR, ir.OMUL, ir.ODIV, ir.OMOD, ir.OLSH, ir.ORSH, ir.OAND, ir.OANDNOT, ir.OEQ, ir.ONE, ir.OLT, ir.OLE, ir.OGT, ir.OGE, ir.OANDAND, ir.OOROR:
                e.discard(n.Left)
                e.discard(n.Right)
 
-       case OADDR:
+       case ir.OADDR:
                e.expr(k.addr(n, "address-of"), n.Left) // "address-of"
-       case ODEREF:
+       case ir.ODEREF:
                e.expr(k.deref(n, "indirection"), n.Left) // "indirection"
-       case ODOT, ODOTMETH, ODOTINTER:
+       case ir.ODOT, ir.ODOTMETH, ir.ODOTINTER:
                e.expr(k.note(n, "dot"), n.Left)
-       case ODOTPTR:
+       case ir.ODOTPTR:
                e.expr(k.deref(n, "dot of pointer"), n.Left) // "dot of pointer"
-       case ODOTTYPE, ODOTTYPE2:
+       case ir.ODOTTYPE, ir.ODOTTYPE2:
                e.expr(k.dotType(n.Type, n, "dot"), n.Left)
-       case OINDEX:
+       case ir.OINDEX:
                if n.Left.Type.IsArray() {
                        e.expr(k.note(n, "fixed-array-index-of"), n.Left)
                } else {
@@ -510,17 +511,17 @@ func (e *Escape) exprSkipInit(k EscHole, n *Node) {
                        e.expr(k.deref(n, "dot of pointer"), n.Left)
                }
                e.discard(n.Right)
-       case OINDEXMAP:
+       case ir.OINDEXMAP:
                e.discard(n.Left)
                e.discard(n.Right)
-       case OSLICE, OSLICEARR, OSLICE3, OSLICE3ARR, OSLICESTR:
+       case ir.OSLICE, ir.OSLICEARR, ir.OSLICE3, ir.OSLICE3ARR, ir.OSLICESTR:
                e.expr(k.note(n, "slice"), n.Left)
                low, high, max := n.SliceBounds()
                e.discard(low)
                e.discard(high)
                e.discard(max)
 
-       case OCONV, OCONVNOP:
+       case ir.OCONV, ir.OCONVNOP:
                if checkPtr(e.curfn, 2) && n.Type.IsUnsafePtr() && n.Left.Type.IsPtr() {
                        // When -d=checkptr=2 is enabled, treat
                        // conversions to unsafe.Pointer as an
@@ -534,35 +535,35 @@ func (e *Escape) exprSkipInit(k EscHole, n *Node) {
                } else {
                        e.expr(k, n.Left)
                }
-       case OCONVIFACE:
+       case ir.OCONVIFACE:
                if !n.Left.Type.IsInterface() && !isdirectiface(n.Left.Type) {
                        k = e.spill(k, n)
                }
                e.expr(k.note(n, "interface-converted"), n.Left)
 
-       case ORECV:
+       case ir.ORECV:
                e.discard(n.Left)
 
-       case OCALLMETH, OCALLFUNC, OCALLINTER, OLEN, OCAP, OCOMPLEX, OREAL, OIMAG, OAPPEND, OCOPY:
+       case ir.OCALLMETH, ir.OCALLFUNC, ir.OCALLINTER, ir.OLEN, ir.OCAP, ir.OCOMPLEX, ir.OREAL, ir.OIMAG, ir.OAPPEND, ir.OCOPY:
                e.call([]EscHole{k}, n, nil)
 
-       case ONEW:
+       case ir.ONEW:
                e.spill(k, n)
 
-       case OMAKESLICE:
+       case ir.OMAKESLICE:
                e.spill(k, n)
                e.discard(n.Left)
                e.discard(n.Right)
-       case OMAKECHAN:
+       case ir.OMAKECHAN:
                e.discard(n.Left)
-       case OMAKEMAP:
+       case ir.OMAKEMAP:
                e.spill(k, n)
                e.discard(n.Left)
 
-       case ORECOVER:
+       case ir.ORECOVER:
                // nop
 
-       case OCALLPART:
+       case ir.OCALLPART:
                // Flow the receiver argument to both the closure and
                // to the receiver parameter.
 
@@ -580,38 +581,38 @@ func (e *Escape) exprSkipInit(k EscHole, n *Node) {
                for i := m.Type.NumResults(); i > 0; i-- {
                        ks = append(ks, e.heapHole())
                }
-               paramK := e.tagHole(ks, asNode(m.Nname), m.Type.Recv())
+               paramK := e.tagHole(ks, ir.AsNode(m.Nname), m.Type.Recv())
 
                e.expr(e.teeHole(paramK, closureK), n.Left)
 
-       case OPTRLIT:
+       case ir.OPTRLIT:
                e.expr(e.spill(k, n), n.Left)
 
-       case OARRAYLIT:
+       case ir.OARRAYLIT:
                for _, elt := range n.List.Slice() {
-                       if elt.Op == OKEY {
+                       if elt.Op == ir.OKEY {
                                elt = elt.Right
                        }
                        e.expr(k.note(n, "array literal element"), elt)
                }
 
-       case OSLICELIT:
+       case ir.OSLICELIT:
                k = e.spill(k, n)
                k.uintptrEscapesHack = uintptrEscapesHack // for ...uintptr parameters
 
                for _, elt := range n.List.Slice() {
-                       if elt.Op == OKEY {
+                       if elt.Op == ir.OKEY {
                                elt = elt.Right
                        }
                        e.expr(k.note(n, "slice-literal-element"), elt)
                }
 
-       case OSTRUCTLIT:
+       case ir.OSTRUCTLIT:
                for _, elt := range n.List.Slice() {
                        e.expr(k.note(n, "struct literal element"), elt.Left)
                }
 
-       case OMAPLIT:
+       case ir.OMAPLIT:
                e.spill(k, n)
 
                // Map keys and values are always stored in the heap.
@@ -620,12 +621,12 @@ func (e *Escape) exprSkipInit(k EscHole, n *Node) {
                        e.assignHeap(elt.Right, "map literal value", n)
                }
 
-       case OCLOSURE:
+       case ir.OCLOSURE:
                k = e.spill(k, n)
 
                // Link addresses of captured variables to closure.
                for _, v := range n.Func.ClosureVars.Slice() {
-                       if v.Op == OXXX { // unnamed out argument; see dcl.go:/^funcargs
+                       if v.Op == ir.OXXX { // unnamed out argument; see dcl.go:/^funcargs
                                continue
                        }
 
@@ -637,11 +638,11 @@ func (e *Escape) exprSkipInit(k EscHole, n *Node) {
                        e.expr(k.note(n, "captured by a closure"), v.Name.Defn)
                }
 
-       case ORUNES2STR, OBYTES2STR, OSTR2RUNES, OSTR2BYTES, ORUNESTR:
+       case ir.ORUNES2STR, ir.OBYTES2STR, ir.OSTR2RUNES, ir.OSTR2BYTES, ir.ORUNESTR:
                e.spill(k, n)
                e.discard(n.Left)
 
-       case OADDSTR:
+       case ir.OADDSTR:
                e.spill(k, n)
 
                // Arguments of OADDSTR never escape;
@@ -652,32 +653,32 @@ func (e *Escape) exprSkipInit(k EscHole, n *Node) {
 
 // unsafeValue evaluates a uintptr-typed arithmetic expression looking
 // for conversions from an unsafe.Pointer.
-func (e *Escape) unsafeValue(k EscHole, n *Node) {
-       if n.Type.Etype != TUINTPTR {
+func (e *Escape) unsafeValue(k EscHole, n *ir.Node) {
+       if n.Type.Etype != types.TUINTPTR {
                base.Fatalf("unexpected type %v for %v", n.Type, n)
        }
 
        e.stmts(n.Ninit)
 
        switch n.Op {
-       case OCONV, OCONVNOP:
+       case ir.OCONV, ir.OCONVNOP:
                if n.Left.Type.IsUnsafePtr() {
                        e.expr(k, n.Left)
                } else {
                        e.discard(n.Left)
                }
-       case ODOTPTR:
+       case ir.ODOTPTR:
                if isReflectHeaderDataField(n) {
                        e.expr(k.deref(n, "reflect.Header.Data"), n.Left)
                } else {
                        e.discard(n.Left)
                }
-       case OPLUS, ONEG, OBITNOT:
+       case ir.OPLUS, ir.ONEG, ir.OBITNOT:
                e.unsafeValue(k, n.Left)
-       case OADD, OSUB, OOR, OXOR, OMUL, ODIV, OMOD, OAND, OANDNOT:
+       case ir.OADD, ir.OSUB, ir.OOR, ir.OXOR, ir.OMUL, ir.ODIV, ir.OMOD, ir.OAND, ir.OANDNOT:
                e.unsafeValue(k, n.Left)
                e.unsafeValue(k, n.Right)
-       case OLSH, ORSH:
+       case ir.OLSH, ir.ORSH:
                e.unsafeValue(k, n.Left)
                // RHS need not be uintptr-typed (#32959) and can't meaningfully
                // flow pointers anyway.
@@ -689,11 +690,11 @@ func (e *Escape) unsafeValue(k EscHole, n *Node) {
 
 // discard evaluates an expression n for side-effects, but discards
 // its value.
-func (e *Escape) discard(n *Node) {
+func (e *Escape) discard(n *ir.Node) {
        e.expr(e.discardHole(), n)
 }
 
-func (e *Escape) discards(l Nodes) {
+func (e *Escape) discards(l ir.Nodes) {
        for _, n := range l.Slice() {
                e.discard(n)
        }
@@ -701,8 +702,8 @@ func (e *Escape) discards(l Nodes) {
 
 // addr evaluates an addressable expression n and returns an EscHole
 // that represents storing into the represented location.
-func (e *Escape) addr(n *Node) EscHole {
-       if n == nil || n.isBlank() {
+func (e *Escape) addr(n *ir.Node) EscHole {
+       if n == nil || ir.IsBlank(n) {
                // Can happen at least in OSELRECV.
                // TODO(mdempsky): Anywhere else?
                return e.discardHole()
@@ -713,23 +714,23 @@ func (e *Escape) addr(n *Node) EscHole {
        switch n.Op {
        default:
                base.Fatalf("unexpected addr: %v", n)
-       case ONAME:
-               if n.Class() == PEXTERN {
+       case ir.ONAME:
+               if n.Class() == ir.PEXTERN {
                        break
                }
                k = e.oldLoc(n).asHole()
-       case ODOT:
+       case ir.ODOT:
                k = e.addr(n.Left)
-       case OINDEX:
+       case ir.OINDEX:
                e.discard(n.Right)
                if n.Left.Type.IsArray() {
                        k = e.addr(n.Left)
                } else {
                        e.discard(n.Left)
                }
-       case ODEREF, ODOTPTR:
+       case ir.ODEREF, ir.ODOTPTR:
                e.discard(n)
-       case OINDEXMAP:
+       case ir.OINDEXMAP:
                e.discard(n.Left)
                e.assignHeap(n.Right, "key of map put", n)
        }
@@ -741,7 +742,7 @@ func (e *Escape) addr(n *Node) EscHole {
        return k
 }
 
-func (e *Escape) addrs(l Nodes) []EscHole {
+func (e *Escape) addrs(l ir.Nodes) []EscHole {
        var ks []EscHole
        for _, n := range l.Slice() {
                ks = append(ks, e.addr(n))
@@ -750,7 +751,7 @@ func (e *Escape) addrs(l Nodes) []EscHole {
 }
 
 // assign evaluates the assignment dst = src.
-func (e *Escape) assign(dst, src *Node, why string, where *Node) {
+func (e *Escape) assign(dst, src *ir.Node, why string, where *ir.Node) {
        // Filter out some no-op assignments for escape analysis.
        ignore := dst != nil && src != nil && isSelfAssign(dst, src)
        if ignore && base.Flag.LowerM != 0 {
@@ -758,7 +759,7 @@ func (e *Escape) assign(dst, src *Node, why string, where *Node) {
        }
 
        k := e.addr(dst)
-       if dst != nil && dst.Op == ODOTPTR && isReflectHeaderDataField(dst) {
+       if dst != nil && dst.Op == ir.ODOTPTR && isReflectHeaderDataField(dst) {
                e.unsafeValue(e.heapHole().note(where, why), src)
        } else {
                if ignore {
@@ -768,22 +769,22 @@ func (e *Escape) assign(dst, src *Node, why string, where *Node) {
        }
 }
 
-func (e *Escape) assignHeap(src *Node, why string, where *Node) {
+func (e *Escape) assignHeap(src *ir.Node, why string, where *ir.Node) {
        e.expr(e.heapHole().note(where, why), src)
 }
 
 // call evaluates a call expressions, including builtin calls. ks
 // should contain the holes representing where the function callee's
 // results flows; where is the OGO/ODEFER context of the call, if any.
-func (e *Escape) call(ks []EscHole, call, where *Node) {
-       topLevelDefer := where != nil && where.Op == ODEFER && e.loopDepth == 1
+func (e *Escape) call(ks []EscHole, call, where *ir.Node) {
+       topLevelDefer := where != nil && where.Op == ir.ODEFER && e.loopDepth == 1
        if topLevelDefer {
                // force stack allocation of defer record, unless
                // open-coded defers are used (see ssa.go)
                where.Esc = EscNever
        }
 
-       argument := func(k EscHole, arg *Node) {
+       argument := func(k EscHole, arg *ir.Node) {
                if topLevelDefer {
                        // Top level defers arguments don't escape to
                        // heap, but they do need to last until end of
@@ -800,21 +801,21 @@ func (e *Escape) call(ks []EscHole, call, where *Node) {
        default:
                base.Fatalf("unexpected call op: %v", call.Op)
 
-       case OCALLFUNC, OCALLMETH, OCALLINTER:
+       case ir.OCALLFUNC, ir.OCALLMETH, ir.OCALLINTER:
                fixVariadicCall(call)
 
                // Pick out the function callee, if statically known.
-               var fn *Node
+               var fn *ir.Node
                switch call.Op {
-               case OCALLFUNC:
+               case ir.OCALLFUNC:
                        switch v := staticValue(call.Left); {
-                       case v.Op == ONAME && v.Class() == PFUNC:
+                       case v.Op == ir.ONAME && v.Class() == ir.PFUNC:
                                fn = v
-                       case v.Op == OCLOSURE:
+                       case v.Op == ir.OCLOSURE:
                                fn = v.Func.Nname
                        }
-               case OCALLMETH:
-                       fn = call.Left.MethodName()
+               case ir.OCALLMETH:
+                       fn = methodExprName(call.Left)
                }
 
                fntype := call.Left.Type
@@ -824,7 +825,7 @@ func (e *Escape) call(ks []EscHole, call, where *Node) {
 
                if ks != nil && fn != nil && e.inMutualBatch(fn) {
                        for i, result := range fn.Type.Results().FieldSlice() {
-                               e.expr(ks[i], asNode(result.Nname))
+                               e.expr(ks[i], ir.AsNode(result.Nname))
                        }
                }
 
@@ -840,7 +841,7 @@ func (e *Escape) call(ks []EscHole, call, where *Node) {
                        argument(e.tagHole(ks, fn, param), args[i])
                }
 
-       case OAPPEND:
+       case ir.OAPPEND:
                args := call.List.Slice()
 
                // Appendee slice may flow directly to the result, if
@@ -865,7 +866,7 @@ func (e *Escape) call(ks []EscHole, call, where *Node) {
                        }
                }
 
-       case OCOPY:
+       case ir.OCOPY:
                argument(e.discardHole(), call.Left)
 
                copiedK := e.discardHole()
@@ -874,17 +875,17 @@ func (e *Escape) call(ks []EscHole, call, where *Node) {
                }
                argument(copiedK, call.Right)
 
-       case OPANIC:
+       case ir.OPANIC:
                argument(e.heapHole(), call.Left)
 
-       case OCOMPLEX:
+       case ir.OCOMPLEX:
                argument(e.discardHole(), call.Left)
                argument(e.discardHole(), call.Right)
-       case ODELETE, OPRINT, OPRINTN, ORECOVER:
+       case ir.ODELETE, ir.OPRINT, ir.OPRINTN, ir.ORECOVER:
                for _, arg := range call.List.Slice() {
                        argument(e.discardHole(), arg)
                }
-       case OLEN, OCAP, OREAL, OIMAG, OCLOSE:
+       case ir.OLEN, ir.OCAP, ir.OREAL, ir.OIMAG, ir.OCLOSE:
                argument(e.discardHole(), call.Left)
        }
 }
@@ -893,14 +894,14 @@ func (e *Escape) call(ks []EscHole, call, where *Node) {
 // ks should contain the holes representing where the function
 // callee's results flows. fn is the statically-known callee function,
 // if any.
-func (e *Escape) tagHole(ks []EscHole, fn *Node, param *types.Field) EscHole {
+func (e *Escape) tagHole(ks []EscHole, fn *ir.Node, param *types.Field) EscHole {
        // If this is a dynamic call, we can't rely on param.Note.
        if fn == nil {
                return e.heapHole()
        }
 
        if e.inMutualBatch(fn) {
-               return e.addr(asNode(param.Nname))
+               return e.addr(ir.AsNode(param.Nname))
        }
 
        // Call to previously tagged function.
@@ -934,7 +935,7 @@ func (e *Escape) tagHole(ks []EscHole, fn *Node, param *types.Field) EscHole {
 // fn has not yet been analyzed, so its parameters and results
 // should be incorporated directly into the flow graph instead of
 // relying on its escape analysis tagging.
-func (e *Escape) inMutualBatch(fn *Node) bool {
+func (e *Escape) inMutualBatch(fn *ir.Node) bool {
        if fn.Name.Defn != nil && fn.Name.Defn.Esc < EscFuncTagged {
                if fn.Name.Defn.Esc == EscFuncUnknown {
                        base.Fatalf("graph inconsistency")
@@ -959,11 +960,11 @@ type EscHole struct {
 
 type EscNote struct {
        next  *EscNote
-       where *Node
+       where *ir.Node
        why   string
 }
 
-func (k EscHole) note(where *Node, why string) EscHole {
+func (k EscHole) note(where *ir.Node, why string) EscHole {
        if where == nil || why == "" {
                base.Fatalf("note: missing where/why")
        }
@@ -985,10 +986,10 @@ func (k EscHole) shift(delta int) EscHole {
        return k
 }
 
-func (k EscHole) deref(where *Node, why string) EscHole { return k.shift(1).note(where, why) }
-func (k EscHole) addr(where *Node, why string) EscHole  { return k.shift(-1).note(where, why) }
+func (k EscHole) deref(where *ir.Node, why string) EscHole { return k.shift(1).note(where, why) }
+func (k EscHole) addr(where *ir.Node, why string) EscHole  { return k.shift(-1).note(where, why) }
 
-func (k EscHole) dotType(t *types.Type, where *Node, why string) EscHole {
+func (k EscHole) dotType(t *types.Type, where *ir.Node, why string) EscHole {
        if !t.IsInterface() && !isdirectiface(t) {
                k = k.shift(1)
        }
@@ -1025,7 +1026,7 @@ func (e *Escape) teeHole(ks ...EscHole) EscHole {
        return loc.asHole()
 }
 
-func (e *Escape) dcl(n *Node) EscHole {
+func (e *Escape) dcl(n *ir.Node) EscHole {
        loc := e.oldLoc(n)
        loc.loopDepth = e.loopDepth
        return loc.asHole()
@@ -1034,7 +1035,7 @@ func (e *Escape) dcl(n *Node) EscHole {
 // spill allocates a new location associated with expression n, flows
 // its address to k, and returns a hole that flows values to it. It's
 // intended for use with most expressions that allocate storage.
-func (e *Escape) spill(k EscHole, n *Node) EscHole {
+func (e *Escape) spill(k EscHole, n *ir.Node) EscHole {
        loc := e.newLoc(n, true)
        e.flow(k.addr(n, "spill"), loc)
        return loc.asHole()
@@ -1051,8 +1052,8 @@ func (e *Escape) later(k EscHole) EscHole {
 
 // canonicalNode returns the canonical *Node that n logically
 // represents.
-func canonicalNode(n *Node) *Node {
-       if n != nil && n.Op == ONAME && n.Name.IsClosureVar() {
+func canonicalNode(n *ir.Node) *ir.Node {
+       if n != nil && n.Op == ir.ONAME && n.Name.IsClosureVar() {
                n = n.Name.Defn
                if n.Name.IsClosureVar() {
                        base.Fatalf("still closure var")
@@ -1062,7 +1063,7 @@ func canonicalNode(n *Node) *Node {
        return n
 }
 
-func (e *Escape) newLoc(n *Node, transient bool) *EscLocation {
+func (e *Escape) newLoc(n *ir.Node, transient bool) *EscLocation {
        if e.curfn == nil {
                base.Fatalf("e.curfn isn't set")
        }
@@ -1079,7 +1080,7 @@ func (e *Escape) newLoc(n *Node, transient bool) *EscLocation {
        }
        e.allLocs = append(e.allLocs, loc)
        if n != nil {
-               if n.Op == ONAME && n.Name.Curfn != e.curfn {
+               if n.Op == ir.ONAME && n.Name.Curfn != e.curfn {
                        base.Fatalf("curfn mismatch: %v != %v", n.Name.Curfn, e.curfn)
                }
 
@@ -1095,7 +1096,7 @@ func (e *Escape) newLoc(n *Node, transient bool) *EscLocation {
        return loc
 }
 
-func (e *Escape) oldLoc(n *Node) *EscLocation {
+func (e *Escape) oldLoc(n *ir.Node) *EscLocation {
        n = canonicalNode(n)
        return n.Opt().(*EscLocation)
 }
@@ -1120,7 +1121,7 @@ func (e *Escape) flow(k EscHole, src *EscLocation) {
                        }
                        explanation := e.explainFlow(pos, dst, src, k.derefs, k.notes, []*logopt.LoggedOpt{})
                        if logopt.Enabled() {
-                               logopt.LogOpt(src.n.Pos, "escapes", "escape", e.curfn.funcname(), fmt.Sprintf("%v escapes to heap", src.n), explanation)
+                               logopt.LogOpt(src.n.Pos, "escapes", "escape", ir.FuncName(e.curfn), fmt.Sprintf("%v escapes to heap", src.n), explanation)
                        }
 
                }
@@ -1214,14 +1215,14 @@ func (e *Escape) walkOne(root *EscLocation, walkgen uint32, enqueue func(*EscLoc
                        // corresponding result parameter, then record
                        // that value flow for tagging the function
                        // later.
-                       if l.isName(PPARAM) {
+                       if l.isName(ir.PPARAM) {
                                if (logopt.Enabled() || base.Flag.LowerM >= 2) && !l.escapes {
                                        if base.Flag.LowerM >= 2 {
                                                fmt.Printf("%s: parameter %v leaks to %s with derefs=%d:\n", base.FmtPos(l.n.Pos), l.n, e.explainLoc(root), derefs)
                                        }
                                        explanation := e.explainPath(root, l)
                                        if logopt.Enabled() {
-                                               logopt.LogOpt(l.n.Pos, "leak", "escape", e.curfn.funcname(),
+                                               logopt.LogOpt(l.n.Pos, "leak", "escape", ir.FuncName(e.curfn),
                                                        fmt.Sprintf("parameter %v leaks to %s with derefs=%d", l.n, e.explainLoc(root), derefs), explanation)
                                        }
                                }
@@ -1238,7 +1239,7 @@ func (e *Escape) walkOne(root *EscLocation, walkgen uint32, enqueue func(*EscLoc
                                        }
                                        explanation := e.explainPath(root, l)
                                        if logopt.Enabled() {
-                                               logopt.LogOpt(l.n.Pos, "escape", "escape", e.curfn.funcname(), fmt.Sprintf("%v escapes to heap", l.n), explanation)
+                                               logopt.LogOpt(l.n.Pos, "escape", "escape", ir.FuncName(e.curfn), fmt.Sprintf("%v escapes to heap", l.n), explanation)
                                        }
                                }
                                l.escapes = true
@@ -1312,7 +1313,7 @@ func (e *Escape) explainFlow(pos string, dst, srcloc *EscLocation, derefs int, n
                } else if srcloc != nil && srcloc.n != nil {
                        epos = srcloc.n.Pos
                }
-               explanation = append(explanation, logopt.NewLoggedOpt(epos, "escflow", "escape", e.curfn.funcname(), flow))
+               explanation = append(explanation, logopt.NewLoggedOpt(epos, "escflow", "escape", ir.FuncName(e.curfn), flow))
        }
 
        for note := notes; note != nil; note = note.next {
@@ -1320,7 +1321,7 @@ func (e *Escape) explainFlow(pos string, dst, srcloc *EscLocation, derefs int, n
                        fmt.Printf("%s:     from %v (%v) at %s\n", pos, note.where, note.why, base.FmtPos(note.where.Pos))
                }
                if logopt.Enabled() {
-                       explanation = append(explanation, logopt.NewLoggedOpt(note.where.Pos, "escflow", "escape", e.curfn.funcname(),
+                       explanation = append(explanation, logopt.NewLoggedOpt(note.where.Pos, "escflow", "escape", ir.FuncName(e.curfn),
                                fmt.Sprintf("     from %v (%v)", note.where, note.why)))
                }
        }
@@ -1335,7 +1336,7 @@ func (e *Escape) explainLoc(l *EscLocation) string {
                // TODO(mdempsky): Omit entirely.
                return "{temp}"
        }
-       if l.n.Op == ONAME {
+       if l.n.Op == ir.ONAME {
                return fmt.Sprintf("%v", l.n)
        }
        return fmt.Sprintf("{storage for %v}", l.n)
@@ -1352,7 +1353,7 @@ func (e *Escape) outlives(l, other *EscLocation) bool {
        // We don't know what callers do with returned values, so
        // pessimistically we need to assume they flow to the heap and
        // outlive everything too.
-       if l.isName(PPARAMOUT) {
+       if l.isName(ir.PPARAMOUT) {
                // Exception: Directly called closures can return
                // locations allocated outside of them without forcing
                // them to the heap. For example:
@@ -1393,8 +1394,8 @@ func (e *Escape) outlives(l, other *EscLocation) bool {
 }
 
 // containsClosure reports whether c is a closure contained within f.
-func containsClosure(f, c *Node) bool {
-       if f.Op != ODCLFUNC || c.Op != ODCLFUNC {
+func containsClosure(f, c *ir.Node) bool {
+       if f.Op != ir.ODCLFUNC || c.Op != ir.ODCLFUNC {
                base.Fatalf("bad containsClosure: %v, %v", f, c)
        }
 
@@ -1414,7 +1415,7 @@ func containsClosure(f, c *Node) bool {
 func (l *EscLocation) leakTo(sink *EscLocation, derefs int) {
        // If sink is a result parameter and we can fit return bits
        // into the escape analysis tag, then record a return leak.
-       if sink.isName(PPARAMOUT) && sink.curfn == l.curfn {
+       if sink.isName(ir.PPARAMOUT) && sink.curfn == l.curfn {
                // TODO(mdempsky): Eliminate dependency on Vargen here.
                ri := int(sink.n.Name.Vargen) - 1
                if ri < numEscResults {
@@ -1428,7 +1429,7 @@ func (l *EscLocation) leakTo(sink *EscLocation, derefs int) {
        l.paramEsc.AddHeap(derefs)
 }
 
-func (e *Escape) finish(fns []*Node) {
+func (e *Escape) finish(fns []*ir.Node) {
        // Record parameter tags for package export data.
        for _, fn := range fns {
                fn.Esc = EscFuncTagged
@@ -1452,18 +1453,18 @@ func (e *Escape) finish(fns []*Node) {
                // Update n.Esc based on escape analysis results.
 
                if loc.escapes {
-                       if n.Op != ONAME {
+                       if n.Op != ir.ONAME {
                                if base.Flag.LowerM != 0 {
                                        base.WarnfAt(n.Pos, "%S escapes to heap", n)
                                }
                                if logopt.Enabled() {
-                                       logopt.LogOpt(n.Pos, "escape", "escape", e.curfn.funcname())
+                                       logopt.LogOpt(n.Pos, "escape", "escape", ir.FuncName(e.curfn))
                                }
                        }
                        n.Esc = EscHeap
                        addrescapes(n)
                } else {
-                       if base.Flag.LowerM != 0 && n.Op != ONAME {
+                       if base.Flag.LowerM != 0 && n.Op != ir.ONAME {
                                base.WarnfAt(n.Pos, "%S does not escape", n)
                        }
                        n.Esc = EscNone
@@ -1474,8 +1475,8 @@ func (e *Escape) finish(fns []*Node) {
        }
 }
 
-func (l *EscLocation) isName(c Class) bool {
-       return l.n != nil && l.n.Op == ONAME && l.n.Class() == c
+func (l *EscLocation) isName(c ir.Class) bool {
+       return l.n != nil && l.n.Op == ir.ONAME && l.n.Class() == c
 }
 
 const numEscResults = 7
@@ -1572,3 +1573,466 @@ func ParseLeaks(s string) EscLeaks {
        copy(l[:], s[4:])
        return l
 }
+
+func escapes(all []*ir.Node) {
+       visitBottomUp(all, escapeFuncs)
+}
+
+const (
+       EscFuncUnknown = 0 + iota
+       EscFuncPlanned
+       EscFuncStarted
+       EscFuncTagged
+)
+
+func min8(a, b int8) int8 {
+       if a < b {
+               return a
+       }
+       return b
+}
+
+func max8(a, b int8) int8 {
+       if a > b {
+               return a
+       }
+       return b
+}
+
+const (
+       EscUnknown = iota
+       EscNone    // Does not escape to heap, result, or parameters.
+       EscHeap    // Reachable from the heap
+       EscNever   // By construction will not escape.
+)
+
+// funcSym returns fn.Func.Nname.Sym if no nils are encountered along the way.
+func funcSym(fn *ir.Node) *types.Sym {
+       if fn == nil || fn.Func.Nname == nil {
+               return nil
+       }
+       return fn.Func.Nname.Sym
+}
+
+// Mark labels that have no backjumps to them as not increasing e.loopdepth.
+// Walk hasn't generated (goto|label).Left.Sym.Label yet, so we'll cheat
+// and set it to one of the following two. Then in esc we'll clear it again.
+var (
+       looping    = ir.Nod(ir.OXXX, nil, nil)
+       nonlooping = ir.Nod(ir.OXXX, nil, nil)
+)
+
+func isSliceSelfAssign(dst, src *ir.Node) bool {
+       // Detect the following special case.
+       //
+       //      func (b *Buffer) Foo() {
+       //              n, m := ...
+       //              b.buf = b.buf[n:m]
+       //      }
+       //
+       // This assignment is a no-op for escape analysis,
+       // it does not store any new pointers into b that were not already there.
+       // However, without this special case b will escape, because we assign to OIND/ODOTPTR.
+       // Here we assume that the statement will not contain calls,
+       // that is, that order will move any calls to init.
+       // Otherwise base ONAME value could change between the moments
+       // when we evaluate it for dst and for src.
+
+       // dst is ONAME dereference.
+       if dst.Op != ir.ODEREF && dst.Op != ir.ODOTPTR || dst.Left.Op != ir.ONAME {
+               return false
+       }
+       // src is a slice operation.
+       switch src.Op {
+       case ir.OSLICE, ir.OSLICE3, ir.OSLICESTR:
+               // OK.
+       case ir.OSLICEARR, ir.OSLICE3ARR:
+               // Since arrays are embedded into containing object,
+               // slice of non-pointer array will introduce a new pointer into b that was not already there
+               // (pointer to b itself). After such assignment, if b contents escape,
+               // b escapes as well. If we ignore such OSLICEARR, we will conclude
+               // that b does not escape when b contents do.
+               //
+               // Pointer to an array is OK since it's not stored inside b directly.
+               // For slicing an array (not pointer to array), there is an implicit OADDR.
+               // We check that to determine non-pointer array slicing.
+               if src.Left.Op == ir.OADDR {
+                       return false
+               }
+       default:
+               return false
+       }
+       // slice is applied to ONAME dereference.
+       if src.Left.Op != ir.ODEREF && src.Left.Op != ir.ODOTPTR || src.Left.Left.Op != ir.ONAME {
+               return false
+       }
+       // dst and src reference the same base ONAME.
+       return dst.Left == src.Left.Left
+}
+
+// isSelfAssign reports whether assignment from src to dst can
+// be ignored by the escape analysis as it's effectively a self-assignment.
+func isSelfAssign(dst, src *ir.Node) bool {
+       if isSliceSelfAssign(dst, src) {
+               return true
+       }
+
+       // Detect trivial assignments that assign back to the same object.
+       //
+       // It covers these cases:
+       //      val.x = val.y
+       //      val.x[i] = val.y[j]
+       //      val.x1.x2 = val.x1.y2
+       //      ... etc
+       //
+       // These assignments do not change assigned object lifetime.
+
+       if dst == nil || src == nil || dst.Op != src.Op {
+               return false
+       }
+
+       switch dst.Op {
+       case ir.ODOT, ir.ODOTPTR:
+               // Safe trailing accessors that are permitted to differ.
+       case ir.OINDEX:
+               if mayAffectMemory(dst.Right) || mayAffectMemory(src.Right) {
+                       return false
+               }
+       default:
+               return false
+       }
+
+       // The expression prefix must be both "safe" and identical.
+       return samesafeexpr(dst.Left, src.Left)
+}
+
+// mayAffectMemory reports whether evaluation of n may affect the program's
+// memory state. If the expression can't affect memory state, then it can be
+// safely ignored by the escape analysis.
+func mayAffectMemory(n *ir.Node) bool {
+       // We may want to use a list of "memory safe" ops instead of generally
+       // "side-effect free", which would include all calls and other ops that can
+       // allocate or change global state. For now, it's safer to start with the latter.
+       //
+       // We're ignoring things like division by zero, index out of range,
+       // and nil pointer dereference here.
+       switch n.Op {
+       case ir.ONAME, ir.OCLOSUREVAR, ir.OLITERAL, ir.ONIL:
+               return false
+
+       // Left+Right group.
+       case ir.OINDEX, ir.OADD, ir.OSUB, ir.OOR, ir.OXOR, ir.OMUL, ir.OLSH, ir.ORSH, ir.OAND, ir.OANDNOT, ir.ODIV, ir.OMOD:
+               return mayAffectMemory(n.Left) || mayAffectMemory(n.Right)
+
+       // Left group.
+       case ir.ODOT, ir.ODOTPTR, ir.ODEREF, ir.OCONVNOP, ir.OCONV, ir.OLEN, ir.OCAP,
+               ir.ONOT, ir.OBITNOT, ir.OPLUS, ir.ONEG, ir.OALIGNOF, ir.OOFFSETOF, ir.OSIZEOF:
+               return mayAffectMemory(n.Left)
+
+       default:
+               return true
+       }
+}
+
+// heapAllocReason returns the reason the given Node must be heap
+// allocated, or the empty string if it doesn't.
+func heapAllocReason(n *ir.Node) string {
+       if n.Type == nil {
+               return ""
+       }
+
+       // Parameters are always passed via the stack.
+       if n.Op == ir.ONAME && (n.Class() == ir.PPARAM || n.Class() == ir.PPARAMOUT) {
+               return ""
+       }
+
+       if n.Type.Width > maxStackVarSize {
+               return "too large for stack"
+       }
+
+       if (n.Op == ir.ONEW || n.Op == ir.OPTRLIT) && n.Type.Elem().Width >= maxImplicitStackVarSize {
+               return "too large for stack"
+       }
+
+       if n.Op == ir.OCLOSURE && closureType(n).Size() >= maxImplicitStackVarSize {
+               return "too large for stack"
+       }
+       if n.Op == ir.OCALLPART && partialCallType(n).Size() >= maxImplicitStackVarSize {
+               return "too large for stack"
+       }
+
+       if n.Op == ir.OMAKESLICE {
+               r := n.Right
+               if r == nil {
+                       r = n.Left
+               }
+               if !smallintconst(r) {
+                       return "non-constant size"
+               }
+               if t := n.Type; t.Elem().Width != 0 && r.Int64Val() >= maxImplicitStackVarSize/t.Elem().Width {
+                       return "too large for stack"
+               }
+       }
+
+       return ""
+}
+
+// addrescapes tags node n as having had its address taken
+// by "increasing" the "value" of n.Esc to EscHeap.
+// Storage is allocated as necessary to allow the address
+// to be taken.
+func addrescapes(n *ir.Node) {
+       switch n.Op {
+       default:
+               // Unexpected Op, probably due to a previous type error. Ignore.
+
+       case ir.ODEREF, ir.ODOTPTR:
+               // Nothing to do.
+
+       case ir.ONAME:
+               if n == nodfp {
+                       break
+               }
+
+               // if this is a tmpname (PAUTO), it was tagged by tmpname as not escaping.
+               // on PPARAM it means something different.
+               if n.Class() == ir.PAUTO && n.Esc == EscNever {
+                       break
+               }
+
+               // If a closure reference escapes, mark the outer variable as escaping.
+               if n.Name.IsClosureVar() {
+                       addrescapes(n.Name.Defn)
+                       break
+               }
+
+               if n.Class() != ir.PPARAM && n.Class() != ir.PPARAMOUT && n.Class() != ir.PAUTO {
+                       break
+               }
+
+               // This is a plain parameter or local variable that needs to move to the heap,
+               // but possibly for the function outside the one we're compiling.
+               // That is, if we have:
+               //
+               //      func f(x int) {
+               //              func() {
+               //                      global = &x
+               //              }
+               //      }
+               //
+               // then we're analyzing the inner closure but we need to move x to the
+               // heap in f, not in the inner closure. Flip over to f before calling moveToHeap.
+               oldfn := Curfn
+               Curfn = n.Name.Curfn
+               if Curfn.Op == ir.OCLOSURE {
+                       Curfn = Curfn.Func.Decl
+                       panic("can't happen")
+               }
+               ln := base.Pos
+               base.Pos = Curfn.Pos
+               moveToHeap(n)
+               Curfn = oldfn
+               base.Pos = ln
+
+       // ODOTPTR has already been introduced,
+       // so these are the non-pointer ODOT and OINDEX.
+       // In &x[0], if x is a slice, then x does not
+       // escape--the pointer inside x does, but that
+       // is always a heap pointer anyway.
+       case ir.ODOT, ir.OINDEX, ir.OPAREN, ir.OCONVNOP:
+               if !n.Left.Type.IsSlice() {
+                       addrescapes(n.Left)
+               }
+       }
+}
+
+// moveToHeap records the parameter or local variable n as moved to the heap.
+func moveToHeap(n *ir.Node) {
+       if base.Flag.LowerR != 0 {
+               ir.Dump("MOVE", n)
+       }
+       if base.Flag.CompilingRuntime {
+               base.Errorf("%v escapes to heap, not allowed in runtime", n)
+       }
+       if n.Class() == ir.PAUTOHEAP {
+               ir.Dump("n", n)
+               base.Fatalf("double move to heap")
+       }
+
+       // Allocate a local stack variable to hold the pointer to the heap copy.
+       // temp will add it to the function declaration list automatically.
+       heapaddr := temp(types.NewPtr(n.Type))
+       heapaddr.Sym = lookup("&" + n.Sym.Name)
+       heapaddr.Orig.Sym = heapaddr.Sym
+       heapaddr.Pos = n.Pos
+
+       // Unset AutoTemp to persist the &foo variable name through SSA to
+       // liveness analysis.
+       // TODO(mdempsky/drchase): Cleaner solution?
+       heapaddr.Name.SetAutoTemp(false)
+
+       // Parameters have a local stack copy used at function start/end
+       // in addition to the copy in the heap that may live longer than
+       // the function.
+       if n.Class() == ir.PPARAM || n.Class() == ir.PPARAMOUT {
+               if n.Xoffset == types.BADWIDTH {
+                       base.Fatalf("addrescapes before param assignment")
+               }
+
+               // We rewrite n below to be a heap variable (indirection of heapaddr).
+               // Preserve a copy so we can still write code referring to the original,
+               // and substitute that copy into the function declaration list
+               // so that analyses of the local (on-stack) variables use it.
+               stackcopy := NewName(n.Sym)
+               stackcopy.Type = n.Type
+               stackcopy.Xoffset = n.Xoffset
+               stackcopy.SetClass(n.Class())
+               stackcopy.Name.Param.Heapaddr = heapaddr
+               if n.Class() == ir.PPARAMOUT {
+                       // Make sure the pointer to the heap copy is kept live throughout the function.
+                       // The function could panic at any point, and then a defer could recover.
+                       // Thus, we need the pointer to the heap copy always available so the
+                       // post-deferreturn code can copy the return value back to the stack.
+                       // See issue 16095.
+                       heapaddr.Name.SetIsOutputParamHeapAddr(true)
+               }
+               n.Name.Param.Stackcopy = stackcopy
+
+               // Substitute the stackcopy into the function variable list so that
+               // liveness and other analyses use the underlying stack slot
+               // and not the now-pseudo-variable n.
+               found := false
+               for i, d := range Curfn.Func.Dcl {
+                       if d == n {
+                               Curfn.Func.Dcl[i] = stackcopy
+                               found = true
+                               break
+                       }
+                       // Parameters are before locals, so can stop early.
+                       // This limits the search even in functions with many local variables.
+                       if d.Class() == ir.PAUTO {
+                               break
+                       }
+               }
+               if !found {
+                       base.Fatalf("cannot find %v in local variable list", n)
+               }
+               Curfn.Func.Dcl = append(Curfn.Func.Dcl, n)
+       }
+
+       // Modify n in place so that uses of n now mean indirection of the heapaddr.
+       n.SetClass(ir.PAUTOHEAP)
+       n.Xoffset = 0
+       n.Name.Param.Heapaddr = heapaddr
+       n.Esc = EscHeap
+       if base.Flag.LowerM != 0 {
+               base.WarnfAt(n.Pos, "moved to heap: %v", n)
+       }
+}
+
+// This special tag is applied to uintptr variables
+// that we believe may hold unsafe.Pointers for
+// calls into assembly functions.
+const unsafeUintptrTag = "unsafe-uintptr"
+
+// This special tag is applied to uintptr parameters of functions
+// marked go:uintptrescapes.
+const uintptrEscapesTag = "uintptr-escapes"
+
+func (e *Escape) paramTag(fn *ir.Node, narg int, f *types.Field) string {
+       name := func() string {
+               if f.Sym != nil {
+                       return f.Sym.Name
+               }
+               return fmt.Sprintf("arg#%d", narg)
+       }
+
+       if fn.Nbody.Len() == 0 {
+               // Assume that uintptr arguments must be held live across the call.
+               // This is most important for syscall.Syscall.
+               // See golang.org/issue/13372.
+               // This really doesn't have much to do with escape analysis per se,
+               // but we are reusing the ability to annotate an individual function
+               // argument and pass those annotations along to importing code.
+               if f.Type.IsUintptr() {
+                       if base.Flag.LowerM != 0 {
+                               base.WarnfAt(f.Pos, "assuming %v is unsafe uintptr", name())
+                       }
+                       return unsafeUintptrTag
+               }
+
+               if !f.Type.HasPointers() { // don't bother tagging for scalars
+                       return ""
+               }
+
+               var esc EscLeaks
+
+               // External functions are assumed unsafe, unless
+               // //go:noescape is given before the declaration.
+               if fn.Func.Pragma&ir.Noescape != 0 {
+                       if base.Flag.LowerM != 0 && f.Sym != nil {
+                               base.WarnfAt(f.Pos, "%v does not escape", name())
+                       }
+               } else {
+                       if base.Flag.LowerM != 0 && f.Sym != nil {
+                               base.WarnfAt(f.Pos, "leaking param: %v", name())
+                       }
+                       esc.AddHeap(0)
+               }
+
+               return esc.Encode()
+       }
+
+       if fn.Func.Pragma&ir.UintptrEscapes != 0 {
+               if f.Type.IsUintptr() {
+                       if base.Flag.LowerM != 0 {
+                               base.WarnfAt(f.Pos, "marking %v as escaping uintptr", name())
+                       }
+                       return uintptrEscapesTag
+               }
+               if f.IsDDD() && f.Type.Elem().IsUintptr() {
+                       // final argument is ...uintptr.
+                       if base.Flag.LowerM != 0 {
+                               base.WarnfAt(f.Pos, "marking %v as escaping ...uintptr", name())
+                       }
+                       return uintptrEscapesTag
+               }
+       }
+
+       if !f.Type.HasPointers() { // don't bother tagging for scalars
+               return ""
+       }
+
+       // Unnamed parameters are unused and therefore do not escape.
+       if f.Sym == nil || f.Sym.IsBlank() {
+               var esc EscLeaks
+               return esc.Encode()
+       }
+
+       n := ir.AsNode(f.Nname)
+       loc := e.oldLoc(n)
+       esc := loc.paramEsc
+       esc.Optimize()
+
+       if base.Flag.LowerM != 0 && !loc.escapes {
+               if esc.Empty() {
+                       base.WarnfAt(f.Pos, "%v does not escape", name())
+               }
+               if x := esc.Heap(); x >= 0 {
+                       if x == 0 {
+                               base.WarnfAt(f.Pos, "leaking param: %v", name())
+                       } else {
+                               // TODO(mdempsky): Mention level=x like below?
+                               base.WarnfAt(f.Pos, "leaking param content: %v", name())
+                       }
+               }
+               for i := 0; i < numEscResults; i++ {
+                       if x := esc.Result(i); x >= 0 {
+                               res := fn.Type.Results().Field(i).Sym
+                               base.WarnfAt(f.Pos, "leaking param: %v to result %v level=%d", name(), res, x)
+                       }
+               }
+       }
+
+       return esc.Encode()
+}
index 1fa64fbe4497da6139667743de1df9f78e115485..36bbb75050749763305c832c07be332c3dbdb845 100644 (file)
@@ -6,6 +6,7 @@ package gc
 
 import (
        "cmd/compile/internal/base"
+       "cmd/compile/internal/ir"
        "cmd/compile/internal/types"
        "cmd/internal/bio"
        "cmd/internal/src"
@@ -20,10 +21,10 @@ func exportf(bout *bio.Writer, format string, args ...interface{}) {
        }
 }
 
-var asmlist []*Node
+var asmlist []*ir.Node
 
 // exportsym marks n for export (or reexport).
-func exportsym(n *Node) {
+func exportsym(n *ir.Node) {
        if n.Sym.OnExportList() {
                return
        }
@@ -40,14 +41,14 @@ func initname(s string) bool {
        return s == "init"
 }
 
-func autoexport(n *Node, ctxt Class) {
-       if n.Sym.Pkg != localpkg {
+func autoexport(n *ir.Node, ctxt ir.Class) {
+       if n.Sym.Pkg != ir.LocalPkg {
                return
        }
-       if (ctxt != PEXTERN && ctxt != PFUNC) || dclcontext != PEXTERN {
+       if (ctxt != ir.PEXTERN && ctxt != ir.PFUNC) || dclcontext != ir.PEXTERN {
                return
        }
-       if n.Type != nil && n.Type.IsKind(TFUNC) && n.IsMethod() {
+       if n.Type != nil && n.Type.IsKind(types.TFUNC) && ir.IsMethod(n) {
                return
        }
 
@@ -73,8 +74,8 @@ func dumpexport(bout *bio.Writer) {
        }
 }
 
-func importsym(ipkg *types.Pkg, s *types.Sym, op Op) *Node {
-       n := asNode(s.PkgDef())
+func importsym(ipkg *types.Pkg, s *types.Sym, op ir.Op) *ir.Node {
+       n := ir.AsNode(s.PkgDef())
        if n == nil {
                // iimport should have created a stub ONONAME
                // declaration for all imported symbols. The exception
@@ -85,10 +86,10 @@ func importsym(ipkg *types.Pkg, s *types.Sym, op Op) *Node {
                }
 
                n = dclname(s)
-               s.SetPkgDef(asTypesNode(n))
+               s.SetPkgDef(ir.AsTypesNode(n))
                s.Importdef = ipkg
        }
-       if n.Op != ONONAME && n.Op != op {
+       if n.Op != ir.ONONAME && n.Op != op {
                redeclare(base.Pos, s, fmt.Sprintf("during import %q", ipkg.Path))
        }
        return n
@@ -98,16 +99,16 @@ func importsym(ipkg *types.Pkg, s *types.Sym, op Op) *Node {
 // If no such type has been declared yet, a forward declaration is returned.
 // ipkg is the package being imported
 func importtype(ipkg *types.Pkg, pos src.XPos, s *types.Sym) *types.Type {
-       n := importsym(ipkg, s, OTYPE)
-       if n.Op != OTYPE {
-               t := types.New(TFORW)
+       n := importsym(ipkg, s, ir.OTYPE)
+       if n.Op != ir.OTYPE {
+               t := types.New(types.TFORW)
                t.Sym = s
-               t.Nod = asTypesNode(n)
+               t.Nod = ir.AsTypesNode(n)
 
-               n.Op = OTYPE
+               n.Op = ir.OTYPE
                n.Pos = pos
                n.Type = t
-               n.SetClass(PEXTERN)
+               n.SetClass(ir.PEXTERN)
        }
 
        t := n.Type
@@ -119,9 +120,9 @@ func importtype(ipkg *types.Pkg, pos src.XPos, s *types.Sym) *types.Type {
 
 // importobj declares symbol s as an imported object representable by op.
 // ipkg is the package being imported
-func importobj(ipkg *types.Pkg, pos src.XPos, s *types.Sym, op Op, ctxt Class, t *types.Type) *Node {
+func importobj(ipkg *types.Pkg, pos src.XPos, s *types.Sym, op ir.Op, ctxt ir.Class, t *types.Type) *ir.Node {
        n := importsym(ipkg, s, op)
-       if n.Op != ONONAME {
+       if n.Op != ir.ONONAME {
                if n.Op == op && (n.Class() != ctxt || !types.Identical(n.Type, t)) {
                        redeclare(base.Pos, s, fmt.Sprintf("during import %q", ipkg.Path))
                }
@@ -131,7 +132,7 @@ func importobj(ipkg *types.Pkg, pos src.XPos, s *types.Sym, op Op, ctxt Class, t
        n.Op = op
        n.Pos = pos
        n.SetClass(ctxt)
-       if ctxt == PFUNC {
+       if ctxt == ir.PFUNC {
                n.Sym.SetFunc(true)
        }
        n.Type = t
@@ -141,7 +142,7 @@ func importobj(ipkg *types.Pkg, pos src.XPos, s *types.Sym, op Op, ctxt Class, t
 // importconst declares symbol s as an imported constant with type t and value val.
 // ipkg is the package being imported
 func importconst(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type, val constant.Value) {
-       n := importobj(ipkg, pos, s, OLITERAL, PEXTERN, t)
+       n := importobj(ipkg, pos, s, ir.OLITERAL, ir.PEXTERN, t)
        if n == nil { // TODO: Check that value matches.
                return
        }
@@ -156,12 +157,12 @@ func importconst(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type, val
 // importfunc declares symbol s as an imported function with type t.
 // ipkg is the package being imported
 func importfunc(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type) {
-       n := importobj(ipkg, pos, s, ONAME, PFUNC, t)
+       n := importobj(ipkg, pos, s, ir.ONAME, ir.PFUNC, t)
        if n == nil {
                return
        }
 
-       n.Func = new(Func)
+       n.Func = new(ir.Func)
 
        if base.Flag.E != 0 {
                fmt.Printf("import func %v%S\n", s, t)
@@ -171,7 +172,7 @@ func importfunc(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type) {
 // importvar declares symbol s as an imported variable with type t.
 // ipkg is the package being imported
 func importvar(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type) {
-       n := importobj(ipkg, pos, s, ONAME, PEXTERN, t)
+       n := importobj(ipkg, pos, s, ir.ONAME, ir.PEXTERN, t)
        if n == nil {
                return
        }
@@ -184,7 +185,7 @@ func importvar(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type) {
 // importalias declares symbol s as an imported type alias with type t.
 // ipkg is the package being imported
 func importalias(ipkg *types.Pkg, pos src.XPos, s *types.Sym, t *types.Type) {
-       n := importobj(ipkg, pos, s, OTYPE, PEXTERN, t)
+       n := importobj(ipkg, pos, s, ir.OTYPE, ir.PEXTERN, t)
        if n == nil {
                return
        }
@@ -199,20 +200,20 @@ func dumpasmhdr() {
        if err != nil {
                base.Fatalf("%v", err)
        }
-       fmt.Fprintf(b, "// generated by compile -asmhdr from package %s\n\n", localpkg.Name)
+       fmt.Fprintf(b, "// generated by compile -asmhdr from package %s\n\n", ir.LocalPkg.Name)
        for _, n := range asmlist {
                if n.Sym.IsBlank() {
                        continue
                }
                switch n.Op {
-               case OLITERAL:
+               case ir.OLITERAL:
                        t := n.Val().Kind()
                        if t == constant.Float || t == constant.Complex {
                                break
                        }
                        fmt.Fprintf(b, "#define const_%s %#v\n", n.Sym.Name, n.Val())
 
-               case OTYPE:
+               case ir.OTYPE:
                        t := n.Type
                        if !t.IsStruct() || t.StructType().Map != nil || t.IsFuncArgStruct() {
                                break
index a70bddca81340e8e4e69ae70542268b7be46481a..0f5294b17d1858704d35ce6b707b1d933f23a818 100644 (file)
@@ -6,6 +6,7 @@ package gc
 
 import (
        "cmd/compile/internal/base"
+       "cmd/compile/internal/ir"
        "cmd/compile/internal/types"
        "cmd/internal/obj"
        "cmd/internal/src"
@@ -29,14 +30,14 @@ func sysvar(name string) *obj.LSym {
 
 // isParamStackCopy reports whether this is the on-stack copy of a
 // function parameter that moved to the heap.
-func (n *Node) isParamStackCopy() bool {
-       return n.Op == ONAME && (n.Class() == PPARAM || n.Class() == PPARAMOUT) && n.Name.Param.Heapaddr != nil
+func isParamStackCopy(n *ir.Node) bool {
+       return n.Op == ir.ONAME && (n.Class() == ir.PPARAM || n.Class() == ir.PPARAMOUT) && n.Name.Param.Heapaddr != nil
 }
 
 // isParamHeapCopy reports whether this is the on-heap copy of
 // a function parameter that moved to the heap.
-func (n *Node) isParamHeapCopy() bool {
-       return n.Op == ONAME && n.Class() == PAUTOHEAP && n.Name.Param.Stackcopy != nil
+func isParamHeapCopy(n *ir.Node) bool {
+       return n.Op == ir.ONAME && n.Class() == ir.PAUTOHEAP && n.Name.Param.Stackcopy != nil
 }
 
 // autotmpname returns the name for an autotmp variable numbered n.
@@ -51,12 +52,12 @@ func autotmpname(n int) string {
 }
 
 // make a new Node off the books
-func tempAt(pos src.XPos, curfn *Node, t *types.Type) *Node {
+func tempAt(pos src.XPos, curfn *ir.Node, t *types.Type) *ir.Node {
        if curfn == nil {
                base.Fatalf("no curfn for tempAt")
        }
-       if curfn.Op == OCLOSURE {
-               Dump("tempAt", curfn)
+       if curfn.Op == ir.OCLOSURE {
+               ir.Dump("tempAt", curfn)
                base.Fatalf("adding tempAt to wrong closure function")
        }
        if t == nil {
@@ -65,12 +66,12 @@ func tempAt(pos src.XPos, curfn *Node, t *types.Type) *Node {
 
        s := &types.Sym{
                Name: autotmpname(len(curfn.Func.Dcl)),
-               Pkg:  localpkg,
+               Pkg:  ir.LocalPkg,
        }
-       n := newnamel(pos, s)
-       s.Def = asTypesNode(n)
+       n := ir.NewNameAt(pos, s)
+       s.Def = ir.AsTypesNode(n)
        n.Type = t
-       n.SetClass(PAUTO)
+       n.SetClass(ir.PAUTO)
        n.Esc = EscNever
        n.Name.Curfn = curfn
        n.Name.SetUsed(true)
@@ -82,6 +83,6 @@ func tempAt(pos src.XPos, curfn *Node, t *types.Type) *Node {
        return n.Orig
 }
 
-func temp(t *types.Type) *Node {
+func temp(t *types.Type) *ir.Node {
        return tempAt(base.Pos, Curfn, t)
 }
index d9b8f704a936221c88b096d77a1908c7e817f647..8642cc4a3056640ec2ecf2dbf3889a600e544f66 100644 (file)
@@ -6,6 +6,7 @@ package gc
 
 import (
        "cmd/compile/internal/base"
+       "cmd/compile/internal/ir"
        "cmd/compile/internal/ssa"
        "cmd/compile/internal/types"
        "cmd/internal/obj"
@@ -13,10 +14,6 @@ import (
        "sync"
 )
 
-const (
-       BADWIDTH = types.BADWIDTH
-)
-
 var (
        // maximum size variable which we will allocate on the stack.
        // This limit is for explicit variable declarations like "var x T" or "x := ...".
@@ -40,7 +37,7 @@ var (
 
 // isRuntimePkg reports whether p is package runtime.
 func isRuntimePkg(p *types.Pkg) bool {
-       if base.Flag.CompilingRuntime && p == localpkg {
+       if base.Flag.CompilingRuntime && p == ir.LocalPkg {
                return true
        }
        return p.Path == "runtime"
@@ -48,31 +45,12 @@ func isRuntimePkg(p *types.Pkg) bool {
 
 // isReflectPkg reports whether p is package reflect.
 func isReflectPkg(p *types.Pkg) bool {
-       if p == localpkg {
+       if p == ir.LocalPkg {
                return base.Ctxt.Pkgpath == "reflect"
        }
        return p.Path == "reflect"
 }
 
-// The Class of a variable/function describes the "storage class"
-// of a variable or function. During parsing, storage classes are
-// called declaration contexts.
-type Class uint8
-
-//go:generate stringer -type=Class
-const (
-       Pxxx      Class = iota // no class; used during ssa conversion to indicate pseudo-variables
-       PEXTERN                // global variables
-       PAUTO                  // local variables
-       PAUTOHEAP              // local variables or parameters moved to heap
-       PPARAM                 // input arguments
-       PPARAMOUT              // output results
-       PFUNC                  // global functions
-
-       // Careful: Class is stored in three bits in Node.flags.
-       _ = uint((1 << 3) - iota) // static assert for iota <= (1 << 3)
-)
-
 // Slices in the runtime are represented by three components:
 //
 // type slice struct {
@@ -102,8 +80,6 @@ var pragcgobuf [][]string
 
 var decldepth int32
 
-var localpkg *types.Pkg // package being compiled
-
 var inimport bool // set during import
 
 var itabpkg *types.Pkg // fake pkg for itab entries
@@ -126,55 +102,51 @@ var gopkg *types.Pkg // pseudo-package for method symbols on anonymous receiver
 
 var zerosize int64
 
-var simtype [NTYPE]types.EType
+var simtype [types.NTYPE]types.EType
 
 var (
-       isInt     [NTYPE]bool
-       isFloat   [NTYPE]bool
-       isComplex [NTYPE]bool
-       issimple  [NTYPE]bool
+       isInt     [types.NTYPE]bool
+       isFloat   [types.NTYPE]bool
+       isComplex [types.NTYPE]bool
+       issimple  [types.NTYPE]bool
 )
 
 var (
-       okforeq    [NTYPE]bool
-       okforadd   [NTYPE]bool
-       okforand   [NTYPE]bool
-       okfornone  [NTYPE]bool
-       okforcmp   [NTYPE]bool
-       okforbool  [NTYPE]bool
-       okforcap   [NTYPE]bool
-       okforlen   [NTYPE]bool
-       okforarith [NTYPE]bool
+       okforeq    [types.NTYPE]bool
+       okforadd   [types.NTYPE]bool
+       okforand   [types.NTYPE]bool
+       okfornone  [types.NTYPE]bool
+       okforcmp   [types.NTYPE]bool
+       okforbool  [types.NTYPE]bool
+       okforcap   [types.NTYPE]bool
+       okforlen   [types.NTYPE]bool
+       okforarith [types.NTYPE]bool
 )
 
-var okforconst [NTYPE]bool
-
 var (
-       okfor [OEND][]bool
-       iscmp [OEND]bool
+       okfor [ir.OEND][]bool
+       iscmp [ir.OEND]bool
 )
 
-var xtop []*Node
+var xtop []*ir.Node
 
-var exportlist []*Node
+var exportlist []*ir.Node
 
-var importlist []*Node // imported functions and methods with inlinable bodies
+var importlist []*ir.Node // imported functions and methods with inlinable bodies
 
 var (
        funcsymsmu sync.Mutex // protects funcsyms and associated package lookups (see func funcsym)
        funcsyms   []*types.Sym
 )
 
-var dclcontext Class // PEXTERN/PAUTO
+var dclcontext ir.Class // PEXTERN/PAUTO
 
-var Curfn *Node
+var Curfn *ir.Node
 
 var Widthptr int
 
 var Widthreg int
 
-var nblank *Node
-
 var typecheckok bool
 
 // Whether we are adding any sort of code instrumentation, such as
@@ -184,7 +156,7 @@ var instrumenting bool
 // Whether we are tracking lexical scopes for DWARF.
 var trackScopes bool
 
-var nodfp *Node
+var nodfp *ir.Node
 
 var autogeneratedPos src.XPos
 
@@ -221,7 +193,7 @@ var thearch Arch
 
 var (
        staticuint64s,
-       zerobase *Node
+       zerobase *ir.Node
 
        assertE2I,
        assertE2I2,
index 92a3611cb785131c26e6d96ab4a585e456a4847f..cf1c85ce29265e522c9cb914a4f33014cfb7fcb5 100644 (file)
@@ -32,6 +32,7 @@ package gc
 
 import (
        "cmd/compile/internal/base"
+       "cmd/compile/internal/ir"
        "cmd/compile/internal/ssa"
        "cmd/internal/obj"
        "cmd/internal/objabi"
@@ -46,7 +47,7 @@ type Progs struct {
        next      *obj.Prog  // next Prog
        pc        int64      // virtual PC; count of Progs
        pos       src.XPos   // position to use for new Progs
-       curfn     *Node      // fn these Progs are for
+       curfn     *ir.Node   // fn these Progs are for
        progcache []obj.Prog // local progcache
        cacheidx  int        // first free element of progcache
 
@@ -56,7 +57,7 @@ type Progs struct {
 
 // newProgs returns a new Progs for fn.
 // worker indicates which of the backend workers will use the Progs.
-func newProgs(fn *Node, worker int) *Progs {
+func newProgs(fn *ir.Node, worker int) *Progs {
        pp := new(Progs)
        if base.Ctxt.CanReuseProgs() {
                sz := len(sharedProgArray) / base.Flag.LowerC
@@ -173,17 +174,17 @@ func (pp *Progs) Appendpp(p *obj.Prog, as obj.As, ftype obj.AddrType, freg int16
        return q
 }
 
-func (pp *Progs) settext(fn *Node) {
+func (pp *Progs) settext(fn *ir.Node) {
        if pp.Text != nil {
                base.Fatalf("Progs.settext called twice")
        }
        ptxt := pp.Prog(obj.ATEXT)
        pp.Text = ptxt
 
-       fn.Func.lsym.Func().Text = ptxt
+       fn.Func.LSym.Func().Text = ptxt
        ptxt.From.Type = obj.TYPE_MEM
        ptxt.From.Name = obj.NAME_EXTERN
-       ptxt.From.Sym = fn.Func.lsym
+       ptxt.From.Sym = fn.Func.LSym
 }
 
 // initLSym defines f's obj.LSym and initializes it based on the
@@ -192,36 +193,36 @@ func (pp *Progs) settext(fn *Node) {
 //
 // initLSym must be called exactly once per function and must be
 // called for both functions with bodies and functions without bodies.
-func (f *Func) initLSym(hasBody bool) {
-       if f.lsym != nil {
+func initLSym(f *ir.Func, hasBody bool) {
+       if f.LSym != nil {
                base.Fatalf("Func.initLSym called twice")
        }
 
-       if nam := f.Nname; !nam.isBlank() {
-               f.lsym = nam.Sym.Linksym()
-               if f.Pragma&Systemstack != 0 {
-                       f.lsym.Set(obj.AttrCFunc, true)
+       if nam := f.Nname; !ir.IsBlank(nam) {
+               f.LSym = nam.Sym.Linksym()
+               if f.Pragma&ir.Systemstack != 0 {
+                       f.LSym.Set(obj.AttrCFunc, true)
                }
 
                var aliasABI obj.ABI
                needABIAlias := false
-               defABI, hasDefABI := symabiDefs[f.lsym.Name]
+               defABI, hasDefABI := symabiDefs[f.LSym.Name]
                if hasDefABI && defABI == obj.ABI0 {
                        // Symbol is defined as ABI0. Create an
                        // Internal -> ABI0 wrapper.
-                       f.lsym.SetABI(obj.ABI0)
+                       f.LSym.SetABI(obj.ABI0)
                        needABIAlias, aliasABI = true, obj.ABIInternal
                } else {
                        // No ABI override. Check that the symbol is
                        // using the expected ABI.
                        want := obj.ABIInternal
-                       if f.lsym.ABI() != want {
-                               base.Fatalf("function symbol %s has the wrong ABI %v, expected %v", f.lsym.Name, f.lsym.ABI(), want)
+                       if f.LSym.ABI() != want {
+                               base.Fatalf("function symbol %s has the wrong ABI %v, expected %v", f.LSym.Name, f.LSym.ABI(), want)
                        }
                }
 
                isLinknameExported := nam.Sym.Linkname != "" && (hasBody || hasDefABI)
-               if abi, ok := symabiRefs[f.lsym.Name]; (ok && abi == obj.ABI0) || isLinknameExported {
+               if abi, ok := symabiRefs[f.LSym.Name]; (ok && abi == obj.ABI0) || isLinknameExported {
                        // Either 1) this symbol is definitely
                        // referenced as ABI0 from this package; or 2)
                        // this symbol is defined in this package but
@@ -233,7 +234,7 @@ func (f *Func) initLSym(hasBody bool) {
                        // since other packages may "pull" symbols
                        // using linkname and we don't want to create
                        // duplicate ABI wrappers.
-                       if f.lsym.ABI() != obj.ABI0 {
+                       if f.LSym.ABI() != obj.ABI0 {
                                needABIAlias, aliasABI = true, obj.ABI0
                        }
                }
@@ -244,9 +245,9 @@ func (f *Func) initLSym(hasBody bool) {
                        // rather than looking them up. The uniqueness
                        // of f.lsym ensures uniqueness of asym.
                        asym := &obj.LSym{
-                               Name: f.lsym.Name,
+                               Name: f.LSym.Name,
                                Type: objabi.SABIALIAS,
-                               R:    []obj.Reloc{{Sym: f.lsym}}, // 0 size, so "informational"
+                               R:    []obj.Reloc{{Sym: f.LSym}}, // 0 size, so "informational"
                        }
                        asym.SetABI(aliasABI)
                        asym.Set(obj.AttrDuplicateOK, true)
@@ -269,7 +270,7 @@ func (f *Func) initLSym(hasBody bool) {
        if f.Needctxt() {
                flag |= obj.NEEDCTXT
        }
-       if f.Pragma&Nosplit != 0 {
+       if f.Pragma&ir.Nosplit != 0 {
                flag |= obj.NOSPLIT
        }
        if f.ReflectMethod() {
@@ -286,10 +287,10 @@ func (f *Func) initLSym(hasBody bool) {
                }
        }
 
-       base.Ctxt.InitTextSym(f.lsym, flag)
+       base.Ctxt.InitTextSym(f.LSym, flag)
 }
 
-func ggloblnod(nam *Node) {
+func ggloblnod(nam *ir.Node) {
        s := nam.Sym.Linksym()
        s.Gotype = ngotype(nam).Linksym()
        flags := 0
index 246a057ade1325701ea7fd5c31ad0d3c7b88d682..212db2184ed0c446ca0f261e767b94596438558f 100644 (file)
@@ -205,6 +205,7 @@ import (
        "bufio"
        "bytes"
        "cmd/compile/internal/base"
+       "cmd/compile/internal/ir"
        "cmd/compile/internal/types"
        "cmd/internal/goobj"
        "cmd/internal/src"
@@ -258,8 +259,8 @@ func iexport(out *bufio.Writer) {
        p := iexporter{
                allPkgs:     map[*types.Pkg]bool{},
                stringIndex: map[string]uint64{},
-               declIndex:   map[*Node]uint64{},
-               inlineIndex: map[*Node]uint64{},
+               declIndex:   map[*ir.Node]uint64{},
+               inlineIndex: map[*ir.Node]uint64{},
                typIndex:    map[*types.Type]uint64{},
        }
 
@@ -278,8 +279,8 @@ func iexport(out *bufio.Writer) {
        // Loop until no more work. We use a queue because while
        // writing out inline bodies, we may discover additional
        // declarations that are needed.
-       for !p.declTodo.empty() {
-               p.doDecl(p.declTodo.popLeft())
+       for !p.declTodo.Empty() {
+               p.doDecl(p.declTodo.PopLeft())
        }
 
        // Append indices to data0 section.
@@ -313,15 +314,15 @@ func iexport(out *bufio.Writer) {
 // we're writing out the main index, which is also read by
 // non-compiler tools and includes a complete package description
 // (i.e., name and height).
-func (w *exportWriter) writeIndex(index map[*Node]uint64, mainIndex bool) {
+func (w *exportWriter) writeIndex(index map[*ir.Node]uint64, mainIndex bool) {
        // Build a map from packages to objects from that package.
-       pkgObjs := map[*types.Pkg][]*Node{}
+       pkgObjs := map[*types.Pkg][]*ir.Node{}
 
        // For the main index, make sure to include every package that
        // we reference, even if we're not exporting (or reexporting)
        // any symbols from it.
        if mainIndex {
-               pkgObjs[localpkg] = nil
+               pkgObjs[ir.LocalPkg] = nil
                for pkg := range w.p.allPkgs {
                        pkgObjs[pkg] = nil
                }
@@ -367,14 +368,14 @@ type iexporter struct {
        // main index.
        allPkgs map[*types.Pkg]bool
 
-       declTodo nodeQueue
+       declTodo ir.NodeQueue
 
        strings     intWriter
        stringIndex map[string]uint64
 
        data0       intWriter
-       declIndex   map[*Node]uint64
-       inlineIndex map[*Node]uint64
+       declIndex   map[*ir.Node]uint64
+       inlineIndex map[*ir.Node]uint64
        typIndex    map[*types.Type]uint64
 }
 
@@ -393,13 +394,13 @@ func (p *iexporter) stringOff(s string) uint64 {
 }
 
 // pushDecl adds n to the declaration work queue, if not already present.
-func (p *iexporter) pushDecl(n *Node) {
-       if n.Sym == nil || asNode(n.Sym.Def) != n && n.Op != OTYPE {
+func (p *iexporter) pushDecl(n *ir.Node) {
+       if n.Sym == nil || ir.AsNode(n.Sym.Def) != n && n.Op != ir.OTYPE {
                base.Fatalf("weird Sym: %v, %v", n, n.Sym)
        }
 
        // Don't export predeclared declarations.
-       if n.Sym.Pkg == builtinpkg || n.Sym.Pkg == unsafepkg {
+       if n.Sym.Pkg == ir.BuiltinPkg || n.Sym.Pkg == unsafepkg {
                return
        }
 
@@ -408,7 +409,7 @@ func (p *iexporter) pushDecl(n *Node) {
        }
 
        p.declIndex[n] = ^uint64(0) // mark n present in work queue
-       p.declTodo.pushRight(n)
+       p.declTodo.PushRight(n)
 }
 
 // exportWriter handles writing out individual data section chunks.
@@ -422,22 +423,22 @@ type exportWriter struct {
        prevColumn int64
 }
 
-func (p *iexporter) doDecl(n *Node) {
+func (p *iexporter) doDecl(n *ir.Node) {
        w := p.newWriter()
        w.setPkg(n.Sym.Pkg, false)
 
        switch n.Op {
-       case ONAME:
+       case ir.ONAME:
                switch n.Class() {
-               case PEXTERN:
+               case ir.PEXTERN:
                        // Variable.
                        w.tag('V')
                        w.pos(n.Pos)
                        w.typ(n.Type)
                        w.varExt(n)
 
-               case PFUNC:
-                       if n.IsMethod() {
+               case ir.PFUNC:
+                       if ir.IsMethod(n) {
                                base.Fatalf("unexpected method: %v", n)
                        }
 
@@ -451,14 +452,14 @@ func (p *iexporter) doDecl(n *Node) {
                        base.Fatalf("unexpected class: %v, %v", n, n.Class())
                }
 
-       case OLITERAL:
+       case ir.OLITERAL:
                // Constant.
                n = typecheck(n, ctxExpr)
                w.tag('C')
                w.pos(n.Pos)
                w.value(n.Type, n.Val())
 
-       case OTYPE:
+       case ir.OTYPE:
                if IsAlias(n.Sym) {
                        // Alias.
                        w.tag('A')
@@ -514,11 +515,11 @@ func (w *exportWriter) tag(tag byte) {
        w.data.WriteByte(tag)
 }
 
-func (p *iexporter) doInline(f *Node) {
+func (p *iexporter) doInline(f *ir.Node) {
        w := p.newWriter()
        w.setPkg(fnpkg(f), false)
 
-       w.stmtList(asNodes(f.Func.Inl.Body))
+       w.stmtList(ir.AsNodes(f.Func.Inl.Body))
 
        p.inlineIndex[f] = w.flush()
 }
@@ -569,7 +570,7 @@ func (w *exportWriter) pkg(pkg *types.Pkg) {
        w.string(pkg.Path)
 }
 
-func (w *exportWriter) qualifiedIdent(n *Node) {
+func (w *exportWriter) qualifiedIdent(n *ir.Node) {
        // Ensure any referenced declarations are written out too.
        w.p.pushDecl(n)
 
@@ -592,7 +593,7 @@ func (w *exportWriter) selector(s *types.Sym) {
        } else {
                pkg := w.currPkg
                if types.IsExported(name) {
-                       pkg = localpkg
+                       pkg = ir.LocalPkg
                }
                if s.Pkg != pkg {
                        base.Fatalf("package mismatch in selector: %v in package %q, but want %q", s, s.Pkg.Path, pkg.Path)
@@ -633,7 +634,7 @@ func (w *exportWriter) startType(k itag) {
 
 func (w *exportWriter) doTyp(t *types.Type) {
        if t.Sym != nil {
-               if t.Sym.Pkg == builtinpkg || t.Sym.Pkg == unsafepkg {
+               if t.Sym.Pkg == ir.BuiltinPkg || t.Sym.Pkg == unsafepkg {
                        base.Fatalf("builtin type missing from typIndex: %v", t)
                }
 
@@ -643,35 +644,35 @@ func (w *exportWriter) doTyp(t *types.Type) {
        }
 
        switch t.Etype {
-       case TPTR:
+       case types.TPTR:
                w.startType(pointerType)
                w.typ(t.Elem())
 
-       case TSLICE:
+       case types.TSLICE:
                w.startType(sliceType)
                w.typ(t.Elem())
 
-       case TARRAY:
+       case types.TARRAY:
                w.startType(arrayType)
                w.uint64(uint64(t.NumElem()))
                w.typ(t.Elem())
 
-       case TCHAN:
+       case types.TCHAN:
                w.startType(chanType)
                w.uint64(uint64(t.ChanDir()))
                w.typ(t.Elem())
 
-       case TMAP:
+       case types.TMAP:
                w.startType(mapType)
                w.typ(t.Key())
                w.typ(t.Elem())
 
-       case TFUNC:
+       case types.TFUNC:
                w.startType(signatureType)
                w.setPkg(t.Pkg(), true)
                w.signature(t)
 
-       case TSTRUCT:
+       case types.TSTRUCT:
                w.startType(structType)
                w.setPkg(t.Pkg(), true)
 
@@ -684,7 +685,7 @@ func (w *exportWriter) doTyp(t *types.Type) {
                        w.string(f.Note)
                }
 
-       case TINTER:
+       case types.TINTER:
                var embeddeds, methods []*types.Field
                for _, m := range t.Methods().Slice() {
                        if m.Sym != nil {
@@ -719,7 +720,7 @@ func (w *exportWriter) setPkg(pkg *types.Pkg, write bool) {
        if pkg == nil {
                // TODO(mdempsky): Proactively set Pkg for types and
                // remove this fallback logic.
-               pkg = localpkg
+               pkg = ir.LocalPkg
        }
 
        if write {
@@ -746,7 +747,7 @@ func (w *exportWriter) paramList(fs []*types.Field) {
 
 func (w *exportWriter) param(f *types.Field) {
        w.pos(f.Pos)
-       w.localIdent(origSym(f.Sym), 0)
+       w.localIdent(ir.OrigSym(f.Sym), 0)
        w.typ(f.Type)
 }
 
@@ -761,16 +762,16 @@ func constTypeOf(typ *types.Type) constant.Kind {
        }
 
        switch typ.Etype {
-       case TBOOL:
+       case types.TBOOL:
                return constant.Bool
-       case TSTRING:
+       case types.TSTRING:
                return constant.String
-       case TINT, TINT8, TINT16, TINT32, TINT64,
-               TUINT, TUINT8, TUINT16, TUINT32, TUINT64, TUINTPTR:
+       case types.TINT, types.TINT8, types.TINT16, types.TINT32, types.TINT64,
+               types.TUINT, types.TUINT8, types.TUINT16, types.TUINT32, types.TUINT64, types.TUINTPTR:
                return constant.Int
-       case TFLOAT32, TFLOAT64:
+       case types.TFLOAT32, types.TFLOAT64:
                return constant.Float
-       case TCOMPLEX64, TCOMPLEX128:
+       case types.TCOMPLEX64, types.TCOMPLEX128:
                return constant.Complex
        }
 
@@ -779,7 +780,7 @@ func constTypeOf(typ *types.Type) constant.Kind {
 }
 
 func (w *exportWriter) value(typ *types.Type, v constant.Value) {
-       assertRepresents(typ, v)
+       ir.AssertValidTypeForConst(typ, v)
        w.typ(typ)
 
        // Each type has only one admissible constant representation,
@@ -808,9 +809,9 @@ func intSize(typ *types.Type) (signed bool, maxBytes uint) {
        }
 
        switch typ.Etype {
-       case TFLOAT32, TCOMPLEX64:
+       case types.TFLOAT32, types.TCOMPLEX64:
                return true, 3
-       case TFLOAT64, TCOMPLEX128:
+       case types.TFLOAT64, types.TCOMPLEX128:
                return true, 7
        }
 
@@ -820,7 +821,7 @@ func intSize(typ *types.Type) (signed bool, maxBytes uint) {
        // The go/types API doesn't expose sizes to importers, so they
        // don't know how big these types are.
        switch typ.Etype {
-       case TINT, TUINT, TUINTPTR:
+       case types.TINT, types.TUINT, types.TUINTPTR:
                maxBytes = 8
        }
 
@@ -954,12 +955,12 @@ func (w *exportWriter) string(s string) { w.uint64(w.p.stringOff(s)) }
 
 // Compiler-specific extensions.
 
-func (w *exportWriter) varExt(n *Node) {
+func (w *exportWriter) varExt(n *ir.Node) {
        w.linkname(n.Sym)
        w.symIdx(n.Sym)
 }
 
-func (w *exportWriter) funcExt(n *Node) {
+func (w *exportWriter) funcExt(n *ir.Node) {
        w.linkname(n.Sym)
        w.symIdx(n.Sym)
 
@@ -993,7 +994,7 @@ func (w *exportWriter) funcExt(n *Node) {
 
 func (w *exportWriter) methExt(m *types.Field) {
        w.bool(m.Nointerface())
-       w.funcExt(asNode(m.Nname))
+       w.funcExt(ir.AsNode(m.Nname))
 }
 
 func (w *exportWriter) linkname(s *types.Sym) {
@@ -1029,15 +1030,15 @@ func (w *exportWriter) typeExt(t *types.Type) {
 
 // Inline bodies.
 
-func (w *exportWriter) stmtList(list Nodes) {
+func (w *exportWriter) stmtList(list ir.Nodes) {
        for _, n := range list.Slice() {
                w.node(n)
        }
-       w.op(OEND)
+       w.op(ir.OEND)
 }
 
-func (w *exportWriter) node(n *Node) {
-       if opprec[n.Op] < 0 {
+func (w *exportWriter) node(n *ir.Node) {
+       if ir.OpPrec[n.Op] < 0 {
                w.stmt(n)
        } else {
                w.expr(n)
@@ -1046,8 +1047,8 @@ func (w *exportWriter) node(n *Node) {
 
 // Caution: stmt will emit more than one node for statement nodes n that have a non-empty
 // n.Ninit and where n cannot have a natural init section (such as in "if", "for", etc.).
-func (w *exportWriter) stmt(n *Node) {
-       if n.Ninit.Len() > 0 && !stmtwithinit(n.Op) {
+func (w *exportWriter) stmt(n *ir.Node) {
+       if n.Ninit.Len() > 0 && !ir.StmtWithInit(n.Op) {
                // can't use stmtList here since we don't want the final OEND
                for _, n := range n.Ninit.Slice() {
                        w.stmt(n)
@@ -1055,8 +1056,8 @@ func (w *exportWriter) stmt(n *Node) {
        }
 
        switch op := n.Op; op {
-       case ODCL:
-               w.op(ODCL)
+       case ir.ODCL:
+               w.op(ir.ODCL)
                w.pos(n.Left.Pos)
                w.localName(n.Left)
                w.typ(n.Left.Type)
@@ -1064,19 +1065,19 @@ func (w *exportWriter) stmt(n *Node) {
        // case ODCLFIELD:
        //      unimplemented - handled by default case
 
-       case OAS:
+       case ir.OAS:
                // Don't export "v = <N>" initializing statements, hope they're always
                // preceded by the DCL which will be re-parsed and typecheck to reproduce
                // the "v = <N>" again.
                if n.Right != nil {
-                       w.op(OAS)
+                       w.op(ir.OAS)
                        w.pos(n.Pos)
                        w.expr(n.Left)
                        w.expr(n.Right)
                }
 
-       case OASOP:
-               w.op(OASOP)
+       case ir.OASOP:
+               w.op(ir.OASOP)
                w.pos(n.Pos)
                w.op(n.SubOp())
                w.expr(n.Left)
@@ -1084,54 +1085,54 @@ func (w *exportWriter) stmt(n *Node) {
                        w.expr(n.Right)
                }
 
-       case OAS2:
-               w.op(OAS2)
+       case ir.OAS2:
+               w.op(ir.OAS2)
                w.pos(n.Pos)
                w.exprList(n.List)
                w.exprList(n.Rlist)
 
-       case OAS2DOTTYPE, OAS2FUNC, OAS2MAPR, OAS2RECV:
-               w.op(OAS2)
+       case ir.OAS2DOTTYPE, ir.OAS2FUNC, ir.OAS2MAPR, ir.OAS2RECV:
+               w.op(ir.OAS2)
                w.pos(n.Pos)
                w.exprList(n.List)
-               w.exprList(asNodes([]*Node{n.Right}))
+               w.exprList(ir.AsNodes([]*ir.Node{n.Right}))
 
-       case ORETURN:
-               w.op(ORETURN)
+       case ir.ORETURN:
+               w.op(ir.ORETURN)
                w.pos(n.Pos)
                w.exprList(n.List)
 
        // case ORETJMP:
        //      unreachable - generated by compiler for trampolin routines
 
-       case OGO, ODEFER:
+       case ir.OGO, ir.ODEFER:
                w.op(op)
                w.pos(n.Pos)
                w.expr(n.Left)
 
-       case OIF:
-               w.op(OIF)
+       case ir.OIF:
+               w.op(ir.OIF)
                w.pos(n.Pos)
                w.stmtList(n.Ninit)
                w.expr(n.Left)
                w.stmtList(n.Nbody)
                w.stmtList(n.Rlist)
 
-       case OFOR:
-               w.op(OFOR)
+       case ir.OFOR:
+               w.op(ir.OFOR)
                w.pos(n.Pos)
                w.stmtList(n.Ninit)
                w.exprsOrNil(n.Left, n.Right)
                w.stmtList(n.Nbody)
 
-       case ORANGE:
-               w.op(ORANGE)
+       case ir.ORANGE:
+               w.op(ir.ORANGE)
                w.pos(n.Pos)
                w.stmtList(n.List)
                w.expr(n.Right)
                w.stmtList(n.Nbody)
 
-       case OSELECT, OSWITCH:
+       case ir.OSELECT, ir.OSWITCH:
                w.op(op)
                w.pos(n.Pos)
                w.stmtList(n.Ninit)
@@ -1141,19 +1142,19 @@ func (w *exportWriter) stmt(n *Node) {
        // case OCASE:
        //      handled by caseList
 
-       case OFALL:
-               w.op(OFALL)
+       case ir.OFALL:
+               w.op(ir.OFALL)
                w.pos(n.Pos)
 
-       case OBREAK, OCONTINUE:
+       case ir.OBREAK, ir.OCONTINUE:
                w.op(op)
                w.pos(n.Pos)
                w.exprsOrNil(n.Left, nil)
 
-       case OEMPTY:
+       case ir.OEMPTY:
                // nothing to emit
 
-       case OGOTO, OLABEL:
+       case ir.OGOTO, ir.OLABEL:
                w.op(op)
                w.pos(n.Pos)
                w.string(n.Sym.Name)
@@ -1163,13 +1164,13 @@ func (w *exportWriter) stmt(n *Node) {
        }
 }
 
-func (w *exportWriter) caseList(sw *Node) {
-       namedTypeSwitch := sw.Op == OSWITCH && sw.Left != nil && sw.Left.Op == OTYPESW && sw.Left.Left != nil
+func (w *exportWriter) caseList(sw *ir.Node) {
+       namedTypeSwitch := sw.Op == ir.OSWITCH && sw.Left != nil && sw.Left.Op == ir.OTYPESW && sw.Left.Left != nil
 
        cases := sw.List.Slice()
        w.uint64(uint64(len(cases)))
        for _, cas := range cases {
-               if cas.Op != OCASE {
+               if cas.Op != ir.OCASE {
                        base.Fatalf("expected OCASE, got %v", cas)
                }
                w.pos(cas.Pos)
@@ -1181,14 +1182,14 @@ func (w *exportWriter) caseList(sw *Node) {
        }
 }
 
-func (w *exportWriter) exprList(list Nodes) {
+func (w *exportWriter) exprList(list ir.Nodes) {
        for _, n := range list.Slice() {
                w.expr(n)
        }
-       w.op(OEND)
+       w.op(ir.OEND)
 }
 
-func (w *exportWriter) expr(n *Node) {
+func (w *exportWriter) expr(n *ir.Node) {
        // from nodefmt (fmt.go)
        //
        // nodefmt reverts nodes back to their original - we don't need to do
@@ -1199,14 +1200,14 @@ func (w *exportWriter) expr(n *Node) {
        // }
 
        // from exprfmt (fmt.go)
-       for n.Op == OPAREN || n.Implicit() && (n.Op == ODEREF || n.Op == OADDR || n.Op == ODOT || n.Op == ODOTPTR) {
+       for n.Op == ir.OPAREN || n.Implicit() && (n.Op == ir.ODEREF || n.Op == ir.OADDR || n.Op == ir.ODOT || n.Op == ir.ODOTPTR) {
                n = n.Left
        }
 
        switch op := n.Op; op {
        // expressions
        // (somewhat closely following the structure of exprfmt in fmt.go)
-       case ONIL:
+       case ir.ONIL:
                if !n.Type.HasNil() {
                        base.Fatalf("unexpected type for nil: %v", n.Type)
                }
@@ -1214,49 +1215,49 @@ func (w *exportWriter) expr(n *Node) {
                        w.expr(n.Orig)
                        break
                }
-               w.op(OLITERAL)
+               w.op(ir.OLITERAL)
                w.pos(n.Pos)
                w.typ(n.Type)
 
-       case OLITERAL:
-               w.op(OLITERAL)
+       case ir.OLITERAL:
+               w.op(ir.OLITERAL)
                w.pos(n.Pos)
                w.value(n.Type, n.Val())
 
-       case OMETHEXPR:
+       case ir.OMETHEXPR:
                // Special case: explicit name of func (*T) method(...) is turned into pkg.(*T).method,
                // but for export, this should be rendered as (*pkg.T).meth.
                // These nodes have the special property that they are names with a left OTYPE and a right ONAME.
-               w.op(OXDOT)
+               w.op(ir.OXDOT)
                w.pos(n.Pos)
                w.expr(n.Left) // n.Left.Op == OTYPE
                w.selector(n.Right.Sym)
 
-       case ONAME:
+       case ir.ONAME:
                // Package scope name.
-               if (n.Class() == PEXTERN || n.Class() == PFUNC) && !n.isBlank() {
-                       w.op(ONONAME)
+               if (n.Class() == ir.PEXTERN || n.Class() == ir.PFUNC) && !ir.IsBlank(n) {
+                       w.op(ir.ONONAME)
                        w.qualifiedIdent(n)
                        break
                }
 
                // Function scope name.
-               w.op(ONAME)
+               w.op(ir.ONAME)
                w.localName(n)
 
        // case OPACK, ONONAME:
        //      should have been resolved by typechecking - handled by default case
 
-       case OTYPE:
-               w.op(OTYPE)
+       case ir.OTYPE:
+               w.op(ir.OTYPE)
                w.typ(n.Type)
 
-       case OTYPESW:
-               w.op(OTYPESW)
+       case ir.OTYPESW:
+               w.op(ir.OTYPESW)
                w.pos(n.Pos)
                var s *types.Sym
                if n.Left != nil {
-                       if n.Left.Op != ONONAME {
+                       if n.Left.Op != ir.ONONAME {
                                base.Fatalf("expected ONONAME, got %v", n.Left)
                        }
                        s = n.Left.Sym
@@ -1273,149 +1274,149 @@ func (w *exportWriter) expr(n *Node) {
        // case OCOMPLIT:
        //      should have been resolved by typechecking - handled by default case
 
-       case OPTRLIT:
-               w.op(OADDR)
+       case ir.OPTRLIT:
+               w.op(ir.OADDR)
                w.pos(n.Pos)
                w.expr(n.Left)
 
-       case OSTRUCTLIT:
-               w.op(OSTRUCTLIT)
+       case ir.OSTRUCTLIT:
+               w.op(ir.OSTRUCTLIT)
                w.pos(n.Pos)
                w.typ(n.Type)
                w.elemList(n.List) // special handling of field names
 
-       case OARRAYLIT, OSLICELIT, OMAPLIT:
-               w.op(OCOMPLIT)
+       case ir.OARRAYLIT, ir.OSLICELIT, ir.OMAPLIT:
+               w.op(ir.OCOMPLIT)
                w.pos(n.Pos)
                w.typ(n.Type)
                w.exprList(n.List)
 
-       case OKEY:
-               w.op(OKEY)
+       case ir.OKEY:
+               w.op(ir.OKEY)
                w.pos(n.Pos)
                w.exprsOrNil(n.Left, n.Right)
 
        // case OSTRUCTKEY:
        //      unreachable - handled in case OSTRUCTLIT by elemList
 
-       case OCALLPART:
+       case ir.OCALLPART:
                // An OCALLPART is an OXDOT before type checking.
-               w.op(OXDOT)
+               w.op(ir.OXDOT)
                w.pos(n.Pos)
                w.expr(n.Left)
                // Right node should be ONAME
                w.selector(n.Right.Sym)
 
-       case OXDOT, ODOT, ODOTPTR, ODOTINTER, ODOTMETH:
-               w.op(OXDOT)
+       case ir.OXDOT, ir.ODOT, ir.ODOTPTR, ir.ODOTINTER, ir.ODOTMETH:
+               w.op(ir.OXDOT)
                w.pos(n.Pos)
                w.expr(n.Left)
                w.selector(n.Sym)
 
-       case ODOTTYPE, ODOTTYPE2:
-               w.op(ODOTTYPE)
+       case ir.ODOTTYPE, ir.ODOTTYPE2:
+               w.op(ir.ODOTTYPE)
                w.pos(n.Pos)
                w.expr(n.Left)
                w.typ(n.Type)
 
-       case OINDEX, OINDEXMAP:
-               w.op(OINDEX)
+       case ir.OINDEX, ir.OINDEXMAP:
+               w.op(ir.OINDEX)
                w.pos(n.Pos)
                w.expr(n.Left)
                w.expr(n.Right)
 
-       case OSLICE, OSLICESTR, OSLICEARR:
-               w.op(OSLICE)
+       case ir.OSLICE, ir.OSLICESTR, ir.OSLICEARR:
+               w.op(ir.OSLICE)
                w.pos(n.Pos)
                w.expr(n.Left)
                low, high, _ := n.SliceBounds()
                w.exprsOrNil(low, high)
 
-       case OSLICE3, OSLICE3ARR:
-               w.op(OSLICE3)
+       case ir.OSLICE3, ir.OSLICE3ARR:
+               w.op(ir.OSLICE3)
                w.pos(n.Pos)
                w.expr(n.Left)
                low, high, max := n.SliceBounds()
                w.exprsOrNil(low, high)
                w.expr(max)
 
-       case OCOPY, OCOMPLEX:
+       case ir.OCOPY, ir.OCOMPLEX:
                // treated like other builtin calls (see e.g., OREAL)
                w.op(op)
                w.pos(n.Pos)
                w.expr(n.Left)
                w.expr(n.Right)
-               w.op(OEND)
+               w.op(ir.OEND)
 
-       case OCONV, OCONVIFACE, OCONVNOP, OBYTES2STR, ORUNES2STR, OSTR2BYTES, OSTR2RUNES, ORUNESTR:
-               w.op(OCONV)
+       case ir.OCONV, ir.OCONVIFACE, ir.OCONVNOP, ir.OBYTES2STR, ir.ORUNES2STR, ir.OSTR2BYTES, ir.OSTR2RUNES, ir.ORUNESTR:
+               w.op(ir.OCONV)
                w.pos(n.Pos)
                w.expr(n.Left)
                w.typ(n.Type)
 
-       case OREAL, OIMAG, OAPPEND, OCAP, OCLOSE, ODELETE, OLEN, OMAKE, ONEW, OPANIC, ORECOVER, OPRINT, OPRINTN:
+       case ir.OREAL, ir.OIMAG, ir.OAPPEND, ir.OCAP, ir.OCLOSE, ir.ODELETE, ir.OLEN, ir.OMAKE, ir.ONEW, ir.OPANIC, ir.ORECOVER, ir.OPRINT, ir.OPRINTN:
                w.op(op)
                w.pos(n.Pos)
                if n.Left != nil {
                        w.expr(n.Left)
-                       w.op(OEND)
+                       w.op(ir.OEND)
                } else {
                        w.exprList(n.List) // emits terminating OEND
                }
                // only append() calls may contain '...' arguments
-               if op == OAPPEND {
+               if op == ir.OAPPEND {
                        w.bool(n.IsDDD())
                } else if n.IsDDD() {
                        base.Fatalf("exporter: unexpected '...' with %v call", op)
                }
 
-       case OCALL, OCALLFUNC, OCALLMETH, OCALLINTER, OGETG:
-               w.op(OCALL)
+       case ir.OCALL, ir.OCALLFUNC, ir.OCALLMETH, ir.OCALLINTER, ir.OGETG:
+               w.op(ir.OCALL)
                w.pos(n.Pos)
                w.stmtList(n.Ninit)
                w.expr(n.Left)
                w.exprList(n.List)
                w.bool(n.IsDDD())
 
-       case OMAKEMAP, OMAKECHAN, OMAKESLICE:
+       case ir.OMAKEMAP, ir.OMAKECHAN, ir.OMAKESLICE:
                w.op(op) // must keep separate from OMAKE for importer
                w.pos(n.Pos)
                w.typ(n.Type)
                switch {
                default:
                        // empty list
-                       w.op(OEND)
+                       w.op(ir.OEND)
                case n.List.Len() != 0: // pre-typecheck
                        w.exprList(n.List) // emits terminating OEND
                case n.Right != nil:
                        w.expr(n.Left)
                        w.expr(n.Right)
-                       w.op(OEND)
-               case n.Left != nil && (n.Op == OMAKESLICE || !n.Left.Type.IsUntyped()):
+                       w.op(ir.OEND)
+               case n.Left != nil && (n.Op == ir.OMAKESLICE || !n.Left.Type.IsUntyped()):
                        w.expr(n.Left)
-                       w.op(OEND)
+                       w.op(ir.OEND)
                }
 
        // unary expressions
-       case OPLUS, ONEG, OADDR, OBITNOT, ODEREF, ONOT, ORECV:
+       case ir.OPLUS, ir.ONEG, ir.OADDR, ir.OBITNOT, ir.ODEREF, ir.ONOT, ir.ORECV:
                w.op(op)
                w.pos(n.Pos)
                w.expr(n.Left)
 
        // binary expressions
-       case OADD, OAND, OANDAND, OANDNOT, ODIV, OEQ, OGE, OGT, OLE, OLT,
-               OLSH, OMOD, OMUL, ONE, OOR, OOROR, ORSH, OSEND, OSUB, OXOR:
+       case ir.OADD, ir.OAND, ir.OANDAND, ir.OANDNOT, ir.ODIV, ir.OEQ, ir.OGE, ir.OGT, ir.OLE, ir.OLT,
+               ir.OLSH, ir.OMOD, ir.OMUL, ir.ONE, ir.OOR, ir.OOROR, ir.ORSH, ir.OSEND, ir.OSUB, ir.OXOR:
                w.op(op)
                w.pos(n.Pos)
                w.expr(n.Left)
                w.expr(n.Right)
 
-       case OADDSTR:
-               w.op(OADDSTR)
+       case ir.OADDSTR:
+               w.op(ir.OADDSTR)
                w.pos(n.Pos)
                w.exprList(n.List)
 
-       case ODCLCONST:
+       case ir.ODCLCONST:
                // if exporting, DCLCONST should just be removed as its usage
                // has already been replaced with literals
 
@@ -1425,11 +1426,11 @@ func (w *exportWriter) expr(n *Node) {
        }
 }
 
-func (w *exportWriter) op(op Op) {
+func (w *exportWriter) op(op ir.Op) {
        w.uint64(uint64(op))
 }
 
-func (w *exportWriter) exprsOrNil(a, b *Node) {
+func (w *exportWriter) exprsOrNil(a, b *ir.Node) {
        ab := 0
        if a != nil {
                ab |= 1
@@ -1446,7 +1447,7 @@ func (w *exportWriter) exprsOrNil(a, b *Node) {
        }
 }
 
-func (w *exportWriter) elemList(list Nodes) {
+func (w *exportWriter) elemList(list ir.Nodes) {
        w.uint64(uint64(list.Len()))
        for _, n := range list.Slice() {
                w.selector(n.Sym)
@@ -1454,7 +1455,7 @@ func (w *exportWriter) elemList(list Nodes) {
        }
 }
 
-func (w *exportWriter) localName(n *Node) {
+func (w *exportWriter) localName(n *ir.Node) {
        // Escape analysis happens after inline bodies are saved, but
        // we're using the same ONAME nodes, so we might still see
        // PAUTOHEAP here.
@@ -1463,7 +1464,7 @@ func (w *exportWriter) localName(n *Node) {
        // PPARAM/PPARAMOUT, because we only want to include vargen in
        // non-param names.
        var v int32
-       if n.Class() == PAUTO || (n.Class() == PAUTOHEAP && n.Name.Param.Stackcopy == nil) {
+       if n.Class() == ir.PAUTO || (n.Class() == ir.PAUTOHEAP && n.Name.Param.Stackcopy == nil) {
                v = n.Name.Vargen
        }
 
index cc0209ed03d72dee053c0c2aa2592909871e6d08..84386140bb9909b19497a8add46f1fdf528098b9 100644 (file)
@@ -9,6 +9,7 @@ package gc
 
 import (
        "cmd/compile/internal/base"
+       "cmd/compile/internal/ir"
        "cmd/compile/internal/types"
        "cmd/internal/bio"
        "cmd/internal/goobj"
@@ -40,8 +41,8 @@ var (
        inlineImporter = map[*types.Sym]iimporterAndOffset{}
 )
 
-func expandDecl(n *Node) {
-       if n.Op != ONONAME {
+func expandDecl(n *ir.Node) {
+       if n.Op != ir.ONONAME {
                return
        }
 
@@ -54,7 +55,7 @@ func expandDecl(n *Node) {
        r.doDecl(n)
 }
 
-func expandInline(fn *Node) {
+func expandInline(fn *ir.Node) {
        if fn.Func.Inl.Body != nil {
                return
        }
@@ -67,7 +68,7 @@ func expandInline(fn *Node) {
        r.doInline(fn)
 }
 
-func importReaderFor(n *Node, importers map[*types.Sym]iimporterAndOffset) *importReader {
+func importReaderFor(n *ir.Node, importers map[*types.Sym]iimporterAndOffset) *importReader {
        x, ok := importers[n.Sym]
        if !ok {
                return nil
@@ -147,10 +148,10 @@ func iimport(pkg *types.Pkg, in *bio.Reader) (fingerprint goobj.FingerprintType)
                if pkg.Name == "" {
                        pkg.Name = pkgName
                        pkg.Height = pkgHeight
-                       numImport[pkgName]++
+                       ir.NumImport[pkgName]++
 
                        // TODO(mdempsky): This belongs somewhere else.
-                       pkg.Lookup("_").Def = asTypesNode(nblank)
+                       pkg.Lookup("_").Def = ir.AsTypesNode(ir.BlankNode)
                } else {
                        if pkg.Name != pkgName {
                                base.Fatalf("conflicting package names %v and %v for path %q", pkg.Name, pkgName, pkg.Path)
@@ -172,9 +173,9 @@ func iimport(pkg *types.Pkg, in *bio.Reader) (fingerprint goobj.FingerprintType)
                        // Create stub declaration. If used, this will
                        // be overwritten by expandDecl.
                        if s.Def != nil {
-                               base.Fatalf("unexpected definition for %v: %v", s, asNode(s.Def))
+                               base.Fatalf("unexpected definition for %v: %v", s, ir.AsNode(s.Def))
                        }
-                       s.Def = asTypesNode(npos(src.NoXPos, dclname(s)))
+                       s.Def = ir.AsTypesNode(npos(src.NoXPos, dclname(s)))
                }
        }
 
@@ -280,8 +281,8 @@ func (r *importReader) setPkg() {
        r.currPkg = r.pkg()
 }
 
-func (r *importReader) doDecl(n *Node) {
-       if n.Op != ONONAME {
+func (r *importReader) doDecl(n *ir.Node) {
+       if n.Op != ir.ONONAME {
                base.Fatalf("doDecl: unexpected Op for %v: %v", n.Sym, n.Op)
        }
 
@@ -330,13 +331,13 @@ func (r *importReader) doDecl(n *Node) {
                        recv := r.param()
                        mtyp := r.signature(recv)
 
-                       m := newfuncnamel(mpos, methodSym(recv.Type, msym), new(Func))
+                       m := newfuncnamel(mpos, methodSym(recv.Type, msym), new(ir.Func))
                        m.Type = mtyp
-                       m.SetClass(PFUNC)
+                       m.SetClass(ir.PFUNC)
                        // methodSym already marked m.Sym as a function.
 
                        f := types.NewField(mpos, msym, mtyp)
-                       f.Nname = asTypesNode(m)
+                       f.Nname = ir.AsTypesNode(m)
                        ms[i] = f
                }
                t.Methods().Set(ms)
@@ -434,7 +435,7 @@ func (r *importReader) ident() *types.Sym {
        }
        pkg := r.currPkg
        if types.IsExported(name) {
-               pkg = localpkg
+               pkg = ir.LocalPkg
        }
        return pkg.Lookup(name)
 }
@@ -498,11 +499,11 @@ func (r *importReader) typ1() *types.Type {
                // support inlining functions with local defined
                // types. Therefore, this must be a package-scope
                // type.
-               n := asNode(r.qualifiedIdent().PkgDef())
-               if n.Op == ONONAME {
+               n := ir.AsNode(r.qualifiedIdent().PkgDef())
+               if n.Op == ir.ONONAME {
                        expandDecl(n)
                }
-               if n.Op != OTYPE {
+               if n.Op != ir.OTYPE {
                        base.Fatalf("expected OTYPE, got %v: %v, %v", n.Op, n.Sym, n)
                }
                return n.Type
@@ -542,7 +543,7 @@ func (r *importReader) typ1() *types.Type {
                        fs[i] = f
                }
 
-               t := types.New(TSTRUCT)
+               t := types.New(types.TSTRUCT)
                t.SetPkg(r.currPkg)
                t.SetFields(fs)
                return t
@@ -567,7 +568,7 @@ func (r *importReader) typ1() *types.Type {
                        methods[i] = types.NewField(pos, sym, typ)
                }
 
-               t := types.New(TINTER)
+               t := types.New(types.TINTER)
                t.SetPkg(r.currPkg)
                t.SetInterface(append(embeddeds, methods...))
 
@@ -634,12 +635,12 @@ func (r *importReader) byte() byte {
 
 // Compiler-specific extensions.
 
-func (r *importReader) varExt(n *Node) {
+func (r *importReader) varExt(n *ir.Node) {
        r.linkname(n.Sym)
        r.symIdx(n.Sym)
 }
 
-func (r *importReader) funcExt(n *Node) {
+func (r *importReader) funcExt(n *ir.Node) {
        r.linkname(n.Sym)
        r.symIdx(n.Sym)
 
@@ -652,7 +653,7 @@ func (r *importReader) funcExt(n *Node) {
 
        // Inline body.
        if u := r.uint64(); u > 0 {
-               n.Func.Inl = &Inline{
+               n.Func.Inl = &ir.Inline{
                        Cost: int32(u - 1),
                }
                n.Func.Endlineno = r.pos()
@@ -663,7 +664,7 @@ func (r *importReader) methExt(m *types.Field) {
        if r.bool() {
                m.SetNointerface(true)
        }
-       r.funcExt(asNode(m.Nname))
+       r.funcExt(ir.AsNode(m.Nname))
 }
 
 func (r *importReader) linkname(s *types.Sym) {
@@ -694,7 +695,7 @@ func (r *importReader) typeExt(t *types.Type) {
 // so we can use index to reference the symbol.
 var typeSymIdx = make(map[*types.Type][2]int64)
 
-func (r *importReader) doInline(n *Node) {
+func (r *importReader) doInline(n *ir.Node) {
        if len(n.Func.Inl.Body) != 0 {
                base.Fatalf("%v already has inline body", n)
        }
@@ -709,7 +710,7 @@ func (r *importReader) doInline(n *Node) {
                // (not doing so can cause significant performance
                // degradation due to unnecessary calls to empty
                // functions).
-               body = []*Node{}
+               body = []*ir.Node{}
        }
        n.Func.Inl.Body = body
 
@@ -717,9 +718,9 @@ func (r *importReader) doInline(n *Node) {
 
        if base.Flag.E > 0 && base.Flag.LowerM > 2 {
                if base.Flag.LowerM > 3 {
-                       fmt.Printf("inl body for %v %#v: %+v\n", n, n.Type, asNodes(n.Func.Inl.Body))
+                       fmt.Printf("inl body for %v %#v: %+v\n", n, n.Type, ir.AsNodes(n.Func.Inl.Body))
                } else {
-                       fmt.Printf("inl body for %v %#v: %v\n", n, n.Type, asNodes(n.Func.Inl.Body))
+                       fmt.Printf("inl body for %v %#v: %v\n", n, n.Type, ir.AsNodes(n.Func.Inl.Body))
                }
        }
 }
@@ -739,15 +740,15 @@ func (r *importReader) doInline(n *Node) {
 // unrefined nodes (since this is what the importer uses). The respective case
 // entries are unreachable in the importer.
 
-func (r *importReader) stmtList() []*Node {
-       var list []*Node
+func (r *importReader) stmtList() []*ir.Node {
+       var list []*ir.Node
        for {
                n := r.node()
                if n == nil {
                        break
                }
                // OBLOCK nodes may be created when importing ODCL nodes - unpack them
-               if n.Op == OBLOCK {
+               if n.Op == ir.OBLOCK {
                        list = append(list, n.List.Slice()...)
                } else {
                        list = append(list, n)
@@ -757,18 +758,18 @@ func (r *importReader) stmtList() []*Node {
        return list
 }
 
-func (r *importReader) caseList(sw *Node) []*Node {
-       namedTypeSwitch := sw.Op == OSWITCH && sw.Left != nil && sw.Left.Op == OTYPESW && sw.Left.Left != nil
+func (r *importReader) caseList(sw *ir.Node) []*ir.Node {
+       namedTypeSwitch := sw.Op == ir.OSWITCH && sw.Left != nil && sw.Left.Op == ir.OTYPESW && sw.Left.Left != nil
 
-       cases := make([]*Node, r.uint64())
+       cases := make([]*ir.Node, r.uint64())
        for i := range cases {
-               cas := nodl(r.pos(), OCASE, nil, nil)
+               cas := ir.NodAt(r.pos(), ir.OCASE, nil, nil)
                cas.List.Set(r.stmtList())
                if namedTypeSwitch {
                        // Note: per-case variables will have distinct, dotted
                        // names after import. That's okay: swt.go only needs
                        // Sym for diagnostics anyway.
-                       caseVar := newnamel(cas.Pos, r.ident())
+                       caseVar := ir.NewNameAt(cas.Pos, r.ident())
                        declare(caseVar, dclcontext)
                        cas.Rlist.Set1(caseVar)
                        caseVar.Name.Defn = sw.Left
@@ -779,8 +780,8 @@ func (r *importReader) caseList(sw *Node) []*Node {
        return cases
 }
 
-func (r *importReader) exprList() []*Node {
-       var list []*Node
+func (r *importReader) exprList() []*ir.Node {
+       var list []*ir.Node
        for {
                n := r.expr()
                if n == nil {
@@ -791,16 +792,16 @@ func (r *importReader) exprList() []*Node {
        return list
 }
 
-func (r *importReader) expr() *Node {
+func (r *importReader) expr() *ir.Node {
        n := r.node()
-       if n != nil && n.Op == OBLOCK {
+       if n != nil && n.Op == ir.OBLOCK {
                base.Fatalf("unexpected block node: %v", n)
        }
        return n
 }
 
 // TODO(gri) split into expr and stmt
-func (r *importReader) node() *Node {
+func (r *importReader) node() *ir.Node {
        switch op := r.op(); op {
        // expressions
        // case OPAREN:
@@ -809,34 +810,34 @@ func (r *importReader) node() *Node {
        // case ONIL:
        //      unreachable - mapped to OLITERAL
 
-       case OLITERAL:
+       case ir.OLITERAL:
                pos := r.pos()
                typ := r.typ()
 
-               var n *Node
+               var n *ir.Node
                if typ.HasNil() {
                        n = nodnil()
                } else {
-                       n = nodlit(r.value(typ))
+                       n = ir.NewLiteral(r.value(typ))
                }
                n = npos(pos, n)
                n.Type = typ
                return n
 
-       case ONONAME:
+       case ir.ONONAME:
                return mkname(r.qualifiedIdent())
 
-       case ONAME:
+       case ir.ONAME:
                return mkname(r.ident())
 
        // case OPACK, ONONAME:
        //      unreachable - should have been resolved by typechecking
 
-       case OTYPE:
+       case ir.OTYPE:
                return typenod(r.typ())
 
-       case OTYPESW:
-               n := nodl(r.pos(), OTYPESW, nil, nil)
+       case ir.OTYPESW:
+               n := ir.NodAt(r.pos(), ir.OTYPESW, nil, nil)
                if s := r.ident(); s != nil {
                        n.Left = npos(n.Pos, newnoname(s))
                }
@@ -853,11 +854,11 @@ func (r *importReader) node() *Node {
        // case OPTRLIT:
        //      unreachable - mapped to case OADDR below by exporter
 
-       case OSTRUCTLIT:
+       case ir.OSTRUCTLIT:
                // TODO(mdempsky): Export position information for OSTRUCTKEY nodes.
                savedlineno := base.Pos
                base.Pos = r.pos()
-               n := nodl(base.Pos, OCOMPLIT, nil, typenod(r.typ()))
+               n := ir.NodAt(base.Pos, ir.OCOMPLIT, nil, typenod(r.typ()))
                n.List.Set(r.elemList()) // special handling of field names
                base.Pos = savedlineno
                return n
@@ -865,15 +866,15 @@ func (r *importReader) node() *Node {
        // case OARRAYLIT, OSLICELIT, OMAPLIT:
        //      unreachable - mapped to case OCOMPLIT below by exporter
 
-       case OCOMPLIT:
-               n := nodl(r.pos(), OCOMPLIT, nil, typenod(r.typ()))
+       case ir.OCOMPLIT:
+               n := ir.NodAt(r.pos(), ir.OCOMPLIT, nil, typenod(r.typ()))
                n.List.Set(r.exprList())
                return n
 
-       case OKEY:
+       case ir.OKEY:
                pos := r.pos()
                left, right := r.exprsOrNil()
-               return nodl(pos, OKEY, left, right)
+               return ir.NodAt(pos, ir.OKEY, left, right)
 
        // case OSTRUCTKEY:
        //      unreachable - handled in case OSTRUCTLIT by elemList
@@ -884,28 +885,28 @@ func (r *importReader) node() *Node {
        // case OXDOT, ODOT, ODOTPTR, ODOTINTER, ODOTMETH:
        //      unreachable - mapped to case OXDOT below by exporter
 
-       case OXDOT:
+       case ir.OXDOT:
                // see parser.new_dotname
-               return npos(r.pos(), nodSym(OXDOT, r.expr(), r.ident()))
+               return npos(r.pos(), nodSym(ir.OXDOT, r.expr(), r.ident()))
 
        // case ODOTTYPE, ODOTTYPE2:
        //      unreachable - mapped to case ODOTTYPE below by exporter
 
-       case ODOTTYPE:
-               n := nodl(r.pos(), ODOTTYPE, r.expr(), nil)
+       case ir.ODOTTYPE:
+               n := ir.NodAt(r.pos(), ir.ODOTTYPE, r.expr(), nil)
                n.Type = r.typ()
                return n
 
        // case OINDEX, OINDEXMAP, OSLICE, OSLICESTR, OSLICEARR, OSLICE3, OSLICE3ARR:
        //      unreachable - mapped to cases below by exporter
 
-       case OINDEX:
-               return nodl(r.pos(), op, r.expr(), r.expr())
+       case ir.OINDEX:
+               return ir.NodAt(r.pos(), op, r.expr(), r.expr())
 
-       case OSLICE, OSLICE3:
-               n := nodl(r.pos(), op, r.expr(), nil)
+       case ir.OSLICE, ir.OSLICE3:
+               n := ir.NodAt(r.pos(), op, r.expr(), nil)
                low, high := r.exprsOrNil()
-               var max *Node
+               var max *ir.Node
                if n.Op.IsSlice3() {
                        max = r.expr()
                }
@@ -915,15 +916,15 @@ func (r *importReader) node() *Node {
        // case OCONV, OCONVIFACE, OCONVNOP, OBYTES2STR, ORUNES2STR, OSTR2BYTES, OSTR2RUNES, ORUNESTR:
        //      unreachable - mapped to OCONV case below by exporter
 
-       case OCONV:
-               n := nodl(r.pos(), OCONV, r.expr(), nil)
+       case ir.OCONV:
+               n := ir.NodAt(r.pos(), ir.OCONV, r.expr(), nil)
                n.Type = r.typ()
                return n
 
-       case OCOPY, OCOMPLEX, OREAL, OIMAG, OAPPEND, OCAP, OCLOSE, ODELETE, OLEN, OMAKE, ONEW, OPANIC, ORECOVER, OPRINT, OPRINTN:
+       case ir.OCOPY, ir.OCOMPLEX, ir.OREAL, ir.OIMAG, ir.OAPPEND, ir.OCAP, ir.OCLOSE, ir.ODELETE, ir.OLEN, ir.OMAKE, ir.ONEW, ir.OPANIC, ir.ORECOVER, ir.OPRINT, ir.OPRINTN:
                n := npos(r.pos(), builtinCall(op))
                n.List.Set(r.exprList())
-               if op == OAPPEND {
+               if op == ir.OAPPEND {
                        n.SetIsDDD(r.bool())
                }
                return n
@@ -931,45 +932,45 @@ func (r *importReader) node() *Node {
        // case OCALL, OCALLFUNC, OCALLMETH, OCALLINTER, OGETG:
        //      unreachable - mapped to OCALL case below by exporter
 
-       case OCALL:
-               n := nodl(r.pos(), OCALL, nil, nil)
+       case ir.OCALL:
+               n := ir.NodAt(r.pos(), ir.OCALL, nil, nil)
                n.Ninit.Set(r.stmtList())
                n.Left = r.expr()
                n.List.Set(r.exprList())
                n.SetIsDDD(r.bool())
                return n
 
-       case OMAKEMAP, OMAKECHAN, OMAKESLICE:
-               n := npos(r.pos(), builtinCall(OMAKE))
+       case ir.OMAKEMAP, ir.OMAKECHAN, ir.OMAKESLICE:
+               n := npos(r.pos(), builtinCall(ir.OMAKE))
                n.List.Append(typenod(r.typ()))
                n.List.Append(r.exprList()...)
                return n
 
        // unary expressions
-       case OPLUS, ONEG, OADDR, OBITNOT, ODEREF, ONOT, ORECV:
-               return nodl(r.pos(), op, r.expr(), nil)
+       case ir.OPLUS, ir.ONEG, ir.OADDR, ir.OBITNOT, ir.ODEREF, ir.ONOT, ir.ORECV:
+               return ir.NodAt(r.pos(), op, r.expr(), nil)
 
        // binary expressions
-       case OADD, OAND, OANDAND, OANDNOT, ODIV, OEQ, OGE, OGT, OLE, OLT,
-               OLSH, OMOD, OMUL, ONE, OOR, OOROR, ORSH, OSEND, OSUB, OXOR:
-               return nodl(r.pos(), op, r.expr(), r.expr())
+       case ir.OADD, ir.OAND, ir.OANDAND, ir.OANDNOT, ir.ODIV, ir.OEQ, ir.OGE, ir.OGT, ir.OLE, ir.OLT,
+               ir.OLSH, ir.OMOD, ir.OMUL, ir.ONE, ir.OOR, ir.OOROR, ir.ORSH, ir.OSEND, ir.OSUB, ir.OXOR:
+               return ir.NodAt(r.pos(), op, r.expr(), r.expr())
 
-       case OADDSTR:
+       case ir.OADDSTR:
                pos := r.pos()
                list := r.exprList()
                x := npos(pos, list[0])
                for _, y := range list[1:] {
-                       x = nodl(pos, OADD, x, y)
+                       x = ir.NodAt(pos, ir.OADD, x, y)
                }
                return x
 
        // --------------------------------------------------------------------
        // statements
-       case ODCL:
+       case ir.ODCL:
                pos := r.pos()
                lhs := npos(pos, dclname(r.ident()))
                typ := typenod(r.typ())
-               return npos(pos, liststmt(variter([]*Node{lhs}, typ, nil))) // TODO(gri) avoid list creation
+               return npos(pos, liststmt(variter([]*ir.Node{lhs}, typ, nil))) // TODO(gri) avoid list creation
 
        // case ODCLFIELD:
        //      unimplemented
@@ -977,11 +978,11 @@ func (r *importReader) node() *Node {
        // case OAS, OASWB:
        //      unreachable - mapped to OAS case below by exporter
 
-       case OAS:
-               return nodl(r.pos(), OAS, r.expr(), r.expr())
+       case ir.OAS:
+               return ir.NodAt(r.pos(), ir.OAS, r.expr(), r.expr())
 
-       case OASOP:
-               n := nodl(r.pos(), OASOP, nil, nil)
+       case ir.OASOP:
+               n := ir.NodAt(r.pos(), ir.OASOP, nil, nil)
                n.SetSubOp(r.op())
                n.Left = r.expr()
                if !r.bool() {
@@ -995,33 +996,33 @@ func (r *importReader) node() *Node {
        // case OAS2DOTTYPE, OAS2FUNC, OAS2MAPR, OAS2RECV:
        //      unreachable - mapped to OAS2 case below by exporter
 
-       case OAS2:
-               n := nodl(r.pos(), OAS2, nil, nil)
+       case ir.OAS2:
+               n := ir.NodAt(r.pos(), ir.OAS2, nil, nil)
                n.List.Set(r.exprList())
                n.Rlist.Set(r.exprList())
                return n
 
-       case ORETURN:
-               n := nodl(r.pos(), ORETURN, nil, nil)
+       case ir.ORETURN:
+               n := ir.NodAt(r.pos(), ir.ORETURN, nil, nil)
                n.List.Set(r.exprList())
                return n
 
        // case ORETJMP:
        //      unreachable - generated by compiler for trampolin routines (not exported)
 
-       case OGO, ODEFER:
-               return nodl(r.pos(), op, r.expr(), nil)
+       case ir.OGO, ir.ODEFER:
+               return ir.NodAt(r.pos(), op, r.expr(), nil)
 
-       case OIF:
-               n := nodl(r.pos(), OIF, nil, nil)
+       case ir.OIF:
+               n := ir.NodAt(r.pos(), ir.OIF, nil, nil)
                n.Ninit.Set(r.stmtList())
                n.Left = r.expr()
                n.Nbody.Set(r.stmtList())
                n.Rlist.Set(r.stmtList())
                return n
 
-       case OFOR:
-               n := nodl(r.pos(), OFOR, nil, nil)
+       case ir.OFOR:
+               n := ir.NodAt(r.pos(), ir.OFOR, nil, nil)
                n.Ninit.Set(r.stmtList())
                left, right := r.exprsOrNil()
                n.Left = left
@@ -1029,15 +1030,15 @@ func (r *importReader) node() *Node {
                n.Nbody.Set(r.stmtList())
                return n
 
-       case ORANGE:
-               n := nodl(r.pos(), ORANGE, nil, nil)
+       case ir.ORANGE:
+               n := ir.NodAt(r.pos(), ir.ORANGE, nil, nil)
                n.List.Set(r.stmtList())
                n.Right = r.expr()
                n.Nbody.Set(r.stmtList())
                return n
 
-       case OSELECT, OSWITCH:
-               n := nodl(r.pos(), op, nil, nil)
+       case ir.OSELECT, ir.OSWITCH:
+               n := ir.NodAt(r.pos(), op, nil, nil)
                n.Ninit.Set(r.stmtList())
                left, _ := r.exprsOrNil()
                n.Left = left
@@ -1047,27 +1048,27 @@ func (r *importReader) node() *Node {
        // case OCASE:
        //      handled by caseList
 
-       case OFALL:
-               n := nodl(r.pos(), OFALL, nil, nil)
+       case ir.OFALL:
+               n := ir.NodAt(r.pos(), ir.OFALL, nil, nil)
                return n
 
-       case OBREAK, OCONTINUE:
+       case ir.OBREAK, ir.OCONTINUE:
                pos := r.pos()
                left, _ := r.exprsOrNil()
                if left != nil {
-                       left = newname(left.Sym)
+                       left = NewName(left.Sym)
                }
-               return nodl(pos, op, left, nil)
+               return ir.NodAt(pos, op, left, nil)
 
        // case OEMPTY:
        //      unreachable - not emitted by exporter
 
-       case OGOTO, OLABEL:
-               n := nodl(r.pos(), op, nil, nil)
+       case ir.OGOTO, ir.OLABEL:
+               n := ir.NodAt(r.pos(), op, nil, nil)
                n.Sym = lookup(r.string())
                return n
 
-       case OEND:
+       case ir.OEND:
                return nil
 
        default:
@@ -1077,21 +1078,21 @@ func (r *importReader) node() *Node {
        }
 }
 
-func (r *importReader) op() Op {
-       return Op(r.uint64())
+func (r *importReader) op() ir.Op {
+       return ir.Op(r.uint64())
 }
 
-func (r *importReader) elemList() []*Node {
+func (r *importReader) elemList() []*ir.Node {
        c := r.uint64()
-       list := make([]*Node, c)
+       list := make([]*ir.Node, c)
        for i := range list {
                s := r.ident()
-               list[i] = nodSym(OSTRUCTKEY, r.expr(), s)
+               list[i] = nodSym(ir.OSTRUCTKEY, r.expr(), s)
        }
        return list
 }
 
-func (r *importReader) exprsOrNil() (a, b *Node) {
+func (r *importReader) exprsOrNil() (a, b *ir.Node) {
        ab := r.uint64()
        if ab&1 != 0 {
                a = r.expr()
index 9319faf6a015d886ebcdb857306ed27fbae699ef..f3c302f6bee2622a6c77335479433643bcfc4b1a 100644 (file)
@@ -6,6 +6,7 @@ package gc
 
 import (
        "cmd/compile/internal/base"
+       "cmd/compile/internal/ir"
        "cmd/compile/internal/types"
        "cmd/internal/obj"
 )
@@ -18,7 +19,7 @@ var renameinitgen int
 
 // Function collecting autotmps generated during typechecking,
 // to be included in the package-level init function.
-var initTodo = nod(ODCLFUNC, nil, nil)
+var initTodo = ir.Nod(ir.ODCLFUNC, nil, nil)
 
 func renameinit() *types.Sym {
        s := lookupN("init.", renameinitgen)
@@ -32,7 +33,7 @@ func renameinit() *types.Sym {
 //   1) Initialize all of the packages the current package depends on.
 //   2) Initialize all the variables that have initializers.
 //   3) Run any init functions.
-func fninit(n []*Node) {
+func fninit(n []*ir.Node) {
        nf := initOrder(n)
 
        var deps []*obj.LSym // initTask records for packages the current package depends on
@@ -47,7 +48,7 @@ func fninit(n []*Node) {
        if len(nf) > 0 {
                base.Pos = nf[0].Pos // prolog/epilog gets line number of first init stmt
                initializers := lookup("init")
-               fn := dclfunc(initializers, nod(OTFUNC, nil, nil))
+               fn := dclfunc(initializers, ir.Nod(ir.OTFUNC, nil, nil))
                for _, dcl := range initTodo.Func.Dcl {
                        dcl.Name.Curfn = fn
                }
@@ -75,24 +76,24 @@ func fninit(n []*Node) {
        // Record user init functions.
        for i := 0; i < renameinitgen; i++ {
                s := lookupN("init.", i)
-               fn := asNode(s.Def).Name.Defn
+               fn := ir.AsNode(s.Def).Name.Defn
                // Skip init functions with empty bodies.
-               if fn.Nbody.Len() == 1 && fn.Nbody.First().Op == OEMPTY {
+               if fn.Nbody.Len() == 1 && fn.Nbody.First().Op == ir.OEMPTY {
                        continue
                }
                fns = append(fns, s.Linksym())
        }
 
-       if len(deps) == 0 && len(fns) == 0 && localpkg.Name != "main" && localpkg.Name != "runtime" {
+       if len(deps) == 0 && len(fns) == 0 && ir.LocalPkg.Name != "main" && ir.LocalPkg.Name != "runtime" {
                return // nothing to initialize
        }
 
        // Make an .inittask structure.
        sym := lookup(".inittask")
-       nn := newname(sym)
-       nn.Type = types.Types[TUINT8] // fake type
-       nn.SetClass(PEXTERN)
-       sym.Def = asTypesNode(nn)
+       nn := NewName(sym)
+       nn.Type = types.Types[types.TUINT8] // fake type
+       nn.SetClass(ir.PEXTERN)
+       sym.Def = ir.AsTypesNode(nn)
        exportsym(nn)
        lsym := sym.Linksym()
        ot := 0
index f553a3f057b609893144ce086974e138b3465ba9..942cb95f2077b535456956712d839cc9b855bfb7 100644 (file)
@@ -10,6 +10,8 @@ import (
        "fmt"
 
        "cmd/compile/internal/base"
+       "cmd/compile/internal/ir"
+       "cmd/compile/internal/types"
 )
 
 // Package initialization
@@ -62,7 +64,7 @@ const (
 type InitOrder struct {
        // blocking maps initialization assignments to the assignments
        // that depend on it.
-       blocking map[*Node][]*Node
+       blocking map[*ir.Node][]*ir.Node
 
        // ready is the queue of Pending initialization assignments
        // that are ready for initialization.
@@ -73,22 +75,22 @@ type InitOrder struct {
 // package-level declarations (in declaration order) and outputs the
 // corresponding list of statements to include in the init() function
 // body.
-func initOrder(l []*Node) []*Node {
+func initOrder(l []*ir.Node) []*ir.Node {
        s := InitSchedule{
-               initplans: make(map[*Node]*InitPlan),
-               inittemps: make(map[*Node]*Node),
+               initplans: make(map[*ir.Node]*InitPlan),
+               inittemps: make(map[*ir.Node]*ir.Node),
        }
        o := InitOrder{
-               blocking: make(map[*Node][]*Node),
+               blocking: make(map[*ir.Node][]*ir.Node),
        }
 
        // Process all package-level assignment in declaration order.
        for _, n := range l {
                switch n.Op {
-               case OAS, OAS2DOTTYPE, OAS2FUNC, OAS2MAPR, OAS2RECV:
+               case ir.OAS, ir.OAS2DOTTYPE, ir.OAS2FUNC, ir.OAS2MAPR, ir.OAS2RECV:
                        o.processAssign(n)
                        o.flushReady(s.staticInit)
-               case ODCLCONST, ODCLFUNC, ODCLTYPE:
+               case ir.ODCLCONST, ir.ODCLFUNC, ir.ODCLTYPE:
                        // nop
                default:
                        base.Fatalf("unexpected package-level statement: %v", n)
@@ -99,7 +101,7 @@ func initOrder(l []*Node) []*Node {
        // have been a dependency cycle.
        for _, n := range l {
                switch n.Op {
-               case OAS, OAS2DOTTYPE, OAS2FUNC, OAS2MAPR, OAS2RECV:
+               case ir.OAS, ir.OAS2DOTTYPE, ir.OAS2FUNC, ir.OAS2MAPR, ir.OAS2RECV:
                        if n.Initorder() != InitDone {
                                // If there have already been errors
                                // printed, those errors may have
@@ -108,7 +110,7 @@ func initOrder(l []*Node) []*Node {
                                // first.
                                base.ExitIfErrors()
 
-                               findInitLoopAndExit(firstLHS(n), new([]*Node))
+                               findInitLoopAndExit(firstLHS(n), new([]*ir.Node))
                                base.Fatalf("initialization unfinished, but failed to identify loop")
                        }
                }
@@ -123,8 +125,8 @@ func initOrder(l []*Node) []*Node {
        return s.out
 }
 
-func (o *InitOrder) processAssign(n *Node) {
-       if n.Initorder() != InitNotStarted || n.Xoffset != BADWIDTH {
+func (o *InitOrder) processAssign(n *ir.Node) {
+       if n.Initorder() != InitNotStarted || n.Xoffset != types.BADWIDTH {
                base.Fatalf("unexpected state: %v, %v, %v", n, n.Initorder(), n.Xoffset)
        }
 
@@ -137,7 +139,7 @@ func (o *InitOrder) processAssign(n *Node) {
                defn := dep.Name.Defn
                // Skip dependencies on functions (PFUNC) and
                // variables already initialized (InitDone).
-               if dep.Class() != PEXTERN || defn.Initorder() == InitDone {
+               if dep.Class() != ir.PEXTERN || defn.Initorder() == InitDone {
                        continue
                }
                n.Xoffset++
@@ -152,16 +154,16 @@ func (o *InitOrder) processAssign(n *Node) {
 // flushReady repeatedly applies initialize to the earliest (in
 // declaration order) assignment ready for initialization and updates
 // the inverse dependency ("blocking") graph.
-func (o *InitOrder) flushReady(initialize func(*Node)) {
+func (o *InitOrder) flushReady(initialize func(*ir.Node)) {
        for o.ready.Len() != 0 {
-               n := heap.Pop(&o.ready).(*Node)
+               n := heap.Pop(&o.ready).(*ir.Node)
                if n.Initorder() != InitPending || n.Xoffset != 0 {
                        base.Fatalf("unexpected state: %v, %v, %v", n, n.Initorder(), n.Xoffset)
                }
 
                initialize(n)
                n.SetInitorder(InitDone)
-               n.Xoffset = BADWIDTH
+               n.Xoffset = types.BADWIDTH
 
                blocked := o.blocking[n]
                delete(o.blocking, n)
@@ -181,7 +183,7 @@ func (o *InitOrder) flushReady(initialize func(*Node)) {
 // path points to a slice used for tracking the sequence of
 // variables/functions visited. Using a pointer to a slice allows the
 // slice capacity to grow and limit reallocations.
-func findInitLoopAndExit(n *Node, path *[]*Node) {
+func findInitLoopAndExit(n *ir.Node, path *[]*ir.Node) {
        // We implement a simple DFS loop-finding algorithm. This
        // could be faster, but initialization cycles are rare.
 
@@ -194,14 +196,14 @@ func findInitLoopAndExit(n *Node, path *[]*Node) {
 
        // There might be multiple loops involving n; by sorting
        // references, we deterministically pick the one reported.
-       refers := collectDeps(n.Name.Defn, false).Sorted(func(ni, nj *Node) bool {
+       refers := collectDeps(n.Name.Defn, false).Sorted(func(ni, nj *ir.Node) bool {
                return ni.Pos.Before(nj.Pos)
        })
 
        *path = append(*path, n)
        for _, ref := range refers {
                // Short-circuit variables that were initialized.
-               if ref.Class() == PEXTERN && ref.Name.Defn.Initorder() == InitDone {
+               if ref.Class() == ir.PEXTERN && ref.Name.Defn.Initorder() == InitDone {
                        continue
                }
 
@@ -213,12 +215,12 @@ func findInitLoopAndExit(n *Node, path *[]*Node) {
 // reportInitLoopAndExit reports and initialization loop as an error
 // and exits. However, if l is not actually an initialization loop, it
 // simply returns instead.
-func reportInitLoopAndExit(l []*Node) {
+func reportInitLoopAndExit(l []*ir.Node) {
        // Rotate loop so that the earliest variable declaration is at
        // the start.
        i := -1
        for j, n := range l {
-               if n.Class() == PEXTERN && (i == -1 || n.Pos.Before(l[i].Pos)) {
+               if n.Class() == ir.PEXTERN && (i == -1 || n.Pos.Before(l[i].Pos)) {
                        i = j
                }
        }
@@ -236,9 +238,9 @@ func reportInitLoopAndExit(l []*Node) {
        var msg bytes.Buffer
        fmt.Fprintf(&msg, "initialization loop:\n")
        for _, n := range l {
-               fmt.Fprintf(&msg, "\t%v: %v refers to\n", n.Line(), n)
+               fmt.Fprintf(&msg, "\t%v: %v refers to\n", ir.Line(n), n)
        }
-       fmt.Fprintf(&msg, "\t%v: %v", l[0].Line(), l[0])
+       fmt.Fprintf(&msg, "\t%v: %v", ir.Line(l[0]), l[0])
 
        base.ErrorfAt(l[0].Pos, msg.String())
        base.ErrorExit()
@@ -248,14 +250,14 @@ func reportInitLoopAndExit(l []*Node) {
 // variables that declaration n depends on. If transitive is true,
 // then it also includes the transitive dependencies of any depended
 // upon functions (but not variables).
-func collectDeps(n *Node, transitive bool) NodeSet {
+func collectDeps(n *ir.Node, transitive bool) ir.NodeSet {
        d := initDeps{transitive: transitive}
        switch n.Op {
-       case OAS:
+       case ir.OAS:
                d.inspect(n.Right)
-       case OAS2DOTTYPE, OAS2FUNC, OAS2MAPR, OAS2RECV:
+       case ir.OAS2DOTTYPE, ir.OAS2FUNC, ir.OAS2MAPR, ir.OAS2RECV:
                d.inspect(n.Right)
-       case ODCLFUNC:
+       case ir.ODCLFUNC:
                d.inspectList(n.Nbody)
        default:
                base.Fatalf("unexpected Op: %v", n.Op)
@@ -265,31 +267,31 @@ func collectDeps(n *Node, transitive bool) NodeSet {
 
 type initDeps struct {
        transitive bool
-       seen       NodeSet
+       seen       ir.NodeSet
 }
 
-func (d *initDeps) inspect(n *Node)     { inspect(n, d.visit) }
-func (d *initDeps) inspectList(l Nodes) { inspectList(l, d.visit) }
+func (d *initDeps) inspect(n *ir.Node)     { ir.Inspect(n, d.visit) }
+func (d *initDeps) inspectList(l ir.Nodes) { ir.InspectList(l, d.visit) }
 
 // visit calls foundDep on any package-level functions or variables
 // referenced by n, if any.
-func (d *initDeps) visit(n *Node) bool {
+func (d *initDeps) visit(n *ir.Node) bool {
        switch n.Op {
-       case OMETHEXPR:
-               d.foundDep(n.MethodName())
+       case ir.OMETHEXPR:
+               d.foundDep(methodExprName(n))
                return false
 
-       case ONAME:
+       case ir.ONAME:
                switch n.Class() {
-               case PEXTERN, PFUNC:
+               case ir.PEXTERN, ir.PFUNC:
                        d.foundDep(n)
                }
 
-       case OCLOSURE:
+       case ir.OCLOSURE:
                d.inspectList(n.Func.Decl.Nbody)
 
-       case ODOTMETH, OCALLPART:
-               d.foundDep(n.MethodName())
+       case ir.ODOTMETH, ir.OCALLPART:
+               d.foundDep(methodExprName(n))
        }
 
        return true
@@ -297,7 +299,7 @@ func (d *initDeps) visit(n *Node) bool {
 
 // foundDep records that we've found a dependency on n by adding it to
 // seen.
-func (d *initDeps) foundDep(n *Node) {
+func (d *initDeps) foundDep(n *ir.Node) {
        // Can happen with method expressions involving interface
        // types; e.g., fixedbugs/issue4495.go.
        if n == nil {
@@ -314,7 +316,7 @@ func (d *initDeps) foundDep(n *Node) {
                return
        }
        d.seen.Add(n)
-       if d.transitive && n.Class() == PFUNC {
+       if d.transitive && n.Class() == ir.PFUNC {
                d.inspectList(n.Name.Defn.Nbody)
        }
 }
@@ -326,13 +328,13 @@ func (d *initDeps) foundDep(n *Node) {
 // an OAS node's Pos may not be unique. For example, given the
 // declaration "var a, b = f(), g()", "a" must be ordered before "b",
 // but both OAS nodes use the "=" token's position as their Pos.
-type declOrder []*Node
+type declOrder []*ir.Node
 
 func (s declOrder) Len() int           { return len(s) }
 func (s declOrder) Less(i, j int) bool { return firstLHS(s[i]).Pos.Before(firstLHS(s[j]).Pos) }
 func (s declOrder) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
 
-func (s *declOrder) Push(x interface{}) { *s = append(*s, x.(*Node)) }
+func (s *declOrder) Push(x interface{}) { *s = append(*s, x.(*ir.Node)) }
 func (s *declOrder) Pop() interface{} {
        n := (*s)[len(*s)-1]
        *s = (*s)[:len(*s)-1]
@@ -341,11 +343,11 @@ func (s *declOrder) Pop() interface{} {
 
 // firstLHS returns the first expression on the left-hand side of
 // assignment n.
-func firstLHS(n *Node) *Node {
+func firstLHS(n *ir.Node) *ir.Node {
        switch n.Op {
-       case OAS:
+       case ir.OAS:
                return n.Left
-       case OAS2DOTTYPE, OAS2FUNC, OAS2RECV, OAS2MAPR:
+       case ir.OAS2DOTTYPE, ir.OAS2FUNC, ir.OAS2RECV, ir.OAS2MAPR:
                return n.List.First()
        }
 
index d71ea9b5ed4075d30554226d3979b4ceba78e7ac..f982b43fb92cbda1d108f32bc629c272fb30a11b 100644 (file)
@@ -28,6 +28,7 @@ package gc
 
 import (
        "cmd/compile/internal/base"
+       "cmd/compile/internal/ir"
        "cmd/compile/internal/logopt"
        "cmd/compile/internal/types"
        "cmd/internal/obj"
@@ -52,8 +53,8 @@ const (
 
 // Get the function's package. For ordinary functions it's on the ->sym, but for imported methods
 // the ->sym can be re-used in the local package, so peel it off the receiver's type.
-func fnpkg(fn *Node) *types.Pkg {
-       if fn.IsMethod() {
+func fnpkg(fn *ir.Node) *types.Pkg {
+       if ir.IsMethod(fn) {
                // method
                rcvr := fn.Type.Recv().Type
 
@@ -72,7 +73,7 @@ func fnpkg(fn *Node) *types.Pkg {
 
 // Lazy typechecking of imported bodies. For local functions, caninl will set ->typecheck
 // because they're a copy of an already checked body.
-func typecheckinl(fn *Node) {
+func typecheckinl(fn *ir.Node) {
        lno := setlineno(fn)
 
        expandInline(fn)
@@ -83,12 +84,12 @@ func typecheckinl(fn *Node) {
        // the ->inl of a local function has been typechecked before caninl copied it.
        pkg := fnpkg(fn)
 
-       if pkg == localpkg || pkg == nil {
+       if pkg == ir.LocalPkg || pkg == nil {
                return // typecheckinl on local function
        }
 
        if base.Flag.LowerM > 2 || base.Debug.Export != 0 {
-               fmt.Printf("typecheck import [%v] %L { %#v }\n", fn.Sym, fn, asNodes(fn.Func.Inl.Body))
+               fmt.Printf("typecheck import [%v] %L { %#v }\n", fn.Sym, fn, ir.AsNodes(fn.Func.Inl.Body))
        }
 
        savefn := Curfn
@@ -110,8 +111,8 @@ func typecheckinl(fn *Node) {
 // Caninl determines whether fn is inlineable.
 // If so, caninl saves fn->nbody in fn->inl and substitutes it with a copy.
 // fn and ->nbody will already have been typechecked.
-func caninl(fn *Node) {
-       if fn.Op != ODCLFUNC {
+func caninl(fn *ir.Node) {
+       if fn.Op != ir.ODCLFUNC {
                base.Fatalf("caninl %v", fn)
        }
        if fn.Func.Nname == nil {
@@ -123,43 +124,43 @@ func caninl(fn *Node) {
                defer func() {
                        if reason != "" {
                                if base.Flag.LowerM > 1 {
-                                       fmt.Printf("%v: cannot inline %v: %s\n", fn.Line(), fn.Func.Nname, reason)
+                                       fmt.Printf("%v: cannot inline %v: %s\n", ir.Line(fn), fn.Func.Nname, reason)
                                }
                                if logopt.Enabled() {
-                                       logopt.LogOpt(fn.Pos, "cannotInlineFunction", "inline", fn.funcname(), reason)
+                                       logopt.LogOpt(fn.Pos, "cannotInlineFunction", "inline", ir.FuncName(fn), reason)
                                }
                        }
                }()
        }
 
        // If marked "go:noinline", don't inline
-       if fn.Func.Pragma&Noinline != 0 {
+       if fn.Func.Pragma&ir.Noinline != 0 {
                reason = "marked go:noinline"
                return
        }
 
        // If marked "go:norace" and -race compilation, don't inline.
-       if base.Flag.Race && fn.Func.Pragma&Norace != 0 {
+       if base.Flag.Race && fn.Func.Pragma&ir.Norace != 0 {
                reason = "marked go:norace with -race compilation"
                return
        }
 
        // If marked "go:nocheckptr" and -d checkptr compilation, don't inline.
-       if base.Debug.Checkptr != 0 && fn.Func.Pragma&NoCheckPtr != 0 {
+       if base.Debug.Checkptr != 0 && fn.Func.Pragma&ir.NoCheckPtr != 0 {
                reason = "marked go:nocheckptr"
                return
        }
 
        // If marked "go:cgo_unsafe_args", don't inline, since the
        // function makes assumptions about its argument frame layout.
-       if fn.Func.Pragma&CgoUnsafeArgs != 0 {
+       if fn.Func.Pragma&ir.CgoUnsafeArgs != 0 {
                reason = "marked go:cgo_unsafe_args"
                return
        }
 
        // If marked as "go:uintptrescapes", don't inline, since the
        // escape information is lost during inlining.
-       if fn.Func.Pragma&UintptrEscapes != 0 {
+       if fn.Func.Pragma&ir.UintptrEscapes != 0 {
                reason = "marked as having an escaping uintptr argument"
                return
        }
@@ -168,7 +169,7 @@ func caninl(fn *Node) {
        // granularity, so inlining yeswritebarrierrec functions can
        // confuse it (#22342). As a workaround, disallow inlining
        // them for now.
-       if fn.Func.Pragma&Yeswritebarrierrec != 0 {
+       if fn.Func.Pragma&ir.Yeswritebarrierrec != 0 {
                reason = "marked go:yeswritebarrierrec"
                return
        }
@@ -206,7 +207,7 @@ func caninl(fn *Node) {
        visitor := hairyVisitor{
                budget:        inlineMaxBudget,
                extraCallCost: cc,
-               usedLocals:    make(map[*Node]bool),
+               usedLocals:    make(map[*ir.Node]bool),
        }
        if visitor.visitList(fn.Nbody) {
                reason = visitor.reason
@@ -217,29 +218,29 @@ func caninl(fn *Node) {
                return
        }
 
-       n.Func.Inl = &Inline{
+       n.Func.Inl = &ir.Inline{
                Cost: inlineMaxBudget - visitor.budget,
                Dcl:  inlcopylist(pruneUnusedAutos(n.Name.Defn.Func.Dcl, &visitor)),
                Body: inlcopylist(fn.Nbody.Slice()),
        }
 
        if base.Flag.LowerM > 1 {
-               fmt.Printf("%v: can inline %#v with cost %d as: %#v { %#v }\n", fn.Line(), n, inlineMaxBudget-visitor.budget, fn.Type, asNodes(n.Func.Inl.Body))
+               fmt.Printf("%v: can inline %#v with cost %d as: %#v { %#v }\n", ir.Line(fn), n, inlineMaxBudget-visitor.budget, fn.Type, ir.AsNodes(n.Func.Inl.Body))
        } else if base.Flag.LowerM != 0 {
-               fmt.Printf("%v: can inline %v\n", fn.Line(), n)
+               fmt.Printf("%v: can inline %v\n", ir.Line(fn), n)
        }
        if logopt.Enabled() {
-               logopt.LogOpt(fn.Pos, "canInlineFunction", "inline", fn.funcname(), fmt.Sprintf("cost: %d", inlineMaxBudget-visitor.budget))
+               logopt.LogOpt(fn.Pos, "canInlineFunction", "inline", ir.FuncName(fn), fmt.Sprintf("cost: %d", inlineMaxBudget-visitor.budget))
        }
 }
 
 // inlFlood marks n's inline body for export and recursively ensures
 // all called functions are marked too.
-func inlFlood(n *Node) {
+func inlFlood(n *ir.Node) {
        if n == nil {
                return
        }
-       if n.Op != ONAME || n.Class() != PFUNC {
+       if n.Op != ir.ONAME || n.Class() != ir.PFUNC {
                base.Fatalf("inlFlood: unexpected %v, %v, %v", n, n.Op, n.Class())
        }
        if n.Func == nil {
@@ -259,28 +260,28 @@ func inlFlood(n *Node) {
        // Recursively identify all referenced functions for
        // reexport. We want to include even non-called functions,
        // because after inlining they might be callable.
-       inspectList(asNodes(n.Func.Inl.Body), func(n *Node) bool {
+       ir.InspectList(ir.AsNodes(n.Func.Inl.Body), func(n *ir.Node) bool {
                switch n.Op {
-               case OMETHEXPR:
-                       inlFlood(n.MethodName())
+               case ir.OMETHEXPR:
+                       inlFlood(methodExprName(n))
 
-               case ONAME:
+               case ir.ONAME:
                        switch n.Class() {
-                       case PFUNC:
+                       case ir.PFUNC:
                                inlFlood(n)
                                exportsym(n)
-                       case PEXTERN:
+                       case ir.PEXTERN:
                                exportsym(n)
                        }
 
-               case ODOTMETH:
-                       fn := n.MethodName()
+               case ir.ODOTMETH:
+                       fn := methodExprName(n)
                        inlFlood(fn)
 
-               case OCALLPART:
+               case ir.OCALLPART:
                        // Okay, because we don't yet inline indirect
                        // calls to method values.
-               case OCLOSURE:
+               case ir.OCLOSURE:
                        // If the closure is inlinable, we'll need to
                        // flood it too. But today we don't support
                        // inlining functions that contain closures.
@@ -299,11 +300,11 @@ type hairyVisitor struct {
        budget        int32
        reason        string
        extraCallCost int32
-       usedLocals    map[*Node]bool
+       usedLocals    map[*ir.Node]bool
 }
 
 // Look for anything we want to punt on.
-func (v *hairyVisitor) visitList(ll Nodes) bool {
+func (v *hairyVisitor) visitList(ll ir.Nodes) bool {
        for _, n := range ll.Slice() {
                if v.visit(n) {
                        return true
@@ -312,19 +313,19 @@ func (v *hairyVisitor) visitList(ll Nodes) bool {
        return false
 }
 
-func (v *hairyVisitor) visit(n *Node) bool {
+func (v *hairyVisitor) visit(n *ir.Node) bool {
        if n == nil {
                return false
        }
 
        switch n.Op {
        // Call is okay if inlinable and we have the budget for the body.
-       case OCALLFUNC:
+       case ir.OCALLFUNC:
                // Functions that call runtime.getcaller{pc,sp} can not be inlined
                // because getcaller{pc,sp} expect a pointer to the caller's first argument.
                //
                // runtime.throw is a "cheap call" like panic in normal code.
-               if n.Left.Op == ONAME && n.Left.Class() == PFUNC && isRuntimePkg(n.Left.Sym.Pkg) {
+               if n.Left.Op == ir.ONAME && n.Left.Class() == ir.PFUNC && isRuntimePkg(n.Left.Sym.Pkg) {
                        fn := n.Left.Sym.Name
                        if fn == "getcallerpc" || fn == "getcallersp" {
                                v.reason = "call to " + fn
@@ -350,7 +351,7 @@ func (v *hairyVisitor) visit(n *Node) bool {
                v.budget -= v.extraCallCost
 
        // Call is okay if inlinable and we have the budget for the body.
-       case OCALLMETH:
+       case ir.OCALLMETH:
                t := n.Left.Type
                if t == nil {
                        base.Fatalf("no function type for [%p] %+v\n", n.Left, n.Left)
@@ -366,7 +367,7 @@ func (v *hairyVisitor) visit(n *Node) bool {
                                break
                        }
                }
-               if inlfn := n.Left.MethodName().Func; inlfn.Inl != nil {
+               if inlfn := methodExprName(n.Left).Func; inlfn.Inl != nil {
                        v.budget -= inlfn.Inl.Cost
                        break
                }
@@ -374,58 +375,58 @@ func (v *hairyVisitor) visit(n *Node) bool {
                v.budget -= v.extraCallCost
 
        // Things that are too hairy, irrespective of the budget
-       case OCALL, OCALLINTER:
+       case ir.OCALL, ir.OCALLINTER:
                // Call cost for non-leaf inlining.
                v.budget -= v.extraCallCost
 
-       case OPANIC:
+       case ir.OPANIC:
                v.budget -= inlineExtraPanicCost
 
-       case ORECOVER:
+       case ir.ORECOVER:
                // recover matches the argument frame pointer to find
                // the right panic value, so it needs an argument frame.
                v.reason = "call to recover"
                return true
 
-       case OCLOSURE,
-               ORANGE,
-               OSELECT,
-               OGO,
-               ODEFER,
-               ODCLTYPE, // can't print yet
-               ORETJMP:
+       case ir.OCLOSURE,
+               ir.ORANGE,
+               ir.OSELECT,
+               ir.OGO,
+               ir.ODEFER,
+               ir.ODCLTYPE, // can't print yet
+               ir.ORETJMP:
                v.reason = "unhandled op " + n.Op.String()
                return true
 
-       case OAPPEND:
+       case ir.OAPPEND:
                v.budget -= inlineExtraAppendCost
 
-       case ODCLCONST, OEMPTY, OFALL:
+       case ir.ODCLCONST, ir.OEMPTY, ir.OFALL:
                // These nodes don't produce code; omit from inlining budget.
                return false
 
-       case OLABEL:
+       case ir.OLABEL:
                // TODO(mdempsky): Add support for inlining labeled control statements.
-               if n.labeledControl() != nil {
+               if labeledControl(n) != nil {
                        v.reason = "labeled control"
                        return true
                }
 
-       case OBREAK, OCONTINUE:
+       case ir.OBREAK, ir.OCONTINUE:
                if n.Sym != nil {
                        // Should have short-circuited due to labeledControl above.
                        base.Fatalf("unexpected labeled break/continue: %v", n)
                }
 
-       case OIF:
-               if Isconst(n.Left, constant.Bool) {
+       case ir.OIF:
+               if ir.IsConst(n.Left, constant.Bool) {
                        // This if and the condition cost nothing.
                        return v.visitList(n.Ninit) || v.visitList(n.Nbody) ||
                                v.visitList(n.Rlist)
                }
 
-       case ONAME:
-               if n.Class() == PAUTO {
+       case ir.ONAME:
+               if n.Class() == ir.PAUTO {
                        v.usedLocals[n] = true
                }
 
@@ -446,26 +447,26 @@ func (v *hairyVisitor) visit(n *Node) bool {
 // inlcopylist (together with inlcopy) recursively copies a list of nodes, except
 // that it keeps the same ONAME, OTYPE, and OLITERAL nodes. It is used for copying
 // the body and dcls of an inlineable function.
-func inlcopylist(ll []*Node) []*Node {
-       s := make([]*Node, 0, len(ll))
+func inlcopylist(ll []*ir.Node) []*ir.Node {
+       s := make([]*ir.Node, 0, len(ll))
        for _, n := range ll {
                s = append(s, inlcopy(n))
        }
        return s
 }
 
-func inlcopy(n *Node) *Node {
+func inlcopy(n *ir.Node) *ir.Node {
        if n == nil {
                return nil
        }
 
        switch n.Op {
-       case ONAME, OTYPE, OLITERAL, ONIL:
+       case ir.ONAME, ir.OTYPE, ir.OLITERAL, ir.ONIL:
                return n
        }
 
-       m := n.copy()
-       if n.Op != OCALLPART && m.Func != nil {
+       m := ir.Copy(n)
+       if n.Op != ir.OCALLPART && m.Func != nil {
                base.Fatalf("unexpected Func: %v", m)
        }
        m.Left = inlcopy(n.Left)
@@ -478,7 +479,7 @@ func inlcopy(n *Node) *Node {
        return m
 }
 
-func countNodes(n *Node) int {
+func countNodes(n *ir.Node) int {
        if n == nil {
                return 0
        }
@@ -502,7 +503,7 @@ func countNodes(n *Node) int {
 
 // Inlcalls/nodelist/node walks fn's statements and expressions and substitutes any
 // calls made to inlineable functions. This is the external entry point.
-func inlcalls(fn *Node) {
+func inlcalls(fn *ir.Node) {
        savefn := Curfn
        Curfn = fn
        maxCost := int32(inlineMaxBudget)
@@ -515,7 +516,7 @@ func inlcalls(fn *Node) {
        // but allow inlining if there is a recursion cycle of many functions.
        // Most likely, the inlining will stop before we even hit the beginning of
        // the cycle again, but the map catches the unusual case.
-       inlMap := make(map[*Node]bool)
+       inlMap := make(map[*ir.Node]bool)
        fn = inlnode(fn, maxCost, inlMap)
        if fn != Curfn {
                base.Fatalf("inlnode replaced curfn")
@@ -524,8 +525,8 @@ func inlcalls(fn *Node) {
 }
 
 // Turn an OINLCALL into a statement.
-func inlconv2stmt(n *Node) {
-       n.Op = OBLOCK
+func inlconv2stmt(n *ir.Node) {
+       n.Op = ir.OBLOCK
 
        // n->ninit stays
        n.List.Set(n.Nbody.Slice())
@@ -537,7 +538,7 @@ func inlconv2stmt(n *Node) {
 // Turn an OINLCALL into a single valued expression.
 // The result of inlconv2expr MUST be assigned back to n, e.g.
 //     n.Left = inlconv2expr(n.Left)
-func inlconv2expr(n *Node) *Node {
+func inlconv2expr(n *ir.Node) *ir.Node {
        r := n.Rlist.First()
        return addinit(r, append(n.Ninit.Slice(), n.Nbody.Slice()...))
 }
@@ -547,8 +548,8 @@ func inlconv2expr(n *Node) *Node {
 // containing the inlined statements on the first list element so
 // order will be preserved Used in return, oas2func and call
 // statements.
-func inlconv2list(n *Node) []*Node {
-       if n.Op != OINLCALL || n.Rlist.Len() == 0 {
+func inlconv2list(n *ir.Node) []*ir.Node {
+       if n.Op != ir.OINLCALL || n.Rlist.Len() == 0 {
                base.Fatalf("inlconv2list %+v\n", n)
        }
 
@@ -557,7 +558,7 @@ func inlconv2list(n *Node) []*Node {
        return s
 }
 
-func inlnodelist(l Nodes, maxCost int32, inlMap map[*Node]bool) {
+func inlnodelist(l ir.Nodes, maxCost int32, inlMap map[*ir.Node]bool) {
        s := l.Slice()
        for i := range s {
                s[i] = inlnode(s[i], maxCost, inlMap)
@@ -577,23 +578,23 @@ func inlnodelist(l Nodes, maxCost int32, inlMap map[*Node]bool) {
 // shorter and less complicated.
 // The result of inlnode MUST be assigned back to n, e.g.
 //     n.Left = inlnode(n.Left)
-func inlnode(n *Node, maxCost int32, inlMap map[*Node]bool) *Node {
+func inlnode(n *ir.Node, maxCost int32, inlMap map[*ir.Node]bool) *ir.Node {
        if n == nil {
                return n
        }
 
        switch n.Op {
-       case ODEFER, OGO:
+       case ir.ODEFER, ir.OGO:
                switch n.Left.Op {
-               case OCALLFUNC, OCALLMETH:
+               case ir.OCALLFUNC, ir.OCALLMETH:
                        n.Left.SetNoInline(true)
                }
 
        // TODO do them here (or earlier),
        // so escape analysis can avoid more heapmoves.
-       case OCLOSURE:
+       case ir.OCLOSURE:
                return n
-       case OCALLMETH:
+       case ir.OCALLMETH:
                // Prevent inlining some reflect.Value methods when using checkptr,
                // even when package reflect was compiled without it (#35073).
                if s := n.Left.Sym; base.Debug.Checkptr != 0 && isReflectPkg(s.Pkg) && (s.Name == "Value.UnsafeAddr" || s.Name == "Value.Pointer") {
@@ -605,24 +606,24 @@ func inlnode(n *Node, maxCost int32, inlMap map[*Node]bool) *Node {
 
        inlnodelist(n.Ninit, maxCost, inlMap)
        for _, n1 := range n.Ninit.Slice() {
-               if n1.Op == OINLCALL {
+               if n1.Op == ir.OINLCALL {
                        inlconv2stmt(n1)
                }
        }
 
        n.Left = inlnode(n.Left, maxCost, inlMap)
-       if n.Left != nil && n.Left.Op == OINLCALL {
+       if n.Left != nil && n.Left.Op == ir.OINLCALL {
                n.Left = inlconv2expr(n.Left)
        }
 
        n.Right = inlnode(n.Right, maxCost, inlMap)
-       if n.Right != nil && n.Right.Op == OINLCALL {
-               if n.Op == OFOR || n.Op == OFORUNTIL {
+       if n.Right != nil && n.Right.Op == ir.OINLCALL {
+               if n.Op == ir.OFOR || n.Op == ir.OFORUNTIL {
                        inlconv2stmt(n.Right)
-               } else if n.Op == OAS2FUNC {
+               } else if n.Op == ir.OAS2FUNC {
                        n.Rlist.Set(inlconv2list(n.Right))
                        n.Right = nil
-                       n.Op = OAS2
+                       n.Op = ir.OAS2
                        n.SetTypecheck(0)
                        n = typecheck(n, ctxStmt)
                } else {
@@ -631,16 +632,16 @@ func inlnode(n *Node, maxCost int32, inlMap map[*Node]bool) *Node {
        }
 
        inlnodelist(n.List, maxCost, inlMap)
-       if n.Op == OBLOCK {
+       if n.Op == ir.OBLOCK {
                for _, n2 := range n.List.Slice() {
-                       if n2.Op == OINLCALL {
+                       if n2.Op == ir.OINLCALL {
                                inlconv2stmt(n2)
                        }
                }
        } else {
                s := n.List.Slice()
                for i1, n1 := range s {
-                       if n1 != nil && n1.Op == OINLCALL {
+                       if n1 != nil && n1.Op == ir.OINLCALL {
                                s[i1] = inlconv2expr(s[i1])
                        }
                }
@@ -649,8 +650,8 @@ func inlnode(n *Node, maxCost int32, inlMap map[*Node]bool) *Node {
        inlnodelist(n.Rlist, maxCost, inlMap)
        s := n.Rlist.Slice()
        for i1, n1 := range s {
-               if n1.Op == OINLCALL {
-                       if n.Op == OIF {
+               if n1.Op == ir.OINLCALL {
+                       if n.Op == ir.OIF {
                                inlconv2stmt(n1)
                        } else {
                                s[i1] = inlconv2expr(s[i1])
@@ -660,7 +661,7 @@ func inlnode(n *Node, maxCost int32, inlMap map[*Node]bool) *Node {
 
        inlnodelist(n.Nbody, maxCost, inlMap)
        for _, n := range n.Nbody.Slice() {
-               if n.Op == OINLCALL {
+               if n.Op == ir.OINLCALL {
                        inlconv2stmt(n)
                }
        }
@@ -669,16 +670,16 @@ func inlnode(n *Node, maxCost int32, inlMap map[*Node]bool) *Node {
        // transmogrify this node itself unless inhibited by the
        // switch at the top of this function.
        switch n.Op {
-       case OCALLFUNC, OCALLMETH:
+       case ir.OCALLFUNC, ir.OCALLMETH:
                if n.NoInline() {
                        return n
                }
        }
 
        switch n.Op {
-       case OCALLFUNC:
+       case ir.OCALLFUNC:
                if base.Flag.LowerM > 3 {
-                       fmt.Printf("%v:call to func %+v\n", n.Line(), n.Left)
+                       fmt.Printf("%v:call to func %+v\n", ir.Line(n), n.Left)
                }
                if isIntrinsicCall(n) {
                        break
@@ -687,9 +688,9 @@ func inlnode(n *Node, maxCost int32, inlMap map[*Node]bool) *Node {
                        n = mkinlcall(n, fn, maxCost, inlMap)
                }
 
-       case OCALLMETH:
+       case ir.OCALLMETH:
                if base.Flag.LowerM > 3 {
-                       fmt.Printf("%v:call to meth %L\n", n.Line(), n.Left.Right)
+                       fmt.Printf("%v:call to meth %L\n", ir.Line(n), n.Left.Right)
                }
 
                // typecheck should have resolved ODOTMETH->type, whose nname points to the actual function.
@@ -697,7 +698,7 @@ func inlnode(n *Node, maxCost int32, inlMap map[*Node]bool) *Node {
                        base.Fatalf("no function type for [%p] %+v\n", n.Left, n.Left)
                }
 
-               n = mkinlcall(n, n.Left.MethodName(), maxCost, inlMap)
+               n = mkinlcall(n, methodExprName(n.Left), maxCost, inlMap)
        }
 
        base.Pos = lno
@@ -706,11 +707,11 @@ func inlnode(n *Node, maxCost int32, inlMap map[*Node]bool) *Node {
 
 // inlCallee takes a function-typed expression and returns the underlying function ONAME
 // that it refers to if statically known. Otherwise, it returns nil.
-func inlCallee(fn *Node) *Node {
+func inlCallee(fn *ir.Node) *ir.Node {
        fn = staticValue(fn)
        switch {
-       case fn.Op == OMETHEXPR:
-               n := fn.MethodName()
+       case fn.Op == ir.OMETHEXPR:
+               n := methodExprName(fn)
                // Check that receiver type matches fn.Left.
                // TODO(mdempsky): Handle implicit dereference
                // of pointer receiver argument?
@@ -718,9 +719,9 @@ func inlCallee(fn *Node) *Node {
                        return nil
                }
                return n
-       case fn.Op == ONAME && fn.Class() == PFUNC:
+       case fn.Op == ir.ONAME && fn.Class() == ir.PFUNC:
                return fn
-       case fn.Op == OCLOSURE:
+       case fn.Op == ir.OCLOSURE:
                c := fn.Func.Decl
                caninl(c)
                return c.Func.Nname
@@ -728,9 +729,9 @@ func inlCallee(fn *Node) *Node {
        return nil
 }
 
-func staticValue(n *Node) *Node {
+func staticValue(n *ir.Node) *ir.Node {
        for {
-               if n.Op == OCONVNOP {
+               if n.Op == ir.OCONVNOP {
                        n = n.Left
                        continue
                }
@@ -746,8 +747,8 @@ func staticValue(n *Node) *Node {
 // staticValue1 implements a simple SSA-like optimization. If n is a local variable
 // that is initialized and never reassigned, staticValue1 returns the initializer
 // expression. Otherwise, it returns nil.
-func staticValue1(n *Node) *Node {
-       if n.Op != ONAME || n.Class() != PAUTO || n.Name.Addrtaken() {
+func staticValue1(n *ir.Node) *ir.Node {
+       if n.Op != ir.ONAME || n.Class() != ir.PAUTO || n.Name.Addrtaken() {
                return nil
        }
 
@@ -756,12 +757,12 @@ func staticValue1(n *Node) *Node {
                return nil
        }
 
-       var rhs *Node
+       var rhs *ir.Node
 FindRHS:
        switch defn.Op {
-       case OAS:
+       case ir.OAS:
                rhs = defn.Right
-       case OAS2:
+       case ir.OAS2:
                for i, lhs := range defn.List.Slice() {
                        if lhs == n {
                                rhs = defn.Rlist.Index(i)
@@ -790,8 +791,8 @@ FindRHS:
 // useful for -m output documenting the reason for inhibited optimizations.
 // NB: global variables are always considered to be re-assigned.
 // TODO: handle initial declaration not including an assignment and followed by a single assignment?
-func reassigned(n *Node) (bool, *Node) {
-       if n.Op != ONAME {
+func reassigned(n *ir.Node) (bool, *ir.Node) {
+       if n.Op != ir.ONAME {
                base.Fatalf("reassigned %v", n)
        }
        // no way to reliably check for no-reassignment of globals, assume it can be
@@ -804,7 +805,7 @@ func reassigned(n *Node) (bool, *Node) {
        // of the corresponding ODCLFUNC.
        // We need to walk the function body to check for reassignments so we follow the
        // linkage to the ODCLFUNC node as that is where body is held.
-       if f.Op == OCLOSURE {
+       if f.Op == ir.OCLOSURE {
                f = f.Func.Decl
        }
        v := reassignVisitor{name: n}
@@ -813,19 +814,19 @@ func reassigned(n *Node) (bool, *Node) {
 }
 
 type reassignVisitor struct {
-       name *Node
+       name *ir.Node
 }
 
-func (v *reassignVisitor) visit(n *Node) *Node {
+func (v *reassignVisitor) visit(n *ir.Node) *ir.Node {
        if n == nil {
                return nil
        }
        switch n.Op {
-       case OAS:
+       case ir.OAS:
                if n.Left == v.name && n != v.name.Name.Defn {
                        return n
                }
-       case OAS2, OAS2FUNC, OAS2MAPR, OAS2DOTTYPE:
+       case ir.OAS2, ir.OAS2FUNC, ir.OAS2MAPR, ir.OAS2DOTTYPE:
                for _, p := range n.List.Slice() {
                        if p == v.name && n != v.name.Name.Defn {
                                return n
@@ -853,7 +854,7 @@ func (v *reassignVisitor) visit(n *Node) *Node {
        return nil
 }
 
-func (v *reassignVisitor) visitList(l Nodes) *Node {
+func (v *reassignVisitor) visitList(l ir.Nodes) *ir.Node {
        for _, n := range l.Slice() {
                if a := v.visit(n); a != nil {
                        return a
@@ -862,17 +863,17 @@ func (v *reassignVisitor) visitList(l Nodes) *Node {
        return nil
 }
 
-func inlParam(t *types.Field, as *Node, inlvars map[*Node]*Node) *Node {
-       n := asNode(t.Nname)
-       if n == nil || n.isBlank() {
-               return nblank
+func inlParam(t *types.Field, as *ir.Node, inlvars map[*ir.Node]*ir.Node) *ir.Node {
+       n := ir.AsNode(t.Nname)
+       if n == nil || ir.IsBlank(n) {
+               return ir.BlankNode
        }
 
        inlvar := inlvars[n]
        if inlvar == nil {
                base.Fatalf("missing inlvar for %v", n)
        }
-       as.Ninit.Append(nod(ODCL, inlvar, nil))
+       as.Ninit.Append(ir.Nod(ir.ODCL, inlvar, nil))
        inlvar.Name.Defn = as
        return inlvar
 }
@@ -886,11 +887,11 @@ var inlgen int
 // parameters.
 // The result of mkinlcall MUST be assigned back to n, e.g.
 //     n.Left = mkinlcall(n.Left, fn, isddd)
-func mkinlcall(n, fn *Node, maxCost int32, inlMap map[*Node]bool) *Node {
+func mkinlcall(n, fn *ir.Node, maxCost int32, inlMap map[*ir.Node]bool) *ir.Node {
        if fn.Func.Inl == nil {
                if logopt.Enabled() {
-                       logopt.LogOpt(n.Pos, "cannotInlineCall", "inline", Curfn.funcname(),
-                               fmt.Sprintf("%s cannot be inlined", fn.pkgFuncName()))
+                       logopt.LogOpt(n.Pos, "cannotInlineCall", "inline", ir.FuncName(Curfn),
+                               fmt.Sprintf("%s cannot be inlined", ir.PkgFuncName(fn)))
                }
                return n
        }
@@ -898,8 +899,8 @@ func mkinlcall(n, fn *Node, maxCost int32, inlMap map[*Node]bool) *Node {
                // The inlined function body is too big. Typically we use this check to restrict
                // inlining into very big functions.  See issue 26546 and 17566.
                if logopt.Enabled() {
-                       logopt.LogOpt(n.Pos, "cannotInlineCall", "inline", Curfn.funcname(),
-                               fmt.Sprintf("cost %d of %s exceeds max large caller cost %d", fn.Func.Inl.Cost, fn.pkgFuncName(), maxCost))
+                       logopt.LogOpt(n.Pos, "cannotInlineCall", "inline", ir.FuncName(Curfn),
+                               fmt.Sprintf("cost %d of %s exceeds max large caller cost %d", fn.Func.Inl.Cost, ir.PkgFuncName(fn), maxCost))
                }
                return n
        }
@@ -907,7 +908,7 @@ func mkinlcall(n, fn *Node, maxCost int32, inlMap map[*Node]bool) *Node {
        if fn == Curfn || fn.Name.Defn == Curfn {
                // Can't recursively inline a function into itself.
                if logopt.Enabled() {
-                       logopt.LogOpt(n.Pos, "cannotInlineCall", "inline", fmt.Sprintf("recursive call to %s", Curfn.funcname()))
+                       logopt.LogOpt(n.Pos, "cannotInlineCall", "inline", fmt.Sprintf("recursive call to %s", ir.FuncName(Curfn)))
                }
                return n
        }
@@ -924,7 +925,7 @@ func mkinlcall(n, fn *Node, maxCost int32, inlMap map[*Node]bool) *Node {
 
        if inlMap[fn] {
                if base.Flag.LowerM > 1 {
-                       fmt.Printf("%v: cannot inline %v into %v: repeated recursive cycle\n", n.Line(), fn, Curfn.funcname())
+                       fmt.Printf("%v: cannot inline %v into %v: repeated recursive cycle\n", ir.Line(n), fn, ir.FuncName(Curfn))
                }
                return n
        }
@@ -938,15 +939,15 @@ func mkinlcall(n, fn *Node, maxCost int32, inlMap map[*Node]bool) *Node {
 
        // We have a function node, and it has an inlineable body.
        if base.Flag.LowerM > 1 {
-               fmt.Printf("%v: inlining call to %v %#v { %#v }\n", n.Line(), fn.Sym, fn.Type, asNodes(fn.Func.Inl.Body))
+               fmt.Printf("%v: inlining call to %v %#v { %#v }\n", ir.Line(n), fn.Sym, fn.Type, ir.AsNodes(fn.Func.Inl.Body))
        } else if base.Flag.LowerM != 0 {
-               fmt.Printf("%v: inlining call to %v\n", n.Line(), fn)
+               fmt.Printf("%v: inlining call to %v\n", ir.Line(n), fn)
        }
        if base.Flag.LowerM > 2 {
-               fmt.Printf("%v: Before inlining: %+v\n", n.Line(), n)
+               fmt.Printf("%v: Before inlining: %+v\n", ir.Line(n), n)
        }
 
-       if ssaDump != "" && ssaDump == Curfn.funcname() {
+       if ssaDump != "" && ssaDump == ir.FuncName(Curfn) {
                ssaDumpInlined = append(ssaDumpInlined, fn)
        }
 
@@ -956,28 +957,28 @@ func mkinlcall(n, fn *Node, maxCost int32, inlMap map[*Node]bool) *Node {
        // may contain side effects (e.g., added by addinit during
        // inlconv2expr or inlconv2list). Make sure to preserve these,
        // if necessary (#42703).
-       if n.Op == OCALLFUNC {
+       if n.Op == ir.OCALLFUNC {
                callee := n.Left
-               for callee.Op == OCONVNOP {
+               for callee.Op == ir.OCONVNOP {
                        ninit.AppendNodes(&callee.Ninit)
                        callee = callee.Left
                }
-               if callee.Op != ONAME && callee.Op != OCLOSURE && callee.Op != OMETHEXPR {
+               if callee.Op != ir.ONAME && callee.Op != ir.OCLOSURE && callee.Op != ir.OMETHEXPR {
                        base.Fatalf("unexpected callee expression: %v", callee)
                }
        }
 
        // Make temp names to use instead of the originals.
-       inlvars := make(map[*Node]*Node)
+       inlvars := make(map[*ir.Node]*ir.Node)
 
        // record formals/locals for later post-processing
-       var inlfvars []*Node
+       var inlfvars []*ir.Node
 
        // Handle captured variables when inlining closures.
        if fn.Name.Defn != nil {
                if c := fn.Name.Defn.Func.OClosure; c != nil {
                        for _, v := range c.Func.ClosureVars.Slice() {
-                               if v.Op == OXXX {
+                               if v.Op == ir.OXXX {
                                        continue
                                }
 
@@ -987,38 +988,38 @@ func mkinlcall(n, fn *Node, maxCost int32, inlMap map[*Node]bool) *Node {
                                // the reassigned check via some sort of copy propagation this would most
                                // likely need to be changed to a loop to walk up to the correct Param
                                if o == nil || (o.Name.Curfn != Curfn && o.Name.Curfn.Func.OClosure != Curfn) {
-                                       base.Fatalf("%v: unresolvable capture %v %v\n", n.Line(), fn, v)
+                                       base.Fatalf("%v: unresolvable capture %v %v\n", ir.Line(n), fn, v)
                                }
 
                                if v.Name.Byval() {
                                        iv := typecheck(inlvar(v), ctxExpr)
-                                       ninit.Append(nod(ODCL, iv, nil))
-                                       ninit.Append(typecheck(nod(OAS, iv, o), ctxStmt))
+                                       ninit.Append(ir.Nod(ir.ODCL, iv, nil))
+                                       ninit.Append(typecheck(ir.Nod(ir.OAS, iv, o), ctxStmt))
                                        inlvars[v] = iv
                                } else {
-                                       addr := newname(lookup("&" + v.Sym.Name))
+                                       addr := NewName(lookup("&" + v.Sym.Name))
                                        addr.Type = types.NewPtr(v.Type)
                                        ia := typecheck(inlvar(addr), ctxExpr)
-                                       ninit.Append(nod(ODCL, ia, nil))
-                                       ninit.Append(typecheck(nod(OAS, ia, nod(OADDR, o, nil)), ctxStmt))
+                                       ninit.Append(ir.Nod(ir.ODCL, ia, nil))
+                                       ninit.Append(typecheck(ir.Nod(ir.OAS, ia, ir.Nod(ir.OADDR, o, nil)), ctxStmt))
                                        inlvars[addr] = ia
 
                                        // When capturing by reference, all occurrence of the captured var
                                        // must be substituted with dereference of the temporary address
-                                       inlvars[v] = typecheck(nod(ODEREF, ia, nil), ctxExpr)
+                                       inlvars[v] = typecheck(ir.Nod(ir.ODEREF, ia, nil), ctxExpr)
                                }
                        }
                }
        }
 
        for _, ln := range fn.Func.Inl.Dcl {
-               if ln.Op != ONAME {
+               if ln.Op != ir.ONAME {
                        continue
                }
-               if ln.Class() == PPARAMOUT { // return values handled below.
+               if ln.Class() == ir.PPARAMOUT { // return values handled below.
                        continue
                }
-               if ln.isParamStackCopy() { // ignore the on-stack copy of a parameter that moved to the heap
+               if isParamStackCopy(ln) { // ignore the on-stack copy of a parameter that moved to the heap
                        // TODO(mdempsky): Remove once I'm confident
                        // this never actually happens. We currently
                        // perform inlining before escape analysis, so
@@ -1028,7 +1029,7 @@ func mkinlcall(n, fn *Node, maxCost int32, inlMap map[*Node]bool) *Node {
                inlf := typecheck(inlvar(ln), ctxExpr)
                inlvars[ln] = inlf
                if base.Flag.GenDwarfInl > 0 {
-                       if ln.Class() == PPARAM {
+                       if ln.Class() == ir.PPARAM {
                                inlf.Name.SetInlFormal(true)
                        } else {
                                inlf.Name.SetInlLocal(true)
@@ -1039,8 +1040,8 @@ func mkinlcall(n, fn *Node, maxCost int32, inlMap map[*Node]bool) *Node {
        }
 
        nreturns := 0
-       inspectList(asNodes(fn.Func.Inl.Body), func(n *Node) bool {
-               if n != nil && n.Op == ORETURN {
+       ir.InspectList(ir.AsNodes(fn.Func.Inl.Body), func(n *ir.Node) bool {
+               if n != nil && n.Op == ir.ORETURN {
                        nreturns++
                }
                return true
@@ -1052,10 +1053,10 @@ func mkinlcall(n, fn *Node, maxCost int32, inlMap map[*Node]bool) *Node {
        delayretvars := nreturns == 1
 
        // temporaries for return values.
-       var retvars []*Node
+       var retvars []*ir.Node
        for i, t := range fn.Type.Results().Fields().Slice() {
-               var m *Node
-               if n := asNode(t.Nname); n != nil && !n.isBlank() && !strings.HasPrefix(n.Sym.Name, "~r") {
+               var m *ir.Node
+               if n := ir.AsNode(t.Nname); n != nil && !ir.IsBlank(n) && !strings.HasPrefix(n.Sym.Name, "~r") {
                        m = inlvar(n)
                        m = typecheck(m, ctxExpr)
                        inlvars[n] = m
@@ -1080,9 +1081,9 @@ func mkinlcall(n, fn *Node, maxCost int32, inlMap map[*Node]bool) *Node {
        }
 
        // Assign arguments to the parameters' temp names.
-       as := nod(OAS2, nil, nil)
+       as := ir.Nod(ir.OAS2, nil, nil)
        as.SetColas(true)
-       if n.Op == OCALLMETH {
+       if n.Op == ir.OCALLMETH {
                if n.Left.Left == nil {
                        base.Fatalf("method call without receiver: %+v", n)
                }
@@ -1092,7 +1093,7 @@ func mkinlcall(n, fn *Node, maxCost int32, inlMap map[*Node]bool) *Node {
 
        // For non-dotted calls to variadic functions, we assign the
        // variadic parameter's temp name separately.
-       var vas *Node
+       var vas *ir.Node
 
        if recv := fn.Type.Recv(); recv != nil {
                as.List.Append(inlParam(recv, as, inlvars))
@@ -1115,13 +1116,13 @@ func mkinlcall(n, fn *Node, maxCost int32, inlMap map[*Node]bool) *Node {
                }
                varargs := as.List.Slice()[x:]
 
-               vas = nod(OAS, nil, nil)
+               vas = ir.Nod(ir.OAS, nil, nil)
                vas.Left = inlParam(param, vas, inlvars)
                if len(varargs) == 0 {
                        vas.Right = nodnil()
                        vas.Right.Type = param.Type
                } else {
-                       vas.Right = nod(OCOMPLIT, nil, typenod(param.Type))
+                       vas.Right = ir.Nod(ir.OCOMPLIT, nil, typenod(param.Type))
                        vas.Right.List.Set(varargs)
                }
        }
@@ -1139,8 +1140,8 @@ func mkinlcall(n, fn *Node, maxCost int32, inlMap map[*Node]bool) *Node {
        if !delayretvars {
                // Zero the return parameters.
                for _, n := range retvars {
-                       ninit.Append(nod(ODCL, n, nil))
-                       ras := nod(OAS, n, nil)
+                       ninit.Append(ir.Nod(ir.ODCL, n, nil))
+                       ras := ir.Nod(ir.OAS, n, nil)
                        ras = typecheck(ras, ctxStmt)
                        ninit.Append(ras)
                }
@@ -1161,7 +1162,7 @@ func mkinlcall(n, fn *Node, maxCost int32, inlMap map[*Node]bool) *Node {
        // to put a breakpoint. Not sure if that's really necessary or not
        // (in which case it could go at the end of the function instead).
        // Note issue 28603.
-       inlMark := nod(OINLMARK, nil, nil)
+       inlMark := ir.Nod(ir.OINLMARK, nil, nil)
        inlMark.Pos = n.Pos.WithIsStmt()
        inlMark.Xoffset = int64(newIndex)
        ninit.Append(inlMark)
@@ -1182,9 +1183,9 @@ func mkinlcall(n, fn *Node, maxCost int32, inlMap map[*Node]bool) *Node {
                newInlIndex:  newIndex,
        }
 
-       body := subst.list(asNodes(fn.Func.Inl.Body))
+       body := subst.list(ir.AsNodes(fn.Func.Inl.Body))
 
-       lab := nodSym(OLABEL, nil, retlabel)
+       lab := nodSym(ir.OLABEL, nil, retlabel)
        body = append(body, lab)
 
        typecheckslice(body, ctxStmt)
@@ -1197,7 +1198,7 @@ func mkinlcall(n, fn *Node, maxCost int32, inlMap map[*Node]bool) *Node {
 
        //dumplist("ninit post", ninit);
 
-       call := nod(OINLCALL, nil, nil)
+       call := ir.Nod(ir.OINLCALL, nil, nil)
        call.Ninit.Set(ninit.Slice())
        call.Nbody.Set(body)
        call.Rlist.Set(retvars)
@@ -1212,13 +1213,13 @@ func mkinlcall(n, fn *Node, maxCost int32, inlMap map[*Node]bool) *Node {
        // luckily these are small.
        inlnodelist(call.Nbody, maxCost, inlMap)
        for _, n := range call.Nbody.Slice() {
-               if n.Op == OINLCALL {
+               if n.Op == ir.OINLCALL {
                        inlconv2stmt(n)
                }
        }
 
        if base.Flag.LowerM > 2 {
-               fmt.Printf("%v: After inlining %+v\n\n", call.Line(), call)
+               fmt.Printf("%v: After inlining %+v\n\n", ir.Line(call), call)
        }
 
        return call
@@ -1227,14 +1228,14 @@ func mkinlcall(n, fn *Node, maxCost int32, inlMap map[*Node]bool) *Node {
 // Every time we expand a function we generate a new set of tmpnames,
 // PAUTO's in the calling functions, and link them off of the
 // PPARAM's, PAUTOS and PPARAMOUTs of the called function.
-func inlvar(var_ *Node) *Node {
+func inlvar(var_ *ir.Node) *ir.Node {
        if base.Flag.LowerM > 3 {
                fmt.Printf("inlvar %+v\n", var_)
        }
 
-       n := newname(var_.Sym)
+       n := NewName(var_.Sym)
        n.Type = var_.Type
-       n.SetClass(PAUTO)
+       n.SetClass(ir.PAUTO)
        n.Name.SetUsed(true)
        n.Name.Curfn = Curfn // the calling function, not the called one
        n.Name.SetAddrtaken(var_.Name.Addrtaken())
@@ -1244,10 +1245,10 @@ func inlvar(var_ *Node) *Node {
 }
 
 // Synthesize a variable to store the inlined function's results in.
-func retvar(t *types.Field, i int) *Node {
-       n := newname(lookupN("~R", i))
+func retvar(t *types.Field, i int) *ir.Node {
+       n := NewName(lookupN("~R", i))
        n.Type = t.Type
-       n.SetClass(PAUTO)
+       n.SetClass(ir.PAUTO)
        n.Name.SetUsed(true)
        n.Name.Curfn = Curfn // the calling function, not the called one
        Curfn.Func.Dcl = append(Curfn.Func.Dcl, n)
@@ -1256,10 +1257,10 @@ func retvar(t *types.Field, i int) *Node {
 
 // Synthesize a variable to store the inlined function's arguments
 // when they come from a multiple return call.
-func argvar(t *types.Type, i int) *Node {
-       n := newname(lookupN("~arg", i))
+func argvar(t *types.Type, i int) *ir.Node {
+       n := NewName(lookupN("~arg", i))
        n.Type = t.Elem()
-       n.SetClass(PAUTO)
+       n.SetClass(ir.PAUTO)
        n.Name.SetUsed(true)
        n.Name.Curfn = Curfn // the calling function, not the called one
        Curfn.Func.Dcl = append(Curfn.Func.Dcl, n)
@@ -1273,13 +1274,13 @@ type inlsubst struct {
        retlabel *types.Sym
 
        // Temporary result variables.
-       retvars []*Node
+       retvars []*ir.Node
 
        // Whether result variables should be initialized at the
        // "return" statement.
        delayretvars bool
 
-       inlvars map[*Node]*Node
+       inlvars map[*ir.Node]*ir.Node
 
        // bases maps from original PosBase to PosBase with an extra
        // inlined call frame.
@@ -1291,8 +1292,8 @@ type inlsubst struct {
 }
 
 // list inlines a list of nodes.
-func (subst *inlsubst) list(ll Nodes) []*Node {
-       s := make([]*Node, 0, ll.Len())
+func (subst *inlsubst) list(ll ir.Nodes) []*ir.Node {
+       s := make([]*ir.Node, 0, ll.Len())
        for _, n := range ll.Slice() {
                s = append(s, subst.node(n))
        }
@@ -1303,13 +1304,13 @@ func (subst *inlsubst) list(ll Nodes) []*Node {
 // inlined function, substituting references to input/output
 // parameters with ones to the tmpnames, and substituting returns with
 // assignments to the output.
-func (subst *inlsubst) node(n *Node) *Node {
+func (subst *inlsubst) node(n *ir.Node) *ir.Node {
        if n == nil {
                return nil
        }
 
        switch n.Op {
-       case ONAME:
+       case ir.ONAME:
                if inlvar := subst.inlvars[n]; inlvar != nil { // These will be set during inlnode
                        if base.Flag.LowerM > 2 {
                                fmt.Printf("substituting name %+v  ->  %+v\n", n, inlvar)
@@ -1322,10 +1323,10 @@ func (subst *inlsubst) node(n *Node) *Node {
                }
                return n
 
-       case OMETHEXPR:
+       case ir.OMETHEXPR:
                return n
 
-       case OLITERAL, ONIL, OTYPE:
+       case ir.OLITERAL, ir.ONIL, ir.OTYPE:
                // If n is a named constant or type, we can continue
                // using it in the inline copy. Otherwise, make a copy
                // so we can update the line number.
@@ -1336,12 +1337,12 @@ func (subst *inlsubst) node(n *Node) *Node {
                // Since we don't handle bodies with closures, this return is guaranteed to belong to the current inlined function.
 
        //              dump("Return before substitution", n);
-       case ORETURN:
-               m := nodSym(OGOTO, nil, subst.retlabel)
+       case ir.ORETURN:
+               m := nodSym(ir.OGOTO, nil, subst.retlabel)
                m.Ninit.Set(subst.list(n.Ninit))
 
                if len(subst.retvars) != 0 && n.List.Len() != 0 {
-                       as := nod(OAS2, nil, nil)
+                       as := ir.Nod(ir.OAS2, nil, nil)
 
                        // Make a shallow copy of retvars.
                        // Otherwise OINLCALL.Rlist will be the same list,
@@ -1353,7 +1354,7 @@ func (subst *inlsubst) node(n *Node) *Node {
 
                        if subst.delayretvars {
                                for _, n := range as.List.Slice() {
-                                       as.Ninit.Append(nod(ODCL, n, nil))
+                                       as.Ninit.Append(ir.Nod(ir.ODCL, n, nil))
                                        n.Name.Defn = as
                                }
                        }
@@ -1368,8 +1369,8 @@ func (subst *inlsubst) node(n *Node) *Node {
                //              dump("Return after substitution", m);
                return m
 
-       case OGOTO, OLABEL:
-               m := n.copy()
+       case ir.OGOTO, ir.OLABEL:
+               m := ir.Copy(n)
                m.Pos = subst.updatedPos(m.Pos)
                m.Ninit.Set(nil)
                p := fmt.Sprintf("%s·%d", n.Sym.Name, inlgen)
@@ -1378,11 +1379,11 @@ func (subst *inlsubst) node(n *Node) *Node {
                return m
        }
 
-       m := n.copy()
+       m := ir.Copy(n)
        m.Pos = subst.updatedPos(m.Pos)
        m.Ninit.Set(nil)
 
-       if n.Op == OCLOSURE {
+       if n.Op == ir.OCLOSURE {
                base.Fatalf("cannot inline function containing closure: %+v", n)
        }
 
@@ -1408,10 +1409,10 @@ func (subst *inlsubst) updatedPos(xpos src.XPos) src.XPos {
        return base.Ctxt.PosTable.XPos(pos)
 }
 
-func pruneUnusedAutos(ll []*Node, vis *hairyVisitor) []*Node {
-       s := make([]*Node, 0, len(ll))
+func pruneUnusedAutos(ll []*ir.Node, vis *hairyVisitor) []*ir.Node {
+       s := make([]*ir.Node, 0, len(ll))
        for _, n := range ll {
-               if n.Class() == PAUTO {
+               if n.Class() == ir.PAUTO {
                        if _, found := vis.usedLocals[n]; !found {
                                continue
                        }
@@ -1423,19 +1424,19 @@ func pruneUnusedAutos(ll []*Node, vis *hairyVisitor) []*Node {
 
 // devirtualize replaces interface method calls within fn with direct
 // concrete-type method calls where applicable.
-func devirtualize(fn *Node) {
+func devirtualize(fn *ir.Node) {
        Curfn = fn
-       inspectList(fn.Nbody, func(n *Node) bool {
-               if n.Op == OCALLINTER {
+       ir.InspectList(fn.Nbody, func(n *ir.Node) bool {
+               if n.Op == ir.OCALLINTER {
                        devirtualizeCall(n)
                }
                return true
        })
 }
 
-func devirtualizeCall(call *Node) {
+func devirtualizeCall(call *ir.Node) {
        recv := staticValue(call.Left.Left)
-       if recv.Op != OCONVIFACE {
+       if recv.Op != ir.OCONVIFACE {
                return
        }
 
@@ -1444,23 +1445,23 @@ func devirtualizeCall(call *Node) {
                return
        }
 
-       x := nodl(call.Left.Pos, ODOTTYPE, call.Left.Left, nil)
+       x := ir.NodAt(call.Left.Pos, ir.ODOTTYPE, call.Left.Left, nil)
        x.Type = typ
-       x = nodlSym(call.Left.Pos, OXDOT, x, call.Left.Sym)
+       x = nodlSym(call.Left.Pos, ir.OXDOT, x, call.Left.Sym)
        x = typecheck(x, ctxExpr|ctxCallee)
        switch x.Op {
-       case ODOTMETH:
+       case ir.ODOTMETH:
                if base.Flag.LowerM != 0 {
                        base.WarnfAt(call.Pos, "devirtualizing %v to %v", call.Left, typ)
                }
-               call.Op = OCALLMETH
+               call.Op = ir.OCALLMETH
                call.Left = x
-       case ODOTINTER:
+       case ir.ODOTINTER:
                // Promoted method from embedded interface-typed field (#42279).
                if base.Flag.LowerM != 0 {
                        base.WarnfAt(call.Pos, "partially devirtualizing %v to %v", call.Left, typ)
                }
-               call.Op = OCALLINTER
+               call.Op = ir.OCALLINTER
                call.Left = x
        default:
                // TODO(mdempsky): Turn back into Fatalf after more testing.
index 30ef4d0eb203569a605301e4f0ab7e05194bb8b8..39d73867e4d79e9781760765c98e691a9b30a650 100644 (file)
@@ -6,6 +6,7 @@ package gc
 
 import (
        "cmd/compile/internal/base"
+       "cmd/compile/internal/ir"
        "cmd/compile/internal/syntax"
        "cmd/internal/objabi"
        "cmd/internal/src"
@@ -25,78 +26,51 @@ func isQuoted(s string) bool {
        return len(s) >= 2 && s[0] == '"' && s[len(s)-1] == '"'
 }
 
-type PragmaFlag int16
-
-const (
-       // Func pragmas.
-       Nointerface    PragmaFlag = 1 << iota
-       Noescape                  // func parameters don't escape
-       Norace                    // func must not have race detector annotations
-       Nosplit                   // func should not execute on separate stack
-       Noinline                  // func should not be inlined
-       NoCheckPtr                // func should not be instrumented by checkptr
-       CgoUnsafeArgs             // treat a pointer to one arg as a pointer to them all
-       UintptrEscapes            // pointers converted to uintptr escape
-
-       // Runtime-only func pragmas.
-       // See ../../../../runtime/README.md for detailed descriptions.
-       Systemstack        // func must run on system stack
-       Nowritebarrier     // emit compiler error instead of write barrier
-       Nowritebarrierrec  // error on write barrier in this or recursive callees
-       Yeswritebarrierrec // cancels Nowritebarrierrec in this function and callees
-
-       // Runtime and cgo type pragmas
-       NotInHeap // values of this type must not be heap allocated
-
-       // Go command pragmas
-       GoBuildPragma
-)
-
 const (
-       FuncPragmas = Nointerface |
-               Noescape |
-               Norace |
-               Nosplit |
-               Noinline |
-               NoCheckPtr |
-               CgoUnsafeArgs |
-               UintptrEscapes |
-               Systemstack |
-               Nowritebarrier |
-               Nowritebarrierrec |
-               Yeswritebarrierrec
-
-       TypePragmas = NotInHeap
+       FuncPragmas = ir.Nointerface |
+               ir.Noescape |
+               ir.Norace |
+               ir.Nosplit |
+               ir.Noinline |
+               ir.NoCheckPtr |
+               ir.CgoUnsafeArgs |
+               ir.UintptrEscapes |
+               ir.Systemstack |
+               ir.Nowritebarrier |
+               ir.Nowritebarrierrec |
+               ir.Yeswritebarrierrec
+
+       TypePragmas = ir.NotInHeap
 )
 
-func pragmaFlag(verb string) PragmaFlag {
+func pragmaFlag(verb string) ir.PragmaFlag {
        switch verb {
        case "go:build":
-               return GoBuildPragma
+               return ir.GoBuildPragma
        case "go:nointerface":
                if objabi.Fieldtrack_enabled != 0 {
-                       return Nointerface
+                       return ir.Nointerface
                }
        case "go:noescape":
-               return Noescape
+               return ir.Noescape
        case "go:norace":
-               return Norace
+               return ir.Norace
        case "go:nosplit":
-               return Nosplit | NoCheckPtr // implies NoCheckPtr (see #34972)
+               return ir.Nosplit | ir.NoCheckPtr // implies NoCheckPtr (see #34972)
        case "go:noinline":
-               return Noinline
+               return ir.Noinline
        case "go:nocheckptr":
-               return NoCheckPtr
+               return ir.NoCheckPtr
        case "go:systemstack":
-               return Systemstack
+               return ir.Systemstack
        case "go:nowritebarrier":
-               return Nowritebarrier
+               return ir.Nowritebarrier
        case "go:nowritebarrierrec":
-               return Nowritebarrierrec | Nowritebarrier // implies Nowritebarrier
+               return ir.Nowritebarrierrec | ir.Nowritebarrier // implies Nowritebarrier
        case "go:yeswritebarrierrec":
-               return Yeswritebarrierrec
+               return ir.Yeswritebarrierrec
        case "go:cgo_unsafe_args":
-               return CgoUnsafeArgs | NoCheckPtr // implies NoCheckPtr (see #34968)
+               return ir.CgoUnsafeArgs | ir.NoCheckPtr // implies NoCheckPtr (see #34968)
        case "go:uintptrescapes":
                // For the next function declared in the file
                // any uintptr arguments may be pointer values
@@ -109,9 +83,9 @@ func pragmaFlag(verb string) PragmaFlag {
                // call. The conversion to uintptr must appear
                // in the argument list.
                // Used in syscall/dll_windows.go.
-               return UintptrEscapes
+               return ir.UintptrEscapes
        case "go:notinheap":
-               return NotInHeap
+               return ir.NotInHeap
        }
        return 0
 }
index c66139027a61ca76182582c259750bc7035de01d..24e926602bf4e22bdca6c4a8c1122650097cbc5d 100644 (file)
@@ -10,6 +10,7 @@ import (
        "bufio"
        "bytes"
        "cmd/compile/internal/base"
+       "cmd/compile/internal/ir"
        "cmd/compile/internal/logopt"
        "cmd/compile/internal/ssa"
        "cmd/compile/internal/types"
@@ -73,17 +74,17 @@ func Main(archInit func(*Arch)) {
        // See bugs 31188 and 21945 (CLs 170638, 98075, 72371).
        base.Ctxt.UseBASEntries = base.Ctxt.Headtype != objabi.Hdarwin
 
-       localpkg = types.NewPkg("", "")
-       localpkg.Prefix = "\"\""
+       ir.LocalPkg = types.NewPkg("", "")
+       ir.LocalPkg.Prefix = "\"\""
 
        // We won't know localpkg's height until after import
        // processing. In the mean time, set to MaxPkgHeight to ensure
        // height comparisons at least work until then.
-       localpkg.Height = types.MaxPkgHeight
+       ir.LocalPkg.Height = types.MaxPkgHeight
 
        // pseudo-package, for scoping
-       builtinpkg = types.NewPkg("go.builtin", "") // TODO(gri) name this package go.builtin?
-       builtinpkg.Prefix = "go.builtin"            // not go%2ebuiltin
+       ir.BuiltinPkg = types.NewPkg("go.builtin", "") // TODO(gri) name this package go.builtin?
+       ir.BuiltinPkg.Prefix = "go.builtin"            // not go%2ebuiltin
 
        // pseudo-package, accessed by import "unsafe"
        unsafepkg = types.NewPkg("unsafe", "unsafe")
@@ -209,29 +210,18 @@ func Main(archInit func(*Arch)) {
        types.Widthptr = Widthptr
        types.Dowidth = dowidth
        types.Fatalf = base.Fatalf
-       types.Sconv = func(s *types.Sym, flag, mode int) string {
-               return sconv(s, FmtFlag(flag), fmtMode(mode))
-       }
-       types.Tconv = func(t *types.Type, flag, mode int) string {
-               return tconv(t, FmtFlag(flag), fmtMode(mode))
-       }
-       types.FormatSym = func(sym *types.Sym, s fmt.State, verb rune, mode int) {
-               symFormat(sym, s, verb, fmtMode(mode))
-       }
-       types.FormatType = func(t *types.Type, s fmt.State, verb rune, mode int) {
-               typeFormat(t, s, verb, fmtMode(mode))
-       }
+       ir.InstallTypeFormats()
        types.TypeLinkSym = func(t *types.Type) *obj.LSym {
                return typenamesym(t).Linksym()
        }
-       types.FmtLeft = int(FmtLeft)
-       types.FmtUnsigned = int(FmtUnsigned)
-       types.FErr = int(FErr)
+       types.FmtLeft = int(ir.FmtLeft)
+       types.FmtUnsigned = int(ir.FmtUnsigned)
+       types.FErr = int(ir.FErr)
        types.Ctxt = base.Ctxt
 
        initUniverse()
 
-       dclcontext = PEXTERN
+       dclcontext = ir.PEXTERN
 
        autogeneratedPos = makePos(src.NewFileBase("<autogenerated>", "<autogenerated>"), 1, 0)
 
@@ -263,7 +253,7 @@ func Main(archInit func(*Arch)) {
        timings.Start("fe", "typecheck", "top1")
        for i := 0; i < len(xtop); i++ {
                n := xtop[i]
-               if op := n.Op; op != ODCL && op != OAS && op != OAS2 && (op != ODCLTYPE || !n.Left.Name.Param.Alias()) {
+               if op := n.Op; op != ir.ODCL && op != ir.OAS && op != ir.OAS2 && (op != ir.ODCLTYPE || !n.Left.Name.Param.Alias()) {
                        xtop[i] = typecheck(n, ctxStmt)
                }
        }
@@ -275,7 +265,7 @@ func Main(archInit func(*Arch)) {
        timings.Start("fe", "typecheck", "top2")
        for i := 0; i < len(xtop); i++ {
                n := xtop[i]
-               if op := n.Op; op == ODCL || op == OAS || op == OAS2 || op == ODCLTYPE && n.Left.Name.Param.Alias() {
+               if op := n.Op; op == ir.ODCL || op == ir.OAS || op == ir.OAS2 || op == ir.ODCLTYPE && n.Left.Name.Param.Alias() {
                        xtop[i] = typecheck(n, ctxStmt)
                }
        }
@@ -286,7 +276,7 @@ func Main(archInit func(*Arch)) {
        var fcount int64
        for i := 0; i < len(xtop); i++ {
                n := xtop[i]
-               if n.Op == ODCLFUNC {
+               if n.Op == ir.ODCLFUNC {
                        Curfn = n
                        decldepth = 1
                        errorsBefore := base.Errors()
@@ -316,7 +306,7 @@ func Main(archInit func(*Arch)) {
        // because variables captured by value do not escape.
        timings.Start("fe", "capturevars")
        for _, n := range xtop {
-               if n.Op == ODCLFUNC && n.Func.OClosure != nil {
+               if n.Op == ir.ODCLFUNC && n.Func.OClosure != nil {
                        Curfn = n
                        capturevars(n)
                }
@@ -340,7 +330,7 @@ func Main(archInit func(*Arch)) {
 
        if base.Flag.LowerL != 0 {
                // Find functions that can be inlined and clone them before walk expands them.
-               visitBottomUp(xtop, func(list []*Node, recursive bool) {
+               visitBottomUp(xtop, func(list []*ir.Node, recursive bool) {
                        numfns := numNonClosures(list)
                        for _, n := range list {
                                if !recursive || numfns > 1 {
@@ -350,7 +340,7 @@ func Main(archInit func(*Arch)) {
                                        caninl(n)
                                } else {
                                        if base.Flag.LowerM > 1 {
-                                               fmt.Printf("%v: cannot inline %v: recursive\n", n.Line(), n.Func.Nname)
+                                               fmt.Printf("%v: cannot inline %v: recursive\n", ir.Line(n), n.Func.Nname)
                                        }
                                }
                                inlcalls(n)
@@ -359,7 +349,7 @@ func Main(archInit func(*Arch)) {
        }
 
        for _, n := range xtop {
-               if n.Op == ODCLFUNC {
+               if n.Op == ir.ODCLFUNC {
                        devirtualize(n)
                }
        }
@@ -389,7 +379,7 @@ func Main(archInit func(*Arch)) {
        // before walk reaches a call of a closure.
        timings.Start("fe", "xclosures")
        for _, n := range xtop {
-               if n.Op == ODCLFUNC && n.Func.OClosure != nil {
+               if n.Op == ir.ODCLFUNC && n.Func.OClosure != nil {
                        Curfn = n
                        transformclosure(n)
                }
@@ -412,7 +402,7 @@ func Main(archInit func(*Arch)) {
        fcount = 0
        for i := 0; i < len(xtop); i++ {
                n := xtop[i]
-               if n.Op == ODCLFUNC {
+               if n.Op == ir.ODCLFUNC {
                        funccompile(n)
                        fcount++
                }
@@ -440,7 +430,7 @@ func Main(archInit func(*Arch)) {
        // Phase 9: Check external declarations.
        timings.Start("be", "externaldcls")
        for i, n := range externdcl {
-               if n.Op == ONAME {
+               if n.Op == ir.ONAME {
                        externdcl[i] = typecheck(externdcl[i], ctxExpr)
                }
        }
@@ -491,7 +481,7 @@ func Main(archInit func(*Arch)) {
 }
 
 // numNonClosures returns the number of functions in list which are not closures.
-func numNonClosures(list []*Node) int {
+func numNonClosures(list []*ir.Node) int {
        count := 0
        for _, n := range list {
                if n.Func.OClosure == nil {
@@ -934,14 +924,14 @@ func pkgnotused(lineno src.XPos, path string, name string) {
 }
 
 func mkpackage(pkgname string) {
-       if localpkg.Name == "" {
+       if ir.LocalPkg.Name == "" {
                if pkgname == "_" {
                        base.Errorf("invalid package name _")
                }
-               localpkg.Name = pkgname
+               ir.LocalPkg.Name = pkgname
        } else {
-               if pkgname != localpkg.Name {
-                       base.Errorf("package %s; expected %s", pkgname, localpkg.Name)
+               if pkgname != ir.LocalPkg.Name {
+                       base.Errorf("package %s; expected %s", pkgname, ir.LocalPkg.Name)
                }
        }
 }
@@ -954,12 +944,12 @@ func clearImports() {
        }
        var unused []importedPkg
 
-       for _, s := range localpkg.Syms {
-               n := asNode(s.Def)
+       for _, s := range ir.LocalPkg.Syms {
+               n := ir.AsNode(s.Def)
                if n == nil {
                        continue
                }
-               if n.Op == OPACK {
+               if n.Op == ir.OPACK {
                        // throw away top-level package name left over
                        // from previous file.
                        // leave s->block set to cause redeclaration
@@ -990,7 +980,7 @@ func clearImports() {
 }
 
 func IsAlias(sym *types.Sym) bool {
-       return sym.Def != nil && asNode(sym.Def).Sym != sym
+       return sym.Def != nil && ir.AsNode(sym.Def).Sym != sym
 }
 
 // recordFlags records the specified command-line flags to be placed
@@ -1057,7 +1047,7 @@ func recordPackageName() {
        // together two package main archives. So allow dups.
        s.Set(obj.AttrDuplicateOK, true)
        base.Ctxt.Data = append(base.Ctxt.Data, s)
-       s.P = []byte(localpkg.Name)
+       s.P = []byte(ir.LocalPkg.Name)
 }
 
 // currentLang returns the current language version.
@@ -1084,9 +1074,9 @@ var langWant lang
 func langSupported(major, minor int, pkg *types.Pkg) bool {
        if pkg == nil {
                // TODO(mdempsky): Set Pkg for local types earlier.
-               pkg = localpkg
+               pkg = ir.LocalPkg
        }
-       if pkg != localpkg {
+       if pkg != ir.LocalPkg {
                // Assume imported packages passed type-checking.
                return true
        }
index 63d2a12c079d6a3cd850406de94fedf696e63956..8fa6d02f2c2c0d8a8b3489cd704bda38d725feb8 100644 (file)
@@ -35,7 +35,10 @@ func main() {
        fmt.Fprintln(&b)
        fmt.Fprintln(&b, "package gc")
        fmt.Fprintln(&b)
-       fmt.Fprintln(&b, `import "cmd/compile/internal/types"`)
+       fmt.Fprintln(&b, `import (`)
+       fmt.Fprintln(&b, `      "cmd/compile/internal/ir"`)
+       fmt.Fprintln(&b, `      "cmd/compile/internal/types"`)
+       fmt.Fprintln(&b, `)`)
 
        mkbuiltin(&b, "runtime")
 
@@ -144,12 +147,12 @@ func (i *typeInterner) mktype(t ast.Expr) string {
                case "rune":
                        return "types.Runetype"
                }
-               return fmt.Sprintf("types.Types[T%s]", strings.ToUpper(t.Name))
+               return fmt.Sprintf("types.Types[types.T%s]", strings.ToUpper(t.Name))
        case *ast.SelectorExpr:
                if t.X.(*ast.Ident).Name != "unsafe" || t.Sel.Name != "Pointer" {
                        log.Fatalf("unhandled type: %#v", t)
                }
-               return "types.Types[TUNSAFEPTR]"
+               return "types.Types[types.TUNSAFEPTR]"
 
        case *ast.ArrayType:
                if t.Len == nil {
@@ -171,7 +174,7 @@ func (i *typeInterner) mktype(t ast.Expr) string {
                if len(t.Methods.List) != 0 {
                        log.Fatal("non-empty interfaces unsupported")
                }
-               return "types.Types[TINTER]"
+               return "types.Types[types.TINTER]"
        case *ast.MapType:
                return fmt.Sprintf("types.NewMap(%s, %s)", i.subtype(t.Key), i.subtype(t.Value))
        case *ast.StarExpr:
@@ -204,7 +207,7 @@ func (i *typeInterner) fields(fl *ast.FieldList, keepNames bool) string {
                        }
                }
        }
-       return fmt.Sprintf("[]*Node{%s}", strings.Join(res, ", "))
+       return fmt.Sprintf("[]*ir.Node{%s}", strings.Join(res, ", "))
 }
 
 func intconst(e ast.Expr) int64 {
index 6dae2cd0a41d2b2144754ab000853548fcfe57e7..eeed3740f063c228dfd0a5ed3eb19014d9d67bcd 100644 (file)
@@ -17,6 +17,7 @@ import (
        "unicode/utf8"
 
        "cmd/compile/internal/base"
+       "cmd/compile/internal/ir"
        "cmd/compile/internal/syntax"
        "cmd/compile/internal/types"
        "cmd/internal/obj"
@@ -74,7 +75,7 @@ func parseFiles(filenames []string) uint {
                testdclstack()
        }
 
-       localpkg.Height = myheight
+       ir.LocalPkg.Height = myheight
 
        return lines
 }
@@ -140,7 +141,7 @@ type noder struct {
        linknames      []linkname
        pragcgobuf     [][]string
        err            chan syntax.Error
-       scope          ScopeID
+       scope          ir.ScopeID
        importedUnsafe bool
        importedEmbed  bool
 
@@ -151,7 +152,7 @@ type noder struct {
        lastCloseScopePos syntax.Pos
 }
 
-func (p *noder) funcBody(fn *Node, block *syntax.BlockStmt) {
+func (p *noder) funcBody(fn *ir.Node, block *syntax.BlockStmt) {
        oldScope := p.scope
        p.scope = 0
        funchdr(fn)
@@ -159,7 +160,7 @@ func (p *noder) funcBody(fn *Node, block *syntax.BlockStmt) {
        if block != nil {
                body := p.stmts(block.List)
                if body == nil {
-                       body = []*Node{nod(OEMPTY, nil, nil)}
+                       body = []*ir.Node{ir.Nod(ir.OEMPTY, nil, nil)}
                }
                fn.Nbody.Set(body)
 
@@ -177,7 +178,7 @@ func (p *noder) openScope(pos syntax.Pos) {
        if trackScopes {
                Curfn.Func.Parents = append(Curfn.Func.Parents, p.scope)
                p.scopeVars = append(p.scopeVars, len(Curfn.Func.Dcl))
-               p.scope = ScopeID(len(Curfn.Func.Parents))
+               p.scope = ir.ScopeID(len(Curfn.Func.Parents))
 
                p.markScope(pos)
        }
@@ -202,7 +203,7 @@ func (p *noder) closeScope(pos syntax.Pos) {
 
                        nmarks := len(Curfn.Func.Marks)
                        Curfn.Func.Marks[nmarks-1].Scope = p.scope
-                       prevScope := ScopeID(0)
+                       prevScope := ir.ScopeID(0)
                        if nmarks >= 2 {
                                prevScope = Curfn.Func.Marks[nmarks-2].Scope
                        }
@@ -223,7 +224,7 @@ func (p *noder) markScope(pos syntax.Pos) {
        if i := len(Curfn.Func.Marks); i > 0 && Curfn.Func.Marks[i-1].Pos == xpos {
                Curfn.Func.Marks[i-1].Scope = p.scope
        } else {
-               Curfn.Func.Marks = append(Curfn.Func.Marks, Mark{xpos, p.scope})
+               Curfn.Func.Marks = append(Curfn.Func.Marks, ir.Mark{Pos: xpos, Scope: p.scope})
        }
 }
 
@@ -251,7 +252,7 @@ func (p *noder) node() {
        mkpackage(p.file.PkgName.Value)
 
        if pragma, ok := p.file.Pragma.(*Pragma); ok {
-               pragma.Flag &^= GoBuildPragma
+               pragma.Flag &^= ir.GoBuildPragma
                p.checkUnused(pragma)
        }
 
@@ -293,7 +294,7 @@ func (p *noder) node() {
        clearImports()
 }
 
-func (p *noder) decls(decls []syntax.Decl) (l []*Node) {
+func (p *noder) decls(decls []syntax.Decl) (l []*ir.Node) {
        var cs constState
 
        for _, decl := range decls {
@@ -355,7 +356,7 @@ func (p *noder) importDecl(imp *syntax.ImportDecl) {
                my = lookup(ipkg.Name)
        }
 
-       pack := p.nod(imp, OPACK, nil, nil)
+       pack := p.nod(imp, ir.OPACK, nil, nil)
        pack.Sym = my
        pack.Name.Pkg = ipkg
 
@@ -372,16 +373,16 @@ func (p *noder) importDecl(imp *syntax.ImportDecl) {
        if my.Def != nil {
                redeclare(pack.Pos, my, "as imported package name")
        }
-       my.Def = asTypesNode(pack)
+       my.Def = ir.AsTypesNode(pack)
        my.Lastlineno = pack.Pos
        my.Block = 1 // at top level
 }
 
-func (p *noder) varDecl(decl *syntax.VarDecl) []*Node {
+func (p *noder) varDecl(decl *syntax.VarDecl) []*ir.Node {
        names := p.declNames(decl.NameList)
        typ := p.typeExprOrNil(decl.Type)
 
-       var exprs []*Node
+       var exprs []*ir.Node
        if decl.Values != nil {
                exprs = p.exprList(decl.Values)
        }
@@ -413,12 +414,12 @@ func (p *noder) varDecl(decl *syntax.VarDecl) []*Node {
 // constant declarations are handled correctly (e.g., issue 15550).
 type constState struct {
        group  *syntax.Group
-       typ    *Node
-       values []*Node
+       typ    *ir.Node
+       values []*ir.Node
        iota   int64
 }
 
-func (p *noder) constDecl(decl *syntax.ConstDecl, cs *constState) []*Node {
+func (p *noder) constDecl(decl *syntax.ConstDecl, cs *constState) []*ir.Node {
        if decl.Group == nil || decl.Group != cs.group {
                *cs = constState{
                        group: decl.Group,
@@ -432,7 +433,7 @@ func (p *noder) constDecl(decl *syntax.ConstDecl, cs *constState) []*Node {
        names := p.declNames(decl.NameList)
        typ := p.typeExprOrNil(decl.Type)
 
-       var values []*Node
+       var values []*ir.Node
        if decl.Values != nil {
                values = p.exprList(decl.Values)
                cs.typ, cs.values = typ, values
@@ -443,7 +444,7 @@ func (p *noder) constDecl(decl *syntax.ConstDecl, cs *constState) []*Node {
                typ, values = cs.typ, cs.values
        }
 
-       nn := make([]*Node, 0, len(names))
+       nn := make([]*ir.Node, 0, len(names))
        for i, n := range names {
                if i >= len(values) {
                        base.Errorf("missing value in const declaration")
@@ -454,14 +455,14 @@ func (p *noder) constDecl(decl *syntax.ConstDecl, cs *constState) []*Node {
                        v = treecopy(v, n.Pos)
                }
 
-               n.Op = OLITERAL
+               n.Op = ir.OLITERAL
                declare(n, dclcontext)
 
                n.Name.Param.Ntype = typ
                n.Name.Defn = v
                n.SetIota(cs.iota)
 
-               nn = append(nn, p.nod(decl, ODCLCONST, n, nil))
+               nn = append(nn, p.nod(decl, ir.ODCLCONST, n, nil))
        }
 
        if len(values) > len(names) {
@@ -473,9 +474,9 @@ func (p *noder) constDecl(decl *syntax.ConstDecl, cs *constState) []*Node {
        return nn
 }
 
-func (p *noder) typeDecl(decl *syntax.TypeDecl) *Node {
+func (p *noder) typeDecl(decl *syntax.TypeDecl) *ir.Node {
        n := p.declName(decl.Name)
-       n.Op = OTYPE
+       n.Op = ir.OTYPE
        declare(n, dclcontext)
 
        // decl.Type may be nil but in that case we got a syntax error during parsing
@@ -492,31 +493,31 @@ func (p *noder) typeDecl(decl *syntax.TypeDecl) *Node {
                p.checkUnused(pragma)
        }
 
-       nod := p.nod(decl, ODCLTYPE, n, nil)
-       if param.Alias() && !langSupported(1, 9, localpkg) {
+       nod := p.nod(decl, ir.ODCLTYPE, n, nil)
+       if param.Alias() && !langSupported(1, 9, ir.LocalPkg) {
                base.ErrorfAt(nod.Pos, "type aliases only supported as of -lang=go1.9")
        }
        return nod
 }
 
-func (p *noder) declNames(names []*syntax.Name) []*Node {
-       nodes := make([]*Node, 0, len(names))
+func (p *noder) declNames(names []*syntax.Name) []*ir.Node {
+       nodes := make([]*ir.Node, 0, len(names))
        for _, name := range names {
                nodes = append(nodes, p.declName(name))
        }
        return nodes
 }
 
-func (p *noder) declName(name *syntax.Name) *Node {
+func (p *noder) declName(name *syntax.Name) *ir.Node {
        n := dclname(p.name(name))
        n.Pos = p.pos(name)
        return n
 }
 
-func (p *noder) funcDecl(fun *syntax.FuncDecl) *Node {
+func (p *noder) funcDecl(fun *syntax.FuncDecl) *ir.Node {
        name := p.name(fun.Name)
        t := p.signature(fun.Recv, fun.Type)
-       f := p.nod(fun, ODCLFUNC, nil, nil)
+       f := p.nod(fun, ir.ODCLFUNC, nil, nil)
 
        if fun.Recv == nil {
                if name.Name == "init" {
@@ -526,14 +527,14 @@ func (p *noder) funcDecl(fun *syntax.FuncDecl) *Node {
                        }
                }
 
-               if localpkg.Name == "main" && name.Name == "main" {
+               if ir.LocalPkg.Name == "main" && name.Name == "main" {
                        if t.List.Len() > 0 || t.Rlist.Len() > 0 {
                                base.ErrorfAt(f.Pos, "func main must have no arguments and no return values")
                        }
                }
        } else {
                f.Func.Shortname = name
-               name = nblank.Sym // filled in by typecheckfunc
+               name = ir.BlankNode.Sym // filled in by typecheckfunc
        }
 
        f.Func.Nname = newfuncnamel(p.pos(fun.Name), name, f.Func)
@@ -542,7 +543,7 @@ func (p *noder) funcDecl(fun *syntax.FuncDecl) *Node {
 
        if pragma, ok := fun.Pragma.(*Pragma); ok {
                f.Func.Pragma = pragma.Flag & FuncPragmas
-               if pragma.Flag&Systemstack != 0 && pragma.Flag&Nosplit != 0 {
+               if pragma.Flag&ir.Systemstack != 0 && pragma.Flag&ir.Nosplit != 0 {
                        base.ErrorfAt(f.Pos, "go:nosplit and go:systemstack cannot be combined")
                }
                pragma.Flag &^= FuncPragmas
@@ -550,22 +551,22 @@ func (p *noder) funcDecl(fun *syntax.FuncDecl) *Node {
        }
 
        if fun.Recv == nil {
-               declare(f.Func.Nname, PFUNC)
+               declare(f.Func.Nname, ir.PFUNC)
        }
 
        p.funcBody(f, fun.Body)
 
        if fun.Body != nil {
-               if f.Func.Pragma&Noescape != 0 {
+               if f.Func.Pragma&ir.Noescape != 0 {
                        base.ErrorfAt(f.Pos, "can only use //go:noescape with external func implementations")
                }
        } else {
-               if base.Flag.Complete || strings.HasPrefix(f.funcname(), "init.") {
+               if base.Flag.Complete || strings.HasPrefix(ir.FuncName(f), "init.") {
                        // Linknamed functions are allowed to have no body. Hopefully
                        // the linkname target has a body. See issue 23311.
                        isLinknamed := false
                        for _, n := range p.linknames {
-                               if f.funcname() == n.local {
+                               if ir.FuncName(f) == n.local {
                                        isLinknamed = true
                                        break
                                }
@@ -579,8 +580,8 @@ func (p *noder) funcDecl(fun *syntax.FuncDecl) *Node {
        return f
 }
 
-func (p *noder) signature(recv *syntax.Field, typ *syntax.FuncType) *Node {
-       n := p.nod(typ, OTFUNC, nil, nil)
+func (p *noder) signature(recv *syntax.Field, typ *syntax.FuncType) *ir.Node {
+       n := p.nod(typ, ir.OTFUNC, nil, nil)
        if recv != nil {
                n.Left = p.param(recv, false, false)
        }
@@ -589,8 +590,8 @@ func (p *noder) signature(recv *syntax.Field, typ *syntax.FuncType) *Node {
        return n
 }
 
-func (p *noder) params(params []*syntax.Field, dddOk bool) []*Node {
-       nodes := make([]*Node, 0, len(params))
+func (p *noder) params(params []*syntax.Field, dddOk bool) []*ir.Node {
+       nodes := make([]*ir.Node, 0, len(params))
        for i, param := range params {
                p.setlineno(param)
                nodes = append(nodes, p.param(param, dddOk, i+1 == len(params)))
@@ -598,17 +599,17 @@ func (p *noder) params(params []*syntax.Field, dddOk bool) []*Node {
        return nodes
 }
 
-func (p *noder) param(param *syntax.Field, dddOk, final bool) *Node {
+func (p *noder) param(param *syntax.Field, dddOk, final bool) *ir.Node {
        var name *types.Sym
        if param.Name != nil {
                name = p.name(param.Name)
        }
 
        typ := p.typeExpr(param.Type)
-       n := p.nodSym(param, ODCLFIELD, typ, name)
+       n := p.nodSym(param, ir.ODCLFIELD, typ, name)
 
        // rewrite ...T parameter
-       if typ.Op == ODDD {
+       if typ.Op == ir.ODDD {
                if !dddOk {
                        // We mark these as syntax errors to get automatic elimination
                        // of multiple such errors per line (see ErrorfAt in subr.go).
@@ -620,7 +621,7 @@ func (p *noder) param(param *syntax.Field, dddOk, final bool) *Node {
                                p.errorAt(param.Name.Pos(), "syntax error: cannot use ... with non-final parameter %s", param.Name.Value)
                        }
                }
-               typ.Op = OTARRAY
+               typ.Op = ir.OTARRAY
                typ.Right = typ.Left
                typ.Left = nil
                n.SetIsDDD(true)
@@ -632,22 +633,22 @@ func (p *noder) param(param *syntax.Field, dddOk, final bool) *Node {
        return n
 }
 
-func (p *noder) exprList(expr syntax.Expr) []*Node {
+func (p *noder) exprList(expr syntax.Expr) []*ir.Node {
        if list, ok := expr.(*syntax.ListExpr); ok {
                return p.exprs(list.ElemList)
        }
-       return []*Node{p.expr(expr)}
+       return []*ir.Node{p.expr(expr)}
 }
 
-func (p *noder) exprs(exprs []syntax.Expr) []*Node {
-       nodes := make([]*Node, 0, len(exprs))
+func (p *noder) exprs(exprs []syntax.Expr) []*ir.Node {
+       nodes := make([]*ir.Node, 0, len(exprs))
        for _, expr := range exprs {
                nodes = append(nodes, p.expr(expr))
        }
        return nodes
 }
 
-func (p *noder) expr(expr syntax.Expr) *Node {
+func (p *noder) expr(expr syntax.Expr) *ir.Node {
        p.setlineno(expr)
        switch expr := expr.(type) {
        case nil, *syntax.BadExpr:
@@ -655,14 +656,14 @@ func (p *noder) expr(expr syntax.Expr) *Node {
        case *syntax.Name:
                return p.mkname(expr)
        case *syntax.BasicLit:
-               n := nodlit(p.basicLit(expr))
+               n := ir.NewLiteral(p.basicLit(expr))
                if expr.Kind == syntax.RuneLit {
                        n.Type = types.UntypedRune
                }
                n.SetDiag(expr.Bad) // avoid follow-on errors if there was a syntax error
                return n
        case *syntax.CompositeLit:
-               n := p.nod(expr, OCOMPLIT, nil, nil)
+               n := p.nod(expr, ir.OCOMPLIT, nil, nil)
                if expr.Type != nil {
                        n.Right = p.expr(expr.Type)
                }
@@ -675,30 +676,30 @@ func (p *noder) expr(expr syntax.Expr) *Node {
                return n
        case *syntax.KeyValueExpr:
                // use position of expr.Key rather than of expr (which has position of ':')
-               return p.nod(expr.Key, OKEY, p.expr(expr.Key), p.wrapname(expr.Value, p.expr(expr.Value)))
+               return p.nod(expr.Key, ir.OKEY, p.expr(expr.Key), p.wrapname(expr.Value, p.expr(expr.Value)))
        case *syntax.FuncLit:
                return p.funcLit(expr)
        case *syntax.ParenExpr:
-               return p.nod(expr, OPAREN, p.expr(expr.X), nil)
+               return p.nod(expr, ir.OPAREN, p.expr(expr.X), nil)
        case *syntax.SelectorExpr:
                // parser.new_dotname
                obj := p.expr(expr.X)
-               if obj.Op == OPACK {
+               if obj.Op == ir.OPACK {
                        obj.Name.SetUsed(true)
                        return importName(obj.Name.Pkg.Lookup(expr.Sel.Value))
                }
-               n := nodSym(OXDOT, obj, p.name(expr.Sel))
+               n := nodSym(ir.OXDOT, obj, p.name(expr.Sel))
                n.Pos = p.pos(expr) // lineno may have been changed by p.expr(expr.X)
                return n
        case *syntax.IndexExpr:
-               return p.nod(expr, OINDEX, p.expr(expr.X), p.expr(expr.Index))
+               return p.nod(expr, ir.OINDEX, p.expr(expr.X), p.expr(expr.Index))
        case *syntax.SliceExpr:
-               op := OSLICE
+               op := ir.OSLICE
                if expr.Full {
-                       op = OSLICE3
+                       op = ir.OSLICE3
                }
                n := p.nod(expr, op, p.expr(expr.X), nil)
-               var index [3]*Node
+               var index [3]*ir.Node
                for i, x := range &expr.Index {
                        if x != nil {
                                index[i] = p.expr(x)
@@ -707,7 +708,7 @@ func (p *noder) expr(expr syntax.Expr) *Node {
                n.SetSliceBounds(index[0], index[1], index[2])
                return n
        case *syntax.AssertExpr:
-               return p.nod(expr, ODOTTYPE, p.expr(expr.X), p.typeExpr(expr.Type))
+               return p.nod(expr, ir.ODOTTYPE, p.expr(expr.X), p.typeExpr(expr.Type))
        case *syntax.Operation:
                if expr.Op == syntax.Add && expr.Y != nil {
                        return p.sum(expr)
@@ -718,23 +719,23 @@ func (p *noder) expr(expr syntax.Expr) *Node {
                }
                return p.nod(expr, p.binOp(expr.Op), x, p.expr(expr.Y))
        case *syntax.CallExpr:
-               n := p.nod(expr, OCALL, p.expr(expr.Fun), nil)
+               n := p.nod(expr, ir.OCALL, p.expr(expr.Fun), nil)
                n.List.Set(p.exprs(expr.ArgList))
                n.SetIsDDD(expr.HasDots)
                return n
 
        case *syntax.ArrayType:
-               var len *Node
+               var len *ir.Node
                if expr.Len != nil {
                        len = p.expr(expr.Len)
                } else {
-                       len = p.nod(expr, ODDD, nil, nil)
+                       len = p.nod(expr, ir.ODDD, nil, nil)
                }
-               return p.nod(expr, OTARRAY, len, p.typeExpr(expr.Elem))
+               return p.nod(expr, ir.OTARRAY, len, p.typeExpr(expr.Elem))
        case *syntax.SliceType:
-               return p.nod(expr, OTARRAY, nil, p.typeExpr(expr.Elem))
+               return p.nod(expr, ir.OTARRAY, nil, p.typeExpr(expr.Elem))
        case *syntax.DotsType:
-               return p.nod(expr, ODDD, p.typeExpr(expr.Elem), nil)
+               return p.nod(expr, ir.ODDD, p.typeExpr(expr.Elem), nil)
        case *syntax.StructType:
                return p.structType(expr)
        case *syntax.InterfaceType:
@@ -742,17 +743,17 @@ func (p *noder) expr(expr syntax.Expr) *Node {
        case *syntax.FuncType:
                return p.signature(nil, expr)
        case *syntax.MapType:
-               return p.nod(expr, OTMAP, p.typeExpr(expr.Key), p.typeExpr(expr.Value))
+               return p.nod(expr, ir.OTMAP, p.typeExpr(expr.Key), p.typeExpr(expr.Value))
        case *syntax.ChanType:
-               n := p.nod(expr, OTCHAN, p.typeExpr(expr.Elem), nil)
+               n := p.nod(expr, ir.OTCHAN, p.typeExpr(expr.Elem), nil)
                n.SetTChanDir(p.chanDir(expr.Dir))
                return n
 
        case *syntax.TypeSwitchGuard:
-               n := p.nod(expr, OTYPESW, nil, p.expr(expr.X))
+               n := p.nod(expr, ir.OTYPESW, nil, p.expr(expr.X))
                if expr.Lhs != nil {
                        n.Left = p.declName(expr.Lhs)
-                       if n.Left.isBlank() {
+                       if ir.IsBlank(n.Left) {
                                base.Errorf("invalid variable name %v in type switch", n.Left)
                        }
                }
@@ -764,7 +765,7 @@ func (p *noder) expr(expr syntax.Expr) *Node {
 // sum efficiently handles very large summation expressions (such as
 // in issue #16394). In particular, it avoids left recursion and
 // collapses string literals.
-func (p *noder) sum(x syntax.Expr) *Node {
+func (p *noder) sum(x syntax.Expr) *ir.Node {
        // While we need to handle long sums with asymptotic
        // efficiency, the vast majority of sums are very small: ~95%
        // have only 2 or 3 operands, and ~99% of string literals are
@@ -799,11 +800,11 @@ func (p *noder) sum(x syntax.Expr) *Node {
        // handle correctly. For now, we avoid these problems by
        // treating named string constants the same as non-constant
        // operands.
-       var nstr *Node
+       var nstr *ir.Node
        chunks := make([]string, 0, 1)
 
        n := p.expr(x)
-       if Isconst(n, constant.String) && n.Sym == nil {
+       if ir.IsConst(n, constant.String) && n.Sym == nil {
                nstr = n
                chunks = append(chunks, nstr.StringVal())
        }
@@ -812,7 +813,7 @@ func (p *noder) sum(x syntax.Expr) *Node {
                add := adds[i]
 
                r := p.expr(add.Y)
-               if Isconst(r, constant.String) && r.Sym == nil {
+               if ir.IsConst(r, constant.String) && r.Sym == nil {
                        if nstr != nil {
                                // Collapse r into nstr instead of adding to n.
                                chunks = append(chunks, r.StringVal())
@@ -828,7 +829,7 @@ func (p *noder) sum(x syntax.Expr) *Node {
                        nstr = nil
                        chunks = chunks[:0]
                }
-               n = p.nod(add, OADD, n, r)
+               n = p.nod(add, ir.OADD, n, r)
        }
        if len(chunks) > 1 {
                nstr.SetVal(constant.MakeString(strings.Join(chunks, "")))
@@ -837,12 +838,12 @@ func (p *noder) sum(x syntax.Expr) *Node {
        return n
 }
 
-func (p *noder) typeExpr(typ syntax.Expr) *Node {
+func (p *noder) typeExpr(typ syntax.Expr) *ir.Node {
        // TODO(mdempsky): Be stricter? typecheck should handle errors anyway.
        return p.expr(typ)
 }
 
-func (p *noder) typeExprOrNil(typ syntax.Expr) *Node {
+func (p *noder) typeExprOrNil(typ syntax.Expr) *ir.Node {
        if typ != nil {
                return p.expr(typ)
        }
@@ -861,15 +862,15 @@ func (p *noder) chanDir(dir syntax.ChanDir) types.ChanDir {
        panic("unhandled ChanDir")
 }
 
-func (p *noder) structType(expr *syntax.StructType) *Node {
-       l := make([]*Node, 0, len(expr.FieldList))
+func (p *noder) structType(expr *syntax.StructType) *ir.Node {
+       l := make([]*ir.Node, 0, len(expr.FieldList))
        for i, field := range expr.FieldList {
                p.setlineno(field)
-               var n *Node
+               var n *ir.Node
                if field.Name == nil {
                        n = p.embedded(field.Type)
                } else {
-                       n = p.nodSym(field, ODCLFIELD, p.typeExpr(field.Type), p.name(field.Name))
+                       n = p.nodSym(field, ir.ODCLFIELD, p.typeExpr(field.Type), p.name(field.Name))
                }
                if i < len(expr.TagList) && expr.TagList[i] != nil {
                        n.SetVal(p.basicLit(expr.TagList[i]))
@@ -878,29 +879,29 @@ func (p *noder) structType(expr *syntax.StructType) *Node {
        }
 
        p.setlineno(expr)
-       n := p.nod(expr, OTSTRUCT, nil, nil)
+       n := p.nod(expr, ir.OTSTRUCT, nil, nil)
        n.List.Set(l)
        return n
 }
 
-func (p *noder) interfaceType(expr *syntax.InterfaceType) *Node {
-       l := make([]*Node, 0, len(expr.MethodList))
+func (p *noder) interfaceType(expr *syntax.InterfaceType) *ir.Node {
+       l := make([]*ir.Node, 0, len(expr.MethodList))
        for _, method := range expr.MethodList {
                p.setlineno(method)
-               var n *Node
+               var n *ir.Node
                if method.Name == nil {
-                       n = p.nodSym(method, ODCLFIELD, importName(p.packname(method.Type)), nil)
+                       n = p.nodSym(method, ir.ODCLFIELD, importName(p.packname(method.Type)), nil)
                } else {
                        mname := p.name(method.Name)
                        sig := p.typeExpr(method.Type)
                        sig.Left = fakeRecv()
-                       n = p.nodSym(method, ODCLFIELD, sig, mname)
+                       n = p.nodSym(method, ir.ODCLFIELD, sig, mname)
                        ifacedcl(n)
                }
                l = append(l, n)
        }
 
-       n := p.nod(expr, OTINTER, nil, nil)
+       n := p.nod(expr, ir.OTINTER, nil, nil)
        n.List.Set(l)
        return n
 }
@@ -915,15 +916,15 @@ func (p *noder) packname(expr syntax.Expr) *types.Sym {
                return name
        case *syntax.SelectorExpr:
                name := p.name(expr.X.(*syntax.Name))
-               def := asNode(name.Def)
+               def := ir.AsNode(name.Def)
                if def == nil {
                        base.Errorf("undefined: %v", name)
                        return name
                }
                var pkg *types.Pkg
-               if def.Op != OPACK {
+               if def.Op != ir.OPACK {
                        base.Errorf("%v is not a package", name)
-                       pkg = localpkg
+                       pkg = ir.LocalPkg
                } else {
                        def.Name.SetUsed(true)
                        pkg = def.Name.Pkg
@@ -933,7 +934,7 @@ func (p *noder) packname(expr syntax.Expr) *types.Sym {
        panic(fmt.Sprintf("unexpected packname: %#v", expr))
 }
 
-func (p *noder) embedded(typ syntax.Expr) *Node {
+func (p *noder) embedded(typ syntax.Expr) *ir.Node {
        op, isStar := typ.(*syntax.Operation)
        if isStar {
                if op.Op != syntax.Mul || op.Y != nil {
@@ -943,25 +944,25 @@ func (p *noder) embedded(typ syntax.Expr) *Node {
        }
 
        sym := p.packname(typ)
-       n := p.nodSym(typ, ODCLFIELD, importName(sym), lookup(sym.Name))
+       n := p.nodSym(typ, ir.ODCLFIELD, importName(sym), lookup(sym.Name))
        n.SetEmbedded(true)
 
        if isStar {
-               n.Left = p.nod(op, ODEREF, n.Left, nil)
+               n.Left = p.nod(op, ir.ODEREF, n.Left, nil)
        }
        return n
 }
 
-func (p *noder) stmts(stmts []syntax.Stmt) []*Node {
+func (p *noder) stmts(stmts []syntax.Stmt) []*ir.Node {
        return p.stmtsFall(stmts, false)
 }
 
-func (p *noder) stmtsFall(stmts []syntax.Stmt, fallOK bool) []*Node {
-       var nodes []*Node
+func (p *noder) stmtsFall(stmts []syntax.Stmt, fallOK bool) []*ir.Node {
+       var nodes []*ir.Node
        for i, stmt := range stmts {
                s := p.stmtFall(stmt, fallOK && i+1 == len(stmts))
                if s == nil {
-               } else if s.Op == OBLOCK && s.Ninit.Len() == 0 {
+               } else if s.Op == ir.OBLOCK && s.Ninit.Len() == 0 {
                        nodes = append(nodes, s.List.Slice()...)
                } else {
                        nodes = append(nodes, s)
@@ -970,11 +971,11 @@ func (p *noder) stmtsFall(stmts []syntax.Stmt, fallOK bool) []*Node {
        return nodes
 }
 
-func (p *noder) stmt(stmt syntax.Stmt) *Node {
+func (p *noder) stmt(stmt syntax.Stmt) *ir.Node {
        return p.stmtFall(stmt, false)
 }
 
-func (p *noder) stmtFall(stmt syntax.Stmt, fallOK bool) *Node {
+func (p *noder) stmtFall(stmt syntax.Stmt, fallOK bool) *ir.Node {
        p.setlineno(stmt)
        switch stmt := stmt.(type) {
        case *syntax.EmptyStmt:
@@ -985,24 +986,24 @@ func (p *noder) stmtFall(stmt syntax.Stmt, fallOK bool) *Node {
                l := p.blockStmt(stmt)
                if len(l) == 0 {
                        // TODO(mdempsky): Line number?
-                       return nod(OEMPTY, nil, nil)
+                       return ir.Nod(ir.OEMPTY, nil, nil)
                }
                return liststmt(l)
        case *syntax.ExprStmt:
                return p.wrapname(stmt, p.expr(stmt.X))
        case *syntax.SendStmt:
-               return p.nod(stmt, OSEND, p.expr(stmt.Chan), p.expr(stmt.Value))
+               return p.nod(stmt, ir.OSEND, p.expr(stmt.Chan), p.expr(stmt.Value))
        case *syntax.DeclStmt:
                return liststmt(p.decls(stmt.DeclList))
        case *syntax.AssignStmt:
                if stmt.Op != 0 && stmt.Op != syntax.Def {
-                       n := p.nod(stmt, OASOP, p.expr(stmt.Lhs), p.expr(stmt.Rhs))
+                       n := p.nod(stmt, ir.OASOP, p.expr(stmt.Lhs), p.expr(stmt.Rhs))
                        n.SetImplicit(stmt.Rhs == syntax.ImplicitOne)
                        n.SetSubOp(p.binOp(stmt.Op))
                        return n
                }
 
-               n := p.nod(stmt, OAS, nil, nil) // assume common case
+               n := p.nod(stmt, ir.OAS, nil, nil) // assume common case
 
                rhs := p.exprList(stmt.Rhs)
                lhs := p.assignList(stmt.Lhs, n, stmt.Op == syntax.Def)
@@ -1012,26 +1013,26 @@ func (p *noder) stmtFall(stmt syntax.Stmt, fallOK bool) *Node {
                        n.Left = lhs[0]
                        n.Right = rhs[0]
                } else {
-                       n.Op = OAS2
+                       n.Op = ir.OAS2
                        n.List.Set(lhs)
                        n.Rlist.Set(rhs)
                }
                return n
 
        case *syntax.BranchStmt:
-               var op Op
+               var op ir.Op
                switch stmt.Tok {
                case syntax.Break:
-                       op = OBREAK
+                       op = ir.OBREAK
                case syntax.Continue:
-                       op = OCONTINUE
+                       op = ir.OCONTINUE
                case syntax.Fallthrough:
                        if !fallOK {
                                base.Errorf("fallthrough statement out of place")
                        }
-                       op = OFALL
+                       op = ir.OFALL
                case syntax.Goto:
-                       op = OGOTO
+                       op = ir.OGOTO
                default:
                        panic("unhandled BranchStmt")
                }
@@ -1041,32 +1042,32 @@ func (p *noder) stmtFall(stmt syntax.Stmt, fallOK bool) *Node {
                }
                return n
        case *syntax.CallStmt:
-               var op Op
+               var op ir.Op
                switch stmt.Tok {
                case syntax.Defer:
-                       op = ODEFER
+                       op = ir.ODEFER
                case syntax.Go:
-                       op = OGO
+                       op = ir.OGO
                default:
                        panic("unhandled CallStmt")
                }
                return p.nod(stmt, op, p.expr(stmt.Call), nil)
        case *syntax.ReturnStmt:
-               var results []*Node
+               var results []*ir.Node
                if stmt.Results != nil {
                        results = p.exprList(stmt.Results)
                }
-               n := p.nod(stmt, ORETURN, nil, nil)
+               n := p.nod(stmt, ir.ORETURN, nil, nil)
                n.List.Set(results)
                if n.List.Len() == 0 && Curfn != nil {
                        for _, ln := range Curfn.Func.Dcl {
-                               if ln.Class() == PPARAM {
+                               if ln.Class() == ir.PPARAM {
                                        continue
                                }
-                               if ln.Class() != PPARAMOUT {
+                               if ln.Class() != ir.PPARAMOUT {
                                        break
                                }
-                               if asNode(ln.Sym.Def) != ln {
+                               if ir.AsNode(ln.Sym.Def) != ln {
                                        base.Errorf("%s is shadowed during return", ln.Sym.Name)
                                }
                        }
@@ -1084,7 +1085,7 @@ func (p *noder) stmtFall(stmt syntax.Stmt, fallOK bool) *Node {
        panic("unhandled Stmt")
 }
 
-func (p *noder) assignList(expr syntax.Expr, defn *Node, colas bool) []*Node {
+func (p *noder) assignList(expr syntax.Expr, defn *ir.Node, colas bool) []*ir.Node {
        if !colas {
                return p.exprList(expr)
        }
@@ -1098,13 +1099,13 @@ func (p *noder) assignList(expr syntax.Expr, defn *Node, colas bool) []*Node {
                exprs = []syntax.Expr{expr}
        }
 
-       res := make([]*Node, len(exprs))
+       res := make([]*ir.Node, len(exprs))
        seen := make(map[*types.Sym]bool, len(exprs))
 
        newOrErr := false
        for i, expr := range exprs {
                p.setlineno(expr)
-               res[i] = nblank
+               res[i] = ir.BlankNode
 
                name, ok := expr.(*syntax.Name)
                if !ok {
@@ -1131,10 +1132,10 @@ func (p *noder) assignList(expr syntax.Expr, defn *Node, colas bool) []*Node {
                }
 
                newOrErr = true
-               n := newname(sym)
+               n := NewName(sym)
                declare(n, dclcontext)
                n.Name.Defn = defn
-               defn.Ninit.Append(nod(ODCL, n, nil))
+               defn.Ninit.Append(ir.Nod(ir.ODCL, n, nil))
                res[i] = n
        }
 
@@ -1144,16 +1145,16 @@ func (p *noder) assignList(expr syntax.Expr, defn *Node, colas bool) []*Node {
        return res
 }
 
-func (p *noder) blockStmt(stmt *syntax.BlockStmt) []*Node {
+func (p *noder) blockStmt(stmt *syntax.BlockStmt) []*ir.Node {
        p.openScope(stmt.Pos())
        nodes := p.stmts(stmt.List)
        p.closeScope(stmt.Rbrace)
        return nodes
 }
 
-func (p *noder) ifStmt(stmt *syntax.IfStmt) *Node {
+func (p *noder) ifStmt(stmt *syntax.IfStmt) *ir.Node {
        p.openScope(stmt.Pos())
-       n := p.nod(stmt, OIF, nil, nil)
+       n := p.nod(stmt, ir.OIF, nil, nil)
        if stmt.Init != nil {
                n.Ninit.Set1(p.stmt(stmt.Init))
        }
@@ -1163,7 +1164,7 @@ func (p *noder) ifStmt(stmt *syntax.IfStmt) *Node {
        n.Nbody.Set(p.blockStmt(stmt.Then))
        if stmt.Else != nil {
                e := p.stmt(stmt.Else)
-               if e.Op == OBLOCK && e.Ninit.Len() == 0 {
+               if e.Op == ir.OBLOCK && e.Ninit.Len() == 0 {
                        n.Rlist.Set(e.List.Slice())
                } else {
                        n.Rlist.Set1(e)
@@ -1173,20 +1174,20 @@ func (p *noder) ifStmt(stmt *syntax.IfStmt) *Node {
        return n
 }
 
-func (p *noder) forStmt(stmt *syntax.ForStmt) *Node {
+func (p *noder) forStmt(stmt *syntax.ForStmt) *ir.Node {
        p.openScope(stmt.Pos())
-       var n *Node
+       var n *ir.Node
        if r, ok := stmt.Init.(*syntax.RangeClause); ok {
                if stmt.Cond != nil || stmt.Post != nil {
                        panic("unexpected RangeClause")
                }
 
-               n = p.nod(r, ORANGE, nil, p.expr(r.X))
+               n = p.nod(r, ir.ORANGE, nil, p.expr(r.X))
                if r.Lhs != nil {
                        n.List.Set(p.assignList(r.Lhs, n, r.Def))
                }
        } else {
-               n = p.nod(stmt, OFOR, nil, nil)
+               n = p.nod(stmt, ir.OFOR, nil, nil)
                if stmt.Init != nil {
                        n.Ninit.Set1(p.stmt(stmt.Init))
                }
@@ -1202,9 +1203,9 @@ func (p *noder) forStmt(stmt *syntax.ForStmt) *Node {
        return n
 }
 
-func (p *noder) switchStmt(stmt *syntax.SwitchStmt) *Node {
+func (p *noder) switchStmt(stmt *syntax.SwitchStmt) *ir.Node {
        p.openScope(stmt.Pos())
-       n := p.nod(stmt, OSWITCH, nil, nil)
+       n := p.nod(stmt, ir.OSWITCH, nil, nil)
        if stmt.Init != nil {
                n.Ninit.Set1(p.stmt(stmt.Init))
        }
@@ -1213,7 +1214,7 @@ func (p *noder) switchStmt(stmt *syntax.SwitchStmt) *Node {
        }
 
        tswitch := n.Left
-       if tswitch != nil && tswitch.Op != OTYPESW {
+       if tswitch != nil && tswitch.Op != ir.OTYPESW {
                tswitch = nil
        }
        n.List.Set(p.caseClauses(stmt.Body, tswitch, stmt.Rbrace))
@@ -1222,8 +1223,8 @@ func (p *noder) switchStmt(stmt *syntax.SwitchStmt) *Node {
        return n
 }
 
-func (p *noder) caseClauses(clauses []*syntax.CaseClause, tswitch *Node, rbrace syntax.Pos) []*Node {
-       nodes := make([]*Node, 0, len(clauses))
+func (p *noder) caseClauses(clauses []*syntax.CaseClause, tswitch *ir.Node, rbrace syntax.Pos) []*ir.Node {
+       nodes := make([]*ir.Node, 0, len(clauses))
        for i, clause := range clauses {
                p.setlineno(clause)
                if i > 0 {
@@ -1231,12 +1232,12 @@ func (p *noder) caseClauses(clauses []*syntax.CaseClause, tswitch *Node, rbrace
                }
                p.openScope(clause.Pos())
 
-               n := p.nod(clause, OCASE, nil, nil)
+               n := p.nod(clause, ir.OCASE, nil, nil)
                if clause.Cases != nil {
                        n.List.Set(p.exprList(clause.Cases))
                }
                if tswitch != nil && tswitch.Left != nil {
-                       nn := newname(tswitch.Left.Sym)
+                       nn := NewName(tswitch.Left.Sym)
                        declare(nn, dclcontext)
                        n.Rlist.Set1(nn)
                        // keep track of the instances for reporting unused
@@ -1255,7 +1256,7 @@ func (p *noder) caseClauses(clauses []*syntax.CaseClause, tswitch *Node, rbrace
                }
 
                n.Nbody.Set(p.stmtsFall(body, true))
-               if l := n.Nbody.Len(); l > 0 && n.Nbody.Index(l-1).Op == OFALL {
+               if l := n.Nbody.Len(); l > 0 && n.Nbody.Index(l-1).Op == ir.OFALL {
                        if tswitch != nil {
                                base.Errorf("cannot fallthrough in type switch")
                        }
@@ -1272,14 +1273,14 @@ func (p *noder) caseClauses(clauses []*syntax.CaseClause, tswitch *Node, rbrace
        return nodes
 }
 
-func (p *noder) selectStmt(stmt *syntax.SelectStmt) *Node {
-       n := p.nod(stmt, OSELECT, nil, nil)
+func (p *noder) selectStmt(stmt *syntax.SelectStmt) *ir.Node {
+       n := p.nod(stmt, ir.OSELECT, nil, nil)
        n.List.Set(p.commClauses(stmt.Body, stmt.Rbrace))
        return n
 }
 
-func (p *noder) commClauses(clauses []*syntax.CommClause, rbrace syntax.Pos) []*Node {
-       nodes := make([]*Node, 0, len(clauses))
+func (p *noder) commClauses(clauses []*syntax.CommClause, rbrace syntax.Pos) []*ir.Node {
+       nodes := make([]*ir.Node, 0, len(clauses))
        for i, clause := range clauses {
                p.setlineno(clause)
                if i > 0 {
@@ -1287,7 +1288,7 @@ func (p *noder) commClauses(clauses []*syntax.CommClause, rbrace syntax.Pos) []*
                }
                p.openScope(clause.Pos())
 
-               n := p.nod(clause, OCASE, nil, nil)
+               n := p.nod(clause, ir.OCASE, nil, nil)
                if clause.Comm != nil {
                        n.List.Set1(p.stmt(clause.Comm))
                }
@@ -1300,18 +1301,18 @@ func (p *noder) commClauses(clauses []*syntax.CommClause, rbrace syntax.Pos) []*
        return nodes
 }
 
-func (p *noder) labeledStmt(label *syntax.LabeledStmt, fallOK bool) *Node {
-       lhs := p.nodSym(label, OLABEL, nil, p.name(label.Label))
+func (p *noder) labeledStmt(label *syntax.LabeledStmt, fallOK bool) *ir.Node {
+       lhs := p.nodSym(label, ir.OLABEL, nil, p.name(label.Label))
 
-       var ls *Node
+       var ls *ir.Node
        if label.Stmt != nil { // TODO(mdempsky): Should always be present.
                ls = p.stmtFall(label.Stmt, fallOK)
        }
 
        lhs.Name.Defn = ls
-       l := []*Node{lhs}
+       l := []*ir.Node{lhs}
        if ls != nil {
-               if ls.Op == OBLOCK && ls.Ninit.Len() == 0 {
+               if ls.Op == ir.OBLOCK && ls.Ninit.Len() == 0 {
                        l = append(l, ls.List.Slice()...)
                } else {
                        l = append(l, ls)
@@ -1320,50 +1321,50 @@ func (p *noder) labeledStmt(label *syntax.LabeledStmt, fallOK bool) *Node {
        return liststmt(l)
 }
 
-var unOps = [...]Op{
-       syntax.Recv: ORECV,
-       syntax.Mul:  ODEREF,
-       syntax.And:  OADDR,
+var unOps = [...]ir.Op{
+       syntax.Recv: ir.ORECV,
+       syntax.Mul:  ir.ODEREF,
+       syntax.And:  ir.OADDR,
 
-       syntax.Not: ONOT,
-       syntax.Xor: OBITNOT,
-       syntax.Add: OPLUS,
-       syntax.Sub: ONEG,
+       syntax.Not: ir.ONOT,
+       syntax.Xor: ir.OBITNOT,
+       syntax.Add: ir.OPLUS,
+       syntax.Sub: ir.ONEG,
 }
 
-func (p *noder) unOp(op syntax.Operator) Op {
+func (p *noder) unOp(op syntax.Operator) ir.Op {
        if uint64(op) >= uint64(len(unOps)) || unOps[op] == 0 {
                panic("invalid Operator")
        }
        return unOps[op]
 }
 
-var binOps = [...]Op{
-       syntax.OrOr:   OOROR,
-       syntax.AndAnd: OANDAND,
+var binOps = [...]ir.Op{
+       syntax.OrOr:   ir.OOROR,
+       syntax.AndAnd: ir.OANDAND,
 
-       syntax.Eql: OEQ,
-       syntax.Neq: ONE,
-       syntax.Lss: OLT,
-       syntax.Leq: OLE,
-       syntax.Gtr: OGT,
-       syntax.Geq: OGE,
+       syntax.Eql: ir.OEQ,
+       syntax.Neq: ir.ONE,
+       syntax.Lss: ir.OLT,
+       syntax.Leq: ir.OLE,
+       syntax.Gtr: ir.OGT,
+       syntax.Geq: ir.OGE,
 
-       syntax.Add: OADD,
-       syntax.Sub: OSUB,
-       syntax.Or:  OOR,
-       syntax.Xor: OXOR,
+       syntax.Add: ir.OADD,
+       syntax.Sub: ir.OSUB,
+       syntax.Or:  ir.OOR,
+       syntax.Xor: ir.OXOR,
 
-       syntax.Mul:    OMUL,
-       syntax.Div:    ODIV,
-       syntax.Rem:    OMOD,
-       syntax.And:    OAND,
-       syntax.AndNot: OANDNOT,
-       syntax.Shl:    OLSH,
-       syntax.Shr:    ORSH,
+       syntax.Mul:    ir.OMUL,
+       syntax.Div:    ir.ODIV,
+       syntax.Rem:    ir.OMOD,
+       syntax.And:    ir.OAND,
+       syntax.AndNot: ir.OANDNOT,
+       syntax.Shl:    ir.OLSH,
+       syntax.Shr:    ir.ORSH,
 }
 
-func (p *noder) binOp(op syntax.Operator) Op {
+func (p *noder) binOp(op syntax.Operator) ir.Op {
        if uint64(op) >= uint64(len(binOps)) || binOps[op] == 0 {
                panic("invalid Operator")
        }
@@ -1374,7 +1375,7 @@ func (p *noder) binOp(op syntax.Operator) Op {
 // literal is not compatible with the current language version.
 func checkLangCompat(lit *syntax.BasicLit) {
        s := lit.Value
-       if len(s) <= 2 || langSupported(1, 13, localpkg) {
+       if len(s) <= 2 || langSupported(1, 13, ir.LocalPkg) {
                return
        }
        // len(s) > 2
@@ -1442,32 +1443,32 @@ func (p *noder) name(name *syntax.Name) *types.Sym {
        return lookup(name.Value)
 }
 
-func (p *noder) mkname(name *syntax.Name) *Node {
+func (p *noder) mkname(name *syntax.Name) *ir.Node {
        // TODO(mdempsky): Set line number?
        return mkname(p.name(name))
 }
 
-func (p *noder) wrapname(n syntax.Node, x *Node) *Node {
+func (p *noder) wrapname(n syntax.Node, x *ir.Node) *ir.Node {
        // These nodes do not carry line numbers.
        // Introduce a wrapper node to give them the correct line.
        switch x.Op {
-       case OTYPE, OLITERAL:
+       case ir.OTYPE, ir.OLITERAL:
                if x.Sym == nil {
                        break
                }
                fallthrough
-       case ONAME, ONONAME, OPACK:
-               x = p.nod(n, OPAREN, x, nil)
+       case ir.ONAME, ir.ONONAME, ir.OPACK:
+               x = p.nod(n, ir.OPAREN, x, nil)
                x.SetImplicit(true)
        }
        return x
 }
 
-func (p *noder) nod(orig syntax.Node, op Op, left, right *Node) *Node {
-       return nodl(p.pos(orig), op, left, right)
+func (p *noder) nod(orig syntax.Node, op ir.Op, left, right *ir.Node) *ir.Node {
+       return ir.NodAt(p.pos(orig), op, left, right)
 }
 
-func (p *noder) nodSym(orig syntax.Node, op Op, left *Node, sym *types.Sym) *Node {
+func (p *noder) nodSym(orig syntax.Node, op ir.Op, left *ir.Node, sym *types.Sym) *ir.Node {
        n := nodSym(op, left, sym)
        n.Pos = p.pos(orig)
        return n
@@ -1508,13 +1509,13 @@ var allowedStdPragmas = map[string]bool{
 
 // *Pragma is the value stored in a syntax.Pragma during parsing.
 type Pragma struct {
-       Flag   PragmaFlag  // collected bits
-       Pos    []PragmaPos // position of each individual flag
+       Flag   ir.PragmaFlag // collected bits
+       Pos    []PragmaPos   // position of each individual flag
        Embeds []PragmaEmbed
 }
 
 type PragmaPos struct {
-       Flag PragmaFlag
+       Flag ir.PragmaFlag
        Pos  syntax.Pos
 }
 
@@ -1631,7 +1632,7 @@ func (p *noder) pragma(pos syntax.Pos, blankLine bool, text string, old syntax.P
                        verb = verb[:i]
                }
                flag := pragmaFlag(verb)
-               const runtimePragmas = Systemstack | Nowritebarrier | Nowritebarrierrec | Yeswritebarrierrec
+               const runtimePragmas = ir.Systemstack | ir.Nowritebarrier | ir.Nowritebarrierrec | ir.Yeswritebarrierrec
                if !base.Flag.CompilingRuntime && flag&runtimePragmas != 0 {
                        p.error(syntax.Error{Pos: pos, Msg: fmt.Sprintf("//%s only allowed in runtime", verb)})
                }
@@ -1667,7 +1668,7 @@ func safeArg(name string) bool {
        return '0' <= c && c <= '9' || 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || c == '.' || c == '_' || c == '/' || c >= utf8.RuneSelf
 }
 
-func mkname(sym *types.Sym) *Node {
+func mkname(sym *types.Sym) *ir.Node {
        n := oldname(sym)
        if n.Name != nil && n.Name.Pack != nil {
                n.Name.Pack.Name.SetUsed(true)
index 6c659c91c775096ab2918e619fcf705a1b7fe109..2961dbf636a4f1fc57ef2af2fca00f0f73d5ba99 100644 (file)
@@ -6,6 +6,7 @@ package gc
 
 import (
        "cmd/compile/internal/base"
+       "cmd/compile/internal/ir"
        "cmd/compile/internal/types"
        "cmd/internal/bio"
        "cmd/internal/obj"
@@ -83,7 +84,7 @@ func printObjHeader(bout *bio.Writer) {
        if base.Flag.BuildID != "" {
                fmt.Fprintf(bout, "build id %q\n", base.Flag.BuildID)
        }
-       if localpkg.Name == "main" {
+       if ir.LocalPkg.Name == "main" {
                fmt.Fprintf(bout, "main\n")
        }
        fmt.Fprintf(bout, "\n") // header ends with blank line
@@ -141,7 +142,7 @@ func dumpdata() {
        for {
                for i := xtops; i < len(xtop); i++ {
                        n := xtop[i]
-                       if n.Op == ODCLFUNC {
+                       if n.Op == ir.ODCLFUNC {
                                funccompile(n)
                        }
                }
@@ -199,16 +200,16 @@ func dumpLinkerObj(bout *bio.Writer) {
 }
 
 func addptabs() {
-       if !base.Ctxt.Flag_dynlink || localpkg.Name != "main" {
+       if !base.Ctxt.Flag_dynlink || ir.LocalPkg.Name != "main" {
                return
        }
        for _, exportn := range exportlist {
                s := exportn.Sym
-               n := asNode(s.Def)
+               n := ir.AsNode(s.Def)
                if n == nil {
                        continue
                }
-               if n.Op != ONAME {
+               if n.Op != ir.ONAME {
                        continue
                }
                if !types.IsExported(s.Name) {
@@ -217,37 +218,37 @@ func addptabs() {
                if s.Pkg.Name != "main" {
                        continue
                }
-               if n.Type.Etype == TFUNC && n.Class() == PFUNC {
+               if n.Type.Etype == types.TFUNC && n.Class() == ir.PFUNC {
                        // function
-                       ptabs = append(ptabs, ptabEntry{s: s, t: asNode(s.Def).Type})
+                       ptabs = append(ptabs, ptabEntry{s: s, t: ir.AsNode(s.Def).Type})
                } else {
                        // variable
-                       ptabs = append(ptabs, ptabEntry{s: s, t: types.NewPtr(asNode(s.Def).Type)})
+                       ptabs = append(ptabs, ptabEntry{s: s, t: types.NewPtr(ir.AsNode(s.Def).Type)})
                }
        }
 }
 
-func dumpGlobal(n *Node) {
+func dumpGlobal(n *ir.Node) {
        if n.Type == nil {
                base.Fatalf("external %v nil type\n", n)
        }
-       if n.Class() == PFUNC {
+       if n.Class() == ir.PFUNC {
                return
        }
-       if n.Sym.Pkg != localpkg {
+       if n.Sym.Pkg != ir.LocalPkg {
                return
        }
        dowidth(n.Type)
        ggloblnod(n)
 }
 
-func dumpGlobalConst(n *Node) {
+func dumpGlobalConst(n *ir.Node) {
        // only export typed constants
        t := n.Type
        if t == nil {
                return
        }
-       if n.Sym.Pkg != localpkg {
+       if n.Sym.Pkg != ir.LocalPkg {
                return
        }
        // only export integer constants for now
@@ -257,21 +258,21 @@ func dumpGlobalConst(n *Node) {
        v := n.Val()
        if t.IsUntyped() {
                // Export untyped integers as int (if they fit).
-               t = types.Types[TINT]
+               t = types.Types[types.TINT]
                if doesoverflow(v, t) {
                        return
                }
        }
-       base.Ctxt.DwarfIntConst(base.Ctxt.Pkgpath, n.Sym.Name, typesymname(t), int64Val(t, v))
+       base.Ctxt.DwarfIntConst(base.Ctxt.Pkgpath, n.Sym.Name, typesymname(t), ir.Int64Val(t, v))
 }
 
 func dumpglobls() {
        // add globals
        for _, n := range externdcl {
                switch n.Op {
-               case ONAME:
+               case ir.ONAME:
                        dumpGlobal(n)
-               case OLITERAL:
+               case ir.OLITERAL:
                        dumpGlobalConst(n)
                }
        }
@@ -474,12 +475,12 @@ func fileStringSym(pos src.XPos, file string, readonly bool, hash []byte) (*obj.
 
 var slicedataGen int
 
-func slicedata(pos src.XPos, s string) *Node {
+func slicedata(pos src.XPos, s string) *ir.Node {
        slicedataGen++
        symname := fmt.Sprintf(".gobytes.%d", slicedataGen)
-       sym := localpkg.Lookup(symname)
-       symnode := newname(sym)
-       sym.Def = asTypesNode(symnode)
+       sym := ir.LocalPkg.Lookup(symname)
+       symnode := NewName(sym)
+       sym.Def = ir.AsTypesNode(symnode)
 
        lsym := sym.Linksym()
        off := dstringdata(lsym, 0, s, pos, "slice")
@@ -488,8 +489,8 @@ func slicedata(pos src.XPos, s string) *Node {
        return symnode
 }
 
-func slicebytes(nam *Node, s string) {
-       if nam.Op != ONAME {
+func slicebytes(nam *ir.Node, s string) {
+       if nam.Op != ir.ONAME {
                base.Fatalf("slicebytes %v", nam)
        }
        slicesym(nam, slicedata(nam.Pos, s), int64(len(s)))
@@ -529,10 +530,10 @@ func dsymptrWeakOff(s *obj.LSym, off int, x *obj.LSym) int {
 
 // slicesym writes a static slice symbol {&arr, lencap, lencap} to n.
 // arr must be an ONAME. slicesym does not modify n.
-func slicesym(n, arr *Node, lencap int64) {
+func slicesym(n, arr *ir.Node, lencap int64) {
        s := n.Sym.Linksym()
        off := n.Xoffset
-       if arr.Op != ONAME {
+       if arr.Op != ir.ONAME {
                base.Fatalf("slicesym non-name arr %v", arr)
        }
        s.WriteAddr(base.Ctxt, off, Widthptr, arr.Sym.Linksym(), arr.Xoffset)
@@ -542,14 +543,14 @@ func slicesym(n, arr *Node, lencap int64) {
 
 // addrsym writes the static address of a to n. a must be an ONAME.
 // Neither n nor a is modified.
-func addrsym(n, a *Node) {
-       if n.Op != ONAME {
+func addrsym(n, a *ir.Node) {
+       if n.Op != ir.ONAME {
                base.Fatalf("addrsym n op %v", n.Op)
        }
        if n.Sym == nil {
                base.Fatalf("addrsym nil n sym")
        }
-       if a.Op != ONAME {
+       if a.Op != ir.ONAME {
                base.Fatalf("addrsym a op %v", a.Op)
        }
        s := n.Sym.Linksym()
@@ -558,14 +559,14 @@ func addrsym(n, a *Node) {
 
 // pfuncsym writes the static address of f to n. f must be a global function.
 // Neither n nor f is modified.
-func pfuncsym(n, f *Node) {
-       if n.Op != ONAME {
+func pfuncsym(n, f *ir.Node) {
+       if n.Op != ir.ONAME {
                base.Fatalf("pfuncsym n op %v", n.Op)
        }
        if n.Sym == nil {
                base.Fatalf("pfuncsym nil n sym")
        }
-       if f.Class() != PFUNC {
+       if f.Class() != ir.PFUNC {
                base.Fatalf("pfuncsym class not PFUNC %d", f.Class())
        }
        s := n.Sym.Linksym()
@@ -574,8 +575,8 @@ func pfuncsym(n, f *Node) {
 
 // litsym writes the static literal c to n.
 // Neither n nor c is modified.
-func litsym(n, c *Node, wid int) {
-       if n.Op != ONAME {
+func litsym(n, c *ir.Node, wid int) {
+       if n.Op != ir.ONAME {
                base.Fatalf("litsym n op %v", n.Op)
        }
        if n.Sym == nil {
@@ -584,10 +585,10 @@ func litsym(n, c *Node, wid int) {
        if !types.Identical(n.Type, c.Type) {
                base.Fatalf("litsym: type mismatch: %v has type %v, but %v has type %v", n, n.Type, c, c.Type)
        }
-       if c.Op == ONIL {
+       if c.Op == ir.ONIL {
                return
        }
-       if c.Op != OLITERAL {
+       if c.Op != ir.OLITERAL {
                base.Fatalf("litsym c op %v", c.Op)
        }
        s := n.Sym.Linksym()
@@ -597,14 +598,14 @@ func litsym(n, c *Node, wid int) {
                s.WriteInt(base.Ctxt, n.Xoffset, wid, i)
 
        case constant.Int:
-               s.WriteInt(base.Ctxt, n.Xoffset, wid, int64Val(n.Type, u))
+               s.WriteInt(base.Ctxt, n.Xoffset, wid, ir.Int64Val(n.Type, u))
 
        case constant.Float:
                f, _ := constant.Float64Val(u)
                switch n.Type.Etype {
-               case TFLOAT32:
+               case types.TFLOAT32:
                        s.WriteFloat32(base.Ctxt, n.Xoffset, float32(f))
-               case TFLOAT64:
+               case types.TFLOAT64:
                        s.WriteFloat64(base.Ctxt, n.Xoffset, f)
                }
 
@@ -612,10 +613,10 @@ func litsym(n, c *Node, wid int) {
                re, _ := constant.Float64Val(constant.Real(u))
                im, _ := constant.Float64Val(constant.Imag(u))
                switch n.Type.Etype {
-               case TCOMPLEX64:
+               case types.TCOMPLEX64:
                        s.WriteFloat32(base.Ctxt, n.Xoffset, float32(re))
                        s.WriteFloat32(base.Ctxt, n.Xoffset+4, float32(im))
-               case TCOMPLEX128:
+               case types.TCOMPLEX128:
                        s.WriteFloat64(base.Ctxt, n.Xoffset, re)
                        s.WriteFloat64(base.Ctxt, n.Xoffset+8, im)
                }
index 3b0f31669627be6ec7d4d1ef2d1028e8cfd53c85..25bdbd5a4143ee6dffd6743d56560d906b0a7f9c 100644 (file)
@@ -6,6 +6,7 @@ package gc
 
 import (
        "cmd/compile/internal/base"
+       "cmd/compile/internal/ir"
        "cmd/compile/internal/types"
        "cmd/internal/src"
        "fmt"
@@ -43,27 +44,27 @@ import (
 
 // Order holds state during the ordering process.
 type Order struct {
-       out  []*Node            // list of generated statements
-       temp []*Node            // stack of temporary variables
-       free map[string][]*Node // free list of unused temporaries, by type.LongString().
+       out  []*ir.Node            // list of generated statements
+       temp []*ir.Node            // stack of temporary variables
+       free map[string][]*ir.Node // free list of unused temporaries, by type.LongString().
 }
 
 // Order rewrites fn.Nbody to apply the ordering constraints
 // described in the comment at the top of the file.
-func order(fn *Node) {
+func order(fn *ir.Node) {
        if base.Flag.W > 1 {
                s := fmt.Sprintf("\nbefore order %v", fn.Func.Nname.Sym)
-               dumplist(s, fn.Nbody)
+               ir.DumpList(s, fn.Nbody)
        }
 
-       orderBlock(&fn.Nbody, map[string][]*Node{})
+       orderBlock(&fn.Nbody, map[string][]*ir.Node{})
 }
 
 // newTemp allocates a new temporary with the given type,
 // pushes it onto the temp stack, and returns it.
 // If clear is true, newTemp emits code to zero the temporary.
-func (o *Order) newTemp(t *types.Type, clear bool) *Node {
-       var v *Node
+func (o *Order) newTemp(t *types.Type, clear bool) *ir.Node {
+       var v *ir.Node
        // Note: LongString is close to the type equality we want,
        // but not exactly. We still need to double-check with types.Identical.
        key := t.LongString()
@@ -81,7 +82,7 @@ func (o *Order) newTemp(t *types.Type, clear bool) *Node {
                v = temp(t)
        }
        if clear {
-               a := nod(OAS, v, nil)
+               a := ir.Nod(ir.OAS, v, nil)
                a = typecheck(a, ctxStmt)
                o.out = append(o.out, a)
        }
@@ -102,9 +103,9 @@ func (o *Order) newTemp(t *types.Type, clear bool) *Node {
 // (The other candidate would be map access, but map access
 // returns a pointer to the result data instead of taking a pointer
 // to be filled in.)
-func (o *Order) copyExpr(n *Node, t *types.Type, clear bool) *Node {
+func (o *Order) copyExpr(n *ir.Node, t *types.Type, clear bool) *ir.Node {
        v := o.newTemp(t, clear)
-       a := nod(OAS, v, n)
+       a := ir.Nod(ir.OAS, v, n)
        a = typecheck(a, ctxStmt)
        o.out = append(o.out, a)
        return v
@@ -114,20 +115,20 @@ func (o *Order) copyExpr(n *Node, t *types.Type, clear bool) *Node {
 // The definition of cheap is that n is a variable or constant.
 // If not, cheapExpr allocates a new tmp, emits tmp = n,
 // and then returns tmp.
-func (o *Order) cheapExpr(n *Node) *Node {
+func (o *Order) cheapExpr(n *ir.Node) *ir.Node {
        if n == nil {
                return nil
        }
 
        switch n.Op {
-       case ONAME, OLITERAL, ONIL:
+       case ir.ONAME, ir.OLITERAL, ir.ONIL:
                return n
-       case OLEN, OCAP:
+       case ir.OLEN, ir.OCAP:
                l := o.cheapExpr(n.Left)
                if l == n.Left {
                        return n
                }
-               a := n.sepcopy()
+               a := ir.SepCopy(n)
                a.Left = l
                return typecheck(a, ctxExpr)
        }
@@ -142,31 +143,31 @@ func (o *Order) cheapExpr(n *Node) *Node {
 // as assigning to the original n.
 //
 // The intended use is to apply to x when rewriting x += y into x = x + y.
-func (o *Order) safeExpr(n *Node) *Node {
+func (o *Order) safeExpr(n *ir.Node) *ir.Node {
        switch n.Op {
-       case ONAME, OLITERAL, ONIL:
+       case ir.ONAME, ir.OLITERAL, ir.ONIL:
                return n
 
-       case ODOT, OLEN, OCAP:
+       case ir.ODOT, ir.OLEN, ir.OCAP:
                l := o.safeExpr(n.Left)
                if l == n.Left {
                        return n
                }
-               a := n.sepcopy()
+               a := ir.SepCopy(n)
                a.Left = l
                return typecheck(a, ctxExpr)
 
-       case ODOTPTR, ODEREF:
+       case ir.ODOTPTR, ir.ODEREF:
                l := o.cheapExpr(n.Left)
                if l == n.Left {
                        return n
                }
-               a := n.sepcopy()
+               a := ir.SepCopy(n)
                a.Left = l
                return typecheck(a, ctxExpr)
 
-       case OINDEX, OINDEXMAP:
-               var l *Node
+       case ir.OINDEX, ir.OINDEXMAP:
+               var l *ir.Node
                if n.Left.Type.IsArray() {
                        l = o.safeExpr(n.Left)
                } else {
@@ -176,7 +177,7 @@ func (o *Order) safeExpr(n *Node) *Node {
                if l == n.Left && r == n.Right {
                        return n
                }
-               a := n.sepcopy()
+               a := ir.SepCopy(n)
                a.Left = l
                a.Right = r
                return typecheck(a, ctxExpr)
@@ -193,8 +194,8 @@ func (o *Order) safeExpr(n *Node) *Node {
 // of ordinary stack variables, those are not 'isaddrokay'. Temporaries are okay,
 // because we emit explicit VARKILL instructions marking the end of those
 // temporaries' lifetimes.
-func isaddrokay(n *Node) bool {
-       return islvalue(n) && (n.Op != ONAME || n.Class() == PEXTERN || n.IsAutoTmp())
+func isaddrokay(n *ir.Node) bool {
+       return islvalue(n) && (n.Op != ir.ONAME || n.Class() == ir.PEXTERN || n.IsAutoTmp())
 }
 
 // addrTemp ensures that n is okay to pass by address to runtime routines.
@@ -202,8 +203,8 @@ func isaddrokay(n *Node) bool {
 // tmp = n, and then returns tmp.
 // The result of addrTemp MUST be assigned back to n, e.g.
 //     n.Left = o.addrTemp(n.Left)
-func (o *Order) addrTemp(n *Node) *Node {
-       if n.Op == OLITERAL || n.Op == ONIL {
+func (o *Order) addrTemp(n *ir.Node) *ir.Node {
+       if n.Op == ir.OLITERAL || n.Op == ir.ONIL {
                // TODO: expand this to all static composite literal nodes?
                n = defaultlit(n, nil)
                dowidth(n.Type)
@@ -224,7 +225,7 @@ func (o *Order) addrTemp(n *Node) *Node {
 
 // mapKeyTemp prepares n to be a key in a map runtime call and returns n.
 // It should only be used for map runtime calls which have *_fast* versions.
-func (o *Order) mapKeyTemp(t *types.Type, n *Node) *Node {
+func (o *Order) mapKeyTemp(t *types.Type, n *ir.Node) *ir.Node {
        // Most map calls need to take the address of the key.
        // Exception: map*_fast* calls. See golang.org/issue/19015.
        if mapfast(t) == mapslow {
@@ -247,21 +248,21 @@ func (o *Order) mapKeyTemp(t *types.Type, n *Node) *Node {
 // It would be nice to handle these generally, but because
 // []byte keys are not allowed in maps, the use of string(k)
 // comes up in important cases in practice. See issue 3512.
-func mapKeyReplaceStrConv(n *Node) bool {
+func mapKeyReplaceStrConv(n *ir.Node) bool {
        var replaced bool
        switch n.Op {
-       case OBYTES2STR:
-               n.Op = OBYTES2STRTMP
+       case ir.OBYTES2STR:
+               n.Op = ir.OBYTES2STRTMP
                replaced = true
-       case OSTRUCTLIT:
+       case ir.OSTRUCTLIT:
                for _, elem := range n.List.Slice() {
                        if mapKeyReplaceStrConv(elem.Left) {
                                replaced = true
                        }
                }
-       case OARRAYLIT:
+       case ir.OARRAYLIT:
                for _, elem := range n.List.Slice() {
-                       if elem.Op == OKEY {
+                       if elem.Op == ir.OKEY {
                                elem = elem.Right
                        }
                        if mapKeyReplaceStrConv(elem) {
@@ -292,11 +293,11 @@ func (o *Order) popTemp(mark ordermarker) {
 // cleanTempNoPop emits VARKILL instructions to *out
 // for each temporary above the mark on the temporary stack.
 // It does not pop the temporaries from the stack.
-func (o *Order) cleanTempNoPop(mark ordermarker) []*Node {
-       var out []*Node
+func (o *Order) cleanTempNoPop(mark ordermarker) []*ir.Node {
+       var out []*ir.Node
        for i := len(o.temp) - 1; i >= int(mark); i-- {
                n := o.temp[i]
-               kill := nod(OVARKILL, n, nil)
+               kill := ir.Nod(ir.OVARKILL, n, nil)
                kill = typecheck(kill, ctxStmt)
                out = append(out, kill)
        }
@@ -311,7 +312,7 @@ func (o *Order) cleanTemp(top ordermarker) {
 }
 
 // stmtList orders each of the statements in the list.
-func (o *Order) stmtList(l Nodes) {
+func (o *Order) stmtList(l ir.Nodes) {
        s := l.Slice()
        for i := range s {
                orderMakeSliceCopy(s[i:])
@@ -323,7 +324,7 @@ func (o *Order) stmtList(l Nodes) {
 //  m = OMAKESLICE([]T, x); OCOPY(m, s)
 // and rewrites it to:
 //  m = OMAKESLICECOPY([]T, x, s); nil
-func orderMakeSliceCopy(s []*Node) {
+func orderMakeSliceCopy(s []*ir.Node) {
        if base.Flag.N != 0 || instrumenting {
                return
        }
@@ -335,17 +336,17 @@ func orderMakeSliceCopy(s []*Node) {
        asn := s[0]
        copyn := s[1]
 
-       if asn == nil || asn.Op != OAS {
+       if asn == nil || asn.Op != ir.OAS {
                return
        }
-       if asn.Left.Op != ONAME {
+       if asn.Left.Op != ir.ONAME {
                return
        }
-       if asn.Left.isBlank() {
+       if ir.IsBlank(asn.Left) {
                return
        }
        maken := asn.Right
-       if maken == nil || maken.Op != OMAKESLICE {
+       if maken == nil || maken.Op != ir.OMAKESLICE {
                return
        }
        if maken.Esc == EscNone {
@@ -354,16 +355,16 @@ func orderMakeSliceCopy(s []*Node) {
        if maken.Left == nil || maken.Right != nil {
                return
        }
-       if copyn.Op != OCOPY {
+       if copyn.Op != ir.OCOPY {
                return
        }
-       if copyn.Left.Op != ONAME {
+       if copyn.Left.Op != ir.ONAME {
                return
        }
        if asn.Left.Sym != copyn.Left.Sym {
                return
        }
-       if copyn.Right.Op != ONAME {
+       if copyn.Right.Op != ir.ONAME {
                return
        }
 
@@ -371,10 +372,10 @@ func orderMakeSliceCopy(s []*Node) {
                return
        }
 
-       maken.Op = OMAKESLICECOPY
+       maken.Op = ir.OMAKESLICECOPY
        maken.Right = copyn.Right
        // Set bounded when m = OMAKESLICE([]T, len(s)); OCOPY(m, s)
-       maken.SetBounded(maken.Left.Op == OLEN && samesafeexpr(maken.Left.Left, copyn.Right))
+       maken.SetBounded(maken.Left.Op == ir.OLEN && samesafeexpr(maken.Left.Left, copyn.Right))
 
        maken = typecheck(maken, ctxExpr)
 
@@ -391,12 +392,12 @@ func (o *Order) edge() {
 
        // Create a new uint8 counter to be allocated in section
        // __libfuzzer_extra_counters.
-       counter := staticname(types.Types[TUINT8])
+       counter := staticname(types.Types[types.TUINT8])
        counter.Name.SetLibfuzzerExtraCounter(true)
 
        // counter += 1
-       incr := nod(OASOP, counter, nodintconst(1))
-       incr.SetSubOp(OADD)
+       incr := ir.Nod(ir.OASOP, counter, nodintconst(1))
+       incr.SetSubOp(ir.OADD)
        incr = typecheck(incr, ctxStmt)
 
        o.out = append(o.out, incr)
@@ -405,7 +406,7 @@ func (o *Order) edge() {
 // orderBlock orders the block of statements in n into a new slice,
 // and then replaces the old slice in n with the new slice.
 // free is a map that can be used to obtain temporary variables by type.
-func orderBlock(n *Nodes, free map[string][]*Node) {
+func orderBlock(n *ir.Nodes, free map[string][]*ir.Node) {
        var order Order
        order.free = free
        mark := order.markTemp()
@@ -419,7 +420,7 @@ func orderBlock(n *Nodes, free map[string][]*Node) {
 // leaves them as the init list of the final *np.
 // The result of exprInPlace MUST be assigned back to n, e.g.
 //     n.Left = o.exprInPlace(n.Left)
-func (o *Order) exprInPlace(n *Node) *Node {
+func (o *Order) exprInPlace(n *ir.Node) *ir.Node {
        var order Order
        order.free = o.free
        n = order.expr(n, nil)
@@ -436,7 +437,7 @@ func (o *Order) exprInPlace(n *Node) *Node {
 // The result of orderStmtInPlace MUST be assigned back to n, e.g.
 //     n.Left = orderStmtInPlace(n.Left)
 // free is a map that can be used to obtain temporary variables by type.
-func orderStmtInPlace(n *Node, free map[string][]*Node) *Node {
+func orderStmtInPlace(n *ir.Node, free map[string][]*ir.Node) *ir.Node {
        var order Order
        order.free = free
        mark := order.markTemp()
@@ -446,8 +447,8 @@ func orderStmtInPlace(n *Node, free map[string][]*Node) *Node {
 }
 
 // init moves n's init list to o.out.
-func (o *Order) init(n *Node) {
-       if n.mayBeShared() {
+func (o *Order) init(n *ir.Node) {
+       if ir.MayBeShared(n) {
                // For concurrency safety, don't mutate potentially shared nodes.
                // First, ensure that no work is required here.
                if n.Ninit.Len() > 0 {
@@ -461,14 +462,14 @@ func (o *Order) init(n *Node) {
 
 // call orders the call expression n.
 // n.Op is OCALLMETH/OCALLFUNC/OCALLINTER or a builtin like OCOPY.
-func (o *Order) call(n *Node) {
+func (o *Order) call(n *ir.Node) {
        if n.Ninit.Len() > 0 {
                // Caller should have already called o.init(n).
                base.Fatalf("%v with unexpected ninit", n.Op)
        }
 
        // Builtin functions.
-       if n.Op != OCALLFUNC && n.Op != OCALLMETH && n.Op != OCALLINTER {
+       if n.Op != ir.OCALLFUNC && n.Op != ir.OCALLMETH && n.Op != ir.OCALLINTER {
                n.Left = o.expr(n.Left, nil)
                n.Right = o.expr(n.Right, nil)
                o.exprList(n.List)
@@ -479,26 +480,26 @@ func (o *Order) call(n *Node) {
        n.Left = o.expr(n.Left, nil)
        o.exprList(n.List)
 
-       if n.Op == OCALLINTER {
+       if n.Op == ir.OCALLINTER {
                return
        }
-       keepAlive := func(arg *Node) {
+       keepAlive := func(arg *ir.Node) {
                // If the argument is really a pointer being converted to uintptr,
                // arrange for the pointer to be kept alive until the call returns,
                // by copying it into a temp and marking that temp
                // still alive when we pop the temp stack.
-               if arg.Op == OCONVNOP && arg.Left.Type.IsUnsafePtr() {
+               if arg.Op == ir.OCONVNOP && arg.Left.Type.IsUnsafePtr() {
                        x := o.copyExpr(arg.Left, arg.Left.Type, false)
                        arg.Left = x
                        x.Name.SetAddrtaken(true) // ensure SSA keeps the x variable
-                       n.Nbody.Append(typecheck(nod(OVARLIVE, x, nil), ctxStmt))
+                       n.Nbody.Append(typecheck(ir.Nod(ir.OVARLIVE, x, nil), ctxStmt))
                }
        }
 
        // Check for "unsafe-uintptr" tag provided by escape analysis.
        for i, param := range n.Left.Type.Params().FieldSlice() {
                if param.Note == unsafeUintptrTag || param.Note == uintptrEscapesTag {
-                       if arg := n.List.Index(i); arg.Op == OSLICELIT {
+                       if arg := n.List.Index(i); arg.Op == ir.OSLICELIT {
                                for _, elt := range arg.List.Slice() {
                                        keepAlive(elt)
                                }
@@ -524,16 +525,16 @@ func (o *Order) call(n *Node) {
 // cases they are also typically registerizable, so not much harm done.
 // And this only applies to the multiple-assignment form.
 // We could do a more precise analysis if needed, like in walk.go.
-func (o *Order) mapAssign(n *Node) {
+func (o *Order) mapAssign(n *ir.Node) {
        switch n.Op {
        default:
                base.Fatalf("order.mapAssign %v", n.Op)
 
-       case OAS, OASOP:
-               if n.Left.Op == OINDEXMAP {
+       case ir.OAS, ir.OASOP:
+               if n.Left.Op == ir.OINDEXMAP {
                        // Make sure we evaluate the RHS before starting the map insert.
                        // We need to make sure the RHS won't panic.  See issue 22881.
-                       if n.Right.Op == OAPPEND {
+                       if n.Right.Op == ir.OAPPEND {
                                s := n.Right.List.Slice()[1:]
                                for i, n := range s {
                                        s[i] = o.cheapExpr(n)
@@ -544,11 +545,11 @@ func (o *Order) mapAssign(n *Node) {
                }
                o.out = append(o.out, n)
 
-       case OAS2, OAS2DOTTYPE, OAS2MAPR, OAS2FUNC:
-               var post []*Node
+       case ir.OAS2, ir.OAS2DOTTYPE, ir.OAS2MAPR, ir.OAS2FUNC:
+               var post []*ir.Node
                for i, m := range n.List.Slice() {
                        switch {
-                       case m.Op == OINDEXMAP:
+                       case m.Op == ir.OINDEXMAP:
                                if !m.Left.IsAutoTmp() {
                                        m.Left = o.copyExpr(m.Left, m.Left.Type, false)
                                }
@@ -556,10 +557,10 @@ func (o *Order) mapAssign(n *Node) {
                                        m.Right = o.copyExpr(m.Right, m.Right.Type, false)
                                }
                                fallthrough
-                       case instrumenting && n.Op == OAS2FUNC && !m.isBlank():
+                       case instrumenting && n.Op == ir.OAS2FUNC && !ir.IsBlank(m):
                                t := o.newTemp(m.Type, false)
                                n.List.SetIndex(i, t)
-                               a := nod(OAS, m, t)
+                               a := ir.Nod(ir.OAS, m, t)
                                a = typecheck(a, ctxStmt)
                                post = append(post, a)
                        }
@@ -573,7 +574,7 @@ func (o *Order) mapAssign(n *Node) {
 // stmt orders the statement n, appending to o.out.
 // Temporaries created during the statement are cleaned
 // up using VARKILL instructions as possible.
-func (o *Order) stmt(n *Node) {
+func (o *Order) stmt(n *ir.Node) {
        if n == nil {
                return
        }
@@ -585,22 +586,22 @@ func (o *Order) stmt(n *Node) {
        default:
                base.Fatalf("order.stmt %v", n.Op)
 
-       case OVARKILL, OVARLIVE, OINLMARK:
+       case ir.OVARKILL, ir.OVARLIVE, ir.OINLMARK:
                o.out = append(o.out, n)
 
-       case OAS:
+       case ir.OAS:
                t := o.markTemp()
                n.Left = o.expr(n.Left, nil)
                n.Right = o.expr(n.Right, n.Left)
                o.mapAssign(n)
                o.cleanTemp(t)
 
-       case OASOP:
+       case ir.OASOP:
                t := o.markTemp()
                n.Left = o.expr(n.Left, nil)
                n.Right = o.expr(n.Right, nil)
 
-               if instrumenting || n.Left.Op == OINDEXMAP && (n.SubOp() == ODIV || n.SubOp() == OMOD) {
+               if instrumenting || n.Left.Op == ir.OINDEXMAP && (n.SubOp() == ir.ODIV || n.SubOp() == ir.OMOD) {
                        // Rewrite m[k] op= r into m[k] = m[k] op r so
                        // that we can ensure that if op panics
                        // because r is zero, the panic happens before
@@ -609,22 +610,22 @@ func (o *Order) stmt(n *Node) {
                        n.Left = o.safeExpr(n.Left)
 
                        l := treecopy(n.Left, src.NoXPos)
-                       if l.Op == OINDEXMAP {
+                       if l.Op == ir.OINDEXMAP {
                                l.SetIndexMapLValue(false)
                        }
                        l = o.copyExpr(l, n.Left.Type, false)
-                       n.Right = nod(n.SubOp(), l, n.Right)
+                       n.Right = ir.Nod(n.SubOp(), l, n.Right)
                        n.Right = typecheck(n.Right, ctxExpr)
                        n.Right = o.expr(n.Right, nil)
 
-                       n.Op = OAS
+                       n.Op = ir.OAS
                        n.ResetAux()
                }
 
                o.mapAssign(n)
                o.cleanTemp(t)
 
-       case OAS2:
+       case ir.OAS2:
                t := o.markTemp()
                o.exprList(n.List)
                o.exprList(n.Rlist)
@@ -632,7 +633,7 @@ func (o *Order) stmt(n *Node) {
                o.cleanTemp(t)
 
        // Special: avoid copy of func call n.Right
-       case OAS2FUNC:
+       case ir.OAS2FUNC:
                t := o.markTemp()
                o.exprList(n.List)
                o.init(n.Right)
@@ -646,14 +647,14 @@ func (o *Order) stmt(n *Node) {
        //
        // OAS2MAPR: make sure key is addressable if needed,
        //           and make sure OINDEXMAP is not copied out.
-       case OAS2DOTTYPE, OAS2RECV, OAS2MAPR:
+       case ir.OAS2DOTTYPE, ir.OAS2RECV, ir.OAS2MAPR:
                t := o.markTemp()
                o.exprList(n.List)
 
                switch r := n.Right; r.Op {
-               case ODOTTYPE2, ORECV:
+               case ir.ODOTTYPE2, ir.ORECV:
                        r.Left = o.expr(r.Left, nil)
-               case OINDEXMAP:
+               case ir.OINDEXMAP:
                        r.Left = o.expr(r.Left, nil)
                        r.Right = o.expr(r.Right, nil)
                        // See similar conversion for OINDEXMAP below.
@@ -667,34 +668,34 @@ func (o *Order) stmt(n *Node) {
                o.cleanTemp(t)
 
        // Special: does not save n onto out.
-       case OBLOCK, OEMPTY:
+       case ir.OBLOCK, ir.OEMPTY:
                o.stmtList(n.List)
 
        // Special: n->left is not an expression; save as is.
-       case OBREAK,
-               OCONTINUE,
-               ODCL,
-               ODCLCONST,
-               ODCLTYPE,
-               OFALL,
-               OGOTO,
-               OLABEL,
-               ORETJMP:
+       case ir.OBREAK,
+               ir.OCONTINUE,
+               ir.ODCL,
+               ir.ODCLCONST,
+               ir.ODCLTYPE,
+               ir.OFALL,
+               ir.OGOTO,
+               ir.OLABEL,
+               ir.ORETJMP:
                o.out = append(o.out, n)
 
        // Special: handle call arguments.
-       case OCALLFUNC, OCALLINTER, OCALLMETH:
+       case ir.OCALLFUNC, ir.OCALLINTER, ir.OCALLMETH:
                t := o.markTemp()
                o.call(n)
                o.out = append(o.out, n)
                o.cleanTemp(t)
 
-       case OCLOSE,
-               OCOPY,
-               OPRINT,
-               OPRINTN,
-               ORECOVER,
-               ORECV:
+       case ir.OCLOSE,
+               ir.OCOPY,
+               ir.OPRINT,
+               ir.OPRINTN,
+               ir.ORECOVER,
+               ir.ORECV:
                t := o.markTemp()
                n.Left = o.expr(n.Left, nil)
                n.Right = o.expr(n.Right, nil)
@@ -704,14 +705,14 @@ func (o *Order) stmt(n *Node) {
                o.cleanTemp(t)
 
        // Special: order arguments to inner call but not call itself.
-       case ODEFER, OGO:
+       case ir.ODEFER, ir.OGO:
                t := o.markTemp()
                o.init(n.Left)
                o.call(n.Left)
                o.out = append(o.out, n)
                o.cleanTemp(t)
 
-       case ODELETE:
+       case ir.ODELETE:
                t := o.markTemp()
                n.List.SetFirst(o.expr(n.List.First(), nil))
                n.List.SetSecond(o.expr(n.List.Second(), nil))
@@ -721,7 +722,7 @@ func (o *Order) stmt(n *Node) {
 
        // Clean temporaries from condition evaluation at
        // beginning of loop body and after for statement.
-       case OFOR:
+       case ir.OFOR:
                t := o.markTemp()
                n.Left = o.exprInPlace(n.Left)
                n.Nbody.Prepend(o.cleanTempNoPop(t)...)
@@ -732,7 +733,7 @@ func (o *Order) stmt(n *Node) {
 
        // Clean temporaries from condition at
        // beginning of both branches.
-       case OIF:
+       case ir.OIF:
                t := o.markTemp()
                n.Left = o.exprInPlace(n.Left)
                n.Nbody.Prepend(o.cleanTempNoPop(t)...)
@@ -744,7 +745,7 @@ func (o *Order) stmt(n *Node) {
 
        // Special: argument will be converted to interface using convT2E
        // so make sure it is an addressable temporary.
-       case OPANIC:
+       case ir.OPANIC:
                t := o.markTemp()
                n.Left = o.expr(n.Left, nil)
                if !n.Left.Type.IsInterface() {
@@ -753,7 +754,7 @@ func (o *Order) stmt(n *Node) {
                o.out = append(o.out, n)
                o.cleanTemp(t)
 
-       case ORANGE:
+       case ir.ORANGE:
                // n.Right is the expression being ranged over.
                // order it, and then make a copy if we need one.
                // We almost always do, to ensure that we don't
@@ -767,8 +768,8 @@ func (o *Order) stmt(n *Node) {
 
                // Mark []byte(str) range expression to reuse string backing storage.
                // It is safe because the storage cannot be mutated.
-               if n.Right.Op == OSTR2BYTES {
-                       n.Right.Op = OSTR2BYTESTMP
+               if n.Right.Op == ir.OSTR2BYTES {
+                       n.Right.Op = ir.OSTR2BYTESTMP
                }
 
                t := o.markTemp()
@@ -779,28 +780,28 @@ func (o *Order) stmt(n *Node) {
                default:
                        base.Fatalf("order.stmt range %v", n.Type)
 
-               case TARRAY, TSLICE:
-                       if n.List.Len() < 2 || n.List.Second().isBlank() {
+               case types.TARRAY, types.TSLICE:
+                       if n.List.Len() < 2 || ir.IsBlank(n.List.Second()) {
                                // for i := range x will only use x once, to compute len(x).
                                // No need to copy it.
                                break
                        }
                        fallthrough
 
-               case TCHAN, TSTRING:
+               case types.TCHAN, types.TSTRING:
                        // chan, string, slice, array ranges use value multiple times.
                        // make copy.
                        r := n.Right
 
-                       if r.Type.IsString() && r.Type != types.Types[TSTRING] {
-                               r = nod(OCONV, r, nil)
-                               r.Type = types.Types[TSTRING]
+                       if r.Type.IsString() && r.Type != types.Types[types.TSTRING] {
+                               r = ir.Nod(ir.OCONV, r, nil)
+                               r.Type = types.Types[types.TSTRING]
                                r = typecheck(r, ctxExpr)
                        }
 
                        n.Right = o.copyExpr(r, r.Type, false)
 
-               case TMAP:
+               case types.TMAP:
                        if isMapClear(n) {
                                // Preserve the body of the map clear pattern so it can
                                // be detected during walk. The loop body will not be used
@@ -826,7 +827,7 @@ func (o *Order) stmt(n *Node) {
                o.out = append(o.out, n)
                o.cleanTemp(t)
 
-       case ORETURN:
+       case ir.ORETURN:
                o.exprList(n.List)
                o.out = append(o.out, n)
 
@@ -839,11 +840,11 @@ func (o *Order) stmt(n *Node) {
        // reordered after the channel evaluation for a different
        // case (if p were nil, then the timing of the fault would
        // give this away).
-       case OSELECT:
+       case ir.OSELECT:
                t := o.markTemp()
 
                for _, n2 := range n.List.Slice() {
-                       if n2.Op != OCASE {
+                       if n2.Op != ir.OCASE {
                                base.Fatalf("order select case %v", n2.Op)
                        }
                        r := n2.Left
@@ -859,20 +860,20 @@ func (o *Order) stmt(n *Node) {
                        }
                        switch r.Op {
                        default:
-                               Dump("select case", r)
+                               ir.Dump("select case", r)
                                base.Fatalf("unknown op in select %v", r.Op)
 
                        // If this is case x := <-ch or case x, y := <-ch, the case has
                        // the ODCL nodes to declare x and y. We want to delay that
                        // declaration (and possible allocation) until inside the case body.
                        // Delete the ODCL nodes here and recreate them inside the body below.
-                       case OSELRECV, OSELRECV2:
+                       case ir.OSELRECV, ir.OSELRECV2:
                                if r.Colas() {
                                        i := 0
-                                       if r.Ninit.Len() != 0 && r.Ninit.First().Op == ODCL && r.Ninit.First().Left == r.Left {
+                                       if r.Ninit.Len() != 0 && r.Ninit.First().Op == ir.ODCL && r.Ninit.First().Left == r.Left {
                                                i++
                                        }
-                                       if i < r.Ninit.Len() && r.Ninit.Index(i).Op == ODCL && r.List.Len() != 0 && r.Ninit.Index(i).Left == r.List.First() {
+                                       if i < r.Ninit.Len() && r.Ninit.Index(i).Op == ir.ODCL && r.List.Len() != 0 && r.Ninit.Index(i).Left == r.List.First() {
                                                i++
                                        }
                                        if i >= r.Ninit.Len() {
@@ -881,7 +882,7 @@ func (o *Order) stmt(n *Node) {
                                }
 
                                if r.Ninit.Len() != 0 {
-                                       dumplist("ninit", r.Ninit)
+                                       ir.DumpList("ninit", r.Ninit)
                                        base.Fatalf("ninit on select recv")
                                }
 
@@ -892,7 +893,7 @@ func (o *Order) stmt(n *Node) {
                                // c is always evaluated; x and ok are only evaluated when assigned.
                                r.Right.Left = o.expr(r.Right.Left, nil)
 
-                               if r.Right.Left.Op != ONAME {
+                               if r.Right.Left.Op != ir.ONAME {
                                        r.Right.Left = o.copyExpr(r.Right.Left, r.Right.Left.Type, false)
                                }
 
@@ -902,7 +903,7 @@ func (o *Order) stmt(n *Node) {
                                // temporary per distinct type, sharing the temp among all receives
                                // with that temp. Similarly one ok bool could be shared among all
                                // the x,ok receives. Not worth doing until there's a clear need.
-                               if r.Left != nil && r.Left.isBlank() {
+                               if r.Left != nil && ir.IsBlank(r.Left) {
                                        r.Left = nil
                                }
                                if r.Left != nil {
@@ -912,38 +913,38 @@ func (o *Order) stmt(n *Node) {
                                        tmp1 := r.Left
 
                                        if r.Colas() {
-                                               tmp2 := nod(ODCL, tmp1, nil)
+                                               tmp2 := ir.Nod(ir.ODCL, tmp1, nil)
                                                tmp2 = typecheck(tmp2, ctxStmt)
                                                n2.Ninit.Append(tmp2)
                                        }
 
                                        r.Left = o.newTemp(r.Right.Left.Type.Elem(), r.Right.Left.Type.Elem().HasPointers())
-                                       tmp2 := nod(OAS, tmp1, r.Left)
+                                       tmp2 := ir.Nod(ir.OAS, tmp1, r.Left)
                                        tmp2 = typecheck(tmp2, ctxStmt)
                                        n2.Ninit.Append(tmp2)
                                }
 
-                               if r.List.Len() != 0 && r.List.First().isBlank() {
+                               if r.List.Len() != 0 && ir.IsBlank(r.List.First()) {
                                        r.List.Set(nil)
                                }
                                if r.List.Len() != 0 {
                                        tmp1 := r.List.First()
                                        if r.Colas() {
-                                               tmp2 := nod(ODCL, tmp1, nil)
+                                               tmp2 := ir.Nod(ir.ODCL, tmp1, nil)
                                                tmp2 = typecheck(tmp2, ctxStmt)
                                                n2.Ninit.Append(tmp2)
                                        }
 
-                                       r.List.Set1(o.newTemp(types.Types[TBOOL], false))
+                                       r.List.Set1(o.newTemp(types.Types[types.TBOOL], false))
                                        tmp2 := okas(tmp1, r.List.First())
                                        tmp2 = typecheck(tmp2, ctxStmt)
                                        n2.Ninit.Append(tmp2)
                                }
                                orderBlock(&n2.Ninit, o.free)
 
-                       case OSEND:
+                       case ir.OSEND:
                                if r.Ninit.Len() != 0 {
-                                       dumplist("ninit", r.Ninit)
+                                       ir.DumpList("ninit", r.Ninit)
                                        base.Fatalf("ninit on select send")
                                }
 
@@ -977,7 +978,7 @@ func (o *Order) stmt(n *Node) {
                o.popTemp(t)
 
        // Special: value being sent is passed as a pointer; make it addressable.
-       case OSEND:
+       case ir.OSEND:
                t := o.markTemp()
                n.Left = o.expr(n.Left, nil)
                n.Right = o.expr(n.Right, nil)
@@ -998,16 +999,16 @@ func (o *Order) stmt(n *Node) {
        // the if-else chain instead.)
        // For now just clean all the temporaries at the end.
        // In practice that's fine.
-       case OSWITCH:
+       case ir.OSWITCH:
                if base.Debug.Libfuzzer != 0 && !hasDefaultCase(n) {
                        // Add empty "default:" case for instrumentation.
-                       n.List.Append(nod(OCASE, nil, nil))
+                       n.List.Append(ir.Nod(ir.OCASE, nil, nil))
                }
 
                t := o.markTemp()
                n.Left = o.expr(n.Left, nil)
                for _, ncas := range n.List.Slice() {
-                       if ncas.Op != OCASE {
+                       if ncas.Op != ir.OCASE {
                                base.Fatalf("order switch case %v", ncas.Op)
                        }
                        o.exprListInPlace(ncas.List)
@@ -1021,9 +1022,9 @@ func (o *Order) stmt(n *Node) {
        base.Pos = lno
 }
 
-func hasDefaultCase(n *Node) bool {
+func hasDefaultCase(n *ir.Node) bool {
        for _, ncas := range n.List.Slice() {
-               if ncas.Op != OCASE {
+               if ncas.Op != ir.OCASE {
                        base.Fatalf("expected case, found %v", ncas.Op)
                }
                if ncas.List.Len() == 0 {
@@ -1034,7 +1035,7 @@ func hasDefaultCase(n *Node) bool {
 }
 
 // exprList orders the expression list l into o.
-func (o *Order) exprList(l Nodes) {
+func (o *Order) exprList(l ir.Nodes) {
        s := l.Slice()
        for i := range s {
                s[i] = o.expr(s[i], nil)
@@ -1043,7 +1044,7 @@ func (o *Order) exprList(l Nodes) {
 
 // exprListInPlace orders the expression list l but saves
 // the side effects on the individual expression ninit lists.
-func (o *Order) exprListInPlace(l Nodes) {
+func (o *Order) exprListInPlace(l ir.Nodes) {
        s := l.Slice()
        for i := range s {
                s[i] = o.exprInPlace(s[i])
@@ -1051,7 +1052,7 @@ func (o *Order) exprListInPlace(l Nodes) {
 }
 
 // prealloc[x] records the allocation to use for x.
-var prealloc = map[*Node]*Node{}
+var prealloc = map[*ir.Node]*ir.Node{}
 
 // expr orders a single expression, appending side
 // effects to o.out as needed.
@@ -1060,7 +1061,7 @@ var prealloc = map[*Node]*Node{}
 // to avoid copying the result of the expression to a temporary.)
 // The result of expr MUST be assigned back to n, e.g.
 //     n.Left = o.expr(n.Left, lhs)
-func (o *Order) expr(n, lhs *Node) *Node {
+func (o *Order) expr(n, lhs *ir.Node) *ir.Node {
        if n == nil {
                return n
        }
@@ -1078,11 +1079,11 @@ func (o *Order) expr(n, lhs *Node) *Node {
        // Addition of strings turns into a function call.
        // Allocate a temporary to hold the strings.
        // Fewer than 5 strings use direct runtime helpers.
-       case OADDSTR:
+       case ir.OADDSTR:
                o.exprList(n.List)
 
                if n.List.Len() > 5 {
-                       t := types.NewArray(types.Types[TSTRING], int64(n.List.Len()))
+                       t := types.NewArray(types.Types[types.TSTRING], int64(n.List.Len()))
                        prealloc[n] = o.newTemp(t, false)
                }
 
@@ -1097,19 +1098,19 @@ func (o *Order) expr(n, lhs *Node) *Node {
 
                haslit := false
                for _, n1 := range n.List.Slice() {
-                       hasbyte = hasbyte || n1.Op == OBYTES2STR
-                       haslit = haslit || n1.Op == OLITERAL && len(n1.StringVal()) != 0
+                       hasbyte = hasbyte || n1.Op == ir.OBYTES2STR
+                       haslit = haslit || n1.Op == ir.OLITERAL && len(n1.StringVal()) != 0
                }
 
                if haslit && hasbyte {
                        for _, n2 := range n.List.Slice() {
-                               if n2.Op == OBYTES2STR {
-                                       n2.Op = OBYTES2STRTMP
+                               if n2.Op == ir.OBYTES2STR {
+                                       n2.Op = ir.OBYTES2STRTMP
                                }
                        }
                }
 
-       case OINDEXMAP:
+       case ir.OINDEXMAP:
                n.Left = o.expr(n.Left, nil)
                n.Right = o.expr(n.Right, nil)
                needCopy := false
@@ -1136,7 +1137,7 @@ func (o *Order) expr(n, lhs *Node) *Node {
 
        // concrete type (not interface) argument might need an addressable
        // temporary to pass to the runtime conversion routine.
-       case OCONVIFACE:
+       case ir.OCONVIFACE:
                n.Left = o.expr(n.Left, nil)
                if n.Left.Type.IsInterface() {
                        break
@@ -1148,21 +1149,21 @@ func (o *Order) expr(n, lhs *Node) *Node {
                        n.Left = o.addrTemp(n.Left)
                }
 
-       case OCONVNOP:
-               if n.Type.IsKind(TUNSAFEPTR) && n.Left.Type.IsKind(TUINTPTR) && (n.Left.Op == OCALLFUNC || n.Left.Op == OCALLINTER || n.Left.Op == OCALLMETH) {
+       case ir.OCONVNOP:
+               if n.Type.IsKind(types.TUNSAFEPTR) && n.Left.Type.IsKind(types.TUINTPTR) && (n.Left.Op == ir.OCALLFUNC || n.Left.Op == ir.OCALLINTER || n.Left.Op == ir.OCALLMETH) {
                        // When reordering unsafe.Pointer(f()) into a separate
                        // statement, the conversion and function call must stay
                        // together. See golang.org/issue/15329.
                        o.init(n.Left)
                        o.call(n.Left)
-                       if lhs == nil || lhs.Op != ONAME || instrumenting {
+                       if lhs == nil || lhs.Op != ir.ONAME || instrumenting {
                                n = o.copyExpr(n, n.Type, false)
                        }
                } else {
                        n.Left = o.expr(n.Left, nil)
                }
 
-       case OANDAND, OOROR:
+       case ir.OANDAND, ir.OOROR:
                // ... = LHS && RHS
                //
                // var r bool
@@ -1176,7 +1177,7 @@ func (o *Order) expr(n, lhs *Node) *Node {
 
                // Evaluate left-hand side.
                lhs := o.expr(n.Left, nil)
-               o.out = append(o.out, typecheck(nod(OAS, r, lhs), ctxStmt))
+               o.out = append(o.out, typecheck(ir.Nod(ir.OAS, r, lhs), ctxStmt))
 
                // Evaluate right-hand side, save generated code.
                saveout := o.out
@@ -1184,14 +1185,14 @@ func (o *Order) expr(n, lhs *Node) *Node {
                t := o.markTemp()
                o.edge()
                rhs := o.expr(n.Right, nil)
-               o.out = append(o.out, typecheck(nod(OAS, r, rhs), ctxStmt))
+               o.out = append(o.out, typecheck(ir.Nod(ir.OAS, r, rhs), ctxStmt))
                o.cleanTemp(t)
                gen := o.out
                o.out = saveout
 
                // If left-hand side doesn't cause a short-circuit, issue right-hand side.
-               nif := nod(OIF, r, nil)
-               if n.Op == OANDAND {
+               nif := ir.Nod(ir.OIF, r, nil)
+               if n.Op == ir.OANDAND {
                        nif.Nbody.Set(gen)
                } else {
                        nif.Rlist.Set(gen)
@@ -1199,24 +1200,24 @@ func (o *Order) expr(n, lhs *Node) *Node {
                o.out = append(o.out, nif)
                n = r
 
-       case OCALLFUNC,
-               OCALLINTER,
-               OCALLMETH,
-               OCAP,
-               OCOMPLEX,
-               OCOPY,
-               OIMAG,
-               OLEN,
-               OMAKECHAN,
-               OMAKEMAP,
-               OMAKESLICE,
-               OMAKESLICECOPY,
-               ONEW,
-               OREAL,
-               ORECOVER,
-               OSTR2BYTES,
-               OSTR2BYTESTMP,
-               OSTR2RUNES:
+       case ir.OCALLFUNC,
+               ir.OCALLINTER,
+               ir.OCALLMETH,
+               ir.OCAP,
+               ir.OCOMPLEX,
+               ir.OCOPY,
+               ir.OIMAG,
+               ir.OLEN,
+               ir.OMAKECHAN,
+               ir.OMAKEMAP,
+               ir.OMAKESLICE,
+               ir.OMAKESLICECOPY,
+               ir.ONEW,
+               ir.OREAL,
+               ir.ORECOVER,
+               ir.OSTR2BYTES,
+               ir.OSTR2BYTESTMP,
+               ir.OSTR2RUNES:
 
                if isRuneCount(n) {
                        // len([]rune(s)) is rewritten to runtime.countrunes(s) later.
@@ -1225,11 +1226,11 @@ func (o *Order) expr(n, lhs *Node) *Node {
                        o.call(n)
                }
 
-               if lhs == nil || lhs.Op != ONAME || instrumenting {
+               if lhs == nil || lhs.Op != ir.ONAME || instrumenting {
                        n = o.copyExpr(n, n.Type, false)
                }
 
-       case OAPPEND:
+       case ir.OAPPEND:
                // Check for append(x, make([]T, y)...) .
                if isAppendOfMake(n) {
                        n.List.SetFirst(o.expr(n.List.First(), nil))             // order x
@@ -1238,11 +1239,11 @@ func (o *Order) expr(n, lhs *Node) *Node {
                        o.exprList(n.List)
                }
 
-               if lhs == nil || lhs.Op != ONAME && !samesafeexpr(lhs, n.List.First()) {
+               if lhs == nil || lhs.Op != ir.ONAME && !samesafeexpr(lhs, n.List.First()) {
                        n = o.copyExpr(n, n.Type, false)
                }
 
-       case OSLICE, OSLICEARR, OSLICESTR, OSLICE3, OSLICE3ARR:
+       case ir.OSLICE, ir.OSLICEARR, ir.OSLICESTR, ir.OSLICE3, ir.OSLICE3ARR:
                n.Left = o.expr(n.Left, nil)
                low, high, max := n.SliceBounds()
                low = o.expr(low, nil)
@@ -1252,16 +1253,16 @@ func (o *Order) expr(n, lhs *Node) *Node {
                max = o.expr(max, nil)
                max = o.cheapExpr(max)
                n.SetSliceBounds(low, high, max)
-               if lhs == nil || lhs.Op != ONAME && !samesafeexpr(lhs, n.Left) {
+               if lhs == nil || lhs.Op != ir.ONAME && !samesafeexpr(lhs, n.Left) {
                        n = o.copyExpr(n, n.Type, false)
                }
 
-       case OCLOSURE:
+       case ir.OCLOSURE:
                if n.Transient() && n.Func.ClosureVars.Len() > 0 {
                        prealloc[n] = o.newTemp(closureType(n), false)
                }
 
-       case OSLICELIT, OCALLPART:
+       case ir.OSLICELIT, ir.OCALLPART:
                n.Left = o.expr(n.Left, nil)
                n.Right = o.expr(n.Right, nil)
                o.exprList(n.List)
@@ -1269,25 +1270,25 @@ func (o *Order) expr(n, lhs *Node) *Node {
                if n.Transient() {
                        var t *types.Type
                        switch n.Op {
-                       case OSLICELIT:
+                       case ir.OSLICELIT:
                                t = types.NewArray(n.Type.Elem(), n.Right.Int64Val())
-                       case OCALLPART:
+                       case ir.OCALLPART:
                                t = partialCallType(n)
                        }
                        prealloc[n] = o.newTemp(t, false)
                }
 
-       case ODOTTYPE, ODOTTYPE2:
+       case ir.ODOTTYPE, ir.ODOTTYPE2:
                n.Left = o.expr(n.Left, nil)
                if !isdirectiface(n.Type) || instrumenting {
                        n = o.copyExpr(n, n.Type, true)
                }
 
-       case ORECV:
+       case ir.ORECV:
                n.Left = o.expr(n.Left, nil)
                n = o.copyExpr(n, n.Type, true)
 
-       case OEQ, ONE, OLT, OLE, OGT, OGE:
+       case ir.OEQ, ir.ONE, ir.OLT, ir.OLE, ir.OGT, ir.OGE:
                n.Left = o.expr(n.Left, nil)
                n.Right = o.expr(n.Right, nil)
 
@@ -1297,11 +1298,11 @@ func (o *Order) expr(n, lhs *Node) *Node {
                        // Mark string(byteSlice) arguments to reuse byteSlice backing
                        // buffer during conversion. String comparison does not
                        // memorize the strings for later use, so it is safe.
-                       if n.Left.Op == OBYTES2STR {
-                               n.Left.Op = OBYTES2STRTMP
+                       if n.Left.Op == ir.OBYTES2STR {
+                               n.Left.Op = ir.OBYTES2STRTMP
                        }
-                       if n.Right.Op == OBYTES2STR {
-                               n.Right.Op = OBYTES2STRTMP
+                       if n.Right.Op == ir.OBYTES2STR {
+                               n.Right.Op = ir.OBYTES2STRTMP
                        }
 
                case t.IsStruct() || t.IsArray():
@@ -1310,7 +1311,7 @@ func (o *Order) expr(n, lhs *Node) *Node {
                        n.Left = o.addrTemp(n.Left)
                        n.Right = o.addrTemp(n.Right)
                }
-       case OMAPLIT:
+       case ir.OMAPLIT:
                // Order map by converting:
                //   map[int]int{
                //     a(): b(),
@@ -1328,9 +1329,9 @@ func (o *Order) expr(n, lhs *Node) *Node {
                // See issue 26552.
                entries := n.List.Slice()
                statics := entries[:0]
-               var dynamics []*Node
+               var dynamics []*ir.Node
                for _, r := range entries {
-                       if r.Op != OKEY {
+                       if r.Op != ir.OKEY {
                                base.Fatalf("OMAPLIT entry not OKEY: %v\n", r)
                        }
 
@@ -1357,14 +1358,14 @@ func (o *Order) expr(n, lhs *Node) *Node {
 
                // Emit the creation of the map (with all its static entries).
                m := o.newTemp(n.Type, false)
-               as := nod(OAS, m, n)
+               as := ir.Nod(ir.OAS, m, n)
                typecheck(as, ctxStmt)
                o.stmt(as)
                n = m
 
                // Emit eval+insert of dynamic entries, one at a time.
                for _, r := range dynamics {
-                       as := nod(OAS, nod(OINDEX, n, r.Left), r.Right)
+                       as := ir.Nod(ir.OAS, ir.Nod(ir.OINDEX, n, r.Left), r.Right)
                        typecheck(as, ctxStmt) // Note: this converts the OINDEX to an OINDEXMAP
                        o.stmt(as)
                }
@@ -1376,11 +1377,11 @@ func (o *Order) expr(n, lhs *Node) *Node {
 
 // okas creates and returns an assignment of val to ok,
 // including an explicit conversion if necessary.
-func okas(ok, val *Node) *Node {
-       if !ok.isBlank() {
+func okas(ok, val *ir.Node) *ir.Node {
+       if !ir.IsBlank(ok) {
                val = conv(val, ok.Type)
        }
-       return nod(OAS, ok, val)
+       return ir.Nod(ir.OAS, ok, val)
 }
 
 // as2 orders OAS2XXXX nodes. It creates temporaries to ensure left-to-right assignment.
@@ -1391,11 +1392,11 @@ func okas(ok, val *Node) *Node {
 //     tmp1, tmp2, tmp3 = ...
 //     a, b, a = tmp1, tmp2, tmp3
 // This is necessary to ensure left to right assignment order.
-func (o *Order) as2(n *Node) {
-       tmplist := []*Node{}
-       left := []*Node{}
+func (o *Order) as2(n *ir.Node) {
+       tmplist := []*ir.Node{}
+       left := []*ir.Node{}
        for ni, l := range n.List.Slice() {
-               if !l.isBlank() {
+               if !ir.IsBlank(l) {
                        tmp := o.newTemp(l.Type, l.Type.HasPointers())
                        n.List.SetIndex(ni, tmp)
                        tmplist = append(tmplist, tmp)
@@ -1405,7 +1406,7 @@ func (o *Order) as2(n *Node) {
 
        o.out = append(o.out, n)
 
-       as := nod(OAS2, nil, nil)
+       as := ir.Nod(ir.OAS2, nil, nil)
        as.List.Set(left)
        as.Rlist.Set(tmplist)
        as = typecheck(as, ctxStmt)
@@ -1414,21 +1415,21 @@ func (o *Order) as2(n *Node) {
 
 // okAs2 orders OAS2XXX with ok.
 // Just like as2, this also adds temporaries to ensure left-to-right assignment.
-func (o *Order) okAs2(n *Node) {
-       var tmp1, tmp2 *Node
-       if !n.List.First().isBlank() {
+func (o *Order) okAs2(n *ir.Node) {
+       var tmp1, tmp2 *ir.Node
+       if !ir.IsBlank(n.List.First()) {
                typ := n.Right.Type
                tmp1 = o.newTemp(typ, typ.HasPointers())
        }
 
-       if !n.List.Second().isBlank() {
-               tmp2 = o.newTemp(types.Types[TBOOL], false)
+       if !ir.IsBlank(n.List.Second()) {
+               tmp2 = o.newTemp(types.Types[types.TBOOL], false)
        }
 
        o.out = append(o.out, n)
 
        if tmp1 != nil {
-               r := nod(OAS, n.List.First(), tmp1)
+               r := ir.Nod(ir.OAS, n.List.First(), tmp1)
                r = typecheck(r, ctxStmt)
                o.mapAssign(r)
                n.List.SetFirst(tmp1)
index f10599dc2806b8b3cb1ac88ed88117c14124e925..38f416c1c3842f8dec8315c2b9c3e5b241a5cf5d 100644 (file)
@@ -6,6 +6,7 @@ package gc
 
 import (
        "cmd/compile/internal/base"
+       "cmd/compile/internal/ir"
        "cmd/compile/internal/ssa"
        "cmd/compile/internal/types"
        "cmd/internal/dwarf"
@@ -23,14 +24,14 @@ import (
 // "Portable" code generation.
 
 var (
-       compilequeue []*Node // functions waiting to be compiled
+       compilequeue []*ir.Node // functions waiting to be compiled
 )
 
-func emitptrargsmap(fn *Node) {
-       if fn.funcname() == "_" || fn.Func.Nname.Sym.Linkname != "" {
+func emitptrargsmap(fn *ir.Node) {
+       if ir.FuncName(fn) == "_" || fn.Func.Nname.Sym.Linkname != "" {
                return
        }
-       lsym := base.Ctxt.Lookup(fn.Func.lsym.Name + ".args_stackmap")
+       lsym := base.Ctxt.Lookup(fn.Func.LSym.Name + ".args_stackmap")
 
        nptr := int(fn.Type.ArgWidth() / int64(Widthptr))
        bv := bvalloc(int32(nptr) * 2)
@@ -41,7 +42,7 @@ func emitptrargsmap(fn *Node) {
        off := duint32(lsym, 0, uint32(nbitmap))
        off = duint32(lsym, off, uint32(bv.n))
 
-       if fn.IsMethod() {
+       if ir.IsMethod(fn) {
                onebitwalktype1(fn.Type.Recvs(), 0, bv)
        }
        if fn.Type.NumParams() > 0 {
@@ -67,12 +68,12 @@ func emitptrargsmap(fn *Node) {
 // really means, in memory, things with pointers needing zeroing at
 // the top of the stack and increasing in size.
 // Non-autos sort on offset.
-func cmpstackvarlt(a, b *Node) bool {
-       if (a.Class() == PAUTO) != (b.Class() == PAUTO) {
-               return b.Class() == PAUTO
+func cmpstackvarlt(a, b *ir.Node) bool {
+       if (a.Class() == ir.PAUTO) != (b.Class() == ir.PAUTO) {
+               return b.Class() == ir.PAUTO
        }
 
-       if a.Class() != PAUTO {
+       if a.Class() != ir.PAUTO {
                return a.Xoffset < b.Xoffset
        }
 
@@ -100,7 +101,7 @@ func cmpstackvarlt(a, b *Node) bool {
 }
 
 // byStackvar implements sort.Interface for []*Node using cmpstackvarlt.
-type byStackVar []*Node
+type byStackVar []*ir.Node
 
 func (s byStackVar) Len() int           { return len(s) }
 func (s byStackVar) Less(i, j int) bool { return cmpstackvarlt(s[i], s[j]) }
@@ -113,28 +114,28 @@ func (s *ssafn) AllocFrame(f *ssa.Func) {
 
        // Mark the PAUTO's unused.
        for _, ln := range fn.Dcl {
-               if ln.Class() == PAUTO {
+               if ln.Class() == ir.PAUTO {
                        ln.Name.SetUsed(false)
                }
        }
 
        for _, l := range f.RegAlloc {
                if ls, ok := l.(ssa.LocalSlot); ok {
-                       ls.N.(*Node).Name.SetUsed(true)
+                       ls.N.(*ir.Node).Name.SetUsed(true)
                }
        }
 
        scratchUsed := false
        for _, b := range f.Blocks {
                for _, v := range b.Values {
-                       if n, ok := v.Aux.(*Node); ok {
+                       if n, ok := v.Aux.(*ir.Node); ok {
                                switch n.Class() {
-                               case PPARAM, PPARAMOUT:
+                               case ir.PPARAM, ir.PPARAMOUT:
                                        // Don't modify nodfp; it is a global.
                                        if n != nodfp {
                                                n.Name.SetUsed(true)
                                        }
-                               case PAUTO:
+                               case ir.PAUTO:
                                        n.Name.SetUsed(true)
                                }
                        }
@@ -146,7 +147,7 @@ func (s *ssafn) AllocFrame(f *ssa.Func) {
        }
 
        if f.Config.NeedsFpScratch && scratchUsed {
-               s.scratchFpMem = tempAt(src.NoXPos, s.curfn, types.Types[TUINT64])
+               s.scratchFpMem = tempAt(src.NoXPos, s.curfn, types.Types[types.TUINT64])
        }
 
        sort.Sort(byStackVar(fn.Dcl))
@@ -154,7 +155,7 @@ func (s *ssafn) AllocFrame(f *ssa.Func) {
        // Reassign stack offsets of the locals that are used.
        lastHasPtr := false
        for i, n := range fn.Dcl {
-               if n.Op != ONAME || n.Class() != PAUTO {
+               if n.Op != ir.ONAME || n.Class() != ir.PAUTO {
                        continue
                }
                if !n.Name.Used() {
@@ -192,7 +193,7 @@ func (s *ssafn) AllocFrame(f *ssa.Func) {
        s.stkptrsize = Rnd(s.stkptrsize, int64(Widthreg))
 }
 
-func funccompile(fn *Node) {
+func funccompile(fn *ir.Node) {
        if Curfn != nil {
                base.Fatalf("funccompile %v inside %v", fn.Func.Nname.Sym, Curfn.Func.Nname.Sym)
        }
@@ -209,21 +210,21 @@ func funccompile(fn *Node) {
 
        if fn.Nbody.Len() == 0 {
                // Initialize ABI wrappers if necessary.
-               fn.Func.initLSym(false)
+               initLSym(fn.Func, false)
                emitptrargsmap(fn)
                return
        }
 
-       dclcontext = PAUTO
+       dclcontext = ir.PAUTO
        Curfn = fn
 
        compile(fn)
 
        Curfn = nil
-       dclcontext = PEXTERN
+       dclcontext = ir.PEXTERN
 }
 
-func compile(fn *Node) {
+func compile(fn *ir.Node) {
        errorsBefore := base.Errors()
        order(fn)
        if base.Errors() > errorsBefore {
@@ -233,7 +234,7 @@ func compile(fn *Node) {
        // Set up the function's LSym early to avoid data races with the assemblers.
        // Do this before walk, as walk needs the LSym to set attributes/relocations
        // (e.g. in markTypeUsedInInterface).
-       fn.Func.initLSym(true)
+       initLSym(fn.Func, true)
 
        walk(fn)
        if base.Errors() > errorsBefore {
@@ -246,7 +247,7 @@ func compile(fn *Node) {
        // From this point, there should be no uses of Curfn. Enforce that.
        Curfn = nil
 
-       if fn.funcname() == "_" {
+       if ir.FuncName(fn) == "_" {
                // We don't need to generate code for this function, just report errors in its body.
                // At this point we've generated any errors needed.
                // (Beyond here we generate only non-spec errors, like "stack frame too large".)
@@ -260,13 +261,13 @@ func compile(fn *Node) {
        // phase of the compiler.
        for _, n := range fn.Func.Dcl {
                switch n.Class() {
-               case PPARAM, PPARAMOUT, PAUTO:
+               case ir.PPARAM, ir.PPARAMOUT, ir.PAUTO:
                        if livenessShouldTrack(n) && n.Name.Addrtaken() {
                                dtypesym(n.Type)
                                // Also make sure we allocate a linker symbol
                                // for the stack object data, for the same reason.
-                               if fn.Func.lsym.Func().StackObjects == nil {
-                                       fn.Func.lsym.Func().StackObjects = base.Ctxt.Lookup(fn.Func.lsym.Name + ".stkobj")
+                               if fn.Func.LSym.Func().StackObjects == nil {
+                                       fn.Func.LSym.Func().StackObjects = base.Ctxt.Lookup(fn.Func.LSym.Name + ".stkobj")
                                }
                        }
                }
@@ -283,13 +284,13 @@ func compile(fn *Node) {
 // If functions are not compiled immediately,
 // they are enqueued in compilequeue,
 // which is drained by compileFunctions.
-func compilenow(fn *Node) bool {
+func compilenow(fn *ir.Node) bool {
        // Issue 38068: if this function is a method AND an inline
        // candidate AND was not inlined (yet), put it onto the compile
        // queue instead of compiling it immediately. This is in case we
        // wind up inlining it into a method wrapper that is generated by
        // compiling a function later on in the xtop list.
-       if fn.IsMethod() && isInlinableButNotInlined(fn) {
+       if ir.IsMethod(fn) && isInlinableButNotInlined(fn) {
                return false
        }
        return base.Flag.LowerC == 1 && base.Debug.CompileLater == 0
@@ -298,7 +299,7 @@ func compilenow(fn *Node) bool {
 // isInlinableButNotInlined returns true if 'fn' was marked as an
 // inline candidate but then never inlined (presumably because we
 // found no call sites).
-func isInlinableButNotInlined(fn *Node) bool {
+func isInlinableButNotInlined(fn *ir.Node) bool {
        if fn.Func.Nname.Func.Inl == nil {
                return false
        }
@@ -314,7 +315,7 @@ const maxStackSize = 1 << 30
 // uses it to generate a plist,
 // and flushes that plist to machine code.
 // worker indicates which of the backend workers is doing the processing.
-func compileSSA(fn *Node, worker int) {
+func compileSSA(fn *ir.Node, worker int) {
        f := buildssa(fn, worker)
        // Note: check arg size to fix issue 25507.
        if f.Frontend().(*ssafn).stksize >= maxStackSize || fn.Type.ArgWidth() >= maxStackSize {
@@ -359,7 +360,7 @@ func compileFunctions() {
                sizeCalculationDisabled = true // not safe to calculate sizes concurrently
                if race.Enabled {
                        // Randomize compilation order to try to shake out races.
-                       tmp := make([]*Node, len(compilequeue))
+                       tmp := make([]*ir.Node, len(compilequeue))
                        perm := rand.Perm(len(compilequeue))
                        for i, v := range perm {
                                tmp[v] = compilequeue[i]
@@ -375,7 +376,7 @@ func compileFunctions() {
                }
                var wg sync.WaitGroup
                base.Ctxt.InParallel = true
-               c := make(chan *Node, base.Flag.LowerC)
+               c := make(chan *ir.Node, base.Flag.LowerC)
                for i := 0; i < base.Flag.LowerC; i++ {
                        wg.Add(1)
                        go func(worker int) {
@@ -397,7 +398,7 @@ func compileFunctions() {
 }
 
 func debuginfo(fnsym *obj.LSym, infosym *obj.LSym, curfn interface{}) ([]dwarf.Scope, dwarf.InlCalls) {
-       fn := curfn.(*Node)
+       fn := curfn.(*ir.Node)
        if fn.Func.Nname != nil {
                if expect := fn.Func.Nname.Sym.Linksym(); fnsym != expect {
                        base.Fatalf("unexpected fnsym: %v != %v", fnsym, expect)
@@ -429,17 +430,17 @@ func debuginfo(fnsym *obj.LSym, infosym *obj.LSym, curfn interface{}) ([]dwarf.S
        //
        // These two adjustments keep toolstash -cmp working for now.
        // Deciding the right answer is, as they say, future work.
-       isODCLFUNC := fn.Op == ODCLFUNC
+       isODCLFUNC := fn.Op == ir.ODCLFUNC
 
-       var apdecls []*Node
+       var apdecls []*ir.Node
        // Populate decls for fn.
        if isODCLFUNC {
                for _, n := range fn.Func.Dcl {
-                       if n.Op != ONAME { // might be OTYPE or OLITERAL
+                       if n.Op != ir.ONAME { // might be OTYPE or OLITERAL
                                continue
                        }
                        switch n.Class() {
-                       case PAUTO:
+                       case ir.PAUTO:
                                if !n.Name.Used() {
                                        // Text == nil -> generating abstract function
                                        if fnsym.Func().Text != nil {
@@ -447,7 +448,7 @@ func debuginfo(fnsym *obj.LSym, infosym *obj.LSym, curfn interface{}) ([]dwarf.S
                                        }
                                        continue
                                }
-                       case PPARAM, PPARAMOUT:
+                       case ir.PPARAM, ir.PPARAMOUT:
                        default:
                                continue
                        }
@@ -474,7 +475,7 @@ func debuginfo(fnsym *obj.LSym, infosym *obj.LSym, curfn interface{}) ([]dwarf.S
        }
        fnsym.Func().Autot = nil
 
-       var varScopes []ScopeID
+       var varScopes []ir.ScopeID
        for _, decl := range decls {
                pos := declPos(decl)
                varScopes = append(varScopes, findScope(fn.Func.Marks, pos))
@@ -488,7 +489,7 @@ func debuginfo(fnsym *obj.LSym, infosym *obj.LSym, curfn interface{}) ([]dwarf.S
        return scopes, inlcalls
 }
 
-func declPos(decl *Node) src.XPos {
+func declPos(decl *ir.Node) src.XPos {
        if decl.Name.Defn != nil && (decl.Name.Captured() || decl.Name.Byval()) {
                // It's not clear which position is correct for captured variables here:
                // * decl.Pos is the wrong position for captured variables, in the inner
@@ -511,10 +512,10 @@ func declPos(decl *Node) src.XPos {
 
 // createSimpleVars creates a DWARF entry for every variable declared in the
 // function, claiming that they are permanently on the stack.
-func createSimpleVars(fnsym *obj.LSym, apDecls []*Node) ([]*Node, []*dwarf.Var, map[*Node]bool) {
+func createSimpleVars(fnsym *obj.LSym, apDecls []*ir.Node) ([]*ir.Node, []*dwarf.Var, map[*ir.Node]bool) {
        var vars []*dwarf.Var
-       var decls []*Node
-       selected := make(map[*Node]bool)
+       var decls []*ir.Node
+       selected := make(map[*ir.Node]bool)
        for _, n := range apDecls {
                if n.IsAutoTmp() {
                        continue
@@ -527,12 +528,12 @@ func createSimpleVars(fnsym *obj.LSym, apDecls []*Node) ([]*Node, []*dwarf.Var,
        return decls, vars, selected
 }
 
-func createSimpleVar(fnsym *obj.LSym, n *Node) *dwarf.Var {
+func createSimpleVar(fnsym *obj.LSym, n *ir.Node) *dwarf.Var {
        var abbrev int
        offs := n.Xoffset
 
        switch n.Class() {
-       case PAUTO:
+       case ir.PAUTO:
                abbrev = dwarf.DW_ABRV_AUTO
                if base.Ctxt.FixedFrameSize() == 0 {
                        offs -= int64(Widthptr)
@@ -542,7 +543,7 @@ func createSimpleVar(fnsym *obj.LSym, n *Node) *dwarf.Var {
                        offs -= int64(Widthptr)
                }
 
-       case PPARAM, PPARAMOUT:
+       case ir.PPARAM, ir.PPARAMOUT:
                abbrev = dwarf.DW_ABRV_PARAM
                offs += base.Ctxt.FixedFrameSize()
        default:
@@ -563,7 +564,7 @@ func createSimpleVar(fnsym *obj.LSym, n *Node) *dwarf.Var {
        declpos := base.Ctxt.InnermostPos(declPos(n))
        return &dwarf.Var{
                Name:          n.Sym.Name,
-               IsReturnValue: n.Class() == PPARAMOUT,
+               IsReturnValue: n.Class() == ir.PPARAMOUT,
                IsInlFormal:   n.Name.InlFormal(),
                Abbrev:        abbrev,
                StackOffset:   int32(offs),
@@ -578,19 +579,19 @@ func createSimpleVar(fnsym *obj.LSym, n *Node) *dwarf.Var {
 
 // createComplexVars creates recomposed DWARF vars with location lists,
 // suitable for describing optimized code.
-func createComplexVars(fnsym *obj.LSym, fn *Func) ([]*Node, []*dwarf.Var, map[*Node]bool) {
+func createComplexVars(fnsym *obj.LSym, fn *ir.Func) ([]*ir.Node, []*dwarf.Var, map[*ir.Node]bool) {
        debugInfo := fn.DebugInfo
 
        // Produce a DWARF variable entry for each user variable.
-       var decls []*Node
+       var decls []*ir.Node
        var vars []*dwarf.Var
-       ssaVars := make(map[*Node]bool)
+       ssaVars := make(map[*ir.Node]bool)
 
        for varID, dvar := range debugInfo.Vars {
-               n := dvar.(*Node)
+               n := dvar.(*ir.Node)
                ssaVars[n] = true
                for _, slot := range debugInfo.VarSlots[varID] {
-                       ssaVars[debugInfo.Slots[slot].N.(*Node)] = true
+                       ssaVars[debugInfo.Slots[slot].N.(*ir.Node)] = true
                }
 
                if dvar := createComplexVar(fnsym, fn, ssa.VarID(varID)); dvar != nil {
@@ -604,11 +605,11 @@ func createComplexVars(fnsym *obj.LSym, fn *Func) ([]*Node, []*dwarf.Var, map[*N
 
 // createDwarfVars process fn, returning a list of DWARF variables and the
 // Nodes they represent.
-func createDwarfVars(fnsym *obj.LSym, complexOK bool, fn *Func, apDecls []*Node) ([]*Node, []*dwarf.Var) {
+func createDwarfVars(fnsym *obj.LSym, complexOK bool, fn *ir.Func, apDecls []*ir.Node) ([]*ir.Node, []*dwarf.Var) {
        // Collect a raw list of DWARF vars.
        var vars []*dwarf.Var
-       var decls []*Node
-       var selected map[*Node]bool
+       var decls []*ir.Node
+       var selected map[*ir.Node]bool
        if base.Ctxt.Flag_locationlists && base.Ctxt.Flag_optimize && fn.DebugInfo != nil && complexOK {
                decls, vars, selected = createComplexVars(fnsym, fn)
        } else {
@@ -640,7 +641,7 @@ func createDwarfVars(fnsym *obj.LSym, complexOK bool, fn *Func, apDecls []*Node)
                if c == '.' || n.Type.IsUntyped() {
                        continue
                }
-               if n.Class() == PPARAM && !canSSAType(n.Type) {
+               if n.Class() == ir.PPARAM && !canSSAType(n.Type) {
                        // SSA-able args get location lists, and may move in and
                        // out of registers, so those are handled elsewhere.
                        // Autos and named output params seem to get handled
@@ -655,10 +656,10 @@ func createDwarfVars(fnsym *obj.LSym, complexOK bool, fn *Func, apDecls []*Node)
                typename := dwarf.InfoPrefix + typesymname(n.Type)
                decls = append(decls, n)
                abbrev := dwarf.DW_ABRV_AUTO_LOCLIST
-               isReturnValue := (n.Class() == PPARAMOUT)
-               if n.Class() == PPARAM || n.Class() == PPARAMOUT {
+               isReturnValue := (n.Class() == ir.PPARAMOUT)
+               if n.Class() == ir.PPARAM || n.Class() == ir.PPARAMOUT {
                        abbrev = dwarf.DW_ABRV_PARAM_LOCLIST
-               } else if n.Class() == PAUTOHEAP {
+               } else if n.Class() == ir.PAUTOHEAP {
                        // If dcl in question has been promoted to heap, do a bit
                        // of extra work to recover original class (auto or param);
                        // see issue 30908. This insures that we get the proper
@@ -667,9 +668,9 @@ func createDwarfVars(fnsym *obj.LSym, complexOK bool, fn *Func, apDecls []*Node)
                        // and not stack).
                        // TODO(thanm): generate a better location expression
                        stackcopy := n.Name.Param.Stackcopy
-                       if stackcopy != nil && (stackcopy.Class() == PPARAM || stackcopy.Class() == PPARAMOUT) {
+                       if stackcopy != nil && (stackcopy.Class() == ir.PPARAM || stackcopy.Class() == ir.PPARAMOUT) {
                                abbrev = dwarf.DW_ABRV_PARAM_LOCLIST
-                               isReturnValue = (stackcopy.Class() == PPARAMOUT)
+                               isReturnValue = (stackcopy.Class() == ir.PPARAMOUT)
                        }
                }
                inlIndex := 0
@@ -707,9 +708,9 @@ func createDwarfVars(fnsym *obj.LSym, complexOK bool, fn *Func, apDecls []*Node)
 // function that is not local to the package being compiled, then the
 // names of the variables may have been "versioned" to avoid conflicts
 // with local vars; disregard this versioning when sorting.
-func preInliningDcls(fnsym *obj.LSym) []*Node {
-       fn := base.Ctxt.DwFixups.GetPrecursorFunc(fnsym).(*Node)
-       var rdcl []*Node
+func preInliningDcls(fnsym *obj.LSym) []*ir.Node {
+       fn := base.Ctxt.DwFixups.GetPrecursorFunc(fnsym).(*ir.Node)
+       var rdcl []*ir.Node
        for _, n := range fn.Func.Inl.Dcl {
                c := n.Sym.Name[0]
                // Avoid reporting "_" parameters, since if there are more than
@@ -726,10 +727,10 @@ func preInliningDcls(fnsym *obj.LSym) []*Node {
 // stack pointer, suitable for use in a DWARF location entry. This has nothing
 // to do with its offset in the user variable.
 func stackOffset(slot ssa.LocalSlot) int32 {
-       n := slot.N.(*Node)
+       n := slot.N.(*ir.Node)
        var off int64
        switch n.Class() {
-       case PAUTO:
+       case ir.PAUTO:
                if base.Ctxt.FixedFrameSize() == 0 {
                        off -= int64(Widthptr)
                }
@@ -737,22 +738,22 @@ func stackOffset(slot ssa.LocalSlot) int32 {
                        // There is a word space for FP on ARM64 even if the frame pointer is disabled
                        off -= int64(Widthptr)
                }
-       case PPARAM, PPARAMOUT:
+       case ir.PPARAM, ir.PPARAMOUT:
                off += base.Ctxt.FixedFrameSize()
        }
        return int32(off + n.Xoffset + slot.Off)
 }
 
 // createComplexVar builds a single DWARF variable entry and location list.
-func createComplexVar(fnsym *obj.LSym, fn *Func, varID ssa.VarID) *dwarf.Var {
+func createComplexVar(fnsym *obj.LSym, fn *ir.Func, varID ssa.VarID) *dwarf.Var {
        debug := fn.DebugInfo
-       n := debug.Vars[varID].(*Node)
+       n := debug.Vars[varID].(*ir.Node)
 
        var abbrev int
        switch n.Class() {
-       case PAUTO:
+       case ir.PAUTO:
                abbrev = dwarf.DW_ABRV_AUTO_LOCLIST
-       case PPARAM, PPARAMOUT:
+       case ir.PPARAM, ir.PPARAMOUT:
                abbrev = dwarf.DW_ABRV_PARAM_LOCLIST
        default:
                return nil
@@ -773,7 +774,7 @@ func createComplexVar(fnsym *obj.LSym, fn *Func, varID ssa.VarID) *dwarf.Var {
        declpos := base.Ctxt.InnermostPos(n.Pos)
        dvar := &dwarf.Var{
                Name:          n.Sym.Name,
-               IsReturnValue: n.Class() == PPARAMOUT,
+               IsReturnValue: n.Class() == ir.PPARAMOUT,
                IsInlFormal:   n.Name.InlFormal(),
                Abbrev:        abbrev,
                Type:          base.Ctxt.Lookup(typename),
index 932ab47d02635996d4c940971dac7f6386160b66..9f1f00d46a50069709d19117d627b95367ff4877 100644 (file)
@@ -5,6 +5,7 @@
 package gc
 
 import (
+       "cmd/compile/internal/ir"
        "cmd/compile/internal/types"
        "reflect"
        "sort"
@@ -12,133 +13,133 @@ import (
 )
 
 func typeWithoutPointers() *types.Type {
-       t := types.New(TSTRUCT)
-       f := &types.Field{Type: types.New(TINT)}
+       t := types.New(types.TSTRUCT)
+       f := &types.Field{Type: types.New(types.TINT)}
        t.SetFields([]*types.Field{f})
        return t
 }
 
 func typeWithPointers() *types.Type {
-       t := types.New(TSTRUCT)
-       f := &types.Field{Type: types.NewPtr(types.New(TINT))}
+       t := types.New(types.TSTRUCT)
+       f := &types.Field{Type: types.NewPtr(types.New(types.TINT))}
        t.SetFields([]*types.Field{f})
        return t
 }
 
-func markUsed(n *Node) *Node {
+func markUsed(n *ir.Node) *ir.Node {
        n.Name.SetUsed(true)
        return n
 }
 
-func markNeedZero(n *Node) *Node {
+func markNeedZero(n *ir.Node) *ir.Node {
        n.Name.SetNeedzero(true)
        return n
 }
 
 // Test all code paths for cmpstackvarlt.
 func TestCmpstackvar(t *testing.T) {
-       nod := func(xoffset int64, t *types.Type, s *types.Sym, cl Class) *Node {
+       nod := func(xoffset int64, t *types.Type, s *types.Sym, cl ir.Class) *ir.Node {
                if s == nil {
                        s = &types.Sym{Name: "."}
                }
-               n := newname(s)
+               n := NewName(s)
                n.Type = t
                n.Xoffset = xoffset
                n.SetClass(cl)
                return n
        }
        testdata := []struct {
-               a, b *Node
+               a, b *ir.Node
                lt   bool
        }{
                {
-                       nod(0, nil, nil, PAUTO),
-                       nod(0, nil, nil, PFUNC),
+                       nod(0, nil, nil, ir.PAUTO),
+                       nod(0, nil, nil, ir.PFUNC),
                        false,
                },
                {
-                       nod(0, nil, nil, PFUNC),
-                       nod(0, nil, nil, PAUTO),
+                       nod(0, nil, nil, ir.PFUNC),
+                       nod(0, nil, nil, ir.PAUTO),
                        true,
                },
                {
-                       nod(0, nil, nil, PFUNC),
-                       nod(10, nil, nil, PFUNC),
+                       nod(0, nil, nil, ir.PFUNC),
+                       nod(10, nil, nil, ir.PFUNC),
                        true,
                },
                {
-                       nod(20, nil, nil, PFUNC),
-                       nod(10, nil, nil, PFUNC),
+                       nod(20, nil, nil, ir.PFUNC),
+                       nod(10, nil, nil, ir.PFUNC),
                        false,
                },
                {
-                       nod(10, nil, nil, PFUNC),
-                       nod(10, nil, nil, PFUNC),
+                       nod(10, nil, nil, ir.PFUNC),
+                       nod(10, nil, nil, ir.PFUNC),
                        false,
                },
                {
-                       nod(10, nil, nil, PPARAM),
-                       nod(20, nil, nil, PPARAMOUT),
+                       nod(10, nil, nil, ir.PPARAM),
+                       nod(20, nil, nil, ir.PPARAMOUT),
                        true,
                },
                {
-                       nod(10, nil, nil, PPARAMOUT),
-                       nod(20, nil, nil, PPARAM),
+                       nod(10, nil, nil, ir.PPARAMOUT),
+                       nod(20, nil, nil, ir.PPARAM),
                        true,
                },
                {
-                       markUsed(nod(0, nil, nil, PAUTO)),
-                       nod(0, nil, nil, PAUTO),
+                       markUsed(nod(0, nil, nil, ir.PAUTO)),
+                       nod(0, nil, nil, ir.PAUTO),
                        true,
                },
                {
-                       nod(0, nil, nil, PAUTO),
-                       markUsed(nod(0, nil, nil, PAUTO)),
+                       nod(0, nil, nil, ir.PAUTO),
+                       markUsed(nod(0, nil, nil, ir.PAUTO)),
                        false,
                },
                {
-                       nod(0, typeWithoutPointers(), nil, PAUTO),
-                       nod(0, typeWithPointers(), nil, PAUTO),
+                       nod(0, typeWithoutPointers(), nil, ir.PAUTO),
+                       nod(0, typeWithPointers(), nil, ir.PAUTO),
                        false,
                },
                {
-                       nod(0, typeWithPointers(), nil, PAUTO),
-                       nod(0, typeWithoutPointers(), nil, PAUTO),
+                       nod(0, typeWithPointers(), nil, ir.PAUTO),
+                       nod(0, typeWithoutPointers(), nil, ir.PAUTO),
                        true,
                },
                {
-                       markNeedZero(nod(0, &types.Type{}, nil, PAUTO)),
-                       nod(0, &types.Type{}, nil, PAUTO),
+                       markNeedZero(nod(0, &types.Type{}, nil, ir.PAUTO)),
+                       nod(0, &types.Type{}, nil, ir.PAUTO),
                        true,
                },
                {
-                       nod(0, &types.Type{}, nil, PAUTO),
-                       markNeedZero(nod(0, &types.Type{}, nil, PAUTO)),
+                       nod(0, &types.Type{}, nil, ir.PAUTO),
+                       markNeedZero(nod(0, &types.Type{}, nil, ir.PAUTO)),
                        false,
                },
                {
-                       nod(0, &types.Type{Width: 1}, nil, PAUTO),
-                       nod(0, &types.Type{Width: 2}, nil, PAUTO),
+                       nod(0, &types.Type{Width: 1}, nil, ir.PAUTO),
+                       nod(0, &types.Type{Width: 2}, nil, ir.PAUTO),
                        false,
                },
                {
-                       nod(0, &types.Type{Width: 2}, nil, PAUTO),
-                       nod(0, &types.Type{Width: 1}, nil, PAUTO),
+                       nod(0, &types.Type{Width: 2}, nil, ir.PAUTO),
+                       nod(0, &types.Type{Width: 1}, nil, ir.PAUTO),
                        true,
                },
                {
-                       nod(0, &types.Type{}, &types.Sym{Name: "abc"}, PAUTO),
-                       nod(0, &types.Type{}, &types.Sym{Name: "xyz"}, PAUTO),
+                       nod(0, &types.Type{}, &types.Sym{Name: "abc"}, ir.PAUTO),
+                       nod(0, &types.Type{}, &types.Sym{Name: "xyz"}, ir.PAUTO),
                        true,
                },
                {
-                       nod(0, &types.Type{}, &types.Sym{Name: "abc"}, PAUTO),
-                       nod(0, &types.Type{}, &types.Sym{Name: "abc"}, PAUTO),
+                       nod(0, &types.Type{}, &types.Sym{Name: "abc"}, ir.PAUTO),
+                       nod(0, &types.Type{}, &types.Sym{Name: "abc"}, ir.PAUTO),
                        false,
                },
                {
-                       nod(0, &types.Type{}, &types.Sym{Name: "xyz"}, PAUTO),
-                       nod(0, &types.Type{}, &types.Sym{Name: "abc"}, PAUTO),
+                       nod(0, &types.Type{}, &types.Sym{Name: "xyz"}, ir.PAUTO),
+                       nod(0, &types.Type{}, &types.Sym{Name: "abc"}, ir.PAUTO),
                        false,
                },
        }
@@ -155,42 +156,42 @@ func TestCmpstackvar(t *testing.T) {
 }
 
 func TestStackvarSort(t *testing.T) {
-       nod := func(xoffset int64, t *types.Type, s *types.Sym, cl Class) *Node {
-               n := newname(s)
+       nod := func(xoffset int64, t *types.Type, s *types.Sym, cl ir.Class) *ir.Node {
+               n := NewName(s)
                n.Type = t
                n.Xoffset = xoffset
                n.SetClass(cl)
                return n
        }
-       inp := []*Node{
-               nod(0, &types.Type{}, &types.Sym{}, PFUNC),
-               nod(0, &types.Type{}, &types.Sym{}, PAUTO),
-               nod(0, &types.Type{}, &types.Sym{}, PFUNC),
-               nod(10, &types.Type{}, &types.Sym{}, PFUNC),
-               nod(20, &types.Type{}, &types.Sym{}, PFUNC),
-               markUsed(nod(0, &types.Type{}, &types.Sym{}, PAUTO)),
-               nod(0, typeWithoutPointers(), &types.Sym{}, PAUTO),
-               nod(0, &types.Type{}, &types.Sym{}, PAUTO),
-               markNeedZero(nod(0, &types.Type{}, &types.Sym{}, PAUTO)),
-               nod(0, &types.Type{Width: 1}, &types.Sym{}, PAUTO),
-               nod(0, &types.Type{Width: 2}, &types.Sym{}, PAUTO),
-               nod(0, &types.Type{}, &types.Sym{Name: "abc"}, PAUTO),
-               nod(0, &types.Type{}, &types.Sym{Name: "xyz"}, PAUTO),
+       inp := []*ir.Node{
+               nod(0, &types.Type{}, &types.Sym{}, ir.PFUNC),
+               nod(0, &types.Type{}, &types.Sym{}, ir.PAUTO),
+               nod(0, &types.Type{}, &types.Sym{}, ir.PFUNC),
+               nod(10, &types.Type{}, &types.Sym{}, ir.PFUNC),
+               nod(20, &types.Type{}, &types.Sym{}, ir.PFUNC),
+               markUsed(nod(0, &types.Type{}, &types.Sym{}, ir.PAUTO)),
+               nod(0, typeWithoutPointers(), &types.Sym{}, ir.PAUTO),
+               nod(0, &types.Type{}, &types.Sym{}, ir.PAUTO),
+               markNeedZero(nod(0, &types.Type{}, &types.Sym{}, ir.PAUTO)),
+               nod(0, &types.Type{Width: 1}, &types.Sym{}, ir.PAUTO),
+               nod(0, &types.Type{Width: 2}, &types.Sym{}, ir.PAUTO),
+               nod(0, &types.Type{}, &types.Sym{Name: "abc"}, ir.PAUTO),
+               nod(0, &types.Type{}, &types.Sym{Name: "xyz"}, ir.PAUTO),
        }
-       want := []*Node{
-               nod(0, &types.Type{}, &types.Sym{}, PFUNC),
-               nod(0, &types.Type{}, &types.Sym{}, PFUNC),
-               nod(10, &types.Type{}, &types.Sym{}, PFUNC),
-               nod(20, &types.Type{}, &types.Sym{}, PFUNC),
-               markUsed(nod(0, &types.Type{}, &types.Sym{}, PAUTO)),
-               markNeedZero(nod(0, &types.Type{}, &types.Sym{}, PAUTO)),
-               nod(0, &types.Type{Width: 2}, &types.Sym{}, PAUTO),
-               nod(0, &types.Type{Width: 1}, &types.Sym{}, PAUTO),
-               nod(0, &types.Type{}, &types.Sym{}, PAUTO),
-               nod(0, &types.Type{}, &types.Sym{}, PAUTO),
-               nod(0, &types.Type{}, &types.Sym{Name: "abc"}, PAUTO),
-               nod(0, &types.Type{}, &types.Sym{Name: "xyz"}, PAUTO),
-               nod(0, typeWithoutPointers(), &types.Sym{}, PAUTO),
+       want := []*ir.Node{
+               nod(0, &types.Type{}, &types.Sym{}, ir.PFUNC),
+               nod(0, &types.Type{}, &types.Sym{}, ir.PFUNC),
+               nod(10, &types.Type{}, &types.Sym{}, ir.PFUNC),
+               nod(20, &types.Type{}, &types.Sym{}, ir.PFUNC),
+               markUsed(nod(0, &types.Type{}, &types.Sym{}, ir.PAUTO)),
+               markNeedZero(nod(0, &types.Type{}, &types.Sym{}, ir.PAUTO)),
+               nod(0, &types.Type{Width: 2}, &types.Sym{}, ir.PAUTO),
+               nod(0, &types.Type{Width: 1}, &types.Sym{}, ir.PAUTO),
+               nod(0, &types.Type{}, &types.Sym{}, ir.PAUTO),
+               nod(0, &types.Type{}, &types.Sym{}, ir.PAUTO),
+               nod(0, &types.Type{}, &types.Sym{Name: "abc"}, ir.PAUTO),
+               nod(0, &types.Type{}, &types.Sym{Name: "xyz"}, ir.PAUTO),
+               nod(0, typeWithoutPointers(), &types.Sym{}, ir.PAUTO),
        }
        sort.Sort(byStackVar(inp))
        if !reflect.DeepEqual(want, inp) {
index 4beaa11a7e3f38848a2c543e570c192af72a2fcf..2a88d4a5b4314b949aa0a39b980a24090498c67f 100644 (file)
@@ -5,6 +5,7 @@
 package gc
 
 import (
+       "cmd/compile/internal/ir"
        "cmd/compile/internal/ssa"
        "cmd/compile/internal/types"
        "cmd/internal/src"
@@ -40,11 +41,11 @@ func (s *state) insertPhis() {
 }
 
 type phiState struct {
-       s       *state                 // SSA state
-       f       *ssa.Func              // function to work on
-       defvars []map[*Node]*ssa.Value // defined variables at end of each block
+       s       *state                    // SSA state
+       f       *ssa.Func                 // function to work on
+       defvars []map[*ir.Node]*ssa.Value // defined variables at end of each block
 
-       varnum map[*Node]int32 // variable numbering
+       varnum map[*ir.Node]int32 // variable numbering
 
        // properties of the dominator tree
        idom  []*ssa.Block // dominator parents
@@ -70,15 +71,15 @@ func (s *phiState) insertPhis() {
        // Find all the variables for which we need to match up reads & writes.
        // This step prunes any basic-block-only variables from consideration.
        // Generate a numbering for these variables.
-       s.varnum = map[*Node]int32{}
-       var vars []*Node
+       s.varnum = map[*ir.Node]int32{}
+       var vars []*ir.Node
        var vartypes []*types.Type
        for _, b := range s.f.Blocks {
                for _, v := range b.Values {
                        if v.Op != ssa.OpFwdRef {
                                continue
                        }
-                       var_ := v.Aux.(*Node)
+                       var_ := v.Aux.(*ir.Node)
 
                        // Optimization: look back 1 block for the definition.
                        if len(b.Preds) == 1 {
@@ -183,7 +184,7 @@ levels:
        }
 }
 
-func (s *phiState) insertVarPhis(n int, var_ *Node, defs []*ssa.Block, typ *types.Type) {
+func (s *phiState) insertVarPhis(n int, var_ *ir.Node, defs []*ssa.Block, typ *types.Type) {
        priq := &s.priq
        q := s.q
        queued := s.queued
@@ -318,7 +319,7 @@ func (s *phiState) resolveFwdRefs() {
                        if v.Op != ssa.OpFwdRef {
                                continue
                        }
-                       n := s.varnum[v.Aux.(*Node)]
+                       n := s.varnum[v.Aux.(*ir.Node)]
                        v.Op = ssa.OpCopy
                        v.Aux = nil
                        v.AddArg(values[n])
@@ -432,11 +433,11 @@ func (s *sparseSet) clear() {
 
 // Variant to use for small functions.
 type simplePhiState struct {
-       s         *state                 // SSA state
-       f         *ssa.Func              // function to work on
-       fwdrefs   []*ssa.Value           // list of FwdRefs to be processed
-       defvars   []map[*Node]*ssa.Value // defined variables at end of each block
-       reachable []bool                 // which blocks are reachable
+       s         *state                    // SSA state
+       f         *ssa.Func                 // function to work on
+       fwdrefs   []*ssa.Value              // list of FwdRefs to be processed
+       defvars   []map[*ir.Node]*ssa.Value // defined variables at end of each block
+       reachable []bool                    // which blocks are reachable
 }
 
 func (s *simplePhiState) insertPhis() {
@@ -449,7 +450,7 @@ func (s *simplePhiState) insertPhis() {
                                continue
                        }
                        s.fwdrefs = append(s.fwdrefs, v)
-                       var_ := v.Aux.(*Node)
+                       var_ := v.Aux.(*ir.Node)
                        if _, ok := s.defvars[b.ID][var_]; !ok {
                                s.defvars[b.ID][var_] = v // treat FwdDefs as definitions.
                        }
@@ -463,7 +464,7 @@ loop:
                v := s.fwdrefs[len(s.fwdrefs)-1]
                s.fwdrefs = s.fwdrefs[:len(s.fwdrefs)-1]
                b := v.Block
-               var_ := v.Aux.(*Node)
+               var_ := v.Aux.(*ir.Node)
                if b == s.f.Entry {
                        // No variable should be live at entry.
                        s.s.Fatalf("Value live at entry. It shouldn't be. func %s, node %v, value %v", s.f.Name, var_, v)
@@ -511,7 +512,7 @@ loop:
 }
 
 // lookupVarOutgoing finds the variable's value at the end of block b.
-func (s *simplePhiState) lookupVarOutgoing(b *ssa.Block, t *types.Type, var_ *Node, line src.XPos) *ssa.Value {
+func (s *simplePhiState) lookupVarOutgoing(b *ssa.Block, t *types.Type, var_ *ir.Node, line src.XPos) *ssa.Value {
        for {
                if v := s.defvars[b.ID][var_]; v != nil {
                        return v
index da2298480ad6066ad9da599938a9ae495523ea40..f0895884668ad30b31e95638126354bdcc250779 100644 (file)
@@ -16,6 +16,7 @@ package gc
 
 import (
        "cmd/compile/internal/base"
+       "cmd/compile/internal/ir"
        "cmd/compile/internal/ssa"
        "cmd/compile/internal/types"
        "cmd/internal/obj"
@@ -100,10 +101,10 @@ type BlockEffects struct {
 
 // A collection of global state used by liveness analysis.
 type Liveness struct {
-       fn         *Node
+       fn         *ir.Node
        f          *ssa.Func
-       vars       []*Node
-       idx        map[*Node]int32
+       vars       []*ir.Node
+       idx        map[*ir.Node]int32
        stkptrsize int64
 
        be []BlockEffects
@@ -205,20 +206,20 @@ type progeffectscache struct {
 // nor do we care about non-local variables,
 // nor do we care about empty structs (handled by the pointer check),
 // nor do we care about the fake PAUTOHEAP variables.
-func livenessShouldTrack(n *Node) bool {
-       return n.Op == ONAME && (n.Class() == PAUTO || n.Class() == PPARAM || n.Class() == PPARAMOUT) && n.Type.HasPointers()
+func livenessShouldTrack(n *ir.Node) bool {
+       return n.Op == ir.ONAME && (n.Class() == ir.PAUTO || n.Class() == ir.PPARAM || n.Class() == ir.PPARAMOUT) && n.Type.HasPointers()
 }
 
 // getvariables returns the list of on-stack variables that we need to track
 // and a map for looking up indices by *Node.
-func getvariables(fn *Node) ([]*Node, map[*Node]int32) {
-       var vars []*Node
+func getvariables(fn *ir.Node) ([]*ir.Node, map[*ir.Node]int32) {
+       var vars []*ir.Node
        for _, n := range fn.Func.Dcl {
                if livenessShouldTrack(n) {
                        vars = append(vars, n)
                }
        }
-       idx := make(map[*Node]int32, len(vars))
+       idx := make(map[*ir.Node]int32, len(vars))
        for i, n := range vars {
                idx[n] = int32(i)
        }
@@ -234,7 +235,7 @@ func (lv *Liveness) initcache() {
 
        for i, node := range lv.vars {
                switch node.Class() {
-               case PPARAM:
+               case ir.PPARAM:
                        // A return instruction with a p.to is a tail return, which brings
                        // the stack pointer back up (if it ever went down) and then jumps
                        // to a new function entirely. That form of instruction must read
@@ -243,7 +244,7 @@ func (lv *Liveness) initcache() {
                        // function runs.
                        lv.cache.tailuevar = append(lv.cache.tailuevar, int32(i))
 
-               case PPARAMOUT:
+               case ir.PPARAMOUT:
                        // All results are live at every return point.
                        // Note that this point is after escaping return values
                        // are copied back to the stack using their PAUTOHEAP references.
@@ -271,7 +272,7 @@ const (
 // If v does not affect any tracked variables, it returns -1, 0.
 func (lv *Liveness) valueEffects(v *ssa.Value) (int32, liveEffect) {
        n, e := affectedNode(v)
-       if e == 0 || n == nil || n.Op != ONAME { // cheapest checks first
+       if e == 0 || n == nil || n.Op != ir.ONAME { // cheapest checks first
                return -1, 0
        }
 
@@ -311,7 +312,7 @@ func (lv *Liveness) valueEffects(v *ssa.Value) (int32, liveEffect) {
 }
 
 // affectedNode returns the *Node affected by v
-func affectedNode(v *ssa.Value) (*Node, ssa.SymEffect) {
+func affectedNode(v *ssa.Value) (*ir.Node, ssa.SymEffect) {
        // Special cases.
        switch v.Op {
        case ssa.OpLoadReg:
@@ -322,9 +323,9 @@ func affectedNode(v *ssa.Value) (*Node, ssa.SymEffect) {
                return n, ssa.SymWrite
 
        case ssa.OpVarLive:
-               return v.Aux.(*Node), ssa.SymRead
+               return v.Aux.(*ir.Node), ssa.SymRead
        case ssa.OpVarDef, ssa.OpVarKill:
-               return v.Aux.(*Node), ssa.SymWrite
+               return v.Aux.(*ir.Node), ssa.SymWrite
        case ssa.OpKeepAlive:
                n, _ := AutoVar(v.Args[0])
                return n, ssa.SymRead
@@ -339,7 +340,7 @@ func affectedNode(v *ssa.Value) (*Node, ssa.SymEffect) {
        case nil, *obj.LSym:
                // ok, but no node
                return nil, e
-       case *Node:
+       case *ir.Node:
                return a, e
        default:
                base.Fatalf("weird aux: %s", v.LongString())
@@ -355,7 +356,7 @@ type livenessFuncCache struct {
 // Constructs a new liveness structure used to hold the global state of the
 // liveness computation. The cfg argument is a slice of *BasicBlocks and the
 // vars argument is a slice of *Nodes.
-func newliveness(fn *Node, f *ssa.Func, vars []*Node, idx map[*Node]int32, stkptrsize int64) *Liveness {
+func newliveness(fn *ir.Node, f *ssa.Func, vars []*ir.Node, idx map[*ir.Node]int32, stkptrsize int64) *Liveness {
        lv := &Liveness{
                fn:         fn,
                f:          f,
@@ -416,20 +417,20 @@ func onebitwalktype1(t *types.Type, off int64, bv bvec) {
        }
 
        switch t.Etype {
-       case TPTR, TUNSAFEPTR, TFUNC, TCHAN, TMAP:
+       case types.TPTR, types.TUNSAFEPTR, types.TFUNC, types.TCHAN, types.TMAP:
                if off&int64(Widthptr-1) != 0 {
                        base.Fatalf("onebitwalktype1: invalid alignment, %v", t)
                }
                bv.Set(int32(off / int64(Widthptr))) // pointer
 
-       case TSTRING:
+       case types.TSTRING:
                // struct { byte *str; intgo len; }
                if off&int64(Widthptr-1) != 0 {
                        base.Fatalf("onebitwalktype1: invalid alignment, %v", t)
                }
                bv.Set(int32(off / int64(Widthptr))) //pointer in first slot
 
-       case TINTER:
+       case types.TINTER:
                // struct { Itab *tab;  void *data; }
                // or, when isnilinter(t)==true:
                // struct { Type *type; void *data; }
@@ -450,14 +451,14 @@ func onebitwalktype1(t *types.Type, off int64, bv bvec) {
                // well as scan itabs to update their itab._type fields).
                bv.Set(int32(off/int64(Widthptr) + 1)) // pointer in second slot
 
-       case TSLICE:
+       case types.TSLICE:
                // struct { byte *array; uintgo len; uintgo cap; }
                if off&int64(Widthptr-1) != 0 {
                        base.Fatalf("onebitwalktype1: invalid TARRAY alignment, %v", t)
                }
                bv.Set(int32(off / int64(Widthptr))) // pointer in first slot (BitsPointer)
 
-       case TARRAY:
+       case types.TARRAY:
                elt := t.Elem()
                if elt.Width == 0 {
                        // Short-circuit for #20739.
@@ -468,7 +469,7 @@ func onebitwalktype1(t *types.Type, off int64, bv bvec) {
                        off += elt.Width
                }
 
-       case TSTRUCT:
+       case types.TSTRUCT:
                for _, f := range t.Fields().Slice() {
                        onebitwalktype1(f.Type, off+f.Offset, bv)
                }
@@ -481,7 +482,7 @@ func onebitwalktype1(t *types.Type, off int64, bv bvec) {
 // Generates live pointer value maps for arguments and local variables. The
 // this argument and the in arguments are always assumed live. The vars
 // argument is a slice of *Nodes.
-func (lv *Liveness) pointerMap(liveout bvec, vars []*Node, args, locals bvec) {
+func (lv *Liveness) pointerMap(liveout bvec, vars []*ir.Node, args, locals bvec) {
        for i := int32(0); ; i++ {
                i = liveout.Next(i)
                if i < 0 {
@@ -489,10 +490,10 @@ func (lv *Liveness) pointerMap(liveout bvec, vars []*Node, args, locals bvec) {
                }
                node := vars[i]
                switch node.Class() {
-               case PAUTO:
+               case ir.PAUTO:
                        onebitwalktype1(node.Type, node.Xoffset+lv.stkptrsize, locals)
 
-               case PPARAM, PPARAMOUT:
+               case ir.PPARAM, ir.PPARAMOUT:
                        onebitwalktype1(node.Type, node.Xoffset, args)
                }
        }
@@ -789,7 +790,7 @@ func (lv *Liveness) epilogue() {
        // don't need to keep the stack copy live?
        if lv.fn.Func.HasDefer() {
                for i, n := range lv.vars {
-                       if n.Class() == PPARAMOUT {
+                       if n.Class() == ir.PPARAMOUT {
                                if n.Name.IsOutputParamHeapAddr() {
                                        // Just to be paranoid.  Heap addresses are PAUTOs.
                                        base.Fatalf("variable %v both output param and heap output param", n)
@@ -887,7 +888,7 @@ func (lv *Liveness) epilogue() {
                                if !liveout.Get(int32(i)) {
                                        continue
                                }
-                               if n.Class() == PPARAM {
+                               if n.Class() == ir.PPARAM {
                                        continue // ok
                                }
                                base.Fatalf("bad live variable at entry of %v: %L", lv.fn.Func.Nname, n)
@@ -920,7 +921,7 @@ func (lv *Liveness) epilogue() {
        // the only things that can possibly be live are the
        // input parameters.
        for j, n := range lv.vars {
-               if n.Class() != PPARAM && lv.stackMaps[0].Get(int32(j)) {
+               if n.Class() != ir.PPARAM && lv.stackMaps[0].Get(int32(j)) {
                        lv.f.Fatalf("%v %L recorded as live on entry", lv.fn.Func.Nname, n)
                }
        }
@@ -967,7 +968,7 @@ func (lv *Liveness) compact(b *ssa.Block) {
 }
 
 func (lv *Liveness) showlive(v *ssa.Value, live bvec) {
-       if base.Flag.Live == 0 || lv.fn.funcname() == "init" || strings.HasPrefix(lv.fn.funcname(), ".") {
+       if base.Flag.Live == 0 || ir.FuncName(lv.fn) == "init" || strings.HasPrefix(ir.FuncName(lv.fn), ".") {
                return
        }
        if !(v == nil || v.Op.IsCall()) {
@@ -986,7 +987,7 @@ func (lv *Liveness) showlive(v *ssa.Value, live bvec) {
 
        s := "live at "
        if v == nil {
-               s += fmt.Sprintf("entry to %s:", lv.fn.funcname())
+               s += fmt.Sprintf("entry to %s:", ir.FuncName(lv.fn))
        } else if sym, ok := v.Aux.(*ssa.AuxCall); ok && sym.Fn != nil {
                fn := sym.Fn.Name
                if pos := strings.Index(fn, "."); pos >= 0 {
@@ -1051,7 +1052,7 @@ func (lv *Liveness) printeffect(printed bool, name string, pos int32, x bool) bo
 // This format synthesizes the information used during the multiple passes
 // into a single presentation.
 func (lv *Liveness) printDebug() {
-       fmt.Printf("liveness: %s\n", lv.fn.funcname())
+       fmt.Printf("liveness: %s\n", ir.FuncName(lv.fn))
 
        for i, b := range lv.f.Blocks {
                if i > 0 {
@@ -1163,10 +1164,10 @@ func (lv *Liveness) emit() (argsSym, liveSym *obj.LSym) {
        // Size args bitmaps to be just large enough to hold the largest pointer.
        // First, find the largest Xoffset node we care about.
        // (Nodes without pointers aren't in lv.vars; see livenessShouldTrack.)
-       var maxArgNode *Node
+       var maxArgNode *ir.Node
        for _, n := range lv.vars {
                switch n.Class() {
-               case PPARAM, PPARAMOUT:
+               case ir.PPARAM, ir.PPARAMOUT:
                        if maxArgNode == nil || n.Xoffset > maxArgNode.Xoffset {
                                maxArgNode = n
                        }
@@ -1265,7 +1266,7 @@ func liveness(e *ssafn, f *ssa.Func, pp *Progs) LivenessMap {
        }
 
        // Emit the live pointer map data structures
-       ls := e.curfn.Func.lsym
+       ls := e.curfn.Func.LSym
        fninfo := ls.Func()
        fninfo.GCArgs, fninfo.GCLocals = lv.emit()
 
@@ -1300,16 +1301,16 @@ func liveness(e *ssafn, f *ssa.Func, pp *Progs) LivenessMap {
 func isfat(t *types.Type) bool {
        if t != nil {
                switch t.Etype {
-               case TSLICE, TSTRING,
-                       TINTER: // maybe remove later
+               case types.TSLICE, types.TSTRING,
+                       types.TINTER: // maybe remove later
                        return true
-               case TARRAY:
+               case types.TARRAY:
                        // Array of 1 element, check if element is fat
                        if t.NumElem() == 1 {
                                return isfat(t.Elem())
                        }
                        return true
-               case TSTRUCT:
+               case types.TSTRUCT:
                        // Struct with 1 field, check if field is fat
                        if t.NumFields() == 1 {
                                return isfat(t.Field(0).Type)
index 20b4bc583b015d8e5c535c1ae688e53e05ef3246..d92749589f70939e1b5bb37c954d06dd1ff6b4f8 100644 (file)
@@ -6,6 +6,7 @@ package gc
 
 import (
        "cmd/compile/internal/base"
+       "cmd/compile/internal/ir"
        "cmd/compile/internal/types"
        "cmd/internal/src"
        "cmd/internal/sys"
@@ -59,8 +60,8 @@ func ispkgin(pkgs []string) bool {
        return false
 }
 
-func instrument(fn *Node) {
-       if fn.Func.Pragma&Norace != 0 {
+func instrument(fn *ir.Node) {
+       if fn.Func.Pragma&ir.Norace != 0 {
                return
        }
 
@@ -82,8 +83,8 @@ func instrument(fn *Node) {
                        // This only works for amd64. This will not
                        // work on arm or others that might support
                        // race in the future.
-                       nodpc := nodfp.copy()
-                       nodpc.Type = types.Types[TUINTPTR]
+                       nodpc := ir.Copy(nodfp)
+                       nodpc.Type = types.Types[types.TUINTPTR]
                        nodpc.Xoffset = int64(-Widthptr)
                        fn.Func.Dcl = append(fn.Func.Dcl, nodpc)
                        fn.Func.Enter.Prepend(mkcall("racefuncenter", nil, nil, nodpc))
index 568c5138ec30bf64f4b402a8c2e04dba39b1b307..edaec21f920c568c2ff494a407caebedef7e8713 100644 (file)
@@ -6,13 +6,14 @@ package gc
 
 import (
        "cmd/compile/internal/base"
+       "cmd/compile/internal/ir"
        "cmd/compile/internal/types"
        "cmd/internal/sys"
        "unicode/utf8"
 )
 
 // range
-func typecheckrange(n *Node) {
+func typecheckrange(n *ir.Node) {
        // Typechecking order is important here:
        // 0. first typecheck range expression (slice/map/chan),
        //      it is evaluated only once and so logically it is not part of the loop.
@@ -38,7 +39,7 @@ func typecheckrange(n *Node) {
        decldepth--
 }
 
-func typecheckrangeExpr(n *Node) {
+func typecheckrangeExpr(n *ir.Node) {
        n.Right = typecheck(n.Right, ctxExpr)
 
        t := n.Right.Type
@@ -65,15 +66,15 @@ func typecheckrangeExpr(n *Node) {
                base.ErrorfAt(n.Pos, "cannot range over %L", n.Right)
                return
 
-       case TARRAY, TSLICE:
-               t1 = types.Types[TINT]
+       case types.TARRAY, types.TSLICE:
+               t1 = types.Types[types.TINT]
                t2 = t.Elem()
 
-       case TMAP:
+       case types.TMAP:
                t1 = t.Key()
                t2 = t.Elem()
 
-       case TCHAN:
+       case types.TCHAN:
                if !t.ChanDir().CanRecv() {
                        base.ErrorfAt(n.Pos, "invalid operation: range %v (receive from send-only type %v)", n.Right, n.Right.Type)
                        return
@@ -85,8 +86,8 @@ func typecheckrangeExpr(n *Node) {
                        toomany = true
                }
 
-       case TSTRING:
-               t1 = types.Types[TINT]
+       case types.TSTRING:
+               t1 = types.Types[types.TINT]
                t2 = types.Runetype
        }
 
@@ -94,7 +95,7 @@ func typecheckrangeExpr(n *Node) {
                base.ErrorfAt(n.Pos, "too many variables in range")
        }
 
-       var v1, v2 *Node
+       var v1, v2 *ir.Node
        if n.List.Len() != 0 {
                v1 = n.List.First()
        }
@@ -106,7 +107,7 @@ func typecheckrangeExpr(n *Node) {
        // "if the second iteration variable is the blank identifier, the range
        // clause is equivalent to the same clause with only the first variable
        // present."
-       if v2.isBlank() {
+       if ir.IsBlank(v2) {
                if v1 != nil {
                        n.List.Set1(v1)
                }
@@ -117,7 +118,7 @@ func typecheckrangeExpr(n *Node) {
                if v1.Name != nil && v1.Name.Defn == n {
                        v1.Type = t1
                } else if v1.Type != nil {
-                       if op, why := assignop(t1, v1.Type); op == OXXX {
+                       if op, why := assignop(t1, v1.Type); op == ir.OXXX {
                                base.ErrorfAt(n.Pos, "cannot assign type %v to %L in range%s", t1, v1, why)
                        }
                }
@@ -128,7 +129,7 @@ func typecheckrangeExpr(n *Node) {
                if v2.Name != nil && v2.Name.Defn == n {
                        v2.Type = t2
                } else if v2.Type != nil {
-                       if op, why := assignop(t2, v2.Type); op == OXXX {
+                       if op, why := assignop(t2, v2.Type); op == ir.OXXX {
                                base.ErrorfAt(n.Pos, "cannot assign type %v to %L in range%s", t2, v2, why)
                        }
                }
@@ -156,7 +157,7 @@ func cheapComputableIndex(width int64) bool {
 // simpler forms.  The result must be assigned back to n.
 // Node n may also be modified in place, and may also be
 // the returned node.
-func walkrange(n *Node) *Node {
+func walkrange(n *ir.Node) *ir.Node {
        if isMapClear(n) {
                m := n.Right
                lno := setlineno(m)
@@ -178,7 +179,7 @@ func walkrange(n *Node) *Node {
        lno := setlineno(a)
        n.Right = nil
 
-       var v1, v2 *Node
+       var v1, v2 *ir.Node
        l := n.List.Len()
        if l > 0 {
                v1 = n.List.First()
@@ -188,11 +189,11 @@ func walkrange(n *Node) *Node {
                v2 = n.List.Second()
        }
 
-       if v2.isBlank() {
+       if ir.IsBlank(v2) {
                v2 = nil
        }
 
-       if v1.isBlank() && v2 == nil {
+       if ir.IsBlank(v1) && v2 == nil {
                v1 = nil
        }
 
@@ -204,17 +205,17 @@ func walkrange(n *Node) *Node {
        // to avoid erroneous processing by racewalk.
        n.List.Set(nil)
 
-       var ifGuard *Node
+       var ifGuard *ir.Node
 
-       translatedLoopOp := OFOR
+       translatedLoopOp := ir.OFOR
 
-       var body []*Node
-       var init []*Node
+       var body []*ir.Node
+       var init []*ir.Node
        switch t.Etype {
        default:
                base.Fatalf("walkrange")
 
-       case TARRAY, TSLICE:
+       case types.TARRAY, types.TSLICE:
                if arrayClear(n, v1, v2, a) {
                        base.Pos = lno
                        return n
@@ -223,14 +224,14 @@ func walkrange(n *Node) *Node {
                // order.stmt arranged for a copy of the array/slice variable if needed.
                ha := a
 
-               hv1 := temp(types.Types[TINT])
-               hn := temp(types.Types[TINT])
+               hv1 := temp(types.Types[types.TINT])
+               hn := temp(types.Types[types.TINT])
 
-               init = append(init, nod(OAS, hv1, nil))
-               init = append(init, nod(OAS, hn, nod(OLEN, ha, nil)))
+               init = append(init, ir.Nod(ir.OAS, hv1, nil))
+               init = append(init, ir.Nod(ir.OAS, hn, ir.Nod(ir.OLEN, ha, nil)))
 
-               n.Left = nod(OLT, hv1, hn)
-               n.Right = nod(OAS, hv1, nod(OADD, hv1, nodintconst(1)))
+               n.Left = ir.Nod(ir.OLT, hv1, hn)
+               n.Right = ir.Nod(ir.OAS, hv1, ir.Nod(ir.OADD, hv1, nodintconst(1)))
 
                // for range ha { body }
                if v1 == nil {
@@ -239,21 +240,21 @@ func walkrange(n *Node) *Node {
 
                // for v1 := range ha { body }
                if v2 == nil {
-                       body = []*Node{nod(OAS, v1, hv1)}
+                       body = []*ir.Node{ir.Nod(ir.OAS, v1, hv1)}
                        break
                }
 
                // for v1, v2 := range ha { body }
                if cheapComputableIndex(n.Type.Elem().Width) {
                        // v1, v2 = hv1, ha[hv1]
-                       tmp := nod(OINDEX, ha, hv1)
+                       tmp := ir.Nod(ir.OINDEX, ha, hv1)
                        tmp.SetBounded(true)
                        // Use OAS2 to correctly handle assignments
                        // of the form "v1, a[v1] := range".
-                       a := nod(OAS2, nil, nil)
+                       a := ir.Nod(ir.OAS2, nil, nil)
                        a.List.Set2(v1, v2)
                        a.Rlist.Set2(hv1, tmp)
-                       body = []*Node{a}
+                       body = []*ir.Node{a}
                        break
                }
 
@@ -269,20 +270,20 @@ func walkrange(n *Node) *Node {
                // TODO(austin): OFORUNTIL inhibits bounds-check
                // elimination on the index variable (see #20711).
                // Enhance the prove pass to understand this.
-               ifGuard = nod(OIF, nil, nil)
-               ifGuard.Left = nod(OLT, hv1, hn)
-               translatedLoopOp = OFORUNTIL
+               ifGuard = ir.Nod(ir.OIF, nil, nil)
+               ifGuard.Left = ir.Nod(ir.OLT, hv1, hn)
+               translatedLoopOp = ir.OFORUNTIL
 
                hp := temp(types.NewPtr(n.Type.Elem()))
-               tmp := nod(OINDEX, ha, nodintconst(0))
+               tmp := ir.Nod(ir.OINDEX, ha, nodintconst(0))
                tmp.SetBounded(true)
-               init = append(init, nod(OAS, hp, nod(OADDR, tmp, nil)))
+               init = append(init, ir.Nod(ir.OAS, hp, ir.Nod(ir.OADDR, tmp, nil)))
 
                // Use OAS2 to correctly handle assignments
                // of the form "v1, a[v1] := range".
-               a := nod(OAS2, nil, nil)
+               a := ir.Nod(ir.OAS2, nil, nil)
                a.List.Set2(v1, v2)
-               a.Rlist.Set2(hv1, nod(ODEREF, hp, nil))
+               a.Rlist.Set2(hv1, ir.Nod(ir.ODEREF, hp, nil))
                body = append(body, a)
 
                // Advance pointer as part of the late increment.
@@ -290,11 +291,11 @@ func walkrange(n *Node) *Node {
                // This runs *after* the condition check, so we know
                // advancing the pointer is safe and won't go past the
                // end of the allocation.
-               a = nod(OAS, hp, addptr(hp, t.Elem().Width))
+               a = ir.Nod(ir.OAS, hp, addptr(hp, t.Elem().Width))
                a = typecheck(a, ctxStmt)
                n.List.Set1(a)
 
-       case TMAP:
+       case types.TMAP:
                // order.stmt allocated the iterator for us.
                // we only use a once, so no copy needed.
                ha := a
@@ -308,29 +309,29 @@ func walkrange(n *Node) *Node {
                fn := syslook("mapiterinit")
 
                fn = substArgTypes(fn, t.Key(), t.Elem(), th)
-               init = append(init, mkcall1(fn, nil, nil, typename(t), ha, nod(OADDR, hit, nil)))
-               n.Left = nod(ONE, nodSym(ODOT, hit, keysym), nodnil())
+               init = append(init, mkcall1(fn, nil, nil, typename(t), ha, ir.Nod(ir.OADDR, hit, nil)))
+               n.Left = ir.Nod(ir.ONE, nodSym(ir.ODOT, hit, keysym), nodnil())
 
                fn = syslook("mapiternext")
                fn = substArgTypes(fn, th)
-               n.Right = mkcall1(fn, nil, nil, nod(OADDR, hit, nil))
+               n.Right = mkcall1(fn, nil, nil, ir.Nod(ir.OADDR, hit, nil))
 
-               key := nodSym(ODOT, hit, keysym)
-               key = nod(ODEREF, key, nil)
+               key := nodSym(ir.ODOT, hit, keysym)
+               key = ir.Nod(ir.ODEREF, key, nil)
                if v1 == nil {
                        body = nil
                } else if v2 == nil {
-                       body = []*Node{nod(OAS, v1, key)}
+                       body = []*ir.Node{ir.Nod(ir.OAS, v1, key)}
                } else {
-                       elem := nodSym(ODOT, hit, elemsym)
-                       elem = nod(ODEREF, elem, nil)
-                       a := nod(OAS2, nil, nil)
+                       elem := nodSym(ir.ODOT, hit, elemsym)
+                       elem = ir.Nod(ir.ODEREF, elem, nil)
+                       a := ir.Nod(ir.OAS2, nil, nil)
                        a.List.Set2(v1, v2)
                        a.Rlist.Set2(key, elem)
-                       body = []*Node{a}
+                       body = []*ir.Node{a}
                }
 
-       case TCHAN:
+       case types.TCHAN:
                // order.stmt arranged for a copy of the channel variable.
                ha := a
 
@@ -339,27 +340,27 @@ func walkrange(n *Node) *Node {
                hv1 := temp(t.Elem())
                hv1.SetTypecheck(1)
                if t.Elem().HasPointers() {
-                       init = append(init, nod(OAS, hv1, nil))
+                       init = append(init, ir.Nod(ir.OAS, hv1, nil))
                }
-               hb := temp(types.Types[TBOOL])
+               hb := temp(types.Types[types.TBOOL])
 
-               n.Left = nod(ONE, hb, nodbool(false))
-               a := nod(OAS2RECV, nil, nil)
+               n.Left = ir.Nod(ir.ONE, hb, nodbool(false))
+               a := ir.Nod(ir.OAS2RECV, nil, nil)
                a.SetTypecheck(1)
                a.List.Set2(hv1, hb)
-               a.Right = nod(ORECV, ha, nil)
+               a.Right = ir.Nod(ir.ORECV, ha, nil)
                n.Left.Ninit.Set1(a)
                if v1 == nil {
                        body = nil
                } else {
-                       body = []*Node{nod(OAS, v1, hv1)}
+                       body = []*ir.Node{ir.Nod(ir.OAS, v1, hv1)}
                }
                // Zero hv1. This prevents hv1 from being the sole, inaccessible
                // reference to an otherwise GC-able value during the next channel receive.
                // See issue 15281.
-               body = append(body, nod(OAS, hv1, nil))
+               body = append(body, ir.Nod(ir.OAS, hv1, nil))
 
-       case TSTRING:
+       case types.TSTRING:
                // Transform string range statements like "for v1, v2 = range a" into
                //
                // ha := a
@@ -378,35 +379,35 @@ func walkrange(n *Node) *Node {
                // order.stmt arranged for a copy of the string variable.
                ha := a
 
-               hv1 := temp(types.Types[TINT])
-               hv1t := temp(types.Types[TINT])
+               hv1 := temp(types.Types[types.TINT])
+               hv1t := temp(types.Types[types.TINT])
                hv2 := temp(types.Runetype)
 
                // hv1 := 0
-               init = append(init, nod(OAS, hv1, nil))
+               init = append(init, ir.Nod(ir.OAS, hv1, nil))
 
                // hv1 < len(ha)
-               n.Left = nod(OLT, hv1, nod(OLEN, ha, nil))
+               n.Left = ir.Nod(ir.OLT, hv1, ir.Nod(ir.OLEN, ha, nil))
 
                if v1 != nil {
                        // hv1t = hv1
-                       body = append(body, nod(OAS, hv1t, hv1))
+                       body = append(body, ir.Nod(ir.OAS, hv1t, hv1))
                }
 
                // hv2 := rune(ha[hv1])
-               nind := nod(OINDEX, ha, hv1)
+               nind := ir.Nod(ir.OINDEX, ha, hv1)
                nind.SetBounded(true)
-               body = append(body, nod(OAS, hv2, conv(nind, types.Runetype)))
+               body = append(body, ir.Nod(ir.OAS, hv2, conv(nind, types.Runetype)))
 
                // if hv2 < utf8.RuneSelf
-               nif := nod(OIF, nil, nil)
-               nif.Left = nod(OLT, hv2, nodintconst(utf8.RuneSelf))
+               nif := ir.Nod(ir.OIF, nil, nil)
+               nif.Left = ir.Nod(ir.OLT, hv2, nodintconst(utf8.RuneSelf))
 
                // hv1++
-               nif.Nbody.Set1(nod(OAS, hv1, nod(OADD, hv1, nodintconst(1))))
+               nif.Nbody.Set1(ir.Nod(ir.OAS, hv1, ir.Nod(ir.OADD, hv1, nodintconst(1))))
 
                // } else {
-               eif := nod(OAS2, nil, nil)
+               eif := ir.Nod(ir.OAS2, nil, nil)
                nif.Rlist.Set1(eif)
 
                // hv2, hv1 = decoderune(ha, hv1)
@@ -419,13 +420,13 @@ func walkrange(n *Node) *Node {
                if v1 != nil {
                        if v2 != nil {
                                // v1, v2 = hv1t, hv2
-                               a := nod(OAS2, nil, nil)
+                               a := ir.Nod(ir.OAS2, nil, nil)
                                a.List.Set2(v1, v2)
                                a.Rlist.Set2(hv1t, hv2)
                                body = append(body, a)
                        } else {
                                // v1 = hv1t
-                               body = append(body, nod(OAS, v1, hv1t))
+                               body = append(body, ir.Nod(ir.OAS, v1, hv1t))
                        }
                }
        }
@@ -466,17 +467,17 @@ func walkrange(n *Node) *Node {
 // }
 //
 // where == for keys of map m is reflexive.
-func isMapClear(n *Node) bool {
+func isMapClear(n *ir.Node) bool {
        if base.Flag.N != 0 || instrumenting {
                return false
        }
 
-       if n.Op != ORANGE || n.Type.Etype != TMAP || n.List.Len() != 1 {
+       if n.Op != ir.ORANGE || n.Type.Etype != types.TMAP || n.List.Len() != 1 {
                return false
        }
 
        k := n.List.First()
-       if k == nil || k.isBlank() {
+       if k == nil || ir.IsBlank(k) {
                return false
        }
 
@@ -490,7 +491,7 @@ func isMapClear(n *Node) bool {
        }
 
        stmt := n.Nbody.First() // only stmt in body
-       if stmt == nil || stmt.Op != ODELETE {
+       if stmt == nil || stmt.Op != ir.ODELETE {
                return false
        }
 
@@ -508,7 +509,7 @@ func isMapClear(n *Node) bool {
 }
 
 // mapClear constructs a call to runtime.mapclear for the map m.
-func mapClear(m *Node) *Node {
+func mapClear(m *ir.Node) *ir.Node {
        t := m.Type
 
        // instantiate mapclear(typ *type, hmap map[any]any)
@@ -533,7 +534,7 @@ func mapClear(m *Node) *Node {
 // in which the evaluation of a is side-effect-free.
 //
 // Parameters are as in walkrange: "for v1, v2 = range a".
-func arrayClear(n, v1, v2, a *Node) bool {
+func arrayClear(n, v1, v2, a *ir.Node) bool {
        if base.Flag.N != 0 || instrumenting {
                return false
        }
@@ -547,7 +548,7 @@ func arrayClear(n, v1, v2, a *Node) bool {
        }
 
        stmt := n.Nbody.First() // only stmt in body
-       if stmt.Op != OAS || stmt.Left.Op != OINDEX {
+       if stmt.Op != ir.OAS || stmt.Left.Op != ir.OINDEX {
                return false
        }
 
@@ -567,32 +568,32 @@ func arrayClear(n, v1, v2, a *Node) bool {
        //      memclr{NoHeap,Has}Pointers(hp, hn)
        //      i = len(a) - 1
        // }
-       n.Op = OIF
+       n.Op = ir.OIF
 
        n.Nbody.Set(nil)
-       n.Left = nod(ONE, nod(OLEN, a, nil), nodintconst(0))
+       n.Left = ir.Nod(ir.ONE, ir.Nod(ir.OLEN, a, nil), nodintconst(0))
 
        // hp = &a[0]
-       hp := temp(types.Types[TUNSAFEPTR])
+       hp := temp(types.Types[types.TUNSAFEPTR])
 
-       tmp := nod(OINDEX, a, nodintconst(0))
+       tmp := ir.Nod(ir.OINDEX, a, nodintconst(0))
        tmp.SetBounded(true)
-       tmp = nod(OADDR, tmp, nil)
-       tmp = convnop(tmp, types.Types[TUNSAFEPTR])
-       n.Nbody.Append(nod(OAS, hp, tmp))
+       tmp = ir.Nod(ir.OADDR, tmp, nil)
+       tmp = convnop(tmp, types.Types[types.TUNSAFEPTR])
+       n.Nbody.Append(ir.Nod(ir.OAS, hp, tmp))
 
        // hn = len(a) * sizeof(elem(a))
-       hn := temp(types.Types[TUINTPTR])
+       hn := temp(types.Types[types.TUINTPTR])
 
-       tmp = nod(OLEN, a, nil)
-       tmp = nod(OMUL, tmp, nodintconst(elemsize))
-       tmp = conv(tmp, types.Types[TUINTPTR])
-       n.Nbody.Append(nod(OAS, hn, tmp))
+       tmp = ir.Nod(ir.OLEN, a, nil)
+       tmp = ir.Nod(ir.OMUL, tmp, nodintconst(elemsize))
+       tmp = conv(tmp, types.Types[types.TUINTPTR])
+       n.Nbody.Append(ir.Nod(ir.OAS, hn, tmp))
 
-       var fn *Node
+       var fn *ir.Node
        if a.Type.Elem().HasPointers() {
                // memclrHasPointers(hp, hn)
-               Curfn.Func.setWBPos(stmt.Pos)
+               Curfn.Func.SetWBPos(stmt.Pos)
                fn = mkcall("memclrHasPointers", nil, nil, hp, hn)
        } else {
                // memclrNoHeapPointers(hp, hn)
@@ -602,7 +603,7 @@ func arrayClear(n, v1, v2, a *Node) bool {
        n.Nbody.Append(fn)
 
        // i = len(a) - 1
-       v1 = nod(OAS, v1, nod(OSUB, nod(OLEN, a, nil), nodintconst(1)))
+       v1 = ir.Nod(ir.OAS, v1, ir.Nod(ir.OSUB, ir.Nod(ir.OLEN, a, nil), nodintconst(1)))
 
        n.Nbody.Append(v1)
 
@@ -614,15 +615,15 @@ func arrayClear(n, v1, v2, a *Node) bool {
 }
 
 // addptr returns (*T)(uintptr(p) + n).
-func addptr(p *Node, n int64) *Node {
+func addptr(p *ir.Node, n int64) *ir.Node {
        t := p.Type
 
-       p = nod(OCONVNOP, p, nil)
-       p.Type = types.Types[TUINTPTR]
+       p = ir.Nod(ir.OCONVNOP, p, nil)
+       p.Type = types.Types[types.TUINTPTR]
 
-       p = nod(OADD, p, nodintconst(n))
+       p = ir.Nod(ir.OADD, p, nodintconst(n))
 
-       p = nod(OCONVNOP, p, nil)
+       p = ir.Nod(ir.OCONVNOP, p, nil)
        p.Type = t
 
        return p
index 456903e7d75f3379335bc88067f200629efbba8b..34047bfefa6ffe22a82750c9922cc53a45c4242e 100644 (file)
@@ -6,6 +6,7 @@ package gc
 
 import (
        "cmd/compile/internal/base"
+       "cmd/compile/internal/ir"
        "cmd/compile/internal/types"
        "cmd/internal/gcprog"
        "cmd/internal/obj"
@@ -84,7 +85,7 @@ func bmap(t *types.Type) *types.Type {
                return t.MapType().Bucket
        }
 
-       bucket := types.New(TSTRUCT)
+       bucket := types.New(types.TSTRUCT)
        keytype := t.Key()
        elemtype := t.Elem()
        dowidth(keytype)
@@ -99,7 +100,7 @@ func bmap(t *types.Type) *types.Type {
        field := make([]*types.Field, 0, 5)
 
        // The first field is: uint8 topbits[BUCKETSIZE].
-       arr := types.NewArray(types.Types[TUINT8], BUCKETSIZE)
+       arr := types.NewArray(types.Types[types.TUINT8], BUCKETSIZE)
        field = append(field, makefield("topbits", arr))
 
        arr = types.NewArray(keytype, BUCKETSIZE)
@@ -120,7 +121,7 @@ func bmap(t *types.Type) *types.Type {
        // See comment on hmap.overflow in runtime/map.go.
        otyp := types.NewPtr(bucket)
        if !elemtype.HasPointers() && !keytype.HasPointers() {
-               otyp = types.Types[TUINTPTR]
+               otyp = types.Types[types.TUINTPTR]
        }
        overflow := makefield("overflow", otyp)
        field = append(field, overflow)
@@ -209,18 +210,18 @@ func hmap(t *types.Type) *types.Type {
        // }
        // must match runtime/map.go:hmap.
        fields := []*types.Field{
-               makefield("count", types.Types[TINT]),
-               makefield("flags", types.Types[TUINT8]),
-               makefield("B", types.Types[TUINT8]),
-               makefield("noverflow", types.Types[TUINT16]),
-               makefield("hash0", types.Types[TUINT32]), // Used in walk.go for OMAKEMAP.
-               makefield("buckets", types.NewPtr(bmap)), // Used in walk.go for OMAKEMAP.
+               makefield("count", types.Types[types.TINT]),
+               makefield("flags", types.Types[types.TUINT8]),
+               makefield("B", types.Types[types.TUINT8]),
+               makefield("noverflow", types.Types[types.TUINT16]),
+               makefield("hash0", types.Types[types.TUINT32]), // Used in walk.go for OMAKEMAP.
+               makefield("buckets", types.NewPtr(bmap)),       // Used in walk.go for OMAKEMAP.
                makefield("oldbuckets", types.NewPtr(bmap)),
-               makefield("nevacuate", types.Types[TUINTPTR]),
-               makefield("extra", types.Types[TUNSAFEPTR]),
+               makefield("nevacuate", types.Types[types.TUINTPTR]),
+               makefield("extra", types.Types[types.TUNSAFEPTR]),
        }
 
-       hmap := types.New(TSTRUCT)
+       hmap := types.New(types.TSTRUCT)
        hmap.SetNoalg(true)
        hmap.SetFields(fields)
        dowidth(hmap)
@@ -268,23 +269,23 @@ func hiter(t *types.Type) *types.Type {
        fields := []*types.Field{
                makefield("key", types.NewPtr(t.Key())),   // Used in range.go for TMAP.
                makefield("elem", types.NewPtr(t.Elem())), // Used in range.go for TMAP.
-               makefield("t", types.Types[TUNSAFEPTR]),
+               makefield("t", types.Types[types.TUNSAFEPTR]),
                makefield("h", types.NewPtr(hmap)),
                makefield("buckets", types.NewPtr(bmap)),
                makefield("bptr", types.NewPtr(bmap)),
-               makefield("overflow", types.Types[TUNSAFEPTR]),
-               makefield("oldoverflow", types.Types[TUNSAFEPTR]),
-               makefield("startBucket", types.Types[TUINTPTR]),
-               makefield("offset", types.Types[TUINT8]),
-               makefield("wrapped", types.Types[TBOOL]),
-               makefield("B", types.Types[TUINT8]),
-               makefield("i", types.Types[TUINT8]),
-               makefield("bucket", types.Types[TUINTPTR]),
-               makefield("checkBucket", types.Types[TUINTPTR]),
+               makefield("overflow", types.Types[types.TUNSAFEPTR]),
+               makefield("oldoverflow", types.Types[types.TUNSAFEPTR]),
+               makefield("startBucket", types.Types[types.TUINTPTR]),
+               makefield("offset", types.Types[types.TUINT8]),
+               makefield("wrapped", types.Types[types.TBOOL]),
+               makefield("B", types.Types[types.TUINT8]),
+               makefield("i", types.Types[types.TUINT8]),
+               makefield("bucket", types.Types[types.TUINTPTR]),
+               makefield("checkBucket", types.Types[types.TUINTPTR]),
        }
 
        // build iterator struct holding the above fields
-       hiter := types.New(TSTRUCT)
+       hiter := types.New(types.TSTRUCT)
        hiter.SetNoalg(true)
        hiter.SetFields(fields)
        dowidth(hiter)
@@ -303,35 +304,35 @@ func deferstruct(stksize int64) *types.Type {
                // Unlike the global makefield function, this one needs to set Pkg
                // because these types might be compared (in SSA CSE sorting).
                // TODO: unify this makefield and the global one above.
-               sym := &types.Sym{Name: name, Pkg: localpkg}
+               sym := &types.Sym{Name: name, Pkg: ir.LocalPkg}
                return types.NewField(src.NoXPos, sym, typ)
        }
-       argtype := types.NewArray(types.Types[TUINT8], stksize)
+       argtype := types.NewArray(types.Types[types.TUINT8], stksize)
        argtype.Width = stksize
        argtype.Align = 1
        // These fields must match the ones in runtime/runtime2.go:_defer and
        // cmd/compile/internal/gc/ssa.go:(*state).call.
        fields := []*types.Field{
-               makefield("siz", types.Types[TUINT32]),
-               makefield("started", types.Types[TBOOL]),
-               makefield("heap", types.Types[TBOOL]),
-               makefield("openDefer", types.Types[TBOOL]),
-               makefield("sp", types.Types[TUINTPTR]),
-               makefield("pc", types.Types[TUINTPTR]),
+               makefield("siz", types.Types[types.TUINT32]),
+               makefield("started", types.Types[types.TBOOL]),
+               makefield("heap", types.Types[types.TBOOL]),
+               makefield("openDefer", types.Types[types.TBOOL]),
+               makefield("sp", types.Types[types.TUINTPTR]),
+               makefield("pc", types.Types[types.TUINTPTR]),
                // Note: the types here don't really matter. Defer structures
                // are always scanned explicitly during stack copying and GC,
                // so we make them uintptr type even though they are real pointers.
-               makefield("fn", types.Types[TUINTPTR]),
-               makefield("_panic", types.Types[TUINTPTR]),
-               makefield("link", types.Types[TUINTPTR]),
-               makefield("framepc", types.Types[TUINTPTR]),
-               makefield("varp", types.Types[TUINTPTR]),
-               makefield("fd", types.Types[TUINTPTR]),
+               makefield("fn", types.Types[types.TUINTPTR]),
+               makefield("_panic", types.Types[types.TUINTPTR]),
+               makefield("link", types.Types[types.TUINTPTR]),
+               makefield("framepc", types.Types[types.TUINTPTR]),
+               makefield("varp", types.Types[types.TUINTPTR]),
+               makefield("fd", types.Types[types.TUINTPTR]),
                makefield("args", argtype),
        }
 
        // build struct holding the above fields
-       s := types.New(TSTRUCT)
+       s := types.New(types.TSTRUCT)
        s.SetNoalg(true)
        s.SetFields(fields)
        s.Width = widstruct(s, s, 0, 1)
@@ -346,7 +347,7 @@ func methodfunc(f *types.Type, receiver *types.Type) *types.Type {
        if receiver != nil {
                inLen++
        }
-       in := make([]*Node, 0, inLen)
+       in := make([]*ir.Node, 0, inLen)
 
        if receiver != nil {
                d := anonfield(receiver)
@@ -360,7 +361,7 @@ func methodfunc(f *types.Type, receiver *types.Type) *types.Type {
        }
 
        outLen := f.Results().Fields().Len()
-       out := make([]*Node, 0, outLen)
+       out := make([]*ir.Node, 0, outLen)
        for _, t := range f.Results().Fields().Slice() {
                d := anonfield(t.Type)
                out = append(out, d)
@@ -447,7 +448,7 @@ func methods(t *types.Type) []*Sig {
 func imethods(t *types.Type) []*Sig {
        var methods []*Sig
        for _, f := range t.Fields().Slice() {
-               if f.Type.Etype != TFUNC || f.Sym == nil {
+               if f.Type.Etype != types.TFUNC || f.Sym == nil {
                        continue
                }
                if f.Sym.IsBlank() {
@@ -494,7 +495,7 @@ func dimportpath(p *types.Pkg) {
        }
 
        str := p.Path
-       if p == localpkg {
+       if p == ir.LocalPkg {
                // Note: myimportpath != "", or else dgopkgpath won't call dimportpath.
                str = base.Ctxt.Pkgpath
        }
@@ -511,7 +512,7 @@ func dgopkgpath(s *obj.LSym, ot int, pkg *types.Pkg) int {
                return duintptr(s, ot, 0)
        }
 
-       if pkg == localpkg && base.Ctxt.Pkgpath == "" {
+       if pkg == ir.LocalPkg && base.Ctxt.Pkgpath == "" {
                // If we don't know the full import path of the package being compiled
                // (i.e. -p was not passed on the compiler command line), emit a reference to
                // type..importpath.""., which the linker will rewrite using the correct import path.
@@ -530,7 +531,7 @@ func dgopkgpathOff(s *obj.LSym, ot int, pkg *types.Pkg) int {
        if pkg == nil {
                return duint32(s, ot, 0)
        }
-       if pkg == localpkg && base.Ctxt.Pkgpath == "" {
+       if pkg == ir.LocalPkg && base.Ctxt.Pkgpath == "" {
                // If we don't know the full import path of the package being compiled
                // (i.e. -p was not passed on the compiler command line), emit a reference to
                // type..importpath.""., which the linker will rewrite using the correct import path.
@@ -674,7 +675,7 @@ func typePkg(t *types.Type) *types.Pkg {
        tsym := t.Sym
        if tsym == nil {
                switch t.Etype {
-               case TARRAY, TSLICE, TPTR, TCHAN:
+               case types.TARRAY, types.TSLICE, types.TPTR, types.TCHAN:
                        if t.Elem() != nil {
                                tsym = t.Elem().Sym
                        }
@@ -717,32 +718,32 @@ func dmethodptrOff(s *obj.LSym, ot int, x *obj.LSym) int {
 }
 
 var kinds = []int{
-       TINT:        objabi.KindInt,
-       TUINT:       objabi.KindUint,
-       TINT8:       objabi.KindInt8,
-       TUINT8:      objabi.KindUint8,
-       TINT16:      objabi.KindInt16,
-       TUINT16:     objabi.KindUint16,
-       TINT32:      objabi.KindInt32,
-       TUINT32:     objabi.KindUint32,
-       TINT64:      objabi.KindInt64,
-       TUINT64:     objabi.KindUint64,
-       TUINTPTR:    objabi.KindUintptr,
-       TFLOAT32:    objabi.KindFloat32,
-       TFLOAT64:    objabi.KindFloat64,
-       TBOOL:       objabi.KindBool,
-       TSTRING:     objabi.KindString,
-       TPTR:        objabi.KindPtr,
-       TSTRUCT:     objabi.KindStruct,
-       TINTER:      objabi.KindInterface,
-       TCHAN:       objabi.KindChan,
-       TMAP:        objabi.KindMap,
-       TARRAY:      objabi.KindArray,
-       TSLICE:      objabi.KindSlice,
-       TFUNC:       objabi.KindFunc,
-       TCOMPLEX64:  objabi.KindComplex64,
-       TCOMPLEX128: objabi.KindComplex128,
-       TUNSAFEPTR:  objabi.KindUnsafePointer,
+       types.TINT:        objabi.KindInt,
+       types.TUINT:       objabi.KindUint,
+       types.TINT8:       objabi.KindInt8,
+       types.TUINT8:      objabi.KindUint8,
+       types.TINT16:      objabi.KindInt16,
+       types.TUINT16:     objabi.KindUint16,
+       types.TINT32:      objabi.KindInt32,
+       types.TUINT32:     objabi.KindUint32,
+       types.TINT64:      objabi.KindInt64,
+       types.TUINT64:     objabi.KindUint64,
+       types.TUINTPTR:    objabi.KindUintptr,
+       types.TFLOAT32:    objabi.KindFloat32,
+       types.TFLOAT64:    objabi.KindFloat64,
+       types.TBOOL:       objabi.KindBool,
+       types.TSTRING:     objabi.KindString,
+       types.TPTR:        objabi.KindPtr,
+       types.TSTRUCT:     objabi.KindStruct,
+       types.TINTER:      objabi.KindInterface,
+       types.TCHAN:       objabi.KindChan,
+       types.TMAP:        objabi.KindMap,
+       types.TARRAY:      objabi.KindArray,
+       types.TSLICE:      objabi.KindSlice,
+       types.TFUNC:       objabi.KindFunc,
+       types.TCOMPLEX64:  objabi.KindComplex64,
+       types.TCOMPLEX128: objabi.KindComplex128,
+       types.TUNSAFEPTR:  objabi.KindUnsafePointer,
 }
 
 // typeptrdata returns the length in bytes of the prefix of t
@@ -753,32 +754,32 @@ func typeptrdata(t *types.Type) int64 {
        }
 
        switch t.Etype {
-       case TPTR,
-               TUNSAFEPTR,
-               TFUNC,
-               TCHAN,
-               TMAP:
+       case types.TPTR,
+               types.TUNSAFEPTR,
+               types.TFUNC,
+               types.TCHAN,
+               types.TMAP:
                return int64(Widthptr)
 
-       case TSTRING:
+       case types.TSTRING:
                // struct { byte *str; intgo len; }
                return int64(Widthptr)
 
-       case TINTER:
+       case types.TINTER:
                // struct { Itab *tab;  void *data; } or
                // struct { Type *type; void *data; }
                // Note: see comment in plive.go:onebitwalktype1.
                return 2 * int64(Widthptr)
 
-       case TSLICE:
+       case types.TSLICE:
                // struct { byte *array; uintgo len; uintgo cap; }
                return int64(Widthptr)
 
-       case TARRAY:
+       case types.TARRAY:
                // haspointers already eliminated t.NumElem() == 0.
                return (t.NumElem()-1)*t.Elem().Width + typeptrdata(t.Elem())
 
-       case TSTRUCT:
+       case types.TSTRUCT:
                // Find the last field that has pointers.
                var lastPtrField *types.Field
                for _, t1 := range t.Fields().Slice() {
@@ -989,38 +990,38 @@ func typenamesym(t *types.Type) *types.Sym {
        return s
 }
 
-func typename(t *types.Type) *Node {
+func typename(t *types.Type) *ir.Node {
        s := typenamesym(t)
        if s.Def == nil {
-               n := newnamel(src.NoXPos, s)
-               n.Type = types.Types[TUINT8]
-               n.SetClass(PEXTERN)
+               n := ir.NewNameAt(src.NoXPos, s)
+               n.Type = types.Types[types.TUINT8]
+               n.SetClass(ir.PEXTERN)
                n.SetTypecheck(1)
-               s.Def = asTypesNode(n)
+               s.Def = ir.AsTypesNode(n)
        }
 
-       n := nod(OADDR, asNode(s.Def), nil)
-       n.Type = types.NewPtr(asNode(s.Def).Type)
+       n := ir.Nod(ir.OADDR, ir.AsNode(s.Def), nil)
+       n.Type = types.NewPtr(ir.AsNode(s.Def).Type)
        n.SetTypecheck(1)
        return n
 }
 
-func itabname(t, itype *types.Type) *Node {
+func itabname(t, itype *types.Type) *ir.Node {
        if t == nil || (t.IsPtr() && t.Elem() == nil) || t.IsUntyped() || !itype.IsInterface() || itype.IsEmptyInterface() {
                base.Fatalf("itabname(%v, %v)", t, itype)
        }
        s := itabpkg.Lookup(t.ShortString() + "," + itype.ShortString())
        if s.Def == nil {
-               n := newname(s)
-               n.Type = types.Types[TUINT8]
-               n.SetClass(PEXTERN)
+               n := NewName(s)
+               n.Type = types.Types[types.TUINT8]
+               n.SetClass(ir.PEXTERN)
                n.SetTypecheck(1)
-               s.Def = asTypesNode(n)
+               s.Def = ir.AsTypesNode(n)
                itabs = append(itabs, itabEntry{t: t, itype: itype, lsym: s.Linksym()})
        }
 
-       n := nod(OADDR, asNode(s.Def), nil)
-       n.Type = types.NewPtr(asNode(s.Def).Type)
+       n := ir.Nod(ir.OADDR, ir.AsNode(s.Def), nil)
+       n.Type = types.NewPtr(ir.AsNode(s.Def).Type)
        n.SetTypecheck(1)
        return n
 }
@@ -1029,35 +1030,35 @@ func itabname(t, itype *types.Type) *Node {
 // That is, if x==x for all x of type t.
 func isreflexive(t *types.Type) bool {
        switch t.Etype {
-       case TBOOL,
-               TINT,
-               TUINT,
-               TINT8,
-               TUINT8,
-               TINT16,
-               TUINT16,
-               TINT32,
-               TUINT32,
-               TINT64,
-               TUINT64,
-               TUINTPTR,
-               TPTR,
-               TUNSAFEPTR,
-               TSTRING,
-               TCHAN:
+       case types.TBOOL,
+               types.TINT,
+               types.TUINT,
+               types.TINT8,
+               types.TUINT8,
+               types.TINT16,
+               types.TUINT16,
+               types.TINT32,
+               types.TUINT32,
+               types.TINT64,
+               types.TUINT64,
+               types.TUINTPTR,
+               types.TPTR,
+               types.TUNSAFEPTR,
+               types.TSTRING,
+               types.TCHAN:
                return true
 
-       case TFLOAT32,
-               TFLOAT64,
-               TCOMPLEX64,
-               TCOMPLEX128,
-               TINTER:
+       case types.TFLOAT32,
+               types.TFLOAT64,
+               types.TCOMPLEX64,
+               types.TCOMPLEX128,
+               types.TINTER:
                return false
 
-       case TARRAY:
+       case types.TARRAY:
                return isreflexive(t.Elem())
 
-       case TSTRUCT:
+       case types.TSTRUCT:
                for _, t1 := range t.Fields().Slice() {
                        if !isreflexive(t1.Type) {
                                return false
@@ -1075,19 +1076,19 @@ func isreflexive(t *types.Type) bool {
 // need the key to be updated.
 func needkeyupdate(t *types.Type) bool {
        switch t.Etype {
-       case TBOOL, TINT, TUINT, TINT8, TUINT8, TINT16, TUINT16, TINT32, TUINT32,
-               TINT64, TUINT64, TUINTPTR, TPTR, TUNSAFEPTR, TCHAN:
+       case types.TBOOL, types.TINT, types.TUINT, types.TINT8, types.TUINT8, types.TINT16, types.TUINT16, types.TINT32, types.TUINT32,
+               types.TINT64, types.TUINT64, types.TUINTPTR, types.TPTR, types.TUNSAFEPTR, types.TCHAN:
                return false
 
-       case TFLOAT32, TFLOAT64, TCOMPLEX64, TCOMPLEX128, // floats and complex can be +0/-0
-               TINTER,
-               TSTRING: // strings might have smaller backing stores
+       case types.TFLOAT32, types.TFLOAT64, types.TCOMPLEX64, types.TCOMPLEX128, // floats and complex can be +0/-0
+               types.TINTER,
+               types.TSTRING: // strings might have smaller backing stores
                return true
 
-       case TARRAY:
+       case types.TARRAY:
                return needkeyupdate(t.Elem())
 
-       case TSTRUCT:
+       case types.TSTRUCT:
                for _, t1 := range t.Fields().Slice() {
                        if needkeyupdate(t1.Type) {
                                return true
@@ -1104,13 +1105,13 @@ func needkeyupdate(t *types.Type) bool {
 // hashMightPanic reports whether the hash of a map key of type t might panic.
 func hashMightPanic(t *types.Type) bool {
        switch t.Etype {
-       case TINTER:
+       case types.TINTER:
                return true
 
-       case TARRAY:
+       case types.TARRAY:
                return hashMightPanic(t.Elem())
 
-       case TSTRUCT:
+       case types.TSTRUCT:
                for _, t1 := range t.Fields().Slice() {
                        if hashMightPanic(t1.Type) {
                                return true
@@ -1161,7 +1162,7 @@ func dtypesym(t *types.Type) *obj.LSym {
 
        if base.Ctxt.Pkgpath != "runtime" || (tbase != types.Types[tbase.Etype] && tbase != types.Bytetype && tbase != types.Runetype && tbase != types.Errortype) { // int, float, etc
                // named types from other files are defined only by those files
-               if tbase.Sym != nil && tbase.Sym.Pkg != localpkg {
+               if tbase.Sym != nil && tbase.Sym.Pkg != ir.LocalPkg {
                        if i, ok := typeSymIdx[tbase]; ok {
                                lsym.Pkg = tbase.Sym.Pkg.Prefix
                                if t != tbase {
@@ -1174,7 +1175,7 @@ func dtypesym(t *types.Type) *obj.LSym {
                        return lsym
                }
                // TODO(mdempsky): Investigate whether this can happen.
-               if tbase.Etype == TFORW {
+               if tbase.Etype == types.TFORW {
                        return lsym
                }
        }
@@ -1185,7 +1186,7 @@ func dtypesym(t *types.Type) *obj.LSym {
                ot = dcommontype(lsym, t)
                ot = dextratype(lsym, ot, t, 0)
 
-       case TARRAY:
+       case types.TARRAY:
                // ../../../../runtime/type.go:/arrayType
                s1 := dtypesym(t.Elem())
                t2 := types.NewSlice(t.Elem())
@@ -1196,14 +1197,14 @@ func dtypesym(t *types.Type) *obj.LSym {
                ot = duintptr(lsym, ot, uint64(t.NumElem()))
                ot = dextratype(lsym, ot, t, 0)
 
-       case TSLICE:
+       case types.TSLICE:
                // ../../../../runtime/type.go:/sliceType
                s1 := dtypesym(t.Elem())
                ot = dcommontype(lsym, t)
                ot = dsymptr(lsym, ot, s1, 0)
                ot = dextratype(lsym, ot, t, 0)
 
-       case TCHAN:
+       case types.TCHAN:
                // ../../../../runtime/type.go:/chanType
                s1 := dtypesym(t.Elem())
                ot = dcommontype(lsym, t)
@@ -1211,7 +1212,7 @@ func dtypesym(t *types.Type) *obj.LSym {
                ot = duintptr(lsym, ot, uint64(t.ChanDir()))
                ot = dextratype(lsym, ot, t, 0)
 
-       case TFUNC:
+       case types.TFUNC:
                for _, t1 := range t.Recvs().Fields().Slice() {
                        dtypesym(t1.Type)
                }
@@ -1250,7 +1251,7 @@ func dtypesym(t *types.Type) *obj.LSym {
                        ot = dsymptr(lsym, ot, dtypesym(t1.Type), 0)
                }
 
-       case TINTER:
+       case types.TINTER:
                m := imethods(t)
                n := len(m)
                for _, a := range m {
@@ -1286,7 +1287,7 @@ func dtypesym(t *types.Type) *obj.LSym {
                }
 
        // ../../../../runtime/type.go:/mapType
-       case TMAP:
+       case types.TMAP:
                s1 := dtypesym(t.Key())
                s2 := dtypesym(t.Elem())
                s3 := dtypesym(bmap(t))
@@ -1326,8 +1327,8 @@ func dtypesym(t *types.Type) *obj.LSym {
                ot = duint32(lsym, ot, flags)
                ot = dextratype(lsym, ot, t, 0)
 
-       case TPTR:
-               if t.Elem().Etype == TANY {
+       case types.TPTR:
+               if t.Elem().Etype == types.TANY {
                        // ../../../../runtime/type.go:/UnsafePointerType
                        ot = dcommontype(lsym, t)
                        ot = dextratype(lsym, ot, t, 0)
@@ -1344,7 +1345,7 @@ func dtypesym(t *types.Type) *obj.LSym {
 
        // ../../../../runtime/type.go:/structType
        // for security, only the exported fields.
-       case TSTRUCT:
+       case types.TSTRUCT:
                fields := t.Fields().Slice()
                for _, t1 := range fields {
                        dtypesym(t1.Type)
@@ -1403,7 +1404,7 @@ func dtypesym(t *types.Type) *obj.LSym {
                // functions must return the existing type structure rather
                // than creating a new one.
                switch t.Etype {
-               case TPTR, TARRAY, TCHAN, TFUNC, TMAP, TSLICE, TSTRUCT:
+               case types.TPTR, types.TARRAY, types.TCHAN, types.TFUNC, types.TMAP, types.TSLICE, types.TSTRUCT:
                        keep = true
                }
        }
@@ -1515,10 +1516,10 @@ func addsignat(t *types.Type) {
        }
 }
 
-func addsignats(dcls []*Node) {
+func addsignats(dcls []*ir.Node) {
        // copy types from dcl list to signatset
        for _, n := range dcls {
-               if n.Op == OTYPE {
+               if n.Op == ir.OTYPE {
                        addsignat(n.Type)
                }
        }
@@ -1571,7 +1572,7 @@ func dumptabs() {
        }
 
        // process ptabs
-       if localpkg.Name == "main" && len(ptabs) > 0 {
+       if ir.LocalPkg.Name == "main" && len(ptabs) > 0 {
                ot := 0
                s := base.Ctxt.Lookup("go.plugin.tabs")
                for _, p := range ptabs {
@@ -1615,17 +1616,17 @@ func dumpbasictypes() {
        // another possible choice would be package main,
        // but using runtime means fewer copies in object files.
        if base.Ctxt.Pkgpath == "runtime" {
-               for i := types.EType(1); i <= TBOOL; i++ {
+               for i := types.EType(1); i <= types.TBOOL; i++ {
                        dtypesym(types.NewPtr(types.Types[i]))
                }
-               dtypesym(types.NewPtr(types.Types[TSTRING]))
-               dtypesym(types.NewPtr(types.Types[TUNSAFEPTR]))
+               dtypesym(types.NewPtr(types.Types[types.TSTRING]))
+               dtypesym(types.NewPtr(types.Types[types.TUNSAFEPTR]))
 
                // emit type structs for error and func(error) string.
                // The latter is the type of an auto-generated wrapper.
                dtypesym(types.NewPtr(types.Errortype))
 
-               dtypesym(functype(nil, []*Node{anonfield(types.Errortype)}, []*Node{anonfield(types.Types[TSTRING])}))
+               dtypesym(functype(nil, []*ir.Node{anonfield(types.Errortype)}, []*ir.Node{anonfield(types.Types[types.TSTRING])}))
 
                // add paths for runtime and main, which 6l imports implicitly.
                dimportpath(Runtimepkg)
@@ -1767,7 +1768,7 @@ func fillptrmask(t *types.Type, ptrmask []byte) {
 // For non-trivial arrays, the program describes the full t.Width size.
 func dgcprog(t *types.Type) (*obj.LSym, int64) {
        dowidth(t)
-       if t.Width == BADWIDTH {
+       if t.Width == types.BADWIDTH {
                base.Fatalf("dgcprog: %v badwidth", t)
        }
        lsym := typesymprefix(".gcprog", t).Linksym()
@@ -1824,17 +1825,17 @@ func (p *GCProg) emit(t *types.Type, offset int64) {
        default:
                base.Fatalf("GCProg.emit: unexpected type %v", t)
 
-       case TSTRING:
+       case types.TSTRING:
                p.w.Ptr(offset / int64(Widthptr))
 
-       case TINTER:
+       case types.TINTER:
                // Note: the first word isn't a pointer. See comment in plive.go:onebitwalktype1.
                p.w.Ptr(offset/int64(Widthptr) + 1)
 
-       case TSLICE:
+       case types.TSLICE:
                p.w.Ptr(offset / int64(Widthptr))
 
-       case TARRAY:
+       case types.TARRAY:
                if t.NumElem() == 0 {
                        // should have been handled by haspointers check above
                        base.Fatalf("GCProg.emit: empty array")
@@ -1859,7 +1860,7 @@ func (p *GCProg) emit(t *types.Type, offset int64) {
                p.w.ZeroUntil((offset + elem.Width) / int64(Widthptr))
                p.w.Repeat(elem.Width/int64(Widthptr), count-1)
 
-       case TSTRUCT:
+       case types.TSTRUCT:
                for _, t1 := range t.Fields().Slice() {
                        p.emit(t1.Type, offset+t1.Offset)
                }
@@ -1868,7 +1869,7 @@ func (p *GCProg) emit(t *types.Type, offset int64) {
 
 // zeroaddr returns the address of a symbol with at least
 // size bytes of zeros.
-func zeroaddr(size int64) *Node {
+func zeroaddr(size int64) *ir.Node {
        if size >= 1<<31 {
                base.Fatalf("map elem too big %d", size)
        }
@@ -1877,14 +1878,14 @@ func zeroaddr(size int64) *Node {
        }
        s := mappkg.Lookup("zero")
        if s.Def == nil {
-               x := newname(s)
-               x.Type = types.Types[TUINT8]
-               x.SetClass(PEXTERN)
+               x := NewName(s)
+               x.Type = types.Types[types.TUINT8]
+               x.SetClass(ir.PEXTERN)
                x.SetTypecheck(1)
-               s.Def = asTypesNode(x)
+               s.Def = ir.AsTypesNode(x)
        }
-       z := nod(OADDR, asNode(s.Def), nil)
-       z.Type = types.NewPtr(types.Types[TUINT8])
+       z := ir.Nod(ir.OADDR, ir.AsNode(s.Def), nil)
+       z.Type = types.NewPtr(types.Types[types.TUINT8])
        z.SetTypecheck(1)
        return z
 }
index 891012cbc9f2bbd06c15a928f925bfbdbdded3cd..ddde18e50541d48ab7020f17b69ba582ef01c4f1 100644 (file)
@@ -4,6 +4,8 @@
 
 package gc
 
+import "cmd/compile/internal/ir"
+
 // Strongly connected components.
 //
 // Run analysis on minimal sets of mutually recursive functions
@@ -30,10 +32,10 @@ package gc
 // when analyzing a set of mutually recursive functions.
 
 type bottomUpVisitor struct {
-       analyze  func([]*Node, bool)
+       analyze  func([]*ir.Node, bool)
        visitgen uint32
-       nodeID   map[*Node]uint32
-       stack    []*Node
+       nodeID   map[*ir.Node]uint32
+       stack    []*ir.Node
 }
 
 // visitBottomUp invokes analyze on the ODCLFUNC nodes listed in list.
@@ -49,18 +51,18 @@ type bottomUpVisitor struct {
 // If recursive is false, the list consists of only a single function and its closures.
 // If recursive is true, the list may still contain only a single function,
 // if that function is itself recursive.
-func visitBottomUp(list []*Node, analyze func(list []*Node, recursive bool)) {
+func visitBottomUp(list []*ir.Node, analyze func(list []*ir.Node, recursive bool)) {
        var v bottomUpVisitor
        v.analyze = analyze
-       v.nodeID = make(map[*Node]uint32)
+       v.nodeID = make(map[*ir.Node]uint32)
        for _, n := range list {
-               if n.Op == ODCLFUNC && !n.Func.IsHiddenClosure() {
+               if n.Op == ir.ODCLFUNC && !n.Func.IsHiddenClosure() {
                        v.visit(n)
                }
        }
 }
 
-func (v *bottomUpVisitor) visit(n *Node) uint32 {
+func (v *bottomUpVisitor) visit(n *ir.Node) uint32 {
        if id := v.nodeID[n]; id > 0 {
                // already visited
                return id
@@ -73,38 +75,38 @@ func (v *bottomUpVisitor) visit(n *Node) uint32 {
        min := v.visitgen
        v.stack = append(v.stack, n)
 
-       inspectList(n.Nbody, func(n *Node) bool {
+       ir.InspectList(n.Nbody, func(n *ir.Node) bool {
                switch n.Op {
-               case ONAME:
-                       if n.Class() == PFUNC {
+               case ir.ONAME:
+                       if n.Class() == ir.PFUNC {
                                if n != nil && n.Name.Defn != nil {
                                        if m := v.visit(n.Name.Defn); m < min {
                                                min = m
                                        }
                                }
                        }
-               case OMETHEXPR:
-                       fn := n.MethodName()
+               case ir.OMETHEXPR:
+                       fn := methodExprName(n)
                        if fn != nil && fn.Name.Defn != nil {
                                if m := v.visit(fn.Name.Defn); m < min {
                                        min = m
                                }
                        }
-               case ODOTMETH:
-                       fn := n.MethodName()
-                       if fn != nil && fn.Op == ONAME && fn.Class() == PFUNC && fn.Name.Defn != nil {
+               case ir.ODOTMETH:
+                       fn := methodExprName(n)
+                       if fn != nil && fn.Op == ir.ONAME && fn.Class() == ir.PFUNC && fn.Name.Defn != nil {
                                if m := v.visit(fn.Name.Defn); m < min {
                                        min = m
                                }
                        }
-               case OCALLPART:
-                       fn := asNode(callpartMethod(n).Nname)
-                       if fn != nil && fn.Op == ONAME && fn.Class() == PFUNC && fn.Name.Defn != nil {
+               case ir.OCALLPART:
+                       fn := ir.AsNode(callpartMethod(n).Nname)
+                       if fn != nil && fn.Op == ir.ONAME && fn.Class() == ir.PFUNC && fn.Name.Defn != nil {
                                if m := v.visit(fn.Name.Defn); m < min {
                                        min = m
                                }
                        }
-               case OCLOSURE:
+               case ir.OCLOSURE:
                        if m := v.visit(n.Func.Decl); m < min {
                                min = m
                        }
index ace1d6bd9c5efe9e2195e5ca0f27a577c8f8c488..b5ebce04bec46db0dd1f475d31801cc90ad8fd24 100644 (file)
@@ -6,6 +6,7 @@ package gc
 
 import (
        "cmd/compile/internal/base"
+       "cmd/compile/internal/ir"
        "cmd/internal/dwarf"
        "cmd/internal/obj"
        "cmd/internal/src"
@@ -17,7 +18,7 @@ func xposBefore(p, q src.XPos) bool {
        return base.Ctxt.PosTable.Pos(p).Before(base.Ctxt.PosTable.Pos(q))
 }
 
-func findScope(marks []Mark, pos src.XPos) ScopeID {
+func findScope(marks []ir.Mark, pos src.XPos) ir.ScopeID {
        i := sort.Search(len(marks), func(i int) bool {
                return xposBefore(pos, marks[i].Pos)
        })
@@ -27,7 +28,7 @@ func findScope(marks []Mark, pos src.XPos) ScopeID {
        return marks[i-1].Scope
 }
 
-func assembleScopes(fnsym *obj.LSym, fn *Node, dwarfVars []*dwarf.Var, varScopes []ScopeID) []dwarf.Scope {
+func assembleScopes(fnsym *obj.LSym, fn *ir.Node, dwarfVars []*dwarf.Var, varScopes []ir.ScopeID) []dwarf.Scope {
        // Initialize the DWARF scope tree based on lexical scopes.
        dwarfScopes := make([]dwarf.Scope, 1+len(fn.Func.Parents))
        for i, parent := range fn.Func.Parents {
@@ -40,7 +41,7 @@ func assembleScopes(fnsym *obj.LSym, fn *Node, dwarfVars []*dwarf.Var, varScopes
 }
 
 // scopeVariables assigns DWARF variable records to their scopes.
-func scopeVariables(dwarfVars []*dwarf.Var, varScopes []ScopeID, dwarfScopes []dwarf.Scope) {
+func scopeVariables(dwarfVars []*dwarf.Var, varScopes []ir.ScopeID, dwarfScopes []dwarf.Scope) {
        sort.Stable(varsByScopeAndOffset{dwarfVars, varScopes})
 
        i0 := 0
@@ -57,7 +58,7 @@ func scopeVariables(dwarfVars []*dwarf.Var, varScopes []ScopeID, dwarfScopes []d
 }
 
 // scopePCs assigns PC ranges to their scopes.
-func scopePCs(fnsym *obj.LSym, marks []Mark, dwarfScopes []dwarf.Scope) {
+func scopePCs(fnsym *obj.LSym, marks []ir.Mark, dwarfScopes []dwarf.Scope) {
        // If there aren't any child scopes (in particular, when scope
        // tracking is disabled), we can skip a whole lot of work.
        if len(marks) == 0 {
@@ -90,7 +91,7 @@ func compactScopes(dwarfScopes []dwarf.Scope) []dwarf.Scope {
 
 type varsByScopeAndOffset struct {
        vars   []*dwarf.Var
-       scopes []ScopeID
+       scopes []ir.ScopeID
 }
 
 func (v varsByScopeAndOffset) Len() int {
index 8d4c8d2be10e7f37d7cbf65e8354380666592cd8..ed7db0aaf7b56d6050bab4ac3b739e139b08c81b 100644 (file)
@@ -6,16 +6,17 @@ package gc
 
 import (
        "cmd/compile/internal/base"
+       "cmd/compile/internal/ir"
        "cmd/compile/internal/types"
 )
 
 // select
-func typecheckselect(sel *Node) {
-       var def *Node
+func typecheckselect(sel *ir.Node) {
+       var def *ir.Node
        lno := setlineno(sel)
        typecheckslice(sel.Ninit.Slice(), ctxStmt)
        for _, ncase := range sel.List.Slice() {
-               if ncase.Op != OCASE {
+               if ncase.Op != ir.OCASE {
                        setlineno(ncase)
                        base.Fatalf("typecheckselect %v", ncase.Op)
                }
@@ -23,7 +24,7 @@ func typecheckselect(sel *Node) {
                if ncase.List.Len() == 0 {
                        // default
                        if def != nil {
-                               base.ErrorfAt(ncase.Pos, "multiple defaults in select (first at %v)", def.Line())
+                               base.ErrorfAt(ncase.Pos, "multiple defaults in select (first at %v)", ir.Line(def))
                        } else {
                                def = ncase
                        }
@@ -37,7 +38,7 @@ func typecheckselect(sel *Node) {
                        switch n.Op {
                        default:
                                pos := n.Pos
-                               if n.Op == ONAME {
+                               if n.Op == ir.ONAME {
                                        // We don't have the right position for ONAME nodes (see #15459 and
                                        // others). Using ncase.Pos for now as it will provide the correct
                                        // line number (assuming the expression follows the "case" keyword
@@ -49,37 +50,37 @@ func typecheckselect(sel *Node) {
                        // convert x = <-c into OSELRECV(x, <-c).
                        // remove implicit conversions; the eventual assignment
                        // will reintroduce them.
-                       case OAS:
-                               if (n.Right.Op == OCONVNOP || n.Right.Op == OCONVIFACE) && n.Right.Implicit() {
+                       case ir.OAS:
+                               if (n.Right.Op == ir.OCONVNOP || n.Right.Op == ir.OCONVIFACE) && n.Right.Implicit() {
                                        n.Right = n.Right.Left
                                }
 
-                               if n.Right.Op != ORECV {
+                               if n.Right.Op != ir.ORECV {
                                        base.ErrorfAt(n.Pos, "select assignment must have receive on right hand side")
                                        break
                                }
 
-                               n.Op = OSELRECV
+                               n.Op = ir.OSELRECV
 
                                // convert x, ok = <-c into OSELRECV2(x, <-c) with ntest=ok
-                       case OAS2RECV:
-                               if n.Right.Op != ORECV {
+                       case ir.OAS2RECV:
+                               if n.Right.Op != ir.ORECV {
                                        base.ErrorfAt(n.Pos, "select assignment must have receive on right hand side")
                                        break
                                }
 
-                               n.Op = OSELRECV2
+                               n.Op = ir.OSELRECV2
                                n.Left = n.List.First()
                                n.List.Set1(n.List.Second())
 
                                // convert <-c into OSELRECV(N, <-c)
-                       case ORECV:
-                               n = nodl(n.Pos, OSELRECV, nil, n)
+                       case ir.ORECV:
+                               n = ir.NodAt(n.Pos, ir.OSELRECV, nil, n)
 
                                n.SetTypecheck(1)
                                ncase.Left = n
 
-                       case OSEND:
+                       case ir.OSEND:
                                break
                        }
                }
@@ -90,7 +91,7 @@ func typecheckselect(sel *Node) {
        base.Pos = lno
 }
 
-func walkselect(sel *Node) {
+func walkselect(sel *ir.Node) {
        lno := setlineno(sel)
        if sel.Nbody.Len() != 0 {
                base.Fatalf("double walkselect")
@@ -108,13 +109,13 @@ func walkselect(sel *Node) {
        base.Pos = lno
 }
 
-func walkselectcases(cases *Nodes) []*Node {
+func walkselectcases(cases *ir.Nodes) []*ir.Node {
        ncas := cases.Len()
        sellineno := base.Pos
 
        // optimization: zero-case select
        if ncas == 0 {
-               return []*Node{mkcall("block", nil, nil)}
+               return []*ir.Node{mkcall("block", nil, nil)}
        }
 
        // optimization: one-case select: single op.
@@ -130,25 +131,25 @@ func walkselectcases(cases *Nodes) []*Node {
                        default:
                                base.Fatalf("select %v", n.Op)
 
-                       case OSEND:
+                       case ir.OSEND:
                                // already ok
 
-                       case OSELRECV, OSELRECV2:
-                               if n.Op == OSELRECV || n.List.Len() == 0 {
+                       case ir.OSELRECV, ir.OSELRECV2:
+                               if n.Op == ir.OSELRECV || n.List.Len() == 0 {
                                        if n.Left == nil {
                                                n = n.Right
                                        } else {
-                                               n.Op = OAS
+                                               n.Op = ir.OAS
                                        }
                                        break
                                }
 
                                if n.Left == nil {
-                                       nblank = typecheck(nblank, ctxExpr|ctxAssign)
-                                       n.Left = nblank
+                                       ir.BlankNode = typecheck(ir.BlankNode, ctxExpr|ctxAssign)
+                                       n.Left = ir.BlankNode
                                }
 
-                               n.Op = OAS2
+                               n.Op = ir.OAS2
                                n.List.Prepend(n.Left)
                                n.Rlist.Set1(n.Right)
                                n.Right = nil
@@ -161,13 +162,13 @@ func walkselectcases(cases *Nodes) []*Node {
                }
 
                l = append(l, cas.Nbody.Slice()...)
-               l = append(l, nod(OBREAK, nil, nil))
+               l = append(l, ir.Nod(ir.OBREAK, nil, nil))
                return l
        }
 
        // convert case value arguments to addresses.
        // this rewrite is used by both the general code and the next optimization.
-       var dflt *Node
+       var dflt *ir.Node
        for _, cas := range cases.Slice() {
                setlineno(cas)
                n := cas.Left
@@ -176,17 +177,17 @@ func walkselectcases(cases *Nodes) []*Node {
                        continue
                }
                switch n.Op {
-               case OSEND:
-                       n.Right = nod(OADDR, n.Right, nil)
+               case ir.OSEND:
+                       n.Right = ir.Nod(ir.OADDR, n.Right, nil)
                        n.Right = typecheck(n.Right, ctxExpr)
 
-               case OSELRECV, OSELRECV2:
-                       if n.Op == OSELRECV2 && n.List.Len() == 0 {
-                               n.Op = OSELRECV
+               case ir.OSELRECV, ir.OSELRECV2:
+                       if n.Op == ir.OSELRECV2 && n.List.Len() == 0 {
+                               n.Op = ir.OSELRECV
                        }
 
                        if n.Left != nil {
-                               n.Left = nod(OADDR, n.Left, nil)
+                               n.Left = ir.Nod(ir.OADDR, n.Left, nil)
                                n.Left = typecheck(n.Left, ctxExpr)
                        }
                }
@@ -201,66 +202,66 @@ func walkselectcases(cases *Nodes) []*Node {
 
                n := cas.Left
                setlineno(n)
-               r := nod(OIF, nil, nil)
+               r := ir.Nod(ir.OIF, nil, nil)
                r.Ninit.Set(cas.Ninit.Slice())
                switch n.Op {
                default:
                        base.Fatalf("select %v", n.Op)
 
-               case OSEND:
+               case ir.OSEND:
                        // if selectnbsend(c, v) { body } else { default body }
                        ch := n.Left
-                       r.Left = mkcall1(chanfn("selectnbsend", 2, ch.Type), types.Types[TBOOL], &r.Ninit, ch, n.Right)
+                       r.Left = mkcall1(chanfn("selectnbsend", 2, ch.Type), types.Types[types.TBOOL], &r.Ninit, ch, n.Right)
 
-               case OSELRECV:
+               case ir.OSELRECV:
                        // if selectnbrecv(&v, c) { body } else { default body }
                        ch := n.Right.Left
                        elem := n.Left
                        if elem == nil {
                                elem = nodnil()
                        }
-                       r.Left = mkcall1(chanfn("selectnbrecv", 2, ch.Type), types.Types[TBOOL], &r.Ninit, elem, ch)
+                       r.Left = mkcall1(chanfn("selectnbrecv", 2, ch.Type), types.Types[types.TBOOL], &r.Ninit, elem, ch)
 
-               case OSELRECV2:
+               case ir.OSELRECV2:
                        // if selectnbrecv2(&v, &received, c) { body } else { default body }
                        ch := n.Right.Left
                        elem := n.Left
                        if elem == nil {
                                elem = nodnil()
                        }
-                       receivedp := nod(OADDR, n.List.First(), nil)
+                       receivedp := ir.Nod(ir.OADDR, n.List.First(), nil)
                        receivedp = typecheck(receivedp, ctxExpr)
-                       r.Left = mkcall1(chanfn("selectnbrecv2", 2, ch.Type), types.Types[TBOOL], &r.Ninit, elem, receivedp, ch)
+                       r.Left = mkcall1(chanfn("selectnbrecv2", 2, ch.Type), types.Types[types.TBOOL], &r.Ninit, elem, receivedp, ch)
                }
 
                r.Left = typecheck(r.Left, ctxExpr)
                r.Nbody.Set(cas.Nbody.Slice())
                r.Rlist.Set(append(dflt.Ninit.Slice(), dflt.Nbody.Slice()...))
-               return []*Node{r, nod(OBREAK, nil, nil)}
+               return []*ir.Node{r, ir.Nod(ir.OBREAK, nil, nil)}
        }
 
        if dflt != nil {
                ncas--
        }
-       casorder := make([]*Node, ncas)
+       casorder := make([]*ir.Node, ncas)
        nsends, nrecvs := 0, 0
 
-       var init []*Node
+       var init []*ir.Node
 
        // generate sel-struct
        base.Pos = sellineno
        selv := temp(types.NewArray(scasetype(), int64(ncas)))
-       r := nod(OAS, selv, nil)
+       r := ir.Nod(ir.OAS, selv, nil)
        r = typecheck(r, ctxStmt)
        init = append(init, r)
 
        // No initialization for order; runtime.selectgo is responsible for that.
-       order := temp(types.NewArray(types.Types[TUINT16], 2*int64(ncas)))
+       order := temp(types.NewArray(types.Types[types.TUINT16], 2*int64(ncas)))
 
-       var pc0, pcs *Node
+       var pc0, pcs *ir.Node
        if base.Flag.Race {
-               pcs = temp(types.NewArray(types.Types[TUINTPTR], int64(ncas)))
-               pc0 = typecheck(nod(OADDR, nod(OINDEX, pcs, nodintconst(0)), nil), ctxExpr)
+               pcs = temp(types.NewArray(types.Types[types.TUINTPTR], int64(ncas)))
+               pc0 = typecheck(ir.Nod(ir.OADDR, ir.Nod(ir.OINDEX, pcs, nodintconst(0)), nil), ctxExpr)
        } else {
                pc0 = nodnil()
        }
@@ -278,16 +279,16 @@ func walkselectcases(cases *Nodes) []*Node {
                }
 
                var i int
-               var c, elem *Node
+               var c, elem *ir.Node
                switch n.Op {
                default:
                        base.Fatalf("select %v", n.Op)
-               case OSEND:
+               case ir.OSEND:
                        i = nsends
                        nsends++
                        c = n.Left
                        elem = n.Right
-               case OSELRECV, OSELRECV2:
+               case ir.OSELRECV, ir.OSELRECV2:
                        nrecvs++
                        i = ncas - nrecvs
                        c = n.Right.Left
@@ -296,23 +297,23 @@ func walkselectcases(cases *Nodes) []*Node {
 
                casorder[i] = cas
 
-               setField := func(f string, val *Node) {
-                       r := nod(OAS, nodSym(ODOT, nod(OINDEX, selv, nodintconst(int64(i))), lookup(f)), val)
+               setField := func(f string, val *ir.Node) {
+                       r := ir.Nod(ir.OAS, nodSym(ir.ODOT, ir.Nod(ir.OINDEX, selv, nodintconst(int64(i))), lookup(f)), val)
                        r = typecheck(r, ctxStmt)
                        init = append(init, r)
                }
 
-               c = convnop(c, types.Types[TUNSAFEPTR])
+               c = convnop(c, types.Types[types.TUNSAFEPTR])
                setField("c", c)
                if elem != nil {
-                       elem = convnop(elem, types.Types[TUNSAFEPTR])
+                       elem = convnop(elem, types.Types[types.TUNSAFEPTR])
                        setField("elem", elem)
                }
 
                // TODO(mdempsky): There should be a cleaner way to
                // handle this.
                if base.Flag.Race {
-                       r = mkcall("selectsetpc", nil, nil, nod(OADDR, nod(OINDEX, pcs, nodintconst(int64(i))), nil))
+                       r = mkcall("selectsetpc", nil, nil, ir.Nod(ir.OADDR, ir.Nod(ir.OINDEX, pcs, nodintconst(int64(i))), nil))
                        init = append(init, r)
                }
        }
@@ -322,9 +323,9 @@ func walkselectcases(cases *Nodes) []*Node {
 
        // run the select
        base.Pos = sellineno
-       chosen := temp(types.Types[TINT])
-       recvOK := temp(types.Types[TBOOL])
-       r = nod(OAS2, nil, nil)
+       chosen := temp(types.Types[types.TINT])
+       recvOK := temp(types.Types[types.TBOOL])
+       r = ir.Nod(ir.OAS2, nil, nil)
        r.List.Set2(chosen, recvOK)
        fn := syslook("selectgo")
        r.Rlist.Set1(mkcall1(fn, fn.Type.Results(), nil, bytePtrToIndex(selv, 0), bytePtrToIndex(order, 0), pc0, nodintconst(int64(nsends)), nodintconst(int64(nrecvs)), nodbool(dflt == nil)))
@@ -332,46 +333,46 @@ func walkselectcases(cases *Nodes) []*Node {
        init = append(init, r)
 
        // selv and order are no longer alive after selectgo.
-       init = append(init, nod(OVARKILL, selv, nil))
-       init = append(init, nod(OVARKILL, order, nil))
+       init = append(init, ir.Nod(ir.OVARKILL, selv, nil))
+       init = append(init, ir.Nod(ir.OVARKILL, order, nil))
        if base.Flag.Race {
-               init = append(init, nod(OVARKILL, pcs, nil))
+               init = append(init, ir.Nod(ir.OVARKILL, pcs, nil))
        }
 
        // dispatch cases
-       dispatch := func(cond, cas *Node) {
+       dispatch := func(cond, cas *ir.Node) {
                cond = typecheck(cond, ctxExpr)
                cond = defaultlit(cond, nil)
 
-               r := nod(OIF, cond, nil)
+               r := ir.Nod(ir.OIF, cond, nil)
 
-               if n := cas.Left; n != nil && n.Op == OSELRECV2 {
-                       x := nod(OAS, n.List.First(), recvOK)
+               if n := cas.Left; n != nil && n.Op == ir.OSELRECV2 {
+                       x := ir.Nod(ir.OAS, n.List.First(), recvOK)
                        x = typecheck(x, ctxStmt)
                        r.Nbody.Append(x)
                }
 
                r.Nbody.AppendNodes(&cas.Nbody)
-               r.Nbody.Append(nod(OBREAK, nil, nil))
+               r.Nbody.Append(ir.Nod(ir.OBREAK, nil, nil))
                init = append(init, r)
        }
 
        if dflt != nil {
                setlineno(dflt)
-               dispatch(nod(OLT, chosen, nodintconst(0)), dflt)
+               dispatch(ir.Nod(ir.OLT, chosen, nodintconst(0)), dflt)
        }
        for i, cas := range casorder {
                setlineno(cas)
-               dispatch(nod(OEQ, chosen, nodintconst(int64(i))), cas)
+               dispatch(ir.Nod(ir.OEQ, chosen, nodintconst(int64(i))), cas)
        }
 
        return init
 }
 
 // bytePtrToIndex returns a Node representing "(*byte)(&n[i])".
-func bytePtrToIndex(n *Node, i int64) *Node {
-       s := nod(OADDR, nod(OINDEX, n, nodintconst(i)), nil)
-       t := types.NewPtr(types.Types[TUINT8])
+func bytePtrToIndex(n *ir.Node, i int64) *ir.Node {
+       s := ir.Nod(ir.OADDR, ir.Nod(ir.OINDEX, n, nodintconst(i)), nil)
+       t := types.NewPtr(types.Types[types.TUINT8])
        return convnop(s, t)
 }
 
@@ -380,9 +381,9 @@ var scase *types.Type
 // Keep in sync with src/runtime/select.go.
 func scasetype() *types.Type {
        if scase == nil {
-               scase = tostruct([]*Node{
-                       namedfield("c", types.Types[TUNSAFEPTR]),
-                       namedfield("elem", types.Types[TUNSAFEPTR]),
+               scase = tostruct([]*ir.Node{
+                       namedfield("c", types.Types[types.TUNSAFEPTR]),
+                       namedfield("elem", types.Types[types.TUNSAFEPTR]),
                })
                scase.SetNoalg(true)
        }
index 219435d6de39e35fcde0ad042acfae5642f1859c..d78b509127675b4e4d2ca955e448c18fcd9f1f6e 100644 (file)
@@ -6,6 +6,7 @@ package gc
 
 import (
        "cmd/compile/internal/base"
+       "cmd/compile/internal/ir"
        "cmd/compile/internal/types"
        "cmd/internal/obj"
        "fmt"
@@ -13,8 +14,8 @@ import (
 )
 
 type InitEntry struct {
-       Xoffset int64 // struct, array only
-       Expr    *Node // bytes of run-time computed expressions
+       Xoffset int64    // struct, array only
+       Expr    *ir.Node // bytes of run-time computed expressions
 }
 
 type InitPlan struct {
@@ -28,21 +29,21 @@ type InitPlan struct {
 type InitSchedule struct {
        // out is the ordered list of dynamic initialization
        // statements.
-       out []*Node
+       out []*ir.Node
 
-       initplans map[*Node]*InitPlan
-       inittemps map[*Node]*Node
+       initplans map[*ir.Node]*InitPlan
+       inittemps map[*ir.Node]*ir.Node
 }
 
-func (s *InitSchedule) append(n *Node) {
+func (s *InitSchedule) append(n *ir.Node) {
        s.out = append(s.out, n)
 }
 
 // staticInit adds an initialization statement n to the schedule.
-func (s *InitSchedule) staticInit(n *Node) {
+func (s *InitSchedule) staticInit(n *ir.Node) {
        if !s.tryStaticInit(n) {
                if base.Flag.Percent != 0 {
-                       Dump("nonstatic", n)
+                       ir.Dump("nonstatic", n)
                }
                s.append(n)
        }
@@ -50,16 +51,16 @@ func (s *InitSchedule) staticInit(n *Node) {
 
 // tryStaticInit attempts to statically execute an initialization
 // statement and reports whether it succeeded.
-func (s *InitSchedule) tryStaticInit(n *Node) bool {
+func (s *InitSchedule) tryStaticInit(n *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 n.Op != OAS {
+       if n.Op != ir.OAS {
                return false
        }
-       if n.Left.isBlank() && candiscard(n.Right) {
+       if ir.IsBlank(n.Left) && candiscard(n.Right) {
                return true
        }
        lno := setlineno(n)
@@ -69,21 +70,21 @@ func (s *InitSchedule) tryStaticInit(n *Node) bool {
 
 // like staticassign but we are copying an already
 // initialized value r.
-func (s *InitSchedule) staticcopy(l *Node, r *Node) bool {
-       if r.Op != ONAME && r.Op != OMETHEXPR {
+func (s *InitSchedule) staticcopy(l *ir.Node, r *ir.Node) bool {
+       if r.Op != ir.ONAME && r.Op != ir.OMETHEXPR {
                return false
        }
-       if r.Class() == PFUNC {
+       if r.Class() == ir.PFUNC {
                pfuncsym(l, r)
                return true
        }
-       if r.Class() != PEXTERN || r.Sym.Pkg != localpkg {
+       if r.Class() != ir.PEXTERN || r.Sym.Pkg != ir.LocalPkg {
                return false
        }
        if r.Name.Defn == nil { // probably zeroed but perhaps supplied externally and of unknown value
                return false
        }
-       if r.Name.Defn.Op != OAS {
+       if r.Name.Defn.Op != ir.OAS {
                return false
        }
        if r.Type.IsString() { // perhaps overwritten by cmd/link -X (#34675)
@@ -92,73 +93,73 @@ func (s *InitSchedule) staticcopy(l *Node, r *Node) bool {
        orig := r
        r = r.Name.Defn.Right
 
-       for r.Op == OCONVNOP && !types.Identical(r.Type, l.Type) {
+       for r.Op == ir.OCONVNOP && !types.Identical(r.Type, l.Type) {
                r = r.Left
        }
 
        switch r.Op {
-       case ONAME, OMETHEXPR:
+       case ir.ONAME, ir.OMETHEXPR:
                if s.staticcopy(l, r) {
                        return true
                }
                // We may have skipped past one or more OCONVNOPs, so
                // use conv to ensure r is assignable to l (#13263).
-               s.append(nod(OAS, l, conv(r, l.Type)))
+               s.append(ir.Nod(ir.OAS, l, conv(r, l.Type)))
                return true
 
-       case ONIL:
+       case ir.ONIL:
                return true
 
-       case OLITERAL:
+       case ir.OLITERAL:
                if isZero(r) {
                        return true
                }
                litsym(l, r, int(l.Type.Width))
                return true
 
-       case OADDR:
-               if a := r.Left; a.Op == ONAME {
+       case ir.OADDR:
+               if a := r.Left; a.Op == ir.ONAME {
                        addrsym(l, a)
                        return true
                }
 
-       case OPTRLIT:
+       case ir.OPTRLIT:
                switch r.Left.Op {
-               case OARRAYLIT, OSLICELIT, OSTRUCTLIT, OMAPLIT:
+               case ir.OARRAYLIT, ir.OSLICELIT, ir.OSTRUCTLIT, ir.OMAPLIT:
                        // copy pointer
                        addrsym(l, s.inittemps[r])
                        return true
                }
 
-       case OSLICELIT:
+       case ir.OSLICELIT:
                // copy slice
                a := s.inittemps[r]
                slicesym(l, a, r.Right.Int64Val())
                return true
 
-       case OARRAYLIT, OSTRUCTLIT:
+       case ir.OARRAYLIT, ir.OSTRUCTLIT:
                p := s.initplans[r]
 
-               n := l.copy()
+               n := ir.Copy(l)
                for i := range p.E {
                        e := &p.E[i]
                        n.Xoffset = l.Xoffset + e.Xoffset
                        n.Type = e.Expr.Type
-                       if e.Expr.Op == OLITERAL || e.Expr.Op == ONIL {
+                       if e.Expr.Op == ir.OLITERAL || e.Expr.Op == ir.ONIL {
                                litsym(n, e.Expr, int(n.Type.Width))
                                continue
                        }
-                       ll := n.sepcopy()
+                       ll := ir.SepCopy(n)
                        if s.staticcopy(ll, e.Expr) {
                                continue
                        }
                        // Requires computation, but we're
                        // copying someone else's computation.
-                       rr := orig.sepcopy()
+                       rr := ir.SepCopy(orig)
                        rr.Type = ll.Type
                        rr.Xoffset += e.Xoffset
                        setlineno(rr)
-                       s.append(nod(OAS, ll, rr))
+                       s.append(ir.Nod(ir.OAS, ll, rr))
                }
 
                return true
@@ -167,35 +168,35 @@ func (s *InitSchedule) staticcopy(l *Node, r *Node) bool {
        return false
 }
 
-func (s *InitSchedule) staticassign(l *Node, r *Node) bool {
-       for r.Op == OCONVNOP {
+func (s *InitSchedule) staticassign(l *ir.Node, r *ir.Node) bool {
+       for r.Op == ir.OCONVNOP {
                r = r.Left
        }
 
        switch r.Op {
-       case ONAME, OMETHEXPR:
+       case ir.ONAME, ir.OMETHEXPR:
                return s.staticcopy(l, r)
 
-       case ONIL:
+       case ir.ONIL:
                return true
 
-       case OLITERAL:
+       case ir.OLITERAL:
                if isZero(r) {
                        return true
                }
                litsym(l, r, int(l.Type.Width))
                return true
 
-       case OADDR:
+       case ir.OADDR:
                if nam := stataddr(r.Left); nam != nil {
                        addrsym(l, nam)
                        return true
                }
                fallthrough
 
-       case OPTRLIT:
+       case ir.OPTRLIT:
                switch r.Left.Op {
-               case OARRAYLIT, OSLICELIT, OMAPLIT, OSTRUCTLIT:
+               case ir.OARRAYLIT, ir.OSLICELIT, ir.OMAPLIT, ir.OSTRUCTLIT:
                        // Init pointer.
                        a := staticname(r.Left.Type)
 
@@ -204,20 +205,20 @@ func (s *InitSchedule) staticassign(l *Node, r *Node) bool {
 
                        // Init underlying literal.
                        if !s.staticassign(a, r.Left) {
-                               s.append(nod(OAS, a, r.Left))
+                               s.append(ir.Nod(ir.OAS, a, r.Left))
                        }
                        return true
                }
                //dump("not static ptrlit", r);
 
-       case OSTR2BYTES:
-               if l.Class() == PEXTERN && r.Left.Op == OLITERAL {
+       case ir.OSTR2BYTES:
+               if l.Class() == ir.PEXTERN && r.Left.Op == ir.OLITERAL {
                        sval := r.Left.StringVal()
                        slicebytes(l, sval)
                        return true
                }
 
-       case OSLICELIT:
+       case ir.OSLICELIT:
                s.initplan(r)
                // Init slice.
                bound := r.Right.Int64Val()
@@ -230,32 +231,32 @@ func (s *InitSchedule) staticassign(l *Node, r *Node) bool {
                l = a
                fallthrough
 
-       case OARRAYLIT, OSTRUCTLIT:
+       case ir.OARRAYLIT, ir.OSTRUCTLIT:
                s.initplan(r)
 
                p := s.initplans[r]
-               n := l.copy()
+               n := ir.Copy(l)
                for i := range p.E {
                        e := &p.E[i]
                        n.Xoffset = l.Xoffset + e.Xoffset
                        n.Type = e.Expr.Type
-                       if e.Expr.Op == OLITERAL || e.Expr.Op == ONIL {
+                       if e.Expr.Op == ir.OLITERAL || e.Expr.Op == ir.ONIL {
                                litsym(n, e.Expr, int(n.Type.Width))
                                continue
                        }
                        setlineno(e.Expr)
-                       a := n.sepcopy()
+                       a := ir.SepCopy(n)
                        if !s.staticassign(a, e.Expr) {
-                               s.append(nod(OAS, a, e.Expr))
+                               s.append(ir.Nod(ir.OAS, a, e.Expr))
                        }
                }
 
                return true
 
-       case OMAPLIT:
+       case ir.OMAPLIT:
                break
 
-       case OCLOSURE:
+       case ir.OCLOSURE:
                if hasemptycvars(r) {
                        if base.Debug.Closure > 0 {
                                base.WarnfAt(r.Pos, "closure converted to global")
@@ -267,13 +268,13 @@ func (s *InitSchedule) staticassign(l *Node, r *Node) bool {
                }
                closuredebugruntimecheck(r)
 
-       case OCONVIFACE:
+       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.
                val := r
-               for val.Op == OCONVIFACE {
+               for val.Op == ir.OCONVIFACE {
                        val = val.Left
                }
 
@@ -283,12 +284,12 @@ func (s *InitSchedule) staticassign(l *Node, r *Node) bool {
                        // 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 == ONIL
+                       return val.Op == ir.ONIL
                }
 
                markTypeUsedInInterface(val.Type, l.Sym.Linksym())
 
-               var itab *Node
+               var itab *ir.Node
                if l.Type.IsEmptyInterface() {
                        itab = typename(val.Type)
                } else {
@@ -296,7 +297,7 @@ func (s *InitSchedule) staticassign(l *Node, r *Node) bool {
                }
 
                // Create a copy of l to modify while we emit data.
-               n := l.copy()
+               n := ir.Copy(l)
 
                // Emit itab, advance offset.
                addrsym(n, itab.Left) // itab is an OADDR node
@@ -304,23 +305,23 @@ func (s *InitSchedule) staticassign(l *Node, r *Node) bool {
 
                // Emit data.
                if isdirectiface(val.Type) {
-                       if val.Op == ONIL {
+                       if val.Op == ir.ONIL {
                                // Nil is zero, nothing to do.
                                return true
                        }
                        // Copy val directly into n.
                        n.Type = val.Type
                        setlineno(val)
-                       a := n.sepcopy()
+                       a := ir.SepCopy(n)
                        if !s.staticassign(a, val) {
-                               s.append(nod(OAS, a, val))
+                               s.append(ir.Nod(ir.OAS, a, val))
                        }
                } else {
                        // Construct temp to hold val, write pointer to temp into n.
                        a := staticname(val.Type)
                        s.inittemps[val] = a
                        if !s.staticassign(a, val) {
-                               s.append(nod(OAS, a, val))
+                               s.append(ir.Nod(ir.OAS, a, val))
                        }
                        addrsym(n, a)
                }
@@ -366,29 +367,29 @@ 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) *Node {
+func staticname(t *types.Type) *ir.Node {
        // Don't use lookupN; it interns the resulting string, but these are all unique.
-       n := newname(lookup(fmt.Sprintf("%s%d", obj.StaticNamePref, statuniqgen)))
+       n := NewName(lookup(fmt.Sprintf("%s%d", obj.StaticNamePref, statuniqgen)))
        statuniqgen++
-       addvar(n, t, PEXTERN)
+       addvar(n, t, ir.PEXTERN)
        n.Sym.Linksym().Set(obj.AttrLocal, true)
        return n
 }
 
 // readonlystaticname returns a name backed by a (writable) static data symbol.
-func readonlystaticname(t *types.Type) *Node {
+func readonlystaticname(t *types.Type) *ir.Node {
        n := staticname(t)
        n.MarkReadonly()
        n.Sym.Linksym().Set(obj.AttrContentAddressable, true)
        return n
 }
 
-func (n *Node) isSimpleName() bool {
-       return (n.Op == ONAME || n.Op == OMETHEXPR) && n.Class() != PAUTOHEAP && n.Class() != PEXTERN
+func isSimpleName(n *ir.Node) bool {
+       return (n.Op == ir.ONAME || n.Op == ir.OMETHEXPR) && n.Class() != ir.PAUTOHEAP && n.Class() != ir.PEXTERN
 }
 
-func litas(l *Node, r *Node, init *Nodes) {
-       a := nod(OAS, l, r)
+func litas(l *ir.Node, r *ir.Node, init *ir.Nodes) {
+       a := ir.Nod(ir.OAS, l, r)
        a = typecheck(a, ctxStmt)
        a = walkexpr(a, init)
        init.Append(a)
@@ -404,15 +405,15 @@ const (
 
 // getdyn calculates the initGenType for n.
 // If top is false, getdyn is recursing.
-func getdyn(n *Node, top bool) initGenType {
+func getdyn(n *ir.Node, top bool) initGenType {
        switch n.Op {
        default:
-               if n.isGoConst() {
+               if isGoConst(n) {
                        return initConst
                }
                return initDynamic
 
-       case OSLICELIT:
+       case ir.OSLICELIT:
                if !top {
                        return initDynamic
                }
@@ -426,15 +427,15 @@ func getdyn(n *Node, top bool) initGenType {
                        return initDynamic
                }
 
-       case OARRAYLIT, OSTRUCTLIT:
+       case ir.OARRAYLIT, ir.OSTRUCTLIT:
        }
 
        var mode initGenType
        for _, n1 := range n.List.Slice() {
                switch n1.Op {
-               case OKEY:
+               case ir.OKEY:
                        n1 = n1.Right
-               case OSTRUCTKEY:
+               case ir.OSTRUCTKEY:
                        n1 = n1.Left
                }
                mode |= getdyn(n1, false)
@@ -446,13 +447,13 @@ func getdyn(n *Node, top bool) initGenType {
 }
 
 // isStaticCompositeLiteral reports whether n is a compile-time constant.
-func isStaticCompositeLiteral(n *Node) bool {
+func isStaticCompositeLiteral(n *ir.Node) bool {
        switch n.Op {
-       case OSLICELIT:
+       case ir.OSLICELIT:
                return false
-       case OARRAYLIT:
+       case ir.OARRAYLIT:
                for _, r := range n.List.Slice() {
-                       if r.Op == OKEY {
+                       if r.Op == ir.OKEY {
                                r = r.Right
                        }
                        if !isStaticCompositeLiteral(r) {
@@ -460,9 +461,9 @@ func isStaticCompositeLiteral(n *Node) bool {
                        }
                }
                return true
-       case OSTRUCTLIT:
+       case ir.OSTRUCTLIT:
                for _, r := range n.List.Slice() {
-                       if r.Op != OSTRUCTKEY {
+                       if r.Op != ir.OSTRUCTKEY {
                                base.Fatalf("isStaticCompositeLiteral: rhs not OSTRUCTKEY: %v", r)
                        }
                        if !isStaticCompositeLiteral(r.Left) {
@@ -470,18 +471,18 @@ func isStaticCompositeLiteral(n *Node) bool {
                        }
                }
                return true
-       case OLITERAL, ONIL:
+       case ir.OLITERAL, ir.ONIL:
                return true
-       case OCONVIFACE:
+       case ir.OCONVIFACE:
                // See staticassign's OCONVIFACE case for comments.
                val := n
-               for val.Op == OCONVIFACE {
+               for val.Op == ir.OCONVIFACE {
                        val = val.Left
                }
                if val.Type.IsInterface() {
-                       return val.Op == ONIL
+                       return val.Op == ir.ONIL
                }
-               if isdirectiface(val.Type) && val.Op == ONIL {
+               if isdirectiface(val.Type) && val.Op == ir.ONIL {
                        return true
                }
                return isStaticCompositeLiteral(val)
@@ -508,37 +509,37 @@ const (
 
 // fixedlit handles struct, array, and slice literals.
 // TODO: expand documentation.
-func fixedlit(ctxt initContext, kind initKind, n *Node, var_ *Node, init *Nodes) {
-       isBlank := var_ == nblank
-       var splitnode func(*Node) (a *Node, value *Node)
+func fixedlit(ctxt initContext, kind initKind, n *ir.Node, var_ *ir.Node, init *ir.Nodes) {
+       isBlank := var_ == ir.BlankNode
+       var splitnode func(*ir.Node) (a *ir.Node, value *ir.Node)
        switch n.Op {
-       case OARRAYLIT, OSLICELIT:
+       case ir.OARRAYLIT, ir.OSLICELIT:
                var k int64
-               splitnode = func(r *Node) (*Node, *Node) {
-                       if r.Op == OKEY {
+               splitnode = func(r *ir.Node) (*ir.Node, *ir.Node) {
+                       if r.Op == ir.OKEY {
                                k = indexconst(r.Left)
                                if k < 0 {
                                        base.Fatalf("fixedlit: invalid index %v", r.Left)
                                }
                                r = r.Right
                        }
-                       a := nod(OINDEX, var_, nodintconst(k))
+                       a := ir.Nod(ir.OINDEX, var_, nodintconst(k))
                        k++
                        if isBlank {
-                               a = nblank
+                               a = ir.BlankNode
                        }
                        return a, r
                }
-       case OSTRUCTLIT:
-               splitnode = func(r *Node) (*Node, *Node) {
-                       if r.Op != OSTRUCTKEY {
+       case ir.OSTRUCTLIT:
+               splitnode = func(r *ir.Node) (*ir.Node, *ir.Node) {
+                       if r.Op != ir.OSTRUCTKEY {
                                base.Fatalf("fixedlit: rhs not OSTRUCTKEY: %v", r)
                        }
                        if r.Sym.IsBlank() || isBlank {
-                               return nblank, r.Left
+                               return ir.BlankNode, r.Left
                        }
                        setlineno(r)
-                       return nodSym(ODOT, var_, r.Sym), r.Left
+                       return nodSym(ir.ODOT, var_, r.Sym), r.Left
                }
        default:
                base.Fatalf("fixedlit bad op: %v", n.Op)
@@ -546,36 +547,36 @@ func fixedlit(ctxt initContext, kind initKind, n *Node, var_ *Node, init *Nodes)
 
        for _, r := range n.List.Slice() {
                a, value := splitnode(r)
-               if a == nblank && candiscard(value) {
+               if a == ir.BlankNode && candiscard(value) {
                        continue
                }
 
                switch value.Op {
-               case OSLICELIT:
+               case ir.OSLICELIT:
                        if (kind == initKindStatic && ctxt == inNonInitFunction) || (kind == initKindDynamic && ctxt == inInitFunction) {
                                slicelit(ctxt, value, a, init)
                                continue
                        }
 
-               case OARRAYLIT, OSTRUCTLIT:
+               case ir.OARRAYLIT, ir.OSTRUCTLIT:
                        fixedlit(ctxt, kind, value, a, init)
                        continue
                }
 
-               islit := value.isGoConst()
+               islit := isGoConst(value)
                if (kind == initKindStatic && !islit) || (kind == initKindDynamic && islit) {
                        continue
                }
 
                // build list of assignments: var[index] = expr
                setlineno(a)
-               a = nod(OAS, a, value)
+               a = ir.Nod(ir.OAS, a, value)
                a = typecheck(a, ctxStmt)
                switch kind {
                case initKindStatic:
                        genAsStatic(a)
                case initKindDynamic, initKindLocalCode:
-                       a = orderStmtInPlace(a, map[string][]*Node{})
+                       a = orderStmtInPlace(a, map[string][]*ir.Node{})
                        a = walkstmt(a)
                        init.Append(a)
                default:
@@ -585,8 +586,8 @@ func fixedlit(ctxt initContext, kind initKind, n *Node, var_ *Node, init *Nodes)
        }
 }
 
-func isSmallSliceLit(n *Node) bool {
-       if n.Op != OSLICELIT {
+func isSmallSliceLit(n *ir.Node) bool {
+       if n.Op != ir.OSLICELIT {
                return false
        }
 
@@ -595,7 +596,7 @@ func isSmallSliceLit(n *Node) bool {
        return smallintconst(r) && (n.Type.Elem().Width == 0 || r.Int64Val() <= smallArrayBytes/n.Type.Elem().Width)
 }
 
-func slicelit(ctxt initContext, n *Node, var_ *Node, init *Nodes) {
+func slicelit(ctxt initContext, n *ir.Node, var_ *ir.Node, init *ir.Nodes) {
        // make an array type corresponding the number of elements we have
        t := types.NewArray(n.Type.Elem(), n.Right.Int64Val())
        dowidth(t)
@@ -610,7 +611,7 @@ func slicelit(ctxt initContext, n *Node, var_ *Node, init *Nodes) {
                // copy static to slice
                var_ = typecheck(var_, ctxExpr|ctxAssign)
                nam := stataddr(var_)
-               if nam == nil || nam.Class() != PEXTERN {
+               if nam == nil || nam.Class() != ir.PEXTERN {
                        base.Fatalf("slicelit: %v", var_)
                }
                slicesym(nam, vstat, t.NumElem())
@@ -638,7 +639,7 @@ func slicelit(ctxt initContext, n *Node, var_ *Node, init *Nodes) {
 
        // if the literal contains constants,
        // make static initialized array (1),(2)
-       var vstat *Node
+       var vstat *ir.Node
 
        mode := getdyn(n, true)
        if mode&initConst != 0 && !isSmallSliceLit(n) {
@@ -654,7 +655,7 @@ func slicelit(ctxt initContext, n *Node, var_ *Node, init *Nodes) {
        vauto := temp(types.NewPtr(t))
 
        // set auto to point at new temp or heap (3 assign)
-       var a *Node
+       var a *ir.Node
        if x := prealloc[n]; x != nil {
                // temp allocated during order.go for dddarg
                if !types.Identical(t, x.Type) {
@@ -662,43 +663,43 @@ func slicelit(ctxt initContext, n *Node, var_ *Node, init *Nodes) {
                }
 
                if vstat == nil {
-                       a = nod(OAS, x, nil)
+                       a = ir.Nod(ir.OAS, x, nil)
                        a = typecheck(a, ctxStmt)
                        init.Append(a) // zero new temp
                } else {
                        // Declare that we're about to initialize all of x.
                        // (Which happens at the *vauto = vstat below.)
-                       init.Append(nod(OVARDEF, x, nil))
+                       init.Append(ir.Nod(ir.OVARDEF, x, nil))
                }
 
-               a = nod(OADDR, x, nil)
+               a = ir.Nod(ir.OADDR, x, nil)
        } else if n.Esc == EscNone {
                a = temp(t)
                if vstat == nil {
-                       a = nod(OAS, temp(t), nil)
+                       a = ir.Nod(ir.OAS, temp(t), nil)
                        a = typecheck(a, ctxStmt)
                        init.Append(a) // zero new temp
                        a = a.Left
                } else {
-                       init.Append(nod(OVARDEF, a, nil))
+                       init.Append(ir.Nod(ir.OVARDEF, a, nil))
                }
 
-               a = nod(OADDR, a, nil)
+               a = ir.Nod(ir.OADDR, a, nil)
        } else {
-               a = nod(ONEW, nil, nil)
+               a = ir.Nod(ir.ONEW, nil, nil)
                a.List.Set1(typenod(t))
        }
 
-       a = nod(OAS, vauto, a)
+       a = ir.Nod(ir.OAS, vauto, a)
        a = typecheck(a, ctxStmt)
        a = walkexpr(a, init)
        init.Append(a)
 
        if vstat != nil {
                // copy static to heap (4)
-               a = nod(ODEREF, vauto, nil)
+               a = ir.Nod(ir.ODEREF, vauto, nil)
 
-               a = nod(OAS, a, vstat)
+               a = ir.Nod(ir.OAS, a, vstat)
                a = typecheck(a, ctxStmt)
                a = walkexpr(a, init)
                init.Append(a)
@@ -707,24 +708,24 @@ func slicelit(ctxt initContext, n *Node, var_ *Node, init *Nodes) {
        // put dynamics into array (5)
        var index int64
        for _, value := range n.List.Slice() {
-               if value.Op == OKEY {
+               if value.Op == ir.OKEY {
                        index = indexconst(value.Left)
                        if index < 0 {
                                base.Fatalf("slicelit: invalid index %v", value.Left)
                        }
                        value = value.Right
                }
-               a := nod(OINDEX, vauto, nodintconst(index))
+               a := ir.Nod(ir.OINDEX, vauto, nodintconst(index))
                a.SetBounded(true)
                index++
 
                // TODO need to check bounds?
 
                switch value.Op {
-               case OSLICELIT:
+               case ir.OSLICELIT:
                        break
 
-               case OARRAYLIT, OSTRUCTLIT:
+               case ir.OARRAYLIT, ir.OSTRUCTLIT:
                        k := initKindDynamic
                        if vstat == nil {
                                // Generate both static and dynamic initializations.
@@ -735,32 +736,32 @@ func slicelit(ctxt initContext, n *Node, var_ *Node, init *Nodes) {
                        continue
                }
 
-               if vstat != nil && value.isGoConst() { // already set by copy from static value
+               if vstat != nil && isGoConst(value) { // already set by copy from static value
                        continue
                }
 
                // build list of vauto[c] = expr
                setlineno(value)
-               a = nod(OAS, a, value)
+               a = ir.Nod(ir.OAS, a, value)
 
                a = typecheck(a, ctxStmt)
-               a = orderStmtInPlace(a, map[string][]*Node{})
+               a = orderStmtInPlace(a, map[string][]*ir.Node{})
                a = walkstmt(a)
                init.Append(a)
        }
 
        // make slice out of heap (6)
-       a = nod(OAS, var_, nod(OSLICE, vauto, nil))
+       a = ir.Nod(ir.OAS, var_, ir.Nod(ir.OSLICE, vauto, nil))
 
        a = typecheck(a, ctxStmt)
-       a = orderStmtInPlace(a, map[string][]*Node{})
+       a = orderStmtInPlace(a, map[string][]*ir.Node{})
        a = walkstmt(a)
        init.Append(a)
 }
 
-func maplit(n *Node, m *Node, init *Nodes) {
+func maplit(n *ir.Node, m *ir.Node, init *ir.Nodes) {
        // make the map var
-       a := nod(OMAKE, nil, nil)
+       a := ir.Nod(ir.OMAKE, nil, nil)
        a.Esc = n.Esc
        a.List.Set2(typenod(n.Type), nodintconst(int64(n.List.Len())))
        litas(m, a, init)
@@ -792,8 +793,8 @@ func maplit(n *Node, m *Node, init *Nodes) {
                vstatk := readonlystaticname(tk)
                vstate := readonlystaticname(te)
 
-               datak := nod(OARRAYLIT, nil, nil)
-               datae := nod(OARRAYLIT, nil, nil)
+               datak := ir.Nod(ir.OARRAYLIT, nil, nil)
+               datae := ir.Nod(ir.OARRAYLIT, nil, nil)
                for _, r := range entries {
                        datak.List.Append(r.Left)
                        datae.List.Append(r.Right)
@@ -805,20 +806,20 @@ func maplit(n *Node, m *Node, init *Nodes) {
                // for i = 0; i < len(vstatk); i++ {
                //      map[vstatk[i]] = vstate[i]
                // }
-               i := temp(types.Types[TINT])
-               rhs := nod(OINDEX, vstate, i)
+               i := temp(types.Types[types.TINT])
+               rhs := ir.Nod(ir.OINDEX, vstate, i)
                rhs.SetBounded(true)
 
-               kidx := nod(OINDEX, vstatk, i)
+               kidx := ir.Nod(ir.OINDEX, vstatk, i)
                kidx.SetBounded(true)
-               lhs := nod(OINDEX, m, kidx)
+               lhs := ir.Nod(ir.OINDEX, m, kidx)
 
-               zero := nod(OAS, i, nodintconst(0))
-               cond := nod(OLT, i, nodintconst(tk.NumElem()))
-               incr := nod(OAS, i, nod(OADD, i, nodintconst(1)))
-               body := nod(OAS, lhs, rhs)
+               zero := ir.Nod(ir.OAS, i, nodintconst(0))
+               cond := ir.Nod(ir.OLT, i, nodintconst(tk.NumElem()))
+               incr := ir.Nod(ir.OAS, i, ir.Nod(ir.OADD, i, nodintconst(1)))
+               body := ir.Nod(ir.OAS, lhs, rhs)
 
-               loop := nod(OFOR, cond, incr)
+               loop := ir.Nod(ir.OFOR, cond, incr)
                loop.Nbody.Set1(body)
                loop.Ninit.Set1(zero)
 
@@ -839,88 +840,88 @@ func maplit(n *Node, m *Node, init *Nodes) {
                index, elem := r.Left, r.Right
 
                setlineno(index)
-               a := nod(OAS, tmpkey, index)
+               a := ir.Nod(ir.OAS, tmpkey, index)
                a = typecheck(a, ctxStmt)
                a = walkstmt(a)
                init.Append(a)
 
                setlineno(elem)
-               a = nod(OAS, tmpelem, elem)
+               a = ir.Nod(ir.OAS, tmpelem, elem)
                a = typecheck(a, ctxStmt)
                a = walkstmt(a)
                init.Append(a)
 
                setlineno(tmpelem)
-               a = nod(OAS, nod(OINDEX, m, tmpkey), tmpelem)
+               a = ir.Nod(ir.OAS, ir.Nod(ir.OINDEX, m, tmpkey), tmpelem)
                a = typecheck(a, ctxStmt)
                a = walkstmt(a)
                init.Append(a)
        }
 
-       a = nod(OVARKILL, tmpkey, nil)
+       a = ir.Nod(ir.OVARKILL, tmpkey, nil)
        a = typecheck(a, ctxStmt)
        init.Append(a)
-       a = nod(OVARKILL, tmpelem, nil)
+       a = ir.Nod(ir.OVARKILL, tmpelem, nil)
        a = typecheck(a, ctxStmt)
        init.Append(a)
 }
 
-func anylit(n *Node, var_ *Node, init *Nodes) {
+func anylit(n *ir.Node, var_ *ir.Node, init *ir.Nodes) {
        t := n.Type
        switch n.Op {
        default:
                base.Fatalf("anylit: not lit, op=%v node=%v", n.Op, n)
 
-       case ONAME, OMETHEXPR:
-               a := nod(OAS, var_, n)
+       case ir.ONAME, ir.OMETHEXPR:
+               a := ir.Nod(ir.OAS, var_, n)
                a = typecheck(a, ctxStmt)
                init.Append(a)
 
-       case OPTRLIT:
+       case ir.OPTRLIT:
                if !t.IsPtr() {
                        base.Fatalf("anylit: not ptr")
                }
 
-               var r *Node
+               var r *ir.Node
                if n.Right != nil {
                        // n.Right is stack temporary used as backing store.
-                       init.Append(nod(OAS, n.Right, nil)) // zero backing store, just in case (#18410)
-                       r = nod(OADDR, n.Right, nil)
+                       init.Append(ir.Nod(ir.OAS, n.Right, nil)) // zero backing store, just in case (#18410)
+                       r = ir.Nod(ir.OADDR, n.Right, nil)
                        r = typecheck(r, ctxExpr)
                } else {
-                       r = nod(ONEW, nil, nil)
+                       r = ir.Nod(ir.ONEW, nil, nil)
                        r.SetTypecheck(1)
                        r.Type = t
                        r.Esc = n.Esc
                }
 
                r = walkexpr(r, init)
-               a := nod(OAS, var_, r)
+               a := ir.Nod(ir.OAS, var_, r)
 
                a = typecheck(a, ctxStmt)
                init.Append(a)
 
-               var_ = nod(ODEREF, var_, nil)
+               var_ = ir.Nod(ir.ODEREF, var_, nil)
                var_ = typecheck(var_, ctxExpr|ctxAssign)
                anylit(n.Left, var_, init)
 
-       case OSTRUCTLIT, OARRAYLIT:
+       case ir.OSTRUCTLIT, ir.OARRAYLIT:
                if !t.IsStruct() && !t.IsArray() {
                        base.Fatalf("anylit: not struct/array")
                }
 
-               if var_.isSimpleName() && n.List.Len() > 4 {
+               if isSimpleName(var_) && n.List.Len() > 4 {
                        // lay out static data
                        vstat := readonlystaticname(t)
 
                        ctxt := inInitFunction
-                       if n.Op == OARRAYLIT {
+                       if n.Op == ir.OARRAYLIT {
                                ctxt = inNonInitFunction
                        }
                        fixedlit(ctxt, initKindStatic, n, vstat, init)
 
                        // copy static to var
-                       a := nod(OAS, var_, vstat)
+                       a := ir.Nod(ir.OAS, var_, vstat)
 
                        a = typecheck(a, ctxStmt)
                        a = walkexpr(a, init)
@@ -932,14 +933,14 @@ func anylit(n *Node, var_ *Node, init *Nodes) {
                }
 
                var components int64
-               if n.Op == OARRAYLIT {
+               if n.Op == ir.OARRAYLIT {
                        components = t.NumElem()
                } else {
                        components = int64(t.NumFields())
                }
                // initialization of an array or struct with unspecified components (missing fields or arrays)
-               if var_.isSimpleName() || int64(n.List.Len()) < components {
-                       a := nod(OAS, var_, nil)
+               if isSimpleName(var_) || int64(n.List.Len()) < components {
+                       a := ir.Nod(ir.OAS, var_, nil)
                        a = typecheck(a, ctxStmt)
                        a = walkexpr(a, init)
                        init.Append(a)
@@ -947,10 +948,10 @@ func anylit(n *Node, var_ *Node, init *Nodes) {
 
                fixedlit(inInitFunction, initKindLocalCode, n, var_, init)
 
-       case OSLICELIT:
+       case ir.OSLICELIT:
                slicelit(inInitFunction, n, var_, init)
 
-       case OMAPLIT:
+       case ir.OMAPLIT:
                if !t.IsMap() {
                        base.Fatalf("anylit: not map")
                }
@@ -958,7 +959,7 @@ func anylit(n *Node, var_ *Node, init *Nodes) {
        }
 }
 
-func oaslit(n *Node, init *Nodes) bool {
+func oaslit(n *ir.Node, init *ir.Nodes) bool {
        if n.Left == nil || n.Right == nil {
                // not a special composite literal assignment
                return false
@@ -967,7 +968,7 @@ func oaslit(n *Node, init *Nodes) bool {
                // not a special composite literal assignment
                return false
        }
-       if !n.Left.isSimpleName() {
+       if !isSimpleName(n.Left) {
                // not a special composite literal assignment
                return false
        }
@@ -981,7 +982,7 @@ func oaslit(n *Node, init *Nodes) bool {
                // not a special composite literal assignment
                return false
 
-       case OSTRUCTLIT, OARRAYLIT, OSLICELIT, OMAPLIT:
+       case ir.OSTRUCTLIT, ir.OARRAYLIT, ir.OSLICELIT, ir.OMAPLIT:
                if vmatch1(n.Left, n.Right) {
                        // not a special composite literal assignment
                        return false
@@ -989,12 +990,12 @@ func oaslit(n *Node, init *Nodes) bool {
                anylit(n.Right, n.Left, init)
        }
 
-       n.Op = OEMPTY
+       n.Op = ir.OEMPTY
        n.Right = nil
        return true
 }
 
-func getlit(lit *Node) int {
+func getlit(lit *ir.Node) int {
        if smallintconst(lit) {
                return int(lit.Int64Val())
        }
@@ -1002,16 +1003,16 @@ func getlit(lit *Node) int {
 }
 
 // stataddr returns the static address of n, if n has one, or else nil.
-func stataddr(n *Node) *Node {
+func stataddr(n *ir.Node) *ir.Node {
        if n == nil {
                return nil
        }
 
        switch n.Op {
-       case ONAME, OMETHEXPR:
-               return n.sepcopy()
+       case ir.ONAME, ir.OMETHEXPR:
+               return ir.SepCopy(n)
 
-       case ODOT:
+       case ir.ODOT:
                nam := stataddr(n.Left)
                if nam == nil {
                        break
@@ -1020,7 +1021,7 @@ func stataddr(n *Node) *Node {
                nam.Type = n.Type
                return nam
 
-       case OINDEX:
+       case ir.OINDEX:
                if n.Left.Type.IsSlice() {
                        break
                }
@@ -1045,7 +1046,7 @@ func stataddr(n *Node) *Node {
        return nil
 }
 
-func (s *InitSchedule) initplan(n *Node) {
+func (s *InitSchedule) initplan(n *ir.Node) {
        if s.initplans[n] != nil {
                return
        }
@@ -1055,10 +1056,10 @@ func (s *InitSchedule) initplan(n *Node) {
        default:
                base.Fatalf("initplan")
 
-       case OARRAYLIT, OSLICELIT:
+       case ir.OARRAYLIT, ir.OSLICELIT:
                var k int64
                for _, a := range n.List.Slice() {
-                       if a.Op == OKEY {
+                       if a.Op == ir.OKEY {
                                k = indexconst(a.Left)
                                if k < 0 {
                                        base.Fatalf("initplan arraylit: invalid index %v", a.Left)
@@ -1069,9 +1070,9 @@ func (s *InitSchedule) initplan(n *Node) {
                        k++
                }
 
-       case OSTRUCTLIT:
+       case ir.OSTRUCTLIT:
                for _, a := range n.List.Slice() {
-                       if a.Op != OSTRUCTKEY {
+                       if a.Op != ir.OSTRUCTKEY {
                                base.Fatalf("initplan structlit")
                        }
                        if a.Sym.IsBlank() {
@@ -1080,9 +1081,9 @@ func (s *InitSchedule) initplan(n *Node) {
                        s.addvalue(p, a.Xoffset, a.Left)
                }
 
-       case OMAPLIT:
+       case ir.OMAPLIT:
                for _, a := range n.List.Slice() {
-                       if a.Op != OKEY {
+                       if a.Op != ir.OKEY {
                                base.Fatalf("initplan maplit")
                        }
                        s.addvalue(p, -1, a.Right)
@@ -1090,7 +1091,7 @@ func (s *InitSchedule) initplan(n *Node) {
        }
 }
 
-func (s *InitSchedule) addvalue(p *InitPlan, xoffset int64, n *Node) {
+func (s *InitSchedule) addvalue(p *InitPlan, xoffset int64, n *ir.Node) {
        // special case: zero can be dropped entirely
        if isZero(n) {
                return
@@ -1112,12 +1113,12 @@ func (s *InitSchedule) addvalue(p *InitPlan, xoffset int64, n *Node) {
        p.E = append(p.E, InitEntry{Xoffset: xoffset, Expr: n})
 }
 
-func isZero(n *Node) bool {
+func isZero(n *ir.Node) bool {
        switch n.Op {
-       case ONIL:
+       case ir.ONIL:
                return true
 
-       case OLITERAL:
+       case ir.OLITERAL:
                switch u := n.Val(); u.Kind() {
                case constant.String:
                        return constant.StringVal(u) == ""
@@ -1127,9 +1128,9 @@ func isZero(n *Node) bool {
                        return constant.Sign(u) == 0
                }
 
-       case OARRAYLIT:
+       case ir.OARRAYLIT:
                for _, n1 := range n.List.Slice() {
-                       if n1.Op == OKEY {
+                       if n1.Op == ir.OKEY {
                                n1 = n1.Right
                        }
                        if !isZero(n1) {
@@ -1138,7 +1139,7 @@ func isZero(n *Node) bool {
                }
                return true
 
-       case OSTRUCTLIT:
+       case ir.OSTRUCTLIT:
                for _, n1 := range n.List.Slice() {
                        if !isZero(n1.Left) {
                                return false
@@ -1150,24 +1151,24 @@ func isZero(n *Node) bool {
        return false
 }
 
-func isvaluelit(n *Node) bool {
-       return n.Op == OARRAYLIT || n.Op == OSTRUCTLIT
+func isvaluelit(n *ir.Node) bool {
+       return n.Op == ir.OARRAYLIT || n.Op == ir.OSTRUCTLIT
 }
 
-func genAsStatic(as *Node) {
+func genAsStatic(as *ir.Node) {
        if as.Left.Type == nil {
                base.Fatalf("genAsStatic as.Left not typechecked")
        }
 
        nam := stataddr(as.Left)
-       if nam == nil || (nam.Class() != PEXTERN && as.Left != nblank) {
+       if nam == nil || (nam.Class() != ir.PEXTERN && as.Left != ir.BlankNode) {
                base.Fatalf("genAsStatic: lhs %v", as.Left)
        }
 
        switch {
-       case as.Right.Op == OLITERAL:
+       case as.Right.Op == ir.OLITERAL:
                litsym(nam, as.Right, int(as.Right.Type.Width))
-       case (as.Right.Op == ONAME || as.Right.Op == OMETHEXPR) && as.Right.Class() == PFUNC:
+       case (as.Right.Op == ir.ONAME || as.Right.Op == ir.OMETHEXPR) && as.Right.Class() == ir.PFUNC:
                pfuncsym(nam, as.Right)
        default:
                base.Fatalf("genAsStatic: rhs %v", as.Right)
index e892a01da08bf88efcc7c7eff24a5ecad157bb58..658ea28fbe2284b760f9c2364b18794bce86076d 100644 (file)
@@ -16,6 +16,7 @@ import (
        "bufio"
        "bytes"
        "cmd/compile/internal/base"
+       "cmd/compile/internal/ir"
        "cmd/compile/internal/ssa"
        "cmd/compile/internal/types"
        "cmd/internal/obj"
@@ -39,7 +40,7 @@ const ssaDumpFile = "ssa.html"
 const maxOpenDefers = 8
 
 // ssaDumpInlined holds all inlined functions when ssaDump contains a function name.
-var ssaDumpInlined []*Node
+var ssaDumpInlined []*ir.Node
 
 func initssaconfig() {
        types_ := ssa.NewTypes()
@@ -50,16 +51,16 @@ func initssaconfig() {
 
        // Generate a few pointer types that are uncommon in the frontend but common in the backend.
        // Caching is disabled in the backend, so generating these here avoids allocations.
-       _ = types.NewPtr(types.Types[TINTER])                             // *interface{}
-       _ = types.NewPtr(types.NewPtr(types.Types[TSTRING]))              // **string
-       _ = types.NewPtr(types.NewSlice(types.Types[TINTER]))             // *[]interface{}
-       _ = types.NewPtr(types.NewPtr(types.Bytetype))                    // **byte
-       _ = types.NewPtr(types.NewSlice(types.Bytetype))                  // *[]byte
-       _ = types.NewPtr(types.NewSlice(types.Types[TSTRING]))            // *[]string
-       _ = types.NewPtr(types.NewPtr(types.NewPtr(types.Types[TUINT8]))) // ***uint8
-       _ = types.NewPtr(types.Types[TINT16])                             // *int16
-       _ = types.NewPtr(types.Types[TINT64])                             // *int64
-       _ = types.NewPtr(types.Errortype)                                 // *error
+       _ = types.NewPtr(types.Types[types.TINTER])                             // *interface{}
+       _ = types.NewPtr(types.NewPtr(types.Types[types.TSTRING]))              // **string
+       _ = types.NewPtr(types.NewSlice(types.Types[types.TINTER]))             // *[]interface{}
+       _ = types.NewPtr(types.NewPtr(types.Bytetype))                          // **byte
+       _ = types.NewPtr(types.NewSlice(types.Bytetype))                        // *[]byte
+       _ = types.NewPtr(types.NewSlice(types.Types[types.TSTRING]))            // *[]string
+       _ = types.NewPtr(types.NewPtr(types.NewPtr(types.Types[types.TUINT8]))) // ***uint8
+       _ = types.NewPtr(types.Types[types.TINT16])                             // *int16
+       _ = types.NewPtr(types.Types[types.TINT64])                             // *int64
+       _ = types.NewPtr(types.Errortype)                                       // *error
        types.NewPtrCacheEnabled = false
        ssaConfig = ssa.NewConfig(thearch.LinkArch.Name, *types_, base.Ctxt, base.Flag.N == 0)
        ssaConfig.SoftFloat = thearch.SoftFloat
@@ -185,9 +186,9 @@ func initssaconfig() {
 // function/method/interface call), where the receiver of a method call is
 // considered as the 0th parameter. This does not include the receiver of an
 // interface call.
-func getParam(n *Node, i int) *types.Field {
+func getParam(n *ir.Node, i int) *types.Field {
        t := n.Left.Type
-       if n.Op == OCALLMETH {
+       if n.Op == ir.OCALLMETH {
                if i == 0 {
                        return t.Recv()
                }
@@ -241,8 +242,8 @@ func dvarint(x *obj.LSym, off int, v int64) int {
 //      - Size of the argument
 //      - Offset of where argument should be placed in the args frame when making call
 func (s *state) emitOpenDeferInfo() {
-       x := base.Ctxt.Lookup(s.curfn.Func.lsym.Name + ".opendefer")
-       s.curfn.Func.lsym.Func().OpenCodedDeferInfo = x
+       x := base.Ctxt.Lookup(s.curfn.Func.LSym.Name + ".opendefer")
+       s.curfn.Func.LSym.Func().OpenCodedDeferInfo = x
        off := 0
 
        // Compute maxargsize (max size of arguments for all defers)
@@ -288,8 +289,8 @@ func (s *state) emitOpenDeferInfo() {
 
 // buildssa builds an SSA function for fn.
 // worker indicates which of the backend workers is doing the processing.
-func buildssa(fn *Node, worker int) *ssa.Func {
-       name := fn.funcname()
+func buildssa(fn *ir.Node, worker int) *ssa.Func {
+       name := ir.FuncName(fn)
        printssa := false
        if ssaDump != "" { // match either a simple name e.g. "(*Reader).Reset", or a package.name e.g. "compress/gzip.(*Reader).Reset"
                printssa = name == ssaDump || base.Ctxt.Pkgpath+"."+name == ssaDump
@@ -297,9 +298,9 @@ func buildssa(fn *Node, worker int) *ssa.Func {
        var astBuf *bytes.Buffer
        if printssa {
                astBuf = &bytes.Buffer{}
-               fdumplist(astBuf, "buildssa-enter", fn.Func.Enter)
-               fdumplist(astBuf, "buildssa-body", fn.Nbody)
-               fdumplist(astBuf, "buildssa-exit", fn.Func.Exit)
+               ir.FDumpList(astBuf, "buildssa-enter", fn.Func.Enter)
+               ir.FDumpList(astBuf, "buildssa-body", fn.Nbody)
+               ir.FDumpList(astBuf, "buildssa-exit", fn.Func.Exit)
                if ssaDumpStdout {
                        fmt.Println("generating SSA for", name)
                        fmt.Print(astBuf.String())
@@ -311,7 +312,7 @@ func buildssa(fn *Node, worker int) *ssa.Func {
        defer s.popLine()
 
        s.hasdefer = fn.Func.HasDefer()
-       if fn.Func.Pragma&CgoUnsafeArgs != 0 {
+       if fn.Func.Pragma&ir.CgoUnsafeArgs != 0 {
                s.cgoUnsafeArgs = true
        }
 
@@ -330,7 +331,7 @@ func buildssa(fn *Node, worker int) *ssa.Func {
        s.f.Name = name
        s.f.DebugTest = s.f.DebugHashMatch("GOSSAHASH")
        s.f.PrintOrHtmlSSA = printssa
-       if fn.Func.Pragma&Nosplit != 0 {
+       if fn.Func.Pragma&ir.Nosplit != 0 {
                s.f.NoSplit = true
        }
        s.panics = map[funcLine]*ssa.Block{}
@@ -355,8 +356,8 @@ func buildssa(fn *Node, worker int) *ssa.Func {
 
        // Allocate starting values
        s.labels = map[string]*ssaLabel{}
-       s.labeledNodes = map[*Node]*ssaLabel{}
-       s.fwdVars = map[*Node]*ssa.Value{}
+       s.labeledNodes = map[*ir.Node]*ssaLabel{}
+       s.fwdVars = map[*ir.Node]*ssa.Value{}
        s.startmem = s.entryNewValue0(ssa.OpInitMem, types.TypeMem)
 
        s.hasOpenDefers = base.Flag.N == 0 && s.hasdefer && !s.curfn.Func.OpenCodedDeferDisallowed()
@@ -376,7 +377,7 @@ func buildssa(fn *Node, worker int) *ssa.Func {
                s.hasOpenDefers = false
        }
        if s.hasOpenDefers &&
-               s.curfn.Func.numReturns*s.curfn.Func.numDefers > 15 {
+               s.curfn.Func.NumReturns*s.curfn.Func.NumDefers > 15 {
                // Since we are generating defer calls at every exit for
                // open-coded defers, skip doing open-coded defers if there are
                // too many returns (especially if there are multiple defers).
@@ -385,8 +386,8 @@ func buildssa(fn *Node, worker int) *ssa.Func {
                s.hasOpenDefers = false
        }
 
-       s.sp = s.entryNewValue0(ssa.OpSP, types.Types[TUINTPTR]) // TODO: use generic pointer type (unsafe.Pointer?) instead
-       s.sb = s.entryNewValue0(ssa.OpSB, types.Types[TUINTPTR])
+       s.sp = s.entryNewValue0(ssa.OpSP, types.Types[types.TUINTPTR]) // TODO: use generic pointer type (unsafe.Pointer?) instead
+       s.sb = s.entryNewValue0(ssa.OpSB, types.Types[types.TUINTPTR])
 
        s.startBlock(s.f.Entry)
        s.vars[memVar] = s.startmem
@@ -394,13 +395,13 @@ func buildssa(fn *Node, worker int) *ssa.Func {
                // Create the deferBits variable and stack slot.  deferBits is a
                // bitmask showing which of the open-coded defers in this function
                // have been activated.
-               deferBitsTemp := tempAt(src.NoXPos, s.curfn, types.Types[TUINT8])
+               deferBitsTemp := tempAt(src.NoXPos, s.curfn, types.Types[types.TUINT8])
                s.deferBitsTemp = deferBitsTemp
                // For this value, AuxInt is initialized to zero by default
-               startDeferBits := s.entryNewValue0(ssa.OpConst8, types.Types[TUINT8])
+               startDeferBits := s.entryNewValue0(ssa.OpConst8, types.Types[types.TUINT8])
                s.vars[deferBitsVar] = startDeferBits
                s.deferBitsAddr = s.addr(deferBitsTemp)
-               s.store(types.Types[TUINT8], s.deferBitsAddr, startDeferBits)
+               s.store(types.Types[types.TUINT8], s.deferBitsAddr, startDeferBits)
                // Make sure that the deferBits stack slot is kept alive (for use
                // by panics) and stores to deferBits are not eliminated, even if
                // all checking code on deferBits in the function exit can be
@@ -410,15 +411,15 @@ func buildssa(fn *Node, worker int) *ssa.Func {
        }
 
        // Generate addresses of local declarations
-       s.decladdrs = map[*Node]*ssa.Value{}
+       s.decladdrs = map[*ir.Node]*ssa.Value{}
        var args []ssa.Param
        var results []ssa.Param
        for _, n := range fn.Func.Dcl {
                switch n.Class() {
-               case PPARAM:
+               case ir.PPARAM:
                        s.decladdrs[n] = s.entryNewValue2A(ssa.OpLocalAddr, types.NewPtr(n.Type), n, s.sp, s.startmem)
                        args = append(args, ssa.Param{Type: n.Type, Offset: int32(n.Xoffset)})
-               case PPARAMOUT:
+               case ir.PPARAMOUT:
                        s.decladdrs[n] = s.entryNewValue2A(ssa.OpLocalAddr, types.NewPtr(n.Type), n, s.sp, s.startmem)
                        results = append(results, ssa.Param{Type: n.Type, Offset: int32(n.Xoffset)})
                        if s.canSSA(n) {
@@ -427,12 +428,12 @@ func buildssa(fn *Node, worker int) *ssa.Func {
                                // the function.
                                s.returns = append(s.returns, n)
                        }
-               case PAUTO:
+               case ir.PAUTO:
                        // processed at each use, to prevent Addr coming
                        // before the decl.
-               case PAUTOHEAP:
+               case ir.PAUTOHEAP:
                        // moved to heap - already handled by frontend
-               case PFUNC:
+               case ir.PFUNC:
                        // local function - already handled by frontend
                default:
                        s.Fatalf("local variable with class %v unimplemented", n.Class())
@@ -441,7 +442,7 @@ func buildssa(fn *Node, worker int) *ssa.Func {
 
        // Populate SSAable arguments.
        for _, n := range fn.Func.Dcl {
-               if n.Class() == PPARAM && s.canSSA(n) {
+               if n.Class() == ir.PPARAM && s.canSSA(n) {
                        v := s.newValue0A(ssa.OpArg, n.Type, n)
                        s.vars[n] = v
                        s.addNamedValue(n, v) // This helps with debugging information, not needed for compilation itself.
@@ -477,7 +478,7 @@ func buildssa(fn *Node, worker int) *ssa.Func {
        return s.f
 }
 
-func dumpSourcesColumn(writer *ssa.HTMLWriter, fn *Node) {
+func dumpSourcesColumn(writer *ssa.HTMLWriter, fn *ir.Node) {
        // Read sources of target function fn.
        fname := base.Ctxt.PosTable.Pos(fn.Pos).Filename()
        targetFn, err := readFuncLines(fname, fn.Pos.Line(), fn.Func.Endlineno.Line())
@@ -565,24 +566,24 @@ func (s *state) updateUnsetPredPos(b *ssa.Block) {
 // Information about each open-coded defer.
 type openDeferInfo struct {
        // The ODEFER node representing the function call of the defer
-       n *Node
+       n *ir.Node
        // If defer call is closure call, the address of the argtmp where the
        // closure is stored.
        closure *ssa.Value
        // The node representing the argtmp where the closure is stored - used for
        // function, method, or interface call, to store a closure that panic
        // processing can use for this defer.
-       closureNode *Node
+       closureNode *ir.Node
        // If defer call is interface call, the address of the argtmp where the
        // receiver is stored
        rcvr *ssa.Value
        // The node representing the argtmp where the receiver is stored
-       rcvrNode *Node
+       rcvrNode *ir.Node
        // The addresses of the argtmps where the evaluated arguments of the defer
        // function call are stored.
        argVals []*ssa.Value
        // The nodes representing the argtmps where the args of the defer are stored
-       argNodes []*Node
+       argNodes []*ir.Node
 }
 
 type state struct {
@@ -593,11 +594,11 @@ type state struct {
        f *ssa.Func
 
        // Node for function
-       curfn *Node
+       curfn *ir.Node
 
        // labels and labeled control flow nodes (OFOR, OFORUNTIL, OSWITCH, OSELECT) in f
        labels       map[string]*ssaLabel
-       labeledNodes map[*Node]*ssaLabel
+       labeledNodes map[*ir.Node]*ssaLabel
 
        // unlabeled break and continue statement tracking
        breakTo    *ssa.Block // current target for plain break statement
@@ -609,18 +610,18 @@ type state struct {
        // variable assignments in the current block (map from variable symbol to ssa value)
        // *Node is the unique identifier (an ONAME Node) for the variable.
        // TODO: keep a single varnum map, then make all of these maps slices instead?
-       vars map[*Node]*ssa.Value
+       vars map[*ir.Node]*ssa.Value
 
        // fwdVars are variables that are used before they are defined in the current block.
        // This map exists just to coalesce multiple references into a single FwdRef op.
        // *Node is the unique identifier (an ONAME Node) for the variable.
-       fwdVars map[*Node]*ssa.Value
+       fwdVars map[*ir.Node]*ssa.Value
 
        // all defined variables at the end of each block. Indexed by block ID.
-       defvars []map[*Node]*ssa.Value
+       defvars []map[*ir.Node]*ssa.Value
 
        // addresses of PPARAM and PPARAMOUT variables.
-       decladdrs map[*Node]*ssa.Value
+       decladdrs map[*ir.Node]*ssa.Value
 
        // starting values. Memory, stack pointer, and globals pointer
        startmem *ssa.Value
@@ -628,7 +629,7 @@ type state struct {
        sb       *ssa.Value
        // value representing address of where deferBits autotmp is stored
        deferBitsAddr *ssa.Value
-       deferBitsTemp *Node
+       deferBitsTemp *ir.Node
 
        // line number stack. The current line number is top of stack
        line []src.XPos
@@ -640,7 +641,7 @@ type state struct {
        panics map[funcLine]*ssa.Block
 
        // list of PPARAMOUT (return) variables.
-       returns []*Node
+       returns []*ir.Node
 
        cgoUnsafeArgs bool
        hasdefer      bool // whether the function contains a defer statement
@@ -692,8 +693,8 @@ func (s *state) Fatalf(msg string, args ...interface{}) {
 func (s *state) Warnl(pos src.XPos, msg string, args ...interface{}) { s.f.Warnl(pos, msg, args...) }
 func (s *state) Debug_checknil() bool                                { return s.f.Frontend().Debug_checknil() }
 
-func ssaMarker(name string) *Node {
-       return newname(&types.Sym{Name: name})
+func ssaMarker(name string) *ir.Node {
+       return NewName(&types.Sym{Name: name})
 }
 
 var (
@@ -716,7 +717,7 @@ func (s *state) startBlock(b *ssa.Block) {
                s.Fatalf("starting block %v when block %v has not ended", b, s.curBlock)
        }
        s.curBlock = b
-       s.vars = map[*Node]*ssa.Value{}
+       s.vars = map[*ir.Node]*ssa.Value{}
        for n := range s.fwdVars {
                delete(s.fwdVars, n)
        }
@@ -920,7 +921,7 @@ func (s *state) constEmptyString(t *types.Type) *ssa.Value {
        return s.f.ConstEmptyString(t)
 }
 func (s *state) constBool(c bool) *ssa.Value {
-       return s.f.ConstBool(types.Types[TBOOL], c)
+       return s.f.ConstBool(types.Types[types.TBOOL], c)
 }
 func (s *state) constInt8(t *types.Type, c int8) *ssa.Value {
        return s.f.ConstInt8(t, c)
@@ -1017,7 +1018,7 @@ func (s *state) instrument(t *types.Type, addr *ssa.Value, wr bool) {
 
        args := []*ssa.Value{addr}
        if needWidth {
-               args = append(args, s.constInt(types.Types[TUINTPTR], w))
+               args = append(args, s.constInt(types.Types[types.TUINTPTR], w))
        }
        s.rtcall(fn, true, nil, args...)
 }
@@ -1051,15 +1052,15 @@ func (s *state) move(t *types.Type, dst, src *ssa.Value) {
 }
 
 // stmtList converts the statement list n to SSA and adds it to s.
-func (s *state) stmtList(l Nodes) {
+func (s *state) stmtList(l ir.Nodes) {
        for _, n := range l.Slice() {
                s.stmt(n)
        }
 }
 
 // stmt converts the statement n to SSA and adds it to s.
-func (s *state) stmt(n *Node) {
-       if !(n.Op == OVARKILL || n.Op == OVARLIVE || n.Op == OVARDEF) {
+func (s *state) stmt(n *ir.Node) {
+       if !(n.Op == ir.OVARKILL || n.Op == ir.OVARLIVE || n.Op == ir.OVARDEF) {
                // OVARKILL, OVARLIVE, and OVARDEF are invisible to the programmer, so we don't use their line numbers to avoid confusion in debugging.
                s.pushLine(n.Pos)
                defer s.popLine()
@@ -1067,30 +1068,30 @@ func (s *state) stmt(n *Node) {
 
        // If s.curBlock is nil, and n isn't a label (which might have an associated goto somewhere),
        // then this code is dead. Stop here.
-       if s.curBlock == nil && n.Op != OLABEL {
+       if s.curBlock == nil && n.Op != ir.OLABEL {
                return
        }
 
        s.stmtList(n.Ninit)
        switch n.Op {
 
-       case OBLOCK:
+       case ir.OBLOCK:
                s.stmtList(n.List)
 
        // No-ops
-       case OEMPTY, ODCLCONST, ODCLTYPE, OFALL:
+       case ir.OEMPTY, ir.ODCLCONST, ir.ODCLTYPE, ir.OFALL:
 
        // Expression statements
-       case OCALLFUNC:
+       case ir.OCALLFUNC:
                if isIntrinsicCall(n) {
                        s.intrinsicCall(n)
                        return
                }
                fallthrough
 
-       case OCALLMETH, OCALLINTER:
+       case ir.OCALLMETH, ir.OCALLINTER:
                s.callResult(n, callNormal)
-               if n.Op == OCALLFUNC && n.Left.Op == ONAME && n.Left.Class() == PFUNC {
+               if n.Op == ir.OCALLFUNC && n.Left.Op == ir.ONAME && n.Left.Class() == ir.PFUNC {
                        if fn := n.Left.Sym.Name; base.Flag.CompilingRuntime && fn == "throw" ||
                                n.Left.Sym.Pkg == Runtimepkg && (fn == "throwinit" || fn == "gopanic" || fn == "panicwrap" || fn == "block" || fn == "panicmakeslicelen" || fn == "panicmakeslicecap") {
                                m := s.mem()
@@ -1102,7 +1103,7 @@ func (s *state) stmt(n *Node) {
                                // go through SSA.
                        }
                }
-       case ODEFER:
+       case ir.ODEFER:
                if base.Debug.Defer > 0 {
                        var defertype string
                        if s.hasOpenDefers {
@@ -1123,10 +1124,10 @@ func (s *state) stmt(n *Node) {
                        }
                        s.callResult(n.Left, d)
                }
-       case OGO:
+       case ir.OGO:
                s.callResult(n.Left, callGo)
 
-       case OAS2DOTTYPE:
+       case ir.OAS2DOTTYPE:
                res, resok := s.dottype(n.Right, true)
                deref := false
                if !canSSAType(n.Right.Type) {
@@ -1147,7 +1148,7 @@ func (s *state) stmt(n *Node) {
                s.assign(n.List.Second(), resok, false, 0)
                return
 
-       case OAS2FUNC:
+       case ir.OAS2FUNC:
                // We come here only when it is an intrinsic call returning two values.
                if !isIntrinsicCall(n.Right) {
                        s.Fatalf("non-intrinsic AS2FUNC not expanded %v", n.Right)
@@ -1159,17 +1160,17 @@ func (s *state) stmt(n *Node) {
                s.assign(n.List.Second(), v2, false, 0)
                return
 
-       case ODCL:
-               if n.Left.Class() == PAUTOHEAP {
+       case ir.ODCL:
+               if n.Left.Class() == ir.PAUTOHEAP {
                        s.Fatalf("DCL %v", n)
                }
 
-       case OLABEL:
+       case ir.OLABEL:
                sym := n.Sym
                lab := s.label(sym)
 
                // Associate label with its control flow node, if any
-               if ctl := n.labeledControl(); ctl != nil {
+               if ctl := labeledControl(n); ctl != nil {
                        s.labeledNodes[ctl] = lab
                }
 
@@ -1186,7 +1187,7 @@ func (s *state) stmt(n *Node) {
                }
                s.startBlock(lab.target)
 
-       case OGOTO:
+       case ir.OGOTO:
                sym := n.Sym
 
                lab := s.label(sym)
@@ -1198,8 +1199,8 @@ func (s *state) stmt(n *Node) {
                b.Pos = s.lastPos.WithIsStmt() // Do this even if b is an empty block.
                b.AddEdgeTo(lab.target)
 
-       case OAS:
-               if n.Left == n.Right && n.Left.Op == ONAME {
+       case ir.OAS:
+               if n.Left == n.Right && n.Left.Op == ir.ONAME {
                        // An x=x assignment. No point in doing anything
                        // here. In addition, skipping this assignment
                        // prevents generating:
@@ -1214,7 +1215,7 @@ func (s *state) stmt(n *Node) {
                rhs := n.Right
                if rhs != nil {
                        switch rhs.Op {
-                       case OSTRUCTLIT, OARRAYLIT, OSLICELIT:
+                       case ir.OSTRUCTLIT, ir.OARRAYLIT, ir.OSLICELIT:
                                // All literals with nonzero fields have already been
                                // rewritten during walk. Any that remain are just T{}
                                // or equivalents. Use the zero value.
@@ -1222,7 +1223,7 @@ func (s *state) stmt(n *Node) {
                                        s.Fatalf("literal with nonzero value in SSA: %v", rhs)
                                }
                                rhs = nil
-                       case OAPPEND:
+                       case ir.OAPPEND:
                                // Check whether we're writing the result of an append back to the same slice.
                                // If so, we handle it specially to avoid write barriers on the fast
                                // (non-growth) path.
@@ -1246,7 +1247,7 @@ func (s *state) stmt(n *Node) {
                        }
                }
 
-               if n.Left.isBlank() {
+               if ir.IsBlank(n.Left) {
                        // _ = rhs
                        // Just evaluate rhs for side-effects.
                        if rhs != nil {
@@ -1279,11 +1280,11 @@ func (s *state) stmt(n *Node) {
                }
 
                var skip skipMask
-               if rhs != nil && (rhs.Op == OSLICE || rhs.Op == OSLICE3 || rhs.Op == OSLICESTR) && samesafeexpr(rhs.Left, n.Left) {
+               if rhs != nil && (rhs.Op == ir.OSLICE || rhs.Op == ir.OSLICE3 || rhs.Op == ir.OSLICESTR) && samesafeexpr(rhs.Left, n.Left) {
                        // We're assigning a slicing operation back to its source.
                        // Don't write back fields we aren't changing. See issue #14855.
                        i, j, k := rhs.SliceBounds()
-                       if i != nil && (i.Op == OLITERAL && i.Val().Kind() == constant.Int && i.Int64Val() == 0) {
+                       if i != nil && (i.Op == ir.OLITERAL && i.Val().Kind() == constant.Int && i.Int64Val() == 0) {
                                // [0:...] is the same as [:...]
                                i = nil
                        }
@@ -1310,8 +1311,8 @@ func (s *state) stmt(n *Node) {
 
                s.assign(n.Left, r, deref, skip)
 
-       case OIF:
-               if Isconst(n.Left, constant.Bool) {
+       case ir.OIF:
+               if ir.IsConst(n.Left, constant.Bool) {
                        s.stmtList(n.Left.Ninit)
                        if n.Left.BoolVal() {
                                s.stmtList(n.Nbody)
@@ -1356,25 +1357,25 @@ func (s *state) stmt(n *Node) {
                }
                s.startBlock(bEnd)
 
-       case ORETURN:
+       case ir.ORETURN:
                s.stmtList(n.List)
                b := s.exit()
                b.Pos = s.lastPos.WithIsStmt()
 
-       case ORETJMP:
+       case ir.ORETJMP:
                s.stmtList(n.List)
                b := s.exit()
                b.Kind = ssa.BlockRetJmp // override BlockRet
                b.Aux = n.Sym.Linksym()
 
-       case OCONTINUE, OBREAK:
+       case ir.OCONTINUE, ir.OBREAK:
                var to *ssa.Block
                if n.Sym == nil {
                        // plain break/continue
                        switch n.Op {
-                       case OCONTINUE:
+                       case ir.OCONTINUE:
                                to = s.continueTo
-                       case OBREAK:
+                       case ir.OBREAK:
                                to = s.breakTo
                        }
                } else {
@@ -1382,9 +1383,9 @@ func (s *state) stmt(n *Node) {
                        sym := n.Sym
                        lab := s.label(sym)
                        switch n.Op {
-                       case OCONTINUE:
+                       case ir.OCONTINUE:
                                to = lab.continueTarget
-                       case OBREAK:
+                       case ir.OBREAK:
                                to = lab.breakTarget
                        }
                }
@@ -1393,7 +1394,7 @@ func (s *state) stmt(n *Node) {
                b.Pos = s.lastPos.WithIsStmt() // Do this even if b is an empty block.
                b.AddEdgeTo(to)
 
-       case OFOR, OFORUNTIL:
+       case ir.OFOR, ir.OFORUNTIL:
                // OFOR: for Ninit; Left; Right { Nbody }
                // cond (Left); body (Nbody); incr (Right)
                //
@@ -1409,7 +1410,7 @@ func (s *state) stmt(n *Node) {
 
                // first, jump to condition test (OFOR) or body (OFORUNTIL)
                b := s.endBlock()
-               if n.Op == OFOR {
+               if n.Op == ir.OFOR {
                        b.AddEdgeTo(bCond)
                        // generate code to test condition
                        s.startBlock(bCond)
@@ -1459,12 +1460,12 @@ func (s *state) stmt(n *Node) {
                if n.Right != nil {
                        s.stmt(n.Right)
                }
-               if n.Op == OFOR {
+               if n.Op == ir.OFOR {
                        if b := s.endBlock(); b != nil {
                                b.AddEdgeTo(bCond)
                                // It can happen that bIncr ends in a block containing only VARKILL,
                                // and that muddles the debugging experience.
-                               if n.Op != OFORUNTIL && b.Pos == src.NoXPos {
+                               if n.Op != ir.OFORUNTIL && b.Pos == src.NoXPos {
                                        b.Pos = bCond.Pos
                                }
                        }
@@ -1481,7 +1482,7 @@ func (s *state) stmt(n *Node) {
 
                s.startBlock(bEnd)
 
-       case OSWITCH, OSELECT:
+       case ir.OSWITCH, ir.OSELECT:
                // These have been mostly rewritten by the front end into their Nbody fields.
                // Our main task is to correctly hook up any break statements.
                bEnd := s.f.NewBlock(ssa.BlockPlain)
@@ -1512,11 +1513,11 @@ func (s *state) stmt(n *Node) {
                }
                s.startBlock(bEnd)
 
-       case OVARDEF:
+       case ir.OVARDEF:
                if !s.canSSA(n.Left) {
                        s.vars[memVar] = s.newValue1Apos(ssa.OpVarDef, types.TypeMem, n.Left, s.mem(), false)
                }
-       case OVARKILL:
+       case ir.OVARKILL:
                // Insert a varkill op to record that a variable is no longer live.
                // We only care about liveness info at call sites, so putting the
                // varkill in the store chain is enough to keep it correctly ordered
@@ -1525,23 +1526,23 @@ func (s *state) stmt(n *Node) {
                        s.vars[memVar] = s.newValue1Apos(ssa.OpVarKill, types.TypeMem, n.Left, s.mem(), false)
                }
 
-       case OVARLIVE:
+       case ir.OVARLIVE:
                // Insert a varlive op to record that a variable is still live.
                if !n.Left.Name.Addrtaken() {
                        s.Fatalf("VARLIVE variable %v must have Addrtaken set", n.Left)
                }
                switch n.Left.Class() {
-               case PAUTO, PPARAM, PPARAMOUT:
+               case ir.PAUTO, ir.PPARAM, ir.PPARAMOUT:
                default:
                        s.Fatalf("VARLIVE variable %v must be Auto or Arg", n.Left)
                }
                s.vars[memVar] = s.newValue1A(ssa.OpVarLive, types.TypeMem, n.Left, s.mem())
 
-       case OCHECKNIL:
+       case ir.OCHECKNIL:
                p := s.expr(n.Left)
                s.nilCheck(p)
 
-       case OINLMARK:
+       case ir.OINLMARK:
                s.newValue1I(ssa.OpInlMark, types.TypeVoid, n.Xoffset, s.mem())
 
        default:
@@ -1600,180 +1601,180 @@ func (s *state) exit() *ssa.Block {
 }
 
 type opAndType struct {
-       op    Op
+       op    ir.Op
        etype types.EType
 }
 
 var opToSSA = map[opAndType]ssa.Op{
-       opAndType{OADD, TINT8}:    ssa.OpAdd8,
-       opAndType{OADD, TUINT8}:   ssa.OpAdd8,
-       opAndType{OADD, TINT16}:   ssa.OpAdd16,
-       opAndType{OADD, TUINT16}:  ssa.OpAdd16,
-       opAndType{OADD, TINT32}:   ssa.OpAdd32,
-       opAndType{OADD, TUINT32}:  ssa.OpAdd32,
-       opAndType{OADD, TINT64}:   ssa.OpAdd64,
-       opAndType{OADD, TUINT64}:  ssa.OpAdd64,
-       opAndType{OADD, TFLOAT32}: ssa.OpAdd32F,
-       opAndType{OADD, TFLOAT64}: ssa.OpAdd64F,
-
-       opAndType{OSUB, TINT8}:    ssa.OpSub8,
-       opAndType{OSUB, TUINT8}:   ssa.OpSub8,
-       opAndType{OSUB, TINT16}:   ssa.OpSub16,
-       opAndType{OSUB, TUINT16}:  ssa.OpSub16,
-       opAndType{OSUB, TINT32}:   ssa.OpSub32,
-       opAndType{OSUB, TUINT32}:  ssa.OpSub32,
-       opAndType{OSUB, TINT64}:   ssa.OpSub64,
-       opAndType{OSUB, TUINT64}:  ssa.OpSub64,
-       opAndType{OSUB, TFLOAT32}: ssa.OpSub32F,
-       opAndType{OSUB, TFLOAT64}: ssa.OpSub64F,
-
-       opAndType{ONOT, TBOOL}: ssa.OpNot,
-
-       opAndType{ONEG, TINT8}:    ssa.OpNeg8,
-       opAndType{ONEG, TUINT8}:   ssa.OpNeg8,
-       opAndType{ONEG, TINT16}:   ssa.OpNeg16,
-       opAndType{ONEG, TUINT16}:  ssa.OpNeg16,
-       opAndType{ONEG, TINT32}:   ssa.OpNeg32,
-       opAndType{ONEG, TUINT32}:  ssa.OpNeg32,
-       opAndType{ONEG, TINT64}:   ssa.OpNeg64,
-       opAndType{ONEG, TUINT64}:  ssa.OpNeg64,
-       opAndType{ONEG, TFLOAT32}: ssa.OpNeg32F,
-       opAndType{ONEG, TFLOAT64}: ssa.OpNeg64F,
-
-       opAndType{OBITNOT, TINT8}:   ssa.OpCom8,
-       opAndType{OBITNOT, TUINT8}:  ssa.OpCom8,
-       opAndType{OBITNOT, TINT16}:  ssa.OpCom16,
-       opAndType{OBITNOT, TUINT16}: ssa.OpCom16,
-       opAndType{OBITNOT, TINT32}:  ssa.OpCom32,
-       opAndType{OBITNOT, TUINT32}: ssa.OpCom32,
-       opAndType{OBITNOT, TINT64}:  ssa.OpCom64,
-       opAndType{OBITNOT, TUINT64}: ssa.OpCom64,
-
-       opAndType{OIMAG, TCOMPLEX64}:  ssa.OpComplexImag,
-       opAndType{OIMAG, TCOMPLEX128}: ssa.OpComplexImag,
-       opAndType{OREAL, TCOMPLEX64}:  ssa.OpComplexReal,
-       opAndType{OREAL, TCOMPLEX128}: ssa.OpComplexReal,
-
-       opAndType{OMUL, TINT8}:    ssa.OpMul8,
-       opAndType{OMUL, TUINT8}:   ssa.OpMul8,
-       opAndType{OMUL, TINT16}:   ssa.OpMul16,
-       opAndType{OMUL, TUINT16}:  ssa.OpMul16,
-       opAndType{OMUL, TINT32}:   ssa.OpMul32,
-       opAndType{OMUL, TUINT32}:  ssa.OpMul32,
-       opAndType{OMUL, TINT64}:   ssa.OpMul64,
-       opAndType{OMUL, TUINT64}:  ssa.OpMul64,
-       opAndType{OMUL, TFLOAT32}: ssa.OpMul32F,
-       opAndType{OMUL, TFLOAT64}: ssa.OpMul64F,
-
-       opAndType{ODIV, TFLOAT32}: ssa.OpDiv32F,
-       opAndType{ODIV, TFLOAT64}: ssa.OpDiv64F,
-
-       opAndType{ODIV, TINT8}:   ssa.OpDiv8,
-       opAndType{ODIV, TUINT8}:  ssa.OpDiv8u,
-       opAndType{ODIV, TINT16}:  ssa.OpDiv16,
-       opAndType{ODIV, TUINT16}: ssa.OpDiv16u,
-       opAndType{ODIV, TINT32}:  ssa.OpDiv32,
-       opAndType{ODIV, TUINT32}: ssa.OpDiv32u,
-       opAndType{ODIV, TINT64}:  ssa.OpDiv64,
-       opAndType{ODIV, TUINT64}: ssa.OpDiv64u,
-
-       opAndType{OMOD, TINT8}:   ssa.OpMod8,
-       opAndType{OMOD, TUINT8}:  ssa.OpMod8u,
-       opAndType{OMOD, TINT16}:  ssa.OpMod16,
-       opAndType{OMOD, TUINT16}: ssa.OpMod16u,
-       opAndType{OMOD, TINT32}:  ssa.OpMod32,
-       opAndType{OMOD, TUINT32}: ssa.OpMod32u,
-       opAndType{OMOD, TINT64}:  ssa.OpMod64,
-       opAndType{OMOD, TUINT64}: ssa.OpMod64u,
-
-       opAndType{OAND, TINT8}:   ssa.OpAnd8,
-       opAndType{OAND, TUINT8}:  ssa.OpAnd8,
-       opAndType{OAND, TINT16}:  ssa.OpAnd16,
-       opAndType{OAND, TUINT16}: ssa.OpAnd16,
-       opAndType{OAND, TINT32}:  ssa.OpAnd32,
-       opAndType{OAND, TUINT32}: ssa.OpAnd32,
-       opAndType{OAND, TINT64}:  ssa.OpAnd64,
-       opAndType{OAND, TUINT64}: ssa.OpAnd64,
-
-       opAndType{OOR, TINT8}:   ssa.OpOr8,
-       opAndType{OOR, TUINT8}:  ssa.OpOr8,
-       opAndType{OOR, TINT16}:  ssa.OpOr16,
-       opAndType{OOR, TUINT16}: ssa.OpOr16,
-       opAndType{OOR, TINT32}:  ssa.OpOr32,
-       opAndType{OOR, TUINT32}: ssa.OpOr32,
-       opAndType{OOR, TINT64}:  ssa.OpOr64,
-       opAndType{OOR, TUINT64}: ssa.OpOr64,
-
-       opAndType{OXOR, TINT8}:   ssa.OpXor8,
-       opAndType{OXOR, TUINT8}:  ssa.OpXor8,
-       opAndType{OXOR, TINT16}:  ssa.OpXor16,
-       opAndType{OXOR, TUINT16}: ssa.OpXor16,
-       opAndType{OXOR, TINT32}:  ssa.OpXor32,
-       opAndType{OXOR, TUINT32}: ssa.OpXor32,
-       opAndType{OXOR, TINT64}:  ssa.OpXor64,
-       opAndType{OXOR, TUINT64}: ssa.OpXor64,
-
-       opAndType{OEQ, TBOOL}:      ssa.OpEqB,
-       opAndType{OEQ, TINT8}:      ssa.OpEq8,
-       opAndType{OEQ, TUINT8}:     ssa.OpEq8,
-       opAndType{OEQ, TINT16}:     ssa.OpEq16,
-       opAndType{OEQ, TUINT16}:    ssa.OpEq16,
-       opAndType{OEQ, TINT32}:     ssa.OpEq32,
-       opAndType{OEQ, TUINT32}:    ssa.OpEq32,
-       opAndType{OEQ, TINT64}:     ssa.OpEq64,
-       opAndType{OEQ, TUINT64}:    ssa.OpEq64,
-       opAndType{OEQ, TINTER}:     ssa.OpEqInter,
-       opAndType{OEQ, TSLICE}:     ssa.OpEqSlice,
-       opAndType{OEQ, TFUNC}:      ssa.OpEqPtr,
-       opAndType{OEQ, TMAP}:       ssa.OpEqPtr,
-       opAndType{OEQ, TCHAN}:      ssa.OpEqPtr,
-       opAndType{OEQ, TPTR}:       ssa.OpEqPtr,
-       opAndType{OEQ, TUINTPTR}:   ssa.OpEqPtr,
-       opAndType{OEQ, TUNSAFEPTR}: ssa.OpEqPtr,
-       opAndType{OEQ, TFLOAT64}:   ssa.OpEq64F,
-       opAndType{OEQ, TFLOAT32}:   ssa.OpEq32F,
-
-       opAndType{ONE, TBOOL}:      ssa.OpNeqB,
-       opAndType{ONE, TINT8}:      ssa.OpNeq8,
-       opAndType{ONE, TUINT8}:     ssa.OpNeq8,
-       opAndType{ONE, TINT16}:     ssa.OpNeq16,
-       opAndType{ONE, TUINT16}:    ssa.OpNeq16,
-       opAndType{ONE, TINT32}:     ssa.OpNeq32,
-       opAndType{ONE, TUINT32}:    ssa.OpNeq32,
-       opAndType{ONE, TINT64}:     ssa.OpNeq64,
-       opAndType{ONE, TUINT64}:    ssa.OpNeq64,
-       opAndType{ONE, TINTER}:     ssa.OpNeqInter,
-       opAndType{ONE, TSLICE}:     ssa.OpNeqSlice,
-       opAndType{ONE, TFUNC}:      ssa.OpNeqPtr,
-       opAndType{ONE, TMAP}:       ssa.OpNeqPtr,
-       opAndType{ONE, TCHAN}:      ssa.OpNeqPtr,
-       opAndType{ONE, TPTR}:       ssa.OpNeqPtr,
-       opAndType{ONE, TUINTPTR}:   ssa.OpNeqPtr,
-       opAndType{ONE, TUNSAFEPTR}: ssa.OpNeqPtr,
-       opAndType{ONE, TFLOAT64}:   ssa.OpNeq64F,
-       opAndType{ONE, TFLOAT32}:   ssa.OpNeq32F,
-
-       opAndType{OLT, TINT8}:    ssa.OpLess8,
-       opAndType{OLT, TUINT8}:   ssa.OpLess8U,
-       opAndType{OLT, TINT16}:   ssa.OpLess16,
-       opAndType{OLT, TUINT16}:  ssa.OpLess16U,
-       opAndType{OLT, TINT32}:   ssa.OpLess32,
-       opAndType{OLT, TUINT32}:  ssa.OpLess32U,
-       opAndType{OLT, TINT64}:   ssa.OpLess64,
-       opAndType{OLT, TUINT64}:  ssa.OpLess64U,
-       opAndType{OLT, TFLOAT64}: ssa.OpLess64F,
-       opAndType{OLT, TFLOAT32}: ssa.OpLess32F,
-
-       opAndType{OLE, TINT8}:    ssa.OpLeq8,
-       opAndType{OLE, TUINT8}:   ssa.OpLeq8U,
-       opAndType{OLE, TINT16}:   ssa.OpLeq16,
-       opAndType{OLE, TUINT16}:  ssa.OpLeq16U,
-       opAndType{OLE, TINT32}:   ssa.OpLeq32,
-       opAndType{OLE, TUINT32}:  ssa.OpLeq32U,
-       opAndType{OLE, TINT64}:   ssa.OpLeq64,
-       opAndType{OLE, TUINT64}:  ssa.OpLeq64U,
-       opAndType{OLE, TFLOAT64}: ssa.OpLeq64F,
-       opAndType{OLE, TFLOAT32}: ssa.OpLeq32F,
+       opAndType{ir.OADD, types.TINT8}:    ssa.OpAdd8,
+       opAndType{ir.OADD, types.TUINT8}:   ssa.OpAdd8,
+       opAndType{ir.OADD, types.TINT16}:   ssa.OpAdd16,
+       opAndType{ir.OADD, types.TUINT16}:  ssa.OpAdd16,
+       opAndType{ir.OADD, types.TINT32}:   ssa.OpAdd32,
+       opAndType{ir.OADD, types.TUINT32}:  ssa.OpAdd32,
+       opAndType{ir.OADD, types.TINT64}:   ssa.OpAdd64,
+       opAndType{ir.OADD, types.TUINT64}:  ssa.OpAdd64,
+       opAndType{ir.OADD, types.TFLOAT32}: ssa.OpAdd32F,
+       opAndType{ir.OADD, types.TFLOAT64}: ssa.OpAdd64F,
+
+       opAndType{ir.OSUB, types.TINT8}:    ssa.OpSub8,
+       opAndType{ir.OSUB, types.TUINT8}:   ssa.OpSub8,
+       opAndType{ir.OSUB, types.TINT16}:   ssa.OpSub16,
+       opAndType{ir.OSUB, types.TUINT16}:  ssa.OpSub16,
+       opAndType{ir.OSUB, types.TINT32}:   ssa.OpSub32,
+       opAndType{ir.OSUB, types.TUINT32}:  ssa.OpSub32,
+       opAndType{ir.OSUB, types.TINT64}:   ssa.OpSub64,
+       opAndType{ir.OSUB, types.TUINT64}:  ssa.OpSub64,
+       opAndType{ir.OSUB, types.TFLOAT32}: ssa.OpSub32F,
+       opAndType{ir.OSUB, types.TFLOAT64}: ssa.OpSub64F,
+
+       opAndType{ir.ONOT, types.TBOOL}: ssa.OpNot,
+
+       opAndType{ir.ONEG, types.TINT8}:    ssa.OpNeg8,
+       opAndType{ir.ONEG, types.TUINT8}:   ssa.OpNeg8,
+       opAndType{ir.ONEG, types.TINT16}:   ssa.OpNeg16,
+       opAndType{ir.ONEG, types.TUINT16}:  ssa.OpNeg16,
+       opAndType{ir.ONEG, types.TINT32}:   ssa.OpNeg32,
+       opAndType{ir.ONEG, types.TUINT32}:  ssa.OpNeg32,
+       opAndType{ir.ONEG, types.TINT64}:   ssa.OpNeg64,
+       opAndType{ir.ONEG, types.TUINT64}:  ssa.OpNeg64,
+       opAndType{ir.ONEG, types.TFLOAT32}: ssa.OpNeg32F,
+       opAndType{ir.ONEG, types.TFLOAT64}: ssa.OpNeg64F,
+
+       opAndType{ir.OBITNOT, types.TINT8}:   ssa.OpCom8,
+       opAndType{ir.OBITNOT, types.TUINT8}:  ssa.OpCom8,
+       opAndType{ir.OBITNOT, types.TINT16}:  ssa.OpCom16,
+       opAndType{ir.OBITNOT, types.TUINT16}: ssa.OpCom16,
+       opAndType{ir.OBITNOT, types.TINT32}:  ssa.OpCom32,
+       opAndType{ir.OBITNOT, types.TUINT32}: ssa.OpCom32,
+       opAndType{ir.OBITNOT, types.TINT64}:  ssa.OpCom64,
+       opAndType{ir.OBITNOT, types.TUINT64}: ssa.OpCom64,
+
+       opAndType{ir.OIMAG, types.TCOMPLEX64}:  ssa.OpComplexImag,
+       opAndType{ir.OIMAG, types.TCOMPLEX128}: ssa.OpComplexImag,
+       opAndType{ir.OREAL, types.TCOMPLEX64}:  ssa.OpComplexReal,
+       opAndType{ir.OREAL, types.TCOMPLEX128}: ssa.OpComplexReal,
+
+       opAndType{ir.OMUL, types.TINT8}:    ssa.OpMul8,
+       opAndType{ir.OMUL, types.TUINT8}:   ssa.OpMul8,
+       opAndType{ir.OMUL, types.TINT16}:   ssa.OpMul16,
+       opAndType{ir.OMUL, types.TUINT16}:  ssa.OpMul16,
+       opAndType{ir.OMUL, types.TINT32}:   ssa.OpMul32,
+       opAndType{ir.OMUL, types.TUINT32}:  ssa.OpMul32,
+       opAndType{ir.OMUL, types.TINT64}:   ssa.OpMul64,
+       opAndType{ir.OMUL, types.TUINT64}:  ssa.OpMul64,
+       opAndType{ir.OMUL, types.TFLOAT32}: ssa.OpMul32F,
+       opAndType{ir.OMUL, types.TFLOAT64}: ssa.OpMul64F,
+
+       opAndType{ir.ODIV, types.TFLOAT32}: ssa.OpDiv32F,
+       opAndType{ir.ODIV, types.TFLOAT64}: ssa.OpDiv64F,
+
+       opAndType{ir.ODIV, types.TINT8}:   ssa.OpDiv8,
+       opAndType{ir.ODIV, types.TUINT8}:  ssa.OpDiv8u,
+       opAndType{ir.ODIV, types.TINT16}:  ssa.OpDiv16,
+       opAndType{ir.ODIV, types.TUINT16}: ssa.OpDiv16u,
+       opAndType{ir.ODIV, types.TINT32}:  ssa.OpDiv32,
+       opAndType{ir.ODIV, types.TUINT32}: ssa.OpDiv32u,
+       opAndType{ir.ODIV, types.TINT64}:  ssa.OpDiv64,
+       opAndType{ir.ODIV, types.TUINT64}: ssa.OpDiv64u,
+
+       opAndType{ir.OMOD, types.TINT8}:   ssa.OpMod8,
+       opAndType{ir.OMOD, types.TUINT8}:  ssa.OpMod8u,
+       opAndType{ir.OMOD, types.TINT16}:  ssa.OpMod16,
+       opAndType{ir.OMOD, types.TUINT16}: ssa.OpMod16u,
+       opAndType{ir.OMOD, types.TINT32}:  ssa.OpMod32,
+       opAndType{ir.OMOD, types.TUINT32}: ssa.OpMod32u,
+       opAndType{ir.OMOD, types.TINT64}:  ssa.OpMod64,
+       opAndType{ir.OMOD, types.TUINT64}: ssa.OpMod64u,
+
+       opAndType{ir.OAND, types.TINT8}:   ssa.OpAnd8,
+       opAndType{ir.OAND, types.TUINT8}:  ssa.OpAnd8,
+       opAndType{ir.OAND, types.TINT16}:  ssa.OpAnd16,
+       opAndType{ir.OAND, types.TUINT16}: ssa.OpAnd16,
+       opAndType{ir.OAND, types.TINT32}:  ssa.OpAnd32,
+       opAndType{ir.OAND, types.TUINT32}: ssa.OpAnd32,
+       opAndType{ir.OAND, types.TINT64}:  ssa.OpAnd64,
+       opAndType{ir.OAND, types.TUINT64}: ssa.OpAnd64,
+
+       opAndType{ir.OOR, types.TINT8}:   ssa.OpOr8,
+       opAndType{ir.OOR, types.TUINT8}:  ssa.OpOr8,
+       opAndType{ir.OOR, types.TINT16}:  ssa.OpOr16,
+       opAndType{ir.OOR, types.TUINT16}: ssa.OpOr16,
+       opAndType{ir.OOR, types.TINT32}:  ssa.OpOr32,
+       opAndType{ir.OOR, types.TUINT32}: ssa.OpOr32,
+       opAndType{ir.OOR, types.TINT64}:  ssa.OpOr64,
+       opAndType{ir.OOR, types.TUINT64}: ssa.OpOr64,
+
+       opAndType{ir.OXOR, types.TINT8}:   ssa.OpXor8,
+       opAndType{ir.OXOR, types.TUINT8}:  ssa.OpXor8,
+       opAndType{ir.OXOR, types.TINT16}:  ssa.OpXor16,
+       opAndType{ir.OXOR, types.TUINT16}: ssa.OpXor16,
+       opAndType{ir.OXOR, types.TINT32}:  ssa.OpXor32,
+       opAndType{ir.OXOR, types.TUINT32}: ssa.OpXor32,
+       opAndType{ir.OXOR, types.TINT64}:  ssa.OpXor64,
+       opAndType{ir.OXOR, types.TUINT64}: ssa.OpXor64,
+
+       opAndType{ir.OEQ, types.TBOOL}:      ssa.OpEqB,
+       opAndType{ir.OEQ, types.TINT8}:      ssa.OpEq8,
+       opAndType{ir.OEQ, types.TUINT8}:     ssa.OpEq8,
+       opAndType{ir.OEQ, types.TINT16}:     ssa.OpEq16,
+       opAndType{ir.OEQ, types.TUINT16}:    ssa.OpEq16,
+       opAndType{ir.OEQ, types.TINT32}:     ssa.OpEq32,
+       opAndType{ir.OEQ, types.TUINT32}:    ssa.OpEq32,
+       opAndType{ir.OEQ, types.TINT64}:     ssa.OpEq64,
+       opAndType{ir.OEQ, types.TUINT64}:    ssa.OpEq64,
+       opAndType{ir.OEQ, types.TINTER}:     ssa.OpEqInter,
+       opAndType{ir.OEQ, types.TSLICE}:     ssa.OpEqSlice,
+       opAndType{ir.OEQ, types.TFUNC}:      ssa.OpEqPtr,
+       opAndType{ir.OEQ, types.TMAP}:       ssa.OpEqPtr,
+       opAndType{ir.OEQ, types.TCHAN}:      ssa.OpEqPtr,
+       opAndType{ir.OEQ, types.TPTR}:       ssa.OpEqPtr,
+       opAndType{ir.OEQ, types.TUINTPTR}:   ssa.OpEqPtr,
+       opAndType{ir.OEQ, types.TUNSAFEPTR}: ssa.OpEqPtr,
+       opAndType{ir.OEQ, types.TFLOAT64}:   ssa.OpEq64F,
+       opAndType{ir.OEQ, types.TFLOAT32}:   ssa.OpEq32F,
+
+       opAndType{ir.ONE, types.TBOOL}:      ssa.OpNeqB,
+       opAndType{ir.ONE, types.TINT8}:      ssa.OpNeq8,
+       opAndType{ir.ONE, types.TUINT8}:     ssa.OpNeq8,
+       opAndType{ir.ONE, types.TINT16}:     ssa.OpNeq16,
+       opAndType{ir.ONE, types.TUINT16}:    ssa.OpNeq16,
+       opAndType{ir.ONE, types.TINT32}:     ssa.OpNeq32,
+       opAndType{ir.ONE, types.TUINT32}:    ssa.OpNeq32,
+       opAndType{ir.ONE, types.TINT64}:     ssa.OpNeq64,
+       opAndType{ir.ONE, types.TUINT64}:    ssa.OpNeq64,
+       opAndType{ir.ONE, types.TINTER}:     ssa.OpNeqInter,
+       opAndType{ir.ONE, types.TSLICE}:     ssa.OpNeqSlice,
+       opAndType{ir.ONE, types.TFUNC}:      ssa.OpNeqPtr,
+       opAndType{ir.ONE, types.TMAP}:       ssa.OpNeqPtr,
+       opAndType{ir.ONE, types.TCHAN}:      ssa.OpNeqPtr,
+       opAndType{ir.ONE, types.TPTR}:       ssa.OpNeqPtr,
+       opAndType{ir.ONE, types.TUINTPTR}:   ssa.OpNeqPtr,
+       opAndType{ir.ONE, types.TUNSAFEPTR}: ssa.OpNeqPtr,
+       opAndType{ir.ONE, types.TFLOAT64}:   ssa.OpNeq64F,
+       opAndType{ir.ONE, types.TFLOAT32}:   ssa.OpNeq32F,
+
+       opAndType{ir.OLT, types.TINT8}:    ssa.OpLess8,
+       opAndType{ir.OLT, types.TUINT8}:   ssa.OpLess8U,
+       opAndType{ir.OLT, types.TINT16}:   ssa.OpLess16,
+       opAndType{ir.OLT, types.TUINT16}:  ssa.OpLess16U,
+       opAndType{ir.OLT, types.TINT32}:   ssa.OpLess32,
+       opAndType{ir.OLT, types.TUINT32}:  ssa.OpLess32U,
+       opAndType{ir.OLT, types.TINT64}:   ssa.OpLess64,
+       opAndType{ir.OLT, types.TUINT64}:  ssa.OpLess64U,
+       opAndType{ir.OLT, types.TFLOAT64}: ssa.OpLess64F,
+       opAndType{ir.OLT, types.TFLOAT32}: ssa.OpLess32F,
+
+       opAndType{ir.OLE, types.TINT8}:    ssa.OpLeq8,
+       opAndType{ir.OLE, types.TUINT8}:   ssa.OpLeq8U,
+       opAndType{ir.OLE, types.TINT16}:   ssa.OpLeq16,
+       opAndType{ir.OLE, types.TUINT16}:  ssa.OpLeq16U,
+       opAndType{ir.OLE, types.TINT32}:   ssa.OpLeq32,
+       opAndType{ir.OLE, types.TUINT32}:  ssa.OpLeq32U,
+       opAndType{ir.OLE, types.TINT64}:   ssa.OpLeq64,
+       opAndType{ir.OLE, types.TUINT64}:  ssa.OpLeq64U,
+       opAndType{ir.OLE, types.TFLOAT64}: ssa.OpLeq64F,
+       opAndType{ir.OLE, types.TFLOAT32}: ssa.OpLeq32F,
 }
 
 func (s *state) concreteEtype(t *types.Type) types.EType {
@@ -1781,25 +1782,25 @@ func (s *state) concreteEtype(t *types.Type) types.EType {
        switch e {
        default:
                return e
-       case TINT:
+       case types.TINT:
                if s.config.PtrSize == 8 {
-                       return TINT64
+                       return types.TINT64
                }
-               return TINT32
-       case TUINT:
+               return types.TINT32
+       case types.TUINT:
                if s.config.PtrSize == 8 {
-                       return TUINT64
+                       return types.TUINT64
                }
-               return TUINT32
-       case TUINTPTR:
+               return types.TUINT32
+       case types.TUINTPTR:
                if s.config.PtrSize == 8 {
-                       return TUINT64
+                       return types.TUINT64
                }
-               return TUINT32
+               return types.TUINT32
        }
 }
 
-func (s *state) ssaOp(op Op, t *types.Type) ssa.Op {
+func (s *state) ssaOp(op ir.Op, t *types.Type) ssa.Op {
        etype := s.concreteEtype(t)
        x, ok := opToSSA[opAndType{op, etype}]
        if !ok {
@@ -1810,10 +1811,10 @@ func (s *state) ssaOp(op Op, t *types.Type) ssa.Op {
 
 func floatForComplex(t *types.Type) *types.Type {
        switch t.Etype {
-       case TCOMPLEX64:
-               return types.Types[TFLOAT32]
-       case TCOMPLEX128:
-               return types.Types[TFLOAT64]
+       case types.TCOMPLEX64:
+               return types.Types[types.TFLOAT32]
+       case types.TCOMPLEX128:
+               return types.Types[types.TFLOAT64]
        }
        base.Fatalf("unexpected type: %v", t)
        return nil
@@ -1821,17 +1822,17 @@ func floatForComplex(t *types.Type) *types.Type {
 
 func complexForFloat(t *types.Type) *types.Type {
        switch t.Etype {
-       case TFLOAT32:
-               return types.Types[TCOMPLEX64]
-       case TFLOAT64:
-               return types.Types[TCOMPLEX128]
+       case types.TFLOAT32:
+               return types.Types[types.TCOMPLEX64]
+       case types.TFLOAT64:
+               return types.Types[types.TCOMPLEX128]
        }
        base.Fatalf("unexpected type: %v", t)
        return nil
 }
 
 type opAndTwoTypes struct {
-       op     Op
+       op     ir.Op
        etype1 types.EType
        etype2 types.EType
 }
@@ -1849,145 +1850,145 @@ type twoOpsAndType struct {
 
 var fpConvOpToSSA = map[twoTypes]twoOpsAndType{
 
-       twoTypes{TINT8, TFLOAT32}:  twoOpsAndType{ssa.OpSignExt8to32, ssa.OpCvt32to32F, TINT32},
-       twoTypes{TINT16, TFLOAT32}: twoOpsAndType{ssa.OpSignExt16to32, ssa.OpCvt32to32F, TINT32},
-       twoTypes{TINT32, TFLOAT32}: twoOpsAndType{ssa.OpCopy, ssa.OpCvt32to32F, TINT32},
-       twoTypes{TINT64, TFLOAT32}: twoOpsAndType{ssa.OpCopy, ssa.OpCvt64to32F, TINT64},
-
-       twoTypes{TINT8, TFLOAT64}:  twoOpsAndType{ssa.OpSignExt8to32, ssa.OpCvt32to64F, TINT32},
-       twoTypes{TINT16, TFLOAT64}: twoOpsAndType{ssa.OpSignExt16to32, ssa.OpCvt32to64F, TINT32},
-       twoTypes{TINT32, TFLOAT64}: twoOpsAndType{ssa.OpCopy, ssa.OpCvt32to64F, TINT32},
-       twoTypes{TINT64, TFLOAT64}: twoOpsAndType{ssa.OpCopy, ssa.OpCvt64to64F, TINT64},
-
-       twoTypes{TFLOAT32, TINT8}:  twoOpsAndType{ssa.OpCvt32Fto32, ssa.OpTrunc32to8, TINT32},
-       twoTypes{TFLOAT32, TINT16}: twoOpsAndType{ssa.OpCvt32Fto32, ssa.OpTrunc32to16, TINT32},
-       twoTypes{TFLOAT32, TINT32}: twoOpsAndType{ssa.OpCvt32Fto32, ssa.OpCopy, TINT32},
-       twoTypes{TFLOAT32, TINT64}: twoOpsAndType{ssa.OpCvt32Fto64, ssa.OpCopy, TINT64},
-
-       twoTypes{TFLOAT64, TINT8}:  twoOpsAndType{ssa.OpCvt64Fto32, ssa.OpTrunc32to8, TINT32},
-       twoTypes{TFLOAT64, TINT16}: twoOpsAndType{ssa.OpCvt64Fto32, ssa.OpTrunc32to16, TINT32},
-       twoTypes{TFLOAT64, TINT32}: twoOpsAndType{ssa.OpCvt64Fto32, ssa.OpCopy, TINT32},
-       twoTypes{TFLOAT64, TINT64}: twoOpsAndType{ssa.OpCvt64Fto64, ssa.OpCopy, TINT64},
+       twoTypes{types.TINT8, types.TFLOAT32}:  twoOpsAndType{ssa.OpSignExt8to32, ssa.OpCvt32to32F, types.TINT32},
+       twoTypes{types.TINT16, types.TFLOAT32}: twoOpsAndType{ssa.OpSignExt16to32, ssa.OpCvt32to32F, types.TINT32},
+       twoTypes{types.TINT32, types.TFLOAT32}: twoOpsAndType{ssa.OpCopy, ssa.OpCvt32to32F, types.TINT32},
+       twoTypes{types.TINT64, types.TFLOAT32}: twoOpsAndType{ssa.OpCopy, ssa.OpCvt64to32F, types.TINT64},
+
+       twoTypes{types.TINT8, types.TFLOAT64}:  twoOpsAndType{ssa.OpSignExt8to32, ssa.OpCvt32to64F, types.TINT32},
+       twoTypes{types.TINT16, types.TFLOAT64}: twoOpsAndType{ssa.OpSignExt16to32, ssa.OpCvt32to64F, types.TINT32},
+       twoTypes{types.TINT32, types.TFLOAT64}: twoOpsAndType{ssa.OpCopy, ssa.OpCvt32to64F, types.TINT32},
+       twoTypes{types.TINT64, types.TFLOAT64}: twoOpsAndType{ssa.OpCopy, ssa.OpCvt64to64F, types.TINT64},
+
+       twoTypes{types.TFLOAT32, types.TINT8}:  twoOpsAndType{ssa.OpCvt32Fto32, ssa.OpTrunc32to8, types.TINT32},
+       twoTypes{types.TFLOAT32, types.TINT16}: twoOpsAndType{ssa.OpCvt32Fto32, ssa.OpTrunc32to16, types.TINT32},
+       twoTypes{types.TFLOAT32, types.TINT32}: twoOpsAndType{ssa.OpCvt32Fto32, ssa.OpCopy, types.TINT32},
+       twoTypes{types.TFLOAT32, types.TINT64}: twoOpsAndType{ssa.OpCvt32Fto64, ssa.OpCopy, types.TINT64},
+
+       twoTypes{types.TFLOAT64, types.TINT8}:  twoOpsAndType{ssa.OpCvt64Fto32, ssa.OpTrunc32to8, types.TINT32},
+       twoTypes{types.TFLOAT64, types.TINT16}: twoOpsAndType{ssa.OpCvt64Fto32, ssa.OpTrunc32to16, types.TINT32},
+       twoTypes{types.TFLOAT64, types.TINT32}: twoOpsAndType{ssa.OpCvt64Fto32, ssa.OpCopy, types.TINT32},
+       twoTypes{types.TFLOAT64, types.TINT64}: twoOpsAndType{ssa.OpCvt64Fto64, ssa.OpCopy, types.TINT64},
        // unsigned
-       twoTypes{TUINT8, TFLOAT32}:  twoOpsAndType{ssa.OpZeroExt8to32, ssa.OpCvt32to32F, TINT32},
-       twoTypes{TUINT16, TFLOAT32}: twoOpsAndType{ssa.OpZeroExt16to32, ssa.OpCvt32to32F, TINT32},
-       twoTypes{TUINT32, TFLOAT32}: twoOpsAndType{ssa.OpZeroExt32to64, ssa.OpCvt64to32F, TINT64}, // go wide to dodge unsigned
-       twoTypes{TUINT64, TFLOAT32}: twoOpsAndType{ssa.OpCopy, ssa.OpInvalid, TUINT64},            // Cvt64Uto32F, branchy code expansion instead
-
-       twoTypes{TUINT8, TFLOAT64}:  twoOpsAndType{ssa.OpZeroExt8to32, ssa.OpCvt32to64F, TINT32},
-       twoTypes{TUINT16, TFLOAT64}: twoOpsAndType{ssa.OpZeroExt16to32, ssa.OpCvt32to64F, TINT32},
-       twoTypes{TUINT32, TFLOAT64}: twoOpsAndType{ssa.OpZeroExt32to64, ssa.OpCvt64to64F, TINT64}, // go wide to dodge unsigned
-       twoTypes{TUINT64, TFLOAT64}: twoOpsAndType{ssa.OpCopy, ssa.OpInvalid, TUINT64},            // Cvt64Uto64F, branchy code expansion instead
-
-       twoTypes{TFLOAT32, TUINT8}:  twoOpsAndType{ssa.OpCvt32Fto32, ssa.OpTrunc32to8, TINT32},
-       twoTypes{TFLOAT32, TUINT16}: twoOpsAndType{ssa.OpCvt32Fto32, ssa.OpTrunc32to16, TINT32},
-       twoTypes{TFLOAT32, TUINT32}: twoOpsAndType{ssa.OpCvt32Fto64, ssa.OpTrunc64to32, TINT64}, // go wide to dodge unsigned
-       twoTypes{TFLOAT32, TUINT64}: twoOpsAndType{ssa.OpInvalid, ssa.OpCopy, TUINT64},          // Cvt32Fto64U, branchy code expansion instead
-
-       twoTypes{TFLOAT64, TUINT8}:  twoOpsAndType{ssa.OpCvt64Fto32, ssa.OpTrunc32to8, TINT32},
-       twoTypes{TFLOAT64, TUINT16}: twoOpsAndType{ssa.OpCvt64Fto32, ssa.OpTrunc32to16, TINT32},
-       twoTypes{TFLOAT64, TUINT32}: twoOpsAndType{ssa.OpCvt64Fto64, ssa.OpTrunc64to32, TINT64}, // go wide to dodge unsigned
-       twoTypes{TFLOAT64, TUINT64}: twoOpsAndType{ssa.OpInvalid, ssa.OpCopy, TUINT64},          // Cvt64Fto64U, branchy code expansion instead
+       twoTypes{types.TUINT8, types.TFLOAT32}:  twoOpsAndType{ssa.OpZeroExt8to32, ssa.OpCvt32to32F, types.TINT32},
+       twoTypes{types.TUINT16, types.TFLOAT32}: twoOpsAndType{ssa.OpZeroExt16to32, ssa.OpCvt32to32F, types.TINT32},
+       twoTypes{types.TUINT32, types.TFLOAT32}: twoOpsAndType{ssa.OpZeroExt32to64, ssa.OpCvt64to32F, types.TINT64}, // go wide to dodge unsigned
+       twoTypes{types.TUINT64, types.TFLOAT32}: twoOpsAndType{ssa.OpCopy, ssa.OpInvalid, types.TUINT64},            // Cvt64Uto32F, branchy code expansion instead
+
+       twoTypes{types.TUINT8, types.TFLOAT64}:  twoOpsAndType{ssa.OpZeroExt8to32, ssa.OpCvt32to64F, types.TINT32},
+       twoTypes{types.TUINT16, types.TFLOAT64}: twoOpsAndType{ssa.OpZeroExt16to32, ssa.OpCvt32to64F, types.TINT32},
+       twoTypes{types.TUINT32, types.TFLOAT64}: twoOpsAndType{ssa.OpZeroExt32to64, ssa.OpCvt64to64F, types.TINT64}, // go wide to dodge unsigned
+       twoTypes{types.TUINT64, types.TFLOAT64}: twoOpsAndType{ssa.OpCopy, ssa.OpInvalid, types.TUINT64},            // Cvt64Uto64F, branchy code expansion instead
+
+       twoTypes{types.TFLOAT32, types.TUINT8}:  twoOpsAndType{ssa.OpCvt32Fto32, ssa.OpTrunc32to8, types.TINT32},
+       twoTypes{types.TFLOAT32, types.TUINT16}: twoOpsAndType{ssa.OpCvt32Fto32, ssa.OpTrunc32to16, types.TINT32},
+       twoTypes{types.TFLOAT32, types.TUINT32}: twoOpsAndType{ssa.OpCvt32Fto64, ssa.OpTrunc64to32, types.TINT64}, // go wide to dodge unsigned
+       twoTypes{types.TFLOAT32, types.TUINT64}: twoOpsAndType{ssa.OpInvalid, ssa.OpCopy, types.TUINT64},          // Cvt32Fto64U, branchy code expansion instead
+
+       twoTypes{types.TFLOAT64, types.TUINT8}:  twoOpsAndType{ssa.OpCvt64Fto32, ssa.OpTrunc32to8, types.TINT32},
+       twoTypes{types.TFLOAT64, types.TUINT16}: twoOpsAndType{ssa.OpCvt64Fto32, ssa.OpTrunc32to16, types.TINT32},
+       twoTypes{types.TFLOAT64, types.TUINT32}: twoOpsAndType{ssa.OpCvt64Fto64, ssa.OpTrunc64to32, types.TINT64}, // go wide to dodge unsigned
+       twoTypes{types.TFLOAT64, types.TUINT64}: twoOpsAndType{ssa.OpInvalid, ssa.OpCopy, types.TUINT64},          // Cvt64Fto64U, branchy code expansion instead
 
        // float
-       twoTypes{TFLOAT64, TFLOAT32}: twoOpsAndType{ssa.OpCvt64Fto32F, ssa.OpCopy, TFLOAT32},
-       twoTypes{TFLOAT64, TFLOAT64}: twoOpsAndType{ssa.OpRound64F, ssa.OpCopy, TFLOAT64},
-       twoTypes{TFLOAT32, TFLOAT32}: twoOpsAndType{ssa.OpRound32F, ssa.OpCopy, TFLOAT32},
-       twoTypes{TFLOAT32, TFLOAT64}: twoOpsAndType{ssa.OpCvt32Fto64F, ssa.OpCopy, TFLOAT64},
+       twoTypes{types.TFLOAT64, types.TFLOAT32}: twoOpsAndType{ssa.OpCvt64Fto32F, ssa.OpCopy, types.TFLOAT32},
+       twoTypes{types.TFLOAT64, types.TFLOAT64}: twoOpsAndType{ssa.OpRound64F, ssa.OpCopy, types.TFLOAT64},
+       twoTypes{types.TFLOAT32, types.TFLOAT32}: twoOpsAndType{ssa.OpRound32F, ssa.OpCopy, types.TFLOAT32},
+       twoTypes{types.TFLOAT32, types.TFLOAT64}: twoOpsAndType{ssa.OpCvt32Fto64F, ssa.OpCopy, types.TFLOAT64},
 }
 
 // this map is used only for 32-bit arch, and only includes the difference
 // on 32-bit arch, don't use int64<->float conversion for uint32
 var fpConvOpToSSA32 = map[twoTypes]twoOpsAndType{
-       twoTypes{TUINT32, TFLOAT32}: twoOpsAndType{ssa.OpCopy, ssa.OpCvt32Uto32F, TUINT32},
-       twoTypes{TUINT32, TFLOAT64}: twoOpsAndType{ssa.OpCopy, ssa.OpCvt32Uto64F, TUINT32},
-       twoTypes{TFLOAT32, TUINT32}: twoOpsAndType{ssa.OpCvt32Fto32U, ssa.OpCopy, TUINT32},
-       twoTypes{TFLOAT64, TUINT32}: twoOpsAndType{ssa.OpCvt64Fto32U, ssa.OpCopy, TUINT32},
+       twoTypes{types.TUINT32, types.TFLOAT32}: twoOpsAndType{ssa.OpCopy, ssa.OpCvt32Uto32F, types.TUINT32},
+       twoTypes{types.TUINT32, types.TFLOAT64}: twoOpsAndType{ssa.OpCopy, ssa.OpCvt32Uto64F, types.TUINT32},
+       twoTypes{types.TFLOAT32, types.TUINT32}: twoOpsAndType{ssa.OpCvt32Fto32U, ssa.OpCopy, types.TUINT32},
+       twoTypes{types.TFLOAT64, types.TUINT32}: twoOpsAndType{ssa.OpCvt64Fto32U, ssa.OpCopy, types.TUINT32},
 }
 
 // uint64<->float conversions, only on machines that have instructions for that
 var uint64fpConvOpToSSA = map[twoTypes]twoOpsAndType{
-       twoTypes{TUINT64, TFLOAT32}: twoOpsAndType{ssa.OpCopy, ssa.OpCvt64Uto32F, TUINT64},
-       twoTypes{TUINT64, TFLOAT64}: twoOpsAndType{ssa.OpCopy, ssa.OpCvt64Uto64F, TUINT64},
-       twoTypes{TFLOAT32, TUINT64}: twoOpsAndType{ssa.OpCvt32Fto64U, ssa.OpCopy, TUINT64},
-       twoTypes{TFLOAT64, TUINT64}: twoOpsAndType{ssa.OpCvt64Fto64U, ssa.OpCopy, TUINT64},
+       twoTypes{types.TUINT64, types.TFLOAT32}: twoOpsAndType{ssa.OpCopy, ssa.OpCvt64Uto32F, types.TUINT64},
+       twoTypes{types.TUINT64, types.TFLOAT64}: twoOpsAndType{ssa.OpCopy, ssa.OpCvt64Uto64F, types.TUINT64},
+       twoTypes{types.TFLOAT32, types.TUINT64}: twoOpsAndType{ssa.OpCvt32Fto64U, ssa.OpCopy, types.TUINT64},
+       twoTypes{types.TFLOAT64, types.TUINT64}: twoOpsAndType{ssa.OpCvt64Fto64U, ssa.OpCopy, types.TUINT64},
 }
 
 var shiftOpToSSA = map[opAndTwoTypes]ssa.Op{
-       opAndTwoTypes{OLSH, TINT8, TUINT8}:   ssa.OpLsh8x8,
-       opAndTwoTypes{OLSH, TUINT8, TUINT8}:  ssa.OpLsh8x8,
-       opAndTwoTypes{OLSH, TINT8, TUINT16}:  ssa.OpLsh8x16,
-       opAndTwoTypes{OLSH, TUINT8, TUINT16}: ssa.OpLsh8x16,
-       opAndTwoTypes{OLSH, TINT8, TUINT32}:  ssa.OpLsh8x32,
-       opAndTwoTypes{OLSH, TUINT8, TUINT32}: ssa.OpLsh8x32,
-       opAndTwoTypes{OLSH, TINT8, TUINT64}:  ssa.OpLsh8x64,
-       opAndTwoTypes{OLSH, TUINT8, TUINT64}: ssa.OpLsh8x64,
-
-       opAndTwoTypes{OLSH, TINT16, TUINT8}:   ssa.OpLsh16x8,
-       opAndTwoTypes{OLSH, TUINT16, TUINT8}:  ssa.OpLsh16x8,
-       opAndTwoTypes{OLSH, TINT16, TUINT16}:  ssa.OpLsh16x16,
-       opAndTwoTypes{OLSH, TUINT16, TUINT16}: ssa.OpLsh16x16,
-       opAndTwoTypes{OLSH, TINT16, TUINT32}:  ssa.OpLsh16x32,
-       opAndTwoTypes{OLSH, TUINT16, TUINT32}: ssa.OpLsh16x32,
-       opAndTwoTypes{OLSH, TINT16, TUINT64}:  ssa.OpLsh16x64,
-       opAndTwoTypes{OLSH, TUINT16, TUINT64}: ssa.OpLsh16x64,
-
-       opAndTwoTypes{OLSH, TINT32, TUINT8}:   ssa.OpLsh32x8,
-       opAndTwoTypes{OLSH, TUINT32, TUINT8}:  ssa.OpLsh32x8,
-       opAndTwoTypes{OLSH, TINT32, TUINT16}:  ssa.OpLsh32x16,
-       opAndTwoTypes{OLSH, TUINT32, TUINT16}: ssa.OpLsh32x16,
-       opAndTwoTypes{OLSH, TINT32, TUINT32}:  ssa.OpLsh32x32,
-       opAndTwoTypes{OLSH, TUINT32, TUINT32}: ssa.OpLsh32x32,
-       opAndTwoTypes{OLSH, TINT32, TUINT64}:  ssa.OpLsh32x64,
-       opAndTwoTypes{OLSH, TUINT32, TUINT64}: ssa.OpLsh32x64,
-
-       opAndTwoTypes{OLSH, TINT64, TUINT8}:   ssa.OpLsh64x8,
-       opAndTwoTypes{OLSH, TUINT64, TUINT8}:  ssa.OpLsh64x8,
-       opAndTwoTypes{OLSH, TINT64, TUINT16}:  ssa.OpLsh64x16,
-       opAndTwoTypes{OLSH, TUINT64, TUINT16}: ssa.OpLsh64x16,
-       opAndTwoTypes{OLSH, TINT64, TUINT32}:  ssa.OpLsh64x32,
-       opAndTwoTypes{OLSH, TUINT64, TUINT32}: ssa.OpLsh64x32,
-       opAndTwoTypes{OLSH, TINT64, TUINT64}:  ssa.OpLsh64x64,
-       opAndTwoTypes{OLSH, TUINT64, TUINT64}: ssa.OpLsh64x64,
-
-       opAndTwoTypes{ORSH, TINT8, TUINT8}:   ssa.OpRsh8x8,
-       opAndTwoTypes{ORSH, TUINT8, TUINT8}:  ssa.OpRsh8Ux8,
-       opAndTwoTypes{ORSH, TINT8, TUINT16}:  ssa.OpRsh8x16,
-       opAndTwoTypes{ORSH, TUINT8, TUINT16}: ssa.OpRsh8Ux16,
-       opAndTwoTypes{ORSH, TINT8, TUINT32}:  ssa.OpRsh8x32,
-       opAndTwoTypes{ORSH, TUINT8, TUINT32}: ssa.OpRsh8Ux32,
-       opAndTwoTypes{ORSH, TINT8, TUINT64}:  ssa.OpRsh8x64,
-       opAndTwoTypes{ORSH, TUINT8, TUINT64}: ssa.OpRsh8Ux64,
-
-       opAndTwoTypes{ORSH, TINT16, TUINT8}:   ssa.OpRsh16x8,
-       opAndTwoTypes{ORSH, TUINT16, TUINT8}:  ssa.OpRsh16Ux8,
-       opAndTwoTypes{ORSH, TINT16, TUINT16}:  ssa.OpRsh16x16,
-       opAndTwoTypes{ORSH, TUINT16, TUINT16}: ssa.OpRsh16Ux16,
-       opAndTwoTypes{ORSH, TINT16, TUINT32}:  ssa.OpRsh16x32,
-       opAndTwoTypes{ORSH, TUINT16, TUINT32}: ssa.OpRsh16Ux32,
-       opAndTwoTypes{ORSH, TINT16, TUINT64}:  ssa.OpRsh16x64,
-       opAndTwoTypes{ORSH, TUINT16, TUINT64}: ssa.OpRsh16Ux64,
-
-       opAndTwoTypes{ORSH, TINT32, TUINT8}:   ssa.OpRsh32x8,
-       opAndTwoTypes{ORSH, TUINT32, TUINT8}:  ssa.OpRsh32Ux8,
-       opAndTwoTypes{ORSH, TINT32, TUINT16}:  ssa.OpRsh32x16,
-       opAndTwoTypes{ORSH, TUINT32, TUINT16}: ssa.OpRsh32Ux16,
-       opAndTwoTypes{ORSH, TINT32, TUINT32}:  ssa.OpRsh32x32,
-       opAndTwoTypes{ORSH, TUINT32, TUINT32}: ssa.OpRsh32Ux32,
-       opAndTwoTypes{ORSH, TINT32, TUINT64}:  ssa.OpRsh32x64,
-       opAndTwoTypes{ORSH, TUINT32, TUINT64}: ssa.OpRsh32Ux64,
-
-       opAndTwoTypes{ORSH, TINT64, TUINT8}:   ssa.OpRsh64x8,
-       opAndTwoTypes{ORSH, TUINT64, TUINT8}:  ssa.OpRsh64Ux8,
-       opAndTwoTypes{ORSH, TINT64, TUINT16}:  ssa.OpRsh64x16,
-       opAndTwoTypes{ORSH, TUINT64, TUINT16}: ssa.OpRsh64Ux16,
-       opAndTwoTypes{ORSH, TINT64, TUINT32}:  ssa.OpRsh64x32,
-       opAndTwoTypes{ORSH, TUINT64, TUINT32}: ssa.OpRsh64Ux32,
-       opAndTwoTypes{ORSH, TINT64, TUINT64}:  ssa.OpRsh64x64,
-       opAndTwoTypes{ORSH, TUINT64, TUINT64}: ssa.OpRsh64Ux64,
-}
-
-func (s *state) ssaShiftOp(op Op, t *types.Type, u *types.Type) ssa.Op {
+       opAndTwoTypes{ir.OLSH, types.TINT8, types.TUINT8}:   ssa.OpLsh8x8,
+       opAndTwoTypes{ir.OLSH, types.TUINT8, types.TUINT8}:  ssa.OpLsh8x8,
+       opAndTwoTypes{ir.OLSH, types.TINT8, types.TUINT16}:  ssa.OpLsh8x16,
+       opAndTwoTypes{ir.OLSH, types.TUINT8, types.TUINT16}: ssa.OpLsh8x16,
+       opAndTwoTypes{ir.OLSH, types.TINT8, types.TUINT32}:  ssa.OpLsh8x32,
+       opAndTwoTypes{ir.OLSH, types.TUINT8, types.TUINT32}: ssa.OpLsh8x32,
+       opAndTwoTypes{ir.OLSH, types.TINT8, types.TUINT64}:  ssa.OpLsh8x64,
+       opAndTwoTypes{ir.OLSH, types.TUINT8, types.TUINT64}: ssa.OpLsh8x64,
+
+       opAndTwoTypes{ir.OLSH, types.TINT16, types.TUINT8}:   ssa.OpLsh16x8,
+       opAndTwoTypes{ir.OLSH, types.TUINT16, types.TUINT8}:  ssa.OpLsh16x8,
+       opAndTwoTypes{ir.OLSH, types.TINT16, types.TUINT16}:  ssa.OpLsh16x16,
+       opAndTwoTypes{ir.OLSH, types.TUINT16, types.TUINT16}: ssa.OpLsh16x16,
+       opAndTwoTypes{ir.OLSH, types.TINT16, types.TUINT32}:  ssa.OpLsh16x32,
+       opAndTwoTypes{ir.OLSH, types.TUINT16, types.TUINT32}: ssa.OpLsh16x32,
+       opAndTwoTypes{ir.OLSH, types.TINT16, types.TUINT64}:  ssa.OpLsh16x64,
+       opAndTwoTypes{ir.OLSH, types.TUINT16, types.TUINT64}: ssa.OpLsh16x64,
+
+       opAndTwoTypes{ir.OLSH, types.TINT32, types.TUINT8}:   ssa.OpLsh32x8,
+       opAndTwoTypes{ir.OLSH, types.TUINT32, types.TUINT8}:  ssa.OpLsh32x8,
+       opAndTwoTypes{ir.OLSH, types.TINT32, types.TUINT16}:  ssa.OpLsh32x16,
+       opAndTwoTypes{ir.OLSH, types.TUINT32, types.TUINT16}: ssa.OpLsh32x16,
+       opAndTwoTypes{ir.OLSH, types.TINT32, types.TUINT32}:  ssa.OpLsh32x32,
+       opAndTwoTypes{ir.OLSH, types.TUINT32, types.TUINT32}: ssa.OpLsh32x32,
+       opAndTwoTypes{ir.OLSH, types.TINT32, types.TUINT64}:  ssa.OpLsh32x64,
+       opAndTwoTypes{ir.OLSH, types.TUINT32, types.TUINT64}: ssa.OpLsh32x64,
+
+       opAndTwoTypes{ir.OLSH, types.TINT64, types.TUINT8}:   ssa.OpLsh64x8,
+       opAndTwoTypes{ir.OLSH, types.TUINT64, types.TUINT8}:  ssa.OpLsh64x8,
+       opAndTwoTypes{ir.OLSH, types.TINT64, types.TUINT16}:  ssa.OpLsh64x16,
+       opAndTwoTypes{ir.OLSH, types.TUINT64, types.TUINT16}: ssa.OpLsh64x16,
+       opAndTwoTypes{ir.OLSH, types.TINT64, types.TUINT32}:  ssa.OpLsh64x32,
+       opAndTwoTypes{ir.OLSH, types.TUINT64, types.TUINT32}: ssa.OpLsh64x32,
+       opAndTwoTypes{ir.OLSH, types.TINT64, types.TUINT64}:  ssa.OpLsh64x64,
+       opAndTwoTypes{ir.OLSH, types.TUINT64, types.TUINT64}: ssa.OpLsh64x64,
+
+       opAndTwoTypes{ir.ORSH, types.TINT8, types.TUINT8}:   ssa.OpRsh8x8,
+       opAndTwoTypes{ir.ORSH, types.TUINT8, types.TUINT8}:  ssa.OpRsh8Ux8,
+       opAndTwoTypes{ir.ORSH, types.TINT8, types.TUINT16}:  ssa.OpRsh8x16,
+       opAndTwoTypes{ir.ORSH, types.TUINT8, types.TUINT16}: ssa.OpRsh8Ux16,
+       opAndTwoTypes{ir.ORSH, types.TINT8, types.TUINT32}:  ssa.OpRsh8x32,
+       opAndTwoTypes{ir.ORSH, types.TUINT8, types.TUINT32}: ssa.OpRsh8Ux32,
+       opAndTwoTypes{ir.ORSH, types.TINT8, types.TUINT64}:  ssa.OpRsh8x64,
+       opAndTwoTypes{ir.ORSH, types.TUINT8, types.TUINT64}: ssa.OpRsh8Ux64,
+
+       opAndTwoTypes{ir.ORSH, types.TINT16, types.TUINT8}:   ssa.OpRsh16x8,
+       opAndTwoTypes{ir.ORSH, types.TUINT16, types.TUINT8}:  ssa.OpRsh16Ux8,
+       opAndTwoTypes{ir.ORSH, types.TINT16, types.TUINT16}:  ssa.OpRsh16x16,
+       opAndTwoTypes{ir.ORSH, types.TUINT16, types.TUINT16}: ssa.OpRsh16Ux16,
+       opAndTwoTypes{ir.ORSH, types.TINT16, types.TUINT32}:  ssa.OpRsh16x32,
+       opAndTwoTypes{ir.ORSH, types.TUINT16, types.TUINT32}: ssa.OpRsh16Ux32,
+       opAndTwoTypes{ir.ORSH, types.TINT16, types.TUINT64}:  ssa.OpRsh16x64,
+       opAndTwoTypes{ir.ORSH, types.TUINT16, types.TUINT64}: ssa.OpRsh16Ux64,
+
+       opAndTwoTypes{ir.ORSH, types.TINT32, types.TUINT8}:   ssa.OpRsh32x8,
+       opAndTwoTypes{ir.ORSH, types.TUINT32, types.TUINT8}:  ssa.OpRsh32Ux8,
+       opAndTwoTypes{ir.ORSH, types.TINT32, types.TUINT16}:  ssa.OpRsh32x16,
+       opAndTwoTypes{ir.ORSH, types.TUINT32, types.TUINT16}: ssa.OpRsh32Ux16,
+       opAndTwoTypes{ir.ORSH, types.TINT32, types.TUINT32}:  ssa.OpRsh32x32,
+       opAndTwoTypes{ir.ORSH, types.TUINT32, types.TUINT32}: ssa.OpRsh32Ux32,
+       opAndTwoTypes{ir.ORSH, types.TINT32, types.TUINT64}:  ssa.OpRsh32x64,
+       opAndTwoTypes{ir.ORSH, types.TUINT32, types.TUINT64}: ssa.OpRsh32Ux64,
+
+       opAndTwoTypes{ir.ORSH, types.TINT64, types.TUINT8}:   ssa.OpRsh64x8,
+       opAndTwoTypes{ir.ORSH, types.TUINT64, types.TUINT8}:  ssa.OpRsh64Ux8,
+       opAndTwoTypes{ir.ORSH, types.TINT64, types.TUINT16}:  ssa.OpRsh64x16,
+       opAndTwoTypes{ir.ORSH, types.TUINT64, types.TUINT16}: ssa.OpRsh64Ux16,
+       opAndTwoTypes{ir.ORSH, types.TINT64, types.TUINT32}:  ssa.OpRsh64x32,
+       opAndTwoTypes{ir.ORSH, types.TUINT64, types.TUINT32}: ssa.OpRsh64Ux32,
+       opAndTwoTypes{ir.ORSH, types.TINT64, types.TUINT64}:  ssa.OpRsh64x64,
+       opAndTwoTypes{ir.ORSH, types.TUINT64, types.TUINT64}: ssa.OpRsh64Ux64,
+}
+
+func (s *state) ssaShiftOp(op ir.Op, t *types.Type, u *types.Type) ssa.Op {
        etype1 := s.concreteEtype(t)
        etype2 := s.concreteEtype(u)
        x, ok := shiftOpToSSA[opAndTwoTypes{op, etype1, etype2}]
@@ -1998,7 +1999,7 @@ func (s *state) ssaShiftOp(op Op, t *types.Type, u *types.Type) ssa.Op {
 }
 
 // expr converts the expression n to ssa, adds it to s and returns the ssa result.
-func (s *state) expr(n *Node) *ssa.Value {
+func (s *state) expr(n *ir.Node) *ssa.Value {
        if hasUniquePos(n) {
                // ONAMEs and named OLITERALs have the line number
                // of the decl, not the use. See issue 14742.
@@ -2008,24 +2009,24 @@ func (s *state) expr(n *Node) *ssa.Value {
 
        s.stmtList(n.Ninit)
        switch n.Op {
-       case OBYTES2STRTMP:
+       case ir.OBYTES2STRTMP:
                slice := s.expr(n.Left)
                ptr := s.newValue1(ssa.OpSlicePtr, s.f.Config.Types.BytePtr, slice)
-               len := s.newValue1(ssa.OpSliceLen, types.Types[TINT], slice)
+               len := s.newValue1(ssa.OpSliceLen, types.Types[types.TINT], slice)
                return s.newValue2(ssa.OpStringMake, n.Type, ptr, len)
-       case OSTR2BYTESTMP:
+       case ir.OSTR2BYTESTMP:
                str := s.expr(n.Left)
                ptr := s.newValue1(ssa.OpStringPtr, s.f.Config.Types.BytePtr, str)
-               len := s.newValue1(ssa.OpStringLen, types.Types[TINT], str)
+               len := s.newValue1(ssa.OpStringLen, types.Types[types.TINT], str)
                return s.newValue3(ssa.OpSliceMake, n.Type, ptr, len, len)
-       case OCFUNC:
+       case ir.OCFUNC:
                aux := n.Left.Sym.Linksym()
                return s.entryNewValue1A(ssa.OpAddr, n.Type, aux, s.sb)
-       case OMETHEXPR:
+       case ir.OMETHEXPR:
                sym := funcsym(n.Sym).Linksym()
                return s.entryNewValue1A(ssa.OpAddr, types.NewPtr(n.Type), sym, s.sb)
-       case ONAME:
-               if n.Class() == PFUNC {
+       case ir.ONAME:
+               if n.Class() == ir.PFUNC {
                        // "value" of a function is the address of the function's closure
                        sym := funcsym(n.Sym).Linksym()
                        return s.entryNewValue1A(ssa.OpAddr, types.NewPtr(n.Type), sym, s.sb)
@@ -2035,10 +2036,10 @@ func (s *state) expr(n *Node) *ssa.Value {
                }
                addr := s.addr(n)
                return s.load(n.Type, addr)
-       case OCLOSUREVAR:
+       case ir.OCLOSUREVAR:
                addr := s.addr(n)
                return s.load(n.Type, addr)
-       case ONIL:
+       case ir.ONIL:
                t := n.Type
                switch {
                case t.IsSlice():
@@ -2048,10 +2049,10 @@ func (s *state) expr(n *Node) *ssa.Value {
                default:
                        return s.constNil(t)
                }
-       case OLITERAL:
+       case ir.OLITERAL:
                switch u := n.Val(); u.Kind() {
                case constant.Int:
-                       i := int64Val(n.Type, u)
+                       i := ir.Int64Val(n.Type, u)
                        switch n.Type.Size() {
                        case 1:
                                return s.constInt8(n.Type, int8(i))
@@ -2089,12 +2090,12 @@ func (s *state) expr(n *Node) *ssa.Value {
                        im, _ := constant.Float64Val(constant.Imag(u))
                        switch n.Type.Size() {
                        case 8:
-                               pt := types.Types[TFLOAT32]
+                               pt := types.Types[types.TFLOAT32]
                                return s.newValue2(ssa.OpComplexMake, n.Type,
                                        s.constFloat32(pt, re),
                                        s.constFloat32(pt, im))
                        case 16:
-                               pt := types.Types[TFLOAT64]
+                               pt := types.Types[types.TFLOAT64]
                                return s.newValue2(ssa.OpComplexMake, n.Type,
                                        s.constFloat64(pt, re),
                                        s.constFloat64(pt, im))
@@ -2106,7 +2107,7 @@ func (s *state) expr(n *Node) *ssa.Value {
                        s.Fatalf("unhandled OLITERAL %v", u.Kind())
                        return nil
                }
-       case OCONVNOP:
+       case ir.OCONVNOP:
                to := n.Type
                from := n.Left.Type
 
@@ -2125,7 +2126,7 @@ func (s *state) expr(n *Node) *ssa.Value {
                v := s.newValue1(ssa.OpCopy, to, x) // ensure that v has the right type
 
                // CONVNOP closure
-               if to.Etype == TFUNC && from.IsPtrShaped() {
+               if to.Etype == types.TFUNC && from.IsPtrShaped() {
                        return v
                }
 
@@ -2140,7 +2141,7 @@ func (s *state) expr(n *Node) *ssa.Value {
                }
 
                // map <--> *hmap
-               if to.Etype == TMAP && from.IsPtr() &&
+               if to.Etype == types.TMAP && from.IsPtr() &&
                        to.MapType().Hmap == from.Elem() {
                        return v
                }
@@ -2171,11 +2172,11 @@ func (s *state) expr(n *Node) *ssa.Value {
                // integer, same width, same sign
                return v
 
-       case OCONV:
+       case ir.OCONV:
                x := s.expr(n.Left)
                ft := n.Left.Type // from type
                tt := n.Type      // to type
-               if ft.IsBoolean() && tt.IsKind(TUINT8) {
+               if ft.IsBoolean() && tt.IsKind(types.TUINT8) {
                        // Bool -> uint8 is generated internally when indexing into runtime.staticbyte.
                        return s.newValue1(ssa.OpCopy, n.Type, x)
                }
@@ -2342,25 +2343,25 @@ func (s *state) expr(n *Node) *ssa.Value {
                s.Fatalf("unhandled OCONV %s -> %s", n.Left.Type.Etype, n.Type.Etype)
                return nil
 
-       case ODOTTYPE:
+       case ir.ODOTTYPE:
                res, _ := s.dottype(n, false)
                return res
 
        // binary ops
-       case OLT, OEQ, ONE, OLE, OGE, OGT:
+       case ir.OLT, ir.OEQ, ir.ONE, ir.OLE, ir.OGE, ir.OGT:
                a := s.expr(n.Left)
                b := s.expr(n.Right)
                if n.Left.Type.IsComplex() {
                        pt := floatForComplex(n.Left.Type)
-                       op := s.ssaOp(OEQ, pt)
-                       r := s.newValueOrSfCall2(op, types.Types[TBOOL], s.newValue1(ssa.OpComplexReal, pt, a), s.newValue1(ssa.OpComplexReal, pt, b))
-                       i := s.newValueOrSfCall2(op, types.Types[TBOOL], s.newValue1(ssa.OpComplexImag, pt, a), s.newValue1(ssa.OpComplexImag, pt, b))
-                       c := s.newValue2(ssa.OpAndB, types.Types[TBOOL], r, i)
+                       op := s.ssaOp(ir.OEQ, pt)
+                       r := s.newValueOrSfCall2(op, types.Types[types.TBOOL], s.newValue1(ssa.OpComplexReal, pt, a), s.newValue1(ssa.OpComplexReal, pt, b))
+                       i := s.newValueOrSfCall2(op, types.Types[types.TBOOL], s.newValue1(ssa.OpComplexImag, pt, a), s.newValue1(ssa.OpComplexImag, pt, b))
+                       c := s.newValue2(ssa.OpAndB, types.Types[types.TBOOL], r, i)
                        switch n.Op {
-                       case OEQ:
+                       case ir.OEQ:
                                return c
-                       case ONE:
-                               return s.newValue1(ssa.OpNot, types.Types[TBOOL], c)
+                       case ir.ONE:
+                               return s.newValue1(ssa.OpNot, types.Types[types.TBOOL], c)
                        default:
                                s.Fatalf("ordered complex compare %v", n.Op)
                        }
@@ -2369,26 +2370,26 @@ func (s *state) expr(n *Node) *ssa.Value {
                // Convert OGE and OGT into OLE and OLT.
                op := n.Op
                switch op {
-               case OGE:
-                       op, a, b = OLE, b, a
-               case OGT:
-                       op, a, b = OLT, b, a
+               case ir.OGE:
+                       op, a, b = ir.OLE, b, a
+               case ir.OGT:
+                       op, a, b = ir.OLT, b, a
                }
                if n.Left.Type.IsFloat() {
                        // float comparison
-                       return s.newValueOrSfCall2(s.ssaOp(op, n.Left.Type), types.Types[TBOOL], a, b)
+                       return s.newValueOrSfCall2(s.ssaOp(op, n.Left.Type), types.Types[types.TBOOL], a, b)
                }
                // integer comparison
-               return s.newValue2(s.ssaOp(op, n.Left.Type), types.Types[TBOOL], a, b)
-       case OMUL:
+               return s.newValue2(s.ssaOp(op, n.Left.Type), types.Types[types.TBOOL], a, b)
+       case ir.OMUL:
                a := s.expr(n.Left)
                b := s.expr(n.Right)
                if n.Type.IsComplex() {
                        mulop := ssa.OpMul64F
                        addop := ssa.OpAdd64F
                        subop := ssa.OpSub64F
-                       pt := floatForComplex(n.Type) // Could be Float32 or Float64
-                       wt := types.Types[TFLOAT64]   // Compute in Float64 to minimize cancellation error
+                       pt := floatForComplex(n.Type)     // Could be Float32 or Float64
+                       wt := types.Types[types.TFLOAT64] // Compute in Float64 to minimize cancellation error
 
                        areal := s.newValue1(ssa.OpComplexReal, pt, a)
                        breal := s.newValue1(ssa.OpComplexReal, pt, b)
@@ -2419,7 +2420,7 @@ func (s *state) expr(n *Node) *ssa.Value {
 
                return s.newValue2(s.ssaOp(n.Op, n.Type), a.Type, a, b)
 
-       case ODIV:
+       case ir.ODIV:
                a := s.expr(n.Left)
                b := s.expr(n.Right)
                if n.Type.IsComplex() {
@@ -2430,8 +2431,8 @@ func (s *state) expr(n *Node) *ssa.Value {
                        addop := ssa.OpAdd64F
                        subop := ssa.OpSub64F
                        divop := ssa.OpDiv64F
-                       pt := floatForComplex(n.Type) // Could be Float32 or Float64
-                       wt := types.Types[TFLOAT64]   // Compute in Float64 to minimize cancellation error
+                       pt := floatForComplex(n.Type)     // Could be Float32 or Float64
+                       wt := types.Types[types.TFLOAT64] // Compute in Float64 to minimize cancellation error
 
                        areal := s.newValue1(ssa.OpComplexReal, pt, a)
                        breal := s.newValue1(ssa.OpComplexReal, pt, b)
@@ -2466,11 +2467,11 @@ func (s *state) expr(n *Node) *ssa.Value {
                        return s.newValueOrSfCall2(s.ssaOp(n.Op, n.Type), a.Type, a, b)
                }
                return s.intDivide(n, a, b)
-       case OMOD:
+       case ir.OMOD:
                a := s.expr(n.Left)
                b := s.expr(n.Right)
                return s.intDivide(n, a, b)
-       case OADD, OSUB:
+       case ir.OADD, ir.OSUB:
                a := s.expr(n.Left)
                b := s.expr(n.Right)
                if n.Type.IsComplex() {
@@ -2484,26 +2485,26 @@ func (s *state) expr(n *Node) *ssa.Value {
                        return s.newValueOrSfCall2(s.ssaOp(n.Op, n.Type), a.Type, a, b)
                }
                return s.newValue2(s.ssaOp(n.Op, n.Type), a.Type, a, b)
-       case OAND, OOR, OXOR:
+       case ir.OAND, ir.OOR, ir.OXOR:
                a := s.expr(n.Left)
                b := s.expr(n.Right)
                return s.newValue2(s.ssaOp(n.Op, n.Type), a.Type, a, b)
-       case OANDNOT:
+       case ir.OANDNOT:
                a := s.expr(n.Left)
                b := s.expr(n.Right)
-               b = s.newValue1(s.ssaOp(OBITNOT, b.Type), b.Type, b)
-               return s.newValue2(s.ssaOp(OAND, n.Type), a.Type, a, b)
-       case OLSH, ORSH:
+               b = s.newValue1(s.ssaOp(ir.OBITNOT, b.Type), b.Type, b)
+               return s.newValue2(s.ssaOp(ir.OAND, n.Type), a.Type, a, b)
+       case ir.OLSH, ir.ORSH:
                a := s.expr(n.Left)
                b := s.expr(n.Right)
                bt := b.Type
                if bt.IsSigned() {
-                       cmp := s.newValue2(s.ssaOp(OLE, bt), types.Types[TBOOL], s.zeroVal(bt), b)
+                       cmp := s.newValue2(s.ssaOp(ir.OLE, bt), types.Types[types.TBOOL], s.zeroVal(bt), b)
                        s.check(cmp, panicshift)
                        bt = bt.ToUnsigned()
                }
                return s.newValue2(s.ssaShiftOp(n.Op, n.Type, bt), a.Type, a, b)
-       case OANDAND, OOROR:
+       case ir.OANDAND, ir.OOROR:
                // To implement OANDAND (and OOROR), we introduce a
                // new temporary variable to hold the result. The
                // variable is associated with the OANDAND node in the
@@ -2530,10 +2531,10 @@ func (s *state) expr(n *Node) *ssa.Value {
 
                bRight := s.f.NewBlock(ssa.BlockPlain)
                bResult := s.f.NewBlock(ssa.BlockPlain)
-               if n.Op == OANDAND {
+               if n.Op == ir.OANDAND {
                        b.AddEdgeTo(bRight)
                        b.AddEdgeTo(bResult)
-               } else if n.Op == OOROR {
+               } else if n.Op == ir.OOROR {
                        b.AddEdgeTo(bResult)
                        b.AddEdgeTo(bRight)
                }
@@ -2546,14 +2547,14 @@ func (s *state) expr(n *Node) *ssa.Value {
                b.AddEdgeTo(bResult)
 
                s.startBlock(bResult)
-               return s.variable(n, types.Types[TBOOL])
-       case OCOMPLEX:
+               return s.variable(n, types.Types[types.TBOOL])
+       case ir.OCOMPLEX:
                r := s.expr(n.Left)
                i := s.expr(n.Right)
                return s.newValue2(ssa.OpComplexMake, n.Type, r, i)
 
        // unary ops
-       case ONEG:
+       case ir.ONEG:
                a := s.expr(n.Left)
                if n.Type.IsComplex() {
                        tp := floatForComplex(n.Type)
@@ -2563,19 +2564,19 @@ func (s *state) expr(n *Node) *ssa.Value {
                                s.newValue1(negop, tp, s.newValue1(ssa.OpComplexImag, tp, a)))
                }
                return s.newValue1(s.ssaOp(n.Op, n.Type), a.Type, a)
-       case ONOT, OBITNOT:
+       case ir.ONOT, ir.OBITNOT:
                a := s.expr(n.Left)
                return s.newValue1(s.ssaOp(n.Op, n.Type), a.Type, a)
-       case OIMAG, OREAL:
+       case ir.OIMAG, ir.OREAL:
                a := s.expr(n.Left)
                return s.newValue1(s.ssaOp(n.Op, n.Left.Type), n.Type, a)
-       case OPLUS:
+       case ir.OPLUS:
                return s.expr(n.Left)
 
-       case OADDR:
+       case ir.OADDR:
                return s.addr(n.Left)
 
-       case ORESULT:
+       case ir.ORESULT:
                if s.prevCall == nil || s.prevCall.Op != ssa.OpStaticLECall && s.prevCall.Op != ssa.OpInterLECall && s.prevCall.Op != ssa.OpClosureLECall {
                        // Do the old thing
                        addr := s.constOffPtrSP(types.NewPtr(n.Type), n.Xoffset)
@@ -2594,12 +2595,12 @@ func (s *state) expr(n *Node) *ssa.Value {
                        return s.rawLoad(n.Type, addr)
                }
 
-       case ODEREF:
+       case ir.ODEREF:
                p := s.exprPtr(n.Left, n.Bounded(), n.Pos)
                return s.load(n.Type, p)
 
-       case ODOT:
-               if n.Left.Op == OSTRUCTLIT {
+       case ir.ODOT:
+               if n.Left.Op == ir.OSTRUCTLIT {
                        // All literals with nonzero fields have already been
                        // rewritten during walk. Any that remain are just T{}
                        // or equivalents. Use the zero value.
@@ -2619,32 +2620,32 @@ func (s *state) expr(n *Node) *ssa.Value {
                v := s.expr(n.Left)
                return s.newValue1I(ssa.OpStructSelect, n.Type, int64(fieldIdx(n)), v)
 
-       case ODOTPTR:
+       case ir.ODOTPTR:
                p := s.exprPtr(n.Left, n.Bounded(), n.Pos)
                p = s.newValue1I(ssa.OpOffPtr, types.NewPtr(n.Type), n.Xoffset, p)
                return s.load(n.Type, p)
 
-       case OINDEX:
+       case ir.OINDEX:
                switch {
                case n.Left.Type.IsString():
-                       if n.Bounded() && Isconst(n.Left, constant.String) && Isconst(n.Right, constant.Int) {
+                       if n.Bounded() && ir.IsConst(n.Left, constant.String) && ir.IsConst(n.Right, constant.Int) {
                                // Replace "abc"[1] with 'b'.
                                // Delayed until now because "abc"[1] is not an ideal constant.
                                // See test/fixedbugs/issue11370.go.
-                               return s.newValue0I(ssa.OpConst8, types.Types[TUINT8], int64(int8(n.Left.StringVal()[n.Right.Int64Val()])))
+                               return s.newValue0I(ssa.OpConst8, types.Types[types.TUINT8], int64(int8(n.Left.StringVal()[n.Right.Int64Val()])))
                        }
                        a := s.expr(n.Left)
                        i := s.expr(n.Right)
-                       len := s.newValue1(ssa.OpStringLen, types.Types[TINT], a)
+                       len := s.newValue1(ssa.OpStringLen, types.Types[types.TINT], a)
                        i = s.boundsCheck(i, len, ssa.BoundsIndex, n.Bounded())
                        ptrtyp := s.f.Config.Types.BytePtr
                        ptr := s.newValue1(ssa.OpStringPtr, ptrtyp, a)
-                       if Isconst(n.Right, constant.Int) {
+                       if ir.IsConst(n.Right, constant.Int) {
                                ptr = s.newValue1I(ssa.OpOffPtr, ptrtyp, n.Right.Int64Val(), ptr)
                        } else {
                                ptr = s.newValue2(ssa.OpAddPtr, ptrtyp, ptr, i)
                        }
-                       return s.load(types.Types[TUINT8], ptr)
+                       return s.load(types.Types[types.TUINT8], ptr)
                case n.Left.Type.IsSlice():
                        p := s.addr(n)
                        return s.load(n.Left.Type.Elem(), p)
@@ -2657,12 +2658,12 @@ func (s *state) expr(n *Node) *ssa.Value {
                                if bound == 0 {
                                        // Bounds check will never succeed.  Might as well
                                        // use constants for the bounds check.
-                                       z := s.constInt(types.Types[TINT], 0)
+                                       z := s.constInt(types.Types[types.TINT], 0)
                                        s.boundsCheck(z, z, ssa.BoundsIndex, false)
                                        // The return value won't be live, return junk.
                                        return s.newValue0(ssa.OpUnknown, n.Type)
                                }
-                               len := s.constInt(types.Types[TINT], bound)
+                               len := s.constInt(types.Types[types.TINT], bound)
                                s.boundsCheck(i, len, ssa.BoundsIndex, n.Bounded()) // checks i == 0
                                return s.newValue1I(ssa.OpArraySelect, n.Type, 0, a)
                        }
@@ -2673,23 +2674,23 @@ func (s *state) expr(n *Node) *ssa.Value {
                        return nil
                }
 
-       case OLEN, OCAP:
+       case ir.OLEN, ir.OCAP:
                switch {
                case n.Left.Type.IsSlice():
                        op := ssa.OpSliceLen
-                       if n.Op == OCAP {
+                       if n.Op == ir.OCAP {
                                op = ssa.OpSliceCap
                        }
-                       return s.newValue1(op, types.Types[TINT], s.expr(n.Left))
+                       return s.newValue1(op, types.Types[types.TINT], s.expr(n.Left))
                case n.Left.Type.IsString(): // string; not reachable for OCAP
-                       return s.newValue1(ssa.OpStringLen, types.Types[TINT], s.expr(n.Left))
+                       return s.newValue1(ssa.OpStringLen, types.Types[types.TINT], s.expr(n.Left))
                case n.Left.Type.IsMap(), n.Left.Type.IsChan():
                        return s.referenceTypeBuiltin(n, s.expr(n.Left))
                default: // array
-                       return s.constInt(types.Types[TINT], n.Left.Type.NumElem())
+                       return s.constInt(types.Types[types.TINT], n.Left.Type.NumElem())
                }
 
-       case OSPTR:
+       case ir.OSPTR:
                a := s.expr(n.Left)
                if n.Left.Type.IsSlice() {
                        return s.newValue1(ssa.OpSlicePtr, n.Type, a)
@@ -2697,26 +2698,26 @@ func (s *state) expr(n *Node) *ssa.Value {
                        return s.newValue1(ssa.OpStringPtr, n.Type, a)
                }
 
-       case OITAB:
+       case ir.OITAB:
                a := s.expr(n.Left)
                return s.newValue1(ssa.OpITab, n.Type, a)
 
-       case OIDATA:
+       case ir.OIDATA:
                a := s.expr(n.Left)
                return s.newValue1(ssa.OpIData, n.Type, a)
 
-       case OEFACE:
+       case ir.OEFACE:
                tab := s.expr(n.Left)
                data := s.expr(n.Right)
                return s.newValue2(ssa.OpIMake, n.Type, tab, data)
 
-       case OSLICEHEADER:
+       case ir.OSLICEHEADER:
                p := s.expr(n.Left)
                l := s.expr(n.List.First())
                c := s.expr(n.List.Second())
                return s.newValue3(ssa.OpSliceMake, n.Type, p, l, c)
 
-       case OSLICE, OSLICEARR, OSLICE3, OSLICE3ARR:
+       case ir.OSLICE, ir.OSLICEARR, ir.OSLICE3, ir.OSLICE3ARR:
                v := s.expr(n.Left)
                var i, j, k *ssa.Value
                low, high, max := n.SliceBounds()
@@ -2732,7 +2733,7 @@ func (s *state) expr(n *Node) *ssa.Value {
                p, l, c := s.slice(v, i, j, k, n.Bounded())
                return s.newValue3(ssa.OpSliceMake, n.Type, p, l, c)
 
-       case OSLICESTR:
+       case ir.OSLICESTR:
                v := s.expr(n.Left)
                var i, j *ssa.Value
                low, high, _ := n.SliceBounds()
@@ -2745,22 +2746,22 @@ func (s *state) expr(n *Node) *ssa.Value {
                p, l, _ := s.slice(v, i, j, nil, n.Bounded())
                return s.newValue2(ssa.OpStringMake, n.Type, p, l)
 
-       case OCALLFUNC:
+       case ir.OCALLFUNC:
                if isIntrinsicCall(n) {
                        return s.intrinsicCall(n)
                }
                fallthrough
 
-       case OCALLINTER, OCALLMETH:
+       case ir.OCALLINTER, ir.OCALLMETH:
                return s.callResult(n, callNormal)
 
-       case OGETG:
+       case ir.OGETG:
                return s.newValue1(ssa.OpGetG, n.Type, s.mem())
 
-       case OAPPEND:
+       case ir.OAPPEND:
                return s.append(n, false)
 
-       case OSTRUCTLIT, OARRAYLIT:
+       case ir.OSTRUCTLIT, ir.OARRAYLIT:
                // All literals with nonzero fields have already been
                // rewritten during walk. Any that remain are just T{}
                // or equivalents. Use the zero value.
@@ -2769,7 +2770,7 @@ func (s *state) expr(n *Node) *ssa.Value {
                }
                return s.zeroVal(n.Type)
 
-       case ONEWOBJ:
+       case ir.ONEWOBJ:
                if n.Type.Elem().Size() == 0 {
                        return s.newValue1A(ssa.OpAddr, n.Type, zerobaseSym, s.sb)
                }
@@ -2789,7 +2790,7 @@ func (s *state) expr(n *Node) *ssa.Value {
 // If inplace is true, it writes the result of the OAPPEND expression n
 // back to the slice being appended to, and returns nil.
 // inplace MUST be set to false if the slice can be SSA'd.
-func (s *state) append(n *Node, inplace bool) *ssa.Value {
+func (s *state) append(n *ir.Node, inplace bool) *ssa.Value {
        // If inplace is false, process as expression "append(s, e1, e2, e3)":
        //
        // ptr, len, cap := s
@@ -2844,11 +2845,11 @@ func (s *state) append(n *Node, inplace bool) *ssa.Value {
        // Decide if we need to grow
        nargs := int64(n.List.Len() - 1)
        p := s.newValue1(ssa.OpSlicePtr, pt, slice)
-       l := s.newValue1(ssa.OpSliceLen, types.Types[TINT], slice)
-       c := s.newValue1(ssa.OpSliceCap, types.Types[TINT], slice)
-       nl := s.newValue2(s.ssaOp(OADD, types.Types[TINT]), types.Types[TINT], l, s.constInt(types.Types[TINT], nargs))
+       l := s.newValue1(ssa.OpSliceLen, types.Types[types.TINT], slice)
+       c := s.newValue1(ssa.OpSliceCap, types.Types[types.TINT], slice)
+       nl := s.newValue2(s.ssaOp(ir.OADD, types.Types[types.TINT]), types.Types[types.TINT], l, s.constInt(types.Types[types.TINT], nargs))
 
-       cmp := s.newValue2(s.ssaOp(OLT, types.Types[TUINT]), types.Types[types.TBOOL], c, nl)
+       cmp := s.newValue2(s.ssaOp(ir.OLT, types.Types[types.TUINT]), types.Types[types.TBOOL], c, nl)
        s.vars[ptrVar] = p
 
        if !inplace {
@@ -2868,22 +2869,22 @@ func (s *state) append(n *Node, inplace bool) *ssa.Value {
        // Call growslice
        s.startBlock(grow)
        taddr := s.expr(n.Left)
-       r := s.rtcall(growslice, true, []*types.Type{pt, types.Types[TINT], types.Types[TINT]}, taddr, p, l, c, nl)
+       r := s.rtcall(growslice, true, []*types.Type{pt, types.Types[types.TINT], types.Types[types.TINT]}, taddr, p, l, c, nl)
 
        if inplace {
-               if sn.Op == ONAME && sn.Class() != PEXTERN {
+               if sn.Op == ir.ONAME && sn.Class() != ir.PEXTERN {
                        // Tell liveness we're about to build a new slice
                        s.vars[memVar] = s.newValue1A(ssa.OpVarDef, types.TypeMem, sn, s.mem())
                }
                capaddr := s.newValue1I(ssa.OpOffPtr, s.f.Config.Types.IntPtr, sliceCapOffset, addr)
-               s.store(types.Types[TINT], capaddr, r[2])
+               s.store(types.Types[types.TINT], capaddr, r[2])
                s.store(pt, addr, r[0])
                // load the value we just stored to avoid having to spill it
                s.vars[ptrVar] = s.load(pt, addr)
                s.vars[lenVar] = r[1] // avoid a spill in the fast path
        } else {
                s.vars[ptrVar] = r[0]
-               s.vars[newlenVar] = s.newValue2(s.ssaOp(OADD, types.Types[TINT]), types.Types[TINT], r[1], s.constInt(types.Types[TINT], nargs))
+               s.vars[newlenVar] = s.newValue2(s.ssaOp(ir.OADD, types.Types[types.TINT]), types.Types[types.TINT], r[1], s.constInt(types.Types[types.TINT], nargs))
                s.vars[capVar] = r[2]
        }
 
@@ -2894,10 +2895,10 @@ func (s *state) append(n *Node, inplace bool) *ssa.Value {
        s.startBlock(assign)
 
        if inplace {
-               l = s.variable(lenVar, types.Types[TINT]) // generates phi for len
-               nl = s.newValue2(s.ssaOp(OADD, types.Types[TINT]), types.Types[TINT], l, s.constInt(types.Types[TINT], nargs))
+               l = s.variable(lenVar, types.Types[types.TINT]) // generates phi for len
+               nl = s.newValue2(s.ssaOp(ir.OADD, types.Types[types.TINT]), types.Types[types.TINT], l, s.constInt(types.Types[types.TINT], nargs))
                lenaddr := s.newValue1I(ssa.OpOffPtr, s.f.Config.Types.IntPtr, sliceLenOffset, addr)
-               s.store(types.Types[TINT], lenaddr, nl)
+               s.store(types.Types[types.TINT], lenaddr, nl)
        }
 
        // Evaluate args
@@ -2919,12 +2920,12 @@ func (s *state) append(n *Node, inplace bool) *ssa.Value {
 
        p = s.variable(ptrVar, pt) // generates phi for ptr
        if !inplace {
-               nl = s.variable(newlenVar, types.Types[TINT]) // generates phi for nl
-               c = s.variable(capVar, types.Types[TINT])     // generates phi for cap
+               nl = s.variable(newlenVar, types.Types[types.TINT]) // generates phi for nl
+               c = s.variable(capVar, types.Types[types.TINT])     // generates phi for cap
        }
        p2 := s.newValue2(ssa.OpPtrIndex, pt, p, l)
        for i, arg := range args {
-               addr := s.newValue2(ssa.OpPtrIndex, pt, p2, s.constInt(types.Types[TINT], int64(i)))
+               addr := s.newValue2(ssa.OpPtrIndex, pt, p2, s.constInt(types.Types[types.TINT], int64(i)))
                if arg.store {
                        s.storeType(et, addr, arg.v, 0, true)
                } else {
@@ -2947,9 +2948,9 @@ func (s *state) append(n *Node, inplace bool) *ssa.Value {
 // if cond is true and no if cond is false.
 // This function is intended to handle && and || better than just calling
 // s.expr(cond) and branching on the result.
-func (s *state) condBranch(cond *Node, yes, no *ssa.Block, likely int8) {
+func (s *state) condBranch(cond *ir.Node, yes, no *ssa.Block, likely int8) {
        switch cond.Op {
-       case OANDAND:
+       case ir.OANDAND:
                mid := s.f.NewBlock(ssa.BlockPlain)
                s.stmtList(cond.Ninit)
                s.condBranch(cond.Left, mid, no, max8(likely, 0))
@@ -2962,7 +2963,7 @@ func (s *state) condBranch(cond *Node, yes, no *ssa.Block, likely int8) {
                // the likeliness of the first branch.
                // TODO: have the frontend give us branch prediction hints for
                // OANDAND and OOROR nodes (if it ever has such info).
-       case OOROR:
+       case ir.OOROR:
                mid := s.f.NewBlock(ssa.BlockPlain)
                s.stmtList(cond.Ninit)
                s.condBranch(cond.Left, yes, mid, min8(likely, 0))
@@ -2972,7 +2973,7 @@ func (s *state) condBranch(cond *Node, yes, no *ssa.Block, likely int8) {
                // Note: if likely==-1, then both recursive calls pass -1.
                // If likely==1, then we don't have enough info to decide
                // the likelihood of the first branch.
-       case ONOT:
+       case ir.ONOT:
                s.stmtList(cond.Ninit)
                s.condBranch(cond.Left, no, yes, -likely)
                return
@@ -2999,8 +3000,8 @@ const (
 // If deref is true, then we do left = *right instead (and right has already been nil-checked).
 // If deref is true and right == nil, just do left = 0.
 // skip indicates assignments (at the top level) that can be avoided.
-func (s *state) assign(left *Node, right *ssa.Value, deref bool, skip skipMask) {
-       if left.Op == ONAME && left.isBlank() {
+func (s *state) assign(left *ir.Node, right *ssa.Value, deref bool, skip skipMask) {
+       if left.Op == ir.ONAME && ir.IsBlank(left) {
                return
        }
        t := left.Type
@@ -3009,7 +3010,7 @@ func (s *state) assign(left *Node, right *ssa.Value, deref bool, skip skipMask)
                if deref {
                        s.Fatalf("can SSA LHS %v but not RHS %s", left, right)
                }
-               if left.Op == ODOT {
+               if left.Op == ir.ODOT {
                        // We're assigning to a field of an ssa-able value.
                        // We need to build a new structure with the new value for the
                        // field we're assigning and the old values for the other fields.
@@ -3044,7 +3045,7 @@ func (s *state) assign(left *Node, right *ssa.Value, deref bool, skip skipMask)
                        // TODO: do we need to update named values here?
                        return
                }
-               if left.Op == OINDEX && left.Left.Type.IsArray() {
+               if left.Op == ir.OINDEX && left.Left.Type.IsArray() {
                        s.pushLine(left.Pos)
                        defer s.popLine()
                        // We're assigning to an element of an ssa-able array.
@@ -3056,7 +3057,7 @@ func (s *state) assign(left *Node, right *ssa.Value, deref bool, skip skipMask)
                        if n == 0 {
                                // The bounds check must fail.  Might as well
                                // ignore the actual index and just use zeros.
-                               z := s.constInt(types.Types[TINT], 0)
+                               z := s.constInt(types.Types[types.TINT], 0)
                                s.boundsCheck(z, z, ssa.BoundsIndex, false)
                                return
                        }
@@ -3064,7 +3065,7 @@ func (s *state) assign(left *Node, right *ssa.Value, deref bool, skip skipMask)
                                s.Fatalf("assigning to non-1-length array")
                        }
                        // Rewrite to a = [1]{v}
-                       len := s.constInt(types.Types[TINT], 1)
+                       len := s.constInt(types.Types[types.TINT], 1)
                        s.boundsCheck(i, len, ssa.BoundsIndex, false) // checks i == 0
                        v := s.newValue1(ssa.OpArrayMake1, t, right)
                        s.assign(left.Left, v, false, 0)
@@ -3078,7 +3079,7 @@ func (s *state) assign(left *Node, right *ssa.Value, deref bool, skip skipMask)
 
        // If this assignment clobbers an entire local variable, then emit
        // OpVarDef so liveness analysis knows the variable is redefined.
-       if base := clobberBase(left); base.Op == ONAME && base.Class() != PEXTERN && skip == 0 {
+       if base := clobberBase(left); base.Op == ir.ONAME && base.Class() != ir.PEXTERN && skip == 0 {
                s.vars[memVar] = s.newValue1Apos(ssa.OpVarDef, types.TypeMem, base, s.mem(), !base.IsAutoTmp())
        }
 
@@ -3090,7 +3091,7 @@ func (s *state) assign(left *Node, right *ssa.Value, deref bool, skip skipMask)
                // is valid, even though they have type uintptr (#19168).
                // Mark it pointer type to signal the writebarrier pass to
                // insert a write barrier.
-               t = types.Types[TUNSAFEPTR]
+               t = types.Types[types.TUNSAFEPTR]
        }
        if deref {
                // Treat as a mem->mem move.
@@ -3133,10 +3134,10 @@ func (s *state) zeroVal(t *types.Type) *ssa.Value {
        case t.IsComplex():
                switch t.Size() {
                case 8:
-                       z := s.constFloat32(types.Types[TFLOAT32], 0)
+                       z := s.constFloat32(types.Types[types.TFLOAT32], 0)
                        return s.entryNewValue2(ssa.OpComplexMake, t, z, z)
                case 16:
-                       z := s.constFloat64(types.Types[TFLOAT64], 0)
+                       z := s.constFloat64(types.Types[types.TFLOAT64], 0)
                        return s.entryNewValue2(ssa.OpComplexMake, t, z, z)
                default:
                        s.Fatalf("bad sized complex type %v", t)
@@ -3190,38 +3191,38 @@ var softFloatOps map[ssa.Op]sfRtCallDef
 func softfloatInit() {
        // Some of these operations get transformed by sfcall.
        softFloatOps = map[ssa.Op]sfRtCallDef{
-               ssa.OpAdd32F: sfRtCallDef{sysfunc("fadd32"), TFLOAT32},
-               ssa.OpAdd64F: sfRtCallDef{sysfunc("fadd64"), TFLOAT64},
-               ssa.OpSub32F: sfRtCallDef{sysfunc("fadd32"), TFLOAT32},
-               ssa.OpSub64F: sfRtCallDef{sysfunc("fadd64"), TFLOAT64},
-               ssa.OpMul32F: sfRtCallDef{sysfunc("fmul32"), TFLOAT32},
-               ssa.OpMul64F: sfRtCallDef{sysfunc("fmul64"), TFLOAT64},
-               ssa.OpDiv32F: sfRtCallDef{sysfunc("fdiv32"), TFLOAT32},
-               ssa.OpDiv64F: sfRtCallDef{sysfunc("fdiv64"), TFLOAT64},
-
-               ssa.OpEq64F:   sfRtCallDef{sysfunc("feq64"), TBOOL},
-               ssa.OpEq32F:   sfRtCallDef{sysfunc("feq32"), TBOOL},
-               ssa.OpNeq64F:  sfRtCallDef{sysfunc("feq64"), TBOOL},
-               ssa.OpNeq32F:  sfRtCallDef{sysfunc("feq32"), TBOOL},
-               ssa.OpLess64F: sfRtCallDef{sysfunc("fgt64"), TBOOL},
-               ssa.OpLess32F: sfRtCallDef{sysfunc("fgt32"), TBOOL},
-               ssa.OpLeq64F:  sfRtCallDef{sysfunc("fge64"), TBOOL},
-               ssa.OpLeq32F:  sfRtCallDef{sysfunc("fge32"), TBOOL},
-
-               ssa.OpCvt32to32F:  sfRtCallDef{sysfunc("fint32to32"), TFLOAT32},
-               ssa.OpCvt32Fto32:  sfRtCallDef{sysfunc("f32toint32"), TINT32},
-               ssa.OpCvt64to32F:  sfRtCallDef{sysfunc("fint64to32"), TFLOAT32},
-               ssa.OpCvt32Fto64:  sfRtCallDef{sysfunc("f32toint64"), TINT64},
-               ssa.OpCvt64Uto32F: sfRtCallDef{sysfunc("fuint64to32"), TFLOAT32},
-               ssa.OpCvt32Fto64U: sfRtCallDef{sysfunc("f32touint64"), TUINT64},
-               ssa.OpCvt32to64F:  sfRtCallDef{sysfunc("fint32to64"), TFLOAT64},
-               ssa.OpCvt64Fto32:  sfRtCallDef{sysfunc("f64toint32"), TINT32},
-               ssa.OpCvt64to64F:  sfRtCallDef{sysfunc("fint64to64"), TFLOAT64},
-               ssa.OpCvt64Fto64:  sfRtCallDef{sysfunc("f64toint64"), TINT64},
-               ssa.OpCvt64Uto64F: sfRtCallDef{sysfunc("fuint64to64"), TFLOAT64},
-               ssa.OpCvt64Fto64U: sfRtCallDef{sysfunc("f64touint64"), TUINT64},
-               ssa.OpCvt32Fto64F: sfRtCallDef{sysfunc("f32to64"), TFLOAT64},
-               ssa.OpCvt64Fto32F: sfRtCallDef{sysfunc("f64to32"), TFLOAT32},
+               ssa.OpAdd32F: sfRtCallDef{sysfunc("fadd32"), types.TFLOAT32},
+               ssa.OpAdd64F: sfRtCallDef{sysfunc("fadd64"), types.TFLOAT64},
+               ssa.OpSub32F: sfRtCallDef{sysfunc("fadd32"), types.TFLOAT32},
+               ssa.OpSub64F: sfRtCallDef{sysfunc("fadd64"), types.TFLOAT64},
+               ssa.OpMul32F: sfRtCallDef{sysfunc("fmul32"), types.TFLOAT32},
+               ssa.OpMul64F: sfRtCallDef{sysfunc("fmul64"), types.TFLOAT64},
+               ssa.OpDiv32F: sfRtCallDef{sysfunc("fdiv32"), types.TFLOAT32},
+               ssa.OpDiv64F: sfRtCallDef{sysfunc("fdiv64"), types.TFLOAT64},
+
+               ssa.OpEq64F:   sfRtCallDef{sysfunc("feq64"), types.TBOOL},
+               ssa.OpEq32F:   sfRtCallDef{sysfunc("feq32"), types.TBOOL},
+               ssa.OpNeq64F:  sfRtCallDef{sysfunc("feq64"), types.TBOOL},
+               ssa.OpNeq32F:  sfRtCallDef{sysfunc("feq32"), types.TBOOL},
+               ssa.OpLess64F: sfRtCallDef{sysfunc("fgt64"), types.TBOOL},
+               ssa.OpLess32F: sfRtCallDef{sysfunc("fgt32"), types.TBOOL},
+               ssa.OpLeq64F:  sfRtCallDef{sysfunc("fge64"), types.TBOOL},
+               ssa.OpLeq32F:  sfRtCallDef{sysfunc("fge32"), types.TBOOL},
+
+               ssa.OpCvt32to32F:  sfRtCallDef{sysfunc("fint32to32"), types.TFLOAT32},
+               ssa.OpCvt32Fto32:  sfRtCallDef{sysfunc("f32toint32"), types.TINT32},
+               ssa.OpCvt64to32F:  sfRtCallDef{sysfunc("fint64to32"), types.TFLOAT32},
+               ssa.OpCvt32Fto64:  sfRtCallDef{sysfunc("f32toint64"), types.TINT64},
+               ssa.OpCvt64Uto32F: sfRtCallDef{sysfunc("fuint64to32"), types.TFLOAT32},
+               ssa.OpCvt32Fto64U: sfRtCallDef{sysfunc("f32touint64"), types.TUINT64},
+               ssa.OpCvt32to64F:  sfRtCallDef{sysfunc("fint32to64"), types.TFLOAT64},
+               ssa.OpCvt64Fto32:  sfRtCallDef{sysfunc("f64toint32"), types.TINT32},
+               ssa.OpCvt64to64F:  sfRtCallDef{sysfunc("fint64to64"), types.TFLOAT64},
+               ssa.OpCvt64Fto64:  sfRtCallDef{sysfunc("f64toint64"), types.TINT64},
+               ssa.OpCvt64Uto64F: sfRtCallDef{sysfunc("fuint64to64"), types.TFLOAT64},
+               ssa.OpCvt64Fto64U: sfRtCallDef{sysfunc("f64touint64"), types.TUINT64},
+               ssa.OpCvt32Fto64F: sfRtCallDef{sysfunc("f32to64"), types.TFLOAT64},
+               ssa.OpCvt64Fto32F: sfRtCallDef{sysfunc("f64to32"), types.TFLOAT32},
        }
 }
 
@@ -3237,7 +3238,7 @@ func (s *state) sfcall(op ssa.Op, args ...*ssa.Value) (*ssa.Value, bool) {
                        args[0], args[1] = args[1], args[0]
                case ssa.OpSub32F,
                        ssa.OpSub64F:
-                       args[1] = s.newValue1(s.ssaOp(ONEG, types.Types[callDef.rtype]), args[1].Type, args[1])
+                       args[1] = s.newValue1(s.ssaOp(ir.ONEG, types.Types[callDef.rtype]), args[1].Type, args[1])
                }
 
                result := s.rtcall(callDef.rtfn, true, []*types.Type{types.Types[callDef.rtype]}, args...)[0]
@@ -3253,7 +3254,7 @@ var intrinsics map[intrinsicKey]intrinsicBuilder
 
 // An intrinsicBuilder converts a call node n into an ssa value that
 // implements that call as an intrinsic. args is a list of arguments to the func.
-type intrinsicBuilder func(s *state, n *Node, args []*ssa.Value) *ssa.Value
+type intrinsicBuilder func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value
 
 type intrinsicKey struct {
        arch *sys.Arch
@@ -3318,7 +3319,7 @@ func init() {
        /******** runtime ********/
        if !instrumenting {
                add("runtime", "slicebytetostringtmp",
-                       func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+                       func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
                                // Compiler frontend optimizations emit OBYTES2STRTMP nodes
                                // for the backend instead of slicebytetostringtmp calls
                                // when not instrumenting.
@@ -3327,98 +3328,98 @@ func init() {
                        all...)
        }
        addF("runtime/internal/math", "MulUintptr",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
                        if s.config.PtrSize == 4 {
-                               return s.newValue2(ssa.OpMul32uover, types.NewTuple(types.Types[TUINT], types.Types[TUINT]), args[0], args[1])
+                               return s.newValue2(ssa.OpMul32uover, types.NewTuple(types.Types[types.TUINT], types.Types[types.TUINT]), args[0], args[1])
                        }
-                       return s.newValue2(ssa.OpMul64uover, types.NewTuple(types.Types[TUINT], types.Types[TUINT]), args[0], args[1])
+                       return s.newValue2(ssa.OpMul64uover, types.NewTuple(types.Types[types.TUINT], types.Types[types.TUINT]), args[0], args[1])
                },
                sys.AMD64, sys.I386, sys.MIPS64)
        add("runtime", "KeepAlive",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
                        data := s.newValue1(ssa.OpIData, s.f.Config.Types.BytePtr, args[0])
                        s.vars[memVar] = s.newValue2(ssa.OpKeepAlive, types.TypeMem, data, s.mem())
                        return nil
                },
                all...)
        add("runtime", "getclosureptr",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
                        return s.newValue0(ssa.OpGetClosurePtr, s.f.Config.Types.Uintptr)
                },
                all...)
 
        add("runtime", "getcallerpc",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
                        return s.newValue0(ssa.OpGetCallerPC, s.f.Config.Types.Uintptr)
                },
                all...)
 
        add("runtime", "getcallersp",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
                        return s.newValue0(ssa.OpGetCallerSP, s.f.Config.Types.Uintptr)
                },
                all...)
 
        /******** runtime/internal/sys ********/
        addF("runtime/internal/sys", "Ctz32",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       return s.newValue1(ssa.OpCtz32, types.Types[TINT], args[0])
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       return s.newValue1(ssa.OpCtz32, types.Types[types.TINT], args[0])
                },
                sys.AMD64, sys.ARM64, sys.ARM, sys.S390X, sys.MIPS, sys.PPC64)
        addF("runtime/internal/sys", "Ctz64",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       return s.newValue1(ssa.OpCtz64, types.Types[TINT], args[0])
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       return s.newValue1(ssa.OpCtz64, types.Types[types.TINT], args[0])
                },
                sys.AMD64, sys.ARM64, sys.ARM, sys.S390X, sys.MIPS, sys.PPC64)
        addF("runtime/internal/sys", "Bswap32",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       return s.newValue1(ssa.OpBswap32, types.Types[TUINT32], args[0])
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       return s.newValue1(ssa.OpBswap32, types.Types[types.TUINT32], args[0])
                },
                sys.AMD64, sys.ARM64, sys.ARM, sys.S390X)
        addF("runtime/internal/sys", "Bswap64",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       return s.newValue1(ssa.OpBswap64, types.Types[TUINT64], args[0])
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       return s.newValue1(ssa.OpBswap64, types.Types[types.TUINT64], args[0])
                },
                sys.AMD64, sys.ARM64, sys.ARM, sys.S390X)
 
        /******** runtime/internal/atomic ********/
        addF("runtime/internal/atomic", "Load",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       v := s.newValue2(ssa.OpAtomicLoad32, types.NewTuple(types.Types[TUINT32], types.TypeMem), args[0], s.mem())
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       v := s.newValue2(ssa.OpAtomicLoad32, types.NewTuple(types.Types[types.TUINT32], types.TypeMem), args[0], s.mem())
                        s.vars[memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v)
-                       return s.newValue1(ssa.OpSelect0, types.Types[TUINT32], v)
+                       return s.newValue1(ssa.OpSelect0, types.Types[types.TUINT32], v)
                },
                sys.AMD64, sys.ARM64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X)
        addF("runtime/internal/atomic", "Load8",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       v := s.newValue2(ssa.OpAtomicLoad8, types.NewTuple(types.Types[TUINT8], types.TypeMem), args[0], s.mem())
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       v := s.newValue2(ssa.OpAtomicLoad8, types.NewTuple(types.Types[types.TUINT8], types.TypeMem), args[0], s.mem())
                        s.vars[memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v)
-                       return s.newValue1(ssa.OpSelect0, types.Types[TUINT8], v)
+                       return s.newValue1(ssa.OpSelect0, types.Types[types.TUINT8], v)
                },
                sys.AMD64, sys.ARM64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X)
        addF("runtime/internal/atomic", "Load64",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       v := s.newValue2(ssa.OpAtomicLoad64, types.NewTuple(types.Types[TUINT64], types.TypeMem), args[0], s.mem())
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       v := s.newValue2(ssa.OpAtomicLoad64, types.NewTuple(types.Types[types.TUINT64], types.TypeMem), args[0], s.mem())
                        s.vars[memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v)
-                       return s.newValue1(ssa.OpSelect0, types.Types[TUINT64], v)
+                       return s.newValue1(ssa.OpSelect0, types.Types[types.TUINT64], v)
                },
                sys.AMD64, sys.ARM64, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X)
        addF("runtime/internal/atomic", "LoadAcq",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       v := s.newValue2(ssa.OpAtomicLoadAcq32, types.NewTuple(types.Types[TUINT32], types.TypeMem), args[0], s.mem())
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       v := s.newValue2(ssa.OpAtomicLoadAcq32, types.NewTuple(types.Types[types.TUINT32], types.TypeMem), args[0], s.mem())
                        s.vars[memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v)
-                       return s.newValue1(ssa.OpSelect0, types.Types[TUINT32], v)
+                       return s.newValue1(ssa.OpSelect0, types.Types[types.TUINT32], v)
                },
                sys.PPC64, sys.S390X)
        addF("runtime/internal/atomic", "LoadAcq64",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       v := s.newValue2(ssa.OpAtomicLoadAcq64, types.NewTuple(types.Types[TUINT64], types.TypeMem), args[0], s.mem())
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       v := s.newValue2(ssa.OpAtomicLoadAcq64, types.NewTuple(types.Types[types.TUINT64], types.TypeMem), args[0], s.mem())
                        s.vars[memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v)
-                       return s.newValue1(ssa.OpSelect0, types.Types[TUINT64], v)
+                       return s.newValue1(ssa.OpSelect0, types.Types[types.TUINT64], v)
                },
                sys.PPC64)
        addF("runtime/internal/atomic", "Loadp",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
                        v := s.newValue2(ssa.OpAtomicLoadPtr, types.NewTuple(s.f.Config.Types.BytePtr, types.TypeMem), args[0], s.mem())
                        s.vars[memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v)
                        return s.newValue1(ssa.OpSelect0, s.f.Config.Types.BytePtr, v)
@@ -3426,65 +3427,65 @@ func init() {
                sys.AMD64, sys.ARM64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X)
 
        addF("runtime/internal/atomic", "Store",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
                        s.vars[memVar] = s.newValue3(ssa.OpAtomicStore32, types.TypeMem, args[0], args[1], s.mem())
                        return nil
                },
                sys.AMD64, sys.ARM64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X)
        addF("runtime/internal/atomic", "Store8",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
                        s.vars[memVar] = s.newValue3(ssa.OpAtomicStore8, types.TypeMem, args[0], args[1], s.mem())
                        return nil
                },
                sys.AMD64, sys.ARM64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X)
        addF("runtime/internal/atomic", "Store64",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
                        s.vars[memVar] = s.newValue3(ssa.OpAtomicStore64, types.TypeMem, args[0], args[1], s.mem())
                        return nil
                },
                sys.AMD64, sys.ARM64, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X)
        addF("runtime/internal/atomic", "StorepNoWB",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
                        s.vars[memVar] = s.newValue3(ssa.OpAtomicStorePtrNoWB, types.TypeMem, args[0], args[1], s.mem())
                        return nil
                },
                sys.AMD64, sys.ARM64, sys.MIPS, sys.MIPS64, sys.RISCV64, sys.S390X)
        addF("runtime/internal/atomic", "StoreRel",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
                        s.vars[memVar] = s.newValue3(ssa.OpAtomicStoreRel32, types.TypeMem, args[0], args[1], s.mem())
                        return nil
                },
                sys.PPC64, sys.S390X)
        addF("runtime/internal/atomic", "StoreRel64",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
                        s.vars[memVar] = s.newValue3(ssa.OpAtomicStoreRel64, types.TypeMem, args[0], args[1], s.mem())
                        return nil
                },
                sys.PPC64)
 
        addF("runtime/internal/atomic", "Xchg",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       v := s.newValue3(ssa.OpAtomicExchange32, types.NewTuple(types.Types[TUINT32], types.TypeMem), args[0], args[1], s.mem())
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       v := s.newValue3(ssa.OpAtomicExchange32, types.NewTuple(types.Types[types.TUINT32], types.TypeMem), args[0], args[1], s.mem())
                        s.vars[memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v)
-                       return s.newValue1(ssa.OpSelect0, types.Types[TUINT32], v)
+                       return s.newValue1(ssa.OpSelect0, types.Types[types.TUINT32], v)
                },
                sys.AMD64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X)
        addF("runtime/internal/atomic", "Xchg64",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       v := s.newValue3(ssa.OpAtomicExchange64, types.NewTuple(types.Types[TUINT64], types.TypeMem), args[0], args[1], s.mem())
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       v := s.newValue3(ssa.OpAtomicExchange64, types.NewTuple(types.Types[types.TUINT64], types.TypeMem), args[0], args[1], s.mem())
                        s.vars[memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v)
-                       return s.newValue1(ssa.OpSelect0, types.Types[TUINT64], v)
+                       return s.newValue1(ssa.OpSelect0, types.Types[types.TUINT64], v)
                },
                sys.AMD64, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X)
 
-       type atomicOpEmitter func(s *state, n *Node, args []*ssa.Value, op ssa.Op, typ types.EType)
+       type atomicOpEmitter func(s *state, n *ir.Node, args []*ssa.Value, op ssa.Op, typ types.EType)
 
        makeAtomicGuardedIntrinsicARM64 := func(op0, op1 ssa.Op, typ, rtyp types.EType, emit atomicOpEmitter) intrinsicBuilder {
 
-               return func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+               return func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
                        // Target Atomic feature is identified by dynamic detection
-                       addr := s.entryNewValue1A(ssa.OpAddr, types.Types[TBOOL].PtrTo(), arm64HasATOMICS, s.sb)
-                       v := s.load(types.Types[TBOOL], addr)
+                       addr := s.entryNewValue1A(ssa.OpAddr, types.Types[types.TBOOL].PtrTo(), arm64HasATOMICS, s.sb)
+                       v := s.load(types.Types[types.TBOOL], addr)
                        b := s.endBlock()
                        b.Kind = ssa.BlockIf
                        b.SetControl(v)
@@ -3507,7 +3508,7 @@ func init() {
 
                        // Merge results.
                        s.startBlock(bEnd)
-                       if rtyp == TNIL {
+                       if rtyp == types.TNIL {
                                return nil
                        } else {
                                return s.variable(n, types.Types[rtyp])
@@ -3515,115 +3516,115 @@ func init() {
                }
        }
 
-       atomicXchgXaddEmitterARM64 := func(s *state, n *Node, args []*ssa.Value, op ssa.Op, typ types.EType) {
+       atomicXchgXaddEmitterARM64 := func(s *state, n *ir.Node, args []*ssa.Value, op ssa.Op, typ types.EType) {
                v := s.newValue3(op, types.NewTuple(types.Types[typ], types.TypeMem), args[0], args[1], s.mem())
                s.vars[memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v)
                s.vars[n] = s.newValue1(ssa.OpSelect0, types.Types[typ], v)
        }
        addF("runtime/internal/atomic", "Xchg",
-               makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicExchange32, ssa.OpAtomicExchange32Variant, TUINT32, TUINT32, atomicXchgXaddEmitterARM64),
+               makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicExchange32, ssa.OpAtomicExchange32Variant, types.TUINT32, types.TUINT32, atomicXchgXaddEmitterARM64),
                sys.ARM64)
        addF("runtime/internal/atomic", "Xchg64",
-               makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicExchange64, ssa.OpAtomicExchange64Variant, TUINT64, TUINT64, atomicXchgXaddEmitterARM64),
+               makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicExchange64, ssa.OpAtomicExchange64Variant, types.TUINT64, types.TUINT64, atomicXchgXaddEmitterARM64),
                sys.ARM64)
 
        addF("runtime/internal/atomic", "Xadd",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       v := s.newValue3(ssa.OpAtomicAdd32, types.NewTuple(types.Types[TUINT32], types.TypeMem), args[0], args[1], s.mem())
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       v := s.newValue3(ssa.OpAtomicAdd32, types.NewTuple(types.Types[types.TUINT32], types.TypeMem), args[0], args[1], s.mem())
                        s.vars[memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v)
-                       return s.newValue1(ssa.OpSelect0, types.Types[TUINT32], v)
+                       return s.newValue1(ssa.OpSelect0, types.Types[types.TUINT32], v)
                },
                sys.AMD64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X)
        addF("runtime/internal/atomic", "Xadd64",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       v := s.newValue3(ssa.OpAtomicAdd64, types.NewTuple(types.Types[TUINT64], types.TypeMem), args[0], args[1], s.mem())
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       v := s.newValue3(ssa.OpAtomicAdd64, types.NewTuple(types.Types[types.TUINT64], types.TypeMem), args[0], args[1], s.mem())
                        s.vars[memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v)
-                       return s.newValue1(ssa.OpSelect0, types.Types[TUINT64], v)
+                       return s.newValue1(ssa.OpSelect0, types.Types[types.TUINT64], v)
                },
                sys.AMD64, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X)
 
        addF("runtime/internal/atomic", "Xadd",
-               makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicAdd32, ssa.OpAtomicAdd32Variant, TUINT32, TUINT32, atomicXchgXaddEmitterARM64),
+               makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicAdd32, ssa.OpAtomicAdd32Variant, types.TUINT32, types.TUINT32, atomicXchgXaddEmitterARM64),
                sys.ARM64)
        addF("runtime/internal/atomic", "Xadd64",
-               makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicAdd64, ssa.OpAtomicAdd64Variant, TUINT64, TUINT64, atomicXchgXaddEmitterARM64),
+               makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicAdd64, ssa.OpAtomicAdd64Variant, types.TUINT64, types.TUINT64, atomicXchgXaddEmitterARM64),
                sys.ARM64)
 
        addF("runtime/internal/atomic", "Cas",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
                        v := s.newValue4(ssa.OpAtomicCompareAndSwap32, types.NewTuple(types.Types[types.TBOOL], types.TypeMem), args[0], args[1], args[2], s.mem())
                        s.vars[memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v)
                        return s.newValue1(ssa.OpSelect0, types.Types[types.TBOOL], v)
                },
                sys.AMD64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X)
        addF("runtime/internal/atomic", "Cas64",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
                        v := s.newValue4(ssa.OpAtomicCompareAndSwap64, types.NewTuple(types.Types[types.TBOOL], types.TypeMem), args[0], args[1], args[2], s.mem())
                        s.vars[memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v)
                        return s.newValue1(ssa.OpSelect0, types.Types[types.TBOOL], v)
                },
                sys.AMD64, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X)
        addF("runtime/internal/atomic", "CasRel",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
                        v := s.newValue4(ssa.OpAtomicCompareAndSwap32, types.NewTuple(types.Types[types.TBOOL], types.TypeMem), args[0], args[1], args[2], s.mem())
                        s.vars[memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v)
                        return s.newValue1(ssa.OpSelect0, types.Types[types.TBOOL], v)
                },
                sys.PPC64)
 
-       atomicCasEmitterARM64 := func(s *state, n *Node, args []*ssa.Value, op ssa.Op, typ types.EType) {
+       atomicCasEmitterARM64 := func(s *state, n *ir.Node, args []*ssa.Value, op ssa.Op, typ types.EType) {
                v := s.newValue4(op, types.NewTuple(types.Types[types.TBOOL], types.TypeMem), args[0], args[1], args[2], s.mem())
                s.vars[memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v)
                s.vars[n] = s.newValue1(ssa.OpSelect0, types.Types[typ], v)
        }
 
        addF("runtime/internal/atomic", "Cas",
-               makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicCompareAndSwap32, ssa.OpAtomicCompareAndSwap32Variant, TUINT32, TBOOL, atomicCasEmitterARM64),
+               makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicCompareAndSwap32, ssa.OpAtomicCompareAndSwap32Variant, types.TUINT32, types.TBOOL, atomicCasEmitterARM64),
                sys.ARM64)
        addF("runtime/internal/atomic", "Cas64",
-               makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicCompareAndSwap64, ssa.OpAtomicCompareAndSwap64Variant, TUINT64, TBOOL, atomicCasEmitterARM64),
+               makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicCompareAndSwap64, ssa.OpAtomicCompareAndSwap64Variant, types.TUINT64, types.TBOOL, atomicCasEmitterARM64),
                sys.ARM64)
 
        addF("runtime/internal/atomic", "And8",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
                        s.vars[memVar] = s.newValue3(ssa.OpAtomicAnd8, types.TypeMem, args[0], args[1], s.mem())
                        return nil
                },
                sys.AMD64, sys.MIPS, sys.PPC64, sys.S390X)
        addF("runtime/internal/atomic", "And",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
                        s.vars[memVar] = s.newValue3(ssa.OpAtomicAnd32, types.TypeMem, args[0], args[1], s.mem())
                        return nil
                },
                sys.AMD64, sys.MIPS, sys.PPC64, sys.S390X)
        addF("runtime/internal/atomic", "Or8",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
                        s.vars[memVar] = s.newValue3(ssa.OpAtomicOr8, types.TypeMem, args[0], args[1], s.mem())
                        return nil
                },
                sys.AMD64, sys.ARM64, sys.MIPS, sys.PPC64, sys.S390X)
        addF("runtime/internal/atomic", "Or",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
                        s.vars[memVar] = s.newValue3(ssa.OpAtomicOr32, types.TypeMem, args[0], args[1], s.mem())
                        return nil
                },
                sys.AMD64, sys.MIPS, sys.PPC64, sys.S390X)
 
-       atomicAndOrEmitterARM64 := func(s *state, n *Node, args []*ssa.Value, op ssa.Op, typ types.EType) {
+       atomicAndOrEmitterARM64 := func(s *state, n *ir.Node, args []*ssa.Value, op ssa.Op, typ types.EType) {
                s.vars[memVar] = s.newValue3(op, types.TypeMem, args[0], args[1], s.mem())
        }
 
        addF("runtime/internal/atomic", "And8",
-               makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicAnd8, ssa.OpAtomicAnd8Variant, TNIL, TNIL, atomicAndOrEmitterARM64),
+               makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicAnd8, ssa.OpAtomicAnd8Variant, types.TNIL, types.TNIL, atomicAndOrEmitterARM64),
                sys.ARM64)
        addF("runtime/internal/atomic", "And",
-               makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicAnd32, ssa.OpAtomicAnd32Variant, TNIL, TNIL, atomicAndOrEmitterARM64),
+               makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicAnd32, ssa.OpAtomicAnd32Variant, types.TNIL, types.TNIL, atomicAndOrEmitterARM64),
                sys.ARM64)
        addF("runtime/internal/atomic", "Or8",
-               makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicOr8, ssa.OpAtomicOr8Variant, TNIL, TNIL, atomicAndOrEmitterARM64),
+               makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicOr8, ssa.OpAtomicOr8Variant, types.TNIL, types.TNIL, atomicAndOrEmitterARM64),
                sys.ARM64)
        addF("runtime/internal/atomic", "Or",
-               makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicOr32, ssa.OpAtomicOr32Variant, TNIL, TNIL, atomicAndOrEmitterARM64),
+               makeAtomicGuardedIntrinsicARM64(ssa.OpAtomicOr32, ssa.OpAtomicOr32Variant, types.TNIL, types.TNIL, atomicAndOrEmitterARM64),
                sys.ARM64)
 
        alias("runtime/internal/atomic", "Loadint64", "runtime/internal/atomic", "Load64", all...)
@@ -3658,57 +3659,57 @@ func init() {
 
        /******** math ********/
        addF("math", "Sqrt",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       return s.newValue1(ssa.OpSqrt, types.Types[TFLOAT64], args[0])
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       return s.newValue1(ssa.OpSqrt, types.Types[types.TFLOAT64], args[0])
                },
                sys.I386, sys.AMD64, sys.ARM, sys.ARM64, sys.MIPS, sys.MIPS64, sys.PPC64, sys.RISCV64, sys.S390X, sys.Wasm)
        addF("math", "Trunc",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       return s.newValue1(ssa.OpTrunc, types.Types[TFLOAT64], args[0])
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       return s.newValue1(ssa.OpTrunc, types.Types[types.TFLOAT64], args[0])
                },
                sys.ARM64, sys.PPC64, sys.S390X, sys.Wasm)
        addF("math", "Ceil",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       return s.newValue1(ssa.OpCeil, types.Types[TFLOAT64], args[0])
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       return s.newValue1(ssa.OpCeil, types.Types[types.TFLOAT64], args[0])
                },
                sys.ARM64, sys.PPC64, sys.S390X, sys.Wasm)
        addF("math", "Floor",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       return s.newValue1(ssa.OpFloor, types.Types[TFLOAT64], args[0])
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       return s.newValue1(ssa.OpFloor, types.Types[types.TFLOAT64], args[0])
                },
                sys.ARM64, sys.PPC64, sys.S390X, sys.Wasm)
        addF("math", "Round",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       return s.newValue1(ssa.OpRound, types.Types[TFLOAT64], args[0])
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       return s.newValue1(ssa.OpRound, types.Types[types.TFLOAT64], args[0])
                },
                sys.ARM64, sys.PPC64, sys.S390X)
        addF("math", "RoundToEven",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       return s.newValue1(ssa.OpRoundToEven, types.Types[TFLOAT64], args[0])
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       return s.newValue1(ssa.OpRoundToEven, types.Types[types.TFLOAT64], args[0])
                },
                sys.ARM64, sys.S390X, sys.Wasm)
        addF("math", "Abs",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       return s.newValue1(ssa.OpAbs, types.Types[TFLOAT64], args[0])
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       return s.newValue1(ssa.OpAbs, types.Types[types.TFLOAT64], args[0])
                },
                sys.ARM64, sys.ARM, sys.PPC64, sys.Wasm)
        addF("math", "Copysign",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       return s.newValue2(ssa.OpCopysign, types.Types[TFLOAT64], args[0], args[1])
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       return s.newValue2(ssa.OpCopysign, types.Types[types.TFLOAT64], args[0], args[1])
                },
                sys.PPC64, sys.Wasm)
        addF("math", "FMA",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       return s.newValue3(ssa.OpFMA, types.Types[TFLOAT64], args[0], args[1], args[2])
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       return s.newValue3(ssa.OpFMA, types.Types[types.TFLOAT64], args[0], args[1], args[2])
                },
                sys.ARM64, sys.PPC64, sys.S390X)
        addF("math", "FMA",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
                        if !s.config.UseFMA {
                                s.vars[n] = s.callResult(n, callNormal) // types.Types[TFLOAT64]
-                               return s.variable(n, types.Types[TFLOAT64])
+                               return s.variable(n, types.Types[types.TFLOAT64])
                        }
-                       v := s.entryNewValue0A(ssa.OpHasCPUFeature, types.Types[TBOOL], x86HasFMA)
+                       v := s.entryNewValue0A(ssa.OpHasCPUFeature, types.Types[types.TBOOL], x86HasFMA)
                        b := s.endBlock()
                        b.Kind = ssa.BlockIf
                        b.SetControl(v)
@@ -3721,7 +3722,7 @@ func init() {
 
                        // We have the intrinsic - use it directly.
                        s.startBlock(bTrue)
-                       s.vars[n] = s.newValue3(ssa.OpFMA, types.Types[TFLOAT64], args[0], args[1], args[2])
+                       s.vars[n] = s.newValue3(ssa.OpFMA, types.Types[types.TFLOAT64], args[0], args[1], args[2])
                        s.endBlock().AddEdgeTo(bEnd)
 
                        // Call the pure Go version.
@@ -3731,17 +3732,17 @@ func init() {
 
                        // Merge results.
                        s.startBlock(bEnd)
-                       return s.variable(n, types.Types[TFLOAT64])
+                       return s.variable(n, types.Types[types.TFLOAT64])
                },
                sys.AMD64)
        addF("math", "FMA",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
                        if !s.config.UseFMA {
                                s.vars[n] = s.callResult(n, callNormal) // types.Types[TFLOAT64]
-                               return s.variable(n, types.Types[TFLOAT64])
+                               return s.variable(n, types.Types[types.TFLOAT64])
                        }
-                       addr := s.entryNewValue1A(ssa.OpAddr, types.Types[TBOOL].PtrTo(), armHasVFPv4, s.sb)
-                       v := s.load(types.Types[TBOOL], addr)
+                       addr := s.entryNewValue1A(ssa.OpAddr, types.Types[types.TBOOL].PtrTo(), armHasVFPv4, s.sb)
+                       v := s.load(types.Types[types.TBOOL], addr)
                        b := s.endBlock()
                        b.Kind = ssa.BlockIf
                        b.SetControl(v)
@@ -3754,7 +3755,7 @@ func init() {
 
                        // We have the intrinsic - use it directly.
                        s.startBlock(bTrue)
-                       s.vars[n] = s.newValue3(ssa.OpFMA, types.Types[TFLOAT64], args[0], args[1], args[2])
+                       s.vars[n] = s.newValue3(ssa.OpFMA, types.Types[types.TFLOAT64], args[0], args[1], args[2])
                        s.endBlock().AddEdgeTo(bEnd)
 
                        // Call the pure Go version.
@@ -3764,13 +3765,13 @@ func init() {
 
                        // Merge results.
                        s.startBlock(bEnd)
-                       return s.variable(n, types.Types[TFLOAT64])
+                       return s.variable(n, types.Types[types.TFLOAT64])
                },
                sys.ARM)
 
-       makeRoundAMD64 := func(op ssa.Op) func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-               return func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       v := s.entryNewValue0A(ssa.OpHasCPUFeature, types.Types[TBOOL], x86HasSSE41)
+       makeRoundAMD64 := func(op ssa.Op) func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+               return func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       v := s.entryNewValue0A(ssa.OpHasCPUFeature, types.Types[types.TBOOL], x86HasSSE41)
                        b := s.endBlock()
                        b.Kind = ssa.BlockIf
                        b.SetControl(v)
@@ -3783,7 +3784,7 @@ func init() {
 
                        // We have the intrinsic - use it directly.
                        s.startBlock(bTrue)
-                       s.vars[n] = s.newValue1(op, types.Types[TFLOAT64], args[0])
+                       s.vars[n] = s.newValue1(op, types.Types[types.TFLOAT64], args[0])
                        s.endBlock().AddEdgeTo(bEnd)
 
                        // Call the pure Go version.
@@ -3793,7 +3794,7 @@ func init() {
 
                        // Merge results.
                        s.startBlock(bEnd)
-                       return s.variable(n, types.Types[TFLOAT64])
+                       return s.variable(n, types.Types[types.TFLOAT64])
                }
        }
        addF("math", "RoundToEven",
@@ -3811,55 +3812,55 @@ func init() {
 
        /******** math/bits ********/
        addF("math/bits", "TrailingZeros64",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       return s.newValue1(ssa.OpCtz64, types.Types[TINT], args[0])
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       return s.newValue1(ssa.OpCtz64, types.Types[types.TINT], args[0])
                },
                sys.AMD64, sys.ARM64, sys.ARM, sys.S390X, sys.MIPS, sys.PPC64, sys.Wasm)
        addF("math/bits", "TrailingZeros32",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       return s.newValue1(ssa.OpCtz32, types.Types[TINT], args[0])
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       return s.newValue1(ssa.OpCtz32, types.Types[types.TINT], args[0])
                },
                sys.AMD64, sys.ARM64, sys.ARM, sys.S390X, sys.MIPS, sys.PPC64, sys.Wasm)
        addF("math/bits", "TrailingZeros16",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       x := s.newValue1(ssa.OpZeroExt16to32, types.Types[TUINT32], args[0])
-                       c := s.constInt32(types.Types[TUINT32], 1<<16)
-                       y := s.newValue2(ssa.OpOr32, types.Types[TUINT32], x, c)
-                       return s.newValue1(ssa.OpCtz32, types.Types[TINT], y)
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       x := s.newValue1(ssa.OpZeroExt16to32, types.Types[types.TUINT32], args[0])
+                       c := s.constInt32(types.Types[types.TUINT32], 1<<16)
+                       y := s.newValue2(ssa.OpOr32, types.Types[types.TUINT32], x, c)
+                       return s.newValue1(ssa.OpCtz32, types.Types[types.TINT], y)
                },
                sys.MIPS)
        addF("math/bits", "TrailingZeros16",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       return s.newValue1(ssa.OpCtz16, types.Types[TINT], args[0])
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       return s.newValue1(ssa.OpCtz16, types.Types[types.TINT], args[0])
                },
                sys.AMD64, sys.I386, sys.ARM, sys.ARM64, sys.Wasm)
        addF("math/bits", "TrailingZeros16",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       x := s.newValue1(ssa.OpZeroExt16to64, types.Types[TUINT64], args[0])
-                       c := s.constInt64(types.Types[TUINT64], 1<<16)
-                       y := s.newValue2(ssa.OpOr64, types.Types[TUINT64], x, c)
-                       return s.newValue1(ssa.OpCtz64, types.Types[TINT], y)
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       x := s.newValue1(ssa.OpZeroExt16to64, types.Types[types.TUINT64], args[0])
+                       c := s.constInt64(types.Types[types.TUINT64], 1<<16)
+                       y := s.newValue2(ssa.OpOr64, types.Types[types.TUINT64], x, c)
+                       return s.newValue1(ssa.OpCtz64, types.Types[types.TINT], y)
                },
                sys.S390X, sys.PPC64)
        addF("math/bits", "TrailingZeros8",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       x := s.newValue1(ssa.OpZeroExt8to32, types.Types[TUINT32], args[0])
-                       c := s.constInt32(types.Types[TUINT32], 1<<8)
-                       y := s.newValue2(ssa.OpOr32, types.Types[TUINT32], x, c)
-                       return s.newValue1(ssa.OpCtz32, types.Types[TINT], y)
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       x := s.newValue1(ssa.OpZeroExt8to32, types.Types[types.TUINT32], args[0])
+                       c := s.constInt32(types.Types[types.TUINT32], 1<<8)
+                       y := s.newValue2(ssa.OpOr32, types.Types[types.TUINT32], x, c)
+                       return s.newValue1(ssa.OpCtz32, types.Types[types.TINT], y)
                },
                sys.MIPS)
        addF("math/bits", "TrailingZeros8",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       return s.newValue1(ssa.OpCtz8, types.Types[TINT], args[0])
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       return s.newValue1(ssa.OpCtz8, types.Types[types.TINT], args[0])
                },
                sys.AMD64, sys.ARM, sys.ARM64, sys.Wasm)
        addF("math/bits", "TrailingZeros8",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       x := s.newValue1(ssa.OpZeroExt8to64, types.Types[TUINT64], args[0])
-                       c := s.constInt64(types.Types[TUINT64], 1<<8)
-                       y := s.newValue2(ssa.OpOr64, types.Types[TUINT64], x, c)
-                       return s.newValue1(ssa.OpCtz64, types.Types[TINT], y)
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       x := s.newValue1(ssa.OpZeroExt8to64, types.Types[types.TUINT64], args[0])
+                       c := s.constInt64(types.Types[types.TUINT64], 1<<8)
+                       y := s.newValue2(ssa.OpOr64, types.Types[types.TUINT64], x, c)
+                       return s.newValue1(ssa.OpCtz64, types.Types[types.TINT], y)
                },
                sys.S390X)
        alias("math/bits", "ReverseBytes64", "runtime/internal/sys", "Bswap64", all...)
@@ -3867,116 +3868,116 @@ func init() {
        // ReverseBytes inlines correctly, no need to intrinsify it.
        // ReverseBytes16 lowers to a rotate, no need for anything special here.
        addF("math/bits", "Len64",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       return s.newValue1(ssa.OpBitLen64, types.Types[TINT], args[0])
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       return s.newValue1(ssa.OpBitLen64, types.Types[types.TINT], args[0])
                },
                sys.AMD64, sys.ARM64, sys.ARM, sys.S390X, sys.MIPS, sys.PPC64, sys.Wasm)
        addF("math/bits", "Len32",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       return s.newValue1(ssa.OpBitLen32, types.Types[TINT], args[0])
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       return s.newValue1(ssa.OpBitLen32, types.Types[types.TINT], args[0])
                },
                sys.AMD64, sys.ARM64)
        addF("math/bits", "Len32",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
                        if s.config.PtrSize == 4 {
-                               return s.newValue1(ssa.OpBitLen32, types.Types[TINT], args[0])
+                               return s.newValue1(ssa.OpBitLen32, types.Types[types.TINT], args[0])
                        }
-                       x := s.newValue1(ssa.OpZeroExt32to64, types.Types[TUINT64], args[0])
-                       return s.newValue1(ssa.OpBitLen64, types.Types[TINT], x)
+                       x := s.newValue1(ssa.OpZeroExt32to64, types.Types[types.TUINT64], args[0])
+                       return s.newValue1(ssa.OpBitLen64, types.Types[types.TINT], x)
                },
                sys.ARM, sys.S390X, sys.MIPS, sys.PPC64, sys.Wasm)
        addF("math/bits", "Len16",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
                        if s.config.PtrSize == 4 {
-                               x := s.newValue1(ssa.OpZeroExt16to32, types.Types[TUINT32], args[0])
-                               return s.newValue1(ssa.OpBitLen32, types.Types[TINT], x)
+                               x := s.newValue1(ssa.OpZeroExt16to32, types.Types[types.TUINT32], args[0])
+                               return s.newValue1(ssa.OpBitLen32, types.Types[types.TINT], x)
                        }
-                       x := s.newValue1(ssa.OpZeroExt16to64, types.Types[TUINT64], args[0])
-                       return s.newValue1(ssa.OpBitLen64, types.Types[TINT], x)
+                       x := s.newValue1(ssa.OpZeroExt16to64, types.Types[types.TUINT64], args[0])
+                       return s.newValue1(ssa.OpBitLen64, types.Types[types.TINT], x)
                },
                sys.ARM64, sys.ARM, sys.S390X, sys.MIPS, sys.PPC64, sys.Wasm)
        addF("math/bits", "Len16",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       return s.newValue1(ssa.OpBitLen16, types.Types[TINT], args[0])
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       return s.newValue1(ssa.OpBitLen16, types.Types[types.TINT], args[0])
                },
                sys.AMD64)
        addF("math/bits", "Len8",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
                        if s.config.PtrSize == 4 {
-                               x := s.newValue1(ssa.OpZeroExt8to32, types.Types[TUINT32], args[0])
-                               return s.newValue1(ssa.OpBitLen32, types.Types[TINT], x)
+                               x := s.newValue1(ssa.OpZeroExt8to32, types.Types[types.TUINT32], args[0])
+                               return s.newValue1(ssa.OpBitLen32, types.Types[types.TINT], x)
                        }
-                       x := s.newValue1(ssa.OpZeroExt8to64, types.Types[TUINT64], args[0])
-                       return s.newValue1(ssa.OpBitLen64, types.Types[TINT], x)
+                       x := s.newValue1(ssa.OpZeroExt8to64, types.Types[types.TUINT64], args[0])
+                       return s.newValue1(ssa.OpBitLen64, types.Types[types.TINT], x)
                },
                sys.ARM64, sys.ARM, sys.S390X, sys.MIPS, sys.PPC64, sys.Wasm)
        addF("math/bits", "Len8",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       return s.newValue1(ssa.OpBitLen8, types.Types[TINT], args[0])
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       return s.newValue1(ssa.OpBitLen8, types.Types[types.TINT], args[0])
                },
                sys.AMD64)
        addF("math/bits", "Len",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
                        if s.config.PtrSize == 4 {
-                               return s.newValue1(ssa.OpBitLen32, types.Types[TINT], args[0])
+                               return s.newValue1(ssa.OpBitLen32, types.Types[types.TINT], args[0])
                        }
-                       return s.newValue1(ssa.OpBitLen64, types.Types[TINT], args[0])
+                       return s.newValue1(ssa.OpBitLen64, types.Types[types.TINT], args[0])
                },
                sys.AMD64, sys.ARM64, sys.ARM, sys.S390X, sys.MIPS, sys.PPC64, sys.Wasm)
        // LeadingZeros is handled because it trivially calls Len.
        addF("math/bits", "Reverse64",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       return s.newValue1(ssa.OpBitRev64, types.Types[TINT], args[0])
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       return s.newValue1(ssa.OpBitRev64, types.Types[types.TINT], args[0])
                },
                sys.ARM64)
        addF("math/bits", "Reverse32",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       return s.newValue1(ssa.OpBitRev32, types.Types[TINT], args[0])
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       return s.newValue1(ssa.OpBitRev32, types.Types[types.TINT], args[0])
                },
                sys.ARM64)
        addF("math/bits", "Reverse16",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       return s.newValue1(ssa.OpBitRev16, types.Types[TINT], args[0])
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       return s.newValue1(ssa.OpBitRev16, types.Types[types.TINT], args[0])
                },
                sys.ARM64)
        addF("math/bits", "Reverse8",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       return s.newValue1(ssa.OpBitRev8, types.Types[TINT], args[0])
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       return s.newValue1(ssa.OpBitRev8, types.Types[types.TINT], args[0])
                },
                sys.ARM64)
        addF("math/bits", "Reverse",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
                        if s.config.PtrSize == 4 {
-                               return s.newValue1(ssa.OpBitRev32, types.Types[TINT], args[0])
+                               return s.newValue1(ssa.OpBitRev32, types.Types[types.TINT], args[0])
                        }
-                       return s.newValue1(ssa.OpBitRev64, types.Types[TINT], args[0])
+                       return s.newValue1(ssa.OpBitRev64, types.Types[types.TINT], args[0])
                },
                sys.ARM64)
        addF("math/bits", "RotateLeft8",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       return s.newValue2(ssa.OpRotateLeft8, types.Types[TUINT8], args[0], args[1])
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       return s.newValue2(ssa.OpRotateLeft8, types.Types[types.TUINT8], args[0], args[1])
                },
                sys.AMD64)
        addF("math/bits", "RotateLeft16",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       return s.newValue2(ssa.OpRotateLeft16, types.Types[TUINT16], args[0], args[1])
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       return s.newValue2(ssa.OpRotateLeft16, types.Types[types.TUINT16], args[0], args[1])
                },
                sys.AMD64)
        addF("math/bits", "RotateLeft32",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       return s.newValue2(ssa.OpRotateLeft32, types.Types[TUINT32], args[0], args[1])
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       return s.newValue2(ssa.OpRotateLeft32, types.Types[types.TUINT32], args[0], args[1])
                },
                sys.AMD64, sys.ARM, sys.ARM64, sys.S390X, sys.PPC64, sys.Wasm)
        addF("math/bits", "RotateLeft64",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       return s.newValue2(ssa.OpRotateLeft64, types.Types[TUINT64], args[0], args[1])
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       return s.newValue2(ssa.OpRotateLeft64, types.Types[types.TUINT64], args[0], args[1])
                },
                sys.AMD64, sys.ARM64, sys.S390X, sys.PPC64, sys.Wasm)
        alias("math/bits", "RotateLeft", "math/bits", "RotateLeft64", p8...)
 
-       makeOnesCountAMD64 := func(op64 ssa.Op, op32 ssa.Op) func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-               return func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       v := s.entryNewValue0A(ssa.OpHasCPUFeature, types.Types[TBOOL], x86HasPOPCNT)
+       makeOnesCountAMD64 := func(op64 ssa.Op, op32 ssa.Op) func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+               return func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       v := s.entryNewValue0A(ssa.OpHasCPUFeature, types.Types[types.TBOOL], x86HasPOPCNT)
                        b := s.endBlock()
                        b.Kind = ssa.BlockIf
                        b.SetControl(v)
@@ -3993,7 +3994,7 @@ func init() {
                        if s.config.PtrSize == 4 {
                                op = op32
                        }
-                       s.vars[n] = s.newValue1(op, types.Types[TINT], args[0])
+                       s.vars[n] = s.newValue1(op, types.Types[types.TINT], args[0])
                        s.endBlock().AddEdgeTo(bEnd)
 
                        // Call the pure Go version.
@@ -4003,67 +4004,67 @@ func init() {
 
                        // Merge results.
                        s.startBlock(bEnd)
-                       return s.variable(n, types.Types[TINT])
+                       return s.variable(n, types.Types[types.TINT])
                }
        }
        addF("math/bits", "OnesCount64",
                makeOnesCountAMD64(ssa.OpPopCount64, ssa.OpPopCount64),
                sys.AMD64)
        addF("math/bits", "OnesCount64",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       return s.newValue1(ssa.OpPopCount64, types.Types[TINT], args[0])
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       return s.newValue1(ssa.OpPopCount64, types.Types[types.TINT], args[0])
                },
                sys.PPC64, sys.ARM64, sys.S390X, sys.Wasm)
        addF("math/bits", "OnesCount32",
                makeOnesCountAMD64(ssa.OpPopCount32, ssa.OpPopCount32),
                sys.AMD64)
        addF("math/bits", "OnesCount32",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       return s.newValue1(ssa.OpPopCount32, types.Types[TINT], args[0])
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       return s.newValue1(ssa.OpPopCount32, types.Types[types.TINT], args[0])
                },
                sys.PPC64, sys.ARM64, sys.S390X, sys.Wasm)
        addF("math/bits", "OnesCount16",
                makeOnesCountAMD64(ssa.OpPopCount16, ssa.OpPopCount16),
                sys.AMD64)
        addF("math/bits", "OnesCount16",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       return s.newValue1(ssa.OpPopCount16, types.Types[TINT], args[0])
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       return s.newValue1(ssa.OpPopCount16, types.Types[types.TINT], args[0])
                },
                sys.ARM64, sys.S390X, sys.PPC64, sys.Wasm)
        addF("math/bits", "OnesCount8",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       return s.newValue1(ssa.OpPopCount8, types.Types[TINT], args[0])
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       return s.newValue1(ssa.OpPopCount8, types.Types[types.TINT], args[0])
                },
                sys.S390X, sys.PPC64, sys.Wasm)
        addF("math/bits", "OnesCount",
                makeOnesCountAMD64(ssa.OpPopCount64, ssa.OpPopCount32),
                sys.AMD64)
        addF("math/bits", "Mul64",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       return s.newValue2(ssa.OpMul64uhilo, types.NewTuple(types.Types[TUINT64], types.Types[TUINT64]), args[0], args[1])
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       return s.newValue2(ssa.OpMul64uhilo, types.NewTuple(types.Types[types.TUINT64], types.Types[types.TUINT64]), args[0], args[1])
                },
                sys.AMD64, sys.ARM64, sys.PPC64, sys.S390X, sys.MIPS64)
        alias("math/bits", "Mul", "math/bits", "Mul64", sys.ArchAMD64, sys.ArchARM64, sys.ArchPPC64, sys.ArchS390X, sys.ArchMIPS64, sys.ArchMIPS64LE)
        addF("math/bits", "Add64",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       return s.newValue3(ssa.OpAdd64carry, types.NewTuple(types.Types[TUINT64], types.Types[TUINT64]), args[0], args[1], args[2])
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       return s.newValue3(ssa.OpAdd64carry, types.NewTuple(types.Types[types.TUINT64], types.Types[types.TUINT64]), args[0], args[1], args[2])
                },
                sys.AMD64, sys.ARM64, sys.PPC64, sys.S390X)
        alias("math/bits", "Add", "math/bits", "Add64", sys.ArchAMD64, sys.ArchARM64, sys.ArchPPC64, sys.ArchS390X)
        addF("math/bits", "Sub64",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       return s.newValue3(ssa.OpSub64borrow, types.NewTuple(types.Types[TUINT64], types.Types[TUINT64]), args[0], args[1], args[2])
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       return s.newValue3(ssa.OpSub64borrow, types.NewTuple(types.Types[types.TUINT64], types.Types[types.TUINT64]), args[0], args[1], args[2])
                },
                sys.AMD64, sys.ARM64, sys.S390X)
        alias("math/bits", "Sub", "math/bits", "Sub64", sys.ArchAMD64, sys.ArchARM64, sys.ArchS390X)
        addF("math/bits", "Div64",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
                        // check for divide-by-zero/overflow and panic with appropriate message
-                       cmpZero := s.newValue2(s.ssaOp(ONE, types.Types[TUINT64]), types.Types[TBOOL], args[2], s.zeroVal(types.Types[TUINT64]))
+                       cmpZero := s.newValue2(s.ssaOp(ir.ONE, types.Types[types.TUINT64]), types.Types[types.TBOOL], args[2], s.zeroVal(types.Types[types.TUINT64]))
                        s.check(cmpZero, panicdivide)
-                       cmpOverflow := s.newValue2(s.ssaOp(OLT, types.Types[TUINT64]), types.Types[TBOOL], args[0], args[2])
+                       cmpOverflow := s.newValue2(s.ssaOp(ir.OLT, types.Types[types.TUINT64]), types.Types[types.TBOOL], args[0], args[2])
                        s.check(cmpOverflow, panicoverflow)
-                       return s.newValue3(ssa.OpDiv128u, types.NewTuple(types.Types[TUINT64], types.Types[TUINT64]), args[0], args[1], args[2])
+                       return s.newValue3(ssa.OpDiv128u, types.NewTuple(types.Types[types.TUINT64], types.Types[types.TUINT64]), args[0], args[1], args[2])
                },
                sys.AMD64)
        alias("math/bits", "Div", "math/bits", "Div64", sys.ArchAMD64)
@@ -4117,8 +4118,8 @@ func init() {
 
        /******** math/big ********/
        add("math/big", "mulWW",
-               func(s *state, n *Node, args []*ssa.Value) *ssa.Value {
-                       return s.newValue2(ssa.OpMul64uhilo, types.NewTuple(types.Types[TUINT64], types.Types[TUINT64]), args[0], args[1])
+               func(s *state, n *ir.Node, args []*ssa.Value) *ssa.Value {
+                       return s.newValue2(ssa.OpMul64uhilo, types.NewTuple(types.Types[types.TUINT64], types.Types[types.TUINT64]), args[0], args[1])
                },
                sys.ArchAMD64, sys.ArchARM64, sys.ArchPPC64LE, sys.ArchPPC64, sys.ArchS390X)
 }
@@ -4130,7 +4131,7 @@ func findIntrinsic(sym *types.Sym) intrinsicBuilder {
                return nil
        }
        pkg := sym.Pkg.Path
-       if sym.Pkg == localpkg {
+       if sym.Pkg == ir.LocalPkg {
                pkg = base.Ctxt.Pkgpath
        }
        if base.Flag.Race && pkg == "sync/atomic" {
@@ -4155,7 +4156,7 @@ func findIntrinsic(sym *types.Sym) intrinsicBuilder {
        return intrinsics[intrinsicKey{thearch.LinkArch.Arch, pkg, fn}]
 }
 
-func isIntrinsicCall(n *Node) bool {
+func isIntrinsicCall(n *ir.Node) bool {
        if n == nil || n.Left == nil {
                return false
        }
@@ -4163,7 +4164,7 @@ func isIntrinsicCall(n *Node) bool {
 }
 
 // intrinsicCall converts a call to a recognized intrinsic function into the intrinsic SSA operation.
-func (s *state) intrinsicCall(n *Node) *ssa.Value {
+func (s *state) intrinsicCall(n *ir.Node) *ssa.Value {
        v := findIntrinsic(n.Left.Sym)(s, n, s.intrinsicArgs(n))
        if ssa.IntrinsicsDebug > 0 {
                x := v
@@ -4179,15 +4180,15 @@ func (s *state) intrinsicCall(n *Node) *ssa.Value {
 }
 
 // intrinsicArgs extracts args from n, evaluates them to SSA values, and returns them.
-func (s *state) intrinsicArgs(n *Node) []*ssa.Value {
+func (s *state) intrinsicArgs(n *ir.Node) []*ssa.Value {
        // Construct map of temps; see comments in s.call about the structure of n.
-       temps := map[*Node]*ssa.Value{}
+       temps := map[*ir.Node]*ssa.Value{}
        for _, a := range n.List.Slice() {
-               if a.Op != OAS {
+               if a.Op != ir.OAS {
                        s.Fatalf("non-assignment as a temp function argument %v", a.Op)
                }
                l, r := a.Left, a.Right
-               if l.Op != ONAME {
+               if l.Op != ir.ONAME {
                        s.Fatalf("non-ONAME temp function argument %v", a.Op)
                }
                // Evaluate and store to "temporary".
@@ -4214,7 +4215,7 @@ func (s *state) intrinsicArgs(n *Node) []*ssa.Value {
 // call. We will also record funcdata information on where the args are stored
 // (as well as the deferBits variable), and this will enable us to run the proper
 // defer calls during panics.
-func (s *state) openDeferRecord(n *Node) {
+func (s *state) openDeferRecord(n *ir.Node) {
        // Do any needed expression evaluation for the args (including the
        // receiver, if any). This may be evaluating something like 'autotmp_3 =
        // once.mutex'. Such a statement will create a mapping in s.vars[] from
@@ -4223,24 +4224,24 @@ func (s *state) openDeferRecord(n *Node) {
        s.stmtList(n.List)
 
        var args []*ssa.Value
-       var argNodes []*Node
+       var argNodes []*ir.Node
 
        opendefer := &openDeferInfo{
                n: n,
        }
        fn := n.Left
-       if n.Op == OCALLFUNC {
+       if n.Op == ir.OCALLFUNC {
                // We must always store the function value in a stack slot for the
                // runtime panic code to use. But in the defer exit code, we will
                // call the function directly if it is a static function.
                closureVal := s.expr(fn)
                closure := s.openDeferSave(nil, fn.Type, closureVal)
-               opendefer.closureNode = closure.Aux.(*Node)
-               if !(fn.Op == ONAME && fn.Class() == PFUNC) {
+               opendefer.closureNode = closure.Aux.(*ir.Node)
+               if !(fn.Op == ir.ONAME && fn.Class() == ir.PFUNC) {
                        opendefer.closure = closure
                }
-       } else if n.Op == OCALLMETH {
-               if fn.Op != ODOTMETH {
+       } else if n.Op == ir.OCALLMETH {
+               if fn.Op != ir.ODOTMETH {
                        base.Fatalf("OCALLMETH: n.Left not an ODOTMETH: %v", fn)
                }
                closureVal := s.getMethodClosure(fn)
@@ -4248,9 +4249,9 @@ func (s *state) openDeferRecord(n *Node) {
                // runtime panic code to use. But in the defer exit code, we will
                // call the method directly.
                closure := s.openDeferSave(nil, fn.Type, closureVal)
-               opendefer.closureNode = closure.Aux.(*Node)
+               opendefer.closureNode = closure.Aux.(*ir.Node)
        } else {
-               if fn.Op != ODOTINTER {
+               if fn.Op != ir.ODOTINTER {
                        base.Fatalf("OCALLINTER: n.Left not an ODOTINTER: %v", fn.Op)
                }
                closure, rcvr := s.getClosureAndRcvr(fn)
@@ -4258,8 +4259,8 @@ func (s *state) openDeferRecord(n *Node) {
                // Important to get the receiver type correct, so it is recognized
                // as a pointer for GC purposes.
                opendefer.rcvr = s.openDeferSave(nil, fn.Type.Recv().Type, rcvr)
-               opendefer.closureNode = opendefer.closure.Aux.(*Node)
-               opendefer.rcvrNode = opendefer.rcvr.Aux.(*Node)
+               opendefer.closureNode = opendefer.closure.Aux.(*ir.Node)
+               opendefer.rcvrNode = opendefer.rcvr.Aux.(*ir.Node)
        }
        for _, argn := range n.Rlist.Slice() {
                var v *ssa.Value
@@ -4269,7 +4270,7 @@ func (s *state) openDeferRecord(n *Node) {
                        v = s.openDeferSave(argn, argn.Type, nil)
                }
                args = append(args, v)
-               argNodes = append(argNodes, v.Aux.(*Node))
+               argNodes = append(argNodes, v.Aux.(*ir.Node))
        }
        opendefer.argVals = args
        opendefer.argNodes = argNodes
@@ -4278,10 +4279,10 @@ func (s *state) openDeferRecord(n *Node) {
 
        // Update deferBits only after evaluation and storage to stack of
        // args/receiver/interface is successful.
-       bitvalue := s.constInt8(types.Types[TUINT8], 1<<uint(index))
-       newDeferBits := s.newValue2(ssa.OpOr8, types.Types[TUINT8], s.variable(deferBitsVar, types.Types[TUINT8]), bitvalue)
+       bitvalue := s.constInt8(types.Types[types.TUINT8], 1<<uint(index))
+       newDeferBits := s.newValue2(ssa.OpOr8, types.Types[types.TUINT8], s.variable(deferBitsVar, types.Types[types.TUINT8]), bitvalue)
        s.vars[deferBitsVar] = newDeferBits
-       s.store(types.Types[TUINT8], s.deferBitsAddr, newDeferBits)
+       s.store(types.Types[types.TUINT8], s.deferBitsAddr, newDeferBits)
 }
 
 // openDeferSave generates SSA nodes to store a value (with type t) for an
@@ -4291,7 +4292,7 @@ func (s *state) openDeferRecord(n *Node) {
 // type t is non-SSAable, then n must be non-nil (and val should be nil) and n is
 // evaluated (via s.addr() below) to get the value that is to be stored. The
 // function returns an SSA value representing a pointer to the autotmp location.
-func (s *state) openDeferSave(n *Node, t *types.Type, val *ssa.Value) *ssa.Value {
+func (s *state) openDeferSave(n *ir.Node, t *types.Type, val *ssa.Value) *ssa.Value {
        canSSA := canSSAType(t)
        var pos src.XPos
        if canSSA {
@@ -4349,7 +4350,7 @@ func (s *state) openDeferExit() {
        s.startBlock(deferExit)
        s.lastDeferExit = deferExit
        s.lastDeferCount = len(s.openDefers)
-       zeroval := s.constInt8(types.Types[TUINT8], 0)
+       zeroval := s.constInt8(types.Types[types.TUINT8], 0)
        testLateExpansion := ssa.LateCallExpansionEnabledWithin(s.f)
        // Test for and run defers in reverse order
        for i := len(s.openDefers) - 1; i >= 0; i-- {
@@ -4357,12 +4358,12 @@ func (s *state) openDeferExit() {
                bCond := s.f.NewBlock(ssa.BlockPlain)
                bEnd := s.f.NewBlock(ssa.BlockPlain)
 
-               deferBits := s.variable(deferBitsVar, types.Types[TUINT8])
+               deferBits := s.variable(deferBitsVar, types.Types[types.TUINT8])
                // Generate code to check if the bit associated with the current
                // defer is set.
-               bitval := s.constInt8(types.Types[TUINT8], 1<<uint(i))
-               andval := s.newValue2(ssa.OpAnd8, types.Types[TUINT8], deferBits, bitval)
-               eqVal := s.newValue2(ssa.OpEq8, types.Types[TBOOL], andval, zeroval)
+               bitval := s.constInt8(types.Types[types.TUINT8], 1<<uint(i))
+               andval := s.newValue2(ssa.OpAnd8, types.Types[types.TUINT8], deferBits, bitval)
+               eqVal := s.newValue2(ssa.OpEq8, types.Types[types.TBOOL], andval, zeroval)
                b := s.endBlock()
                b.Kind = ssa.BlockIf
                b.SetControl(eqVal)
@@ -4373,9 +4374,9 @@ func (s *state) openDeferExit() {
 
                // Clear this bit in deferBits and force store back to stack, so
                // we will not try to re-run this defer call if this defer call panics.
-               nbitval := s.newValue1(ssa.OpCom8, types.Types[TUINT8], bitval)
-               maskedval := s.newValue2(ssa.OpAnd8, types.Types[TUINT8], deferBits, nbitval)
-               s.store(types.Types[TUINT8], s.deferBitsAddr, maskedval)
+               nbitval := s.newValue1(ssa.OpCom8, types.Types[types.TUINT8], bitval)
+               maskedval := s.newValue2(ssa.OpAnd8, types.Types[types.TUINT8], deferBits, nbitval)
+               s.store(types.Types[types.TUINT8], s.deferBitsAddr, maskedval)
                // Use this value for following tests, so we keep previous
                // bits cleared.
                s.vars[deferBitsVar] = maskedval
@@ -4393,11 +4394,11 @@ func (s *state) openDeferExit() {
                        // rcvr in case of OCALLINTER
                        v := s.load(r.rcvr.Type.Elem(), r.rcvr)
                        addr := s.constOffPtrSP(s.f.Config.Types.UintptrPtr, argStart)
-                       ACArgs = append(ACArgs, ssa.Param{Type: types.Types[TUINTPTR], Offset: int32(argStart)})
+                       ACArgs = append(ACArgs, ssa.Param{Type: types.Types[types.TUINTPTR], Offset: int32(argStart)})
                        if testLateExpansion {
                                callArgs = append(callArgs, v)
                        } else {
-                               s.store(types.Types[TUINTPTR], addr, v)
+                               s.store(types.Types[types.TUINTPTR], addr, v)
                        }
                }
                for j, argAddrVal := range r.argVals {
@@ -4426,7 +4427,7 @@ func (s *state) openDeferExit() {
                if r.closure != nil {
                        v := s.load(r.closure.Type.Elem(), r.closure)
                        s.maybeNilCheckClosure(v, callDefer)
-                       codeptr := s.rawLoad(types.Types[TUINTPTR], v)
+                       codeptr := s.rawLoad(types.Types[types.TUINTPTR], v)
                        aux := ssa.ClosureAuxCall(ACArgs, ACResults)
                        if testLateExpansion {
                                callArgs = append(callArgs, s.mem())
@@ -4475,17 +4476,17 @@ func (s *state) openDeferExit() {
        }
 }
 
-func (s *state) callResult(n *Node, k callKind) *ssa.Value {
+func (s *state) callResult(n *ir.Node, k callKind) *ssa.Value {
        return s.call(n, k, false)
 }
 
-func (s *state) callAddr(n *Node, k callKind) *ssa.Value {
+func (s *state) callAddr(n *ir.Node, k callKind) *ssa.Value {
        return s.call(n, k, true)
 }
 
 // Calls the function n using the specified call type.
 // Returns the address of the return value (or nil if none).
-func (s *state) call(n *Node, k callKind, returnResultAddr bool) *ssa.Value {
+func (s *state) call(n *ir.Node, k callKind, returnResultAddr bool) *ssa.Value {
        s.prevCall = nil
        var sym *types.Sym     // target symbol (if static)
        var closure *ssa.Value // ptr to closure to run (if dynamic)
@@ -4507,9 +4508,9 @@ func (s *state) call(n *Node, k callKind, returnResultAddr bool) *ssa.Value {
        testLateExpansion := false
 
        switch n.Op {
-       case OCALLFUNC:
+       case ir.OCALLFUNC:
                testLateExpansion = k != callDeferStack && ssa.LateCallExpansionEnabledWithin(s.f)
-               if k == callNormal && fn.Op == ONAME && fn.Class() == PFUNC {
+               if k == callNormal && fn.Op == ir.ONAME && fn.Class() == ir.PFUNC {
                        sym = fn.Sym
                        break
                }
@@ -4519,8 +4520,8 @@ func (s *state) call(n *Node, k callKind, returnResultAddr bool) *ssa.Value {
                        // not the point of defer statement.
                        s.maybeNilCheckClosure(closure, k)
                }
-       case OCALLMETH:
-               if fn.Op != ODOTMETH {
+       case ir.OCALLMETH:
+               if fn.Op != ir.ODOTMETH {
                        s.Fatalf("OCALLMETH: n.Left not an ODOTMETH: %v", fn)
                }
                testLateExpansion = k != callDeferStack && ssa.LateCallExpansionEnabledWithin(s.f)
@@ -4531,15 +4532,15 @@ func (s *state) call(n *Node, k callKind, returnResultAddr bool) *ssa.Value {
                closure = s.getMethodClosure(fn)
                // Note: receiver is already present in n.Rlist, so we don't
                // want to set it here.
-       case OCALLINTER:
-               if fn.Op != ODOTINTER {
+       case ir.OCALLINTER:
+               if fn.Op != ir.ODOTINTER {
                        s.Fatalf("OCALLINTER: n.Left not an ODOTINTER: %v", fn.Op)
                }
                testLateExpansion = k != callDeferStack && ssa.LateCallExpansionEnabledWithin(s.f)
                var iclosure *ssa.Value
                iclosure, rcvr = s.getClosureAndRcvr(fn)
                if k == callNormal {
-                       codeptr = s.load(types.Types[TUINTPTR], iclosure)
+                       codeptr = s.load(types.Types[types.TUINTPTR], iclosure)
                } else {
                        closure = iclosure
                }
@@ -4564,9 +4565,9 @@ func (s *state) call(n *Node, k callKind, returnResultAddr bool) *ssa.Value {
 
                // Must match reflect.go:deferstruct and src/runtime/runtime2.go:_defer.
                // 0: siz
-               s.store(types.Types[TUINT32],
-                       s.newValue1I(ssa.OpOffPtr, types.Types[TUINT32].PtrTo(), t.FieldOff(0), addr),
-                       s.constInt32(types.Types[TUINT32], int32(stksize)))
+               s.store(types.Types[types.TUINT32],
+                       s.newValue1I(ssa.OpOffPtr, types.Types[types.TUINT32].PtrTo(), t.FieldOff(0), addr),
+                       s.constInt32(types.Types[types.TUINT32], int32(stksize)))
                // 1: started, set in deferprocStack
                // 2: heap, set in deferprocStack
                // 3: openDefer
@@ -4590,10 +4591,10 @@ func (s *state) call(n *Node, k callKind, returnResultAddr bool) *ssa.Value {
                // Set receiver (for interface calls). Always a pointer.
                if rcvr != nil {
                        p := s.newValue1I(ssa.OpOffPtr, ft.Recv().Type.PtrTo(), off, addr)
-                       s.store(types.Types[TUINTPTR], p, rcvr)
+                       s.store(types.Types[types.TUINTPTR], p, rcvr)
                }
                // Set receiver (for method calls).
-               if n.Op == OCALLMETH {
+               if n.Op == ir.OCALLMETH {
                        f := ft.Recv()
                        s.storeArgWithBase(args[0], f.Type, addr, off+f.Offset)
                        args = args[1:]
@@ -4605,15 +4606,15 @@ func (s *state) call(n *Node, k callKind, returnResultAddr bool) *ssa.Value {
                }
 
                // Call runtime.deferprocStack with pointer to _defer record.
-               ACArgs = append(ACArgs, ssa.Param{Type: types.Types[TUINTPTR], Offset: int32(base.Ctxt.FixedFrameSize())})
+               ACArgs = append(ACArgs, ssa.Param{Type: types.Types[types.TUINTPTR], Offset: int32(base.Ctxt.FixedFrameSize())})
                aux := ssa.StaticAuxCall(deferprocStack, ACArgs, ACResults)
                if testLateExpansion {
                        callArgs = append(callArgs, addr, s.mem())
                        call = s.newValue0A(ssa.OpStaticLECall, aux.LateExpansionResultType(), aux)
                        call.AddArgs(callArgs...)
                } else {
-                       arg0 := s.constOffPtrSP(types.Types[TUINTPTR], base.Ctxt.FixedFrameSize())
-                       s.store(types.Types[TUINTPTR], arg0, addr)
+                       arg0 := s.constOffPtrSP(types.Types[types.TUINTPTR], base.Ctxt.FixedFrameSize())
+                       s.store(types.Types[types.TUINTPTR], arg0, addr)
                        call = s.newValue1A(ssa.OpStaticCall, types.TypeMem, aux, s.mem())
                }
                if stksize < int64(Widthptr) {
@@ -4630,20 +4631,20 @@ func (s *state) call(n *Node, k callKind, returnResultAddr bool) *ssa.Value {
                // Defer/go args.
                if k != callNormal {
                        // Write argsize and closure (args to newproc/deferproc).
-                       argsize := s.constInt32(types.Types[TUINT32], int32(stksize))
-                       ACArgs = append(ACArgs, ssa.Param{Type: types.Types[TUINT32], Offset: int32(argStart)})
+                       argsize := s.constInt32(types.Types[types.TUINT32], int32(stksize))
+                       ACArgs = append(ACArgs, ssa.Param{Type: types.Types[types.TUINT32], Offset: int32(argStart)})
                        if testLateExpansion {
                                callArgs = append(callArgs, argsize)
                        } else {
                                addr := s.constOffPtrSP(s.f.Config.Types.UInt32Ptr, argStart)
-                               s.store(types.Types[TUINT32], addr, argsize)
+                               s.store(types.Types[types.TUINT32], addr, argsize)
                        }
-                       ACArgs = append(ACArgs, ssa.Param{Type: types.Types[TUINTPTR], Offset: int32(argStart) + int32(Widthptr)})
+                       ACArgs = append(ACArgs, ssa.Param{Type: types.Types[types.TUINTPTR], Offset: int32(argStart) + int32(Widthptr)})
                        if testLateExpansion {
                                callArgs = append(callArgs, closure)
                        } else {
                                addr := s.constOffPtrSP(s.f.Config.Types.UintptrPtr, argStart+int64(Widthptr))
-                               s.store(types.Types[TUINTPTR], addr, closure)
+                               s.store(types.Types[types.TUINTPTR], addr, closure)
                        }
                        stksize += 2 * int64(Widthptr)
                        argStart += 2 * int64(Widthptr)
@@ -4652,18 +4653,18 @@ func (s *state) call(n *Node, k callKind, returnResultAddr bool) *ssa.Value {
                // Set receiver (for interface calls).
                if rcvr != nil {
                        addr := s.constOffPtrSP(s.f.Config.Types.UintptrPtr, argStart)
-                       ACArgs = append(ACArgs, ssa.Param{Type: types.Types[TUINTPTR], Offset: int32(argStart)})
+                       ACArgs = append(ACArgs, ssa.Param{Type: types.Types[types.TUINTPTR], Offset: int32(argStart)})
                        if testLateExpansion {
                                callArgs = append(callArgs, rcvr)
                        } else {
-                               s.store(types.Types[TUINTPTR], addr, rcvr)
+                               s.store(types.Types[types.TUINTPTR], addr, rcvr)
                        }
                }
 
                // Write args.
                t := n.Left.Type
                args := n.Rlist.Slice()
-               if n.Op == OCALLMETH {
+               if n.Op == ir.OCALLMETH {
                        f := t.Recv()
                        ACArg, arg := s.putArg(args[0], f.Type, argStart+f.Offset, testLateExpansion)
                        ACArgs = append(ACArgs, ACArg)
@@ -4703,7 +4704,7 @@ func (s *state) call(n *Node, k callKind, returnResultAddr bool) *ssa.Value {
                        // can't always figure that out currently, and it's
                        // critical that we not clobber any arguments already
                        // stored onto the stack.
-                       codeptr = s.rawLoad(types.Types[TUINTPTR], closure)
+                       codeptr = s.rawLoad(types.Types[types.TUINTPTR], closure)
                        if testLateExpansion {
                                aux := ssa.ClosureAuxCall(ACArgs, ACResults)
                                call = s.newValue2A(ssa.OpClosureLECall, aux.LateExpansionResultType(), aux, codeptr, closure)
@@ -4787,26 +4788,26 @@ func (s *state) maybeNilCheckClosure(closure *ssa.Value, k callKind) {
 }
 
 // getMethodClosure returns a value representing the closure for a method call
-func (s *state) getMethodClosure(fn *Node) *ssa.Value {
+func (s *state) getMethodClosure(fn *ir.Node) *ssa.Value {
        // Make a name n2 for the function.
        // fn.Sym might be sync.(*Mutex).Unlock.
        // Make a PFUNC node out of that, then evaluate it.
        // We get back an SSA value representing &sync.(*Mutex).Unlock·f.
        // We can then pass that to defer or go.
-       n2 := newnamel(fn.Pos, fn.Sym)
+       n2 := ir.NewNameAt(fn.Pos, fn.Sym)
        n2.Name.Curfn = s.curfn
-       n2.SetClass(PFUNC)
+       n2.SetClass(ir.PFUNC)
        // n2.Sym already existed, so it's already marked as a function.
        n2.Pos = fn.Pos
-       n2.Type = types.Types[TUINT8] // fake type for a static closure. Could use runtime.funcval if we had it.
+       n2.Type = types.Types[types.TUINT8] // fake type for a static closure. Could use runtime.funcval if we had it.
        return s.expr(n2)
 }
 
 // getClosureAndRcvr returns values for the appropriate closure and receiver of an
 // interface call
-func (s *state) getClosureAndRcvr(fn *Node) (*ssa.Value, *ssa.Value) {
+func (s *state) getClosureAndRcvr(fn *ir.Node) (*ssa.Value, *ssa.Value) {
        i := s.expr(fn.Left)
-       itab := s.newValue1(ssa.OpITab, types.Types[TUINTPTR], i)
+       itab := s.newValue1(ssa.OpITab, types.Types[types.TUINTPTR], i)
        s.nilCheck(itab)
        itabidx := fn.Xoffset + 2*int64(Widthptr) + 8 // offset of fun field in runtime.itab
        closure := s.newValue1I(ssa.OpOffPtr, s.f.Config.Types.UintptrPtr, itabidx, itab)
@@ -4818,9 +4819,9 @@ func (s *state) getClosureAndRcvr(fn *Node) (*ssa.Value, *ssa.Value) {
 // -1 means signed, +1 means unsigned, 0 means non-integer/non-pointer.
 func etypesign(e types.EType) int8 {
        switch e {
-       case TINT8, TINT16, TINT32, TINT64, TINT:
+       case types.TINT8, types.TINT16, types.TINT32, types.TINT64, types.TINT:
                return -1
-       case TUINT8, TUINT16, TUINT32, TUINT64, TUINT, TUINTPTR, TUNSAFEPTR:
+       case types.TUINT8, types.TUINT16, types.TUINT32, types.TUINT64, types.TUINT, types.TUINTPTR, types.TUNSAFEPTR:
                return +1
        }
        return 0
@@ -4828,17 +4829,17 @@ func etypesign(e types.EType) int8 {
 
 // addr converts the address of the expression n to SSA, adds it to s and returns the SSA result.
 // The value that the returned Value represents is guaranteed to be non-nil.
-func (s *state) addr(n *Node) *ssa.Value {
-       if n.Op != ONAME {
+func (s *state) addr(n *ir.Node) *ssa.Value {
+       if n.Op != ir.ONAME {
                s.pushLine(n.Pos)
                defer s.popLine()
        }
 
        t := types.NewPtr(n.Type)
        switch n.Op {
-       case ONAME:
+       case ir.ONAME:
                switch n.Class() {
-               case PEXTERN:
+               case ir.PEXTERN:
                        // global variable
                        v := s.entryNewValue1A(ssa.OpAddr, t, n.Sym.Linksym(), s.sb)
                        // TODO: Make OpAddr use AuxInt as well as Aux.
@@ -4846,7 +4847,7 @@ func (s *state) addr(n *Node) *ssa.Value {
                                v = s.entryNewValue1I(ssa.OpOffPtr, v.Type, n.Xoffset, v)
                        }
                        return v
-               case PPARAM:
+               case ir.PPARAM:
                        // parameter slot
                        v := s.decladdrs[n]
                        if v != nil {
@@ -4858,10 +4859,10 @@ func (s *state) addr(n *Node) *ssa.Value {
                        }
                        s.Fatalf("addr of undeclared ONAME %v. declared: %v", n, s.decladdrs)
                        return nil
-               case PAUTO:
+               case ir.PAUTO:
                        return s.newValue2Apos(ssa.OpLocalAddr, t, n, s.sp, s.mem(), !n.IsAutoTmp())
 
-               case PPARAMOUT: // Same as PAUTO -- cannot generate LEA early.
+               case ir.PPARAMOUT: // Same as PAUTO -- cannot generate LEA early.
                        // ensure that we reuse symbols for out parameters so
                        // that cse works on their addresses
                        return s.newValue2Apos(ssa.OpLocalAddr, t, n, s.sp, s.mem(), true)
@@ -4869,7 +4870,7 @@ func (s *state) addr(n *Node) *ssa.Value {
                        s.Fatalf("variable address class %v not implemented", n.Class())
                        return nil
                }
-       case ORESULT:
+       case ir.ORESULT:
                // load return from callee
                if s.prevCall == nil || s.prevCall.Op != ssa.OpStaticLECall && s.prevCall.Op != ssa.OpInterLECall && s.prevCall.Op != ssa.OpClosureLECall {
                        return s.constOffPtrSP(t, n.Xoffset)
@@ -4882,38 +4883,38 @@ func (s *state) addr(n *Node) *ssa.Value {
                x := s.newValue1I(ssa.OpSelectNAddr, t, which, s.prevCall)
                return x
 
-       case OINDEX:
+       case ir.OINDEX:
                if n.Left.Type.IsSlice() {
                        a := s.expr(n.Left)
                        i := s.expr(n.Right)
-                       len := s.newValue1(ssa.OpSliceLen, types.Types[TINT], a)
+                       len := s.newValue1(ssa.OpSliceLen, types.Types[types.TINT], a)
                        i = s.boundsCheck(i, len, ssa.BoundsIndex, n.Bounded())
                        p := s.newValue1(ssa.OpSlicePtr, t, a)
                        return s.newValue2(ssa.OpPtrIndex, t, p, i)
                } else { // array
                        a := s.addr(n.Left)
                        i := s.expr(n.Right)
-                       len := s.constInt(types.Types[TINT], n.Left.Type.NumElem())
+                       len := s.constInt(types.Types[types.TINT], n.Left.Type.NumElem())
                        i = s.boundsCheck(i, len, ssa.BoundsIndex, n.Bounded())
                        return s.newValue2(ssa.OpPtrIndex, types.NewPtr(n.Left.Type.Elem()), a, i)
                }
-       case ODEREF:
+       case ir.ODEREF:
                return s.exprPtr(n.Left, n.Bounded(), n.Pos)
-       case ODOT:
+       case ir.ODOT:
                p := s.addr(n.Left)
                return s.newValue1I(ssa.OpOffPtr, t, n.Xoffset, p)
-       case ODOTPTR:
+       case ir.ODOTPTR:
                p := s.exprPtr(n.Left, n.Bounded(), n.Pos)
                return s.newValue1I(ssa.OpOffPtr, t, n.Xoffset, p)
-       case OCLOSUREVAR:
+       case ir.OCLOSUREVAR:
                return s.newValue1I(ssa.OpOffPtr, t, n.Xoffset,
                        s.entryNewValue0(ssa.OpGetClosurePtr, s.f.Config.Types.BytePtr))
-       case OCONVNOP:
+       case ir.OCONVNOP:
                addr := s.addr(n.Left)
                return s.newValue1(ssa.OpCopy, t, addr) // ensure that addr has the right type
-       case OCALLFUNC, OCALLINTER, OCALLMETH:
+       case ir.OCALLFUNC, ir.OCALLINTER, ir.OCALLMETH:
                return s.callAddr(n, callNormal)
-       case ODOTTYPE:
+       case ir.ODOTTYPE:
                v, _ := s.dottype(n, false)
                if v.Op != ssa.OpLoad {
                        s.Fatalf("dottype of non-load")
@@ -4930,29 +4931,29 @@ func (s *state) addr(n *Node) *ssa.Value {
 
 // canSSA reports whether n is SSA-able.
 // n must be an ONAME (or an ODOT sequence with an ONAME base).
-func (s *state) canSSA(n *Node) bool {
+func (s *state) canSSA(n *ir.Node) bool {
        if base.Flag.N != 0 {
                return false
        }
-       for n.Op == ODOT || (n.Op == OINDEX && n.Left.Type.IsArray()) {
+       for n.Op == ir.ODOT || (n.Op == ir.OINDEX && n.Left.Type.IsArray()) {
                n = n.Left
        }
-       if n.Op != ONAME {
+       if n.Op != ir.ONAME {
                return false
        }
        if n.Name.Addrtaken() {
                return false
        }
-       if n.isParamHeapCopy() {
+       if isParamHeapCopy(n) {
                return false
        }
-       if n.Class() == PAUTOHEAP {
+       if n.Class() == ir.PAUTOHEAP {
                s.Fatalf("canSSA of PAUTOHEAP %v", n)
        }
        switch n.Class() {
-       case PEXTERN:
+       case ir.PEXTERN:
                return false
-       case PPARAMOUT:
+       case ir.PPARAMOUT:
                if s.hasdefer {
                        // TODO: handle this case? Named return values must be
                        // in memory so that the deferred function can see them.
@@ -4967,7 +4968,7 @@ func (s *state) canSSA(n *Node) bool {
                        return false
                }
        }
-       if n.Class() == PPARAM && n.Sym != nil && n.Sym.Name == ".this" {
+       if n.Class() == ir.PPARAM && n.Sym != nil && n.Sym.Name == ".this" {
                // wrappers generated by genwrapper need to update
                // the .this pointer in place.
                // TODO: treat as a PPARAMOUT?
@@ -4987,7 +4988,7 @@ func canSSAType(t *types.Type) bool {
                return false
        }
        switch t.Etype {
-       case TARRAY:
+       case types.TARRAY:
                // We can't do larger arrays because dynamic indexing is
                // not supported on SSA variables.
                // TODO: allow if all indexes are constant.
@@ -4995,7 +4996,7 @@ func canSSAType(t *types.Type) bool {
                        return canSSAType(t.Elem())
                }
                return false
-       case TSTRUCT:
+       case types.TSTRUCT:
                if t.NumFields() > ssa.MaxStruct {
                        return false
                }
@@ -5011,7 +5012,7 @@ func canSSAType(t *types.Type) bool {
 }
 
 // exprPtr evaluates n to a pointer and nil-checks it.
-func (s *state) exprPtr(n *Node, bounded bool, lineno src.XPos) *ssa.Value {
+func (s *state) exprPtr(n *ir.Node, bounded bool, lineno src.XPos) *ssa.Value {
        p := s.expr(n)
        if bounded || n.NonNil() {
                if s.f.Frontend().Debug_checknil() && lineno.Line() > 1 {
@@ -5092,9 +5093,9 @@ func (s *state) boundsCheck(idx, len *ssa.Value, kind ssa.BoundsKind, bounded bo
 
        var cmp *ssa.Value
        if kind == ssa.BoundsIndex || kind == ssa.BoundsIndexU {
-               cmp = s.newValue2(ssa.OpIsInBounds, types.Types[TBOOL], idx, len)
+               cmp = s.newValue2(ssa.OpIsInBounds, types.Types[types.TBOOL], idx, len)
        } else {
-               cmp = s.newValue2(ssa.OpIsSliceInBounds, types.Types[TBOOL], idx, len)
+               cmp = s.newValue2(ssa.OpIsSliceInBounds, types.Types[types.TBOOL], idx, len)
        }
        b := s.endBlock()
        b.Kind = ssa.BlockIf
@@ -5120,7 +5121,7 @@ func (s *state) boundsCheck(idx, len *ssa.Value, kind ssa.BoundsKind, bounded bo
                if kind != ssa.BoundsIndex && kind != ssa.BoundsIndexU {
                        op = ssa.OpSpectreSliceIndex
                }
-               idx = s.newValue2(op, types.Types[TINT], idx, len)
+               idx = s.newValue2(op, types.Types[types.TINT], idx, len)
        }
 
        return idx
@@ -5150,7 +5151,7 @@ func (s *state) check(cmp *ssa.Value, fn *obj.LSym) {
        s.startBlock(bNext)
 }
 
-func (s *state) intDivide(n *Node, a, b *ssa.Value) *ssa.Value {
+func (s *state) intDivide(n *ir.Node, a, b *ssa.Value) *ssa.Value {
        needcheck := true
        switch b.Op {
        case ssa.OpConst8, ssa.OpConst16, ssa.OpConst32, ssa.OpConst64:
@@ -5160,7 +5161,7 @@ func (s *state) intDivide(n *Node, a, b *ssa.Value) *ssa.Value {
        }
        if needcheck {
                // do a size-appropriate check for zero
-               cmp := s.newValue2(s.ssaOp(ONE, n.Type), types.Types[TBOOL], b, s.zeroVal(n.Type))
+               cmp := s.newValue2(s.ssaOp(ir.ONE, n.Type), types.Types[types.TBOOL], b, s.zeroVal(n.Type))
                s.check(cmp, panicdivide)
        }
        return s.newValue2(s.ssaOp(n.Op, n.Type), a.Type, a, b)
@@ -5291,24 +5292,24 @@ func (s *state) storeTypeScalars(t *types.Type, left, right *ssa.Value, skip ski
                if skip&skipLen != 0 {
                        return
                }
-               len := s.newValue1(ssa.OpStringLen, types.Types[TINT], right)
+               len := s.newValue1(ssa.OpStringLen, types.Types[types.TINT], right)
                lenAddr := s.newValue1I(ssa.OpOffPtr, s.f.Config.Types.IntPtr, s.config.PtrSize, left)
-               s.store(types.Types[TINT], lenAddr, len)
+               s.store(types.Types[types.TINT], lenAddr, len)
        case t.IsSlice():
                if skip&skipLen == 0 {
-                       len := s.newValue1(ssa.OpSliceLen, types.Types[TINT], right)
+                       len := s.newValue1(ssa.OpSliceLen, types.Types[types.TINT], right)
                        lenAddr := s.newValue1I(ssa.OpOffPtr, s.f.Config.Types.IntPtr, s.config.PtrSize, left)
-                       s.store(types.Types[TINT], lenAddr, len)
+                       s.store(types.Types[types.TINT], lenAddr, len)
                }
                if skip&skipCap == 0 {
-                       cap := s.newValue1(ssa.OpSliceCap, types.Types[TINT], right)
+                       cap := s.newValue1(ssa.OpSliceCap, types.Types[types.TINT], right)
                        capAddr := s.newValue1I(ssa.OpOffPtr, s.f.Config.Types.IntPtr, 2*s.config.PtrSize, left)
-                       s.store(types.Types[TINT], capAddr, cap)
+                       s.store(types.Types[types.TINT], capAddr, cap)
                }
        case t.IsInterface():
                // itab field doesn't need a write barrier (even though it is a pointer).
                itab := s.newValue1(ssa.OpITab, s.f.Config.Types.BytePtr, right)
-               s.store(types.Types[TUINTPTR], left, itab)
+               s.store(types.Types[types.TUINTPTR], left, itab)
        case t.IsStruct():
                n := t.NumFields()
                for i := 0; i < n; i++ {
@@ -5369,7 +5370,7 @@ func (s *state) storeTypePtrs(t *types.Type, left, right *ssa.Value) {
 // putArg evaluates n for the purpose of passing it as an argument to a function and returns the corresponding Param for the call.
 // If forLateExpandedCall is true, it returns the argument value to pass to the call operation.
 // If forLateExpandedCall is false, then the value is stored at the specified stack offset, and the returned value is nil.
-func (s *state) putArg(n *Node, t *types.Type, off int64, forLateExpandedCall bool) (ssa.Param, *ssa.Value) {
+func (s *state) putArg(n *ir.Node, t *types.Type, off int64, forLateExpandedCall bool) (ssa.Param, *ssa.Value) {
        var a *ssa.Value
        if forLateExpandedCall {
                if !canSSAType(t) {
@@ -5383,7 +5384,7 @@ func (s *state) putArg(n *Node, t *types.Type, off int64, forLateExpandedCall bo
        return ssa.Param{Type: t, Offset: int32(off)}, a
 }
 
-func (s *state) storeArgWithBase(n *Node, t *types.Type, base *ssa.Value, off int64) {
+func (s *state) storeArgWithBase(n *ir.Node, t *types.Type, base *ssa.Value, off int64) {
        pt := types.NewPtr(t)
        var addr *ssa.Value
        if base == s.sp {
@@ -5412,11 +5413,11 @@ func (s *state) slice(v, i, j, k *ssa.Value, bounded bool) (p, l, c *ssa.Value)
        switch {
        case t.IsSlice():
                ptr = s.newValue1(ssa.OpSlicePtr, types.NewPtr(t.Elem()), v)
-               len = s.newValue1(ssa.OpSliceLen, types.Types[TINT], v)
-               cap = s.newValue1(ssa.OpSliceCap, types.Types[TINT], v)
+               len = s.newValue1(ssa.OpSliceLen, types.Types[types.TINT], v)
+               cap = s.newValue1(ssa.OpSliceCap, types.Types[types.TINT], v)
        case t.IsString():
-               ptr = s.newValue1(ssa.OpStringPtr, types.NewPtr(types.Types[TUINT8]), v)
-               len = s.newValue1(ssa.OpStringLen, types.Types[TINT], v)
+               ptr = s.newValue1(ssa.OpStringPtr, types.NewPtr(types.Types[types.TUINT8]), v)
+               len = s.newValue1(ssa.OpStringLen, types.Types[types.TINT], v)
                cap = len
        case t.IsPtr():
                if !t.Elem().IsArray() {
@@ -5424,7 +5425,7 @@ func (s *state) slice(v, i, j, k *ssa.Value, bounded bool) (p, l, c *ssa.Value)
                }
                s.nilCheck(v)
                ptr = s.newValue1(ssa.OpCopy, types.NewPtr(t.Elem().Elem()), v)
-               len = s.constInt(types.Types[TINT], t.Elem().NumElem())
+               len = s.constInt(types.Types[types.TINT], t.Elem().NumElem())
                cap = len
        default:
                s.Fatalf("bad type in slice %v\n", t)
@@ -5432,7 +5433,7 @@ func (s *state) slice(v, i, j, k *ssa.Value, bounded bool) (p, l, c *ssa.Value)
 
        // Set default values
        if i == nil {
-               i = s.constInt(types.Types[TINT], 0)
+               i = s.constInt(types.Types[types.TINT], 0)
        }
        if j == nil {
                j = len
@@ -5470,18 +5471,18 @@ func (s *state) slice(v, i, j, k *ssa.Value, bounded bool) (p, l, c *ssa.Value)
        }
 
        // Word-sized integer operations.
-       subOp := s.ssaOp(OSUB, types.Types[TINT])
-       mulOp := s.ssaOp(OMUL, types.Types[TINT])
-       andOp := s.ssaOp(OAND, types.Types[TINT])
+       subOp := s.ssaOp(ir.OSUB, types.Types[types.TINT])
+       mulOp := s.ssaOp(ir.OMUL, types.Types[types.TINT])
+       andOp := s.ssaOp(ir.OAND, types.Types[types.TINT])
 
        // Calculate the length (rlen) and capacity (rcap) of the new slice.
        // For strings the capacity of the result is unimportant. However,
        // we use rcap to test if we've generated a zero-length slice.
        // Use length of strings for that.
-       rlen := s.newValue2(subOp, types.Types[TINT], j, i)
+       rlen := s.newValue2(subOp, types.Types[types.TINT], j, i)
        rcap := rlen
        if j != k && !t.IsString() {
-               rcap = s.newValue2(subOp, types.Types[TINT], k, i)
+               rcap = s.newValue2(subOp, types.Types[types.TINT], k, i)
        }
 
        if (i.Op == ssa.OpConst64 || i.Op == ssa.OpConst32) && i.AuxInt == 0 {
@@ -5503,15 +5504,15 @@ func (s *state) slice(v, i, j, k *ssa.Value, bounded bool) (p, l, c *ssa.Value)
        //
        // Where mask(x) is 0 if x==0 and -1 if x>0 and stride is the width
        // of the element type.
-       stride := s.constInt(types.Types[TINT], ptr.Type.Elem().Width)
+       stride := s.constInt(types.Types[types.TINT], ptr.Type.Elem().Width)
 
        // The delta is the number of bytes to offset ptr by.
-       delta := s.newValue2(mulOp, types.Types[TINT], i, stride)
+       delta := s.newValue2(mulOp, types.Types[types.TINT], i, stride)
 
        // If we're slicing to the point where the capacity is zero,
        // zero out the delta.
-       mask := s.newValue1(ssa.OpSlicemask, types.Types[TINT], rcap)
-       delta = s.newValue2(andOp, types.Types[TINT], delta, mask)
+       mask := s.newValue1(ssa.OpSlicemask, types.Types[types.TINT], rcap)
+       delta = s.newValue2(andOp, types.Types[types.TINT], delta, mask)
 
        // Compute rptr = ptr + delta.
        rptr := s.newValue2(ssa.OpAddPtr, ptr.Type, ptr, delta)
@@ -5544,15 +5545,15 @@ var u64_f32 = u642fcvtTab{
        one:   (*state).constInt64,
 }
 
-func (s *state) uint64Tofloat64(n *Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value {
+func (s *state) uint64Tofloat64(n *ir.Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value {
        return s.uint64Tofloat(&u64_f64, n, x, ft, tt)
 }
 
-func (s *state) uint64Tofloat32(n *Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value {
+func (s *state) uint64Tofloat32(n *ir.Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value {
        return s.uint64Tofloat(&u64_f32, n, x, ft, tt)
 }
 
-func (s *state) uint64Tofloat(cvttab *u642fcvtTab, n *Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value {
+func (s *state) uint64Tofloat(cvttab *u642fcvtTab, n *ir.Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value {
        // if x >= 0 {
        //    result = (floatY) x
        // } else {
@@ -5578,7 +5579,7 @@ func (s *state) uint64Tofloat(cvttab *u642fcvtTab, n *Node, x *ssa.Value, ft, tt
        // equal to 10000000001; that rounds up, and the 1 cannot
        // be lost else it would round down if the LSB of the
        // candidate mantissa is 0.
-       cmp := s.newValue2(cvttab.leq, types.Types[TBOOL], s.zeroVal(ft), x)
+       cmp := s.newValue2(cvttab.leq, types.Types[types.TBOOL], s.zeroVal(ft), x)
        b := s.endBlock()
        b.Kind = ssa.BlockIf
        b.SetControl(cmp)
@@ -5625,21 +5626,21 @@ var u32_f32 = u322fcvtTab{
        cvtF2F: ssa.OpCvt64Fto32F,
 }
 
-func (s *state) uint32Tofloat64(n *Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value {
+func (s *state) uint32Tofloat64(n *ir.Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value {
        return s.uint32Tofloat(&u32_f64, n, x, ft, tt)
 }
 
-func (s *state) uint32Tofloat32(n *Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value {
+func (s *state) uint32Tofloat32(n *ir.Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value {
        return s.uint32Tofloat(&u32_f32, n, x, ft, tt)
 }
 
-func (s *state) uint32Tofloat(cvttab *u322fcvtTab, n *Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value {
+func (s *state) uint32Tofloat(cvttab *u322fcvtTab, n *ir.Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value {
        // if x >= 0 {
        //      result = floatY(x)
        // } else {
        //      result = floatY(float64(x) + (1<<32))
        // }
-       cmp := s.newValue2(ssa.OpLeq32, types.Types[TBOOL], s.zeroVal(ft), x)
+       cmp := s.newValue2(ssa.OpLeq32, types.Types[types.TBOOL], s.zeroVal(ft), x)
        b := s.endBlock()
        b.Kind = ssa.BlockIf
        b.SetControl(cmp)
@@ -5658,9 +5659,9 @@ func (s *state) uint32Tofloat(cvttab *u322fcvtTab, n *Node, x *ssa.Value, ft, tt
 
        b.AddEdgeTo(bElse)
        s.startBlock(bElse)
-       a1 := s.newValue1(ssa.OpCvt32to64F, types.Types[TFLOAT64], x)
-       twoToThe32 := s.constFloat64(types.Types[TFLOAT64], float64(1<<32))
-       a2 := s.newValue2(ssa.OpAdd64F, types.Types[TFLOAT64], a1, twoToThe32)
+       a1 := s.newValue1(ssa.OpCvt32to64F, types.Types[types.TFLOAT64], x)
+       twoToThe32 := s.constFloat64(types.Types[types.TFLOAT64], float64(1<<32))
+       a2 := s.newValue2(ssa.OpAdd64F, types.Types[types.TFLOAT64], a1, twoToThe32)
        a3 := s.newValue1(cvttab.cvtF2F, tt, a2)
 
        s.vars[n] = a3
@@ -5672,7 +5673,7 @@ func (s *state) uint32Tofloat(cvttab *u322fcvtTab, n *Node, x *ssa.Value, ft, tt
 }
 
 // referenceTypeBuiltin generates code for the len/cap builtins for maps and channels.
-func (s *state) referenceTypeBuiltin(n *Node, x *ssa.Value) *ssa.Value {
+func (s *state) referenceTypeBuiltin(n *ir.Node, x *ssa.Value) *ssa.Value {
        if !n.Left.Type.IsMap() && !n.Left.Type.IsChan() {
                s.Fatalf("node must be a map or a channel")
        }
@@ -5685,8 +5686,8 @@ func (s *state) referenceTypeBuiltin(n *Node, x *ssa.Value) *ssa.Value {
        //   return *(((*int)n)+1)
        // }
        lenType := n.Type
-       nilValue := s.constNil(types.Types[TUINTPTR])
-       cmp := s.newValue2(ssa.OpEqPtr, types.Types[TBOOL], x, nilValue)
+       nilValue := s.constNil(types.Types[types.TUINTPTR])
+       cmp := s.newValue2(ssa.OpEqPtr, types.Types[types.TBOOL], x, nilValue)
        b := s.endBlock()
        b.Kind = ssa.BlockIf
        b.SetControl(cmp)
@@ -5706,10 +5707,10 @@ func (s *state) referenceTypeBuiltin(n *Node, x *ssa.Value) *ssa.Value {
        b.AddEdgeTo(bElse)
        s.startBlock(bElse)
        switch n.Op {
-       case OLEN:
+       case ir.OLEN:
                // length is stored in the first word for map/chan
                s.vars[n] = s.load(lenType, x)
-       case OCAP:
+       case ir.OCAP:
                // capacity is stored in the second word for chan
                sw := s.newValue1I(ssa.OpOffPtr, lenType.PtrTo(), lenType.Width, x)
                s.vars[n] = s.load(lenType, sw)
@@ -5770,22 +5771,22 @@ var f64_u32 = f2uCvtTab{
        cutoff:     1 << 31,
 }
 
-func (s *state) float32ToUint64(n *Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value {
+func (s *state) float32ToUint64(n *ir.Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value {
        return s.floatToUint(&f32_u64, n, x, ft, tt)
 }
-func (s *state) float64ToUint64(n *Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value {
+func (s *state) float64ToUint64(n *ir.Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value {
        return s.floatToUint(&f64_u64, n, x, ft, tt)
 }
 
-func (s *state) float32ToUint32(n *Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value {
+func (s *state) float32ToUint32(n *ir.Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value {
        return s.floatToUint(&f32_u32, n, x, ft, tt)
 }
 
-func (s *state) float64ToUint32(n *Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value {
+func (s *state) float64ToUint32(n *ir.Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value {
        return s.floatToUint(&f64_u32, n, x, ft, tt)
 }
 
-func (s *state) floatToUint(cvttab *f2uCvtTab, n *Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value {
+func (s *state) floatToUint(cvttab *f2uCvtTab, n *ir.Node, x *ssa.Value, ft, tt *types.Type) *ssa.Value {
        // cutoff:=1<<(intY_Size-1)
        // if x < floatX(cutoff) {
        //      result = uintY(x)
@@ -5795,7 +5796,7 @@ func (s *state) floatToUint(cvttab *f2uCvtTab, n *Node, x *ssa.Value, ft, tt *ty
        //      result = z | -(cutoff)
        // }
        cutoff := cvttab.floatValue(s, ft, float64(cvttab.cutoff))
-       cmp := s.newValue2(cvttab.ltf, types.Types[TBOOL], x, cutoff)
+       cmp := s.newValue2(cvttab.ltf, types.Types[types.TBOOL], x, cutoff)
        b := s.endBlock()
        b.Kind = ssa.BlockIf
        b.SetControl(cmp)
@@ -5829,7 +5830,7 @@ func (s *state) floatToUint(cvttab *f2uCvtTab, n *Node, x *ssa.Value, ft, tt *ty
 // dottype generates SSA for a type assertion node.
 // commaok indicates whether to panic or return a bool.
 // If commaok is false, resok will be nil.
-func (s *state) dottype(n *Node, commaok bool) (res, resok *ssa.Value) {
+func (s *state) dottype(n *ir.Node, commaok bool) (res, resok *ssa.Value) {
        iface := s.expr(n.Left)   // input interface
        target := s.expr(n.Right) // target type
        byteptr := s.f.Config.Types.BytePtr
@@ -5845,7 +5846,7 @@ func (s *state) dottype(n *Node, commaok bool) (res, resok *ssa.Value) {
                        // Get itab/type field from input.
                        itab := s.newValue1(ssa.OpITab, byteptr, iface)
                        // Conversion succeeds iff that field is not nil.
-                       cond := s.newValue2(ssa.OpNeqPtr, types.Types[TBOOL], itab, s.constNil(byteptr))
+                       cond := s.newValue2(ssa.OpNeqPtr, types.Types[types.TBOOL], itab, s.constNil(byteptr))
 
                        if n.Left.Type.IsEmptyInterface() && commaok {
                                // Converting empty interface to empty interface with ,ok is just a nil check.
@@ -5910,13 +5911,13 @@ func (s *state) dottype(n *Node, commaok bool) (res, resok *ssa.Value) {
                }
                if n.Left.Type.IsEmptyInterface() {
                        if commaok {
-                               call := s.rtcall(assertE2I2, true, []*types.Type{n.Type, types.Types[TBOOL]}, target, iface)
+                               call := s.rtcall(assertE2I2, true, []*types.Type{n.Type, types.Types[types.TBOOL]}, target, iface)
                                return call[0], call[1]
                        }
                        return s.rtcall(assertE2I, true, []*types.Type{n.Type}, target, iface)[0], nil
                }
                if commaok {
-                       call := s.rtcall(assertI2I2, true, []*types.Type{n.Type, types.Types[TBOOL]}, target, iface)
+                       call := s.rtcall(assertI2I2, true, []*types.Type{n.Type, types.Types[types.TBOOL]}, target, iface)
                        return call[0], call[1]
                }
                return s.rtcall(assertI2I, true, []*types.Type{n.Type}, target, iface)[0], nil
@@ -5941,7 +5942,7 @@ func (s *state) dottype(n *Node, commaok bool) (res, resok *ssa.Value) {
                targetITab = s.expr(n.List.First())
        }
 
-       var tmp *Node       // temporary for use with large types
+       var tmp *ir.Node    // temporary for use with large types
        var addr *ssa.Value // address of tmp
        if commaok && !canSSAType(n.Type) {
                // unSSAable type, use temporary.
@@ -5951,7 +5952,7 @@ func (s *state) dottype(n *Node, commaok bool) (res, resok *ssa.Value) {
                addr = s.addr(tmp)
        }
 
-       cond := s.newValue2(ssa.OpEqPtr, types.Types[TBOOL], itab, targetITab)
+       cond := s.newValue2(ssa.OpEqPtr, types.Types[types.TBOOL], itab, targetITab)
        b := s.endBlock()
        b.Kind = ssa.BlockIf
        b.SetControl(cond)
@@ -6031,7 +6032,7 @@ func (s *state) dottype(n *Node, commaok bool) (res, resok *ssa.Value) {
 }
 
 // variable returns the value of a variable at the current location.
-func (s *state) variable(name *Node, t *types.Type) *ssa.Value {
+func (s *state) variable(name *ir.Node, t *types.Type) *ssa.Value {
        v := s.vars[name]
        if v != nil {
                return v
@@ -6057,8 +6058,8 @@ func (s *state) mem() *ssa.Value {
        return s.variable(memVar, types.TypeMem)
 }
 
-func (s *state) addNamedValue(n *Node, v *ssa.Value) {
-       if n.Class() == Pxxx {
+func (s *state) addNamedValue(n *ir.Node, v *ssa.Value) {
+       if n.Class() == ir.Pxxx {
                // Don't track our marker nodes (memVar etc.).
                return
        }
@@ -6066,12 +6067,12 @@ func (s *state) addNamedValue(n *Node, v *ssa.Value) {
                // Don't track temporary variables.
                return
        }
-       if n.Class() == PPARAMOUT {
+       if n.Class() == ir.PPARAMOUT {
                // Don't track named output values.  This prevents return values
                // from being assigned too early. See #14591 and #14762. TODO: allow this.
                return
        }
-       if n.Class() == PAUTO && n.Xoffset != 0 {
+       if n.Class() == ir.PAUTO && n.Xoffset != 0 {
                s.Fatalf("AUTO var with offset %v %d", n, n.Xoffset)
        }
        loc := ssa.LocalSlot{N: n, Type: n.Type, Off: 0}
@@ -6110,7 +6111,7 @@ type SSAGenState struct {
        bstart []*obj.Prog
 
        // Some architectures require a 64-bit temporary for FP-related register shuffling. Examples include PPC and Sparc V8.
-       ScratchFpMem *Node
+       ScratchFpMem *ir.Node
 
        maxarg int64 // largest frame size for arguments to calls made by the function
 
@@ -6193,14 +6194,14 @@ func (s *SSAGenState) DebugFriendlySetPosFrom(v *ssa.Value) {
 }
 
 // byXoffset implements sort.Interface for []*Node using Xoffset as the ordering.
-type byXoffset []*Node
+type byXoffset []*ir.Node
 
 func (s byXoffset) Len() int           { return len(s) }
 func (s byXoffset) Less(i, j int) bool { return s[i].Xoffset < s[j].Xoffset }
 func (s byXoffset) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
 
 func emitStackObjects(e *ssafn, pp *Progs) {
-       var vars []*Node
+       var vars []*ir.Node
        for _, n := range e.curfn.Func.Dcl {
                if livenessShouldTrack(n) && n.Name.Addrtaken() {
                        vars = append(vars, n)
@@ -6215,7 +6216,7 @@ func emitStackObjects(e *ssafn, pp *Progs) {
 
        // Populate the stack object data.
        // Format must match runtime/stack.go:stackObjectRecord.
-       x := e.curfn.Func.lsym.Func().StackObjects
+       x := e.curfn.Func.LSym.Func().StackObjects
        off := 0
        off = duintptr(x, off, uint64(len(vars)))
        for _, v := range vars {
@@ -6252,7 +6253,7 @@ func genssa(f *ssa.Func, pp *Progs) {
        s.livenessMap = liveness(e, f, pp)
        emitStackObjects(e, pp)
 
-       openDeferInfo := e.curfn.Func.lsym.Func().OpenCodedDeferInfo
+       openDeferInfo := e.curfn.Func.LSym.Func().OpenCodedDeferInfo
        if openDeferInfo != nil {
                // This function uses open-coded defers -- write out the funcdata
                // info that we computed at the end of genssa.
@@ -6457,7 +6458,7 @@ func genssa(f *ssa.Func, pp *Progs) {
                                // some of the inline marks.
                                // Use this instruction instead.
                                p.Pos = p.Pos.WithIsStmt() // promote position to a statement
-                               pp.curfn.Func.lsym.Func().AddInlMark(p, inlMarks[m])
+                               pp.curfn.Func.LSym.Func().AddInlMark(p, inlMarks[m])
                                // Make the inline mark a real nop, so it doesn't generate any code.
                                m.As = obj.ANOP
                                m.Pos = src.NoXPos
@@ -6469,7 +6470,7 @@ func genssa(f *ssa.Func, pp *Progs) {
                // Any unmatched inline marks now need to be added to the inlining tree (and will generate a nop instruction).
                for _, p := range inlMarkList {
                        if p.As != obj.ANOP {
-                               pp.curfn.Func.lsym.Func().AddInlMark(p, inlMarks[p])
+                               pp.curfn.Func.LSym.Func().AddInlMark(p, inlMarks[p])
                        }
                }
        }
@@ -6489,7 +6490,7 @@ func genssa(f *ssa.Func, pp *Progs) {
                                }
                                return bstart[b].Pc
                        case ssa.BlockEnd.ID:
-                               return e.curfn.Func.lsym.Size
+                               return e.curfn.Func.LSym.Size
                        default:
                                return valueToProgAfter[v].Pc
                        }
@@ -6591,7 +6592,7 @@ func defframe(s *SSAGenState, e *ssafn) {
                if !n.Name.Needzero() {
                        continue
                }
-               if n.Class() != PAUTO {
+               if n.Class() != ir.PAUTO {
                        e.Fatalf(n.Pos, "needzero class %d", n.Class())
                }
                if n.Type.Size()%int64(Widthptr) != 0 || n.Xoffset%int64(Widthptr) != 0 || n.Type.Size() == 0 {
@@ -6675,8 +6676,8 @@ func AddAux2(a *obj.Addr, v *ssa.Value, offset int64) {
        case *obj.LSym:
                a.Name = obj.NAME_EXTERN
                a.Sym = n
-       case *Node:
-               if n.Class() == PPARAM || n.Class() == PPARAMOUT {
+       case *ir.Node:
+               if n.Class() == ir.PPARAM || n.Class() == ir.PPARAMOUT {
                        a.Name = obj.NAME_PARAM
                        a.Sym = n.Orig.Sym.Linksym()
                        a.Offset += n.Xoffset
@@ -6702,17 +6703,17 @@ func (s *state) extendIndex(idx, len *ssa.Value, kind ssa.BoundsKind, bounded bo
                // high word and branch to out-of-bounds failure if it is not 0.
                var lo *ssa.Value
                if idx.Type.IsSigned() {
-                       lo = s.newValue1(ssa.OpInt64Lo, types.Types[TINT], idx)
+                       lo = s.newValue1(ssa.OpInt64Lo, types.Types[types.TINT], idx)
                } else {
-                       lo = s.newValue1(ssa.OpInt64Lo, types.Types[TUINT], idx)
+                       lo = s.newValue1(ssa.OpInt64Lo, types.Types[types.TUINT], idx)
                }
                if bounded || base.Flag.B != 0 {
                        return lo
                }
                bNext := s.f.NewBlock(ssa.BlockPlain)
                bPanic := s.f.NewBlock(ssa.BlockExit)
-               hi := s.newValue1(ssa.OpInt64Hi, types.Types[TUINT32], idx)
-               cmp := s.newValue2(ssa.OpEq32, types.Types[TBOOL], hi, s.constInt32(types.Types[TUINT32], 0))
+               hi := s.newValue1(ssa.OpInt64Hi, types.Types[types.TUINT32], idx)
+               cmp := s.newValue2(ssa.OpEq32, types.Types[types.TBOOL], hi, s.constInt32(types.Types[types.TUINT32], 0))
                if !idx.Type.IsSigned() {
                        switch kind {
                        case ssa.BoundsIndex:
@@ -6781,7 +6782,7 @@ func (s *state) extendIndex(idx, len *ssa.Value, kind ssa.BoundsKind, bounded bo
                        s.Fatalf("bad unsigned index extension %s", idx.Type)
                }
        }
-       return s.newValue1(op, types.Types[TINT], idx)
+       return s.newValue1(op, types.Types[types.TINT], idx)
 }
 
 // CheckLoweredPhi checks that regalloc and stackalloc correctly handled phi values.
@@ -6814,12 +6815,12 @@ func CheckLoweredGetClosurePtr(v *ssa.Value) {
 
 // AutoVar returns a *Node and int64 representing the auto variable and offset within it
 // where v should be spilled.
-func AutoVar(v *ssa.Value) (*Node, int64) {
+func AutoVar(v *ssa.Value) (*ir.Node, int64) {
        loc := v.Block.Func.RegAlloc[v.ID].(ssa.LocalSlot)
        if v.Type.Size() > loc.Type.Size() {
                v.Fatalf("spill/restore type %s doesn't fit in slot type %s", v.Type, loc.Type)
        }
-       return loc.N.(*Node), loc.Off
+       return loc.N.(*ir.Node), loc.Off
 }
 
 func AddrAuto(a *obj.Addr, v *ssa.Value) {
@@ -6828,7 +6829,7 @@ func AddrAuto(a *obj.Addr, v *ssa.Value) {
        a.Sym = n.Sym.Linksym()
        a.Reg = int16(thearch.REGSP)
        a.Offset = n.Xoffset + off
-       if n.Class() == PPARAM || n.Class() == PPARAMOUT {
+       if n.Class() == ir.PPARAM || n.Class() == ir.PPARAMOUT {
                a.Name = obj.NAME_PARAM
        } else {
                a.Name = obj.NAME_AUTO
@@ -6925,7 +6926,7 @@ func (s *SSAGenState) UseArgs(n int64) {
 }
 
 // fieldIdx finds the index of the field referred to by the ODOT node n.
-func fieldIdx(n *Node) int {
+func fieldIdx(n *ir.Node) int {
        t := n.Left.Type
        f := n.Sym
        if !t.IsStruct() {
@@ -6952,9 +6953,9 @@ func fieldIdx(n *Node) int {
 // ssafn holds frontend information about a function that the backend is processing.
 // It also exports a bunch of compiler services for the ssa backend.
 type ssafn struct {
-       curfn        *Node
+       curfn        *ir.Node
        strings      map[string]*obj.LSym // map from constant string to data symbols
-       scratchFpMem *Node                // temp for floating point register / memory moves on some architectures
+       scratchFpMem *ir.Node             // temp for floating point register / memory moves on some architectures
        stksize      int64                // stack size for current frame
        stkptrsize   int64                // prefix of stack containing pointers
        log          bool                 // print ssa debug to the stdout
@@ -6980,8 +6981,8 @@ func (e *ssafn) Auto(pos src.XPos, t *types.Type) ssa.GCNode {
 }
 
 func (e *ssafn) SplitString(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot) {
-       ptrType := types.NewPtr(types.Types[TUINT8])
-       lenType := types.Types[TINT]
+       ptrType := types.NewPtr(types.Types[types.TUINT8])
+       lenType := types.Types[types.TINT]
        // Split this string up into two separate variables.
        p := e.SplitSlot(&name, ".ptr", 0, ptrType)
        l := e.SplitSlot(&name, ".len", ptrType.Size(), lenType)
@@ -6989,9 +6990,9 @@ func (e *ssafn) SplitString(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot) {
 }
 
 func (e *ssafn) SplitInterface(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot) {
-       n := name.N.(*Node)
-       u := types.Types[TUINTPTR]
-       t := types.NewPtr(types.Types[TUINT8])
+       n := name.N.(*ir.Node)
+       u := types.Types[types.TUINTPTR]
+       t := types.NewPtr(types.Types[types.TUINT8])
        // Split this interface up into two separate variables.
        f := ".itab"
        if n.Type.IsEmptyInterface() {
@@ -7004,7 +7005,7 @@ func (e *ssafn) SplitInterface(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot
 
 func (e *ssafn) SplitSlice(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot, ssa.LocalSlot) {
        ptrType := types.NewPtr(name.Type.Elem())
-       lenType := types.Types[TINT]
+       lenType := types.Types[types.TINT]
        p := e.SplitSlot(&name, ".ptr", 0, ptrType)
        l := e.SplitSlot(&name, ".len", ptrType.Size(), lenType)
        c := e.SplitSlot(&name, ".cap", ptrType.Size()+lenType.Size(), lenType)
@@ -7015,9 +7016,9 @@ func (e *ssafn) SplitComplex(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot)
        s := name.Type.Size() / 2
        var t *types.Type
        if s == 8 {
-               t = types.Types[TFLOAT64]
+               t = types.Types[types.TFLOAT64]
        } else {
-               t = types.Types[TFLOAT32]
+               t = types.Types[types.TFLOAT32]
        }
        r := e.SplitSlot(&name, ".real", 0, t)
        i := e.SplitSlot(&name, ".imag", t.Size(), t)
@@ -7027,14 +7028,14 @@ func (e *ssafn) SplitComplex(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot)
 func (e *ssafn) SplitInt64(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot) {
        var t *types.Type
        if name.Type.IsSigned() {
-               t = types.Types[TINT32]
+               t = types.Types[types.TINT32]
        } else {
-               t = types.Types[TUINT32]
+               t = types.Types[types.TUINT32]
        }
        if thearch.LinkArch.ByteOrder == binary.BigEndian {
-               return e.SplitSlot(&name, ".hi", 0, t), e.SplitSlot(&name, ".lo", t.Size(), types.Types[TUINT32])
+               return e.SplitSlot(&name, ".hi", 0, t), e.SplitSlot(&name, ".lo", t.Size(), types.Types[types.TUINT32])
        }
-       return e.SplitSlot(&name, ".hi", t.Size(), t), e.SplitSlot(&name, ".lo", 0, types.Types[TUINT32])
+       return e.SplitSlot(&name, ".hi", t.Size(), t), e.SplitSlot(&name, ".lo", 0, types.Types[types.TUINT32])
 }
 
 func (e *ssafn) SplitStruct(name ssa.LocalSlot, i int) ssa.LocalSlot {
@@ -7046,7 +7047,7 @@ func (e *ssafn) SplitStruct(name ssa.LocalSlot, i int) ssa.LocalSlot {
 }
 
 func (e *ssafn) SplitArray(name ssa.LocalSlot) ssa.LocalSlot {
-       n := name.N.(*Node)
+       n := name.N.(*ir.Node)
        at := name.Type
        if at.NumElem() != 1 {
                e.Fatalf(n.Pos, "bad array size")
@@ -7061,19 +7062,19 @@ func (e *ssafn) DerefItab(it *obj.LSym, offset int64) *obj.LSym {
 
 // SplitSlot returns a slot representing the data of parent starting at offset.
 func (e *ssafn) SplitSlot(parent *ssa.LocalSlot, suffix string, offset int64, t *types.Type) ssa.LocalSlot {
-       node := parent.N.(*Node)
+       node := parent.N.(*ir.Node)
 
-       if node.Class() != PAUTO || node.Name.Addrtaken() {
+       if node.Class() != ir.PAUTO || node.Name.Addrtaken() {
                // addressed things and non-autos retain their parents (i.e., cannot truly be split)
                return ssa.LocalSlot{N: node, Type: t, Off: parent.Off + offset}
        }
 
-       s := &types.Sym{Name: node.Sym.Name + suffix, Pkg: localpkg}
-       n := newnamel(parent.N.(*Node).Pos, s)
-       s.Def = asTypesNode(n)
-       asNode(s.Def).Name.SetUsed(true)
+       s := &types.Sym{Name: node.Sym.Name + suffix, Pkg: ir.LocalPkg}
+       n := ir.NewNameAt(parent.N.(*ir.Node).Pos, s)
+       s.Def = ir.AsTypesNode(n)
+       ir.AsNode(s.Def).Name.SetUsed(true)
        n.Type = t
-       n.SetClass(PAUTO)
+       n.SetClass(ir.PAUTO)
        n.Esc = EscNever
        n.Name.Curfn = e.curfn
        e.curfn.Func.Dcl = append(e.curfn.Func.Dcl, n)
@@ -7103,7 +7104,7 @@ func (e *ssafn) Log() bool {
 // Fatal reports a compiler error and exits.
 func (e *ssafn) Fatalf(pos src.XPos, msg string, args ...interface{}) {
        base.Pos = pos
-       nargs := append([]interface{}{e.curfn.funcname()}, args...)
+       nargs := append([]interface{}{ir.FuncName(e.curfn)}, args...)
        base.Fatalf("'%s': "+msg, nargs...)
 }
 
@@ -7139,35 +7140,18 @@ func (e *ssafn) Syslook(name string) *obj.LSym {
 }
 
 func (e *ssafn) SetWBPos(pos src.XPos) {
-       e.curfn.Func.setWBPos(pos)
+       e.curfn.Func.SetWBPos(pos)
 }
 
 func (e *ssafn) MyImportPath() string {
        return base.Ctxt.Pkgpath
 }
 
-func (n *Node) Typ() *types.Type {
-       return n.Type
-}
-func (n *Node) StorageClass() ssa.StorageClass {
-       switch n.Class() {
-       case PPARAM:
-               return ssa.ClassParam
-       case PPARAMOUT:
-               return ssa.ClassParamOut
-       case PAUTO:
-               return ssa.ClassAuto
-       default:
-               base.Fatalf("untranslatable storage class for %v: %s", n, n.Class())
-               return 0
-       }
-}
-
-func clobberBase(n *Node) *Node {
-       if n.Op == ODOT && n.Left.Type.NumFields() == 1 {
+func clobberBase(n *ir.Node) *ir.Node {
+       if n.Op == ir.ODOT && n.Left.Type.NumFields() == 1 {
                return clobberBase(n.Left)
        }
-       if n.Op == OINDEX && n.Left.Type.IsArray() && n.Left.Type.NumElem() == 1 {
+       if n.Op == ir.OINDEX && n.Left.Type.IsArray() && n.Left.Type.NumElem() == 1 {
                return clobberBase(n.Left)
        }
        return n
index 00402a1bee65d45c03de18f3b31b4b6d47508518..46f4153fe19fcfe8df3aa7f5447c97f54fae136d 100644 (file)
@@ -6,6 +6,7 @@ package gc
 
 import (
        "cmd/compile/internal/base"
+       "cmd/compile/internal/ir"
        "cmd/compile/internal/types"
        "cmd/internal/src"
        "crypto/md5"
@@ -39,11 +40,11 @@ var (
 // It's primarily used to distinguish references to named objects,
 // whose Pos will point back to their declaration position rather than
 // their usage position.
-func hasUniquePos(n *Node) bool {
+func hasUniquePos(n *ir.Node) bool {
        switch n.Op {
-       case ONAME, OPACK:
+       case ir.ONAME, ir.OPACK:
                return false
-       case OLITERAL, ONIL, OTYPE:
+       case ir.OLITERAL, ir.ONIL, ir.OTYPE:
                if n.Sym != nil {
                        return false
                }
@@ -59,7 +60,7 @@ func hasUniquePos(n *Node) bool {
        return true
 }
 
-func setlineno(n *Node) src.XPos {
+func setlineno(n *ir.Node) src.XPos {
        lno := base.Pos
        if n != nil && hasUniquePos(n) {
                base.Pos = n.Pos
@@ -68,7 +69,7 @@ func setlineno(n *Node) src.XPos {
 }
 
 func lookup(name string) *types.Sym {
-       return localpkg.Lookup(name)
+       return ir.LocalPkg.Lookup(name)
 }
 
 // lookupN looks up the symbol starting with prefix and ending with
@@ -77,7 +78,7 @@ func lookupN(prefix string, n int) *types.Sym {
        var buf [20]byte // plenty long enough for all current users
        copy(buf[:], prefix)
        b := strconv.AppendInt(buf[:len(prefix)], int64(n), 10)
-       return localpkg.LookupBytes(b)
+       return ir.LocalPkg.LookupBytes(b)
 }
 
 // autolabel generates a new Name node for use with
@@ -101,7 +102,7 @@ func autolabel(prefix string) *types.Sym {
 
 // find all the exported symbols in package opkg
 // and make them available in the current package
-func importdot(opkg *types.Pkg, pack *Node) {
+func importdot(opkg *types.Pkg, pack *ir.Node) {
        n := 0
        for _, s := range opkg.Syms {
                if s.Def == nil {
@@ -119,11 +120,11 @@ func importdot(opkg *types.Pkg, pack *Node) {
 
                s1.Def = s.Def
                s1.Block = s.Block
-               if asNode(s1.Def).Name == nil {
-                       Dump("s1def", asNode(s1.Def))
+               if ir.AsNode(s1.Def).Name == nil {
+                       ir.Dump("s1def", ir.AsNode(s1.Def))
                        base.Fatalf("missing Name")
                }
-               asNode(s1.Def).Name.Pack = pack
+               ir.AsNode(s1.Def).Name.Pack = pack
                s1.Origpkg = opkg
                n++
        }
@@ -134,118 +135,27 @@ func importdot(opkg *types.Pkg, pack *Node) {
        }
 }
 
-func nod(op Op, nleft, nright *Node) *Node {
-       return nodl(base.Pos, op, nleft, nright)
-}
-
-func nodl(pos src.XPos, op Op, nleft, nright *Node) *Node {
-       var n *Node
-       switch op {
-       case ODCLFUNC:
-               var x struct {
-                       n Node
-                       f Func
-               }
-               n = &x.n
-               n.Func = &x.f
-               n.Func.Decl = n
-       case ONAME:
-               base.Fatalf("use newname instead")
-       case OLABEL, OPACK:
-               var x struct {
-                       n Node
-                       m Name
-               }
-               n = &x.n
-               n.Name = &x.m
-       default:
-               n = new(Node)
-       }
-       n.Op = op
-       n.Left = nleft
-       n.Right = nright
-       n.Pos = pos
-       n.Xoffset = BADWIDTH
-       n.Orig = n
-       return n
-}
-
 // newname returns a new ONAME Node associated with symbol s.
-func newname(s *types.Sym) *Node {
-       n := newnamel(base.Pos, s)
+func NewName(s *types.Sym) *ir.Node {
+       n := ir.NewNameAt(base.Pos, s)
        n.Name.Curfn = Curfn
        return n
 }
 
-// newnamel returns a new ONAME Node associated with symbol s at position pos.
-// The caller is responsible for setting n.Name.Curfn.
-func newnamel(pos src.XPos, s *types.Sym) *Node {
-       if s == nil {
-               base.Fatalf("newnamel nil")
-       }
-
-       var x struct {
-               n Node
-               m Name
-               p Param
-       }
-       n := &x.n
-       n.Name = &x.m
-       n.Name.Param = &x.p
-
-       n.Op = ONAME
-       n.Pos = pos
-       n.Orig = n
-
-       n.Sym = s
-       return n
-}
-
 // nodSym makes a Node with Op op and with the Left field set to left
 // and the Sym field set to sym. This is for ODOT and friends.
-func nodSym(op Op, left *Node, sym *types.Sym) *Node {
+func nodSym(op ir.Op, left *ir.Node, sym *types.Sym) *ir.Node {
        return nodlSym(base.Pos, op, left, sym)
 }
 
 // nodlSym makes a Node with position Pos, with Op op, and with the Left field set to left
 // and the Sym field set to sym. This is for ODOT and friends.
-func nodlSym(pos src.XPos, op Op, left *Node, sym *types.Sym) *Node {
-       n := nodl(pos, op, left, nil)
+func nodlSym(pos src.XPos, op ir.Op, left *ir.Node, sym *types.Sym) *ir.Node {
+       n := ir.NodAt(pos, op, left, nil)
        n.Sym = sym
        return n
 }
 
-// rawcopy returns a shallow copy of n.
-// Note: copy or sepcopy (rather than rawcopy) is usually the
-//       correct choice (see comment with Node.copy, below).
-func (n *Node) rawcopy() *Node {
-       copy := *n
-       return &copy
-}
-
-// sepcopy returns a separate shallow copy of n, with the copy's
-// Orig pointing to itself.
-func (n *Node) sepcopy() *Node {
-       copy := *n
-       copy.Orig = &copy
-       return &copy
-}
-
-// copy returns shallow copy of n and adjusts the copy's Orig if
-// necessary: In general, if n.Orig points to itself, the copy's
-// Orig should point to itself as well. Otherwise, if n is modified,
-// the copy's Orig node appears modified, too, and then doesn't
-// represent the original node anymore.
-// (This caused the wrong complit Op to be used when printing error
-// messages; see issues #26855, #27765).
-func (n *Node) copy() *Node {
-       copy := *n
-       if n.Orig == n {
-               copy.Orig = &copy
-       }
-       return &copy
-}
-
 // methcmp sorts methods by symbol.
 type methcmp []*types.Field
 
@@ -253,67 +163,60 @@ func (x methcmp) Len() int           { return len(x) }
 func (x methcmp) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
 func (x methcmp) Less(i, j int) bool { return x[i].Sym.Less(x[j].Sym) }
 
-func nodintconst(v int64) *Node {
-       return nodlit(constant.MakeInt64(v))
+func nodintconst(v int64) *ir.Node {
+       return ir.NewLiteral(constant.MakeInt64(v))
 }
 
-func nodnil() *Node {
-       n := nod(ONIL, nil, nil)
-       n.Type = types.Types[TNIL]
+func nodnil() *ir.Node {
+       n := ir.Nod(ir.ONIL, nil, nil)
+       n.Type = types.Types[types.TNIL]
        return n
 }
 
-func nodbool(b bool) *Node {
-       return nodlit(constant.MakeBool(b))
+func nodbool(b bool) *ir.Node {
+       return ir.NewLiteral(constant.MakeBool(b))
 }
 
-func nodstr(s string) *Node {
-       return nodlit(constant.MakeString(s))
+func nodstr(s string) *ir.Node {
+       return ir.NewLiteral(constant.MakeString(s))
 }
 
 // treecopy recursively copies n, with the exception of
 // ONAME, OLITERAL, OTYPE, and ONONAME leaves.
 // If pos.IsKnown(), it sets the source position of newly
 // allocated nodes to pos.
-func treecopy(n *Node, pos src.XPos) *Node {
+func treecopy(n *ir.Node, pos src.XPos) *ir.Node {
        if n == nil {
                return nil
        }
 
        switch n.Op {
        default:
-               m := n.sepcopy()
+               m := ir.SepCopy(n)
                m.Left = treecopy(n.Left, pos)
                m.Right = treecopy(n.Right, pos)
                m.List.Set(listtreecopy(n.List.Slice(), pos))
                if pos.IsKnown() {
                        m.Pos = pos
                }
-               if m.Name != nil && n.Op != ODCLFIELD {
-                       Dump("treecopy", n)
+               if m.Name != nil && n.Op != ir.ODCLFIELD {
+                       ir.Dump("treecopy", n)
                        base.Fatalf("treecopy Name")
                }
                return m
 
-       case OPACK:
+       case ir.OPACK:
                // OPACK nodes are never valid in const value declarations,
                // but allow them like any other declared symbol to avoid
                // crashing (golang.org/issue/11361).
                fallthrough
 
-       case ONAME, ONONAME, OLITERAL, ONIL, OTYPE:
+       case ir.ONAME, ir.ONONAME, ir.OLITERAL, ir.ONIL, ir.OTYPE:
                return n
 
        }
 }
 
-// isNil reports whether n represents the universal untyped zero value "nil".
-func (n *Node) isNil() bool {
-       // Check n.Orig because constant propagation may produce typed nil constants,
-       // which don't exist in the Go spec.
-       return n.Orig.Op == ONIL
-}
-
 func isptrto(t *types.Type, et types.EType) bool {
        if t == nil {
                return false
@@ -331,13 +234,6 @@ func isptrto(t *types.Type, et types.EType) bool {
        return true
 }
 
-func (n *Node) isBlank() bool {
-       if n == nil {
-               return false
-       }
-       return n.Sym.IsBlank()
-}
-
 // methtype returns the underlying type, if any,
 // that owns methods with receiver parameter t.
 // The result is either a named type or an anonymous struct.
@@ -367,7 +263,7 @@ func methtype(t *types.Type) *types.Type {
                return t
        }
        switch t.Etype {
-       case TARRAY, TCHAN, TFUNC, TMAP, TSLICE, TSTRING, TSTRUCT:
+       case types.TARRAY, types.TCHAN, types.TFUNC, types.TMAP, types.TSLICE, types.TSTRING, types.TSTRUCT:
                return t
        }
        return nil
@@ -377,17 +273,17 @@ func methtype(t *types.Type) *types.Type {
 // If so, return op code to use in conversion.
 // If not, return OXXX. In this case, the string return parameter may
 // hold a reason why. In all other cases, it'll be the empty string.
-func assignop(src, dst *types.Type) (Op, string) {
+func assignop(src, dst *types.Type) (ir.Op, string) {
        if src == dst {
-               return OCONVNOP, ""
+               return ir.OCONVNOP, ""
        }
-       if src == nil || dst == nil || src.Etype == TFORW || dst.Etype == TFORW || src.Orig == nil || dst.Orig == nil {
-               return OXXX, ""
+       if src == nil || dst == nil || src.Etype == types.TFORW || dst.Etype == types.TFORW || src.Orig == nil || dst.Orig == nil {
+               return ir.OXXX, ""
        }
 
        // 1. src type is identical to dst.
        if types.Identical(src, dst) {
-               return OCONVNOP, ""
+               return ir.OCONVNOP, ""
        }
 
        // 2. src and dst have identical underlying types
@@ -401,31 +297,31 @@ func assignop(src, dst *types.Type) (Op, string) {
                if src.IsEmptyInterface() {
                        // Conversion between two empty interfaces
                        // requires no code.
-                       return OCONVNOP, ""
+                       return ir.OCONVNOP, ""
                }
                if (src.Sym == nil || dst.Sym == nil) && !src.IsInterface() {
                        // Conversion between two types, at least one unnamed,
                        // needs no conversion. The exception is nonempty interfaces
                        // which need to have their itab updated.
-                       return OCONVNOP, ""
+                       return ir.OCONVNOP, ""
                }
        }
 
        // 3. dst is an interface type and src implements dst.
-       if dst.IsInterface() && src.Etype != TNIL {
+       if dst.IsInterface() && src.Etype != types.TNIL {
                var missing, have *types.Field
                var ptr int
                if implements(src, dst, &missing, &have, &ptr) {
-                       return OCONVIFACE, ""
+                       return ir.OCONVIFACE, ""
                }
 
                // we'll have complained about this method anyway, suppress spurious messages.
                if have != nil && have.Sym == missing.Sym && (have.Type.Broke() || missing.Type.Broke()) {
-                       return OCONVIFACE, ""
+                       return ir.OCONVIFACE, ""
                }
 
                var why string
-               if isptrto(src, TINTER) {
+               if isptrto(src, types.TINTER) {
                        why = fmt.Sprintf(":\n\t%v is pointer to interface, not interface", src)
                } else if have != nil && have.Sym == missing.Sym && have.Nointerface() {
                        why = fmt.Sprintf(":\n\t%v does not implement %v (%v method is marked 'nointerface')", src, dst, missing.Sym)
@@ -441,22 +337,22 @@ func assignop(src, dst *types.Type) (Op, string) {
                        why = fmt.Sprintf(":\n\t%v does not implement %v (missing %v method)", src, dst, missing.Sym)
                }
 
-               return OXXX, why
+               return ir.OXXX, why
        }
 
-       if isptrto(dst, TINTER) {
+       if isptrto(dst, types.TINTER) {
                why := fmt.Sprintf(":\n\t%v is pointer to interface, not interface", dst)
-               return OXXX, why
+               return ir.OXXX, why
        }
 
-       if src.IsInterface() && dst.Etype != TBLANK {
+       if src.IsInterface() && dst.Etype != types.TBLANK {
                var missing, have *types.Field
                var ptr int
                var why string
                if implements(dst, src, &missing, &have, &ptr) {
                        why = ": need type assertion"
                }
-               return OXXX, why
+               return ir.OXXX, why
        }
 
        // 4. src is a bidirectional channel value, dst is a channel type,
@@ -464,31 +360,31 @@ func assignop(src, dst *types.Type) (Op, string) {
        // either src or dst is not a named type.
        if src.IsChan() && src.ChanDir() == types.Cboth && dst.IsChan() {
                if types.Identical(src.Elem(), dst.Elem()) && (src.Sym == nil || dst.Sym == nil) {
-                       return OCONVNOP, ""
+                       return ir.OCONVNOP, ""
                }
        }
 
        // 5. src is the predeclared identifier nil and dst is a nillable type.
-       if src.Etype == TNIL {
+       if src.Etype == types.TNIL {
                switch dst.Etype {
-               case TPTR,
-                       TFUNC,
-                       TMAP,
-                       TCHAN,
-                       TINTER,
-                       TSLICE:
-                       return OCONVNOP, ""
+               case types.TPTR,
+                       types.TFUNC,
+                       types.TMAP,
+                       types.TCHAN,
+                       types.TINTER,
+                       types.TSLICE:
+                       return ir.OCONVNOP, ""
                }
        }
 
        // 6. rule about untyped constants - already converted by defaultlit.
 
        // 7. Any typed value can be assigned to the blank identifier.
-       if dst.Etype == TBLANK {
-               return OCONVNOP, ""
+       if dst.Etype == types.TBLANK {
+               return ir.OCONVNOP, ""
        }
 
-       return OXXX, ""
+       return ir.OXXX, ""
 }
 
 // Can we convert a value of type src to a value of type dst?
@@ -496,12 +392,12 @@ func assignop(src, dst *types.Type) (Op, string) {
 // If not, return OXXX. In this case, the string return parameter may
 // hold a reason why. In all other cases, it'll be the empty string.
 // srcConstant indicates whether the value of type src is a constant.
-func convertop(srcConstant bool, src, dst *types.Type) (Op, string) {
+func convertop(srcConstant bool, src, dst *types.Type) (ir.Op, string) {
        if src == dst {
-               return OCONVNOP, ""
+               return ir.OCONVNOP, ""
        }
        if src == nil || dst == nil {
-               return OXXX, ""
+               return ir.OXXX, ""
        }
 
        // Conversions from regular to go:notinheap are not allowed
@@ -510,17 +406,17 @@ func convertop(srcConstant bool, src, dst *types.Type) (Op, string) {
        // (a) Disallow (*T) to (*U) where T is go:notinheap but U isn't.
        if src.IsPtr() && dst.IsPtr() && dst.Elem().NotInHeap() && !src.Elem().NotInHeap() {
                why := fmt.Sprintf(":\n\t%v is incomplete (or unallocatable), but %v is not", dst.Elem(), src.Elem())
-               return OXXX, why
+               return ir.OXXX, why
        }
        // (b) Disallow string to []T where T is go:notinheap.
        if src.IsString() && dst.IsSlice() && dst.Elem().NotInHeap() && (dst.Elem().Etype == types.Bytetype.Etype || dst.Elem().Etype == types.Runetype.Etype) {
                why := fmt.Sprintf(":\n\t%v is incomplete (or unallocatable)", dst.Elem())
-               return OXXX, why
+               return ir.OXXX, why
        }
 
        // 1. src can be assigned to dst.
        op, why := assignop(src, dst)
-       if op != OXXX {
+       if op != ir.OXXX {
                return op, why
        }
 
@@ -529,57 +425,57 @@ func convertop(srcConstant bool, src, dst *types.Type) (Op, string) {
        // with the good message from assignop.
        // Otherwise clear the error.
        if src.IsInterface() || dst.IsInterface() {
-               return OXXX, why
+               return ir.OXXX, why
        }
 
        // 2. Ignoring struct tags, src and dst have identical underlying types.
        if types.IdenticalIgnoreTags(src.Orig, dst.Orig) {
-               return OCONVNOP, ""
+               return ir.OCONVNOP, ""
        }
 
        // 3. src and dst are unnamed pointer types and, ignoring struct tags,
        // their base types have identical underlying types.
        if src.IsPtr() && dst.IsPtr() && src.Sym == nil && dst.Sym == nil {
                if types.IdenticalIgnoreTags(src.Elem().Orig, dst.Elem().Orig) {
-                       return OCONVNOP, ""
+                       return ir.OCONVNOP, ""
                }
        }
 
        // 4. src and dst are both integer or floating point types.
        if (src.IsInteger() || src.IsFloat()) && (dst.IsInteger() || dst.IsFloat()) {
                if simtype[src.Etype] == simtype[dst.Etype] {
-                       return OCONVNOP, ""
+                       return ir.OCONVNOP, ""
                }
-               return OCONV, ""
+               return ir.OCONV, ""
        }
 
        // 5. src and dst are both complex types.
        if src.IsComplex() && dst.IsComplex() {
                if simtype[src.Etype] == simtype[dst.Etype] {
-                       return OCONVNOP, ""
+                       return ir.OCONVNOP, ""
                }
-               return OCONV, ""
+               return ir.OCONV, ""
        }
 
        // Special case for constant conversions: any numeric
        // conversion is potentially okay. We'll validate further
        // within evconst. See #38117.
        if srcConstant && (src.IsInteger() || src.IsFloat() || src.IsComplex()) && (dst.IsInteger() || dst.IsFloat() || dst.IsComplex()) {
-               return OCONV, ""
+               return ir.OCONV, ""
        }
 
        // 6. src is an integer or has type []byte or []rune
        // and dst is a string type.
        if src.IsInteger() && dst.IsString() {
-               return ORUNESTR, ""
+               return ir.ORUNESTR, ""
        }
 
        if src.IsSlice() && dst.IsString() {
                if src.Elem().Etype == types.Bytetype.Etype {
-                       return OBYTES2STR, ""
+                       return ir.OBYTES2STR, ""
                }
                if src.Elem().Etype == types.Runetype.Etype {
-                       return ORUNES2STR, ""
+                       return ir.ORUNES2STR, ""
                }
        }
 
@@ -587,45 +483,45 @@ func convertop(srcConstant bool, src, dst *types.Type) (Op, string) {
        // String to slice.
        if src.IsString() && dst.IsSlice() {
                if dst.Elem().Etype == types.Bytetype.Etype {
-                       return OSTR2BYTES, ""
+                       return ir.OSTR2BYTES, ""
                }
                if dst.Elem().Etype == types.Runetype.Etype {
-                       return OSTR2RUNES, ""
+                       return ir.OSTR2RUNES, ""
                }
        }
 
        // 8. src is a pointer or uintptr and dst is unsafe.Pointer.
        if (src.IsPtr() || src.IsUintptr()) && dst.IsUnsafePtr() {
-               return OCONVNOP, ""
+               return ir.OCONVNOP, ""
        }
 
        // 9. src is unsafe.Pointer and dst is a pointer or uintptr.
        if src.IsUnsafePtr() && (dst.IsPtr() || dst.IsUintptr()) {
-               return OCONVNOP, ""
+               return ir.OCONVNOP, ""
        }
 
        // src is map and dst is a pointer to corresponding hmap.
        // This rule is needed for the implementation detail that
        // go gc maps are implemented as a pointer to a hmap struct.
-       if src.Etype == TMAP && dst.IsPtr() &&
+       if src.Etype == types.TMAP && dst.IsPtr() &&
                src.MapType().Hmap == dst.Elem() {
-               return OCONVNOP, ""
+               return ir.OCONVNOP, ""
        }
 
-       return OXXX, ""
+       return ir.OXXX, ""
 }
 
-func assignconv(n *Node, t *types.Type, context string) *Node {
+func assignconv(n *ir.Node, t *types.Type, context string) *ir.Node {
        return assignconvfn(n, t, func() string { return context })
 }
 
 // Convert node n for assignment to type t.
-func assignconvfn(n *Node, t *types.Type, context func() string) *Node {
+func assignconvfn(n *ir.Node, t *types.Type, context func() string) *ir.Node {
        if n == nil || n.Type == nil || n.Type.Broke() {
                return n
        }
 
-       if t.Etype == TBLANK && n.Type.Etype == TNIL {
+       if t.Etype == types.TBLANK && n.Type.Etype == types.TNIL {
                base.Errorf("use of untyped nil")
        }
 
@@ -633,16 +529,16 @@ func assignconvfn(n *Node, t *types.Type, context func() string) *Node {
        if n.Type == nil {
                return n
        }
-       if t.Etype == TBLANK {
+       if t.Etype == types.TBLANK {
                return n
        }
 
        // Convert ideal bool from comparison to plain bool
        // if the next step is non-bool (like interface{}).
        if n.Type == types.UntypedBool && !t.IsBoolean() {
-               if n.Op == ONAME || n.Op == OLITERAL {
-                       r := nod(OCONVNOP, n, nil)
-                       r.Type = types.Types[TBOOL]
+               if n.Op == ir.ONAME || n.Op == ir.OLITERAL {
+                       r := ir.Nod(ir.OCONVNOP, n, nil)
+                       r.Type = types.Types[types.TBOOL]
                        r.SetTypecheck(1)
                        r.SetImplicit(true)
                        n = r
@@ -654,12 +550,12 @@ func assignconvfn(n *Node, t *types.Type, context func() string) *Node {
        }
 
        op, why := assignop(n.Type, t)
-       if op == OXXX {
+       if op == ir.OXXX {
                base.Errorf("cannot use %L as type %v in %s%s", n, t, context(), why)
-               op = OCONV
+               op = ir.OCONV
        }
 
-       r := nod(op, n, nil)
+       r := ir.Nod(op, n, nil)
        r.Type = t
        r.SetTypecheck(1)
        r.SetImplicit(true)
@@ -667,103 +563,29 @@ func assignconvfn(n *Node, t *types.Type, context func() string) *Node {
        return r
 }
 
-// IsMethod reports whether n is a method.
-// n must be a function or a method.
-func (n *Node) IsMethod() bool {
-       return n.Type.Recv() != nil
-}
-
-// SliceBounds returns n's slice bounds: low, high, and max in expr[low:high:max].
-// n must be a slice expression. max is nil if n is a simple slice expression.
-func (n *Node) SliceBounds() (low, high, max *Node) {
-       if n.List.Len() == 0 {
-               return nil, nil, nil
-       }
-
-       switch n.Op {
-       case OSLICE, OSLICEARR, OSLICESTR:
-               s := n.List.Slice()
-               return s[0], s[1], nil
-       case OSLICE3, OSLICE3ARR:
-               s := n.List.Slice()
-               return s[0], s[1], s[2]
-       }
-       base.Fatalf("SliceBounds op %v: %v", n.Op, n)
-       return nil, nil, nil
-}
-
-// SetSliceBounds sets n's slice bounds, where n is a slice expression.
-// n must be a slice expression. If max is non-nil, n must be a full slice expression.
-func (n *Node) SetSliceBounds(low, high, max *Node) {
-       switch n.Op {
-       case OSLICE, OSLICEARR, OSLICESTR:
-               if max != nil {
-                       base.Fatalf("SetSliceBounds %v given three bounds", n.Op)
-               }
-               s := n.List.Slice()
-               if s == nil {
-                       if low == nil && high == nil {
-                               return
-                       }
-                       n.List.Set2(low, high)
-                       return
-               }
-               s[0] = low
-               s[1] = high
-               return
-       case OSLICE3, OSLICE3ARR:
-               s := n.List.Slice()
-               if s == nil {
-                       if low == nil && high == nil && max == nil {
-                               return
-                       }
-                       n.List.Set3(low, high, max)
-                       return
-               }
-               s[0] = low
-               s[1] = high
-               s[2] = max
-               return
-       }
-       base.Fatalf("SetSliceBounds op %v: %v", n.Op, n)
-}
-
-// IsSlice3 reports whether o is a slice3 op (OSLICE3, OSLICE3ARR).
-// o must be a slicing op.
-func (o Op) IsSlice3() bool {
-       switch o {
-       case OSLICE, OSLICEARR, OSLICESTR:
-               return false
-       case OSLICE3, OSLICE3ARR:
-               return true
-       }
-       base.Fatalf("IsSlice3 op %v", o)
-       return false
-}
-
 // backingArrayPtrLen extracts the pointer and length from a slice or string.
 // This constructs two nodes referring to n, so n must be a cheapexpr.
-func (n *Node) backingArrayPtrLen() (ptr, len *Node) {
-       var init Nodes
+func backingArrayPtrLen(n *ir.Node) (ptr, len *ir.Node) {
+       var init ir.Nodes
        c := cheapexpr(n, &init)
        if c != n || init.Len() != 0 {
                base.Fatalf("backingArrayPtrLen not cheap: %v", n)
        }
-       ptr = nod(OSPTR, n, nil)
+       ptr = ir.Nod(ir.OSPTR, n, nil)
        if n.Type.IsString() {
-               ptr.Type = types.Types[TUINT8].PtrTo()
+               ptr.Type = types.Types[types.TUINT8].PtrTo()
        } else {
                ptr.Type = n.Type.Elem().PtrTo()
        }
-       len = nod(OLEN, n, nil)
-       len.Type = types.Types[TINT]
+       len = ir.Nod(ir.OLEN, n, nil)
+       len.Type = types.Types[types.TINT]
        return ptr, len
 }
 
 // labeledControl returns the control flow Node (for, switch, select)
 // associated with the label n, if any.
-func (n *Node) labeledControl() *Node {
-       if n.Op != OLABEL {
+func labeledControl(n *ir.Node) *ir.Node {
+       if n.Op != ir.OLABEL {
                base.Fatalf("labeledControl %v", n.Op)
        }
        ctl := n.Name.Defn
@@ -771,18 +593,18 @@ func (n *Node) labeledControl() *Node {
                return nil
        }
        switch ctl.Op {
-       case OFOR, OFORUNTIL, OSWITCH, OSELECT:
+       case ir.OFOR, ir.OFORUNTIL, ir.OSWITCH, ir.OSELECT:
                return ctl
        }
        return nil
 }
 
-func syslook(name string) *Node {
+func syslook(name string) *ir.Node {
        s := Runtimepkg.Lookup(name)
        if s == nil || s.Def == nil {
                base.Fatalf("syslook: can't find runtime.%s", name)
        }
-       return asNode(s.Def)
+       return ir.AsNode(s.Def)
 }
 
 // typehash computes a hash value for type t to use in type switch statements.
@@ -796,49 +618,49 @@ func typehash(t *types.Type) uint32 {
 
 // updateHasCall checks whether expression n contains any function
 // calls and sets the n.HasCall flag if so.
-func updateHasCall(n *Node) {
+func updateHasCall(n *ir.Node) {
        if n == nil {
                return
        }
        n.SetHasCall(calcHasCall(n))
 }
 
-func calcHasCall(n *Node) bool {
+func calcHasCall(n *ir.Node) bool {
        if n.Ninit.Len() != 0 {
                // TODO(mdempsky): This seems overly conservative.
                return true
        }
 
        switch n.Op {
-       case OLITERAL, ONIL, ONAME, OTYPE:
+       case ir.OLITERAL, ir.ONIL, ir.ONAME, ir.OTYPE:
                if n.HasCall() {
                        base.Fatalf("OLITERAL/ONAME/OTYPE should never have calls: %+v", n)
                }
                return false
-       case OCALL, OCALLFUNC, OCALLMETH, OCALLINTER:
+       case ir.OCALL, ir.OCALLFUNC, ir.OCALLMETH, ir.OCALLINTER:
                return true
-       case OANDAND, OOROR:
+       case ir.OANDAND, ir.OOROR:
                // hard with instrumented code
                if instrumenting {
                        return true
                }
-       case OINDEX, OSLICE, OSLICEARR, OSLICE3, OSLICE3ARR, OSLICESTR,
-               ODEREF, ODOTPTR, ODOTTYPE, ODIV, OMOD:
+       case ir.OINDEX, ir.OSLICE, ir.OSLICEARR, ir.OSLICE3, ir.OSLICE3ARR, ir.OSLICESTR,
+               ir.ODEREF, ir.ODOTPTR, ir.ODOTTYPE, ir.ODIV, ir.OMOD:
                // These ops might panic, make sure they are done
                // before we start marshaling args for a call. See issue 16760.
                return true
 
        // When using soft-float, these ops might be rewritten to function calls
        // so we ensure they are evaluated first.
-       case OADD, OSUB, ONEG, OMUL:
+       case ir.OADD, ir.OSUB, ir.ONEG, ir.OMUL:
                if thearch.SoftFloat && (isFloat[n.Type.Etype] || isComplex[n.Type.Etype]) {
                        return true
                }
-       case OLT, OEQ, ONE, OLE, OGE, OGT:
+       case ir.OLT, ir.OEQ, ir.ONE, ir.OLE, ir.OGE, ir.OGT:
                if thearch.SoftFloat && (isFloat[n.Left.Type.Etype] || isComplex[n.Left.Type.Etype]) {
                        return true
                }
-       case OCONV:
+       case ir.OCONV:
                if thearch.SoftFloat && ((isFloat[n.Type.Etype] || isComplex[n.Type.Etype]) || (isFloat[n.Left.Type.Etype] || isComplex[n.Left.Type.Etype])) {
                        return true
                }
@@ -853,7 +675,7 @@ func calcHasCall(n *Node) bool {
        return false
 }
 
-func badtype(op Op, tl, tr *types.Type) {
+func badtype(op ir.Op, tl, tr *types.Type) {
        var s string
        if tl != nil {
                s += fmt.Sprintf("\n\t%v", tl)
@@ -876,20 +698,20 @@ func badtype(op Op, tl, tr *types.Type) {
 
 // brcom returns !(op).
 // For example, brcom(==) is !=.
-func brcom(op Op) Op {
+func brcom(op ir.Op) ir.Op {
        switch op {
-       case OEQ:
-               return ONE
-       case ONE:
-               return OEQ
-       case OLT:
-               return OGE
-       case OGT:
-               return OLE
-       case OLE:
-               return OGT
-       case OGE:
-               return OLT
+       case ir.OEQ:
+               return ir.ONE
+       case ir.ONE:
+               return ir.OEQ
+       case ir.OLT:
+               return ir.OGE
+       case ir.OGT:
+               return ir.OLE
+       case ir.OLE:
+               return ir.OGT
+       case ir.OGE:
+               return ir.OLT
        }
        base.Fatalf("brcom: no com for %v\n", op)
        return op
@@ -897,20 +719,20 @@ func brcom(op Op) Op {
 
 // brrev returns reverse(op).
 // For example, Brrev(<) is >.
-func brrev(op Op) Op {
+func brrev(op ir.Op) ir.Op {
        switch op {
-       case OEQ:
-               return OEQ
-       case ONE:
-               return ONE
-       case OLT:
-               return OGT
-       case OGT:
-               return OLT
-       case OLE:
-               return OGE
-       case OGE:
-               return OLE
+       case ir.OEQ:
+               return ir.OEQ
+       case ir.ONE:
+               return ir.ONE
+       case ir.OLT:
+               return ir.OGT
+       case ir.OGT:
+               return ir.OLT
+       case ir.OLE:
+               return ir.OGE
+       case ir.OGE:
+               return ir.OLE
        }
        base.Fatalf("brrev: no rev for %v\n", op)
        return op
@@ -918,7 +740,7 @@ func brrev(op Op) Op {
 
 // return side effect-free n, appending side effects to init.
 // result is assignable if n is.
-func safeexpr(n *Node, init *Nodes) *Node {
+func safeexpr(n *ir.Node, init *ir.Nodes) *ir.Node {
        if n == nil {
                return nil
        }
@@ -929,43 +751,43 @@ func safeexpr(n *Node, init *Nodes) *Node {
        }
 
        switch n.Op {
-       case ONAME, OLITERAL, ONIL:
+       case ir.ONAME, ir.OLITERAL, ir.ONIL:
                return n
 
-       case ODOT, OLEN, OCAP:
+       case ir.ODOT, ir.OLEN, ir.OCAP:
                l := safeexpr(n.Left, init)
                if l == n.Left {
                        return n
                }
-               r := n.copy()
+               r := ir.Copy(n)
                r.Left = l
                r = typecheck(r, ctxExpr)
                r = walkexpr(r, init)
                return r
 
-       case ODOTPTR, ODEREF:
+       case ir.ODOTPTR, ir.ODEREF:
                l := safeexpr(n.Left, init)
                if l == n.Left {
                        return n
                }
-               a := n.copy()
+               a := ir.Copy(n)
                a.Left = l
                a = walkexpr(a, init)
                return a
 
-       case OINDEX, OINDEXMAP:
+       case ir.OINDEX, ir.OINDEXMAP:
                l := safeexpr(n.Left, init)
                r := safeexpr(n.Right, init)
                if l == n.Left && r == n.Right {
                        return n
                }
-               a := n.copy()
+               a := ir.Copy(n)
                a.Left = l
                a.Right = r
                a = walkexpr(a, init)
                return a
 
-       case OSTRUCTLIT, OARRAYLIT, OSLICELIT:
+       case ir.OSTRUCTLIT, ir.OARRAYLIT, ir.OSLICELIT:
                if isStaticCompositeLiteral(n) {
                        return n
                }
@@ -978,9 +800,9 @@ func safeexpr(n *Node, init *Nodes) *Node {
        return cheapexpr(n, init)
 }
 
-func copyexpr(n *Node, t *types.Type, init *Nodes) *Node {
+func copyexpr(n *ir.Node, t *types.Type, init *ir.Nodes) *ir.Node {
        l := temp(t)
-       a := nod(OAS, l, n)
+       a := ir.Nod(ir.OAS, l, n)
        a = typecheck(a, ctxStmt)
        a = walkexpr(a, init)
        init.Append(a)
@@ -989,9 +811,9 @@ func copyexpr(n *Node, t *types.Type, init *Nodes) *Node {
 
 // return side-effect free and cheap n, appending side effects to init.
 // result may not be assignable.
-func cheapexpr(n *Node, init *Nodes) *Node {
+func cheapexpr(n *ir.Node, init *ir.Nodes) *ir.Node {
        switch n.Op {
-       case ONAME, OLITERAL, ONIL:
+       case ir.ONAME, ir.OLITERAL, ir.ONIL:
                return n
        }
 
@@ -1135,7 +957,7 @@ func dotpath(s *types.Sym, t *types.Type, save **types.Field, ignorecase bool) (
 // find missing fields that
 // will give shortest unique addressing.
 // modify the tree with missing type names.
-func adddot(n *Node) *Node {
+func adddot(n *ir.Node) *ir.Node {
        n.Left = typecheck(n.Left, ctxType|ctxExpr)
        if n.Left.Diag() {
                n.SetDiag(true)
@@ -1145,7 +967,7 @@ func adddot(n *Node) *Node {
                return n
        }
 
-       if n.Left.Op == OTYPE {
+       if n.Left.Op == ir.OTYPE {
                return n
        }
 
@@ -1158,7 +980,7 @@ func adddot(n *Node) *Node {
        case path != nil:
                // rebuild elided dots
                for c := len(path) - 1; c >= 0; c-- {
-                       n.Left = nodSym(ODOT, n.Left, path[c].field.Sym)
+                       n.Left = nodSym(ir.ODOT, n.Left, path[c].field.Sym)
                        n.Left.SetImplicit(true)
                }
        case ambig:
@@ -1294,8 +1116,8 @@ func expandmeth(t *types.Type) {
 }
 
 // Given funarg struct list, return list of ODCLFIELD Node fn args.
-func structargs(tl *types.Type, mustname bool) []*Node {
-       var args []*Node
+func structargs(tl *types.Type, mustname bool) []*ir.Node {
+       var args []*ir.Node
        gen := 0
        for _, t := range tl.Fields().Slice() {
                s := t.Sym
@@ -1341,20 +1163,20 @@ func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym) {
 
        // Only generate (*T).M wrappers for T.M in T's own package.
        if rcvr.IsPtr() && rcvr.Elem() == method.Type.Recv().Type &&
-               rcvr.Elem().Sym != nil && rcvr.Elem().Sym.Pkg != localpkg {
+               rcvr.Elem().Sym != nil && rcvr.Elem().Sym.Pkg != ir.LocalPkg {
                return
        }
 
        // Only generate I.M wrappers for I in I's own package
        // but keep doing it for error.Error (was issue #29304).
-       if rcvr.IsInterface() && rcvr.Sym != nil && rcvr.Sym.Pkg != localpkg && rcvr != types.Errortype {
+       if rcvr.IsInterface() && rcvr.Sym != nil && rcvr.Sym.Pkg != ir.LocalPkg && rcvr != types.Errortype {
                return
        }
 
        base.Pos = autogeneratedPos
-       dclcontext = PEXTERN
+       dclcontext = ir.PEXTERN
 
-       tfn := nod(OTFUNC, nil, nil)
+       tfn := ir.Nod(ir.OTFUNC, nil, nil)
        tfn.Left = namedfield(".this", rcvr)
        tfn.List.Set(structargs(method.Type.Params(), true))
        tfn.Rlist.Set(structargs(method.Type.Results(), false))
@@ -1362,21 +1184,21 @@ func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym) {
        fn := dclfunc(newnam, tfn)
        fn.Func.SetDupok(true)
 
-       nthis := asNode(tfn.Type.Recv().Nname)
+       nthis := ir.AsNode(tfn.Type.Recv().Nname)
 
        methodrcvr := method.Type.Recv().Type
 
        // generate nil pointer check for better error
        if rcvr.IsPtr() && rcvr.Elem() == methodrcvr {
                // generating wrapper from *T to T.
-               n := nod(OIF, nil, nil)
-               n.Left = nod(OEQ, nthis, nodnil())
-               call := nod(OCALL, syslook("panicwrap"), nil)
+               n := ir.Nod(ir.OIF, nil, nil)
+               n.Left = ir.Nod(ir.OEQ, nthis, nodnil())
+               call := ir.Nod(ir.OCALL, syslook("panicwrap"), nil)
                n.Nbody.Set1(call)
                fn.Nbody.Append(n)
        }
 
-       dot := adddot(nodSym(OXDOT, nthis, method.Sym))
+       dot := adddot(nodSym(ir.OXDOT, nthis, method.Sym))
 
        // generate call
        // It's not possible to use a tail call when dynamic linking on ppc64le. The
@@ -1390,18 +1212,18 @@ func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym) {
                dot = dot.Left // skip final .M
                // TODO(mdempsky): Remove dependency on dotlist.
                if !dotlist[0].field.Type.IsPtr() {
-                       dot = nod(OADDR, dot, nil)
+                       dot = ir.Nod(ir.OADDR, dot, nil)
                }
-               as := nod(OAS, nthis, convnop(dot, rcvr))
+               as := ir.Nod(ir.OAS, nthis, convnop(dot, rcvr))
                fn.Nbody.Append(as)
-               fn.Nbody.Append(nodSym(ORETJMP, nil, methodSym(methodrcvr, method.Sym)))
+               fn.Nbody.Append(nodSym(ir.ORETJMP, nil, methodSym(methodrcvr, method.Sym)))
        } else {
                fn.Func.SetWrapper(true) // ignore frame for panic+recover matching
-               call := nod(OCALL, dot, nil)
+               call := ir.Nod(ir.OCALL, dot, nil)
                call.List.Set(paramNnames(tfn.Type))
                call.SetIsDDD(tfn.Type.IsVariadic())
                if method.Type.NumResults() > 0 {
-                       n := nod(ORETURN, nil, nil)
+                       n := ir.Nod(ir.ORETURN, nil, nil)
                        n.List.Set1(call)
                        call = n
                }
@@ -1409,7 +1231,7 @@ func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym) {
        }
 
        if false && base.Flag.LowerR != 0 {
-               dumplist("genwrapper body", fn.Nbody)
+               ir.DumpList("genwrapper body", fn.Nbody)
        }
 
        funcbody()
@@ -1428,31 +1250,31 @@ func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym) {
        if rcvr.IsPtr() && rcvr.Elem() == method.Type.Recv().Type && rcvr.Elem().Sym != nil {
                inlcalls(fn)
        }
-       escapeFuncs([]*Node{fn}, false)
+       escapeFuncs([]*ir.Node{fn}, false)
 
        Curfn = nil
        xtop = append(xtop, fn)
 }
 
-func paramNnames(ft *types.Type) []*Node {
-       args := make([]*Node, ft.NumParams())
+func paramNnames(ft *types.Type) []*ir.Node {
+       args := make([]*ir.Node, ft.NumParams())
        for i, f := range ft.Params().FieldSlice() {
-               args[i] = asNode(f.Nname)
+               args[i] = ir.AsNode(f.Nname)
        }
        return args
 }
 
-func hashmem(t *types.Type) *Node {
+func hashmem(t *types.Type) *ir.Node {
        sym := Runtimepkg.Lookup("memhash")
 
-       n := newname(sym)
+       n := NewName(sym)
        setNodeNameFunc(n)
-       n.Type = functype(nil, []*Node{
+       n.Type = functype(nil, []*ir.Node{
                anonfield(types.NewPtr(t)),
-               anonfield(types.Types[TUINTPTR]),
-               anonfield(types.Types[TUINTPTR]),
-       }, []*Node{
-               anonfield(types.Types[TUINTPTR]),
+               anonfield(types.Types[types.TUINTPTR]),
+               anonfield(types.Types[types.TUINTPTR]),
+       }, []*ir.Node{
+               anonfield(types.Types[types.TUINTPTR]),
        })
        return n
 }
@@ -1571,16 +1393,16 @@ func implements(t, iface *types.Type, m, samename **types.Field, ptr *int) bool
        return true
 }
 
-func listtreecopy(l []*Node, pos src.XPos) []*Node {
-       var out []*Node
+func listtreecopy(l []*ir.Node, pos src.XPos) []*ir.Node {
+       var out []*ir.Node
        for _, n := range l {
                out = append(out, treecopy(n, pos))
        }
        return out
 }
 
-func liststmt(l []*Node) *Node {
-       n := nod(OBLOCK, nil, nil)
+func liststmt(l []*ir.Node) *ir.Node {
+       n := ir.Nod(ir.OBLOCK, nil, nil)
        n.List.Set(l)
        if len(l) != 0 {
                n.Pos = l[0].Pos
@@ -1588,7 +1410,7 @@ func liststmt(l []*Node) *Node {
        return n
 }
 
-func ngotype(n *Node) *types.Sym {
+func ngotype(n *ir.Node) *types.Sym {
        if n.Type != nil {
                return typenamesym(n.Type)
        }
@@ -1597,13 +1419,13 @@ func ngotype(n *Node) *types.Sym {
 
 // The result of addinit MUST be assigned back to n, e.g.
 //     n.Left = addinit(n.Left, init)
-func addinit(n *Node, init []*Node) *Node {
+func addinit(n *ir.Node, init []*ir.Node) *ir.Node {
        if len(init) == 0 {
                return n
        }
-       if n.mayBeShared() {
+       if ir.MayBeShared(n) {
                // Introduce OCONVNOP to hold init list.
-               n = nod(OCONVNOP, n, nil)
+               n = ir.Nod(ir.OCONVNOP, n, nil)
                n.Type = n.Left.Type
                n.SetTypecheck(1)
        }
@@ -1674,20 +1496,20 @@ func isdirectiface(t *types.Type) bool {
        }
 
        switch t.Etype {
-       case TPTR:
+       case types.TPTR:
                // Pointers to notinheap types must be stored indirectly. See issue 42076.
                return !t.Elem().NotInHeap()
-       case TCHAN,
-               TMAP,
-               TFUNC,
-               TUNSAFEPTR:
+       case types.TCHAN,
+               types.TMAP,
+               types.TFUNC,
+               types.TUNSAFEPTR:
                return true
 
-       case TARRAY:
+       case types.TARRAY:
                // Array of 1 direct iface type can be direct.
                return t.NumElem() == 1 && isdirectiface(t.Elem())
 
-       case TSTRUCT:
+       case types.TSTRUCT:
                // Struct with 1 field of direct iface type can be direct.
                return t.NumFields() == 1 && isdirectiface(t.Field(0).Type)
        }
@@ -1696,9 +1518,9 @@ func isdirectiface(t *types.Type) bool {
 }
 
 // itabType loads the _type field from a runtime.itab struct.
-func itabType(itab *Node) *Node {
-       typ := nodSym(ODOTPTR, itab, nil)
-       typ.Type = types.NewPtr(types.Types[TUINT8])
+func itabType(itab *ir.Node) *ir.Node {
+       typ := nodSym(ir.ODOTPTR, itab, nil)
+       typ.Type = types.NewPtr(types.Types[types.TUINT8])
        typ.SetTypecheck(1)
        typ.Xoffset = int64(Widthptr) // offset of _type in runtime.itab
        typ.SetBounded(true)          // guaranteed not to fault
@@ -1708,11 +1530,11 @@ func itabType(itab *Node) *Node {
 // ifaceData loads the data field from an interface.
 // The concrete type must be known to have type t.
 // It follows the pointer if !isdirectiface(t).
-func ifaceData(pos src.XPos, n *Node, t *types.Type) *Node {
+func ifaceData(pos src.XPos, n *ir.Node, t *types.Type) *ir.Node {
        if t.IsInterface() {
                base.Fatalf("ifaceData interface: %v", t)
        }
-       ptr := nodlSym(pos, OIDATA, n, nil)
+       ptr := nodlSym(pos, ir.OIDATA, n, nil)
        if isdirectiface(t) {
                ptr.Type = t
                ptr.SetTypecheck(1)
@@ -1720,7 +1542,7 @@ func ifaceData(pos src.XPos, n *Node, t *types.Type) *Node {
        }
        ptr.Type = types.NewPtr(t)
        ptr.SetTypecheck(1)
-       ind := nodl(pos, ODEREF, ptr, nil)
+       ind := ir.NodAt(pos, ir.ODEREF, ptr, nil)
        ind.Type = t
        ind.SetTypecheck(1)
        ind.SetBounded(true)
@@ -1730,7 +1552,7 @@ func ifaceData(pos src.XPos, n *Node, t *types.Type) *Node {
 // typePos returns the position associated with t.
 // This is where t was declared or where it appeared as a type expression.
 func typePos(t *types.Type) src.XPos {
-       n := asNode(t.Nod)
+       n := ir.AsNode(t.Nod)
        if n == nil || !n.Pos.IsKnown() {
                base.Fatalf("bad type: %v", t)
        }
index 7befbdf06c15de85b81387fe226aa3d4dbf89866..f3195df79aa13113805d6b6e9da2d20009ee4754 100644 (file)
@@ -6,6 +6,7 @@ package gc
 
 import (
        "cmd/compile/internal/base"
+       "cmd/compile/internal/ir"
        "cmd/compile/internal/types"
        "cmd/internal/src"
        "go/constant"
@@ -14,16 +15,16 @@ import (
 )
 
 // typecheckswitch typechecks a switch statement.
-func typecheckswitch(n *Node) {
+func typecheckswitch(n *ir.Node) {
        typecheckslice(n.Ninit.Slice(), ctxStmt)
-       if n.Left != nil && n.Left.Op == OTYPESW {
+       if n.Left != nil && n.Left.Op == ir.OTYPESW {
                typecheckTypeSwitch(n)
        } else {
                typecheckExprSwitch(n)
        }
 }
 
-func typecheckTypeSwitch(n *Node) {
+func typecheckTypeSwitch(n *ir.Node) {
        n.Left.Right = typecheck(n.Left.Right, ctxExpr)
        t := n.Left.Right.Type
        if t != nil && !t.IsInterface() {
@@ -34,17 +35,17 @@ func typecheckTypeSwitch(n *Node) {
        // We don't actually declare the type switch's guarded
        // declaration itself. So if there are no cases, we won't
        // notice that it went unused.
-       if v := n.Left.Left; v != nil && !v.isBlank() && n.List.Len() == 0 {
+       if v := n.Left.Left; v != nil && !ir.IsBlank(v) && n.List.Len() == 0 {
                base.ErrorfAt(v.Pos, "%v declared but not used", v.Sym)
        }
 
-       var defCase, nilCase *Node
+       var defCase, nilCase *ir.Node
        var ts typeSet
        for _, ncase := range n.List.Slice() {
                ls := ncase.List.Slice()
                if len(ls) == 0 { // default:
                        if defCase != nil {
-                               base.ErrorfAt(ncase.Pos, "multiple defaults in switch (first at %v)", defCase.Line())
+                               base.ErrorfAt(ncase.Pos, "multiple defaults in switch (first at %v)", ir.Line(defCase))
                        } else {
                                defCase = ncase
                        }
@@ -60,13 +61,13 @@ func typecheckTypeSwitch(n *Node) {
                        var missing, have *types.Field
                        var ptr int
                        switch {
-                       case n1.isNil(): // case nil:
+                       case ir.IsNil(n1): // case nil:
                                if nilCase != nil {
-                                       base.ErrorfAt(ncase.Pos, "multiple nil cases in type switch (first at %v)", nilCase.Line())
+                                       base.ErrorfAt(ncase.Pos, "multiple nil cases in type switch (first at %v)", ir.Line(nilCase))
                                } else {
                                        nilCase = ncase
                                }
-                       case n1.Op != OTYPE:
+                       case n1.Op != ir.OTYPE:
                                base.ErrorfAt(ncase.Pos, "%L is not a type", n1)
                        case !n1.Type.IsInterface() && !implements(n1.Type, t, &missing, &have, &ptr) && !missing.Broke():
                                if have != nil && !have.Broke() {
@@ -81,7 +82,7 @@ func typecheckTypeSwitch(n *Node) {
                                }
                        }
 
-                       if n1.Op == OTYPE {
+                       if n1.Op == ir.OTYPE {
                                ts.add(ncase.Pos, n1.Type)
                        }
                }
@@ -90,9 +91,9 @@ func typecheckTypeSwitch(n *Node) {
                        // Assign the clause variable's type.
                        vt := t
                        if len(ls) == 1 {
-                               if ls[0].Op == OTYPE {
+                               if ls[0].Op == ir.OTYPE {
                                        vt = ls[0].Type
-                               } else if !ls[0].isNil() {
+                               } else if !ir.IsNil(ls[0]) {
                                        // Invalid single-type case;
                                        // mark variable as broken.
                                        vt = nil
@@ -143,8 +144,8 @@ func (s *typeSet) add(pos src.XPos, typ *types.Type) {
        s.m[ls] = append(prevs, typeSetEntry{pos, typ})
 }
 
-func typecheckExprSwitch(n *Node) {
-       t := types.Types[TBOOL]
+func typecheckExprSwitch(n *ir.Node) {
+       t := types.Types[types.TBOOL]
        if n.Left != nil {
                n.Left = typecheck(n.Left, ctxExpr)
                n.Left = defaultlit(n.Left, nil)
@@ -156,7 +157,7 @@ func typecheckExprSwitch(n *Node) {
                switch {
                case t.IsMap():
                        nilonly = "map"
-               case t.Etype == TFUNC:
+               case t.Etype == types.TFUNC:
                        nilonly = "func"
                case t.IsSlice():
                        nilonly = "slice"
@@ -171,13 +172,13 @@ func typecheckExprSwitch(n *Node) {
                }
        }
 
-       var defCase *Node
+       var defCase *ir.Node
        var cs constSet
        for _, ncase := range n.List.Slice() {
                ls := ncase.List.Slice()
                if len(ls) == 0 { // default:
                        if defCase != nil {
-                               base.ErrorfAt(ncase.Pos, "multiple defaults in switch (first at %v)", defCase.Line())
+                               base.ErrorfAt(ncase.Pos, "multiple defaults in switch (first at %v)", ir.Line(defCase))
                        } else {
                                defCase = ncase
                        }
@@ -192,14 +193,14 @@ func typecheckExprSwitch(n *Node) {
                                continue
                        }
 
-                       if nilonly != "" && !n1.isNil() {
+                       if nilonly != "" && !ir.IsNil(n1) {
                                base.ErrorfAt(ncase.Pos, "invalid case %v in switch (can only compare %s %v to nil)", n1, nilonly, n.Left)
                        } else if t.IsInterface() && !n1.Type.IsInterface() && !IsComparable(n1.Type) {
                                base.ErrorfAt(ncase.Pos, "invalid case %L in switch (incomparable type)", n1)
                        } else {
                                op1, _ := assignop(n1.Type, t)
                                op2, _ := assignop(t, n1.Type)
-                               if op1 == OXXX && op2 == OXXX {
+                               if op1 == ir.OXXX && op2 == ir.OXXX {
                                        if n.Left != nil {
                                                base.ErrorfAt(ncase.Pos, "invalid case %v in switch on %v (mismatched types %v and %v)", n1, n.Left, n1.Type, t)
                                        } else {
@@ -224,13 +225,13 @@ func typecheckExprSwitch(n *Node) {
 }
 
 // walkswitch walks a switch statement.
-func walkswitch(sw *Node) {
+func walkswitch(sw *ir.Node) {
        // Guard against double walk, see #25776.
        if sw.List.Len() == 0 && sw.Nbody.Len() > 0 {
                return // Was fatal, but eliminating every possible source of double-walking is hard
        }
 
-       if sw.Left != nil && sw.Left.Op == OTYPESW {
+       if sw.Left != nil && sw.Left.Op == ir.OTYPESW {
                walkTypeSwitch(sw)
        } else {
                walkExprSwitch(sw)
@@ -239,7 +240,7 @@ func walkswitch(sw *Node) {
 
 // walkExprSwitch generates an AST implementing sw.  sw is an
 // expression switch.
-func walkExprSwitch(sw *Node) {
+func walkExprSwitch(sw *ir.Node) {
        lno := setlineno(sw)
 
        cond := sw.Left
@@ -259,12 +260,12 @@ func walkExprSwitch(sw *Node) {
        // because walkexpr will lower the string
        // conversion into a runtime call.
        // See issue 24937 for more discussion.
-       if cond.Op == OBYTES2STR && allCaseExprsAreSideEffectFree(sw) {
-               cond.Op = OBYTES2STRTMP
+       if cond.Op == ir.OBYTES2STR && allCaseExprsAreSideEffectFree(sw) {
+               cond.Op = ir.OBYTES2STRTMP
        }
 
        cond = walkexpr(cond, &sw.Ninit)
-       if cond.Op != OLITERAL && cond.Op != ONIL {
+       if cond.Op != ir.OLITERAL && cond.Op != ir.ONIL {
                cond = copyexpr(cond, cond.Type, &sw.Nbody)
        }
 
@@ -274,11 +275,11 @@ func walkExprSwitch(sw *Node) {
                exprname: cond,
        }
 
-       var defaultGoto *Node
-       var body Nodes
+       var defaultGoto *ir.Node
+       var body ir.Nodes
        for _, ncase := range sw.List.Slice() {
                label := autolabel(".s")
-               jmp := npos(ncase.Pos, nodSym(OGOTO, nil, label))
+               jmp := npos(ncase.Pos, nodSym(ir.OGOTO, nil, label))
 
                // Process case dispatch.
                if ncase.List.Len() == 0 {
@@ -293,10 +294,10 @@ func walkExprSwitch(sw *Node) {
                }
 
                // Process body.
-               body.Append(npos(ncase.Pos, nodSym(OLABEL, nil, label)))
+               body.Append(npos(ncase.Pos, nodSym(ir.OLABEL, nil, label)))
                body.Append(ncase.Nbody.Slice()...)
                if fall, pos := hasFall(ncase.Nbody.Slice()); !fall {
-                       br := nod(OBREAK, nil, nil)
+                       br := ir.Nod(ir.OBREAK, nil, nil)
                        br.Pos = pos
                        body.Append(br)
                }
@@ -304,7 +305,7 @@ func walkExprSwitch(sw *Node) {
        sw.List.Set(nil)
 
        if defaultGoto == nil {
-               br := nod(OBREAK, nil, nil)
+               br := ir.Nod(ir.OBREAK, nil, nil)
                br.Pos = br.Pos.WithNotStmt()
                defaultGoto = br
        }
@@ -317,21 +318,21 @@ func walkExprSwitch(sw *Node) {
 
 // An exprSwitch walks an expression switch.
 type exprSwitch struct {
-       exprname *Node // value being switched on
+       exprname *ir.Node // value being switched on
 
-       done    Nodes
+       done    ir.Nodes
        clauses []exprClause
 }
 
 type exprClause struct {
        pos    src.XPos
-       lo, hi *Node
-       jmp    *Node
+       lo, hi *ir.Node
+       jmp    *ir.Node
 }
 
-func (s *exprSwitch) Add(pos src.XPos, expr, jmp *Node) {
+func (s *exprSwitch) Add(pos src.XPos, expr, jmp *ir.Node) {
        c := exprClause{pos: pos, lo: expr, hi: expr, jmp: jmp}
-       if okforcmp[s.exprname.Type.Etype] && expr.Op == OLITERAL {
+       if okforcmp[s.exprname.Type.Etype] && expr.Op == ir.OLITERAL {
                s.clauses = append(s.clauses, c)
                return
        }
@@ -341,7 +342,7 @@ func (s *exprSwitch) Add(pos src.XPos, expr, jmp *Node) {
        s.flush()
 }
 
-func (s *exprSwitch) Emit(out *Nodes) {
+func (s *exprSwitch) Emit(out *ir.Nodes) {
        s.flush()
        out.AppendNodes(&s.done)
 }
@@ -389,12 +390,12 @@ func (s *exprSwitch) flush() {
 
                // Perform two-level binary search.
                binarySearch(len(runs), &s.done,
-                       func(i int) *Node {
-                               return nod(OLE, nod(OLEN, s.exprname, nil), nodintconst(runLen(runs[i-1])))
+                       func(i int) *ir.Node {
+                               return ir.Nod(ir.OLE, ir.Nod(ir.OLEN, s.exprname, nil), nodintconst(runLen(runs[i-1])))
                        },
-                       func(i int, nif *Node) {
+                       func(i int, nif *ir.Node) {
                                run := runs[i]
-                               nif.Left = nod(OEQ, nod(OLEN, s.exprname, nil), nodintconst(runLen(run)))
+                               nif.Left = ir.Nod(ir.OEQ, ir.Nod(ir.OLEN, s.exprname, nil), nodintconst(runLen(run)))
                                s.search(run, &nif.Nbody)
                        },
                )
@@ -422,12 +423,12 @@ func (s *exprSwitch) flush() {
        s.search(cc, &s.done)
 }
 
-func (s *exprSwitch) search(cc []exprClause, out *Nodes) {
+func (s *exprSwitch) search(cc []exprClause, out *ir.Nodes) {
        binarySearch(len(cc), out,
-               func(i int) *Node {
-                       return nod(OLE, s.exprname, cc[i-1].hi)
+               func(i int) *ir.Node {
+                       return ir.Nod(ir.OLE, s.exprname, cc[i-1].hi)
                },
-               func(i int, nif *Node) {
+               func(i int, nif *ir.Node) {
                        c := &cc[i]
                        nif.Left = c.test(s.exprname)
                        nif.Nbody.Set1(c.jmp)
@@ -435,27 +436,27 @@ func (s *exprSwitch) search(cc []exprClause, out *Nodes) {
        )
 }
 
-func (c *exprClause) test(exprname *Node) *Node {
+func (c *exprClause) test(exprname *ir.Node) *ir.Node {
        // Integer range.
        if c.hi != c.lo {
-               low := nodl(c.pos, OGE, exprname, c.lo)
-               high := nodl(c.pos, OLE, exprname, c.hi)
-               return nodl(c.pos, OANDAND, low, high)
+               low := ir.NodAt(c.pos, ir.OGE, exprname, c.lo)
+               high := ir.NodAt(c.pos, ir.OLE, exprname, c.hi)
+               return ir.NodAt(c.pos, ir.OANDAND, low, high)
        }
 
        // Optimize "switch true { ...}" and "switch false { ... }".
-       if Isconst(exprname, constant.Bool) && !c.lo.Type.IsInterface() {
+       if ir.IsConst(exprname, constant.Bool) && !c.lo.Type.IsInterface() {
                if exprname.BoolVal() {
                        return c.lo
                } else {
-                       return nodl(c.pos, ONOT, c.lo, nil)
+                       return ir.NodAt(c.pos, ir.ONOT, c.lo, nil)
                }
        }
 
-       return nodl(c.pos, OEQ, exprname, c.lo)
+       return ir.NodAt(c.pos, ir.OEQ, exprname, c.lo)
 }
 
-func allCaseExprsAreSideEffectFree(sw *Node) bool {
+func allCaseExprsAreSideEffectFree(sw *ir.Node) bool {
        // In theory, we could be more aggressive, allowing any
        // side-effect-free expressions in cases, but it's a bit
        // tricky because some of that information is unavailable due
@@ -464,11 +465,11 @@ func allCaseExprsAreSideEffectFree(sw *Node) bool {
        // enough.
 
        for _, ncase := range sw.List.Slice() {
-               if ncase.Op != OCASE {
+               if ncase.Op != ir.OCASE {
                        base.Fatalf("switch string(byteslice) bad op: %v", ncase.Op)
                }
                for _, v := range ncase.List.Slice() {
-                       if v.Op != OLITERAL {
+                       if v.Op != ir.OLITERAL {
                                return false
                        }
                }
@@ -477,7 +478,7 @@ func allCaseExprsAreSideEffectFree(sw *Node) bool {
 }
 
 // hasFall reports whether stmts ends with a "fallthrough" statement.
-func hasFall(stmts []*Node) (bool, src.XPos) {
+func hasFall(stmts []*ir.Node) (bool, src.XPos) {
        // Search backwards for the index of the fallthrough
        // statement. Do not assume it'll be in the last
        // position, since in some cases (e.g. when the statement
@@ -485,30 +486,30 @@ func hasFall(stmts []*Node) (bool, src.XPos) {
        // nodes will be at the end of the list.
 
        i := len(stmts) - 1
-       for i >= 0 && stmts[i].Op == OVARKILL {
+       for i >= 0 && stmts[i].Op == ir.OVARKILL {
                i--
        }
        if i < 0 {
                return false, src.NoXPos
        }
-       return stmts[i].Op == OFALL, stmts[i].Pos
+       return stmts[i].Op == ir.OFALL, stmts[i].Pos
 }
 
 // walkTypeSwitch generates an AST that implements sw, where sw is a
 // type switch.
-func walkTypeSwitch(sw *Node) {
+func walkTypeSwitch(sw *ir.Node) {
        var s typeSwitch
        s.facename = sw.Left.Right
        sw.Left = nil
 
        s.facename = walkexpr(s.facename, &sw.Ninit)
        s.facename = copyexpr(s.facename, s.facename.Type, &sw.Nbody)
-       s.okname = temp(types.Types[TBOOL])
+       s.okname = temp(types.Types[types.TBOOL])
 
        // Get interface descriptor word.
        // For empty interfaces this will be the type.
        // For non-empty interfaces this will be the itab.
-       itab := nod(OITAB, s.facename, nil)
+       itab := ir.Nod(ir.OITAB, s.facename, nil)
 
        // For empty interfaces, do:
        //     if e._type == nil {
@@ -516,8 +517,8 @@ func walkTypeSwitch(sw *Node) {
        //     }
        //     h := e._type.hash
        // Use a similar strategy for non-empty interfaces.
-       ifNil := nod(OIF, nil, nil)
-       ifNil.Left = nod(OEQ, itab, nodnil())
+       ifNil := ir.Nod(ir.OIF, nil, nil)
+       ifNil.Left = ir.Nod(ir.OEQ, itab, nodnil())
        base.Pos = base.Pos.WithNotStmt() // disable statement marks after the first check.
        ifNil.Left = typecheck(ifNil.Left, ctxExpr)
        ifNil.Left = defaultlit(ifNil.Left, nil)
@@ -525,8 +526,8 @@ func walkTypeSwitch(sw *Node) {
        sw.Nbody.Append(ifNil)
 
        // Load hash from type or itab.
-       dotHash := nodSym(ODOTPTR, itab, nil)
-       dotHash.Type = types.Types[TUINT32]
+       dotHash := nodSym(ir.ODOTPTR, itab, nil)
+       dotHash.Type = types.Types[types.TUINT32]
        dotHash.SetTypecheck(1)
        if s.facename.Type.IsEmptyInterface() {
                dotHash.Xoffset = int64(2 * Widthptr) // offset of hash in runtime._type
@@ -536,11 +537,11 @@ func walkTypeSwitch(sw *Node) {
        dotHash.SetBounded(true) // guaranteed not to fault
        s.hashname = copyexpr(dotHash, dotHash.Type, &sw.Nbody)
 
-       br := nod(OBREAK, nil, nil)
-       var defaultGoto, nilGoto *Node
-       var body Nodes
+       br := ir.Nod(ir.OBREAK, nil, nil)
+       var defaultGoto, nilGoto *ir.Node
+       var body ir.Nodes
        for _, ncase := range sw.List.Slice() {
-               var caseVar *Node
+               var caseVar *ir.Node
                if ncase.Rlist.Len() != 0 {
                        caseVar = ncase.Rlist.First()
                }
@@ -549,13 +550,13 @@ func walkTypeSwitch(sw *Node) {
                // we initialize the case variable as part of the type assertion.
                // In other cases, we initialize it in the body.
                var singleType *types.Type
-               if ncase.List.Len() == 1 && ncase.List.First().Op == OTYPE {
+               if ncase.List.Len() == 1 && ncase.List.First().Op == ir.OTYPE {
                        singleType = ncase.List.First().Type
                }
                caseVarInitialized := false
 
                label := autolabel(".s")
-               jmp := npos(ncase.Pos, nodSym(OGOTO, nil, label))
+               jmp := npos(ncase.Pos, nodSym(ir.OGOTO, nil, label))
 
                if ncase.List.Len() == 0 { // default:
                        if defaultGoto != nil {
@@ -565,7 +566,7 @@ func walkTypeSwitch(sw *Node) {
                }
 
                for _, n1 := range ncase.List.Slice() {
-                       if n1.isNil() { // case nil:
+                       if ir.IsNil(n1) { // case nil:
                                if nilGoto != nil {
                                        base.Fatalf("duplicate nil case not detected during typechecking")
                                }
@@ -581,7 +582,7 @@ func walkTypeSwitch(sw *Node) {
                        }
                }
 
-               body.Append(npos(ncase.Pos, nodSym(OLABEL, nil, label)))
+               body.Append(npos(ncase.Pos, nodSym(ir.OLABEL, nil, label)))
                if caseVar != nil && !caseVarInitialized {
                        val := s.facename
                        if singleType != nil {
@@ -591,9 +592,9 @@ func walkTypeSwitch(sw *Node) {
                                }
                                val = ifaceData(ncase.Pos, s.facename, singleType)
                        }
-                       l := []*Node{
-                               nodl(ncase.Pos, ODCL, caseVar, nil),
-                               nodl(ncase.Pos, OAS, caseVar, val),
+                       l := []*ir.Node{
+                               ir.NodAt(ncase.Pos, ir.ODCL, caseVar, nil),
+                               ir.NodAt(ncase.Pos, ir.OAS, caseVar, val),
                        }
                        typecheckslice(l, ctxStmt)
                        body.Append(l...)
@@ -621,36 +622,36 @@ func walkTypeSwitch(sw *Node) {
 // A typeSwitch walks a type switch.
 type typeSwitch struct {
        // Temporary variables (i.e., ONAMEs) used by type switch dispatch logic:
-       facename *Node // value being type-switched on
-       hashname *Node // type hash of the value being type-switched on
-       okname   *Node // boolean used for comma-ok type assertions
+       facename *ir.Node // value being type-switched on
+       hashname *ir.Node // type hash of the value being type-switched on
+       okname   *ir.Node // boolean used for comma-ok type assertions
 
-       done    Nodes
+       done    ir.Nodes
        clauses []typeClause
 }
 
 type typeClause struct {
        hash uint32
-       body Nodes
+       body ir.Nodes
 }
 
-func (s *typeSwitch) Add(pos src.XPos, typ *types.Type, caseVar, jmp *Node) {
-       var body Nodes
+func (s *typeSwitch) Add(pos src.XPos, typ *types.Type, caseVar, jmp *ir.Node) {
+       var body ir.Nodes
        if caseVar != nil {
-               l := []*Node{
-                       nodl(pos, ODCL, caseVar, nil),
-                       nodl(pos, OAS, caseVar, nil),
+               l := []*ir.Node{
+                       ir.NodAt(pos, ir.ODCL, caseVar, nil),
+                       ir.NodAt(pos, ir.OAS, caseVar, nil),
                }
                typecheckslice(l, ctxStmt)
                body.Append(l...)
        } else {
-               caseVar = nblank
+               caseVar = ir.BlankNode
        }
 
        // cv, ok = iface.(type)
-       as := nodl(pos, OAS2, nil, nil)
+       as := ir.NodAt(pos, ir.OAS2, nil, nil)
        as.List.Set2(caseVar, s.okname) // cv, ok =
-       dot := nodl(pos, ODOTTYPE, s.facename, nil)
+       dot := ir.NodAt(pos, ir.ODOTTYPE, s.facename, nil)
        dot.Type = typ // iface.(type)
        as.Rlist.Set1(dot)
        as = typecheck(as, ctxStmt)
@@ -658,7 +659,7 @@ func (s *typeSwitch) Add(pos src.XPos, typ *types.Type, caseVar, jmp *Node) {
        body.Append(as)
 
        // if ok { goto label }
-       nif := nodl(pos, OIF, nil, nil)
+       nif := ir.NodAt(pos, ir.OIF, nil, nil)
        nif.Left = s.okname
        nif.Nbody.Set1(jmp)
        body.Append(nif)
@@ -675,7 +676,7 @@ func (s *typeSwitch) Add(pos src.XPos, typ *types.Type, caseVar, jmp *Node) {
        s.done.AppendNodes(&body)
 }
 
-func (s *typeSwitch) Emit(out *Nodes) {
+func (s *typeSwitch) Emit(out *ir.Nodes) {
        s.flush()
        out.AppendNodes(&s.done)
 }
@@ -702,14 +703,14 @@ func (s *typeSwitch) flush() {
        cc = merged
 
        binarySearch(len(cc), &s.done,
-               func(i int) *Node {
-                       return nod(OLE, s.hashname, nodintconst(int64(cc[i-1].hash)))
+               func(i int) *ir.Node {
+                       return ir.Nod(ir.OLE, s.hashname, nodintconst(int64(cc[i-1].hash)))
                },
-               func(i int, nif *Node) {
+               func(i int, nif *ir.Node) {
                        // TODO(mdempsky): Omit hash equality check if
                        // there's only one type.
                        c := cc[i]
-                       nif.Left = nod(OEQ, s.hashname, nodintconst(int64(c.hash)))
+                       nif.Left = ir.Nod(ir.OEQ, s.hashname, nodintconst(int64(c.hash)))
                        nif.Nbody.AppendNodes(&c.body)
                },
        )
@@ -724,15 +725,15 @@ func (s *typeSwitch) flush() {
 //
 // leaf(i, nif) should setup nif (an OIF node) to test case i. In
 // particular, it should set nif.Left and nif.Nbody.
-func binarySearch(n int, out *Nodes, less func(i int) *Node, leaf func(i int, nif *Node)) {
+func binarySearch(n int, out *ir.Nodes, less func(i int) *ir.Node, leaf func(i int, nif *ir.Node)) {
        const binarySearchMin = 4 // minimum number of cases for binary search
 
-       var do func(lo, hi int, out *Nodes)
-       do = func(lo, hi int, out *Nodes) {
+       var do func(lo, hi int, out *ir.Nodes)
+       do = func(lo, hi int, out *ir.Nodes) {
                n := hi - lo
                if n < binarySearchMin {
                        for i := lo; i < hi; i++ {
-                               nif := nod(OIF, nil, nil)
+                               nif := ir.Nod(ir.OIF, nil, nil)
                                leaf(i, nif)
                                base.Pos = base.Pos.WithNotStmt()
                                nif.Left = typecheck(nif.Left, ctxExpr)
@@ -744,7 +745,7 @@ func binarySearch(n int, out *Nodes, less func(i int) *Node, leaf func(i int, ni
                }
 
                half := lo + n/2
-               nif := nod(OIF, nil, nil)
+               nif := ir.Nod(ir.OIF, nil, nil)
                nif.Left = less(half)
                base.Pos = base.Pos.WithNotStmt()
                nif.Left = typecheck(nif.Left, ctxExpr)
index b61b9b05258925c14df8099937668840ef651c19..78fdf100ad2881d5a0be7a9881332b7c433ce37f 100644 (file)
@@ -6,6 +6,7 @@ package gc
 
 import (
        "cmd/compile/internal/base"
+       "cmd/compile/internal/ir"
        "cmd/compile/internal/types"
        "fmt"
        "go/constant"
@@ -19,7 +20,7 @@ const enableTrace = false
 var traceIndent []byte
 var skipDowidthForTracing bool
 
-func tracePrint(title string, n *Node) func(np **Node) {
+func tracePrint(title string, n *ir.Node) func(np **ir.Node) {
        indent := traceIndent
 
        // guard against nil
@@ -36,7 +37,7 @@ func tracePrint(title string, n *Node) func(np **Node) {
        fmt.Printf("%s: %s%s %p %s %v tc=%d\n", pos, indent, title, n, op, n, tc)
        traceIndent = append(traceIndent, ". "...)
 
-       return func(np **Node) {
+       return func(np **ir.Node) {
                traceIndent = traceIndent[:len(traceIndent)-2]
 
                // if we have a result, use that
@@ -76,11 +77,11 @@ const (
 // marks variables that escape the local frame.
 // rewrites n.Op to be more specific in some cases.
 
-var typecheckdefstack []*Node
+var typecheckdefstack []*ir.Node
 
 // resolve ONONAME to definition, if any.
-func resolve(n *Node) (res *Node) {
-       if n == nil || n.Op != ONONAME {
+func resolve(n *ir.Node) (res *ir.Node) {
+       if n == nil || n.Op != ir.ONONAME {
                return n
        }
 
@@ -89,7 +90,7 @@ func resolve(n *Node) (res *Node) {
                defer tracePrint("resolve", n)(&res)
        }
 
-       if n.Sym.Pkg != localpkg {
+       if n.Sym.Pkg != ir.LocalPkg {
                if inimport {
                        base.Fatalf("recursive inimport")
                }
@@ -99,12 +100,12 @@ func resolve(n *Node) (res *Node) {
                return n
        }
 
-       r := asNode(n.Sym.Def)
+       r := ir.AsNode(n.Sym.Def)
        if r == nil {
                return n
        }
 
-       if r.Op == OIOTA {
+       if r.Op == ir.OIOTA {
                if x := getIotaValue(); x >= 0 {
                        return nodintconst(x)
                }
@@ -114,41 +115,41 @@ func resolve(n *Node) (res *Node) {
        return r
 }
 
-func typecheckslice(l []*Node, top int) {
+func typecheckslice(l []*ir.Node, top int) {
        for i := range l {
                l[i] = typecheck(l[i], top)
        }
 }
 
 var _typekind = []string{
-       TINT:        "int",
-       TUINT:       "uint",
-       TINT8:       "int8",
-       TUINT8:      "uint8",
-       TINT16:      "int16",
-       TUINT16:     "uint16",
-       TINT32:      "int32",
-       TUINT32:     "uint32",
-       TINT64:      "int64",
-       TUINT64:     "uint64",
-       TUINTPTR:    "uintptr",
-       TCOMPLEX64:  "complex64",
-       TCOMPLEX128: "complex128",
-       TFLOAT32:    "float32",
-       TFLOAT64:    "float64",
-       TBOOL:       "bool",
-       TSTRING:     "string",
-       TPTR:        "pointer",
-       TUNSAFEPTR:  "unsafe.Pointer",
-       TSTRUCT:     "struct",
-       TINTER:      "interface",
-       TCHAN:       "chan",
-       TMAP:        "map",
-       TARRAY:      "array",
-       TSLICE:      "slice",
-       TFUNC:       "func",
-       TNIL:        "nil",
-       TIDEAL:      "untyped number",
+       types.TINT:        "int",
+       types.TUINT:       "uint",
+       types.TINT8:       "int8",
+       types.TUINT8:      "uint8",
+       types.TINT16:      "int16",
+       types.TUINT16:     "uint16",
+       types.TINT32:      "int32",
+       types.TUINT32:     "uint32",
+       types.TINT64:      "int64",
+       types.TUINT64:     "uint64",
+       types.TUINTPTR:    "uintptr",
+       types.TCOMPLEX64:  "complex64",
+       types.TCOMPLEX128: "complex128",
+       types.TFLOAT32:    "float32",
+       types.TFLOAT64:    "float64",
+       types.TBOOL:       "bool",
+       types.TSTRING:     "string",
+       types.TPTR:        "pointer",
+       types.TUNSAFEPTR:  "unsafe.Pointer",
+       types.TSTRUCT:     "struct",
+       types.TINTER:      "interface",
+       types.TCHAN:       "chan",
+       types.TMAP:        "map",
+       types.TARRAY:      "array",
+       types.TSLICE:      "slice",
+       types.TFUNC:       "func",
+       types.TNIL:        "nil",
+       types.TIDEAL:      "untyped number",
 }
 
 func typekind(t *types.Type) string {
@@ -165,7 +166,7 @@ func typekind(t *types.Type) string {
        return fmt.Sprintf("etype=%d", et)
 }
 
-func cycleFor(start *Node) []*Node {
+func cycleFor(start *ir.Node) []*ir.Node {
        // Find the start node in typecheck_tcstack.
        // We know that it must exist because each time we mark
        // a node with n.SetTypecheck(2) we push it on the stack,
@@ -178,7 +179,7 @@ func cycleFor(start *Node) []*Node {
        }
 
        // collect all nodes with same Op
-       var cycle []*Node
+       var cycle []*ir.Node
        for _, n := range typecheck_tcstack[i:] {
                if n.Op == start.Op {
                        cycle = append(cycle, n)
@@ -188,20 +189,20 @@ func cycleFor(start *Node) []*Node {
        return cycle
 }
 
-func cycleTrace(cycle []*Node) string {
+func cycleTrace(cycle []*ir.Node) string {
        var s string
        for i, n := range cycle {
-               s += fmt.Sprintf("\n\t%v: %v uses %v", n.Line(), n, cycle[(i+1)%len(cycle)])
+               s += fmt.Sprintf("\n\t%v: %v uses %v", ir.Line(n), n, cycle[(i+1)%len(cycle)])
        }
        return s
 }
 
-var typecheck_tcstack []*Node
+var typecheck_tcstack []*ir.Node
 
 // typecheck type checks node n.
 // The result of typecheck MUST be assigned back to n, e.g.
 //     n.Left = typecheck(n.Left, top)
-func typecheck(n *Node, top int) (res *Node) {
+func typecheck(n *ir.Node, top int) (res *ir.Node) {
        // cannot type check until all the source has been parsed
        if !typecheckok {
                base.Fatalf("early typecheck")
@@ -219,7 +220,7 @@ func typecheck(n *Node, top int) (res *Node) {
        lno := setlineno(n)
 
        // Skip over parens.
-       for n.Op == OPAREN {
+       for n.Op == ir.OPAREN {
                n = n.Left
        }
 
@@ -230,7 +231,7 @@ func typecheck(n *Node, top int) (res *Node) {
        // But re-typecheck ONAME/OTYPE/OLITERAL/OPACK node in case context has changed.
        if n.Typecheck() == 1 {
                switch n.Op {
-               case ONAME, OTYPE, OLITERAL, OPACK:
+               case ir.ONAME, ir.OTYPE, ir.OLITERAL, ir.OPACK:
                        break
 
                default:
@@ -244,12 +245,12 @@ func typecheck(n *Node, top int) (res *Node) {
                // otherwise a stack trace of typechecking.
                switch n.Op {
                // We can already diagnose variables used as types.
-               case ONAME:
+               case ir.ONAME:
                        if top&(ctxExpr|ctxType) == ctxType {
                                base.Errorf("%v is not a type", n)
                        }
 
-               case OTYPE:
+               case ir.OTYPE:
                        // Only report a type cycle if we are expecting a type.
                        // Otherwise let other code report an error.
                        if top&ctxType == ctxType {
@@ -274,7 +275,7 @@ func typecheck(n *Node, top int) (res *Node) {
                                base.ErrorfAt(n.Pos, "invalid recursive type alias %v%s", n, cycleTrace(cycle))
                        }
 
-               case OLITERAL:
+               case ir.OLITERAL:
                        if top&(ctxExpr|ctxType) == ctxType {
                                base.Errorf("%v is not a type", n)
                                break
@@ -286,7 +287,7 @@ func typecheck(n *Node, top int) (res *Node) {
                        var trace string
                        for i := len(typecheck_tcstack) - 1; i >= 0; i-- {
                                x := typecheck_tcstack[i]
-                               trace += fmt.Sprintf("\n\t%v %v", x.Line(), x)
+                               trace += fmt.Sprintf("\n\t%v %v", ir.Line(x), x)
                        }
                        base.Errorf("typechecking loop involving %v%s", n, trace)
                }
@@ -316,34 +317,34 @@ func typecheck(n *Node, top int) (res *Node) {
 // value of type int (see also checkmake for comparison).
 // The result of indexlit MUST be assigned back to n, e.g.
 //     n.Left = indexlit(n.Left)
-func indexlit(n *Node) *Node {
-       if n != nil && n.Type != nil && n.Type.Etype == TIDEAL {
-               return defaultlit(n, types.Types[TINT])
+func indexlit(n *ir.Node) *ir.Node {
+       if n != nil && n.Type != nil && n.Type.Etype == types.TIDEAL {
+               return defaultlit(n, types.Types[types.TINT])
        }
        return n
 }
 
 // The result of typecheck1 MUST be assigned back to n, e.g.
 //     n.Left = typecheck1(n.Left, top)
-func typecheck1(n *Node, top int) (res *Node) {
+func typecheck1(n *ir.Node, top int) (res *ir.Node) {
        if enableTrace && base.Flag.LowerT {
                defer tracePrint("typecheck1", n)(&res)
        }
 
        switch n.Op {
-       case OLITERAL, ONAME, ONONAME, OTYPE:
+       case ir.OLITERAL, ir.ONAME, ir.ONONAME, ir.OTYPE:
                if n.Sym == nil {
                        break
                }
 
-               if n.Op == ONAME && n.SubOp() != 0 && top&ctxCallee == 0 {
+               if n.Op == ir.ONAME && n.SubOp() != 0 && top&ctxCallee == 0 {
                        base.Errorf("use of builtin %v not in function call", n.Sym)
                        n.Type = nil
                        return n
                }
 
                typecheckdef(n)
-               if n.Op == ONONAME {
+               if n.Op == ir.ONONAME {
                        n.Type = nil
                        return n
                }
@@ -353,22 +354,22 @@ func typecheck1(n *Node, top int) (res *Node) {
        switch n.Op {
        // until typecheck is complete, do nothing.
        default:
-               Dump("typecheck", n)
+               ir.Dump("typecheck", n)
 
                base.Fatalf("typecheck %v", n.Op)
 
        // names
-       case OLITERAL:
+       case ir.OLITERAL:
                ok |= ctxExpr
 
                if n.Type == nil && n.Val().Kind() == constant.String {
                        base.Fatalf("string literal missing type")
                }
 
-       case ONIL, ONONAME:
+       case ir.ONIL, ir.ONONAME:
                ok |= ctxExpr
 
-       case ONAME:
+       case ir.ONAME:
                if n.Name.Decldepth == 0 {
                        n.Name.Decldepth = decldepth
                }
@@ -379,7 +380,7 @@ func typecheck1(n *Node, top int) (res *Node) {
 
                if top&ctxAssign == 0 {
                        // not a write to the variable
-                       if n.isBlank() {
+                       if ir.IsBlank(n) {
                                base.Errorf("cannot use _ as value")
                                n.Type = nil
                                return n
@@ -390,23 +391,23 @@ func typecheck1(n *Node, top int) (res *Node) {
 
                ok |= ctxExpr
 
-       case OPACK:
+       case ir.OPACK:
                base.Errorf("use of package %v without selector", n.Sym)
                n.Type = nil
                return n
 
-       case ODDD:
+       case ir.ODDD:
                break
 
        // types (ODEREF is with exprs)
-       case OTYPE:
+       case ir.OTYPE:
                ok |= ctxType
 
                if n.Type == nil {
                        return n
                }
 
-       case OTARRAY:
+       case ir.OTARRAY:
                ok |= ctxType
                r := typecheck(n.Right, ctxType)
                if r.Type == nil {
@@ -417,7 +418,7 @@ func typecheck1(n *Node, top int) (res *Node) {
                var t *types.Type
                if n.Left == nil {
                        t = types.NewSlice(r.Type)
-               } else if n.Left.Op == ODDD {
+               } else if n.Left.Op == ir.ODDD {
                        if !n.Diag() {
                                n.SetDiag(true)
                                base.Errorf("use of [...] array outside of array literal")
@@ -427,11 +428,11 @@ func typecheck1(n *Node, top int) (res *Node) {
                } else {
                        n.Left = indexlit(typecheck(n.Left, ctxExpr))
                        l := n.Left
-                       if consttype(l) != constant.Int {
+                       if ir.ConstType(l) != constant.Int {
                                switch {
                                case l.Type == nil:
                                        // Error already reported elsewhere.
-                               case l.Type.IsInteger() && l.Op != OLITERAL:
+                               case l.Type.IsInteger() && l.Op != ir.OLITERAL:
                                        base.Errorf("non-constant array bound %v", l)
                                default:
                                        base.Errorf("invalid array bound %v", l)
@@ -441,7 +442,7 @@ func typecheck1(n *Node, top int) (res *Node) {
                        }
 
                        v := l.Val()
-                       if doesoverflow(v, types.Types[TINT]) {
+                       if doesoverflow(v, types.Types[types.TINT]) {
                                base.Errorf("array bound is too large")
                                n.Type = nil
                                return n
@@ -462,7 +463,7 @@ func typecheck1(n *Node, top int) (res *Node) {
                n.Right = nil
                checkwidth(t)
 
-       case OTMAP:
+       case ir.OTMAP:
                ok |= ctxType
                n.Left = typecheck(n.Left, ctxType)
                n.Right = typecheck(n.Right, ctxType)
@@ -484,7 +485,7 @@ func typecheck1(n *Node, top int) (res *Node) {
                n.Left = nil
                n.Right = nil
 
-       case OTCHAN:
+       case ir.OTCHAN:
                ok |= ctxType
                n.Left = typecheck(n.Left, ctxType)
                l := n.Left
@@ -500,16 +501,16 @@ func typecheck1(n *Node, top int) (res *Node) {
                n.Left = nil
                n.ResetAux()
 
-       case OTSTRUCT:
+       case ir.OTSTRUCT:
                ok |= ctxType
                setTypeNode(n, tostruct(n.List.Slice()))
                n.List.Set(nil)
 
-       case OTINTER:
+       case ir.OTINTER:
                ok |= ctxType
                setTypeNode(n, tointerface(n.List.Slice()))
 
-       case OTFUNC:
+       case ir.OTFUNC:
                ok |= ctxType
                setTypeNode(n, functype(n.Left, n.List.Slice(), n.Rlist.Slice()))
                n.Left = nil
@@ -517,7 +518,7 @@ func typecheck1(n *Node, top int) (res *Node) {
                n.Rlist.Set(nil)
 
        // type or expr
-       case ODEREF:
+       case ir.ODEREF:
                n.Left = typecheck(n.Left, ctxExpr|ctxType)
                l := n.Left
                t := l.Type
@@ -525,7 +526,7 @@ func typecheck1(n *Node, top int) (res *Node) {
                        n.Type = nil
                        return n
                }
-               if l.Op == OTYPE {
+               if l.Op == ir.OTYPE {
                        ok |= ctxType
                        setTypeNode(n, types.NewPtr(l.Type))
                        n.Left = nil
@@ -548,30 +549,30 @@ func typecheck1(n *Node, top int) (res *Node) {
                n.Type = t.Elem()
 
        // arithmetic exprs
-       case OASOP,
-               OADD,
-               OAND,
-               OANDAND,
-               OANDNOT,
-               ODIV,
-               OEQ,
-               OGE,
-               OGT,
-               OLE,
-               OLT,
-               OLSH,
-               ORSH,
-               OMOD,
-               OMUL,
-               ONE,
-               OOR,
-               OOROR,
-               OSUB,
-               OXOR:
-               var l *Node
-               var op Op
-               var r *Node
-               if n.Op == OASOP {
+       case ir.OASOP,
+               ir.OADD,
+               ir.OAND,
+               ir.OANDAND,
+               ir.OANDNOT,
+               ir.ODIV,
+               ir.OEQ,
+               ir.OGE,
+               ir.OGT,
+               ir.OLE,
+               ir.OLT,
+               ir.OLSH,
+               ir.ORSH,
+               ir.OMOD,
+               ir.OMUL,
+               ir.ONE,
+               ir.OOR,
+               ir.OOROR,
+               ir.OSUB,
+               ir.OXOR:
+               var l *ir.Node
+               var op ir.Op
+               var r *ir.Node
+               if n.Op == ir.OASOP {
                        ok |= ctxStmt
                        n.Left = typecheck(n.Left, ctxExpr)
                        n.Right = typecheck(n.Right, ctxExpr)
@@ -601,8 +602,8 @@ func typecheck1(n *Node, top int) (res *Node) {
                        }
                        op = n.Op
                }
-               if op == OLSH || op == ORSH {
-                       r = defaultlit(r, types.Types[TUINT])
+               if op == ir.OLSH || op == ir.ORSH {
+                       r = defaultlit(r, types.Types[types.TUINT])
                        n.Right = r
                        t := r.Type
                        if !t.IsInteger() {
@@ -616,7 +617,7 @@ func typecheck1(n *Node, top int) (res *Node) {
                                return n
                        }
                        t = l.Type
-                       if t != nil && t.Etype != TIDEAL && !t.IsInteger() {
+                       if t != nil && t.Etype != types.TIDEAL && !t.IsInteger() {
                                base.Errorf("invalid operation: %v (shift of type %v)", n, t)
                                n.Type = nil
                                return n
@@ -625,7 +626,7 @@ func typecheck1(n *Node, top int) (res *Node) {
                        // no defaultlit for left
                        // the outer context gives the type
                        n.Type = l.Type
-                       if (l.Type == types.UntypedFloat || l.Type == types.UntypedComplex) && r.Op == OLITERAL {
+                       if (l.Type == types.UntypedFloat || l.Type == types.UntypedComplex) && r.Op == ir.OLITERAL {
                                n.Type = types.UntypedInt
                        }
 
@@ -635,7 +636,7 @@ func typecheck1(n *Node, top int) (res *Node) {
                // For "x == x && len(s)", it's better to report that "len(s)" (type int)
                // can't be used with "&&" than to report that "x == x" (type untyped bool)
                // can't be converted to int (see issue #41500).
-               if n.Op == OANDAND || n.Op == OOROR {
+               if n.Op == ir.OANDAND || n.Op == ir.OOROR {
                        if !n.Left.Type.IsBoolean() {
                                base.Errorf("invalid operation: %v (operator %v not defined on %s)", n, n.Op, typekind(n.Left.Type))
                                n.Type = nil
@@ -658,15 +659,15 @@ func typecheck1(n *Node, top int) (res *Node) {
                        return n
                }
                t := l.Type
-               if t.Etype == TIDEAL {
+               if t.Etype == types.TIDEAL {
                        t = r.Type
                }
                et := t.Etype
-               if et == TIDEAL {
-                       et = TINT
+               if et == types.TIDEAL {
+                       et = types.TINT
                }
-               aop := OXXX
-               if iscmp[n.Op] && t.Etype != TIDEAL && !types.Identical(l.Type, r.Type) {
+               aop := ir.OXXX
+               if iscmp[n.Op] && t.Etype != types.TIDEAL && !types.Identical(l.Type, r.Type) {
                        // comparison is okay as long as one side is
                        // assignable to the other.  convert so they have
                        // the same type.
@@ -675,9 +676,9 @@ func typecheck1(n *Node, top int) (res *Node) {
                        // in that case, check comparability of the concrete type.
                        // The conversion allocates, so only do it if the concrete type is huge.
                        converted := false
-                       if r.Type.Etype != TBLANK {
+                       if r.Type.Etype != types.TBLANK {
                                aop, _ = assignop(l.Type, r.Type)
-                               if aop != OXXX {
+                               if aop != ir.OXXX {
                                        if r.Type.IsInterface() && !l.Type.IsInterface() && !IsComparable(l.Type) {
                                                base.Errorf("invalid operation: %v (operator %v not defined on %s)", n, op, typekind(l.Type))
                                                n.Type = nil
@@ -686,7 +687,7 @@ func typecheck1(n *Node, top int) (res *Node) {
 
                                        dowidth(l.Type)
                                        if r.Type.IsInterface() == l.Type.IsInterface() || l.Type.Width >= 1<<16 {
-                                               l = nod(aop, l, nil)
+                                               l = ir.Nod(aop, l, nil)
                                                l.Type = r.Type
                                                l.SetTypecheck(1)
                                                n.Left = l
@@ -697,9 +698,9 @@ func typecheck1(n *Node, top int) (res *Node) {
                                }
                        }
 
-                       if !converted && l.Type.Etype != TBLANK {
+                       if !converted && l.Type.Etype != types.TBLANK {
                                aop, _ = assignop(r.Type, l.Type)
-                               if aop != OXXX {
+                               if aop != ir.OXXX {
                                        if l.Type.IsInterface() && !r.Type.IsInterface() && !IsComparable(r.Type) {
                                                base.Errorf("invalid operation: %v (operator %v not defined on %s)", n, op, typekind(r.Type))
                                                n.Type = nil
@@ -708,7 +709,7 @@ func typecheck1(n *Node, top int) (res *Node) {
 
                                        dowidth(r.Type)
                                        if r.Type.IsInterface() == l.Type.IsInterface() || r.Type.Width >= 1<<16 {
-                                               r = nod(aop, r, nil)
+                                               r = ir.Nod(aop, r, nil)
                                                r.Type = l.Type
                                                r.SetTypecheck(1)
                                                n.Right = r
@@ -721,7 +722,7 @@ func typecheck1(n *Node, top int) (res *Node) {
                        et = t.Etype
                }
 
-               if t.Etype != TIDEAL && !types.Identical(l.Type, r.Type) {
+               if t.Etype != types.TIDEAL && !types.Identical(l.Type, r.Type) {
                        l, r = defaultlit2(l, r, true)
                        if l.Type == nil || r.Type == nil {
                                n.Type = nil
@@ -734,7 +735,7 @@ func typecheck1(n *Node, top int) (res *Node) {
                        }
                }
 
-               if t.Etype == TIDEAL {
+               if t.Etype == types.TIDEAL {
                        t = mixUntyped(l.Type, r.Type)
                }
                if dt := defaultType(t); !okfor[op][dt.Etype] {
@@ -751,19 +752,19 @@ func typecheck1(n *Node, top int) (res *Node) {
                        return n
                }
 
-               if l.Type.IsSlice() && !l.isNil() && !r.isNil() {
+               if l.Type.IsSlice() && !ir.IsNil(l) && !ir.IsNil(r) {
                        base.Errorf("invalid operation: %v (slice can only be compared to nil)", n)
                        n.Type = nil
                        return n
                }
 
-               if l.Type.IsMap() && !l.isNil() && !r.isNil() {
+               if l.Type.IsMap() && !ir.IsNil(l) && !ir.IsNil(r) {
                        base.Errorf("invalid operation: %v (map can only be compared to nil)", n)
                        n.Type = nil
                        return n
                }
 
-               if l.Type.Etype == TFUNC && !l.isNil() && !r.isNil() {
+               if l.Type.Etype == types.TFUNC && !ir.IsNil(l) && !ir.IsNil(r) {
                        base.Errorf("invalid operation: %v (func can only be compared to nil)", n)
                        n.Type = nil
                        return n
@@ -781,31 +782,31 @@ func typecheck1(n *Node, top int) (res *Node) {
                        t = types.UntypedBool
                        n.Type = t
                        n = evalConst(n)
-                       if n.Op != OLITERAL {
+                       if n.Op != ir.OLITERAL {
                                l, r = defaultlit2(l, r, true)
                                n.Left = l
                                n.Right = r
                        }
                }
 
-               if et == TSTRING && n.Op == OADD {
+               if et == types.TSTRING && n.Op == ir.OADD {
                        // create or update OADDSTR node with list of strings in x + y + z + (w + v) + ...
-                       if l.Op == OADDSTR {
+                       if l.Op == ir.OADDSTR {
                                orig := n
                                n = l
                                n.Pos = orig.Pos
                        } else {
-                               n = nodl(n.Pos, OADDSTR, nil, nil)
+                               n = ir.NodAt(n.Pos, ir.OADDSTR, nil, nil)
                                n.List.Set1(l)
                        }
-                       if r.Op == OADDSTR {
+                       if r.Op == ir.OADDSTR {
                                n.List.AppendNodes(&r.List)
                        } else {
                                n.List.Append(r)
                        }
                }
 
-               if (op == ODIV || op == OMOD) && Isconst(r, constant.Int) {
+               if (op == ir.ODIV || op == ir.OMOD) && ir.IsConst(r, constant.Int) {
                        if constant.Sign(r.Val()) == 0 {
                                base.Errorf("division by zero")
                                n.Type = nil
@@ -815,7 +816,7 @@ func typecheck1(n *Node, top int) (res *Node) {
 
                n.Type = t
 
-       case OBITNOT, ONEG, ONOT, OPLUS:
+       case ir.OBITNOT, ir.ONEG, ir.ONOT, ir.OPLUS:
                ok |= ctxExpr
                n.Left = typecheck(n.Left, ctxExpr)
                l := n.Left
@@ -833,7 +834,7 @@ func typecheck1(n *Node, top int) (res *Node) {
                n.Type = t
 
        // exprs
-       case OADDR:
+       case ir.OADDR:
                ok |= ctxExpr
 
                n.Left = typecheck(n.Left, ctxExpr)
@@ -843,13 +844,13 @@ func typecheck1(n *Node, top int) (res *Node) {
                }
 
                switch n.Left.Op {
-               case OARRAYLIT, OMAPLIT, OSLICELIT, OSTRUCTLIT:
-                       n.Op = OPTRLIT
+               case ir.OARRAYLIT, ir.OMAPLIT, ir.OSLICELIT, ir.OSTRUCTLIT:
+                       n.Op = ir.OPTRLIT
 
                default:
                        checklvalue(n.Left, "take the address of")
                        r := outervalue(n.Left)
-                       if r.Op == ONAME {
+                       if r.Op == ir.ONAME {
                                if r.Orig != r {
                                        base.Fatalf("found non-orig name node %v", r) // TODO(mdempsky): What does this mean?
                                }
@@ -871,17 +872,17 @@ func typecheck1(n *Node, top int) (res *Node) {
 
                n.Type = types.NewPtr(n.Left.Type)
 
-       case OCOMPLIT:
+       case ir.OCOMPLIT:
                ok |= ctxExpr
                n = typecheckcomplit(n)
                if n.Type == nil {
                        return n
                }
 
-       case OXDOT, ODOT:
-               if n.Op == OXDOT {
+       case ir.OXDOT, ir.ODOT:
+               if n.Op == ir.OXDOT {
                        n = adddot(n)
-                       n.Op = ODOT
+                       n.Op = ir.ODOT
                        if n.Left == nil {
                                n.Type = nil
                                return n
@@ -894,14 +895,14 @@ func typecheck1(n *Node, top int) (res *Node) {
 
                t := n.Left.Type
                if t == nil {
-                       base.UpdateErrorDot(n.Line(), n.Left.String(), n.String())
+                       base.UpdateErrorDot(ir.Line(n), n.Left.String(), n.String())
                        n.Type = nil
                        return n
                }
 
                s := n.Sym
 
-               if n.Left.Op == OTYPE {
+               if n.Left.Op == ir.OTYPE {
                        n = typecheckMethodExpr(n)
                        if n.Type == nil {
                                return n
@@ -916,7 +917,7 @@ func typecheck1(n *Node, top int) (res *Node) {
                                n.Type = nil
                                return n
                        }
-                       n.Op = ODOTPTR
+                       n.Op = ir.ODOTPTR
                        checkwidth(t)
                }
 
@@ -952,7 +953,7 @@ func typecheck1(n *Node, top int) (res *Node) {
                }
 
                switch n.Op {
-               case ODOTINTER, ODOTMETH:
+               case ir.ODOTINTER, ir.ODOTMETH:
                        if top&ctxCallee != 0 {
                                ok |= ctxCallee
                        } else {
@@ -964,7 +965,7 @@ func typecheck1(n *Node, top int) (res *Node) {
                        ok |= ctxExpr
                }
 
-       case ODOTTYPE:
+       case ir.ODOTTYPE:
                ok |= ctxExpr
                n.Left = typecheck(n.Left, ctxExpr)
                n.Left = defaultlit(n.Left, nil)
@@ -1009,7 +1010,7 @@ func typecheck1(n *Node, top int) (res *Node) {
                        }
                }
 
-       case OINDEX:
+       case ir.OINDEX:
                ok |= ctxExpr
                n.Left = typecheck(n.Left, ctxExpr)
                n.Left = defaultlit(n.Left, nil)
@@ -1028,7 +1029,7 @@ func typecheck1(n *Node, top int) (res *Node) {
                        n.Type = nil
                        return n
 
-               case TSTRING, TARRAY, TSLICE:
+               case types.TSTRING, types.TARRAY, types.TSLICE:
                        n.Right = indexlit(n.Right)
                        if t.IsString() {
                                n.Type = types.Bytetype
@@ -1047,27 +1048,27 @@ func typecheck1(n *Node, top int) (res *Node) {
                                break
                        }
 
-                       if !n.Bounded() && Isconst(n.Right, constant.Int) {
+                       if !n.Bounded() && ir.IsConst(n.Right, constant.Int) {
                                x := n.Right.Val()
                                if constant.Sign(x) < 0 {
                                        base.Errorf("invalid %s index %v (index must be non-negative)", why, n.Right)
                                } else if t.IsArray() && constant.Compare(x, token.GEQ, constant.MakeInt64(t.NumElem())) {
                                        base.Errorf("invalid array index %v (out of bounds for %d-element array)", n.Right, t.NumElem())
-                               } else if Isconst(n.Left, constant.String) && constant.Compare(x, token.GEQ, constant.MakeInt64(int64(len(n.Left.StringVal())))) {
+                               } else if ir.IsConst(n.Left, constant.String) && constant.Compare(x, token.GEQ, constant.MakeInt64(int64(len(n.Left.StringVal())))) {
                                        base.Errorf("invalid string index %v (out of bounds for %d-byte string)", n.Right, len(n.Left.StringVal()))
-                               } else if doesoverflow(x, types.Types[TINT]) {
+                               } else if doesoverflow(x, types.Types[types.TINT]) {
                                        base.Errorf("invalid %s index %v (index too large)", why, n.Right)
                                }
                        }
 
-               case TMAP:
+               case types.TMAP:
                        n.Right = assignconv(n.Right, t.Key(), "map index")
                        n.Type = t.Elem()
-                       n.Op = OINDEXMAP
+                       n.Op = ir.OINDEXMAP
                        n.ResetAux()
                }
 
-       case ORECV:
+       case ir.ORECV:
                ok |= ctxStmt | ctxExpr
                n.Left = typecheck(n.Left, ctxExpr)
                n.Left = defaultlit(n.Left, nil)
@@ -1091,7 +1092,7 @@ func typecheck1(n *Node, top int) (res *Node) {
 
                n.Type = t.Elem()
 
-       case OSEND:
+       case ir.OSEND:
                ok |= ctxStmt
                n.Left = typecheck(n.Left, ctxExpr)
                n.Right = typecheck(n.Right, ctxExpr)
@@ -1120,7 +1121,7 @@ func typecheck1(n *Node, top int) (res *Node) {
                }
                n.Type = nil
 
-       case OSLICEHEADER:
+       case ir.OSLICEHEADER:
                // Errors here are Fatalf instead of Errorf because only the compiler
                // can construct an OSLICEHEADER node.
                // Components used in OSLICEHEADER that are supplied by parsed source code
@@ -1147,25 +1148,25 @@ func typecheck1(n *Node, top int) (res *Node) {
                n.Left = typecheck(n.Left, ctxExpr)
                l := typecheck(n.List.First(), ctxExpr)
                c := typecheck(n.List.Second(), ctxExpr)
-               l = defaultlit(l, types.Types[TINT])
-               c = defaultlit(c, types.Types[TINT])
+               l = defaultlit(l, types.Types[types.TINT])
+               c = defaultlit(c, types.Types[types.TINT])
 
-               if Isconst(l, constant.Int) && l.Int64Val() < 0 {
+               if ir.IsConst(l, constant.Int) && l.Int64Val() < 0 {
                        base.Fatalf("len for OSLICEHEADER must be non-negative")
                }
 
-               if Isconst(c, constant.Int) && c.Int64Val() < 0 {
+               if ir.IsConst(c, constant.Int) && c.Int64Val() < 0 {
                        base.Fatalf("cap for OSLICEHEADER must be non-negative")
                }
 
-               if Isconst(l, constant.Int) && Isconst(c, constant.Int) && constant.Compare(l.Val(), token.GTR, c.Val()) {
+               if ir.IsConst(l, constant.Int) && ir.IsConst(c, constant.Int) && constant.Compare(l.Val(), token.GTR, c.Val()) {
                        base.Fatalf("len larger than cap for OSLICEHEADER")
                }
 
                n.List.SetFirst(l)
                n.List.SetSecond(c)
 
-       case OMAKESLICECOPY:
+       case ir.OMAKESLICECOPY:
                // Errors here are Fatalf instead of Errorf because only the compiler
                // can construct an OMAKESLICECOPY node.
                // Components used in OMAKESCLICECOPY that are supplied by parsed source code
@@ -1193,14 +1194,14 @@ func typecheck1(n *Node, top int) (res *Node) {
                n.Left = typecheck(n.Left, ctxExpr)
                n.Right = typecheck(n.Right, ctxExpr)
 
-               n.Left = defaultlit(n.Left, types.Types[TINT])
+               n.Left = defaultlit(n.Left, types.Types[types.TINT])
 
-               if !n.Left.Type.IsInteger() && n.Type.Etype != TIDEAL {
+               if !n.Left.Type.IsInteger() && n.Type.Etype != types.TIDEAL {
                        base.Errorf("non-integer len argument in OMAKESLICECOPY")
                }
 
-               if Isconst(n.Left, constant.Int) {
-                       if doesoverflow(n.Left.Val(), types.Types[TINT]) {
+               if ir.IsConst(n.Left, constant.Int) {
+                       if doesoverflow(n.Left.Val(), types.Types[types.TINT]) {
                                base.Fatalf("len for OMAKESLICECOPY too large")
                        }
                        if constant.Sign(n.Left.Val()) < 0 {
@@ -1208,7 +1209,7 @@ func typecheck1(n *Node, top int) (res *Node) {
                        }
                }
 
-       case OSLICE, OSLICE3:
+       case ir.OSLICE, ir.OSLICE3:
                ok |= ctxExpr
                n.Left = typecheck(n.Left, ctxExpr)
                low, high, max := n.SliceBounds()
@@ -1233,7 +1234,7 @@ func typecheck1(n *Node, top int) (res *Node) {
                                return n
                        }
 
-                       n.Left = nod(OADDR, n.Left, nil)
+                       n.Left = ir.Nod(ir.OADDR, n.Left, nil)
                        n.Left.SetImplicit(true)
                        n.Left = typecheck(n.Left, ctxExpr)
                        l = n.Left
@@ -1247,15 +1248,15 @@ func typecheck1(n *Node, top int) (res *Node) {
                                return n
                        }
                        n.Type = t
-                       n.Op = OSLICESTR
+                       n.Op = ir.OSLICESTR
                } else if t.IsPtr() && t.Elem().IsArray() {
                        tp = t.Elem()
                        n.Type = types.NewSlice(tp.Elem())
                        dowidth(n.Type)
                        if hasmax {
-                               n.Op = OSLICE3ARR
+                               n.Op = ir.OSLICE3ARR
                        } else {
-                               n.Op = OSLICEARR
+                               n.Op = ir.OSLICEARR
                        }
                } else if t.IsSlice() {
                        n.Type = t
@@ -1283,7 +1284,7 @@ func typecheck1(n *Node, top int) (res *Node) {
                }
 
        // call and call like
-       case OCALL:
+       case ir.OCALL:
                typecheckslice(n.Ninit.Slice(), ctxStmt) // imported rewritten f(g()) calls (#30907)
                n.Left = typecheck(n.Left, ctxExpr|ctxType|ctxCallee)
                if n.Left.Diag() {
@@ -1292,8 +1293,8 @@ func typecheck1(n *Node, top int) (res *Node) {
 
                l := n.Left
 
-               if l.Op == ONAME && l.SubOp() != 0 {
-                       if n.IsDDD() && l.SubOp() != OAPPEND {
+               if l.Op == ir.ONAME && l.SubOp() != 0 {
+                       if n.IsDDD() && l.SubOp() != ir.OAPPEND {
                                base.Errorf("invalid use of ... with builtin %v", l)
                        }
 
@@ -1307,7 +1308,7 @@ func typecheck1(n *Node, top int) (res *Node) {
 
                n.Left = defaultlit(n.Left, nil)
                l = n.Left
-               if l.Op == OTYPE {
+               if l.Op == ir.OTYPE {
                        if n.IsDDD() {
                                if !l.Type.Broke() {
                                        base.Errorf("invalid use of ... in type conversion to %v", l.Type)
@@ -1321,7 +1322,7 @@ func typecheck1(n *Node, top int) (res *Node) {
                        // turn CALL(type, arg) into CONV(arg) w/ type
                        n.Left = nil
 
-                       n.Op = OCONV
+                       n.Op = ir.OCONV
                        n.Type = l.Type
                        if !onearg(n, "conversion to %v", l.Type) {
                                n.Type = nil
@@ -1340,11 +1341,11 @@ func typecheck1(n *Node, top int) (res *Node) {
                checkwidth(t)
 
                switch l.Op {
-               case ODOTINTER:
-                       n.Op = OCALLINTER
+               case ir.ODOTINTER:
+                       n.Op = ir.OCALLINTER
 
-               case ODOTMETH:
-                       n.Op = OCALLMETH
+               case ir.ODOTMETH:
+                       n.Op = ir.OCALLMETH
 
                        // typecheckaste was used here but there wasn't enough
                        // information further down the call chain to know if we
@@ -1357,8 +1358,8 @@ func typecheck1(n *Node, top int) (res *Node) {
                        }
 
                default:
-                       n.Op = OCALLFUNC
-                       if t.Etype != TFUNC {
+                       n.Op = ir.OCALLFUNC
+                       if t.Etype != types.TFUNC {
                                name := l.String()
                                if isBuiltinFuncName(name) && l.Name.Defn != nil {
                                        // be more specific when the function
@@ -1373,7 +1374,7 @@ func typecheck1(n *Node, top int) (res *Node) {
                        }
                }
 
-               typecheckaste(OCALL, n.Left, n.IsDDD(), t.Params(), n.List, func() string { return fmt.Sprintf("argument to %v", n.Left) })
+               typecheckaste(ir.OCALL, n.Left, n.IsDDD(), t.Params(), n.List, func() string { return fmt.Sprintf("argument to %v", n.Left) })
                ok |= ctxStmt
                if t.NumResults() == 0 {
                        break
@@ -1382,14 +1383,14 @@ func typecheck1(n *Node, top int) (res *Node) {
                if t.NumResults() == 1 {
                        n.Type = l.Type.Results().Field(0).Type
 
-                       if n.Op == OCALLFUNC && n.Left.Op == ONAME && isRuntimePkg(n.Left.Sym.Pkg) && n.Left.Sym.Name == "getg" {
+                       if n.Op == ir.OCALLFUNC && n.Left.Op == ir.ONAME && isRuntimePkg(n.Left.Sym.Pkg) && n.Left.Sym.Name == "getg" {
                                // Emit code for runtime.getg() directly instead of calling function.
                                // Most such rewrites (for example the similar one for math.Sqrt) should be done in walk,
                                // so that the ordering pass can make sure to preserve the semantics of the original code
                                // (in particular, the exact time of the function call) by introducing temporaries.
                                // In this case, we know getg() always returns the same result within a given function
                                // and we want to avoid the temporaries, so we do the rewrite earlier than is typical.
-                               n.Op = OGETG
+                               n.Op = ir.OGETG
                        }
 
                        break
@@ -1403,15 +1404,15 @@ func typecheck1(n *Node, top int) (res *Node) {
 
                n.Type = l.Type.Results()
 
-       case OALIGNOF, OOFFSETOF, OSIZEOF:
+       case ir.OALIGNOF, ir.OOFFSETOF, ir.OSIZEOF:
                ok |= ctxExpr
                if !onearg(n, "%v", n.Op) {
                        n.Type = nil
                        return n
                }
-               n.Type = types.Types[TUINTPTR]
+               n.Type = types.Types[types.TUINTPTR]
 
-       case OCAP, OLEN:
+       case ir.OCAP, ir.OLEN:
                ok |= ctxExpr
                if !onearg(n, "%v", n.Op) {
                        n.Type = nil
@@ -1429,7 +1430,7 @@ func typecheck1(n *Node, top int) (res *Node) {
                }
 
                var ok bool
-               if n.Op == OLEN {
+               if n.Op == ir.OLEN {
                        ok = okforlen[t.Etype]
                } else {
                        ok = okforcap[t.Etype]
@@ -1440,9 +1441,9 @@ func typecheck1(n *Node, top int) (res *Node) {
                        return n
                }
 
-               n.Type = types.Types[TINT]
+               n.Type = types.Types[types.TINT]
 
-       case OREAL, OIMAG:
+       case ir.OREAL, ir.OIMAG:
                ok |= ctxExpr
                if !onearg(n, "%v", n.Op) {
                        n.Type = nil
@@ -1459,19 +1460,19 @@ func typecheck1(n *Node, top int) (res *Node) {
 
                // Determine result type.
                switch t.Etype {
-               case TIDEAL:
+               case types.TIDEAL:
                        n.Type = types.UntypedFloat
-               case TCOMPLEX64:
-                       n.Type = types.Types[TFLOAT32]
-               case TCOMPLEX128:
-                       n.Type = types.Types[TFLOAT64]
+               case types.TCOMPLEX64:
+                       n.Type = types.Types[types.TFLOAT32]
+               case types.TCOMPLEX128:
+                       n.Type = types.Types[types.TFLOAT64]
                default:
                        base.Errorf("invalid argument %L for %v", l, n.Op)
                        n.Type = nil
                        return n
                }
 
-       case OCOMPLEX:
+       case ir.OCOMPLEX:
                ok |= ctxExpr
                typecheckargs(n)
                if !twoarg(n) {
@@ -1505,18 +1506,18 @@ func typecheck1(n *Node, top int) (res *Node) {
                        n.Type = nil
                        return n
 
-               case TIDEAL:
+               case types.TIDEAL:
                        t = types.UntypedComplex
 
-               case TFLOAT32:
-                       t = types.Types[TCOMPLEX64]
+               case types.TFLOAT32:
+                       t = types.Types[types.TCOMPLEX64]
 
-               case TFLOAT64:
-                       t = types.Types[TCOMPLEX128]
+               case types.TFLOAT64:
+                       t = types.Types[types.TCOMPLEX128]
                }
                n.Type = t
 
-       case OCLOSE:
+       case ir.OCLOSE:
                if !onearg(n, "%v", n.Op) {
                        n.Type = nil
                        return n
@@ -1543,7 +1544,7 @@ func typecheck1(n *Node, top int) (res *Node) {
 
                ok |= ctxStmt
 
-       case ODELETE:
+       case ir.ODELETE:
                ok |= ctxStmt
                typecheckargs(n)
                args := n.List
@@ -1575,7 +1576,7 @@ func typecheck1(n *Node, top int) (res *Node) {
 
                args.SetSecond(assignconv(r, l.Type.Key(), "delete"))
 
-       case OAPPEND:
+       case ir.OAPPEND:
                ok |= ctxExpr
                typecheckargs(n)
                args := n.List
@@ -1593,7 +1594,7 @@ func typecheck1(n *Node, top int) (res *Node) {
 
                n.Type = t
                if !t.IsSlice() {
-                       if args.First().isNil() {
+                       if ir.IsNil(args.First()) {
                                base.Errorf("first argument to append must be typed slice; have untyped nil")
                                n.Type = nil
                                return n
@@ -1617,8 +1618,8 @@ func typecheck1(n *Node, top int) (res *Node) {
                                return n
                        }
 
-                       if t.Elem().IsKind(TUINT8) && args.Second().Type.IsString() {
-                               args.SetSecond(defaultlit(args.Second(), types.Types[TSTRING]))
+                       if t.Elem().IsKind(types.TUINT8) && args.Second().Type.IsString() {
+                               args.SetSecond(defaultlit(args.Second(), types.Types[types.TSTRING]))
                                break
                        }
 
@@ -1635,14 +1636,14 @@ func typecheck1(n *Node, top int) (res *Node) {
                        checkwidth(as[i].Type) // ensure width is calculated for backend
                }
 
-       case OCOPY:
+       case ir.OCOPY:
                ok |= ctxStmt | ctxExpr
                typecheckargs(n)
                if !twoarg(n) {
                        n.Type = nil
                        return n
                }
-               n.Type = types.Types[TINT]
+               n.Type = types.Types[types.TINT]
                if n.Left.Type == nil || n.Right.Type == nil {
                        n.Type = nil
                        return n
@@ -1682,7 +1683,7 @@ func typecheck1(n *Node, top int) (res *Node) {
                        return n
                }
 
-       case OCONV:
+       case ir.OCONV:
                ok |= ctxExpr
                checkwidth(n.Type) // ensure width is calculated for backend
                n.Left = typecheck(n.Left, ctxExpr)
@@ -1692,41 +1693,41 @@ func typecheck1(n *Node, top int) (res *Node) {
                        n.Type = nil
                        return n
                }
-               op, why := convertop(n.Left.Op == OLITERAL, t, n.Type)
+               op, why := convertop(n.Left.Op == ir.OLITERAL, t, n.Type)
                n.Op = op
-               if n.Op == OXXX {
+               if n.Op == ir.OXXX {
                        if !n.Diag() && !n.Type.Broke() && !n.Left.Diag() {
                                base.Errorf("cannot convert %L to type %v%s", n.Left, n.Type, why)
                                n.SetDiag(true)
                        }
-                       n.Op = OCONV
+                       n.Op = ir.OCONV
                        n.Type = nil
                        return n
                }
 
                switch n.Op {
-               case OCONVNOP:
+               case ir.OCONVNOP:
                        if t.Etype == n.Type.Etype {
                                switch t.Etype {
-                               case TFLOAT32, TFLOAT64, TCOMPLEX64, TCOMPLEX128:
+                               case types.TFLOAT32, types.TFLOAT64, types.TCOMPLEX64, types.TCOMPLEX128:
                                        // Floating point casts imply rounding and
                                        // so the conversion must be kept.
-                                       n.Op = OCONV
+                                       n.Op = ir.OCONV
                                }
                        }
 
                // do not convert to []byte literal. See CL 125796.
                // generated code and compiler memory footprint is better without it.
-               case OSTR2BYTES:
+               case ir.OSTR2BYTES:
                        break
 
-               case OSTR2RUNES:
-                       if n.Left.Op == OLITERAL {
+               case ir.OSTR2RUNES:
+                       if n.Left.Op == ir.OLITERAL {
                                n = stringtoruneslit(n)
                        }
                }
 
-       case OMAKE:
+       case ir.OMAKE:
                ok |= ctxExpr
                args := n.List.Slice()
                if len(args) == 0 {
@@ -1751,7 +1752,7 @@ func typecheck1(n *Node, top int) (res *Node) {
                        n.Type = nil
                        return n
 
-               case TSLICE:
+               case types.TSLICE:
                        if i >= len(args) {
                                base.Errorf("missing len argument to make(%v)", t)
                                n.Type = nil
@@ -1761,7 +1762,7 @@ func typecheck1(n *Node, top int) (res *Node) {
                        l = args[i]
                        i++
                        l = typecheck(l, ctxExpr)
-                       var r *Node
+                       var r *ir.Node
                        if i < len(args) {
                                r = args[i]
                                i++
@@ -1776,7 +1777,7 @@ func typecheck1(n *Node, top int) (res *Node) {
                                n.Type = nil
                                return n
                        }
-                       if Isconst(l, constant.Int) && r != nil && Isconst(r, constant.Int) && constant.Compare(l.Val(), token.GTR, r.Val()) {
+                       if ir.IsConst(l, constant.Int) && r != nil && ir.IsConst(r, constant.Int) && constant.Compare(l.Val(), token.GTR, r.Val()) {
                                base.Errorf("len larger than cap in make(%v)", t)
                                n.Type = nil
                                return n
@@ -1784,14 +1785,14 @@ func typecheck1(n *Node, top int) (res *Node) {
 
                        n.Left = l
                        n.Right = r
-                       n.Op = OMAKESLICE
+                       n.Op = ir.OMAKESLICE
 
-               case TMAP:
+               case types.TMAP:
                        if i < len(args) {
                                l = args[i]
                                i++
                                l = typecheck(l, ctxExpr)
-                               l = defaultlit(l, types.Types[TINT])
+                               l = defaultlit(l, types.Types[types.TINT])
                                if l.Type == nil {
                                        n.Type = nil
                                        return n
@@ -1804,15 +1805,15 @@ func typecheck1(n *Node, top int) (res *Node) {
                        } else {
                                n.Left = nodintconst(0)
                        }
-                       n.Op = OMAKEMAP
+                       n.Op = ir.OMAKEMAP
 
-               case TCHAN:
+               case types.TCHAN:
                        l = nil
                        if i < len(args) {
                                l = args[i]
                                i++
                                l = typecheck(l, ctxExpr)
-                               l = defaultlit(l, types.Types[TINT])
+                               l = defaultlit(l, types.Types[types.TINT])
                                if l.Type == nil {
                                        n.Type = nil
                                        return n
@@ -1825,19 +1826,19 @@ func typecheck1(n *Node, top int) (res *Node) {
                        } else {
                                n.Left = nodintconst(0)
                        }
-                       n.Op = OMAKECHAN
+                       n.Op = ir.OMAKECHAN
                }
 
                if i < len(args) {
                        base.Errorf("too many arguments to make(%v)", t)
-                       n.Op = OMAKE
+                       n.Op = ir.OMAKE
                        n.Type = nil
                        return n
                }
 
                n.Type = t
 
-       case ONEW:
+       case ir.ONEW:
                ok |= ctxExpr
                args := n.List
                if args.Len() == 0 {
@@ -1862,33 +1863,33 @@ func typecheck1(n *Node, top int) (res *Node) {
                n.Left = l
                n.Type = types.NewPtr(t)
 
-       case OPRINT, OPRINTN:
+       case ir.OPRINT, ir.OPRINTN:
                ok |= ctxStmt
                typecheckargs(n)
                ls := n.List.Slice()
                for i1, n1 := range ls {
                        // Special case for print: int constant is int64, not int.
-                       if Isconst(n1, constant.Int) {
-                               ls[i1] = defaultlit(ls[i1], types.Types[TINT64])
+                       if ir.IsConst(n1, constant.Int) {
+                               ls[i1] = defaultlit(ls[i1], types.Types[types.TINT64])
                        } else {
                                ls[i1] = defaultlit(ls[i1], nil)
                        }
                }
 
-       case OPANIC:
+       case ir.OPANIC:
                ok |= ctxStmt
                if !onearg(n, "panic") {
                        n.Type = nil
                        return n
                }
                n.Left = typecheck(n.Left, ctxExpr)
-               n.Left = defaultlit(n.Left, types.Types[TINTER])
+               n.Left = defaultlit(n.Left, types.Types[types.TINTER])
                if n.Left.Type == nil {
                        n.Type = nil
                        return n
                }
 
-       case ORECOVER:
+       case ir.ORECOVER:
                ok |= ctxExpr | ctxStmt
                if n.List.Len() != 0 {
                        base.Errorf("too many arguments to recover")
@@ -1896,16 +1897,16 @@ func typecheck1(n *Node, top int) (res *Node) {
                        return n
                }
 
-               n.Type = types.Types[TINTER]
+               n.Type = types.Types[types.TINTER]
 
-       case OCLOSURE:
+       case ir.OCLOSURE:
                ok |= ctxExpr
                typecheckclosure(n, top)
                if n.Type == nil {
                        return n
                }
 
-       case OITAB:
+       case ir.OITAB:
                ok |= ctxExpr
                n.Left = typecheck(n.Left, ctxExpr)
                t := n.Left.Type
@@ -1916,14 +1917,14 @@ func typecheck1(n *Node, top int) (res *Node) {
                if !t.IsInterface() {
                        base.Fatalf("OITAB of %v", t)
                }
-               n.Type = types.NewPtr(types.Types[TUINTPTR])
+               n.Type = types.NewPtr(types.Types[types.TUINTPTR])
 
-       case OIDATA:
+       case ir.OIDATA:
                // Whoever creates the OIDATA node must know a priori the concrete type at that moment,
                // usually by just having checked the OITAB.
                base.Fatalf("cannot typecheck interface data %v", n)
 
-       case OSPTR:
+       case ir.OSPTR:
                ok |= ctxExpr
                n.Left = typecheck(n.Left, ctxExpr)
                t := n.Left.Type
@@ -1935,72 +1936,72 @@ func typecheck1(n *Node, top int) (res *Node) {
                        base.Fatalf("OSPTR of %v", t)
                }
                if t.IsString() {
-                       n.Type = types.NewPtr(types.Types[TUINT8])
+                       n.Type = types.NewPtr(types.Types[types.TUINT8])
                } else {
                        n.Type = types.NewPtr(t.Elem())
                }
 
-       case OCLOSUREVAR:
+       case ir.OCLOSUREVAR:
                ok |= ctxExpr
 
-       case OCFUNC:
+       case ir.OCFUNC:
                ok |= ctxExpr
                n.Left = typecheck(n.Left, ctxExpr)
-               n.Type = types.Types[TUINTPTR]
+               n.Type = types.Types[types.TUINTPTR]
 
-       case OCONVNOP:
+       case ir.OCONVNOP:
                ok |= ctxExpr
                n.Left = typecheck(n.Left, ctxExpr)
 
        // statements
-       case OAS:
+       case ir.OAS:
                ok |= ctxStmt
 
                typecheckas(n)
 
                // Code that creates temps does not bother to set defn, so do it here.
-               if n.Left.Op == ONAME && n.Left.IsAutoTmp() {
+               if n.Left.Op == ir.ONAME && n.Left.IsAutoTmp() {
                        n.Left.Name.Defn = n
                }
 
-       case OAS2:
+       case ir.OAS2:
                ok |= ctxStmt
                typecheckas2(n)
 
-       case OBREAK,
-               OCONTINUE,
-               ODCL,
-               OEMPTY,
-               OGOTO,
-               OFALL,
-               OVARKILL,
-               OVARLIVE:
+       case ir.OBREAK,
+               ir.OCONTINUE,
+               ir.ODCL,
+               ir.OEMPTY,
+               ir.OGOTO,
+               ir.OFALL,
+               ir.OVARKILL,
+               ir.OVARLIVE:
                ok |= ctxStmt
 
-       case OLABEL:
+       case ir.OLABEL:
                ok |= ctxStmt
                decldepth++
                if n.Sym.IsBlank() {
                        // Empty identifier is valid but useless.
                        // Eliminate now to simplify life later.
                        // See issues 7538, 11589, 11593.
-                       n.Op = OEMPTY
+                       n.Op = ir.OEMPTY
                        n.Left = nil
                }
 
-       case ODEFER:
+       case ir.ODEFER:
                ok |= ctxStmt
                n.Left = typecheck(n.Left, ctxStmt|ctxExpr)
                if !n.Left.Diag() {
                        checkdefergo(n)
                }
 
-       case OGO:
+       case ir.OGO:
                ok |= ctxStmt
                n.Left = typecheck(n.Left, ctxStmt|ctxExpr)
                checkdefergo(n)
 
-       case OFOR, OFORUNTIL:
+       case ir.OFOR, ir.OFORUNTIL:
                ok |= ctxStmt
                typecheckslice(n.Ninit.Slice(), ctxStmt)
                decldepth++
@@ -2013,13 +2014,13 @@ func typecheck1(n *Node, top int) (res *Node) {
                        }
                }
                n.Right = typecheck(n.Right, ctxStmt)
-               if n.Op == OFORUNTIL {
+               if n.Op == ir.OFORUNTIL {
                        typecheckslice(n.List.Slice(), ctxStmt)
                }
                typecheckslice(n.Nbody.Slice(), ctxStmt)
                decldepth--
 
-       case OIF:
+       case ir.OIF:
                ok |= ctxStmt
                typecheckslice(n.Ninit.Slice(), ctxStmt)
                n.Left = typecheck(n.Left, ctxExpr)
@@ -2033,7 +2034,7 @@ func typecheck1(n *Node, top int) (res *Node) {
                typecheckslice(n.Nbody.Slice(), ctxStmt)
                typecheckslice(n.Rlist.Slice(), ctxStmt)
 
-       case ORETURN:
+       case ir.ORETURN:
                ok |= ctxStmt
                typecheckargs(n)
                if Curfn == nil {
@@ -2045,47 +2046,47 @@ func typecheck1(n *Node, top int) (res *Node) {
                if Curfn.Type.FuncType().Outnamed && n.List.Len() == 0 {
                        break
                }
-               typecheckaste(ORETURN, nil, false, Curfn.Type.Results(), n.List, func() string { return "return argument" })
+               typecheckaste(ir.ORETURN, nil, false, Curfn.Type.Results(), n.List, func() string { return "return argument" })
 
-       case ORETJMP:
+       case ir.ORETJMP:
                ok |= ctxStmt
 
-       case OSELECT:
+       case ir.OSELECT:
                ok |= ctxStmt
                typecheckselect(n)
 
-       case OSWITCH:
+       case ir.OSWITCH:
                ok |= ctxStmt
                typecheckswitch(n)
 
-       case ORANGE:
+       case ir.ORANGE:
                ok |= ctxStmt
                typecheckrange(n)
 
-       case OTYPESW:
+       case ir.OTYPESW:
                base.Errorf("use of .(type) outside type switch")
                n.Type = nil
                return n
 
-       case ODCLFUNC:
+       case ir.ODCLFUNC:
                ok |= ctxStmt
                typecheckfunc(n)
 
-       case ODCLCONST:
+       case ir.ODCLCONST:
                ok |= ctxStmt
                n.Left = typecheck(n.Left, ctxExpr)
 
-       case ODCLTYPE:
+       case ir.ODCLTYPE:
                ok |= ctxStmt
                n.Left = typecheck(n.Left, ctxType)
                checkwidth(n.Left.Type)
        }
 
        t := n.Type
-       if t != nil && !t.IsFuncArgStruct() && n.Op != OTYPE {
+       if t != nil && !t.IsFuncArgStruct() && n.Op != ir.OTYPE {
                switch t.Etype {
-               case TFUNC, // might have TANY; wait until it's called
-                       TANY, TFORW, TIDEAL, TNIL, TBLANK:
+               case types.TFUNC, // might have TANY; wait until it's called
+                       types.TANY, types.TFORW, types.TIDEAL, types.TNIL, types.TBLANK:
                        break
 
                default:
@@ -2094,7 +2095,7 @@ func typecheck1(n *Node, top int) (res *Node) {
        }
 
        n = evalConst(n)
-       if n.Op == OTYPE && top&ctxType == 0 {
+       if n.Op == ir.OTYPE && top&ctxType == 0 {
                if !n.Type.Broke() {
                        base.Errorf("type %v is not an expression", n.Type)
                }
@@ -2102,7 +2103,7 @@ func typecheck1(n *Node, top int) (res *Node) {
                return n
        }
 
-       if top&(ctxExpr|ctxType) == ctxType && n.Op != OTYPE {
+       if top&(ctxExpr|ctxType) == ctxType && n.Op != ir.OTYPE {
                base.Errorf("%v is not a type", n)
                n.Type = nil
                return n
@@ -2128,7 +2129,7 @@ func typecheck1(n *Node, top int) (res *Node) {
        return n
 }
 
-func typecheckargs(n *Node) {
+func typecheckargs(n *ir.Node) {
        if n.List.Len() != 1 || n.IsDDD() {
                typecheckslice(n.List.Slice(), ctxExpr)
                return
@@ -2144,10 +2145,10 @@ func typecheckargs(n *Node) {
 
        // Save n as n.Orig for fmt.go.
        if n.Orig == n {
-               n.Orig = n.sepcopy()
+               n.Orig = ir.SepCopy(n)
        }
 
-       as := nod(OAS2, nil, nil)
+       as := ir.Nod(ir.OAS2, nil, nil)
        as.Rlist.AppendNodes(&n.List)
 
        // If we're outside of function context, then this call will
@@ -2161,7 +2162,7 @@ func typecheckargs(n *Node) {
        }
        for _, f := range t.FieldSlice() {
                t := temp(f.Type)
-               as.Ninit.Append(nod(ODCL, t, nil))
+               as.Ninit.Append(ir.Nod(ir.ODCL, t, nil))
                as.List.Append(t)
                n.List.Append(t)
        }
@@ -2173,7 +2174,7 @@ func typecheckargs(n *Node) {
        n.Ninit.Append(as)
 }
 
-func checksliceindex(l *Node, r *Node, tp *types.Type) bool {
+func checksliceindex(l *ir.Node, r *ir.Node, tp *types.Type) bool {
        t := r.Type
        if t == nil {
                return false
@@ -2183,7 +2184,7 @@ func checksliceindex(l *Node, r *Node, tp *types.Type) bool {
                return false
        }
 
-       if r.Op == OLITERAL {
+       if r.Op == ir.OLITERAL {
                x := r.Val()
                if constant.Sign(x) < 0 {
                        base.Errorf("invalid slice index %v (index must be non-negative)", r)
@@ -2191,10 +2192,10 @@ func checksliceindex(l *Node, r *Node, tp *types.Type) bool {
                } else if tp != nil && tp.NumElem() >= 0 && constant.Compare(x, token.GTR, constant.MakeInt64(tp.NumElem())) {
                        base.Errorf("invalid slice index %v (out of bounds for %d-element array)", r, tp.NumElem())
                        return false
-               } else if Isconst(l, constant.String) && constant.Compare(x, token.GTR, constant.MakeInt64(int64(len(l.StringVal())))) {
+               } else if ir.IsConst(l, constant.String) && constant.Compare(x, token.GTR, constant.MakeInt64(int64(len(l.StringVal())))) {
                        base.Errorf("invalid slice index %v (out of bounds for %d-byte string)", r, len(l.StringVal()))
                        return false
-               } else if doesoverflow(x, types.Types[TINT]) {
+               } else if doesoverflow(x, types.Types[types.TINT]) {
                        base.Errorf("invalid slice index %v (index too large)", r)
                        return false
                }
@@ -2203,8 +2204,8 @@ func checksliceindex(l *Node, r *Node, tp *types.Type) bool {
        return true
 }
 
-func checksliceconst(lo *Node, hi *Node) bool {
-       if lo != nil && hi != nil && lo.Op == OLITERAL && hi.Op == OLITERAL && constant.Compare(lo.Val(), token.GTR, hi.Val()) {
+func checksliceconst(lo *ir.Node, hi *ir.Node) bool {
+       if lo != nil && hi != nil && lo.Op == ir.OLITERAL && hi.Op == ir.OLITERAL && constant.Compare(lo.Val(), token.GTR, hi.Val()) {
                base.Errorf("invalid slice index: %v > %v", lo, hi)
                return false
        }
@@ -2212,39 +2213,39 @@ func checksliceconst(lo *Node, hi *Node) bool {
        return true
 }
 
-func checkdefergo(n *Node) {
+func checkdefergo(n *ir.Node) {
        what := "defer"
-       if n.Op == OGO {
+       if n.Op == ir.OGO {
                what = "go"
        }
 
        switch n.Left.Op {
        // ok
-       case OCALLINTER,
-               OCALLMETH,
-               OCALLFUNC,
-               OCLOSE,
-               OCOPY,
-               ODELETE,
-               OPANIC,
-               OPRINT,
-               OPRINTN,
-               ORECOVER:
+       case ir.OCALLINTER,
+               ir.OCALLMETH,
+               ir.OCALLFUNC,
+               ir.OCLOSE,
+               ir.OCOPY,
+               ir.ODELETE,
+               ir.OPANIC,
+               ir.OPRINT,
+               ir.OPRINTN,
+               ir.ORECOVER:
                return
 
-       case OAPPEND,
-               OCAP,
-               OCOMPLEX,
-               OIMAG,
-               OLEN,
-               OMAKE,
-               OMAKESLICE,
-               OMAKECHAN,
-               OMAKEMAP,
-               ONEW,
-               OREAL,
-               OLITERAL: // conversion or unsafe.Alignof, Offsetof, Sizeof
-               if n.Left.Orig != nil && n.Left.Orig.Op == OCONV {
+       case ir.OAPPEND,
+               ir.OCAP,
+               ir.OCOMPLEX,
+               ir.OIMAG,
+               ir.OLEN,
+               ir.OMAKE,
+               ir.OMAKESLICE,
+               ir.OMAKECHAN,
+               ir.OMAKEMAP,
+               ir.ONEW,
+               ir.OREAL,
+               ir.OLITERAL: // conversion or unsafe.Alignof, Offsetof, Sizeof
+               if n.Left.Orig != nil && n.Left.Orig.Op == ir.OCONV {
                        break
                }
                base.ErrorfAt(n.Pos, "%s discards result of %v", what, n.Left)
@@ -2267,7 +2268,7 @@ func checkdefergo(n *Node) {
 
 // The result of implicitstar MUST be assigned back to n, e.g.
 //     n.Left = implicitstar(n.Left)
-func implicitstar(n *Node) *Node {
+func implicitstar(n *ir.Node) *ir.Node {
        // insert implicit * if needed for fixed array
        t := n.Type
        if t == nil || !t.IsPtr() {
@@ -2280,13 +2281,13 @@ func implicitstar(n *Node) *Node {
        if !t.IsArray() {
                return n
        }
-       n = nod(ODEREF, n, nil)
+       n = ir.Nod(ir.ODEREF, n, nil)
        n.SetImplicit(true)
        n = typecheck(n, ctxExpr)
        return n
 }
 
-func onearg(n *Node, f string, args ...interface{}) bool {
+func onearg(n *ir.Node, f string, args ...interface{}) bool {
        if n.Left != nil {
                return true
        }
@@ -2309,7 +2310,7 @@ func onearg(n *Node, f string, args ...interface{}) bool {
        return true
 }
 
-func twoarg(n *Node) bool {
+func twoarg(n *ir.Node) bool {
        if n.Left != nil {
                return true
        }
@@ -2327,7 +2328,7 @@ func twoarg(n *Node) bool {
        return true
 }
 
-func lookdot1(errnode *Node, s *types.Sym, t *types.Type, fs *types.Fields, dostrcmp int) *types.Field {
+func lookdot1(errnode *ir.Node, s *types.Sym, t *types.Type, fs *types.Fields, dostrcmp int) *types.Field {
        var r *types.Field
        for _, f := range fs.Slice() {
                if dostrcmp != 0 && f.Sym.Name == s.Name {
@@ -2358,7 +2359,7 @@ func lookdot1(errnode *Node, s *types.Sym, t *types.Type, fs *types.Fields, dost
 
 // typecheckMethodExpr checks selector expressions (ODOT) where the
 // base expression is a type expression (OTYPE).
-func typecheckMethodExpr(n *Node) (res *Node) {
+func typecheckMethodExpr(n *ir.Node) (res *ir.Node) {
        if enableTrace && base.Flag.LowerT {
                defer tracePrint("typecheckMethodExpr", n)(&res)
        }
@@ -2411,20 +2412,20 @@ func typecheckMethodExpr(n *Node) (res *Node) {
                return n
        }
 
-       n.Op = OMETHEXPR
+       n.Op = ir.OMETHEXPR
        if n.Name == nil {
-               n.Name = new(Name)
+               n.Name = new(ir.Name)
        }
-       n.Right = newname(n.Sym)
+       n.Right = NewName(n.Sym)
        n.Sym = methodSym(t, n.Sym)
        n.Type = methodfunc(m.Type, n.Left.Type)
        n.Xoffset = 0
-       n.SetClass(PFUNC)
+       n.SetClass(ir.PFUNC)
        n.SetOpt(m)
        // methodSym already marked n.Sym as a function.
 
        // Issue 25065. Make sure that we emit the symbol for a local method.
-       if base.Ctxt.Flag_dynlink && !inimport && (t.Sym == nil || t.Sym.Pkg == localpkg) {
+       if base.Ctxt.Flag_dynlink && !inimport && (t.Sym == nil || t.Sym.Pkg == ir.LocalPkg) {
                makefuncsym(n.Sym)
        }
 
@@ -2446,7 +2447,7 @@ func derefall(t *types.Type) *types.Type {
        return t
 }
 
-func lookdot(n *Node, t *types.Type, dostrcmp int) *types.Field {
+func lookdot(n *ir.Node, t *types.Type, dostrcmp int) *types.Field {
        s := n.Sym
 
        dowidth(t)
@@ -2471,19 +2472,19 @@ func lookdot(n *Node, t *types.Type, dostrcmp int) *types.Field {
                if f2 != nil {
                        base.Errorf("%v is both field and method", n.Sym)
                }
-               if f1.Offset == BADWIDTH {
+               if f1.Offset == types.BADWIDTH {
                        base.Fatalf("lookdot badwidth %v %p", f1, f1)
                }
                n.Xoffset = f1.Offset
                n.Type = f1.Type
                if t.IsInterface() {
                        if n.Left.Type.IsPtr() {
-                               n.Left = nod(ODEREF, n.Left, nil) // implicitstar
+                               n.Left = ir.Nod(ir.ODEREF, n.Left, nil) // implicitstar
                                n.Left.SetImplicit(true)
                                n.Left = typecheck(n.Left, ctxExpr)
                        }
 
-                       n.Op = ODOTINTER
+                       n.Op = ir.ODOTINTER
                } else {
                        n.SetOpt(f1)
                }
@@ -2502,11 +2503,11 @@ func lookdot(n *Node, t *types.Type, dostrcmp int) *types.Field {
                if !types.Identical(rcvr, tt) {
                        if rcvr.IsPtr() && types.Identical(rcvr.Elem(), tt) {
                                checklvalue(n.Left, "call pointer method on")
-                               n.Left = nod(OADDR, n.Left, nil)
+                               n.Left = ir.Nod(ir.OADDR, n.Left, nil)
                                n.Left.SetImplicit(true)
                                n.Left = typecheck(n.Left, ctxType|ctxExpr)
                        } else if tt.IsPtr() && (!rcvr.IsPtr() || rcvr.IsPtr() && rcvr.Elem().NotInHeap()) && types.Identical(tt.Elem(), rcvr) {
-                               n.Left = nod(ODEREF, n.Left, nil)
+                               n.Left = ir.Nod(ir.ODEREF, n.Left, nil)
                                n.Left.SetImplicit(true)
                                n.Left = typecheck(n.Left, ctxType|ctxExpr)
                        } else if tt.IsPtr() && tt.Elem().IsPtr() && types.Identical(derefall(tt), derefall(rcvr)) {
@@ -2516,7 +2517,7 @@ func lookdot(n *Node, t *types.Type, dostrcmp int) *types.Field {
                                        if rcvr.IsPtr() && !tt.Elem().IsPtr() {
                                                break
                                        }
-                                       n.Left = nod(ODEREF, n.Left, nil)
+                                       n.Left = ir.Nod(ir.ODEREF, n.Left, nil)
                                        n.Left.SetImplicit(true)
                                        n.Left = typecheck(n.Left, ctxType|ctxExpr)
                                        tt = tt.Elem()
@@ -2528,11 +2529,11 @@ func lookdot(n *Node, t *types.Type, dostrcmp int) *types.Field {
 
                pll := n
                ll := n.Left
-               for ll.Left != nil && (ll.Op == ODOT || ll.Op == ODOTPTR || ll.Op == ODEREF) {
+               for ll.Left != nil && (ll.Op == ir.ODOT || ll.Op == ir.ODOTPTR || ll.Op == ir.ODEREF) {
                        pll = ll
                        ll = ll.Left
                }
-               if pll.Implicit() && ll.Type.IsPtr() && ll.Type.Sym != nil && asNode(ll.Type.Sym.Def) != nil && asNode(ll.Type.Sym.Def).Op == OTYPE {
+               if pll.Implicit() && ll.Type.IsPtr() && ll.Type.Sym != nil && ir.AsNode(ll.Type.Sym.Def) != nil && ir.AsNode(ll.Type.Sym.Def).Op == ir.OTYPE {
                        // It is invalid to automatically dereference a named pointer type when selecting a method.
                        // Make n.Left == ll to clarify error message.
                        n.Left = ll
@@ -2542,7 +2543,7 @@ func lookdot(n *Node, t *types.Type, dostrcmp int) *types.Field {
                n.Sym = methodSym(n.Left.Type, f2.Sym)
                n.Xoffset = f2.Offset
                n.Type = f2.Type
-               n.Op = ODOTMETH
+               n.Op = ir.ODOTMETH
                n.SetOpt(f2)
 
                return f2
@@ -2551,9 +2552,9 @@ func lookdot(n *Node, t *types.Type, dostrcmp int) *types.Field {
        return nil
 }
 
-func nokeys(l Nodes) bool {
+func nokeys(l ir.Nodes) bool {
        for _, n := range l.Slice() {
-               if n.Op == OKEY || n.Op == OSTRUCTKEY {
+               if n.Op == ir.OKEY || n.Op == ir.OSTRUCTKEY {
                        return false
                }
        }
@@ -2571,7 +2572,7 @@ func hasddd(t *types.Type) bool {
 }
 
 // typecheck assignment: type list = expression list
-func typecheckaste(op Op, call *Node, isddd bool, tstruct *types.Type, nl Nodes, desc func() string) {
+func typecheckaste(op ir.Op, call *ir.Node, isddd bool, tstruct *types.Type, nl ir.Nodes, desc func() string) {
        var t *types.Type
        var i int
 
@@ -2582,7 +2583,7 @@ func typecheckaste(op Op, call *Node, isddd bool, tstruct *types.Type, nl Nodes,
                return
        }
 
-       var n *Node
+       var n *ir.Node
        if nl.Len() == 1 {
                n = nl.First()
        }
@@ -2671,7 +2672,7 @@ notenough:
                        // call is the expression being called, not the overall call.
                        // Method expressions have the form T.M, and the compiler has
                        // rewritten those to ONAME nodes but left T in Left.
-                       if call.Op == OMETHEXPR {
+                       if call.Op == ir.OMETHEXPR {
                                base.Errorf("not enough arguments in call to method expression %v%s", call, details)
                        } else {
                                base.Errorf("not enough arguments in call to %v%s", call, details)
@@ -2694,7 +2695,7 @@ toomany:
        }
 }
 
-func errorDetails(nl Nodes, tstruct *types.Type, isddd bool) string {
+func errorDetails(nl ir.Nodes, tstruct *types.Type, isddd bool) string {
        // If we don't know any type at a call site, let's suppress any return
        // message signatures. See Issue https://golang.org/issues/19012.
        if tstruct == nil {
@@ -2706,7 +2707,7 @@ func errorDetails(nl Nodes, tstruct *types.Type, isddd bool) string {
                        return ""
                }
        }
-       return fmt.Sprintf("\n\thave %s\n\twant %v", nl.sigerr(isddd), tstruct)
+       return fmt.Sprintf("\n\thave %s\n\twant %v", fmtSignature(nl, isddd), tstruct)
 }
 
 // sigrepr is a type's representation to the outside world,
@@ -2720,7 +2721,7 @@ func sigrepr(t *types.Type, isddd bool) string {
                return "bool"
        }
 
-       if t.Etype == TIDEAL {
+       if t.Etype == types.TIDEAL {
                // "untyped number" is not commonly used
                // outside of the compiler, so let's use "number".
                // TODO(mdempsky): Revisit this.
@@ -2738,7 +2739,7 @@ func sigrepr(t *types.Type, isddd bool) string {
 }
 
 // sigerr returns the signature of the types at the call or return.
-func (nl Nodes) sigerr(isddd bool) string {
+func fmtSignature(nl ir.Nodes, isddd bool) string {
        if nl.Len() < 1 {
                return "()"
        }
@@ -2764,7 +2765,7 @@ func fielddup(name string, hash map[string]bool) {
 // iscomptype reports whether type t is a composite literal type.
 func iscomptype(t *types.Type) bool {
        switch t.Etype {
-       case TARRAY, TSLICE, TSTRUCT, TMAP:
+       case types.TARRAY, types.TSLICE, types.TSTRUCT, types.TMAP:
                return true
        default:
                return false
@@ -2773,8 +2774,8 @@ func iscomptype(t *types.Type) bool {
 
 // pushtype adds elided type information for composite literals if
 // appropriate, and returns the resulting expression.
-func pushtype(n *Node, t *types.Type) *Node {
-       if n == nil || n.Op != OCOMPLIT || n.Right != nil {
+func pushtype(n *ir.Node, t *types.Type) *ir.Node {
+       if n == nil || n.Op != ir.OCOMPLIT || n.Right != nil {
                return n
        }
 
@@ -2787,7 +2788,7 @@ func pushtype(n *Node, t *types.Type) *Node {
                // For *T, return &T{...}.
                n.Right = typenod(t.Elem())
 
-               n = nodl(n.Pos, OADDR, n, nil)
+               n = ir.NodAt(n.Pos, ir.OADDR, n, nil)
                n.SetImplicit(true)
        }
 
@@ -2796,7 +2797,7 @@ func pushtype(n *Node, t *types.Type) *Node {
 
 // The result of typecheckcomplit MUST be assigned back to n, e.g.
 //     n.Left = typecheckcomplit(n.Left)
-func typecheckcomplit(n *Node) (res *Node) {
+func typecheckcomplit(n *ir.Node) (res *ir.Node) {
        if enableTrace && base.Flag.LowerT {
                defer tracePrint("typecheckcomplit", n)(&res)
        }
@@ -2813,12 +2814,12 @@ func typecheckcomplit(n *Node) (res *Node) {
        }
 
        // Save original node (including n.Right)
-       n.Orig = n.copy()
+       n.Orig = ir.Copy(n)
 
        setlineno(n.Right)
 
        // Need to handle [...]T arrays specially.
-       if n.Right.Op == OTARRAY && n.Right.Left != nil && n.Right.Left.Op == ODDD {
+       if n.Right.Op == ir.OTARRAY && n.Right.Left != nil && n.Right.Left.Op == ir.ODDD {
                n.Right.Right = typecheck(n.Right.Right, ctxType)
                if n.Right.Right.Type == nil {
                        n.Type = nil
@@ -2828,7 +2829,7 @@ func typecheckcomplit(n *Node) (res *Node) {
 
                length := typecheckarraylit(elemType, -1, n.List.Slice(), "array literal")
 
-               n.Op = OARRAYLIT
+               n.Op = ir.OARRAYLIT
                n.Type = types.NewArray(elemType, length)
                n.Right = nil
                return n
@@ -2847,21 +2848,21 @@ func typecheckcomplit(n *Node) (res *Node) {
                base.Errorf("invalid composite literal type %v", t)
                n.Type = nil
 
-       case TARRAY:
+       case types.TARRAY:
                typecheckarraylit(t.Elem(), t.NumElem(), n.List.Slice(), "array literal")
-               n.Op = OARRAYLIT
+               n.Op = ir.OARRAYLIT
                n.Right = nil
 
-       case TSLICE:
+       case types.TSLICE:
                length := typecheckarraylit(t.Elem(), -1, n.List.Slice(), "slice literal")
-               n.Op = OSLICELIT
+               n.Op = ir.OSLICELIT
                n.Right = nodintconst(length)
 
-       case TMAP:
+       case types.TMAP:
                var cs constSet
                for i3, l := range n.List.Slice() {
                        setlineno(l)
-                       if l.Op != OKEY {
+                       if l.Op != ir.OKEY {
                                n.List.SetIndex(i3, typecheck(l, ctxExpr))
                                base.Errorf("missing key in map literal")
                                continue
@@ -2879,10 +2880,10 @@ func typecheckcomplit(n *Node) (res *Node) {
                        l.Right = assignconv(r, t.Elem(), "map value")
                }
 
-               n.Op = OMAPLIT
+               n.Op = ir.OMAPLIT
                n.Right = nil
 
-       case TSTRUCT:
+       case types.TSTRUCT:
                // Need valid field offsets for Xoffset below.
                dowidth(t)
 
@@ -2904,12 +2905,12 @@ func typecheckcomplit(n *Node) (res *Node) {
 
                                f := t.Field(i)
                                s := f.Sym
-                               if s != nil && !types.IsExported(s.Name) && s.Pkg != localpkg {
+                               if s != nil && !types.IsExported(s.Name) && s.Pkg != ir.LocalPkg {
                                        base.Errorf("implicit assignment of unexported field '%s' in %v literal", s.Name, t)
                                }
                                // No pushtype allowed here. Must name fields for that.
                                n1 = assignconv(n1, f.Type, "field value")
-                               n1 = nodSym(OSTRUCTKEY, n1, f.Sym)
+                               n1 = nodSym(ir.OSTRUCTKEY, n1, f.Sym)
                                n1.Xoffset = f.Offset
                                ls[i] = n1
                        }
@@ -2924,10 +2925,10 @@ func typecheckcomplit(n *Node) (res *Node) {
                        for i, l := range ls {
                                setlineno(l)
 
-                               if l.Op == OKEY {
+                               if l.Op == ir.OKEY {
                                        key := l.Left
 
-                                       l.Op = OSTRUCTKEY
+                                       l.Op = ir.OSTRUCTKEY
                                        l.Left = l.Right
                                        l.Right = nil
 
@@ -2935,7 +2936,7 @@ func typecheckcomplit(n *Node) (res *Node) {
                                        // the field to the right of the dot,
                                        // so s will be non-nil, but an OXDOT
                                        // is never a valid struct literal key.
-                                       if key.Sym == nil || key.Op == OXDOT || key.Sym.IsBlank() {
+                                       if key.Sym == nil || key.Op == ir.OXDOT || key.Sym.IsBlank() {
                                                base.Errorf("invalid field name %v in struct initializer", key)
                                                l.Left = typecheck(l.Left, ctxExpr)
                                                continue
@@ -2945,7 +2946,7 @@ func typecheckcomplit(n *Node) (res *Node) {
                                        // package, because of import dot. Redirect to correct sym
                                        // before we do the lookup.
                                        s := key.Sym
-                                       if s.Pkg != localpkg && types.IsExported(s.Name) {
+                                       if s.Pkg != ir.LocalPkg && types.IsExported(s.Name) {
                                                s1 := lookup(s.Name)
                                                if s1.Origpkg == s.Pkg {
                                                        s = s1
@@ -2954,7 +2955,7 @@ func typecheckcomplit(n *Node) (res *Node) {
                                        l.Sym = s
                                }
 
-                               if l.Op != OSTRUCTKEY {
+                               if l.Op != ir.OSTRUCTKEY {
                                        if !errored {
                                                base.Errorf("mixture of field:value and value initializers")
                                                errored = true
@@ -2999,7 +3000,7 @@ func typecheckcomplit(n *Node) (res *Node) {
                        }
                }
 
-               n.Op = OSTRUCTLIT
+               n.Op = ir.OSTRUCTLIT
                n.Right = nil
        }
 
@@ -3007,12 +3008,12 @@ func typecheckcomplit(n *Node) (res *Node) {
 }
 
 // typecheckarraylit type-checks a sequence of slice/array literal elements.
-func typecheckarraylit(elemType *types.Type, bound int64, elts []*Node, ctx string) int64 {
+func typecheckarraylit(elemType *types.Type, bound int64, elts []*ir.Node, ctx string) int64 {
        // If there are key/value pairs, create a map to keep seen
        // keys so we can check for duplicate indices.
        var indices map[int64]bool
        for _, elt := range elts {
-               if elt.Op == OKEY {
+               if elt.Op == ir.OKEY {
                        indices = make(map[int64]bool)
                        break
                }
@@ -3022,8 +3023,8 @@ func typecheckarraylit(elemType *types.Type, bound int64, elts []*Node, ctx stri
        for i, elt := range elts {
                setlineno(elt)
                r := elts[i]
-               var kv *Node
-               if elt.Op == OKEY {
+               var kv *ir.Node
+               if elt.Op == ir.OKEY {
                        elt.Left = typecheck(elt.Left, ctxExpr)
                        key = indexconst(elt.Left)
                        if key < 0 {
@@ -3076,7 +3077,7 @@ func typecheckarraylit(elemType *types.Type, bound int64, elts []*Node, ctx stri
 
 // visible reports whether sym is exported or locally defined.
 func visible(sym *types.Sym) bool {
-       return sym != nil && (types.IsExported(sym.Name) || sym.Pkg == localpkg)
+       return sym != nil && (types.IsExported(sym.Name) || sym.Pkg == ir.LocalPkg)
 }
 
 // nonexported reports whether sym is an unexported field.
@@ -3085,9 +3086,9 @@ func nonexported(sym *types.Sym) bool {
 }
 
 // lvalue etc
-func islvalue(n *Node) bool {
+func islvalue(n *ir.Node) bool {
        switch n.Op {
-       case OINDEX:
+       case ir.OINDEX:
                if n.Left.Type != nil && n.Left.Type.IsArray() {
                        return islvalue(n.Left)
                }
@@ -3095,14 +3096,14 @@ func islvalue(n *Node) bool {
                        return false
                }
                fallthrough
-       case ODEREF, ODOTPTR, OCLOSUREVAR:
+       case ir.ODEREF, ir.ODOTPTR, ir.OCLOSUREVAR:
                return true
 
-       case ODOT:
+       case ir.ODOT:
                return islvalue(n.Left)
 
-       case ONAME:
-               if n.Class() == PFUNC {
+       case ir.ONAME:
+               if n.Class() == ir.PFUNC {
                        return false
                }
                return true
@@ -3111,17 +3112,17 @@ func islvalue(n *Node) bool {
        return false
 }
 
-func checklvalue(n *Node, verb string) {
+func checklvalue(n *ir.Node, verb string) {
        if !islvalue(n) {
                base.Errorf("cannot %s %v", verb, n)
        }
 }
 
-func checkassign(stmt *Node, n *Node) {
+func checkassign(stmt *ir.Node, n *ir.Node) {
        // Variables declared in ORANGE are assigned on every iteration.
-       if n.Name == nil || n.Name.Defn != stmt || stmt.Op == ORANGE {
+       if n.Name == nil || n.Name.Defn != stmt || stmt.Op == ir.ORANGE {
                r := outervalue(n)
-               if r.Op == ONAME {
+               if r.Op == ir.ONAME {
                        r.Name.SetAssigned(true)
                        if r.Name.IsClosureVar() {
                                r.Name.Defn.Name.SetAssigned(true)
@@ -3132,7 +3133,7 @@ func checkassign(stmt *Node, n *Node) {
        if islvalue(n) {
                return
        }
-       if n.Op == OINDEXMAP {
+       if n.Op == ir.OINDEXMAP {
                n.SetIndexMapLValue(true)
                return
        }
@@ -3143,11 +3144,11 @@ func checkassign(stmt *Node, n *Node) {
        }
 
        switch {
-       case n.Op == ODOT && n.Left.Op == OINDEXMAP:
+       case n.Op == ir.ODOT && n.Left.Op == ir.OINDEXMAP:
                base.Errorf("cannot assign to struct field %v in map", n)
-       case (n.Op == OINDEX && n.Left.Type.IsString()) || n.Op == OSLICESTR:
+       case (n.Op == ir.OINDEX && n.Left.Type.IsString()) || n.Op == ir.OSLICESTR:
                base.Errorf("cannot assign to %v (strings are immutable)", n)
-       case n.Op == OLITERAL && n.Sym != nil && n.isGoConst():
+       case n.Op == ir.OLITERAL && n.Sym != nil && isGoConst(n):
                base.Errorf("cannot assign to %v (declared const)", n)
        default:
                base.Errorf("cannot assign to %v", n)
@@ -3155,7 +3156,7 @@ func checkassign(stmt *Node, n *Node) {
        n.Type = nil
 }
 
-func checkassignlist(stmt *Node, l Nodes) {
+func checkassignlist(stmt *ir.Node, l ir.Nodes) {
        for _, n := range l.Slice() {
                checkassign(stmt, n)
        }
@@ -3176,35 +3177,35 @@ func checkassignlist(stmt *Node, l Nodes) {
 // currently OK, since the only place samesafeexpr gets used on an
 // lvalue expression is for OSLICE and OAPPEND optimizations, and it
 // is correct in those settings.
-func samesafeexpr(l *Node, r *Node) bool {
+func samesafeexpr(l *ir.Node, r *ir.Node) bool {
        if l.Op != r.Op || !types.Identical(l.Type, r.Type) {
                return false
        }
 
        switch l.Op {
-       case ONAME, OCLOSUREVAR:
+       case ir.ONAME, ir.OCLOSUREVAR:
                return l == r
 
-       case ODOT, ODOTPTR:
+       case ir.ODOT, ir.ODOTPTR:
                return l.Sym != nil && r.Sym != nil && l.Sym == r.Sym && samesafeexpr(l.Left, r.Left)
 
-       case ODEREF, OCONVNOP,
-               ONOT, OBITNOT, OPLUS, ONEG:
+       case ir.ODEREF, ir.OCONVNOP,
+               ir.ONOT, ir.OBITNOT, ir.OPLUS, ir.ONEG:
                return samesafeexpr(l.Left, r.Left)
 
-       case OCONV:
+       case ir.OCONV:
                // Some conversions can't be reused, such as []byte(str).
                // Allow only numeric-ish types. This is a bit conservative.
                return issimple[l.Type.Etype] && samesafeexpr(l.Left, r.Left)
 
-       case OINDEX, OINDEXMAP,
-               OADD, OSUB, OOR, OXOR, OMUL, OLSH, ORSH, OAND, OANDNOT, ODIV, OMOD:
+       case ir.OINDEX, ir.OINDEXMAP,
+               ir.OADD, ir.OSUB, ir.OOR, ir.OXOR, ir.OMUL, ir.OLSH, ir.ORSH, ir.OAND, ir.OANDNOT, ir.ODIV, ir.OMOD:
                return samesafeexpr(l.Left, r.Left) && samesafeexpr(l.Right, r.Right)
 
-       case OLITERAL:
+       case ir.OLITERAL:
                return constant.Compare(l.Val(), token.EQL, r.Val())
 
-       case ONIL:
+       case ir.ONIL:
                return true
        }
 
@@ -3214,7 +3215,7 @@ func samesafeexpr(l *Node, r *Node) bool {
 // type check assignment.
 // if this assignment is the definition of a var on the left side,
 // fill in the var's type.
-func typecheckas(n *Node) {
+func typecheckas(n *ir.Node) {
        if enableTrace && base.Flag.LowerT {
                defer tracePrint("typecheckas", n)(nil)
        }
@@ -3260,19 +3261,19 @@ func typecheckas(n *Node) {
        if n.Left.Typecheck() == 0 {
                n.Left = typecheck(n.Left, ctxExpr|ctxAssign)
        }
-       if !n.Left.isBlank() {
+       if !ir.IsBlank(n.Left) {
                checkwidth(n.Left.Type) // ensure width is calculated for backend
        }
 }
 
-func checkassignto(src *types.Type, dst *Node) {
-       if op, why := assignop(src, dst.Type); op == OXXX {
+func checkassignto(src *types.Type, dst *ir.Node) {
+       if op, why := assignop(src, dst.Type); op == ir.OXXX {
                base.Errorf("cannot assign %v to %L in multiple assignment%s", src, dst, why)
                return
        }
 }
 
-func typecheckas2(n *Node) {
+func typecheckas2(n *ir.Node) {
        if enableTrace && base.Flag.LowerT {
                defer tracePrint("typecheckas2", n)(nil)
        }
@@ -3297,8 +3298,8 @@ func typecheckas2(n *Node) {
        }
        checkassignlist(n, n.List)
 
-       var l *Node
-       var r *Node
+       var l *ir.Node
+       var r *ir.Node
        if cl == cr {
                // easy
                ls := n.List.Slice()
@@ -3326,7 +3327,7 @@ func typecheckas2(n *Node) {
                        goto out
                }
                switch r.Op {
-               case OCALLMETH, OCALLINTER, OCALLFUNC:
+               case ir.OCALLMETH, ir.OCALLINTER, ir.OCALLFUNC:
                        if !r.Type.IsFuncArgStruct() {
                                break
                        }
@@ -3334,7 +3335,7 @@ func typecheckas2(n *Node) {
                        if cr != cl {
                                goto mismatch
                        }
-                       n.Op = OAS2FUNC
+                       n.Op = ir.OAS2FUNC
                        n.Right = r
                        n.Rlist.Set(nil)
                        for i, l := range n.List.Slice() {
@@ -3356,15 +3357,15 @@ func typecheckas2(n *Node) {
                        goto out
                }
                switch r.Op {
-               case OINDEXMAP, ORECV, ODOTTYPE:
+               case ir.OINDEXMAP, ir.ORECV, ir.ODOTTYPE:
                        switch r.Op {
-                       case OINDEXMAP:
-                               n.Op = OAS2MAPR
-                       case ORECV:
-                               n.Op = OAS2RECV
-                       case ODOTTYPE:
-                               n.Op = OAS2DOTTYPE
-                               r.Op = ODOTTYPE2
+                       case ir.OINDEXMAP:
+                               n.Op = ir.OAS2MAPR
+                       case ir.ORECV:
+                               n.Op = ir.OAS2RECV
+                       case ir.ODOTTYPE:
+                               n.Op = ir.OAS2DOTTYPE
+                               r.Op = ir.ODOTTYPE2
                        }
                        n.Right = r
                        n.Rlist.Set(nil)
@@ -3376,10 +3377,10 @@ func typecheckas2(n *Node) {
                        }
                        l := n.List.Second()
                        if l.Type != nil && !l.Type.IsBoolean() {
-                               checkassignto(types.Types[TBOOL], l)
+                               checkassignto(types.Types[types.TBOOL], l)
                        }
                        if l.Name != nil && l.Name.Defn == n && l.Name.Param.Ntype == nil {
-                               l.Type = types.Types[TBOOL]
+                               l.Type = types.Types[types.TBOOL]
                        }
                        goto out
                }
@@ -3389,7 +3390,7 @@ mismatch:
        switch r.Op {
        default:
                base.Errorf("assignment mismatch: %d variables but %d values", cl, cr)
-       case OCALLFUNC, OCALLMETH, OCALLINTER:
+       case ir.OCALLFUNC, ir.OCALLMETH, ir.OCALLINTER:
                base.Errorf("assignment mismatch: %d variables but %v returns %d values", cl, r.Left, cr)
        }
 
@@ -3405,13 +3406,13 @@ out:
 }
 
 // type check function definition
-func typecheckfunc(n *Node) {
+func typecheckfunc(n *ir.Node) {
        if enableTrace && base.Flag.LowerT {
                defer tracePrint("typecheckfunc", n)(nil)
        }
 
        for _, ln := range n.Func.Dcl {
-               if ln.Op == ONAME && (ln.Class() == PPARAM || ln.Class() == PPARAMOUT) {
+               if ln.Op == ir.ONAME && (ln.Class() == ir.PPARAM || ln.Class() == ir.PPARAMOUT) {
                        ln.Name.Decldepth = 1
                }
        }
@@ -3424,13 +3425,13 @@ func typecheckfunc(n *Node) {
        n.Type = t
        rcvr := t.Recv()
        if rcvr != nil && n.Func.Shortname != nil {
-               m := addmethod(n, n.Func.Shortname, t, true, n.Func.Pragma&Nointerface != 0)
+               m := addmethod(n, n.Func.Shortname, t, true, n.Func.Pragma&ir.Nointerface != 0)
                if m == nil {
                        return
                }
 
                n.Func.Nname.Sym = methodSym(rcvr.Type, n.Func.Shortname)
-               declare(n.Func.Nname, PFUNC)
+               declare(n.Func.Nname, ir.PFUNC)
        }
 
        if base.Ctxt.Flag_dynlink && !inimport && n.Func.Nname != nil {
@@ -3440,25 +3441,25 @@ func typecheckfunc(n *Node) {
 
 // The result of stringtoruneslit MUST be assigned back to n, e.g.
 //     n.Left = stringtoruneslit(n.Left)
-func stringtoruneslit(n *Node) *Node {
-       if n.Left.Op != OLITERAL || n.Left.Val().Kind() != constant.String {
+func stringtoruneslit(n *ir.Node) *ir.Node {
+       if n.Left.Op != ir.OLITERAL || n.Left.Val().Kind() != constant.String {
                base.Fatalf("stringtoarraylit %v", n)
        }
 
-       var l []*Node
+       var l []*ir.Node
        i := 0
        for _, r := range n.Left.StringVal() {
-               l = append(l, nod(OKEY, nodintconst(int64(i)), nodintconst(int64(r))))
+               l = append(l, ir.Nod(ir.OKEY, nodintconst(int64(i)), nodintconst(int64(r))))
                i++
        }
 
-       nn := nod(OCOMPLIT, nil, typenod(n.Type))
+       nn := ir.Nod(ir.OCOMPLIT, nil, typenod(n.Type))
        nn.List.Set(l)
        nn = typecheck(nn, ctxExpr)
        return nn
 }
 
-var mapqueue []*Node
+var mapqueue []*ir.Node
 
 func checkMapKeys() {
        for _, n := range mapqueue {
@@ -3471,13 +3472,13 @@ func checkMapKeys() {
 }
 
 func setUnderlying(t, underlying *types.Type) {
-       if underlying.Etype == TFORW {
+       if underlying.Etype == types.TFORW {
                // This type isn't computed yet; when it is, update n.
                underlying.ForwardType().Copyto = append(underlying.ForwardType().Copyto, t)
                return
        }
 
-       n := asNode(t.Nod)
+       n := ir.AsNode(t.Nod)
        ft := t.ForwardType()
        cache := t.Cache
 
@@ -3485,7 +3486,7 @@ func setUnderlying(t, underlying *types.Type) {
        *t = *underlying
 
        // Restore unnecessarily clobbered attributes.
-       t.Nod = asTypesNode(n)
+       t.Nod = ir.AsTypesNode(n)
        t.Sym = n.Sym
        if n.Name != nil {
                t.Vargen = n.Name.Vargen
@@ -3502,7 +3503,7 @@ func setUnderlying(t, underlying *types.Type) {
        }
 
        // Propagate go:notinheap pragma from the Name to the Type.
-       if n.Name != nil && n.Name.Param != nil && n.Name.Param.Pragma()&NotInHeap != 0 {
+       if n.Name != nil && n.Name.Param != nil && n.Name.Param.Pragma()&ir.NotInHeap != 0 {
                t.SetNotInHeap(true)
        }
 
@@ -3519,7 +3520,7 @@ func setUnderlying(t, underlying *types.Type) {
        }
 }
 
-func typecheckdeftype(n *Node) {
+func typecheckdeftype(n *ir.Node) {
        if enableTrace && base.Flag.LowerT {
                defer tracePrint("typecheckdeftype", n)(nil)
        }
@@ -3539,14 +3540,14 @@ func typecheckdeftype(n *Node) {
        }
 }
 
-func typecheckdef(n *Node) {
+func typecheckdef(n *ir.Node) {
        if enableTrace && base.Flag.LowerT {
                defer tracePrint("typecheckdef", n)(nil)
        }
 
        lno := setlineno(n)
 
-       if n.Op == ONONAME {
+       if n.Op == ir.ONONAME {
                if !n.Diag() {
                        n.SetDiag(true)
 
@@ -3585,7 +3586,7 @@ func typecheckdef(n *Node) {
        default:
                base.Fatalf("typecheckdef %v", n.Op)
 
-       case OLITERAL:
+       case ir.OLITERAL:
                if n.Name.Param.Ntype != nil {
                        n.Name.Param.Ntype = typecheck(n.Name.Param.Ntype, ctxType)
                        n.Type = n.Name.Param.Ntype.Type
@@ -3599,7 +3600,7 @@ func typecheckdef(n *Node) {
                e := n.Name.Defn
                n.Name.Defn = nil
                if e == nil {
-                       Dump("typecheckdef nil defn", n)
+                       ir.Dump("typecheckdef nil defn", n)
                        base.ErrorfAt(n.Pos, "xxx")
                }
 
@@ -3607,9 +3608,9 @@ func typecheckdef(n *Node) {
                if e.Type == nil {
                        goto ret
                }
-               if !e.isGoConst() {
+               if !isGoConst(e) {
                        if !e.Diag() {
-                               if e.Op == ONIL {
+                               if e.Op == ir.ONIL {
                                        base.ErrorfAt(n.Pos, "const initializer cannot be nil")
                                } else {
                                        base.ErrorfAt(n.Pos, "const initializer %v is not a constant", e)
@@ -3621,7 +3622,7 @@ func typecheckdef(n *Node) {
 
                t := n.Type
                if t != nil {
-                       if !okforconst[t.Etype] {
+                       if !ir.OKForConst[t.Etype] {
                                base.ErrorfAt(n.Pos, "invalid constant type %v", t)
                                goto ret
                        }
@@ -3639,7 +3640,7 @@ func typecheckdef(n *Node) {
                        n.SetVal(e.Val())
                }
 
-       case ONAME:
+       case ir.ONAME:
                if n.Name.Param.Ntype != nil {
                        n.Name.Param.Ntype = typecheck(n.Name.Param.Ntype, ctxType)
                        n.Type = n.Name.Param.Ntype.Type
@@ -3667,7 +3668,7 @@ func typecheckdef(n *Node) {
                        base.Fatalf("var without type, init: %v", n.Sym)
                }
 
-               if n.Name.Defn.Op == ONAME {
+               if n.Name.Defn.Op == ir.ONAME {
                        n.Name.Defn = typecheck(n.Name.Defn, ctxExpr)
                        n.Type = n.Name.Defn.Type
                        break
@@ -3675,7 +3676,7 @@ func typecheckdef(n *Node) {
 
                n.Name.Defn = typecheck(n.Name.Defn, ctxStmt) // fills in n.Type
 
-       case OTYPE:
+       case ir.OTYPE:
                if p := n.Name.Param; p.Alias() {
                        // Type alias declaration: Simply use the rhs type - no need
                        // to create a new type.
@@ -3690,7 +3691,7 @@ func typecheckdef(n *Node) {
                                // For package-level type aliases, set n.Sym.Def so we can identify
                                // it as a type alias during export. See also #31959.
                                if n.Name.Curfn == nil {
-                                       n.Sym.Def = asTypesNode(p.Ntype)
+                                       n.Sym.Def = ir.AsTypesNode(p.Ntype)
                                }
                        }
                        break
@@ -3699,11 +3700,11 @@ func typecheckdef(n *Node) {
                // regular type declaration
                defercheckwidth()
                n.SetWalkdef(1)
-               setTypeNode(n, types.New(TFORW))
+               setTypeNode(n, types.New(types.TFORW))
                n.Type.Sym = n.Sym
                errorsBefore := base.Errors()
                typecheckdeftype(n)
-               if n.Type.Etype == TFORW && base.Errors() > errorsBefore {
+               if n.Type.Etype == types.TFORW && base.Errors() > errorsBefore {
                        // Something went wrong during type-checking,
                        // but it was reported. Silence future errors.
                        n.Type.SetBroke(true)
@@ -3712,7 +3713,7 @@ func typecheckdef(n *Node) {
        }
 
 ret:
-       if n.Op != OLITERAL && n.Type != nil && n.Type.IsUntyped() {
+       if n.Op != ir.OLITERAL && n.Type != nil && n.Type.IsUntyped() {
                base.Fatalf("got %v for %v", n.Type, n)
        }
        last := len(typecheckdefstack) - 1
@@ -3726,22 +3727,22 @@ ret:
        n.SetWalkdef(1)
 }
 
-func checkmake(t *types.Type, arg string, np **Node) bool {
+func checkmake(t *types.Type, arg string, np **ir.Node) bool {
        n := *np
-       if !n.Type.IsInteger() && n.Type.Etype != TIDEAL {
+       if !n.Type.IsInteger() && n.Type.Etype != types.TIDEAL {
                base.Errorf("non-integer %s argument in make(%v) - %v", arg, t, n.Type)
                return false
        }
 
        // Do range checks for constants before defaultlit
        // to avoid redundant "constant NNN overflows int" errors.
-       if n.Op == OLITERAL {
+       if n.Op == ir.OLITERAL {
                v := toint(n.Val())
                if constant.Sign(v) < 0 {
                        base.Errorf("negative %s argument in make(%v)", arg, t)
                        return false
                }
-               if doesoverflow(v, types.Types[TINT]) {
+               if doesoverflow(v, types.Types[types.TINT]) {
                        base.Errorf("%s argument too large in make(%v)", arg, t)
                        return false
                }
@@ -3752,30 +3753,30 @@ func checkmake(t *types.Type, arg string, np **Node) bool {
        // are the same as for index expressions. Factor the code better;
        // for instance, indexlit might be called here and incorporate some
        // of the bounds checks done for make.
-       n = defaultlit(n, types.Types[TINT])
+       n = defaultlit(n, types.Types[types.TINT])
        *np = n
 
        return true
 }
 
-func markbreak(n *Node, implicit *Node) {
+func markbreak(n *ir.Node, implicit *ir.Node) {
        if n == nil {
                return
        }
 
        switch n.Op {
-       case OBREAK:
+       case ir.OBREAK:
                if n.Sym == nil {
                        if implicit != nil {
                                implicit.SetHasBreak(true)
                        }
                } else {
-                       lab := asNode(n.Sym.Label)
+                       lab := ir.AsNode(n.Sym.Label)
                        if lab != nil {
                                lab.SetHasBreak(true)
                        }
                }
-       case OFOR, OFORUNTIL, OSWITCH, OTYPESW, OSELECT, ORANGE:
+       case ir.OFOR, ir.OFORUNTIL, ir.OSWITCH, ir.OTYPESW, ir.OSELECT, ir.ORANGE:
                implicit = n
                fallthrough
        default:
@@ -3788,17 +3789,17 @@ func markbreak(n *Node, implicit *Node) {
        }
 }
 
-func markbreaklist(l Nodes, implicit *Node) {
+func markbreaklist(l ir.Nodes, implicit *ir.Node) {
        s := l.Slice()
        for i := 0; i < len(s); i++ {
                n := s[i]
                if n == nil {
                        continue
                }
-               if n.Op == OLABEL && i+1 < len(s) && n.Name.Defn == s[i+1] {
+               if n.Op == ir.OLABEL && i+1 < len(s) && n.Name.Defn == s[i+1] {
                        switch n.Name.Defn.Op {
-                       case OFOR, OFORUNTIL, OSWITCH, OTYPESW, OSELECT, ORANGE:
-                               n.Sym.Label = asTypesNode(n.Name.Defn)
+                       case ir.OFOR, ir.OFORUNTIL, ir.OSWITCH, ir.OTYPESW, ir.OSELECT, ir.ORANGE:
+                               n.Sym.Label = ir.AsTypesNode(n.Name.Defn)
                                markbreak(n.Name.Defn, n.Name.Defn)
                                n.Sym.Label = nil
                                i++
@@ -3811,31 +3812,31 @@ func markbreaklist(l Nodes, implicit *Node) {
 }
 
 // isterminating reports whether the Nodes list ends with a terminating statement.
-func (l Nodes) isterminating() bool {
+func isTermNodes(l ir.Nodes) bool {
        s := l.Slice()
        c := len(s)
        if c == 0 {
                return false
        }
-       return s[c-1].isterminating()
+       return isTermNode(s[c-1])
 }
 
 // Isterminating reports whether the node n, the last one in a
 // statement list, is a terminating statement.
-func (n *Node) isterminating() bool {
+func isTermNode(n *ir.Node) bool {
        switch n.Op {
        // NOTE: OLABEL is treated as a separate statement,
        // not a separate prefix, so skipping to the last statement
        // in the block handles the labeled statement case by
        // skipping over the label. No case OLABEL here.
 
-       case OBLOCK:
-               return n.List.isterminating()
+       case ir.OBLOCK:
+               return isTermNodes(n.List)
 
-       case OGOTO, ORETURN, ORETJMP, OPANIC, OFALL:
+       case ir.OGOTO, ir.ORETURN, ir.ORETJMP, ir.OPANIC, ir.OFALL:
                return true
 
-       case OFOR, OFORUNTIL:
+       case ir.OFOR, ir.OFORUNTIL:
                if n.Left != nil {
                        return false
                }
@@ -3844,16 +3845,16 @@ func (n *Node) isterminating() bool {
                }
                return true
 
-       case OIF:
-               return n.Nbody.isterminating() && n.Rlist.isterminating()
+       case ir.OIF:
+               return isTermNodes(n.Nbody) && isTermNodes(n.Rlist)
 
-       case OSWITCH, OTYPESW, OSELECT:
+       case ir.OSWITCH, ir.OTYPESW, ir.OSELECT:
                if n.HasBreak() {
                        return false
                }
                def := false
                for _, n1 := range n.List.Slice() {
-                       if !n1.Nbody.isterminating() {
+                       if !isTermNodes(n1.Nbody) {
                                return false
                        }
                        if n1.List.Len() == 0 { // default
@@ -3861,7 +3862,7 @@ func (n *Node) isterminating() bool {
                        }
                }
 
-               if n.Op != OSELECT && !def {
+               if n.Op != ir.OSELECT && !def {
                        return false
                }
                return true
@@ -3871,21 +3872,21 @@ func (n *Node) isterminating() bool {
 }
 
 // checkreturn makes sure that fn terminates appropriately.
-func checkreturn(fn *Node) {
+func checkreturn(fn *ir.Node) {
        if fn.Type.NumResults() != 0 && fn.Nbody.Len() != 0 {
                markbreaklist(fn.Nbody, nil)
-               if !fn.Nbody.isterminating() {
+               if !isTermNodes(fn.Nbody) {
                        base.ErrorfAt(fn.Func.Endlineno, "missing return at end of function")
                }
        }
 }
 
-func deadcode(fn *Node) {
+func deadcode(fn *ir.Node) {
        deadcodeslice(&fn.Nbody)
        deadcodefn(fn)
 }
 
-func deadcodefn(fn *Node) {
+func deadcodefn(fn *ir.Node) {
        if fn.Nbody.Len() == 0 {
                return
        }
@@ -3895,12 +3896,12 @@ func deadcodefn(fn *Node) {
                        return
                }
                switch n.Op {
-               case OIF:
-                       if !Isconst(n.Left, constant.Bool) || n.Nbody.Len() > 0 || n.Rlist.Len() > 0 {
+               case ir.OIF:
+                       if !ir.IsConst(n.Left, constant.Bool) || n.Nbody.Len() > 0 || n.Rlist.Len() > 0 {
                                return
                        }
-               case OFOR:
-                       if !Isconst(n.Left, constant.Bool) || n.Left.BoolVal() {
+               case ir.OFOR:
+                       if !ir.IsConst(n.Left, constant.Bool) || n.Left.BoolVal() {
                                return
                        }
                default:
@@ -3908,13 +3909,13 @@ func deadcodefn(fn *Node) {
                }
        }
 
-       fn.Nbody.Set([]*Node{nod(OEMPTY, nil, nil)})
+       fn.Nbody.Set([]*ir.Node{ir.Nod(ir.OEMPTY, nil, nil)})
 }
 
-func deadcodeslice(nn *Nodes) {
+func deadcodeslice(nn *ir.Nodes) {
        var lastLabel = -1
        for i, n := range nn.Slice() {
-               if n != nil && n.Op == OLABEL {
+               if n != nil && n.Op == ir.OLABEL {
                        lastLabel = i
                }
        }
@@ -3926,15 +3927,15 @@ func deadcodeslice(nn *Nodes) {
                if n == nil {
                        continue
                }
-               if n.Op == OIF {
+               if n.Op == ir.OIF {
                        n.Left = deadcodeexpr(n.Left)
-                       if Isconst(n.Left, constant.Bool) {
-                               var body Nodes
+                       if ir.IsConst(n.Left, constant.Bool) {
+                               var body ir.Nodes
                                if n.Left.BoolVal() {
-                                       n.Rlist = Nodes{}
+                                       n.Rlist = ir.Nodes{}
                                        body = n.Nbody
                                } else {
-                                       n.Nbody = Nodes{}
+                                       n.Nbody = ir.Nodes{}
                                        body = n.Rlist
                                }
                                // If "then" or "else" branch ends with panic or return statement,
@@ -3944,7 +3945,7 @@ func deadcodeslice(nn *Nodes) {
                                // might be the target of a goto. See issue 28616.
                                if body := body.Slice(); len(body) != 0 {
                                        switch body[(len(body) - 1)].Op {
-                                       case ORETURN, ORETJMP, OPANIC:
+                                       case ir.ORETURN, ir.ORETJMP, ir.OPANIC:
                                                if i > lastLabel {
                                                        cut = true
                                                }
@@ -3964,25 +3965,25 @@ func deadcodeslice(nn *Nodes) {
        }
 }
 
-func deadcodeexpr(n *Node) *Node {
+func deadcodeexpr(n *ir.Node) *ir.Node {
        // Perform dead-code elimination on short-circuited boolean
        // expressions involving constants with the intent of
        // producing a constant 'if' condition.
        switch n.Op {
-       case OANDAND:
+       case ir.OANDAND:
                n.Left = deadcodeexpr(n.Left)
                n.Right = deadcodeexpr(n.Right)
-               if Isconst(n.Left, constant.Bool) {
+               if ir.IsConst(n.Left, constant.Bool) {
                        if n.Left.BoolVal() {
                                return n.Right // true && x => x
                        } else {
                                return n.Left // false && x => false
                        }
                }
-       case OOROR:
+       case ir.OOROR:
                n.Left = deadcodeexpr(n.Left)
                n.Right = deadcodeexpr(n.Right)
-               if Isconst(n.Left, constant.Bool) {
+               if ir.IsConst(n.Left, constant.Bool) {
                        if n.Left.BoolVal() {
                                return n.Left // true || x => true
                        } else {
@@ -3994,17 +3995,17 @@ func deadcodeexpr(n *Node) *Node {
 }
 
 // setTypeNode sets n to an OTYPE node representing t.
-func setTypeNode(n *Node, t *types.Type) {
-       n.Op = OTYPE
+func setTypeNode(n *ir.Node, t *types.Type) {
+       n.Op = ir.OTYPE
        n.Type = t
-       n.Type.Nod = asTypesNode(n)
+       n.Type.Nod = ir.AsTypesNode(n)
 }
 
 // getIotaValue returns the current value for "iota",
 // or -1 if not within a ConstSpec.
 func getIotaValue() int64 {
        if i := len(typecheckdefstack); i > 0 {
-               if x := typecheckdefstack[i-1]; x.Op == OLITERAL {
+               if x := typecheckdefstack[i-1]; x.Op == ir.OLITERAL {
                        return x.Iota()
                }
        }
@@ -4021,12 +4022,12 @@ func curpkg() *types.Pkg {
        fn := Curfn
        if fn == nil {
                // Initialization expressions for package-scope variables.
-               return localpkg
+               return ir.LocalPkg
        }
 
        // TODO(mdempsky): Standardize on either ODCLFUNC or ONAME for
        // Curfn, rather than mixing them.
-       if fn.Op == ODCLFUNC {
+       if fn.Op == ir.ODCLFUNC {
                fn = fn.Func.Nname
        }
 
@@ -4036,16 +4037,16 @@ func curpkg() *types.Pkg {
 // MethodName returns the ONAME representing the method
 // referenced by expression n, which must be a method selector,
 // method expression, or method value.
-func (n *Node) MethodName() *Node {
-       return asNode(n.MethodFunc().Nname)
+func methodExprName(n *ir.Node) *ir.Node {
+       return ir.AsNode(methodExprFunc(n).Nname)
 }
 
 // MethodFunc is like MethodName, but returns the types.Field instead.
-func (n *Node) MethodFunc() *types.Field {
+func methodExprFunc(n *ir.Node) *types.Field {
        switch n.Op {
-       case ODOTMETH, OMETHEXPR:
+       case ir.ODOTMETH, ir.OMETHEXPR:
                return n.Opt().(*types.Field)
-       case OCALLPART:
+       case ir.OCALLPART:
                return callpartMethod(n)
        }
        base.Fatalf("unexpected node: %v (%v)", n, n.Op)
index 748f8458bdb51ce372b894d260248578a97f706d..e46735df28dbed79dd062078aa3deaf5edb5be39 100644 (file)
@@ -3,56 +3,3 @@
 // license that can be found in the LICENSE file.
 
 package gc
-
-import (
-       "cmd/compile/internal/types"
-)
-
-// convenience constants
-const (
-       Txxx = types.Txxx
-
-       TINT8    = types.TINT8
-       TUINT8   = types.TUINT8
-       TINT16   = types.TINT16
-       TUINT16  = types.TUINT16
-       TINT32   = types.TINT32
-       TUINT32  = types.TUINT32
-       TINT64   = types.TINT64
-       TUINT64  = types.TUINT64
-       TINT     = types.TINT
-       TUINT    = types.TUINT
-       TUINTPTR = types.TUINTPTR
-
-       TCOMPLEX64  = types.TCOMPLEX64
-       TCOMPLEX128 = types.TCOMPLEX128
-
-       TFLOAT32 = types.TFLOAT32
-       TFLOAT64 = types.TFLOAT64
-
-       TBOOL = types.TBOOL
-
-       TPTR       = types.TPTR
-       TFUNC      = types.TFUNC
-       TSLICE     = types.TSLICE
-       TARRAY     = types.TARRAY
-       TSTRUCT    = types.TSTRUCT
-       TCHAN      = types.TCHAN
-       TMAP       = types.TMAP
-       TINTER     = types.TINTER
-       TFORW      = types.TFORW
-       TANY       = types.TANY
-       TSTRING    = types.TSTRING
-       TUNSAFEPTR = types.TUNSAFEPTR
-
-       // pseudo-types for literals
-       TIDEAL = types.TIDEAL
-       TNIL   = types.TNIL
-       TBLANK = types.TBLANK
-
-       // pseudo-types for frame layout
-       TFUNCARGS = types.TFUNCARGS
-       TCHANARGS = types.TCHANARGS
-
-       NTYPE = types.NTYPE
-)
index 7240f726f6296ee33d07d4c6b91107c0d48220de..d6d53f05cc949bb89e51bee76d33267257441661 100644 (file)
@@ -6,11 +6,3 @@
 // TODO(gri) try to eliminate these soon
 
 package gc
-
-import (
-       "cmd/compile/internal/types"
-       "unsafe"
-)
-
-func asNode(n *types.Node) *Node      { return (*Node)(unsafe.Pointer(n)) }
-func asTypesNode(n *Node) *types.Node { return (*types.Node)(unsafe.Pointer(n)) }
index aa0ee4075dd183d7eda5217b3a771d194f8b3fcd..bf31055dcc1beb0d1c7300f25938f343d14735b1 100644 (file)
@@ -8,31 +8,29 @@ package gc
 
 import (
        "cmd/compile/internal/base"
+       "cmd/compile/internal/ir"
        "cmd/compile/internal/types"
        "cmd/internal/src"
 )
 
-// builtinpkg is a fake package that declares the universe block.
-var builtinpkg *types.Pkg
-
 var basicTypes = [...]struct {
        name  string
        etype types.EType
 }{
-       {"int8", TINT8},
-       {"int16", TINT16},
-       {"int32", TINT32},
-       {"int64", TINT64},
-       {"uint8", TUINT8},
-       {"uint16", TUINT16},
-       {"uint32", TUINT32},
-       {"uint64", TUINT64},
-       {"float32", TFLOAT32},
-       {"float64", TFLOAT64},
-       {"complex64", TCOMPLEX64},
-       {"complex128", TCOMPLEX128},
-       {"bool", TBOOL},
-       {"string", TSTRING},
+       {"int8", types.TINT8},
+       {"int16", types.TINT16},
+       {"int32", types.TINT32},
+       {"int64", types.TINT64},
+       {"uint8", types.TUINT8},
+       {"uint16", types.TUINT16},
+       {"uint32", types.TUINT32},
+       {"uint64", types.TUINT64},
+       {"float32", types.TFLOAT32},
+       {"float64", types.TFLOAT64},
+       {"complex64", types.TCOMPLEX64},
+       {"complex128", types.TCOMPLEX128},
+       {"bool", types.TBOOL},
+       {"string", types.TSTRING},
 }
 
 var typedefs = [...]struct {
@@ -41,30 +39,30 @@ var typedefs = [...]struct {
        sameas32 types.EType
        sameas64 types.EType
 }{
-       {"int", TINT, TINT32, TINT64},
-       {"uint", TUINT, TUINT32, TUINT64},
-       {"uintptr", TUINTPTR, TUINT32, TUINT64},
+       {"int", types.TINT, types.TINT32, types.TINT64},
+       {"uint", types.TUINT, types.TUINT32, types.TUINT64},
+       {"uintptr", types.TUINTPTR, types.TUINT32, types.TUINT64},
 }
 
 var builtinFuncs = [...]struct {
        name string
-       op   Op
+       op   ir.Op
 }{
-       {"append", OAPPEND},
-       {"cap", OCAP},
-       {"close", OCLOSE},
-       {"complex", OCOMPLEX},
-       {"copy", OCOPY},
-       {"delete", ODELETE},
-       {"imag", OIMAG},
-       {"len", OLEN},
-       {"make", OMAKE},
-       {"new", ONEW},
-       {"panic", OPANIC},
-       {"print", OPRINT},
-       {"println", OPRINTN},
-       {"real", OREAL},
-       {"recover", ORECOVER},
+       {"append", ir.OAPPEND},
+       {"cap", ir.OCAP},
+       {"close", ir.OCLOSE},
+       {"complex", ir.OCOMPLEX},
+       {"copy", ir.OCOPY},
+       {"delete", ir.ODELETE},
+       {"imag", ir.OIMAG},
+       {"len", ir.OLEN},
+       {"make", ir.OMAKE},
+       {"new", ir.ONEW},
+       {"panic", ir.OPANIC},
+       {"print", ir.OPRINT},
+       {"println", ir.OPRINTN},
+       {"real", ir.OREAL},
+       {"recover", ir.ORECOVER},
 }
 
 // isBuiltinFuncName reports whether name matches a builtin function
@@ -80,11 +78,11 @@ func isBuiltinFuncName(name string) bool {
 
 var unsafeFuncs = [...]struct {
        name string
-       op   Op
+       op   ir.Op
 }{
-       {"Alignof", OALIGNOF},
-       {"Offsetof", OOFFSETOF},
-       {"Sizeof", OSIZEOF},
+       {"Alignof", ir.OALIGNOF},
+       {"Offsetof", ir.OOFFSETOF},
+       {"Sizeof", ir.OSIZEOF},
 }
 
 // initUniverse initializes the universe block.
@@ -101,71 +99,71 @@ func lexinit() {
                if int(etype) >= len(types.Types) {
                        base.Fatalf("lexinit: %s bad etype", s.name)
                }
-               s2 := builtinpkg.Lookup(s.name)
+               s2 := ir.BuiltinPkg.Lookup(s.name)
                t := types.Types[etype]
                if t == nil {
                        t = types.New(etype)
                        t.Sym = s2
-                       if etype != TANY && etype != TSTRING {
+                       if etype != types.TANY && etype != types.TSTRING {
                                dowidth(t)
                        }
                        types.Types[etype] = t
                }
-               s2.Def = asTypesNode(typenod(t))
-               asNode(s2.Def).Name = new(Name)
+               s2.Def = ir.AsTypesNode(typenod(t))
+               ir.AsNode(s2.Def).Name = new(ir.Name)
        }
 
        for _, s := range &builtinFuncs {
-               s2 := builtinpkg.Lookup(s.name)
-               s2.Def = asTypesNode(newname(s2))
-               asNode(s2.Def).SetSubOp(s.op)
+               s2 := ir.BuiltinPkg.Lookup(s.name)
+               s2.Def = ir.AsTypesNode(NewName(s2))
+               ir.AsNode(s2.Def).SetSubOp(s.op)
        }
 
        for _, s := range &unsafeFuncs {
                s2 := unsafepkg.Lookup(s.name)
-               s2.Def = asTypesNode(newname(s2))
-               asNode(s2.Def).SetSubOp(s.op)
+               s2.Def = ir.AsTypesNode(NewName(s2))
+               ir.AsNode(s2.Def).SetSubOp(s.op)
        }
 
-       types.UntypedString = types.New(TSTRING)
-       types.UntypedBool = types.New(TBOOL)
-       types.Types[TANY] = types.New(TANY)
+       types.UntypedString = types.New(types.TSTRING)
+       types.UntypedBool = types.New(types.TBOOL)
+       types.Types[types.TANY] = types.New(types.TANY)
 
-       s := builtinpkg.Lookup("true")
-       s.Def = asTypesNode(nodbool(true))
-       asNode(s.Def).Sym = lookup("true")
-       asNode(s.Def).Name = new(Name)
-       asNode(s.Def).Type = types.UntypedBool
+       s := ir.BuiltinPkg.Lookup("true")
+       s.Def = ir.AsTypesNode(nodbool(true))
+       ir.AsNode(s.Def).Sym = lookup("true")
+       ir.AsNode(s.Def).Name = new(ir.Name)
+       ir.AsNode(s.Def).Type = types.UntypedBool
 
-       s = builtinpkg.Lookup("false")
-       s.Def = asTypesNode(nodbool(false))
-       asNode(s.Def).Sym = lookup("false")
-       asNode(s.Def).Name = new(Name)
-       asNode(s.Def).Type = types.UntypedBool
+       s = ir.BuiltinPkg.Lookup("false")
+       s.Def = ir.AsTypesNode(nodbool(false))
+       ir.AsNode(s.Def).Sym = lookup("false")
+       ir.AsNode(s.Def).Name = new(ir.Name)
+       ir.AsNode(s.Def).Type = types.UntypedBool
 
        s = lookup("_")
        s.Block = -100
-       s.Def = asTypesNode(newname(s))
-       types.Types[TBLANK] = types.New(TBLANK)
-       asNode(s.Def).Type = types.Types[TBLANK]
-       nblank = asNode(s.Def)
+       s.Def = ir.AsTypesNode(NewName(s))
+       types.Types[types.TBLANK] = types.New(types.TBLANK)
+       ir.AsNode(s.Def).Type = types.Types[types.TBLANK]
+       ir.BlankNode = ir.AsNode(s.Def)
 
-       s = builtinpkg.Lookup("_")
+       s = ir.BuiltinPkg.Lookup("_")
        s.Block = -100
-       s.Def = asTypesNode(newname(s))
-       types.Types[TBLANK] = types.New(TBLANK)
-       asNode(s.Def).Type = types.Types[TBLANK]
-
-       types.Types[TNIL] = types.New(TNIL)
-       s = builtinpkg.Lookup("nil")
-       s.Def = asTypesNode(nodnil())
-       asNode(s.Def).Sym = s
-       asNode(s.Def).Name = new(Name)
-
-       s = builtinpkg.Lookup("iota")
-       s.Def = asTypesNode(nod(OIOTA, nil, nil))
-       asNode(s.Def).Sym = s
-       asNode(s.Def).Name = new(Name)
+       s.Def = ir.AsTypesNode(NewName(s))
+       types.Types[types.TBLANK] = types.New(types.TBLANK)
+       ir.AsNode(s.Def).Type = types.Types[types.TBLANK]
+
+       types.Types[types.TNIL] = types.New(types.TNIL)
+       s = ir.BuiltinPkg.Lookup("nil")
+       s.Def = ir.AsTypesNode(nodnil())
+       ir.AsNode(s.Def).Sym = s
+       ir.AsNode(s.Def).Name = new(ir.Name)
+
+       s = ir.BuiltinPkg.Lookup("iota")
+       s.Def = ir.AsTypesNode(ir.Nod(ir.OIOTA, nil, nil))
+       ir.AsNode(s.Def).Sym = s
+       ir.AsNode(s.Def).Name = new(ir.Name)
 }
 
 func typeinit() {
@@ -173,42 +171,42 @@ func typeinit() {
                base.Fatalf("typeinit before betypeinit")
        }
 
-       for et := types.EType(0); et < NTYPE; et++ {
+       for et := types.EType(0); et < types.NTYPE; et++ {
                simtype[et] = et
        }
 
-       types.Types[TPTR] = types.New(TPTR)
-       dowidth(types.Types[TPTR])
+       types.Types[types.TPTR] = types.New(types.TPTR)
+       dowidth(types.Types[types.TPTR])
 
-       t := types.New(TUNSAFEPTR)
-       types.Types[TUNSAFEPTR] = t
+       t := types.New(types.TUNSAFEPTR)
+       types.Types[types.TUNSAFEPTR] = t
        t.Sym = unsafepkg.Lookup("Pointer")
-       t.Sym.Def = asTypesNode(typenod(t))
-       asNode(t.Sym.Def).Name = new(Name)
-       dowidth(types.Types[TUNSAFEPTR])
+       t.Sym.Def = ir.AsTypesNode(typenod(t))
+       ir.AsNode(t.Sym.Def).Name = new(ir.Name)
+       dowidth(types.Types[types.TUNSAFEPTR])
 
-       for et := TINT8; et <= TUINT64; et++ {
+       for et := types.TINT8; et <= types.TUINT64; et++ {
                isInt[et] = true
        }
-       isInt[TINT] = true
-       isInt[TUINT] = true
-       isInt[TUINTPTR] = true
+       isInt[types.TINT] = true
+       isInt[types.TUINT] = true
+       isInt[types.TUINTPTR] = true
 
-       isFloat[TFLOAT32] = true
-       isFloat[TFLOAT64] = true
+       isFloat[types.TFLOAT32] = true
+       isFloat[types.TFLOAT64] = true
 
-       isComplex[TCOMPLEX64] = true
-       isComplex[TCOMPLEX128] = true
+       isComplex[types.TCOMPLEX64] = true
+       isComplex[types.TCOMPLEX128] = true
 
        // initialize okfor
-       for et := types.EType(0); et < NTYPE; et++ {
-               if isInt[et] || et == TIDEAL {
+       for et := types.EType(0); et < types.NTYPE; et++ {
+               if isInt[et] || et == types.TIDEAL {
                        okforeq[et] = true
                        okforcmp[et] = true
                        okforarith[et] = true
                        okforadd[et] = true
                        okforand[et] = true
-                       okforconst[et] = true
+                       ir.OKForConst[et] = true
                        issimple[et] = true
                }
 
@@ -217,7 +215,7 @@ func typeinit() {
                        okforcmp[et] = true
                        okforadd[et] = true
                        okforarith[et] = true
-                       okforconst[et] = true
+                       ir.OKForConst[et] = true
                        issimple[et] = true
                }
 
@@ -225,43 +223,43 @@ func typeinit() {
                        okforeq[et] = true
                        okforadd[et] = true
                        okforarith[et] = true
-                       okforconst[et] = true
+                       ir.OKForConst[et] = true
                        issimple[et] = true
                }
        }
 
-       issimple[TBOOL] = true
+       issimple[types.TBOOL] = true
 
-       okforadd[TSTRING] = true
+       okforadd[types.TSTRING] = true
 
-       okforbool[TBOOL] = true
+       okforbool[types.TBOOL] = true
 
-       okforcap[TARRAY] = true
-       okforcap[TCHAN] = true
-       okforcap[TSLICE] = true
+       okforcap[types.TARRAY] = true
+       okforcap[types.TCHAN] = true
+       okforcap[types.TSLICE] = true
 
-       okforconst[TBOOL] = true
-       okforconst[TSTRING] = true
+       ir.OKForConst[types.TBOOL] = true
+       ir.OKForConst[types.TSTRING] = true
 
-       okforlen[TARRAY] = true
-       okforlen[TCHAN] = true
-       okforlen[TMAP] = true
-       okforlen[TSLICE] = true
-       okforlen[TSTRING] = true
+       okforlen[types.TARRAY] = true
+       okforlen[types.TCHAN] = true
+       okforlen[types.TMAP] = true
+       okforlen[types.TSLICE] = true
+       okforlen[types.TSTRING] = true
 
-       okforeq[TPTR] = true
-       okforeq[TUNSAFEPTR] = true
-       okforeq[TINTER] = true
-       okforeq[TCHAN] = true
-       okforeq[TSTRING] = true
-       okforeq[TBOOL] = true
-       okforeq[TMAP] = true    // nil only; refined in typecheck
-       okforeq[TFUNC] = true   // nil only; refined in typecheck
-       okforeq[TSLICE] = true  // nil only; refined in typecheck
-       okforeq[TARRAY] = true  // only if element type is comparable; refined in typecheck
-       okforeq[TSTRUCT] = true // only if all struct fields are comparable; refined in typecheck
+       okforeq[types.TPTR] = true
+       okforeq[types.TUNSAFEPTR] = true
+       okforeq[types.TINTER] = true
+       okforeq[types.TCHAN] = true
+       okforeq[types.TSTRING] = true
+       okforeq[types.TBOOL] = true
+       okforeq[types.TMAP] = true    // nil only; refined in typecheck
+       okforeq[types.TFUNC] = true   // nil only; refined in typecheck
+       okforeq[types.TSLICE] = true  // nil only; refined in typecheck
+       okforeq[types.TARRAY] = true  // only if element type is comparable; refined in typecheck
+       okforeq[types.TSTRUCT] = true // only if all struct fields are comparable; refined in typecheck
 
-       okforcmp[TSTRING] = true
+       okforcmp[types.TSTRING] = true
 
        var i int
        for i = 0; i < len(okfor); i++ {
@@ -269,51 +267,51 @@ func typeinit() {
        }
 
        // binary
-       okfor[OADD] = okforadd[:]
-       okfor[OAND] = okforand[:]
-       okfor[OANDAND] = okforbool[:]
-       okfor[OANDNOT] = okforand[:]
-       okfor[ODIV] = okforarith[:]
-       okfor[OEQ] = okforeq[:]
-       okfor[OGE] = okforcmp[:]
-       okfor[OGT] = okforcmp[:]
-       okfor[OLE] = okforcmp[:]
-       okfor[OLT] = okforcmp[:]
-       okfor[OMOD] = okforand[:]
-       okfor[OMUL] = okforarith[:]
-       okfor[ONE] = okforeq[:]
-       okfor[OOR] = okforand[:]
-       okfor[OOROR] = okforbool[:]
-       okfor[OSUB] = okforarith[:]
-       okfor[OXOR] = okforand[:]
-       okfor[OLSH] = okforand[:]
-       okfor[ORSH] = okforand[:]
+       okfor[ir.OADD] = okforadd[:]
+       okfor[ir.OAND] = okforand[:]
+       okfor[ir.OANDAND] = okforbool[:]
+       okfor[ir.OANDNOT] = okforand[:]
+       okfor[ir.ODIV] = okforarith[:]
+       okfor[ir.OEQ] = okforeq[:]
+       okfor[ir.OGE] = okforcmp[:]
+       okfor[ir.OGT] = okforcmp[:]
+       okfor[ir.OLE] = okforcmp[:]
+       okfor[ir.OLT] = okforcmp[:]
+       okfor[ir.OMOD] = okforand[:]
+       okfor[ir.OMUL] = okforarith[:]
+       okfor[ir.ONE] = okforeq[:]
+       okfor[ir.OOR] = okforand[:]
+       okfor[ir.OOROR] = okforbool[:]
+       okfor[ir.OSUB] = okforarith[:]
+       okfor[ir.OXOR] = okforand[:]
+       okfor[ir.OLSH] = okforand[:]
+       okfor[ir.ORSH] = okforand[:]
 
        // unary
-       okfor[OBITNOT] = okforand[:]
-       okfor[ONEG] = okforarith[:]
-       okfor[ONOT] = okforbool[:]
-       okfor[OPLUS] = okforarith[:]
+       okfor[ir.OBITNOT] = okforand[:]
+       okfor[ir.ONEG] = okforarith[:]
+       okfor[ir.ONOT] = okforbool[:]
+       okfor[ir.OPLUS] = okforarith[:]
 
        // special
-       okfor[OCAP] = okforcap[:]
-       okfor[OLEN] = okforlen[:]
+       okfor[ir.OCAP] = okforcap[:]
+       okfor[ir.OLEN] = okforlen[:]
 
        // comparison
-       iscmp[OLT] = true
-       iscmp[OGT] = true
-       iscmp[OGE] = true
-       iscmp[OLE] = true
-       iscmp[OEQ] = true
-       iscmp[ONE] = true
+       iscmp[ir.OLT] = true
+       iscmp[ir.OGT] = true
+       iscmp[ir.OGE] = true
+       iscmp[ir.OLE] = true
+       iscmp[ir.OEQ] = true
+       iscmp[ir.ONE] = true
 
-       types.Types[TINTER] = types.New(TINTER) // empty interface
+       types.Types[types.TINTER] = types.New(types.TINTER) // empty interface
 
        // simple aliases
-       simtype[TMAP] = TPTR
-       simtype[TCHAN] = TPTR
-       simtype[TFUNC] = TPTR
-       simtype[TUNSAFEPTR] = TPTR
+       simtype[types.TMAP] = types.TPTR
+       simtype[types.TCHAN] = types.TPTR
+       simtype[types.TFUNC] = types.TPTR
+       simtype[types.TUNSAFEPTR] = types.TPTR
 
        slicePtrOffset = 0
        sliceLenOffset = Rnd(slicePtrOffset+int64(Widthptr), int64(Widthptr))
@@ -323,29 +321,29 @@ func typeinit() {
        // string is same as slice wo the cap
        sizeofString = Rnd(sliceLenOffset+int64(Widthptr), int64(Widthptr))
 
-       dowidth(types.Types[TSTRING])
+       dowidth(types.Types[types.TSTRING])
        dowidth(types.UntypedString)
 }
 
 func makeErrorInterface() *types.Type {
        sig := functypefield(fakeRecvField(), nil, []*types.Field{
-               types.NewField(src.NoXPos, nil, types.Types[TSTRING]),
+               types.NewField(src.NoXPos, nil, types.Types[types.TSTRING]),
        })
 
        method := types.NewField(src.NoXPos, lookup("Error"), sig)
 
-       t := types.New(TINTER)
+       t := types.New(types.TINTER)
        t.SetInterface([]*types.Field{method})
        return t
 }
 
 func lexinit1() {
        // error type
-       s := builtinpkg.Lookup("error")
+       s := ir.BuiltinPkg.Lookup("error")
        types.Errortype = makeErrorInterface()
        types.Errortype.Sym = s
        types.Errortype.Orig = makeErrorInterface()
-       s.Def = asTypesNode(typenod(types.Errortype))
+       s.Def = ir.AsTypesNode(typenod(types.Errortype))
        dowidth(types.Errortype)
 
        // We create separate byte and rune types for better error messages
@@ -357,24 +355,24 @@ func lexinit1() {
        // type aliases, albeit at the cost of having to deal with it everywhere).
 
        // byte alias
-       s = builtinpkg.Lookup("byte")
-       types.Bytetype = types.New(TUINT8)
+       s = ir.BuiltinPkg.Lookup("byte")
+       types.Bytetype = types.New(types.TUINT8)
        types.Bytetype.Sym = s
-       s.Def = asTypesNode(typenod(types.Bytetype))
-       asNode(s.Def).Name = new(Name)
+       s.Def = ir.AsTypesNode(typenod(types.Bytetype))
+       ir.AsNode(s.Def).Name = new(ir.Name)
        dowidth(types.Bytetype)
 
        // rune alias
-       s = builtinpkg.Lookup("rune")
-       types.Runetype = types.New(TINT32)
+       s = ir.BuiltinPkg.Lookup("rune")
+       types.Runetype = types.New(types.TINT32)
        types.Runetype.Sym = s
-       s.Def = asTypesNode(typenod(types.Runetype))
-       asNode(s.Def).Name = new(Name)
+       s.Def = ir.AsTypesNode(typenod(types.Runetype))
+       ir.AsNode(s.Def).Name = new(ir.Name)
        dowidth(types.Runetype)
 
        // backend-dependent builtin types (e.g. int).
        for _, s := range &typedefs {
-               s1 := builtinpkg.Lookup(s.name)
+               s1 := ir.BuiltinPkg.Lookup(s.name)
 
                sameas := s.sameas32
                if Widthptr == 8 {
@@ -386,9 +384,9 @@ func lexinit1() {
                t := types.New(s.etype)
                t.Sym = s1
                types.Types[s.etype] = t
-               s1.Def = asTypesNode(typenod(t))
-               asNode(s1.Def).Name = new(Name)
-               s1.Origpkg = builtinpkg
+               s1.Def = ir.AsTypesNode(typenod(t))
+               ir.AsNode(s1.Def).Name = new(ir.Name)
+               s1.Origpkg = ir.BuiltinPkg
 
                dowidth(t)
        }
@@ -400,7 +398,7 @@ func finishUniverse() {
        // that we silently skip symbols that are already declared in the
        // package block rather than emitting a redeclared symbol error.
 
-       for _, s := range builtinpkg.Syms {
+       for _, s := range ir.BuiltinPkg.Syms {
                if s.Def == nil {
                        continue
                }
@@ -413,8 +411,8 @@ func finishUniverse() {
                s1.Block = s.Block
        }
 
-       nodfp = newname(lookup(".fp"))
-       nodfp.Type = types.Types[TINT32]
-       nodfp.SetClass(PPARAM)
+       nodfp = NewName(lookup(".fp"))
+       nodfp.Type = types.Types[types.TINT32]
+       nodfp.SetClass(ir.PPARAM)
        nodfp.Name.SetUsed(true)
 }
index a1c1c1bf6e291b32e8ec65d4f3f266ade744b96e..fce79a631964c1f2a30711d8275dd01f54332c4f 100644 (file)
@@ -4,12 +4,15 @@
 
 package gc
 
-import "cmd/compile/internal/base"
+import (
+       "cmd/compile/internal/base"
+       "cmd/compile/internal/ir"
+)
 
 // evalunsafe evaluates a package unsafe operation and returns the result.
-func evalunsafe(n *Node) int64 {
+func evalunsafe(n *ir.Node) int64 {
        switch n.Op {
-       case OALIGNOF, OSIZEOF:
+       case ir.OALIGNOF, ir.OSIZEOF:
                n.Left = typecheck(n.Left, ctxExpr)
                n.Left = defaultlit(n.Left, nil)
                tr := n.Left.Type
@@ -17,14 +20,14 @@ func evalunsafe(n *Node) int64 {
                        return 0
                }
                dowidth(tr)
-               if n.Op == OALIGNOF {
+               if n.Op == ir.OALIGNOF {
                        return int64(tr.Align)
                }
                return tr.Width
 
-       case OOFFSETOF:
+       case ir.OOFFSETOF:
                // must be a selector.
-               if n.Left.Op != OXDOT {
+               if n.Left.Op != ir.OXDOT {
                        base.Errorf("invalid expression %v", n)
                        return 0
                }
@@ -40,9 +43,9 @@ func evalunsafe(n *Node) int64 {
                        return 0
                }
                switch n.Left.Op {
-               case ODOT, ODOTPTR:
+               case ir.ODOT, ir.ODOTPTR:
                        break
-               case OCALLPART:
+               case ir.OCALLPART:
                        base.Errorf("invalid expression %v: argument is a method value", n)
                        return 0
                default:
@@ -54,7 +57,7 @@ func evalunsafe(n *Node) int64 {
                var v int64
                for r := n.Left; r != sbase; r = r.Left {
                        switch r.Op {
-                       case ODOTPTR:
+                       case ir.ODOTPTR:
                                // For Offsetof(s.f), s may itself be a pointer,
                                // but accessing f must not otherwise involve
                                // indirection via embedded pointer types.
@@ -63,10 +66,10 @@ func evalunsafe(n *Node) int64 {
                                        return 0
                                }
                                fallthrough
-                       case ODOT:
+                       case ir.ODOT:
                                v += r.Xoffset
                        default:
-                               Dump("unsafenmagic", n.Left)
+                               ir.Dump("unsafenmagic", n.Left)
                                base.Fatalf("impossible %#v node after dot insertion", r.Op)
                        }
                }
index 597a29a940e56d0e7a78872449910e4f143cd876..4baddbc029a8d2dc587650a1b99243bc20b9b619 100644 (file)
@@ -12,12 +12,6 @@ import (
        "cmd/compile/internal/base"
 )
 
-// Line returns n's position as a string. If n has been inlined,
-// it uses the outermost position where n has been inlined.
-func (n *Node) Line() string {
-       return base.FmtPos(n.Pos)
-}
-
 var (
        memprofilerate int64
        traceHandler   func(string)
index d7cd7ddf27ca3465e8a8c27e52d96fdeac2d19c1..619a413b9e49ce37e6a662a96954f0089f5ace15 100644 (file)
@@ -6,6 +6,7 @@ package gc
 
 import (
        "cmd/compile/internal/base"
+       "cmd/compile/internal/ir"
        "cmd/compile/internal/types"
        "cmd/internal/obj"
        "cmd/internal/objabi"
@@ -21,20 +22,20 @@ import (
 const tmpstringbufsize = 32
 const zeroValSize = 1024 // must match value of runtime/map.go:maxZero
 
-func walk(fn *Node) {
+func walk(fn *ir.Node) {
        Curfn = fn
        errorsBefore := base.Errors()
 
        if base.Flag.W != 0 {
                s := fmt.Sprintf("\nbefore walk %v", Curfn.Func.Nname.Sym)
-               dumplist(s, Curfn.Nbody)
+               ir.DumpList(s, Curfn.Nbody)
        }
 
        lno := base.Pos
 
        // Final typecheck for any unused variables.
        for i, ln := range fn.Func.Dcl {
-               if ln.Op == ONAME && (ln.Class() == PAUTO || ln.Class() == PAUTOHEAP) {
+               if ln.Op == ir.ONAME && (ln.Class() == ir.PAUTO || ln.Class() == ir.PAUTOHEAP) {
                        ln = typecheck(ln, ctxExpr|ctxAssign)
                        fn.Func.Dcl[i] = ln
                }
@@ -42,16 +43,16 @@ func walk(fn *Node) {
 
        // Propagate the used flag for typeswitch variables up to the NONAME in its definition.
        for _, ln := range fn.Func.Dcl {
-               if ln.Op == ONAME && (ln.Class() == PAUTO || ln.Class() == PAUTOHEAP) && ln.Name.Defn != nil && ln.Name.Defn.Op == OTYPESW && ln.Name.Used() {
+               if ln.Op == ir.ONAME && (ln.Class() == ir.PAUTO || ln.Class() == ir.PAUTOHEAP) && ln.Name.Defn != nil && ln.Name.Defn.Op == ir.OTYPESW && ln.Name.Used() {
                        ln.Name.Defn.Left.Name.SetUsed(true)
                }
        }
 
        for _, ln := range fn.Func.Dcl {
-               if ln.Op != ONAME || (ln.Class() != PAUTO && ln.Class() != PAUTOHEAP) || ln.Sym.Name[0] == '&' || ln.Name.Used() {
+               if ln.Op != ir.ONAME || (ln.Class() != ir.PAUTO && ln.Class() != ir.PAUTOHEAP) || ln.Sym.Name[0] == '&' || ln.Name.Used() {
                        continue
                }
-               if defn := ln.Name.Defn; defn != nil && defn.Op == OTYPESW {
+               if defn := ln.Name.Defn; defn != nil && defn.Op == ir.OTYPESW {
                        if defn.Left.Name.Used() {
                                continue
                        }
@@ -69,32 +70,32 @@ func walk(fn *Node) {
        walkstmtlist(Curfn.Nbody.Slice())
        if base.Flag.W != 0 {
                s := fmt.Sprintf("after walk %v", Curfn.Func.Nname.Sym)
-               dumplist(s, Curfn.Nbody)
+               ir.DumpList(s, Curfn.Nbody)
        }
 
        zeroResults()
        heapmoves()
        if base.Flag.W != 0 && Curfn.Func.Enter.Len() > 0 {
                s := fmt.Sprintf("enter %v", Curfn.Func.Nname.Sym)
-               dumplist(s, Curfn.Func.Enter)
+               ir.DumpList(s, Curfn.Func.Enter)
        }
 }
 
-func walkstmtlist(s []*Node) {
+func walkstmtlist(s []*ir.Node) {
        for i := range s {
                s[i] = walkstmt(s[i])
        }
 }
 
-func paramoutheap(fn *Node) bool {
+func paramoutheap(fn *ir.Node) bool {
        for _, ln := range fn.Func.Dcl {
                switch ln.Class() {
-               case PPARAMOUT:
-                       if ln.isParamStackCopy() || ln.Name.Addrtaken() {
+               case ir.PPARAMOUT:
+                       if isParamStackCopy(ln) || ln.Name.Addrtaken() {
                                return true
                        }
 
-               case PAUTO:
+               case ir.PAUTO:
                        // stop early - parameters are over
                        return false
                }
@@ -105,7 +106,7 @@ func paramoutheap(fn *Node) bool {
 
 // The result of walkstmt MUST be assigned back to n, e.g.
 //     n.Left = walkstmt(n.Left)
-func walkstmt(n *Node) *Node {
+func walkstmt(n *ir.Node) *ir.Node {
        if n == nil {
                return n
        }
@@ -116,49 +117,49 @@ func walkstmt(n *Node) *Node {
 
        switch n.Op {
        default:
-               if n.Op == ONAME {
+               if n.Op == ir.ONAME {
                        base.Errorf("%v is not a top level statement", n.Sym)
                } else {
                        base.Errorf("%v is not a top level statement", n.Op)
                }
-               Dump("nottop", n)
-
-       case OAS,
-               OASOP,
-               OAS2,
-               OAS2DOTTYPE,
-               OAS2RECV,
-               OAS2FUNC,
-               OAS2MAPR,
-               OCLOSE,
-               OCOPY,
-               OCALLMETH,
-               OCALLINTER,
-               OCALL,
-               OCALLFUNC,
-               ODELETE,
-               OSEND,
-               OPRINT,
-               OPRINTN,
-               OPANIC,
-               OEMPTY,
-               ORECOVER,
-               OGETG:
+               ir.Dump("nottop", n)
+
+       case ir.OAS,
+               ir.OASOP,
+               ir.OAS2,
+               ir.OAS2DOTTYPE,
+               ir.OAS2RECV,
+               ir.OAS2FUNC,
+               ir.OAS2MAPR,
+               ir.OCLOSE,
+               ir.OCOPY,
+               ir.OCALLMETH,
+               ir.OCALLINTER,
+               ir.OCALL,
+               ir.OCALLFUNC,
+               ir.ODELETE,
+               ir.OSEND,
+               ir.OPRINT,
+               ir.OPRINTN,
+               ir.OPANIC,
+               ir.OEMPTY,
+               ir.ORECOVER,
+               ir.OGETG:
                if n.Typecheck() == 0 {
                        base.Fatalf("missing typecheck: %+v", n)
                }
-               wascopy := n.Op == OCOPY
+               wascopy := n.Op == ir.OCOPY
                init := n.Ninit
                n.Ninit.Set(nil)
                n = walkexpr(n, &init)
                n = addinit(n, init.Slice())
-               if wascopy && n.Op == OCONVNOP {
-                       n.Op = OEMPTY // don't leave plain values as statements.
+               if wascopy && n.Op == ir.OCONVNOP {
+                       n.Op = ir.OEMPTY // don't leave plain values as statements.
                }
 
        // special case for a receive where we throw away
        // the value received.
-       case ORECV:
+       case ir.ORECV:
                if n.Typecheck() == 0 {
                        base.Fatalf("missing typecheck: %+v", n)
                }
@@ -171,44 +172,44 @@ func walkstmt(n *Node) *Node {
 
                n = addinit(n, init.Slice())
 
-       case OBREAK,
-               OCONTINUE,
-               OFALL,
-               OGOTO,
-               OLABEL,
-               ODCLCONST,
-               ODCLTYPE,
-               OCHECKNIL,
-               OVARDEF,
-               OVARKILL,
-               OVARLIVE:
+       case ir.OBREAK,
+               ir.OCONTINUE,
+               ir.OFALL,
+               ir.OGOTO,
+               ir.OLABEL,
+               ir.ODCLCONST,
+               ir.ODCLTYPE,
+               ir.OCHECKNIL,
+               ir.OVARDEF,
+               ir.OVARKILL,
+               ir.OVARLIVE:
                break
 
-       case ODCL:
+       case ir.ODCL:
                v := n.Left
-               if v.Class() == PAUTOHEAP {
+               if v.Class() == ir.PAUTOHEAP {
                        if base.Flag.CompilingRuntime {
                                base.Errorf("%v escapes to heap, not allowed in runtime", v)
                        }
                        if prealloc[v] == nil {
                                prealloc[v] = callnew(v.Type)
                        }
-                       nn := nod(OAS, v.Name.Param.Heapaddr, prealloc[v])
+                       nn := ir.Nod(ir.OAS, v.Name.Param.Heapaddr, prealloc[v])
                        nn.SetColas(true)
                        nn = typecheck(nn, ctxStmt)
                        return walkstmt(nn)
                }
 
-       case OBLOCK:
+       case ir.OBLOCK:
                walkstmtlist(n.List.Slice())
 
-       case OCASE:
+       case ir.OCASE:
                base.Errorf("case statement out of place")
 
-       case ODEFER:
+       case ir.ODEFER:
                Curfn.Func.SetHasDefer(true)
-               Curfn.Func.numDefers++
-               if Curfn.Func.numDefers > maxOpenDefers {
+               Curfn.Func.NumDefers++
+               if Curfn.Func.NumDefers > maxOpenDefers {
                        // Don't allow open-coded defers if there are more than
                        // 8 defers in the function, since we use a single
                        // byte to record active defers.
@@ -220,22 +221,22 @@ func walkstmt(n *Node) *Node {
                        Curfn.Func.SetOpenCodedDeferDisallowed(true)
                }
                fallthrough
-       case OGO:
+       case ir.OGO:
                switch n.Left.Op {
-               case OPRINT, OPRINTN:
+               case ir.OPRINT, ir.OPRINTN:
                        n.Left = wrapCall(n.Left, &n.Ninit)
 
-               case ODELETE:
+               case ir.ODELETE:
                        if mapfast(n.Left.List.First().Type) == mapslow {
                                n.Left = wrapCall(n.Left, &n.Ninit)
                        } else {
                                n.Left = walkexpr(n.Left, &n.Ninit)
                        }
 
-               case OCOPY:
+               case ir.OCOPY:
                        n.Left = copyany(n.Left, &n.Ninit, true)
 
-               case OCALLFUNC, OCALLMETH, OCALLINTER:
+               case ir.OCALLFUNC, ir.OCALLMETH, ir.OCALLINTER:
                        if n.Left.Nbody.Len() > 0 {
                                n.Left = wrapCall(n.Left, &n.Ninit)
                        } else {
@@ -246,7 +247,7 @@ func walkstmt(n *Node) *Node {
                        n.Left = walkexpr(n.Left, &n.Ninit)
                }
 
-       case OFOR, OFORUNTIL:
+       case ir.OFOR, ir.OFORUNTIL:
                if n.Left != nil {
                        walkstmtlist(n.Left.Ninit.Slice())
                        init := n.Left.Ninit
@@ -256,34 +257,34 @@ func walkstmt(n *Node) *Node {
                }
 
                n.Right = walkstmt(n.Right)
-               if n.Op == OFORUNTIL {
+               if n.Op == ir.OFORUNTIL {
                        walkstmtlist(n.List.Slice())
                }
                walkstmtlist(n.Nbody.Slice())
 
-       case OIF:
+       case ir.OIF:
                n.Left = walkexpr(n.Left, &n.Ninit)
                walkstmtlist(n.Nbody.Slice())
                walkstmtlist(n.Rlist.Slice())
 
-       case ORETURN:
-               Curfn.Func.numReturns++
+       case ir.ORETURN:
+               Curfn.Func.NumReturns++
                if n.List.Len() == 0 {
                        break
                }
                if (Curfn.Type.FuncType().Outnamed && n.List.Len() > 1) || paramoutheap(Curfn) {
                        // assign to the function out parameters,
                        // so that reorder3 can fix up conflicts
-                       var rl []*Node
+                       var rl []*ir.Node
 
                        for _, ln := range Curfn.Func.Dcl {
                                cl := ln.Class()
-                               if cl == PAUTO || cl == PAUTOHEAP {
+                               if cl == ir.PAUTO || cl == ir.PAUTOHEAP {
                                        break
                                }
-                               if cl == PPARAMOUT {
-                                       if ln.isParamStackCopy() {
-                                               ln = walkexpr(typecheck(nod(ODEREF, ln.Name.Param.Heapaddr, nil), ctxExpr), nil)
+                               if cl == ir.PPARAMOUT {
+                                       if isParamStackCopy(ln) {
+                                               ln = walkexpr(typecheck(ir.Nod(ir.ODEREF, ln.Name.Param.Heapaddr, nil), ctxExpr), nil)
                                        }
                                        rl = append(rl, ln)
                                }
@@ -307,34 +308,34 @@ func walkstmt(n *Node) *Node {
                // For each return parameter (lhs), assign the corresponding result (rhs).
                lhs := Curfn.Type.Results()
                rhs := n.List.Slice()
-               res := make([]*Node, lhs.NumFields())
+               res := make([]*ir.Node, lhs.NumFields())
                for i, nl := range lhs.FieldSlice() {
-                       nname := asNode(nl.Nname)
-                       if nname.isParamHeapCopy() {
+                       nname := ir.AsNode(nl.Nname)
+                       if isParamHeapCopy(nname) {
                                nname = nname.Name.Param.Stackcopy
                        }
-                       a := nod(OAS, nname, rhs[i])
+                       a := ir.Nod(ir.OAS, nname, rhs[i])
                        res[i] = convas(a, &n.Ninit)
                }
                n.List.Set(res)
 
-       case ORETJMP:
+       case ir.ORETJMP:
                break
 
-       case OINLMARK:
+       case ir.OINLMARK:
                break
 
-       case OSELECT:
+       case ir.OSELECT:
                walkselect(n)
 
-       case OSWITCH:
+       case ir.OSWITCH:
                walkswitch(n)
 
-       case ORANGE:
+       case ir.ORANGE:
                n = walkrange(n)
        }
 
-       if n.Op == ONAME {
+       if n.Op == ir.ONAME {
                base.Fatalf("walkstmt ended up with name: %+v", n)
        }
        return n
@@ -345,20 +346,20 @@ func walkstmt(n *Node) *Node {
 // the types expressions are calculated.
 // compile-time constants are evaluated.
 // complex side effects like statements are appended to init
-func walkexprlist(s []*Node, init *Nodes) {
+func walkexprlist(s []*ir.Node, init *ir.Nodes) {
        for i := range s {
                s[i] = walkexpr(s[i], init)
        }
 }
 
-func walkexprlistsafe(s []*Node, init *Nodes) {
+func walkexprlistsafe(s []*ir.Node, init *ir.Nodes) {
        for i, n := range s {
                s[i] = safeexpr(n, init)
                s[i] = walkexpr(s[i], init)
        }
 }
 
-func walkexprlistcheap(s []*Node, init *Nodes) {
+func walkexprlistcheap(s []*ir.Node, init *ir.Nodes) {
        for i, n := range s {
                s[i] = cheapexpr(n, init)
                s[i] = walkexpr(s[i], init)
@@ -381,7 +382,7 @@ func convFuncName(from, to *types.Type) (fnname string, needsaddr bool) {
                        return "convT16", false
                case from.Size() == 4 && from.Align == 4 && !from.HasPointers():
                        return "convT32", false
-               case from.Size() == 8 && from.Align == types.Types[TUINT64].Align && !from.HasPointers():
+               case from.Size() == 8 && from.Align == types.Types[types.TUINT64].Align && !from.HasPointers():
                        return "convT64", false
                }
                if sc := from.SoleComponent(); sc != nil {
@@ -412,7 +413,7 @@ func convFuncName(from, to *types.Type) (fnname string, needsaddr bool) {
 
 // The result of walkexpr MUST be assigned back to n, e.g.
 //     n.Left = walkexpr(n.Left, init)
-func walkexpr(n *Node, init *Nodes) *Node {
+func walkexpr(n *ir.Node, init *ir.Nodes) *ir.Node {
        if n == nil {
                return n
        }
@@ -420,7 +421,7 @@ func walkexpr(n *Node, init *Nodes) *Node {
        // Eagerly checkwidth all expressions for the back end.
        if n.Type != nil && !n.Type.WidthCalculated() {
                switch n.Type.Etype {
-               case TBLANK, TNIL, TIDEAL:
+               case types.TBLANK, types.TNIL, types.TIDEAL:
                default:
                        checkwidth(n.Type)
                }
@@ -441,7 +442,7 @@ func walkexpr(n *Node, init *Nodes) *Node {
        lno := setlineno(n)
 
        if base.Flag.LowerW > 1 {
-               Dump("before walk expr", n)
+               ir.Dump("before walk expr", n)
        }
 
        if n.Typecheck() != 1 {
@@ -452,8 +453,8 @@ func walkexpr(n *Node, init *Nodes) *Node {
                base.Fatalf("expression has untyped type: %+v", n)
        }
 
-       if n.Op == ONAME && n.Class() == PAUTOHEAP {
-               nn := nod(ODEREF, n.Name.Param.Heapaddr, nil)
+       if n.Op == ir.ONAME && n.Class() == ir.PAUTOHEAP {
+               nn := ir.Nod(ir.ODEREF, n.Name.Param.Heapaddr, nil)
                nn = typecheck(nn, ctxExpr)
                nn = walkexpr(nn, init)
                nn.Left.MarkNonNil()
@@ -463,44 +464,44 @@ func walkexpr(n *Node, init *Nodes) *Node {
 opswitch:
        switch n.Op {
        default:
-               Dump("walk", n)
+               ir.Dump("walk", n)
                base.Fatalf("walkexpr: switch 1 unknown op %+S", n)
 
-       case ONONAME, OEMPTY, OGETG, ONEWOBJ, OMETHEXPR:
+       case ir.ONONAME, ir.OEMPTY, ir.OGETG, ir.ONEWOBJ, ir.OMETHEXPR:
 
-       case OTYPE, ONAME, OLITERAL, ONIL:
+       case ir.OTYPE, ir.ONAME, ir.OLITERAL, ir.ONIL:
                // TODO(mdempsky): Just return n; see discussion on CL 38655.
                // Perhaps refactor to use Node.mayBeShared for these instead.
                // If these return early, make sure to still call
                // stringsym for constant strings.
 
-       case ONOT, ONEG, OPLUS, OBITNOT, OREAL, OIMAG, ODOTMETH, ODOTINTER,
-               ODEREF, OSPTR, OITAB, OIDATA, OADDR:
+       case ir.ONOT, ir.ONEG, ir.OPLUS, ir.OBITNOT, ir.OREAL, ir.OIMAG, ir.ODOTMETH, ir.ODOTINTER,
+               ir.ODEREF, ir.OSPTR, ir.OITAB, ir.OIDATA, ir.OADDR:
                n.Left = walkexpr(n.Left, init)
 
-       case OEFACE, OAND, OANDNOT, OSUB, OMUL, OADD, OOR, OXOR, OLSH, ORSH:
+       case ir.OEFACE, ir.OAND, ir.OANDNOT, ir.OSUB, ir.OMUL, ir.OADD, ir.OOR, ir.OXOR, ir.OLSH, ir.ORSH:
                n.Left = walkexpr(n.Left, init)
                n.Right = walkexpr(n.Right, init)
 
-       case ODOT, ODOTPTR:
+       case ir.ODOT, ir.ODOTPTR:
                usefield(n)
                n.Left = walkexpr(n.Left, init)
 
-       case ODOTTYPE, ODOTTYPE2:
+       case ir.ODOTTYPE, ir.ODOTTYPE2:
                n.Left = walkexpr(n.Left, init)
                // Set up interface type addresses for back end.
                n.Right = typename(n.Type)
-               if n.Op == ODOTTYPE {
+               if n.Op == ir.ODOTTYPE {
                        n.Right.Right = typename(n.Left.Type)
                }
                if !n.Type.IsInterface() && !n.Left.Type.IsEmptyInterface() {
                        n.List.Set1(itabname(n.Type, n.Left.Type))
                }
 
-       case OLEN, OCAP:
+       case ir.OLEN, ir.OCAP:
                if isRuneCount(n) {
                        // Replace len([]rune(string)) with runtime.countrunes(string).
-                       n = mkcall("countrunes", n.Type, init, conv(n.Left.Left, types.Types[TSTRING]))
+                       n = mkcall("countrunes", n.Type, init, conv(n.Left.Left, types.Types[types.TSTRING]))
                        break
                }
 
@@ -519,7 +520,7 @@ opswitch:
                        n.SetTypecheck(1)
                }
 
-       case OCOMPLEX:
+       case ir.OCOMPLEX:
                // Use results from call expression as arguments for complex.
                if n.Left == nil && n.Right == nil {
                        n.Left = n.List.First()
@@ -528,38 +529,38 @@ opswitch:
                n.Left = walkexpr(n.Left, init)
                n.Right = walkexpr(n.Right, init)
 
-       case OEQ, ONE, OLT, OLE, OGT, OGE:
+       case ir.OEQ, ir.ONE, ir.OLT, ir.OLE, ir.OGT, ir.OGE:
                n = walkcompare(n, init)
 
-       case OANDAND, OOROR:
+       case ir.OANDAND, ir.OOROR:
                n.Left = walkexpr(n.Left, init)
 
                // cannot put side effects from n.Right on init,
                // because they cannot run before n.Left is checked.
                // save elsewhere and store on the eventual n.Right.
-               var ll Nodes
+               var ll ir.Nodes
 
                n.Right = walkexpr(n.Right, &ll)
                n.Right = addinit(n.Right, ll.Slice())
 
-       case OPRINT, OPRINTN:
+       case ir.OPRINT, ir.OPRINTN:
                n = walkprint(n, init)
 
-       case OPANIC:
+       case ir.OPANIC:
                n = mkcall("gopanic", nil, init, n.Left)
 
-       case ORECOVER:
-               n = mkcall("gorecover", n.Type, init, nod(OADDR, nodfp, nil))
+       case ir.ORECOVER:
+               n = mkcall("gorecover", n.Type, init, ir.Nod(ir.OADDR, nodfp, nil))
 
-       case OCLOSUREVAR, OCFUNC:
+       case ir.OCLOSUREVAR, ir.OCFUNC:
 
-       case OCALLINTER, OCALLFUNC, OCALLMETH:
-               if n.Op == OCALLINTER {
+       case ir.OCALLINTER, ir.OCALLFUNC, ir.OCALLMETH:
+               if n.Op == ir.OCALLINTER {
                        usemethod(n)
                        markUsedIfaceMethod(n)
                }
 
-               if n.Op == OCALLFUNC && n.Left.Op == OCLOSURE {
+               if n.Op == ir.OCALLFUNC && n.Left.Op == ir.OCLOSURE {
                        // Transform direct call of a closure to call of a normal function.
                        // transformclosure already did all preparation work.
 
@@ -581,12 +582,12 @@ opswitch:
 
                walkCall(n, init)
 
-       case OAS, OASOP:
+       case ir.OAS, ir.OASOP:
                init.AppendNodes(&n.Ninit)
 
                // Recognize m[k] = append(m[k], ...) so we can reuse
                // the mapassign call.
-               mapAppend := n.Left.Op == OINDEXMAP && n.Right.Op == OAPPEND
+               mapAppend := n.Left.Op == ir.OINDEXMAP && n.Right.Op == ir.OAPPEND
                if mapAppend && !samesafeexpr(n.Left, n.Right.List.First()) {
                        base.Fatalf("not same expressions: %v != %v", n.Left, n.Right.List.First())
                }
@@ -598,12 +599,12 @@ opswitch:
                        n.Right.List.SetFirst(n.Left)
                }
 
-               if n.Op == OASOP {
+               if n.Op == ir.OASOP {
                        // Rewrite x op= y into x = x op y.
-                       n.Right = nod(n.SubOp(), n.Left, n.Right)
+                       n.Right = ir.Nod(n.SubOp(), n.Left, n.Right)
                        n.Right = typecheck(n.Right, ctxExpr)
 
-                       n.Op = OAS
+                       n.Op = ir.OAS
                        n.ResetAux()
                }
 
@@ -624,18 +625,18 @@ opswitch:
                default:
                        n.Right = walkexpr(n.Right, init)
 
-               case ORECV:
+               case ir.ORECV:
                        // x = <-c; n.Left is x, n.Right.Left is c.
                        // order.stmt made sure x is addressable.
                        n.Right.Left = walkexpr(n.Right.Left, init)
 
-                       n1 := nod(OADDR, n.Left, nil)
+                       n1 := ir.Nod(ir.OADDR, n.Left, nil)
                        r := n.Right.Left // the channel
                        n = mkcall1(chanfn("chanrecv1", 2, r.Type), nil, init, r, n1)
                        n = walkexpr(n, init)
                        break opswitch
 
-               case OAPPEND:
+               case ir.OAPPEND:
                        // x = append(...)
                        r := n.Right
                        if r.Type.Elem().NotInHeap() {
@@ -651,7 +652,7 @@ opswitch:
                                r = walkappend(r, init, n)
                        }
                        n.Right = r
-                       if r.Op == OAPPEND {
+                       if r.Op == ir.OAPPEND {
                                // Left in place for back end.
                                // Do not add a new write barrier.
                                // Set up address of type for back end.
@@ -666,16 +667,16 @@ opswitch:
                        n = convas(n, init)
                }
 
-       case OAS2:
+       case ir.OAS2:
                init.AppendNodes(&n.Ninit)
                walkexprlistsafe(n.List.Slice(), init)
                walkexprlistsafe(n.Rlist.Slice(), init)
-               ll := ascompatee(OAS, n.List.Slice(), n.Rlist.Slice(), init)
+               ll := ascompatee(ir.OAS, n.List.Slice(), n.Rlist.Slice(), init)
                ll = reorder3(ll)
                n = liststmt(ll)
 
        // a,b,... = fn()
-       case OAS2FUNC:
+       case ir.OAS2FUNC:
                init.AppendNodes(&n.Ninit)
 
                r := n.Right
@@ -693,26 +694,26 @@ opswitch:
 
        // x, y = <-c
        // order.stmt made sure x is addressable or blank.
-       case OAS2RECV:
+       case ir.OAS2RECV:
                init.AppendNodes(&n.Ninit)
 
                r := n.Right
                walkexprlistsafe(n.List.Slice(), init)
                r.Left = walkexpr(r.Left, init)
-               var n1 *Node
-               if n.List.First().isBlank() {
+               var n1 *ir.Node
+               if ir.IsBlank(n.List.First()) {
                        n1 = nodnil()
                } else {
-                       n1 = nod(OADDR, n.List.First(), nil)
+                       n1 = ir.Nod(ir.OADDR, n.List.First(), nil)
                }
                fn := chanfn("chanrecv2", 2, r.Left.Type)
                ok := n.List.Second()
-               call := mkcall1(fn, types.Types[TBOOL], init, r.Left, n1)
-               n = nod(OAS, ok, call)
+               call := mkcall1(fn, types.Types[types.TBOOL], init, r.Left, n1)
+               n = ir.Nod(ir.OAS, ok, call)
                n = typecheck(n, ctxStmt)
 
        // a,b = m[i]
-       case OAS2MAPR:
+       case ir.OAS2MAPR:
                init.AppendNodes(&n.Ninit)
 
                r := n.Right
@@ -722,14 +723,14 @@ opswitch:
                t := r.Left.Type
 
                fast := mapfast(t)
-               var key *Node
+               var key *ir.Node
                if fast != mapslow {
                        // fast versions take key by value
                        key = r.Right
                } else {
                        // standard version takes key by reference
                        // order.expr made sure key is addressable.
-                       key = nod(OADDR, r.Right, nil)
+                       key = ir.Nod(ir.OADDR, r.Right, nil)
                }
 
                // from:
@@ -751,27 +752,27 @@ opswitch:
                // mapaccess2* returns a typed bool, but due to spec changes,
                // the boolean result of i.(T) is now untyped so we make it the
                // same type as the variable on the lhs.
-               if ok := n.List.Second(); !ok.isBlank() && ok.Type.IsBoolean() {
+               if ok := n.List.Second(); !ir.IsBlank(ok) && ok.Type.IsBoolean() {
                        r.Type.Field(1).Type = ok.Type
                }
                n.Right = r
-               n.Op = OAS2FUNC
+               n.Op = ir.OAS2FUNC
 
                // don't generate a = *var if a is _
-               if !a.isBlank() {
+               if !ir.IsBlank(a) {
                        var_ := temp(types.NewPtr(t.Elem()))
                        var_.SetTypecheck(1)
                        var_.MarkNonNil() // mapaccess always returns a non-nil pointer
                        n.List.SetFirst(var_)
                        n = walkexpr(n, init)
                        init.Append(n)
-                       n = nod(OAS, a, nod(ODEREF, var_, nil))
+                       n = ir.Nod(ir.OAS, a, ir.Nod(ir.ODEREF, var_, nil))
                }
 
                n = typecheck(n, ctxStmt)
                n = walkexpr(n, init)
 
-       case ODELETE:
+       case ir.ODELETE:
                init.AppendNodes(&n.Ninit)
                map_ := n.List.First()
                key := n.List.Second()
@@ -782,26 +783,26 @@ opswitch:
                fast := mapfast(t)
                if fast == mapslow {
                        // order.stmt made sure key is addressable.
-                       key = nod(OADDR, key, nil)
+                       key = ir.Nod(ir.OADDR, key, nil)
                }
                n = mkcall1(mapfndel(mapdelete[fast], t), nil, init, typename(t), map_, key)
 
-       case OAS2DOTTYPE:
+       case ir.OAS2DOTTYPE:
                walkexprlistsafe(n.List.Slice(), init)
                n.Right = walkexpr(n.Right, init)
 
-       case OCONVIFACE:
+       case ir.OCONVIFACE:
                n.Left = walkexpr(n.Left, init)
 
                fromType := n.Left.Type
                toType := n.Type
 
-               if !fromType.IsInterface() && !Curfn.Func.Nname.isBlank() { // skip unnamed functions (func _())
-                       markTypeUsedInInterface(fromType, Curfn.Func.lsym)
+               if !fromType.IsInterface() && !ir.IsBlank(Curfn.Func.Nname) { // skip unnamed functions (func _())
+                       markTypeUsedInInterface(fromType, Curfn.Func.LSym)
                }
 
                // typeword generates the type word of the interface value.
-               typeword := func() *Node {
+               typeword := func() *ir.Node {
                        if toType.IsEmptyInterface() {
                                return typename(fromType)
                        }
@@ -810,7 +811,7 @@ opswitch:
 
                // Optimize convT2E or convT2I as a two-word copy when T is pointer-shaped.
                if isdirectiface(fromType) {
-                       l := nod(OEFACE, typeword(), n.Left)
+                       l := ir.Nod(ir.OEFACE, typeword(), n.Left)
                        l.Type = toType
                        l.SetTypecheck(n.Typecheck())
                        n = l
@@ -818,20 +819,20 @@ opswitch:
                }
 
                if staticuint64s == nil {
-                       staticuint64s = newname(Runtimepkg.Lookup("staticuint64s"))
-                       staticuint64s.SetClass(PEXTERN)
+                       staticuint64s = NewName(Runtimepkg.Lookup("staticuint64s"))
+                       staticuint64s.SetClass(ir.PEXTERN)
                        // The actual type is [256]uint64, but we use [256*8]uint8 so we can address
                        // individual bytes.
-                       staticuint64s.Type = types.NewArray(types.Types[TUINT8], 256*8)
-                       zerobase = newname(Runtimepkg.Lookup("zerobase"))
-                       zerobase.SetClass(PEXTERN)
-                       zerobase.Type = types.Types[TUINTPTR]
+                       staticuint64s.Type = types.NewArray(types.Types[types.TUINT8], 256*8)
+                       zerobase = NewName(Runtimepkg.Lookup("zerobase"))
+                       zerobase.SetClass(ir.PEXTERN)
+                       zerobase.Type = types.Types[types.TUINTPTR]
                }
 
                // Optimize convT2{E,I} for many cases in which T is not pointer-shaped,
                // by using an existing addressable value identical to n.Left
                // or creating one on the stack.
-               var value *Node
+               var value *ir.Node
                switch {
                case fromType.Size() == 0:
                        // n.Left is zero-sized. Use zerobase.
@@ -842,25 +843,25 @@ opswitch:
                        // and staticuint64s[n.Left * 8 + 7] on big-endian.
                        n.Left = cheapexpr(n.Left, init)
                        // byteindex widens n.Left so that the multiplication doesn't overflow.
-                       index := nod(OLSH, byteindex(n.Left), nodintconst(3))
+                       index := ir.Nod(ir.OLSH, byteindex(n.Left), nodintconst(3))
                        if thearch.LinkArch.ByteOrder == binary.BigEndian {
-                               index = nod(OADD, index, nodintconst(7))
+                               index = ir.Nod(ir.OADD, index, nodintconst(7))
                        }
-                       value = nod(OINDEX, staticuint64s, index)
+                       value = ir.Nod(ir.OINDEX, staticuint64s, index)
                        value.SetBounded(true)
-               case n.Left.Class() == PEXTERN && n.Left.Name != nil && n.Left.Name.Readonly():
+               case n.Left.Class() == ir.PEXTERN && n.Left.Name != nil && n.Left.Name.Readonly():
                        // n.Left is a readonly global; use it directly.
                        value = n.Left
                case !fromType.IsInterface() && n.Esc == EscNone && fromType.Width <= 1024:
                        // n.Left does not escape. Use a stack temporary initialized to n.Left.
                        value = temp(fromType)
-                       init.Append(typecheck(nod(OAS, value, n.Left), ctxStmt))
+                       init.Append(typecheck(ir.Nod(ir.OAS, value, n.Left), ctxStmt))
                }
 
                if value != nil {
                        // Value is identical to n.Left.
                        // Construct the interface directly: {type/itab, &value}.
-                       l := nod(OEFACE, typeword(), typecheck(nod(OADDR, value, nil), ctxExpr))
+                       l := ir.Nod(ir.OEFACE, typeword(), typecheck(ir.Nod(ir.OADDR, value, nil), ctxExpr))
                        l.Type = toType
                        l.SetTypecheck(n.Typecheck())
                        n = l
@@ -876,19 +877,19 @@ opswitch:
                if toType.IsEmptyInterface() && fromType.IsInterface() && !fromType.IsEmptyInterface() {
                        // Evaluate the input interface.
                        c := temp(fromType)
-                       init.Append(nod(OAS, c, n.Left))
+                       init.Append(ir.Nod(ir.OAS, c, n.Left))
 
                        // Get the itab out of the interface.
-                       tmp := temp(types.NewPtr(types.Types[TUINT8]))
-                       init.Append(nod(OAS, tmp, typecheck(nod(OITAB, c, nil), ctxExpr)))
+                       tmp := temp(types.NewPtr(types.Types[types.TUINT8]))
+                       init.Append(ir.Nod(ir.OAS, tmp, typecheck(ir.Nod(ir.OITAB, c, nil), ctxExpr)))
 
                        // Get the type out of the itab.
-                       nif := nod(OIF, typecheck(nod(ONE, tmp, nodnil()), ctxExpr), nil)
-                       nif.Nbody.Set1(nod(OAS, tmp, itabType(tmp)))
+                       nif := ir.Nod(ir.OIF, typecheck(ir.Nod(ir.ONE, tmp, nodnil()), ctxExpr), nil)
+                       nif.Nbody.Set1(ir.Nod(ir.OAS, tmp, itabType(tmp)))
                        init.Append(nif)
 
                        // Build the result.
-                       e := nod(OEFACE, tmp, ifaceData(n.Pos, c, types.NewPtr(types.Types[TUINT8])))
+                       e := ir.Nod(ir.OEFACE, tmp, ifaceData(n.Pos, c, types.NewPtr(types.Types[types.TUINT8])))
                        e.Type = toType // assign type manually, typecheck doesn't understand OEFACE.
                        e.SetTypecheck(1)
                        n = e
@@ -905,19 +906,19 @@ opswitch:
                        dowidth(fromType)
                        fn = substArgTypes(fn, fromType)
                        dowidth(fn.Type)
-                       call := nod(OCALL, fn, nil)
+                       call := ir.Nod(ir.OCALL, fn, nil)
                        call.List.Set1(n.Left)
                        call = typecheck(call, ctxExpr)
                        call = walkexpr(call, init)
                        call = safeexpr(call, init)
-                       e := nod(OEFACE, typeword(), call)
+                       e := ir.Nod(ir.OEFACE, typeword(), call)
                        e.Type = toType
                        e.SetTypecheck(1)
                        n = e
                        break
                }
 
-               var tab *Node
+               var tab *ir.Node
                if fromType.IsInterface() {
                        // convI2I
                        tab = typename(toType)
@@ -937,21 +938,21 @@ opswitch:
                        if !islvalue(v) {
                                v = copyexpr(v, v.Type, init)
                        }
-                       v = nod(OADDR, v, nil)
+                       v = ir.Nod(ir.OADDR, v, nil)
                }
 
                dowidth(fromType)
                fn := syslook(fnname)
                fn = substArgTypes(fn, fromType, toType)
                dowidth(fn.Type)
-               n = nod(OCALL, fn, nil)
+               n = ir.Nod(ir.OCALL, fn, nil)
                n.List.Set2(tab, v)
                n = typecheck(n, ctxExpr)
                n = walkexpr(n, init)
 
-       case OCONV, OCONVNOP:
+       case ir.OCONV, ir.OCONVNOP:
                n.Left = walkexpr(n.Left, init)
-               if n.Op == OCONVNOP && checkPtr(Curfn, 1) {
+               if n.Op == ir.OCONVNOP && checkPtr(Curfn, 1) {
                        if n.Type.IsPtr() && n.Left.Type.IsUnsafePtr() { // unsafe.Pointer to *T
                                n = walkCheckPtrAlignment(n, init, nil)
                                break
@@ -962,22 +963,22 @@ opswitch:
                        }
                }
                param, result := rtconvfn(n.Left.Type, n.Type)
-               if param == Txxx {
+               if param == types.Txxx {
                        break
                }
-               fn := basicnames[param] + "to" + basicnames[result]
+               fn := ir.BasicTypeNames[param] + "to" + ir.BasicTypeNames[result]
                n = conv(mkcall(fn, types.Types[result], init, conv(n.Left, types.Types[param])), n.Type)
 
-       case ODIV, OMOD:
+       case ir.ODIV, ir.OMOD:
                n.Left = walkexpr(n.Left, init)
                n.Right = walkexpr(n.Right, init)
 
                // rewrite complex div into function call.
                et := n.Left.Type.Etype
 
-               if isComplex[et] && n.Op == ODIV {
+               if isComplex[et] && n.Op == ir.ODIV {
                        t := n.Type
-                       n = mkcall("complex128div", types.Types[TCOMPLEX128], init, conv(n.Left, types.Types[TCOMPLEX128]), conv(n.Right, types.Types[TCOMPLEX128]))
+                       n = mkcall("complex128div", types.Types[types.TCOMPLEX128], init, conv(n.Left, types.Types[types.TCOMPLEX128]), conv(n.Right, types.Types[types.TCOMPLEX128]))
                        n = conv(n, t)
                        break
                }
@@ -990,12 +991,12 @@ opswitch:
                // rewrite 64-bit div and mod on 32-bit architectures.
                // TODO: Remove this code once we can introduce
                // runtime calls late in SSA processing.
-               if Widthreg < 8 && (et == TINT64 || et == TUINT64) {
-                       if n.Right.Op == OLITERAL {
+               if Widthreg < 8 && (et == types.TINT64 || et == types.TUINT64) {
+                       if n.Right.Op == ir.OLITERAL {
                                // Leave div/mod by constant powers of 2 or small 16-bit constants.
                                // The SSA backend will handle those.
                                switch et {
-                               case TINT64:
+                               case types.TINT64:
                                        c := n.Right.Int64Val()
                                        if c < 0 {
                                                c = -c
@@ -1003,7 +1004,7 @@ opswitch:
                                        if c != 0 && c&(c-1) == 0 {
                                                break opswitch
                                        }
-                               case TUINT64:
+                               case types.TUINT64:
                                        c := n.Right.Uint64Val()
                                        if c < 1<<16 {
                                                break opswitch
@@ -1014,12 +1015,12 @@ opswitch:
                                }
                        }
                        var fn string
-                       if et == TINT64 {
+                       if et == types.TINT64 {
                                fn = "int64"
                        } else {
                                fn = "uint64"
                        }
-                       if n.Op == ODIV {
+                       if n.Op == ir.ODIV {
                                fn += "div"
                        } else {
                                fn += "mod"
@@ -1027,7 +1028,7 @@ opswitch:
                        n = mkcall(fn, n.Type, init, conv(n.Left, types.Types[et]), conv(n.Right, types.Types[et]))
                }
 
-       case OINDEX:
+       case ir.OINDEX:
                n.Left = walkexpr(n.Left, init)
 
                // save the original node for bounds checking elision.
@@ -1047,15 +1048,15 @@ opswitch:
                }
                if t.IsArray() {
                        n.SetBounded(bounded(r, t.NumElem()))
-                       if base.Flag.LowerM != 0 && n.Bounded() && !Isconst(n.Right, constant.Int) {
+                       if base.Flag.LowerM != 0 && n.Bounded() && !ir.IsConst(n.Right, constant.Int) {
                                base.Warn("index bounds check elided")
                        }
                        if smallintconst(n.Right) && !n.Bounded() {
                                base.Errorf("index out of bounds")
                        }
-               } else if Isconst(n.Left, constant.String) {
+               } else if ir.IsConst(n.Left, constant.String) {
                        n.SetBounded(bounded(r, int64(len(n.Left.StringVal()))))
-                       if base.Flag.LowerM != 0 && n.Bounded() && !Isconst(n.Right, constant.Int) {
+                       if base.Flag.LowerM != 0 && n.Bounded() && !ir.IsConst(n.Right, constant.Int) {
                                base.Warn("index bounds check elided")
                        }
                        if smallintconst(n.Right) && !n.Bounded() {
@@ -1063,13 +1064,13 @@ opswitch:
                        }
                }
 
-               if Isconst(n.Right, constant.Int) {
-                       if v := n.Right.Val(); constant.Sign(v) < 0 || doesoverflow(v, types.Types[TINT]) {
+               if ir.IsConst(n.Right, constant.Int) {
+                       if v := n.Right.Val(); constant.Sign(v) < 0 || doesoverflow(v, types.Types[types.TINT]) {
                                base.Errorf("index out of bounds")
                        }
                }
 
-       case OINDEXMAP:
+       case ir.OINDEXMAP:
                // Replace m[k] with *map{access1,assign}(maptype, m, &k)
                n.Left = walkexpr(n.Left, init)
                n.Right = walkexpr(n.Right, init)
@@ -1082,7 +1083,7 @@ opswitch:
                        if fast == mapslow {
                                // standard version takes key by reference.
                                // order.expr made sure key is addressable.
-                               key = nod(OADDR, key, nil)
+                               key = ir.Nod(ir.OADDR, key, nil)
                        }
                        n = mkcall1(mapfn(mapassign[fast], t), nil, init, typename(t), map_, key)
                } else {
@@ -1091,7 +1092,7 @@ opswitch:
                        if fast == mapslow {
                                // standard version takes key by reference.
                                // order.expr made sure key is addressable.
-                               key = nod(OADDR, key, nil)
+                               key = ir.Nod(ir.OADDR, key, nil)
                        }
 
                        if w := t.Elem().Width; w <= zeroValSize {
@@ -1103,20 +1104,20 @@ opswitch:
                }
                n.Type = types.NewPtr(t.Elem())
                n.MarkNonNil() // mapaccess1* and mapassign always return non-nil pointers.
-               n = nod(ODEREF, n, nil)
+               n = ir.Nod(ir.ODEREF, n, nil)
                n.Type = t.Elem()
                n.SetTypecheck(1)
 
-       case ORECV:
+       case ir.ORECV:
                base.Fatalf("walkexpr ORECV") // should see inside OAS only
 
-       case OSLICEHEADER:
+       case ir.OSLICEHEADER:
                n.Left = walkexpr(n.Left, init)
                n.List.SetFirst(walkexpr(n.List.First(), init))
                n.List.SetSecond(walkexpr(n.List.Second(), init))
 
-       case OSLICE, OSLICEARR, OSLICESTR, OSLICE3, OSLICE3ARR:
-               checkSlice := checkPtr(Curfn, 1) && n.Op == OSLICE3ARR && n.Left.Op == OCONVNOP && n.Left.Left.Type.IsUnsafePtr()
+       case ir.OSLICE, ir.OSLICEARR, ir.OSLICESTR, ir.OSLICE3, ir.OSLICE3ARR:
+               checkSlice := checkPtr(Curfn, 1) && n.Op == ir.OSLICE3ARR && n.Left.Op == ir.OCONVNOP && n.Left.Left.Type.IsUnsafePtr()
                if checkSlice {
                        n.Left.Left = walkexpr(n.Left.Left, init)
                } else {
@@ -1135,12 +1136,12 @@ opswitch:
                        n.Left = walkCheckPtrAlignment(n.Left, init, max)
                }
                if n.Op.IsSlice3() {
-                       if max != nil && max.Op == OCAP && samesafeexpr(n.Left, max.Left) {
+                       if max != nil && max.Op == ir.OCAP && samesafeexpr(n.Left, max.Left) {
                                // Reduce x[i:j:cap(x)] to x[i:j].
-                               if n.Op == OSLICE3 {
-                                       n.Op = OSLICE
+                               if n.Op == ir.OSLICE3 {
+                                       n.Op = ir.OSLICE
                                } else {
-                                       n.Op = OSLICEARR
+                                       n.Op = ir.OSLICEARR
                                }
                                n = reduceSlice(n)
                        }
@@ -1148,7 +1149,7 @@ opswitch:
                        n = reduceSlice(n)
                }
 
-       case ONEW:
+       case ir.ONEW:
                if n.Type.Elem().NotInHeap() {
                        base.Errorf("%v can't be allocated in Go; it is incomplete (or unallocatable)", n.Type.Elem())
                }
@@ -1157,74 +1158,74 @@ opswitch:
                                base.Fatalf("large ONEW with EscNone: %v", n)
                        }
                        r := temp(n.Type.Elem())
-                       r = nod(OAS, r, nil) // zero temp
+                       r = ir.Nod(ir.OAS, r, nil) // zero temp
                        r = typecheck(r, ctxStmt)
                        init.Append(r)
-                       r = nod(OADDR, r.Left, nil)
+                       r = ir.Nod(ir.OADDR, r.Left, nil)
                        r = typecheck(r, ctxExpr)
                        n = r
                } else {
                        n = callnew(n.Type.Elem())
                }
 
-       case OADDSTR:
+       case ir.OADDSTR:
                n = addstr(n, init)
 
-       case OAPPEND:
+       case ir.OAPPEND:
                // order should make sure we only see OAS(node, OAPPEND), which we handle above.
                base.Fatalf("append outside assignment")
 
-       case OCOPY:
+       case ir.OCOPY:
                n = copyany(n, init, instrumenting && !base.Flag.CompilingRuntime)
 
                // cannot use chanfn - closechan takes any, not chan any
-       case OCLOSE:
+       case ir.OCLOSE:
                fn := syslook("closechan")
 
                fn = substArgTypes(fn, n.Left.Type)
                n = mkcall1(fn, nil, init, n.Left)
 
-       case OMAKECHAN:
+       case ir.OMAKECHAN:
                // When size fits into int, use makechan instead of
                // makechan64, which is faster and shorter on 32 bit platforms.
                size := n.Left
                fnname := "makechan64"
-               argtype := types.Types[TINT64]
+               argtype := types.Types[types.TINT64]
 
                // Type checking guarantees that TIDEAL size is positive and fits in an int.
                // The case of size overflow when converting TUINT or TUINTPTR to TINT
                // will be handled by the negative range checks in makechan during runtime.
-               if size.Type.IsKind(TIDEAL) || size.Type.Size() <= types.Types[TUINT].Size() {
+               if size.Type.IsKind(types.TIDEAL) || size.Type.Size() <= types.Types[types.TUINT].Size() {
                        fnname = "makechan"
-                       argtype = types.Types[TINT]
+                       argtype = types.Types[types.TINT]
                }
 
                n = mkcall1(chanfn(fnname, 1, n.Type), n.Type, init, typename(n.Type), conv(size, argtype))
 
-       case OMAKEMAP:
+       case ir.OMAKEMAP:
                t := n.Type
                hmapType := hmap(t)
                hint := n.Left
 
                // var h *hmap
-               var h *Node
+               var h *ir.Node
                if n.Esc == EscNone {
                        // Allocate hmap on stack.
 
                        // var hv hmap
                        hv := temp(hmapType)
-                       zero := nod(OAS, hv, nil)
+                       zero := ir.Nod(ir.OAS, hv, nil)
                        zero = typecheck(zero, ctxStmt)
                        init.Append(zero)
                        // h = &hv
-                       h = nod(OADDR, hv, nil)
+                       h = ir.Nod(ir.OADDR, hv, nil)
 
                        // Allocate one bucket pointed to by hmap.buckets on stack if hint
                        // is not larger than BUCKETSIZE. In case hint is larger than
                        // BUCKETSIZE runtime.makemap will allocate the buckets on the heap.
                        // Maximum key and elem size is 128 bytes, larger objects
                        // are stored with an indirection. So max bucket size is 2048+eps.
-                       if !Isconst(hint, constant.Int) ||
+                       if !ir.IsConst(hint, constant.Int) ||
                                constant.Compare(hint.Val(), token.LEQ, constant.MakeInt64(BUCKETSIZE)) {
 
                                // In case hint is larger than BUCKETSIZE runtime.makemap
@@ -1236,20 +1237,20 @@ opswitch:
                                //     h.buckets = b
                                // }
 
-                               nif := nod(OIF, nod(OLE, hint, nodintconst(BUCKETSIZE)), nil)
+                               nif := ir.Nod(ir.OIF, ir.Nod(ir.OLE, hint, nodintconst(BUCKETSIZE)), nil)
                                nif.SetLikely(true)
 
                                // var bv bmap
                                bv := temp(bmap(t))
-                               zero = nod(OAS, bv, nil)
+                               zero = ir.Nod(ir.OAS, bv, nil)
                                nif.Nbody.Append(zero)
 
                                // b = &bv
-                               b := nod(OADDR, bv, nil)
+                               b := ir.Nod(ir.OADDR, bv, nil)
 
                                // h.buckets = b
                                bsym := hmapType.Field(5).Sym // hmap.buckets see reflect.go:hmap
-                               na := nod(OAS, nodSym(ODOT, h, bsym), b)
+                               na := ir.Nod(ir.OAS, nodSym(ir.ODOT, h, bsym), b)
                                nif.Nbody.Append(na)
 
                                nif = typecheck(nif, ctxStmt)
@@ -1258,7 +1259,7 @@ opswitch:
                        }
                }
 
-               if Isconst(hint, constant.Int) && constant.Compare(hint.Val(), token.LEQ, constant.MakeInt64(BUCKETSIZE)) {
+               if ir.IsConst(hint, constant.Int) && constant.Compare(hint.Val(), token.LEQ, constant.MakeInt64(BUCKETSIZE)) {
                        // Handling make(map[any]any) and
                        // make(map[any]any, hint) where hint <= BUCKETSIZE
                        // special allows for faster map initialization and
@@ -1270,9 +1271,9 @@ opswitch:
                                // Only need to initialize h.hash0 since
                                // hmap h has been allocated on the stack already.
                                // h.hash0 = fastrand()
-                               rand := mkcall("fastrand", types.Types[TUINT32], init)
+                               rand := mkcall("fastrand", types.Types[types.TUINT32], init)
                                hashsym := hmapType.Field(4).Sym // hmap.hash0 see reflect.go:hmap
-                               a := nod(OAS, nodSym(ODOT, h, hashsym), rand)
+                               a := ir.Nod(ir.OAS, nodSym(ir.ODOT, h, hashsym), rand)
                                a = typecheck(a, ctxStmt)
                                a = walkexpr(a, init)
                                init.Append(a)
@@ -1296,15 +1297,15 @@ opswitch:
                        // When hint fits into int, use makemap instead of
                        // makemap64, which is faster and shorter on 32 bit platforms.
                        fnname := "makemap64"
-                       argtype := types.Types[TINT64]
+                       argtype := types.Types[types.TINT64]
 
                        // Type checking guarantees that TIDEAL hint is positive and fits in an int.
                        // See checkmake call in TMAP case of OMAKE case in OpSwitch in typecheck1 function.
                        // The case of hint overflow when converting TUINT or TUINTPTR to TINT
                        // will be handled by the negative range checks in makemap during runtime.
-                       if hint.Type.IsKind(TIDEAL) || hint.Type.Size() <= types.Types[TUINT].Size() {
+                       if hint.Type.IsKind(types.TIDEAL) || hint.Type.Size() <= types.Types[types.TUINT].Size() {
                                fnname = "makemap"
-                               argtype = types.Types[TINT]
+                               argtype = types.Types[types.TINT]
                        }
 
                        fn := syslook(fnname)
@@ -1312,7 +1313,7 @@ opswitch:
                        n = mkcall1(fn, n.Type, init, typename(n.Type), conv(hint, argtype), h)
                }
 
-       case OMAKESLICE:
+       case ir.OMAKESLICE:
                l := n.Left
                r := n.Right
                if r == nil {
@@ -1341,8 +1342,8 @@ opswitch:
                        //     if len < 0 { panicmakeslicelen() }
                        //     panicmakeslicecap()
                        // }
-                       nif := nod(OIF, nod(OGT, conv(l, types.Types[TUINT64]), nodintconst(i)), nil)
-                       niflen := nod(OIF, nod(OLT, l, nodintconst(0)), nil)
+                       nif := ir.Nod(ir.OIF, ir.Nod(ir.OGT, conv(l, types.Types[types.TUINT64]), nodintconst(i)), nil)
+                       niflen := ir.Nod(ir.OIF, ir.Nod(ir.OLT, l, nodintconst(0)), nil)
                        niflen.Nbody.Set1(mkcall("panicmakeslicelen", nil, init))
                        nif.Nbody.Append(niflen, mkcall("panicmakeslicecap", nil, init))
                        nif = typecheck(nif, ctxStmt)
@@ -1350,10 +1351,10 @@ opswitch:
 
                        t = types.NewArray(t.Elem(), i) // [r]T
                        var_ := temp(t)
-                       a := nod(OAS, var_, nil) // zero temp
+                       a := ir.Nod(ir.OAS, var_, nil) // zero temp
                        a = typecheck(a, ctxStmt)
                        init.Append(a)
-                       r := nod(OSLICE, var_, nil) // arr[:l]
+                       r := ir.Nod(ir.OSLICE, var_, nil) // arr[:l]
                        r.SetSliceBounds(nil, l, nil)
                        r = conv(r, n.Type) // in case n.Type is named.
                        r = typecheck(r, ctxExpr)
@@ -1367,31 +1368,31 @@ opswitch:
                        len, cap := l, r
 
                        fnname := "makeslice64"
-                       argtype := types.Types[TINT64]
+                       argtype := types.Types[types.TINT64]
 
                        // Type checking guarantees that TIDEAL len/cap are positive and fit in an int.
                        // The case of len or cap overflow when converting TUINT or TUINTPTR to TINT
                        // will be handled by the negative range checks in makeslice during runtime.
-                       if (len.Type.IsKind(TIDEAL) || len.Type.Size() <= types.Types[TUINT].Size()) &&
-                               (cap.Type.IsKind(TIDEAL) || cap.Type.Size() <= types.Types[TUINT].Size()) {
+                       if (len.Type.IsKind(types.TIDEAL) || len.Type.Size() <= types.Types[types.TUINT].Size()) &&
+                               (cap.Type.IsKind(types.TIDEAL) || cap.Type.Size() <= types.Types[types.TUINT].Size()) {
                                fnname = "makeslice"
-                               argtype = types.Types[TINT]
+                               argtype = types.Types[types.TINT]
                        }
 
-                       m := nod(OSLICEHEADER, nil, nil)
+                       m := ir.Nod(ir.OSLICEHEADER, nil, nil)
                        m.Type = t
 
                        fn := syslook(fnname)
-                       m.Left = mkcall1(fn, types.Types[TUNSAFEPTR], init, typename(t.Elem()), conv(len, argtype), conv(cap, argtype))
+                       m.Left = mkcall1(fn, types.Types[types.TUNSAFEPTR], init, typename(t.Elem()), conv(len, argtype), conv(cap, argtype))
                        m.Left.MarkNonNil()
-                       m.List.Set2(conv(len, types.Types[TINT]), conv(cap, types.Types[TINT]))
+                       m.List.Set2(conv(len, types.Types[types.TINT]), conv(cap, types.Types[types.TINT]))
 
                        m = typecheck(m, ctxExpr)
                        m = walkexpr(m, init)
                        n = m
                }
 
-       case OMAKESLICECOPY:
+       case ir.OMAKESLICECOPY:
                if n.Esc == EscNone {
                        base.Fatalf("OMAKESLICECOPY with EscNone: %v", n)
                }
@@ -1401,9 +1402,9 @@ opswitch:
                        base.Errorf("%v can't be allocated in Go; it is incomplete (or unallocatable)", t.Elem())
                }
 
-               length := conv(n.Left, types.Types[TINT])
-               copylen := nod(OLEN, n.Right, nil)
-               copyptr := nod(OSPTR, n.Right, nil)
+               length := conv(n.Left, types.Types[types.TINT])
+               copylen := ir.Nod(ir.OLEN, n.Right, nil)
+               copyptr := ir.Nod(ir.OSPTR, n.Right, nil)
 
                if !t.Elem().HasPointers() && n.Bounded() {
                        // When len(to)==len(from) and elements have no pointers:
@@ -1412,25 +1413,25 @@ opswitch:
                        // We do not check for overflow of len(to)*elem.Width here
                        // since len(from) is an existing checked slice capacity
                        // with same elem.Width for the from slice.
-                       size := nod(OMUL, conv(length, types.Types[TUINTPTR]), conv(nodintconst(t.Elem().Width), types.Types[TUINTPTR]))
+                       size := ir.Nod(ir.OMUL, conv(length, types.Types[types.TUINTPTR]), conv(nodintconst(t.Elem().Width), types.Types[types.TUINTPTR]))
 
                        // instantiate mallocgc(size uintptr, typ *byte, needszero bool) unsafe.Pointer
                        fn := syslook("mallocgc")
-                       sh := nod(OSLICEHEADER, nil, nil)
-                       sh.Left = mkcall1(fn, types.Types[TUNSAFEPTR], init, size, nodnil(), nodbool(false))
+                       sh := ir.Nod(ir.OSLICEHEADER, nil, nil)
+                       sh.Left = mkcall1(fn, types.Types[types.TUNSAFEPTR], init, size, nodnil(), nodbool(false))
                        sh.Left.MarkNonNil()
                        sh.List.Set2(length, length)
                        sh.Type = t
 
                        s := temp(t)
-                       r := typecheck(nod(OAS, s, sh), ctxStmt)
+                       r := typecheck(ir.Nod(ir.OAS, s, sh), ctxStmt)
                        r = walkexpr(r, init)
                        init.Append(r)
 
                        // instantiate memmove(to *any, frm *any, size uintptr)
                        fn = syslook("memmove")
                        fn = substArgTypes(fn, t.Elem(), t.Elem())
-                       ncopy := mkcall1(fn, nil, init, nod(OSPTR, s, nil), copyptr, size)
+                       ncopy := mkcall1(fn, nil, init, ir.Nod(ir.OSPTR, s, nil), copyptr, size)
                        ncopy = typecheck(ncopy, ctxStmt)
                        ncopy = walkexpr(ncopy, init)
                        init.Append(ncopy)
@@ -1439,8 +1440,8 @@ opswitch:
                } else { // Replace make+copy with runtime.makeslicecopy.
                        // instantiate makeslicecopy(typ *byte, tolen int, fromlen int, from unsafe.Pointer) unsafe.Pointer
                        fn := syslook("makeslicecopy")
-                       s := nod(OSLICEHEADER, nil, nil)
-                       s.Left = mkcall1(fn, types.Types[TUNSAFEPTR], init, typename(t.Elem()), length, copylen, conv(copyptr, types.Types[TUNSAFEPTR]))
+                       s := ir.Nod(ir.OSLICEHEADER, nil, nil)
+                       s.Left = mkcall1(fn, types.Types[types.TUNSAFEPTR], init, typename(t.Elem()), length, copylen, conv(copyptr, types.Types[types.TUNSAFEPTR]))
                        s.Left.MarkNonNil()
                        s.List.Set2(length, length)
                        s.Type = t
@@ -1448,33 +1449,33 @@ opswitch:
                        n = walkexpr(n, init)
                }
 
-       case ORUNESTR:
+       case ir.ORUNESTR:
                a := nodnil()
                if n.Esc == EscNone {
-                       t := types.NewArray(types.Types[TUINT8], 4)
-                       a = nod(OADDR, temp(t), nil)
+                       t := types.NewArray(types.Types[types.TUINT8], 4)
+                       a = ir.Nod(ir.OADDR, temp(t), nil)
                }
                // intstring(*[4]byte, rune)
-               n = mkcall("intstring", n.Type, init, a, conv(n.Left, types.Types[TINT64]))
+               n = mkcall("intstring", n.Type, init, a, conv(n.Left, types.Types[types.TINT64]))
 
-       case OBYTES2STR, ORUNES2STR:
+       case ir.OBYTES2STR, ir.ORUNES2STR:
                a := nodnil()
                if n.Esc == EscNone {
                        // Create temporary buffer for string on stack.
-                       t := types.NewArray(types.Types[TUINT8], tmpstringbufsize)
-                       a = nod(OADDR, temp(t), nil)
+                       t := types.NewArray(types.Types[types.TUINT8], tmpstringbufsize)
+                       a = ir.Nod(ir.OADDR, temp(t), nil)
                }
-               if n.Op == ORUNES2STR {
+               if n.Op == ir.ORUNES2STR {
                        // slicerunetostring(*[32]byte, []rune) string
                        n = mkcall("slicerunetostring", n.Type, init, a, n.Left)
                } else {
                        // slicebytetostring(*[32]byte, ptr *byte, n int) string
                        n.Left = cheapexpr(n.Left, init)
-                       ptr, len := n.Left.backingArrayPtrLen()
+                       ptr, len := backingArrayPtrLen(n.Left)
                        n = mkcall("slicebytetostring", n.Type, init, a, ptr, len)
                }
 
-       case OBYTES2STRTMP:
+       case ir.OBYTES2STRTMP:
                n.Left = walkexpr(n.Left, init)
                if !instrumenting {
                        // Let the backend handle OBYTES2STRTMP directly
@@ -1483,37 +1484,37 @@ opswitch:
                }
                // slicebytetostringtmp(ptr *byte, n int) string
                n.Left = cheapexpr(n.Left, init)
-               ptr, len := n.Left.backingArrayPtrLen()
+               ptr, len := backingArrayPtrLen(n.Left)
                n = mkcall("slicebytetostringtmp", n.Type, init, ptr, len)
 
-       case OSTR2BYTES:
+       case ir.OSTR2BYTES:
                s := n.Left
-               if Isconst(s, constant.String) {
+               if ir.IsConst(s, constant.String) {
                        sc := s.StringVal()
 
                        // Allocate a [n]byte of the right size.
-                       t := types.NewArray(types.Types[TUINT8], int64(len(sc)))
-                       var a *Node
+                       t := types.NewArray(types.Types[types.TUINT8], int64(len(sc)))
+                       var a *ir.Node
                        if n.Esc == EscNone && len(sc) <= int(maxImplicitStackVarSize) {
-                               a = nod(OADDR, temp(t), nil)
+                               a = ir.Nod(ir.OADDR, temp(t), nil)
                        } else {
                                a = callnew(t)
                        }
                        p := temp(t.PtrTo()) // *[n]byte
-                       init.Append(typecheck(nod(OAS, p, a), ctxStmt))
+                       init.Append(typecheck(ir.Nod(ir.OAS, p, a), ctxStmt))
 
                        // Copy from the static string data to the [n]byte.
                        if len(sc) > 0 {
-                               as := nod(OAS,
-                                       nod(ODEREF, p, nil),
-                                       nod(ODEREF, convnop(nod(OSPTR, s, nil), t.PtrTo()), nil))
+                               as := ir.Nod(ir.OAS,
+                                       ir.Nod(ir.ODEREF, p, nil),
+                                       ir.Nod(ir.ODEREF, convnop(ir.Nod(ir.OSPTR, s, nil), t.PtrTo()), nil))
                                as = typecheck(as, ctxStmt)
                                as = walkstmt(as)
                                init.Append(as)
                        }
 
                        // Slice the [n]byte to a []byte.
-                       n.Op = OSLICEARR
+                       n.Op = ir.OSLICEARR
                        n.Left = p
                        n = walkexpr(n, init)
                        break
@@ -1522,13 +1523,13 @@ opswitch:
                a := nodnil()
                if n.Esc == EscNone {
                        // Create temporary buffer for slice on stack.
-                       t := types.NewArray(types.Types[TUINT8], tmpstringbufsize)
-                       a = nod(OADDR, temp(t), nil)
+                       t := types.NewArray(types.Types[types.TUINT8], tmpstringbufsize)
+                       a = ir.Nod(ir.OADDR, temp(t), nil)
                }
                // stringtoslicebyte(*32[byte], string) []byte
-               n = mkcall("stringtoslicebyte", n.Type, init, a, conv(s, types.Types[TSTRING]))
+               n = mkcall("stringtoslicebyte", n.Type, init, a, conv(s, types.Types[types.TSTRING]))
 
-       case OSTR2BYTESTMP:
+       case ir.OSTR2BYTESTMP:
                // []byte(string) conversion that creates a slice
                // referring to the actual string bytes.
                // This conversion is handled later by the backend and
@@ -1538,17 +1539,17 @@ opswitch:
                // for i, c := range []byte(string)
                n.Left = walkexpr(n.Left, init)
 
-       case OSTR2RUNES:
+       case ir.OSTR2RUNES:
                a := nodnil()
                if n.Esc == EscNone {
                        // Create temporary buffer for slice on stack.
-                       t := types.NewArray(types.Types[TINT32], tmpstringbufsize)
-                       a = nod(OADDR, temp(t), nil)
+                       t := types.NewArray(types.Types[types.TINT32], tmpstringbufsize)
+                       a = ir.Nod(ir.OADDR, temp(t), nil)
                }
                // stringtoslicerune(*[32]rune, string) []rune
-               n = mkcall("stringtoslicerune", n.Type, init, a, conv(n.Left, types.Types[TSTRING]))
+               n = mkcall("stringtoslicerune", n.Type, init, a, conv(n.Left, types.Types[types.TSTRING]))
 
-       case OARRAYLIT, OSLICELIT, OMAPLIT, OSTRUCTLIT, OPTRLIT:
+       case ir.OARRAYLIT, ir.OSLICELIT, ir.OMAPLIT, ir.OSTRUCTLIT, ir.OPTRLIT:
                if isStaticCompositeLiteral(n) && !canSSAType(n.Type) {
                        // n can be directly represented in the read-only data section.
                        // Make direct reference to the static data. See issue 12841.
@@ -1562,17 +1563,17 @@ opswitch:
                anylit(n, var_, init)
                n = var_
 
-       case OSEND:
+       case ir.OSEND:
                n1 := n.Right
                n1 = assignconv(n1, n.Left.Type.Elem(), "chan send")
                n1 = walkexpr(n1, init)
-               n1 = nod(OADDR, n1, nil)
+               n1 = ir.Nod(ir.OADDR, n1, nil)
                n = mkcall1(chanfn("chansend1", 2, n.Left.Type), nil, init, n.Left, n1)
 
-       case OCLOSURE:
+       case ir.OCLOSURE:
                n = walkclosure(n, init)
 
-       case OCALLPART:
+       case ir.OCALLPART:
                n = walkpartialcall(n, init)
        }
 
@@ -1586,7 +1587,7 @@ opswitch:
        if n.Type != t {
                base.Fatalf("evconst changed Type: %v had type %v, now %v", n, t, n.Type)
        }
-       if n.Op == OLITERAL {
+       if n.Op == ir.OLITERAL {
                n = typecheck(n, ctxExpr)
                // Emit string symbol now to avoid emitting
                // any concurrently during the backend.
@@ -1598,7 +1599,7 @@ opswitch:
        updateHasCall(n)
 
        if base.Flag.LowerW != 0 && n != nil {
-               Dump("after walk expr", n)
+               ir.Dump("after walk expr", n)
        }
 
        base.Pos = lno
@@ -1618,10 +1619,10 @@ func markTypeUsedInInterface(t *types.Type, from *obj.LSym) {
 
 // markUsedIfaceMethod marks that an interface method is used in the current
 // function. n is OCALLINTER node.
-func markUsedIfaceMethod(n *Node) {
+func markUsedIfaceMethod(n *ir.Node) {
        ityp := n.Left.Left.Type
        tsym := typenamesym(ityp).Linksym()
-       r := obj.Addrel(Curfn.Func.lsym)
+       r := obj.Addrel(Curfn.Func.LSym)
        r.Sym = tsym
        // n.Left.Xoffset is the method index * Widthptr (the offset of code pointer
        // in itab).
@@ -1637,54 +1638,54 @@ func markUsedIfaceMethod(n *Node) {
 // If no such function is necessary, it returns (Txxx, Txxx).
 func rtconvfn(src, dst *types.Type) (param, result types.EType) {
        if thearch.SoftFloat {
-               return Txxx, Txxx
+               return types.Txxx, types.Txxx
        }
 
        switch thearch.LinkArch.Family {
        case sys.ARM, sys.MIPS:
                if src.IsFloat() {
                        switch dst.Etype {
-                       case TINT64, TUINT64:
-                               return TFLOAT64, dst.Etype
+                       case types.TINT64, types.TUINT64:
+                               return types.TFLOAT64, dst.Etype
                        }
                }
                if dst.IsFloat() {
                        switch src.Etype {
-                       case TINT64, TUINT64:
-                               return src.Etype, TFLOAT64
+                       case types.TINT64, types.TUINT64:
+                               return src.Etype, types.TFLOAT64
                        }
                }
 
        case sys.I386:
                if src.IsFloat() {
                        switch dst.Etype {
-                       case TINT64, TUINT64:
-                               return TFLOAT64, dst.Etype
-                       case TUINT32, TUINT, TUINTPTR:
-                               return TFLOAT64, TUINT32
+                       case types.TINT64, types.TUINT64:
+                               return types.TFLOAT64, dst.Etype
+                       case types.TUINT32, types.TUINT, types.TUINTPTR:
+                               return types.TFLOAT64, types.TUINT32
                        }
                }
                if dst.IsFloat() {
                        switch src.Etype {
-                       case TINT64, TUINT64:
-                               return src.Etype, TFLOAT64
-                       case TUINT32, TUINT, TUINTPTR:
-                               return TUINT32, TFLOAT64
+                       case types.TINT64, types.TUINT64:
+                               return src.Etype, types.TFLOAT64
+                       case types.TUINT32, types.TUINT, types.TUINTPTR:
+                               return types.TUINT32, types.TFLOAT64
                        }
                }
        }
-       return Txxx, Txxx
+       return types.Txxx, types.Txxx
 }
 
 // TODO(josharian): combine this with its caller and simplify
-func reduceSlice(n *Node) *Node {
+func reduceSlice(n *ir.Node) *ir.Node {
        low, high, max := n.SliceBounds()
-       if high != nil && high.Op == OLEN && samesafeexpr(n.Left, high.Left) {
+       if high != nil && high.Op == ir.OLEN && samesafeexpr(n.Left, high.Left) {
                // Reduce x[i:len(x)] to x[i:].
                high = nil
        }
        n.SetSliceBounds(low, high, max)
-       if (n.Op == OSLICE || n.Op == OSLICESTR) && low == nil && high == nil {
+       if (n.Op == ir.OSLICE || n.Op == ir.OSLICESTR) && low == nil && high == nil {
                // Reduce x[:] to x.
                if base.Debug.Slice > 0 {
                        base.Warn("slice: omit slice operation")
@@ -1694,19 +1695,19 @@ func reduceSlice(n *Node) *Node {
        return n
 }
 
-func ascompatee1(l *Node, r *Node, init *Nodes) *Node {
+func ascompatee1(l *ir.Node, r *ir.Node, init *ir.Nodes) *ir.Node {
        // convas will turn map assigns into function calls,
        // making it impossible for reorder3 to work.
-       n := nod(OAS, l, r)
+       n := ir.Nod(ir.OAS, l, r)
 
-       if l.Op == OINDEXMAP {
+       if l.Op == ir.OINDEXMAP {
                return n
        }
 
        return convas(n, init)
 }
 
-func ascompatee(op Op, nl, nr []*Node, init *Nodes) []*Node {
+func ascompatee(op ir.Op, nl, nr []*ir.Node, init *ir.Nodes) []*ir.Node {
        // check assign expression list to
        // an expression list. called in
        //      expr-list = expr-list
@@ -1719,14 +1720,14 @@ func ascompatee(op Op, nl, nr []*Node, init *Nodes) []*Node {
                nr[i1] = safeexpr(nr[i1], init)
        }
 
-       var nn []*Node
+       var nn []*ir.Node
        i := 0
        for ; i < len(nl); i++ {
                if i >= len(nr) {
                        break
                }
                // Do not generate 'x = x' during return. See issue 4014.
-               if op == ORETURN && samesafeexpr(nl[i], nr[i]) {
+               if op == ir.ORETURN && samesafeexpr(nl[i], nr[i]) {
                        continue
                }
                nn = append(nn, ascompatee1(nl[i], nr[i], init))
@@ -1734,17 +1735,17 @@ func ascompatee(op Op, nl, nr []*Node, init *Nodes) []*Node {
 
        // cannot happen: caller checked that lists had same length
        if i < len(nl) || i < len(nr) {
-               var nln, nrn Nodes
+               var nln, nrn ir.Nodes
                nln.Set(nl)
                nrn.Set(nr)
-               base.Fatalf("error in shape across %+v %v %+v / %d %d [%s]", nln, op, nrn, len(nl), len(nr), Curfn.funcname())
+               base.Fatalf("error in shape across %+v %v %+v / %d %d [%s]", nln, op, nrn, len(nl), len(nr), ir.FuncName(Curfn))
        }
        return nn
 }
 
 // fncall reports whether assigning an rvalue of type rt to an lvalue l might involve a function call.
-func fncall(l *Node, rt *types.Type) bool {
-       if l.HasCall() || l.Op == OINDEXMAP {
+func fncall(l *ir.Node, rt *types.Type) bool {
+       if l.HasCall() || l.Op == ir.OINDEXMAP {
                return true
        }
        if types.Identical(l.Type, rt) {
@@ -1757,14 +1758,14 @@ func fncall(l *Node, rt *types.Type) bool {
 // check assign type list to
 // an expression list. called in
 //     expr-list = func()
-func ascompatet(nl Nodes, nr *types.Type) []*Node {
+func ascompatet(nl ir.Nodes, nr *types.Type) []*ir.Node {
        if nl.Len() != nr.NumFields() {
                base.Fatalf("ascompatet: assignment count mismatch: %d = %d", nl.Len(), nr.NumFields())
        }
 
-       var nn, mm Nodes
+       var nn, mm ir.Nodes
        for i, l := range nl.Slice() {
-               if l.isBlank() {
+               if ir.IsBlank(l) {
                        continue
                }
                r := nr.Field(i)
@@ -1774,22 +1775,22 @@ func ascompatet(nl Nodes, nr *types.Type) []*Node {
                if fncall(l, r.Type) {
                        tmp := temp(r.Type)
                        tmp = typecheck(tmp, ctxExpr)
-                       a := nod(OAS, l, tmp)
+                       a := ir.Nod(ir.OAS, l, tmp)
                        a = convas(a, &mm)
                        mm.Append(a)
                        l = tmp
                }
 
-               res := nod(ORESULT, nil, nil)
+               res := ir.Nod(ir.ORESULT, nil, nil)
                res.Xoffset = base.Ctxt.FixedFrameSize() + r.Offset
                res.Type = r.Type
                res.SetTypecheck(1)
 
-               a := nod(OAS, l, res)
+               a := ir.Nod(ir.OAS, l, res)
                a = convas(a, &nn)
                updateHasCall(a)
                if a.HasCall() {
-                       Dump("ascompatet ucount", a)
+                       ir.Dump("ascompatet ucount", a)
                        base.Fatalf("ascompatet: too many function calls evaluating parameters")
                }
 
@@ -1799,13 +1800,13 @@ func ascompatet(nl Nodes, nr *types.Type) []*Node {
 }
 
 // package all the arguments that match a ... T parameter into a []T.
-func mkdotargslice(typ *types.Type, args []*Node) *Node {
-       var n *Node
+func mkdotargslice(typ *types.Type, args []*ir.Node) *ir.Node {
+       var n *ir.Node
        if len(args) == 0 {
                n = nodnil()
                n.Type = typ
        } else {
-               n = nod(OCOMPLIT, nil, typenod(typ))
+               n = ir.Nod(ir.OCOMPLIT, nil, typenod(typ))
                n.List.Append(args...)
                n.SetImplicit(true)
        }
@@ -1819,7 +1820,7 @@ func mkdotargslice(typ *types.Type, args []*Node) *Node {
 
 // fixVariadicCall rewrites calls to variadic functions to use an
 // explicit ... argument if one is not already present.
-func fixVariadicCall(call *Node) {
+func fixVariadicCall(call *ir.Node) {
        fntype := call.Left.Type
        if !fntype.IsVariadic() || call.IsDDD() {
                return
@@ -1839,7 +1840,7 @@ func fixVariadicCall(call *Node) {
        call.SetIsDDD(true)
 }
 
-func walkCall(n *Node, init *Nodes) {
+func walkCall(n *ir.Node, init *ir.Nodes) {
        if n.Rlist.Len() != 0 {
                return // already walked
        }
@@ -1851,8 +1852,8 @@ func walkCall(n *Node, init *Nodes) {
        walkexprlist(args, init)
 
        // If this is a method call, add the receiver at the beginning of the args.
-       if n.Op == OCALLMETH {
-               withRecv := make([]*Node, len(args)+1)
+       if n.Op == ir.OCALLMETH {
+               withRecv := make([]*ir.Node, len(args)+1)
                withRecv[0] = n.Left.Left
                n.Left.Left = nil
                copy(withRecv[1:], args)
@@ -1863,12 +1864,12 @@ func walkCall(n *Node, init *Nodes) {
        // store that argument into a temporary variable,
        // to prevent that calls from clobbering arguments already on the stack.
        // When instrumenting, all arguments might require function calls.
-       var tempAssigns []*Node
+       var tempAssigns []*ir.Node
        for i, arg := range args {
                updateHasCall(arg)
                // Determine param type.
                var t *types.Type
-               if n.Op == OCALLMETH {
+               if n.Op == ir.OCALLMETH {
                        if i == 0 {
                                t = n.Left.Type.Recv().Type
                        } else {
@@ -1880,7 +1881,7 @@ func walkCall(n *Node, init *Nodes) {
                if instrumenting || fncall(arg, t) {
                        // make assignment of fncall to tempAt
                        tmp := temp(t)
-                       a := nod(OAS, tmp, arg)
+                       a := ir.Nod(ir.OAS, tmp, arg)
                        a = convas(a, init)
                        tempAssigns = append(tempAssigns, a)
                        // replace arg with temp
@@ -1893,14 +1894,14 @@ func walkCall(n *Node, init *Nodes) {
 }
 
 // generate code for print
-func walkprint(nn *Node, init *Nodes) *Node {
+func walkprint(nn *ir.Node, init *ir.Nodes) *ir.Node {
        // Hoist all the argument evaluation up before the lock.
        walkexprlistcheap(nn.List.Slice(), init)
 
        // For println, add " " between elements and "\n" at the end.
-       if nn.Op == OPRINTN {
+       if nn.Op == ir.OPRINTN {
                s := nn.List.Slice()
-               t := make([]*Node, 0, len(s)*2)
+               t := make([]*ir.Node, 0, len(s)*2)
                for i, n := range s {
                        if i != 0 {
                                t = append(t, nodstr(" "))
@@ -1913,10 +1914,10 @@ func walkprint(nn *Node, init *Nodes) *Node {
 
        // Collapse runs of constant strings.
        s := nn.List.Slice()
-       t := make([]*Node, 0, len(s))
+       t := make([]*ir.Node, 0, len(s))
        for i := 0; i < len(s); {
                var strs []string
-               for i < len(s) && Isconst(s[i], constant.String) {
+               for i < len(s) && ir.IsConst(s[i], constant.String) {
                        strs = append(strs, s[i].StringVal())
                        i++
                }
@@ -1930,73 +1931,73 @@ func walkprint(nn *Node, init *Nodes) *Node {
        }
        nn.List.Set(t)
 
-       calls := []*Node{mkcall("printlock", nil, init)}
+       calls := []*ir.Node{mkcall("printlock", nil, init)}
        for i, n := range nn.List.Slice() {
-               if n.Op == OLITERAL {
+               if n.Op == ir.OLITERAL {
                        if n.Type == types.UntypedRune {
                                n = defaultlit(n, types.Runetype)
                        }
 
                        switch n.Val().Kind() {
                        case constant.Int:
-                               n = defaultlit(n, types.Types[TINT64])
+                               n = defaultlit(n, types.Types[types.TINT64])
 
                        case constant.Float:
-                               n = defaultlit(n, types.Types[TFLOAT64])
+                               n = defaultlit(n, types.Types[types.TFLOAT64])
                        }
                }
 
-               if n.Op != OLITERAL && n.Type != nil && n.Type.Etype == TIDEAL {
-                       n = defaultlit(n, types.Types[TINT64])
+               if n.Op != ir.OLITERAL && n.Type != nil && n.Type.Etype == types.TIDEAL {
+                       n = defaultlit(n, types.Types[types.TINT64])
                }
                n = defaultlit(n, nil)
                nn.List.SetIndex(i, n)
-               if n.Type == nil || n.Type.Etype == TFORW {
+               if n.Type == nil || n.Type.Etype == types.TFORW {
                        continue
                }
 
-               var on *Node
+               var on *ir.Node
                switch n.Type.Etype {
-               case TINTER:
+               case types.TINTER:
                        if n.Type.IsEmptyInterface() {
                                on = syslook("printeface")
                        } else {
                                on = syslook("printiface")
                        }
                        on = substArgTypes(on, n.Type) // any-1
-               case TPTR:
+               case types.TPTR:
                        if n.Type.Elem().NotInHeap() {
                                on = syslook("printuintptr")
-                               n = nod(OCONV, n, nil)
-                               n.Type = types.Types[TUNSAFEPTR]
-                               n = nod(OCONV, n, nil)
-                               n.Type = types.Types[TUINTPTR]
+                               n = ir.Nod(ir.OCONV, n, nil)
+                               n.Type = types.Types[types.TUNSAFEPTR]
+                               n = ir.Nod(ir.OCONV, n, nil)
+                               n.Type = types.Types[types.TUINTPTR]
                                break
                        }
                        fallthrough
-               case TCHAN, TMAP, TFUNC, TUNSAFEPTR:
+               case types.TCHAN, types.TMAP, types.TFUNC, types.TUNSAFEPTR:
                        on = syslook("printpointer")
                        on = substArgTypes(on, n.Type) // any-1
-               case TSLICE:
+               case types.TSLICE:
                        on = syslook("printslice")
                        on = substArgTypes(on, n.Type) // any-1
-               case TUINT, TUINT8, TUINT16, TUINT32, TUINT64, TUINTPTR:
+               case types.TUINT, types.TUINT8, types.TUINT16, types.TUINT32, types.TUINT64, types.TUINTPTR:
                        if isRuntimePkg(n.Type.Sym.Pkg) && n.Type.Sym.Name == "hex" {
                                on = syslook("printhex")
                        } else {
                                on = syslook("printuint")
                        }
-               case TINT, TINT8, TINT16, TINT32, TINT64:
+               case types.TINT, types.TINT8, types.TINT16, types.TINT32, types.TINT64:
                        on = syslook("printint")
-               case TFLOAT32, TFLOAT64:
+               case types.TFLOAT32, types.TFLOAT64:
                        on = syslook("printfloat")
-               case TCOMPLEX64, TCOMPLEX128:
+               case types.TCOMPLEX64, types.TCOMPLEX128:
                        on = syslook("printcomplex")
-               case TBOOL:
+               case types.TBOOL:
                        on = syslook("printbool")
-               case TSTRING:
+               case types.TSTRING:
                        cs := ""
-                       if Isconst(n, constant.String) {
+                       if ir.IsConst(n, constant.String) {
                                cs = n.StringVal()
                        }
                        switch cs {
@@ -2008,15 +2009,15 @@ func walkprint(nn *Node, init *Nodes) *Node {
                                on = syslook("printstring")
                        }
                default:
-                       badtype(OPRINT, n.Type, nil)
+                       badtype(ir.OPRINT, n.Type, nil)
                        continue
                }
 
-               r := nod(OCALL, on, nil)
+               r := ir.Nod(ir.OCALL, on, nil)
                if params := on.Type.Params().FieldSlice(); len(params) > 0 {
                        t := params[0].Type
                        if !types.Identical(t, n.Type) {
-                               n = nod(OCONV, n, nil)
+                               n = ir.Nod(ir.OCONV, n, nil)
                                n.Type = t
                        }
                        r.List.Append(n)
@@ -2029,16 +2030,16 @@ func walkprint(nn *Node, init *Nodes) *Node {
        typecheckslice(calls, ctxStmt)
        walkexprlist(calls, init)
 
-       r := nod(OEMPTY, nil, nil)
+       r := ir.Nod(ir.OEMPTY, nil, nil)
        r = typecheck(r, ctxStmt)
        r = walkexpr(r, init)
        r.Ninit.Set(calls)
        return r
 }
 
-func callnew(t *types.Type) *Node {
+func callnew(t *types.Type) *ir.Node {
        dowidth(t)
-       n := nod(ONEWOBJ, typename(t), nil)
+       n := ir.Nod(ir.ONEWOBJ, typename(t), nil)
        n.Type = types.NewPtr(t)
        n.SetTypecheck(1)
        n.MarkNonNil()
@@ -2047,16 +2048,16 @@ func callnew(t *types.Type) *Node {
 
 // isReflectHeaderDataField reports whether l is an expression p.Data
 // where p has type reflect.SliceHeader or reflect.StringHeader.
-func isReflectHeaderDataField(l *Node) bool {
-       if l.Type != types.Types[TUINTPTR] {
+func isReflectHeaderDataField(l *ir.Node) bool {
+       if l.Type != types.Types[types.TUINTPTR] {
                return false
        }
 
        var tsym *types.Sym
        switch l.Op {
-       case ODOT:
+       case ir.ODOT:
                tsym = l.Left.Type.Sym
-       case ODOTPTR:
+       case ir.ODOTPTR:
                tsym = l.Left.Type.Elem().Sym
        default:
                return false
@@ -2068,8 +2069,8 @@ func isReflectHeaderDataField(l *Node) bool {
        return tsym.Name == "SliceHeader" || tsym.Name == "StringHeader"
 }
 
-func convas(n *Node, init *Nodes) *Node {
-       if n.Op != OAS {
+func convas(n *ir.Node, init *ir.Nodes) *ir.Node {
+       if n.Op != ir.OAS {
                base.Fatalf("convas: not OAS %v", n.Op)
        }
        defer updateHasCall(n)
@@ -2086,7 +2087,7 @@ func convas(n *Node, init *Nodes) *Node {
                return n
        }
 
-       if n.Left.isBlank() {
+       if ir.IsBlank(n.Left) {
                n.Right = defaultlit(n.Right, nil)
                return n
        }
@@ -2106,25 +2107,25 @@ func convas(n *Node, init *Nodes) *Node {
 // be later use of an earlier lvalue.
 //
 // function calls have been removed.
-func reorder3(all []*Node) []*Node {
+func reorder3(all []*ir.Node) []*ir.Node {
        // If a needed expression may be affected by an
        // earlier assignment, make an early copy of that
        // expression and use the copy instead.
-       var early []*Node
+       var early []*ir.Node
 
-       var mapinit Nodes
+       var mapinit ir.Nodes
        for i, n := range all {
                l := n.Left
 
                // Save subexpressions needed on left side.
                // Drill through non-dereferences.
                for {
-                       if l.Op == ODOT || l.Op == OPAREN {
+                       if l.Op == ir.ODOT || l.Op == ir.OPAREN {
                                l = l.Left
                                continue
                        }
 
-                       if l.Op == OINDEX && l.Left.Type.IsArray() {
+                       if l.Op == ir.OINDEX && l.Left.Type.IsArray() {
                                l.Right = reorder3save(l.Right, all, i, &early)
                                l = l.Left
                                continue
@@ -2137,17 +2138,17 @@ func reorder3(all []*Node) []*Node {
                default:
                        base.Fatalf("reorder3 unexpected lvalue %#v", l.Op)
 
-               case ONAME:
+               case ir.ONAME:
                        break
 
-               case OINDEX, OINDEXMAP:
+               case ir.OINDEX, ir.OINDEXMAP:
                        l.Left = reorder3save(l.Left, all, i, &early)
                        l.Right = reorder3save(l.Right, all, i, &early)
-                       if l.Op == OINDEXMAP {
+                       if l.Op == ir.OINDEXMAP {
                                all[i] = convas(all[i], &mapinit)
                        }
 
-               case ODEREF, ODOTPTR:
+               case ir.ODEREF, ir.ODOTPTR:
                        l.Left = reorder3save(l.Left, all, i, &early)
                }
 
@@ -2165,13 +2166,13 @@ func reorder3(all []*Node) []*Node {
 // replace *np with that temp.
 // The result of reorder3save MUST be assigned back to n, e.g.
 //     n.Left = reorder3save(n.Left, all, i, early)
-func reorder3save(n *Node, all []*Node, i int, early *[]*Node) *Node {
+func reorder3save(n *ir.Node, all []*ir.Node, i int, early *[]*ir.Node) *ir.Node {
        if !aliased(n, all[:i]) {
                return n
        }
 
        q := temp(n.Type)
-       q = nod(OAS, q, n)
+       q = ir.Nod(ir.OAS, q, n)
        q = typecheck(q, ctxStmt)
        *early = append(*early, q)
        return q.Left
@@ -2179,15 +2180,15 @@ func reorder3save(n *Node, all []*Node, i int, early *[]*Node) *Node {
 
 // what's the outer value that a write to n affects?
 // outer value means containing struct or array.
-func outervalue(n *Node) *Node {
+func outervalue(n *ir.Node) *ir.Node {
        for {
                switch n.Op {
-               case OXDOT:
+               case ir.OXDOT:
                        base.Fatalf("OXDOT in walk")
-               case ODOT, OPAREN, OCONVNOP:
+               case ir.ODOT, ir.OPAREN, ir.OCONVNOP:
                        n = n.Left
                        continue
-               case OINDEX:
+               case ir.OINDEX:
                        if n.Left.Type != nil && n.Left.Type.IsArray() {
                                n = n.Left
                                continue
@@ -2200,14 +2201,14 @@ func outervalue(n *Node) *Node {
 
 // Is it possible that the computation of r might be
 // affected by assignments in all?
-func aliased(r *Node, all []*Node) bool {
+func aliased(r *ir.Node, all []*ir.Node) bool {
        if r == nil {
                return false
        }
 
        // Treat all fields of a struct as referring to the whole struct.
        // We could do better but we would have to keep track of the fields.
-       for r.Op == ODOT {
+       for r.Op == ir.ODOT {
                r = r.Left
        }
 
@@ -2219,12 +2220,12 @@ func aliased(r *Node, all []*Node) bool {
        memwrite := false
        for _, as := range all {
                // We can ignore assignments to blank.
-               if as.Left.isBlank() {
+               if ir.IsBlank(as.Left) {
                        continue
                }
 
                l := outervalue(as.Left)
-               if l.Op != ONAME {
+               if l.Op != ir.ONAME {
                        memwrite = true
                        continue
                }
@@ -2233,11 +2234,11 @@ func aliased(r *Node, all []*Node) bool {
                default:
                        base.Fatalf("unexpected class: %v, %v", l, l.Class())
 
-               case PAUTOHEAP, PEXTERN:
+               case ir.PAUTOHEAP, ir.PEXTERN:
                        memwrite = true
                        continue
 
-               case PAUTO, PPARAM, PPARAMOUT:
+               case ir.PAUTO, ir.PPARAM, ir.PPARAMOUT:
                        if l.Name.Addrtaken() {
                                memwrite = true
                                continue
@@ -2274,18 +2275,18 @@ func aliased(r *Node, all []*Node) bool {
 // does the evaluation of n only refer to variables
 // whose addresses have not been taken?
 // (and no other memory)
-func varexpr(n *Node) bool {
+func varexpr(n *ir.Node) bool {
        if n == nil {
                return true
        }
 
        switch n.Op {
-       case OLITERAL, ONIL:
+       case ir.OLITERAL, ir.ONIL:
                return true
 
-       case ONAME:
+       case ir.ONAME:
                switch n.Class() {
-               case PAUTO, PPARAM, PPARAMOUT:
+               case ir.PAUTO, ir.PPARAM, ir.PPARAMOUT:
                        if !n.Name.Addrtaken() {
                                return true
                        }
@@ -2293,30 +2294,30 @@ func varexpr(n *Node) bool {
 
                return false
 
-       case OADD,
-               OSUB,
-               OOR,
-               OXOR,
-               OMUL,
-               ODIV,
-               OMOD,
-               OLSH,
-               ORSH,
-               OAND,
-               OANDNOT,
-               OPLUS,
-               ONEG,
-               OBITNOT,
-               OPAREN,
-               OANDAND,
-               OOROR,
-               OCONV,
-               OCONVNOP,
-               OCONVIFACE,
-               ODOTTYPE:
+       case ir.OADD,
+               ir.OSUB,
+               ir.OOR,
+               ir.OXOR,
+               ir.OMUL,
+               ir.ODIV,
+               ir.OMOD,
+               ir.OLSH,
+               ir.ORSH,
+               ir.OAND,
+               ir.OANDNOT,
+               ir.OPLUS,
+               ir.ONEG,
+               ir.OBITNOT,
+               ir.OPAREN,
+               ir.OANDAND,
+               ir.OOROR,
+               ir.OCONV,
+               ir.OCONVNOP,
+               ir.OCONVIFACE,
+               ir.ODOTTYPE:
                return varexpr(n.Left) && varexpr(n.Right)
 
-       case ODOT: // but not ODOTPTR
+       case ir.ODOT: // but not ODOTPTR
                // Should have been handled in aliased.
                base.Fatalf("varexpr unexpected ODOT")
        }
@@ -2326,16 +2327,16 @@ func varexpr(n *Node) bool {
 }
 
 // is the name l mentioned in r?
-func vmatch2(l *Node, r *Node) bool {
+func vmatch2(l *ir.Node, r *ir.Node) bool {
        if r == nil {
                return false
        }
        switch r.Op {
        // match each right given left
-       case ONAME:
+       case ir.ONAME:
                return l == r
 
-       case OLITERAL, ONIL:
+       case ir.OLITERAL, ir.ONIL:
                return false
        }
 
@@ -2355,15 +2356,15 @@ func vmatch2(l *Node, r *Node) bool {
 
 // is any name mentioned in l also mentioned in r?
 // called by sinit.go
-func vmatch1(l *Node, r *Node) bool {
+func vmatch1(l *ir.Node, r *ir.Node) bool {
        // isolate all left sides
        if l == nil || r == nil {
                return false
        }
        switch l.Op {
-       case ONAME:
+       case ir.ONAME:
                switch l.Class() {
-               case PPARAM, PAUTO:
+               case ir.PPARAM, ir.PAUTO:
                        break
 
                default:
@@ -2376,7 +2377,7 @@ func vmatch1(l *Node, r *Node) bool {
 
                return vmatch2(l, r)
 
-       case OLITERAL, ONIL:
+       case ir.OLITERAL, ir.ONIL:
                return false
        }
 
@@ -2396,10 +2397,10 @@ func vmatch1(l *Node, r *Node) bool {
 
 // paramstoheap returns code to allocate memory for heap-escaped parameters
 // and to copy non-result parameters' values from the stack.
-func paramstoheap(params *types.Type) []*Node {
-       var nn []*Node
+func paramstoheap(params *types.Type) []*ir.Node {
+       var nn []*ir.Node
        for _, t := range params.Fields().Slice() {
-               v := asNode(t.Nname)
+               v := ir.AsNode(t.Nname)
                if v != nil && v.Sym != nil && strings.HasPrefix(v.Sym.Name, "~r") { // unnamed result
                        v = nil
                }
@@ -2408,9 +2409,9 @@ func paramstoheap(params *types.Type) []*Node {
                }
 
                if stackcopy := v.Name.Param.Stackcopy; stackcopy != nil {
-                       nn = append(nn, walkstmt(nod(ODCL, v, nil)))
-                       if stackcopy.Class() == PPARAM {
-                               nn = append(nn, walkstmt(typecheck(nod(OAS, v, stackcopy), ctxStmt)))
+                       nn = append(nn, walkstmt(ir.Nod(ir.ODCL, v, nil)))
+                       if stackcopy.Class() == ir.PPARAM {
+                               nn = append(nn, walkstmt(typecheck(ir.Nod(ir.OAS, v, stackcopy), ctxStmt)))
                        }
                }
        }
@@ -2427,14 +2428,14 @@ func paramstoheap(params *types.Type) []*Node {
 // The generated code is added to Curfn's Enter list.
 func zeroResults() {
        for _, f := range Curfn.Type.Results().Fields().Slice() {
-               v := asNode(f.Nname)
+               v := ir.AsNode(f.Nname)
                if v != nil && v.Name.Param.Heapaddr != nil {
                        // The local which points to the return value is the
                        // thing that needs zeroing. This is already handled
                        // by a Needzero annotation in plive.go:livenessepilogue.
                        continue
                }
-               if v.isParamHeapCopy() {
+               if isParamHeapCopy(v) {
                        // TODO(josharian/khr): Investigate whether we can switch to "continue" here,
                        // and document more in either case.
                        // In the review of CL 114797, Keith wrote (roughly):
@@ -2444,21 +2445,21 @@ func zeroResults() {
                        v = v.Name.Param.Stackcopy
                }
                // Zero the stack location containing f.
-               Curfn.Func.Enter.Append(nodl(Curfn.Pos, OAS, v, nil))
+               Curfn.Func.Enter.Append(ir.NodAt(Curfn.Pos, ir.OAS, v, nil))
        }
 }
 
 // returnsfromheap returns code to copy values for heap-escaped parameters
 // back to the stack.
-func returnsfromheap(params *types.Type) []*Node {
-       var nn []*Node
+func returnsfromheap(params *types.Type) []*ir.Node {
+       var nn []*ir.Node
        for _, t := range params.Fields().Slice() {
-               v := asNode(t.Nname)
+               v := ir.AsNode(t.Nname)
                if v == nil {
                        continue
                }
-               if stackcopy := v.Name.Param.Stackcopy; stackcopy != nil && stackcopy.Class() == PPARAMOUT {
-                       nn = append(nn, walkstmt(typecheck(nod(OAS, stackcopy, v), ctxStmt)))
+               if stackcopy := v.Name.Param.Stackcopy; stackcopy != nil && stackcopy.Class() == ir.PPARAMOUT {
+                       nn = append(nn, walkstmt(typecheck(ir.Nod(ir.OAS, stackcopy, v), ctxStmt)))
                }
        }
 
@@ -2480,8 +2481,8 @@ func heapmoves() {
        base.Pos = lno
 }
 
-func vmkcall(fn *Node, t *types.Type, init *Nodes, va []*Node) *Node {
-       if fn.Type == nil || fn.Type.Etype != TFUNC {
+func vmkcall(fn *ir.Node, t *types.Type, init *ir.Nodes, va []*ir.Node) *ir.Node {
+       if fn.Type == nil || fn.Type.Etype != types.TFUNC {
                base.Fatalf("mkcall %v %v", fn, fn.Type)
        }
 
@@ -2490,7 +2491,7 @@ func vmkcall(fn *Node, t *types.Type, init *Nodes, va []*Node) *Node {
                base.Fatalf("vmkcall %v needs %v args got %v", fn, n, len(va))
        }
 
-       r := nod(OCALL, fn, nil)
+       r := ir.Nod(ir.OCALL, fn, nil)
        r.List.Set(va)
        if fn.Type.NumResults() > 0 {
                r = typecheck(r, ctxExpr|ctxMultiOK)
@@ -2502,19 +2503,19 @@ func vmkcall(fn *Node, t *types.Type, init *Nodes, va []*Node) *Node {
        return r
 }
 
-func mkcall(name string, t *types.Type, init *Nodes, args ...*Node) *Node {
+func mkcall(name string, t *types.Type, init *ir.Nodes, args ...*ir.Node) *ir.Node {
        return vmkcall(syslook(name), t, init, args)
 }
 
-func mkcall1(fn *Node, t *types.Type, init *Nodes, args ...*Node) *Node {
+func mkcall1(fn *ir.Node, t *types.Type, init *ir.Nodes, args ...*ir.Node) *ir.Node {
        return vmkcall(fn, t, init, args)
 }
 
-func conv(n *Node, t *types.Type) *Node {
+func conv(n *ir.Node, t *types.Type) *ir.Node {
        if types.Identical(n.Type, t) {
                return n
        }
-       n = nod(OCONV, n, nil)
+       n = ir.Nod(ir.OCONV, n, nil)
        n.Type = t
        n = typecheck(n, ctxExpr)
        return n
@@ -2522,11 +2523,11 @@ func conv(n *Node, t *types.Type) *Node {
 
 // convnop converts node n to type t using the OCONVNOP op
 // and typechecks the result with ctxExpr.
-func convnop(n *Node, t *types.Type) *Node {
+func convnop(n *ir.Node, t *types.Type) *ir.Node {
        if types.Identical(n.Type, t) {
                return n
        }
-       n = nod(OCONVNOP, n, nil)
+       n = ir.Nod(ir.OCONVNOP, n, nil)
        n.Type = t
        n = typecheck(n, ctxExpr)
        return n
@@ -2535,23 +2536,23 @@ func convnop(n *Node, t *types.Type) *Node {
 // byteindex converts n, which is byte-sized, to an int used to index into an array.
 // We cannot use conv, because we allow converting bool to int here,
 // which is forbidden in user code.
-func byteindex(n *Node) *Node {
+func byteindex(n *ir.Node) *ir.Node {
        // We cannot convert from bool to int directly.
        // While converting from int8 to int is possible, it would yield
        // the wrong result for negative values.
        // Reinterpreting the value as an unsigned byte solves both cases.
-       if !types.Identical(n.Type, types.Types[TUINT8]) {
-               n = nod(OCONV, n, nil)
-               n.Type = types.Types[TUINT8]
+       if !types.Identical(n.Type, types.Types[types.TUINT8]) {
+               n = ir.Nod(ir.OCONV, n, nil)
+               n.Type = types.Types[types.TUINT8]
                n.SetTypecheck(1)
        }
-       n = nod(OCONV, n, nil)
-       n.Type = types.Types[TINT]
+       n = ir.Nod(ir.OCONV, n, nil)
+       n.Type = types.Types[types.TINT]
        n.SetTypecheck(1)
        return n
 }
 
-func chanfn(name string, n int, t *types.Type) *Node {
+func chanfn(name string, n int, t *types.Type) *ir.Node {
        if !t.IsChan() {
                base.Fatalf("chanfn %v", t)
        }
@@ -2567,7 +2568,7 @@ func chanfn(name string, n int, t *types.Type) *Node {
        return fn
 }
 
-func mapfn(name string, t *types.Type) *Node {
+func mapfn(name string, t *types.Type) *ir.Node {
        if !t.IsMap() {
                base.Fatalf("mapfn %v", t)
        }
@@ -2576,7 +2577,7 @@ func mapfn(name string, t *types.Type) *Node {
        return fn
 }
 
-func mapfndel(name string, t *types.Type) *Node {
+func mapfndel(name string, t *types.Type) *ir.Node {
        if !t.IsMap() {
                base.Fatalf("mapfn %v", t)
        }
@@ -2635,13 +2636,13 @@ func mapfast(t *types.Type) int {
        return mapslow
 }
 
-func writebarrierfn(name string, l *types.Type, r *types.Type) *Node {
+func writebarrierfn(name string, l *types.Type, r *types.Type) *ir.Node {
        fn := syslook(name)
        fn = substArgTypes(fn, l, r)
        return fn
 }
 
-func addstr(n *Node, init *Nodes) *Node {
+func addstr(n *ir.Node, init *ir.Nodes) *ir.Node {
        // order.expr rewrote OADDSTR to have a list of strings.
        c := n.List.Len()
 
@@ -2653,7 +2654,7 @@ func addstr(n *Node, init *Nodes) *Node {
        if n.Esc == EscNone {
                sz := int64(0)
                for _, n1 := range n.List.Slice() {
-                       if n1.Op == OLITERAL {
+                       if n1.Op == ir.OLITERAL {
                                sz += int64(len(n1.StringVal()))
                        }
                }
@@ -2661,15 +2662,15 @@ func addstr(n *Node, init *Nodes) *Node {
                // Don't allocate the buffer if the result won't fit.
                if sz < tmpstringbufsize {
                        // Create temporary buffer for result string on stack.
-                       t := types.NewArray(types.Types[TUINT8], tmpstringbufsize)
-                       buf = nod(OADDR, temp(t), nil)
+                       t := types.NewArray(types.Types[types.TUINT8], tmpstringbufsize)
+                       buf = ir.Nod(ir.OADDR, temp(t), nil)
                }
        }
 
        // build list of string arguments
-       args := []*Node{buf}
+       args := []*ir.Node{buf}
        for _, n2 := range n.List.Slice() {
-               args = append(args, conv(n2, types.Types[TSTRING]))
+               args = append(args, conv(n2, types.Types[types.TSTRING]))
        }
 
        var fn string
@@ -2681,18 +2682,18 @@ func addstr(n *Node, init *Nodes) *Node {
                // large numbers of strings are passed to the runtime as a slice.
                fn = "concatstrings"
 
-               t := types.NewSlice(types.Types[TSTRING])
-               slice := nod(OCOMPLIT, nil, typenod(t))
+               t := types.NewSlice(types.Types[types.TSTRING])
+               slice := ir.Nod(ir.OCOMPLIT, nil, typenod(t))
                if prealloc[n] != nil {
                        prealloc[slice] = prealloc[n]
                }
                slice.List.Set(args[1:]) // skip buf arg
-               args = []*Node{buf, slice}
+               args = []*ir.Node{buf, slice}
                slice.Esc = EscNone
        }
 
        cat := syslook(fn)
-       r := nod(OCALL, cat, nil)
+       r := ir.Nod(ir.OCALL, cat, nil)
        r.List.Set(args)
        r = typecheck(r, ctxExpr)
        r = walkexpr(r, init)
@@ -2701,7 +2702,7 @@ func addstr(n *Node, init *Nodes) *Node {
        return r
 }
 
-func walkAppendArgs(n *Node, init *Nodes) {
+func walkAppendArgs(n *ir.Node, init *ir.Nodes) {
        walkexprlistsafe(n.List.Slice(), init)
 
        // walkexprlistsafe will leave OINDEX (s[n]) alone if both s
@@ -2727,7 +2728,7 @@ func walkAppendArgs(n *Node, init *Nodes) {
 //   s
 //
 // l2 is allowed to be a string.
-func appendslice(n *Node, init *Nodes) *Node {
+func appendslice(n *ir.Node, init *ir.Nodes) *ir.Node {
        walkAppendArgs(n, init)
 
        l1 := n.List.First()
@@ -2735,82 +2736,82 @@ func appendslice(n *Node, init *Nodes) *Node {
        l2 = cheapexpr(l2, init)
        n.List.SetSecond(l2)
 
-       var nodes Nodes
+       var nodes ir.Nodes
 
        // var s []T
        s := temp(l1.Type)
-       nodes.Append(nod(OAS, s, l1)) // s = l1
+       nodes.Append(ir.Nod(ir.OAS, s, l1)) // s = l1
 
        elemtype := s.Type.Elem()
 
        // n := len(s) + len(l2)
-       nn := temp(types.Types[TINT])
-       nodes.Append(nod(OAS, nn, nod(OADD, nod(OLEN, s, nil), nod(OLEN, l2, nil))))
+       nn := temp(types.Types[types.TINT])
+       nodes.Append(ir.Nod(ir.OAS, nn, ir.Nod(ir.OADD, ir.Nod(ir.OLEN, s, nil), ir.Nod(ir.OLEN, l2, nil))))
 
        // if uint(n) > uint(cap(s))
-       nif := nod(OIF, nil, nil)
-       nuint := conv(nn, types.Types[TUINT])
-       scapuint := conv(nod(OCAP, s, nil), types.Types[TUINT])
-       nif.Left = nod(OGT, nuint, scapuint)
+       nif := ir.Nod(ir.OIF, nil, nil)
+       nuint := conv(nn, types.Types[types.TUINT])
+       scapuint := conv(ir.Nod(ir.OCAP, s, nil), types.Types[types.TUINT])
+       nif.Left = ir.Nod(ir.OGT, nuint, scapuint)
 
        // instantiate growslice(typ *type, []any, int) []any
        fn := syslook("growslice")
        fn = substArgTypes(fn, elemtype, elemtype)
 
        // s = growslice(T, s, n)
-       nif.Nbody.Set1(nod(OAS, s, mkcall1(fn, s.Type, &nif.Ninit, typename(elemtype), s, nn)))
+       nif.Nbody.Set1(ir.Nod(ir.OAS, s, mkcall1(fn, s.Type, &nif.Ninit, typename(elemtype), s, nn)))
        nodes.Append(nif)
 
        // s = s[:n]
-       nt := nod(OSLICE, s, nil)
+       nt := ir.Nod(ir.OSLICE, s, nil)
        nt.SetSliceBounds(nil, nn, nil)
        nt.SetBounded(true)
-       nodes.Append(nod(OAS, s, nt))
+       nodes.Append(ir.Nod(ir.OAS, s, nt))
 
-       var ncopy *Node
+       var ncopy *ir.Node
        if elemtype.HasPointers() {
                // copy(s[len(l1):], l2)
-               nptr1 := nod(OSLICE, s, nil)
+               nptr1 := ir.Nod(ir.OSLICE, s, nil)
                nptr1.Type = s.Type
-               nptr1.SetSliceBounds(nod(OLEN, l1, nil), nil, nil)
+               nptr1.SetSliceBounds(ir.Nod(ir.OLEN, l1, nil), nil, nil)
                nptr1 = cheapexpr(nptr1, &nodes)
 
                nptr2 := l2
 
-               Curfn.Func.setWBPos(n.Pos)
+               Curfn.Func.SetWBPos(n.Pos)
 
                // instantiate typedslicecopy(typ *type, dstPtr *any, dstLen int, srcPtr *any, srcLen int) int
                fn := syslook("typedslicecopy")
                fn = substArgTypes(fn, l1.Type.Elem(), l2.Type.Elem())
-               ptr1, len1 := nptr1.backingArrayPtrLen()
-               ptr2, len2 := nptr2.backingArrayPtrLen()
-               ncopy = mkcall1(fn, types.Types[TINT], &nodes, typename(elemtype), ptr1, len1, ptr2, len2)
+               ptr1, len1 := backingArrayPtrLen(nptr1)
+               ptr2, len2 := backingArrayPtrLen(nptr2)
+               ncopy = mkcall1(fn, types.Types[types.TINT], &nodes, typename(elemtype), ptr1, len1, ptr2, len2)
        } else if instrumenting && !base.Flag.CompilingRuntime {
                // rely on runtime to instrument:
                //  copy(s[len(l1):], l2)
                // l2 can be a slice or string.
-               nptr1 := nod(OSLICE, s, nil)
+               nptr1 := ir.Nod(ir.OSLICE, s, nil)
                nptr1.Type = s.Type
-               nptr1.SetSliceBounds(nod(OLEN, l1, nil), nil, nil)
+               nptr1.SetSliceBounds(ir.Nod(ir.OLEN, l1, nil), nil, nil)
                nptr1 = cheapexpr(nptr1, &nodes)
                nptr2 := l2
 
-               ptr1, len1 := nptr1.backingArrayPtrLen()
-               ptr2, len2 := nptr2.backingArrayPtrLen()
+               ptr1, len1 := backingArrayPtrLen(nptr1)
+               ptr2, len2 := backingArrayPtrLen(nptr2)
 
                fn := syslook("slicecopy")
                fn = substArgTypes(fn, ptr1.Type.Elem(), ptr2.Type.Elem())
-               ncopy = mkcall1(fn, types.Types[TINT], &nodes, ptr1, len1, ptr2, len2, nodintconst(elemtype.Width))
+               ncopy = mkcall1(fn, types.Types[types.TINT], &nodes, ptr1, len1, ptr2, len2, nodintconst(elemtype.Width))
        } else {
                // memmove(&s[len(l1)], &l2[0], len(l2)*sizeof(T))
-               nptr1 := nod(OINDEX, s, nod(OLEN, l1, nil))
+               nptr1 := ir.Nod(ir.OINDEX, s, ir.Nod(ir.OLEN, l1, nil))
                nptr1.SetBounded(true)
-               nptr1 = nod(OADDR, nptr1, nil)
+               nptr1 = ir.Nod(ir.OADDR, nptr1, nil)
 
-               nptr2 := nod(OSPTR, l2, nil)
+               nptr2 := ir.Nod(ir.OSPTR, l2, nil)
 
-               nwid := cheapexpr(conv(nod(OLEN, l2, nil), types.Types[TUINTPTR]), &nodes)
-               nwid = nod(OMUL, nwid, nodintconst(elemtype.Width))
+               nwid := cheapexpr(conv(ir.Nod(ir.OLEN, l2, nil), types.Types[types.TUINTPTR]), &nodes)
+               nwid = ir.Nod(ir.OMUL, nwid, nodintconst(elemtype.Width))
 
                // instantiate func memmove(to *any, frm *any, length uintptr)
                fn := syslook("memmove")
@@ -2827,7 +2828,7 @@ func appendslice(n *Node, init *Nodes) *Node {
 
 // isAppendOfMake reports whether n is of the form append(x , make([]T, y)...).
 // isAppendOfMake assumes n has already been typechecked.
-func isAppendOfMake(n *Node) bool {
+func isAppendOfMake(n *ir.Node) bool {
        if base.Flag.N != 0 || instrumenting {
                return false
        }
@@ -2836,12 +2837,12 @@ func isAppendOfMake(n *Node) bool {
                base.Fatalf("missing typecheck: %+v", n)
        }
 
-       if n.Op != OAPPEND || !n.IsDDD() || n.List.Len() != 2 {
+       if n.Op != ir.OAPPEND || !n.IsDDD() || n.List.Len() != 2 {
                return false
        }
 
        second := n.List.Second()
-       if second.Op != OMAKESLICE || second.Right != nil {
+       if second.Op != ir.OMAKESLICE || second.Right != nil {
                return false
        }
 
@@ -2852,7 +2853,7 @@ func isAppendOfMake(n *Node) bool {
 
        // The care of overflow of the len argument to make will be handled by an explicit check of int(len) < 0 during runtime.
        y := second.Left
-       if !Isconst(y, constant.Int) && y.Type.Size() > types.Types[TUINT].Size() {
+       if !ir.IsConst(y, constant.Int) && y.Type.Size() > types.Types[types.TUINT].Size() {
                return false
        }
 
@@ -2886,11 +2887,11 @@ func isAppendOfMake(n *Node) bool {
 //     }
 //   }
 //   s
-func extendslice(n *Node, init *Nodes) *Node {
+func extendslice(n *ir.Node, init *ir.Nodes) *ir.Node {
        // isAppendOfMake made sure all possible positive values of l2 fit into an uint.
        // The case of l2 overflow when converting from e.g. uint to int is handled by an explicit
        // check of l2 < 0 at runtime which is generated below.
-       l2 := conv(n.List.Second().Left, types.Types[TINT])
+       l2 := conv(n.List.Second().Left, types.Types[types.TINT])
        l2 = typecheck(l2, ctxExpr)
        n.List.SetSecond(l2) // walkAppendArgs expects l2 in n.List.Second().
 
@@ -2899,10 +2900,10 @@ func extendslice(n *Node, init *Nodes) *Node {
        l1 := n.List.First()
        l2 = n.List.Second() // re-read l2, as it may have been updated by walkAppendArgs
 
-       var nodes []*Node
+       var nodes []*ir.Node
 
        // if l2 >= 0 (likely happens), do nothing
-       nifneg := nod(OIF, nod(OGE, l2, nodintconst(0)), nil)
+       nifneg := ir.Nod(ir.OIF, ir.Nod(ir.OGE, l2, nodintconst(0)), nil)
        nifneg.SetLikely(true)
 
        // else panicmakeslicelen()
@@ -2911,67 +2912,67 @@ func extendslice(n *Node, init *Nodes) *Node {
 
        // s := l1
        s := temp(l1.Type)
-       nodes = append(nodes, nod(OAS, s, l1))
+       nodes = append(nodes, ir.Nod(ir.OAS, s, l1))
 
        elemtype := s.Type.Elem()
 
        // n := len(s) + l2
-       nn := temp(types.Types[TINT])
-       nodes = append(nodes, nod(OAS, nn, nod(OADD, nod(OLEN, s, nil), l2)))
+       nn := temp(types.Types[types.TINT])
+       nodes = append(nodes, ir.Nod(ir.OAS, nn, ir.Nod(ir.OADD, ir.Nod(ir.OLEN, s, nil), l2)))
 
        // if uint(n) > uint(cap(s))
-       nuint := conv(nn, types.Types[TUINT])
-       capuint := conv(nod(OCAP, s, nil), types.Types[TUINT])
-       nif := nod(OIF, nod(OGT, nuint, capuint), nil)
+       nuint := conv(nn, types.Types[types.TUINT])
+       capuint := conv(ir.Nod(ir.OCAP, s, nil), types.Types[types.TUINT])
+       nif := ir.Nod(ir.OIF, ir.Nod(ir.OGT, nuint, capuint), nil)
 
        // instantiate growslice(typ *type, old []any, newcap int) []any
        fn := syslook("growslice")
        fn = substArgTypes(fn, elemtype, elemtype)
 
        // s = growslice(T, s, n)
-       nif.Nbody.Set1(nod(OAS, s, mkcall1(fn, s.Type, &nif.Ninit, typename(elemtype), s, nn)))
+       nif.Nbody.Set1(ir.Nod(ir.OAS, s, mkcall1(fn, s.Type, &nif.Ninit, typename(elemtype), s, nn)))
        nodes = append(nodes, nif)
 
        // s = s[:n]
-       nt := nod(OSLICE, s, nil)
+       nt := ir.Nod(ir.OSLICE, s, nil)
        nt.SetSliceBounds(nil, nn, nil)
        nt.SetBounded(true)
-       nodes = append(nodes, nod(OAS, s, nt))
+       nodes = append(nodes, ir.Nod(ir.OAS, s, nt))
 
        // lptr := &l1[0]
        l1ptr := temp(l1.Type.Elem().PtrTo())
-       tmp := nod(OSPTR, l1, nil)
-       nodes = append(nodes, nod(OAS, l1ptr, tmp))
+       tmp := ir.Nod(ir.OSPTR, l1, nil)
+       nodes = append(nodes, ir.Nod(ir.OAS, l1ptr, tmp))
 
        // sptr := &s[0]
        sptr := temp(elemtype.PtrTo())
-       tmp = nod(OSPTR, s, nil)
-       nodes = append(nodes, nod(OAS, sptr, tmp))
+       tmp = ir.Nod(ir.OSPTR, s, nil)
+       nodes = append(nodes, ir.Nod(ir.OAS, sptr, tmp))
 
        // hp := &s[len(l1)]
-       hp := nod(OINDEX, s, nod(OLEN, l1, nil))
+       hp := ir.Nod(ir.OINDEX, s, ir.Nod(ir.OLEN, l1, nil))
        hp.SetBounded(true)
-       hp = nod(OADDR, hp, nil)
-       hp = convnop(hp, types.Types[TUNSAFEPTR])
+       hp = ir.Nod(ir.OADDR, hp, nil)
+       hp = convnop(hp, types.Types[types.TUNSAFEPTR])
 
        // hn := l2 * sizeof(elem(s))
-       hn := nod(OMUL, l2, nodintconst(elemtype.Width))
-       hn = conv(hn, types.Types[TUINTPTR])
+       hn := ir.Nod(ir.OMUL, l2, nodintconst(elemtype.Width))
+       hn = conv(hn, types.Types[types.TUINTPTR])
 
        clrname := "memclrNoHeapPointers"
        hasPointers := elemtype.HasPointers()
        if hasPointers {
                clrname = "memclrHasPointers"
-               Curfn.Func.setWBPos(n.Pos)
+               Curfn.Func.SetWBPos(n.Pos)
        }
 
-       var clr Nodes
+       var clr ir.Nodes
        clrfn := mkcall(clrname, nil, &clr, hp, hn)
        clr.Append(clrfn)
 
        if hasPointers {
                // if l1ptr == sptr
-               nifclr := nod(OIF, nod(OEQ, l1ptr, sptr), nil)
+               nifclr := ir.Nod(ir.OIF, ir.Nod(ir.OEQ, l1ptr, sptr), nil)
                nifclr.Nbody = clr
                nodes = append(nodes, nifclr)
        } else {
@@ -3005,7 +3006,7 @@ func extendslice(n *Node, init *Nodes) *Node {
 //     ...
 //   }
 //   s
-func walkappend(n *Node, init *Nodes, dst *Node) *Node {
+func walkappend(n *ir.Node, init *ir.Nodes, dst *ir.Node) *ir.Node {
        if !samesafeexpr(dst, n.List.First()) {
                n.List.SetFirst(safeexpr(n.List.First(), init))
                n.List.SetFirst(walkexpr(n.List.First(), init))
@@ -3041,39 +3042,39 @@ func walkappend(n *Node, init *Nodes, dst *Node) *Node {
                return n
        }
 
-       var l []*Node
+       var l []*ir.Node
 
        ns := temp(nsrc.Type)
-       l = append(l, nod(OAS, ns, nsrc)) // s = src
+       l = append(l, ir.Nod(ir.OAS, ns, nsrc)) // s = src
 
        na := nodintconst(int64(argc)) // const argc
-       nx := nod(OIF, nil, nil)       // if cap(s) - len(s) < argc
-       nx.Left = nod(OLT, nod(OSUB, nod(OCAP, ns, nil), nod(OLEN, ns, nil)), na)
+       nx := ir.Nod(ir.OIF, nil, nil) // if cap(s) - len(s) < argc
+       nx.Left = ir.Nod(ir.OLT, ir.Nod(ir.OSUB, ir.Nod(ir.OCAP, ns, nil), ir.Nod(ir.OLEN, ns, nil)), na)
 
        fn := syslook("growslice") //   growslice(<type>, old []T, mincap int) (ret []T)
        fn = substArgTypes(fn, ns.Type.Elem(), ns.Type.Elem())
 
-       nx.Nbody.Set1(nod(OAS, ns,
+       nx.Nbody.Set1(ir.Nod(ir.OAS, ns,
                mkcall1(fn, ns.Type, &nx.Ninit, typename(ns.Type.Elem()), ns,
-                       nod(OADD, nod(OLEN, ns, nil), na))))
+                       ir.Nod(ir.OADD, ir.Nod(ir.OLEN, ns, nil), na))))
 
        l = append(l, nx)
 
-       nn := temp(types.Types[TINT])
-       l = append(l, nod(OAS, nn, nod(OLEN, ns, nil))) // n = len(s)
+       nn := temp(types.Types[types.TINT])
+       l = append(l, ir.Nod(ir.OAS, nn, ir.Nod(ir.OLEN, ns, nil))) // n = len(s)
 
-       nx = nod(OSLICE, ns, nil) // ...s[:n+argc]
-       nx.SetSliceBounds(nil, nod(OADD, nn, na), nil)
+       nx = ir.Nod(ir.OSLICE, ns, nil) // ...s[:n+argc]
+       nx.SetSliceBounds(nil, ir.Nod(ir.OADD, nn, na), nil)
        nx.SetBounded(true)
-       l = append(l, nod(OAS, ns, nx)) // s = s[:n+argc]
+       l = append(l, ir.Nod(ir.OAS, ns, nx)) // s = s[:n+argc]
 
        ls = n.List.Slice()[1:]
        for i, n := range ls {
-               nx = nod(OINDEX, ns, nn) // s[n] ...
+               nx = ir.Nod(ir.OINDEX, ns, nn) // s[n] ...
                nx.SetBounded(true)
-               l = append(l, nod(OAS, nx, n)) // s[n] = arg
+               l = append(l, ir.Nod(ir.OAS, nx, n)) // s[n] = arg
                if i+1 < len(ls) {
-                       l = append(l, nod(OAS, nn, nod(OADD, nn, nodintconst(1)))) // n = n + 1
+                       l = append(l, ir.Nod(ir.OAS, nn, ir.Nod(ir.OADD, nn, nodintconst(1)))) // n = n + 1
                }
        }
 
@@ -3094,14 +3095,14 @@ func walkappend(n *Node, init *Nodes, dst *Node) *Node {
 //
 // Also works if b is a string.
 //
-func copyany(n *Node, init *Nodes, runtimecall bool) *Node {
+func copyany(n *ir.Node, init *ir.Nodes, runtimecall bool) *ir.Node {
        if n.Left.Type.Elem().HasPointers() {
-               Curfn.Func.setWBPos(n.Pos)
+               Curfn.Func.SetWBPos(n.Pos)
                fn := writebarrierfn("typedslicecopy", n.Left.Type.Elem(), n.Right.Type.Elem())
                n.Left = cheapexpr(n.Left, init)
-               ptrL, lenL := n.Left.backingArrayPtrLen()
+               ptrL, lenL := backingArrayPtrLen(n.Left)
                n.Right = cheapexpr(n.Right, init)
-               ptrR, lenR := n.Right.backingArrayPtrLen()
+               ptrR, lenR := backingArrayPtrLen(n.Right)
                return mkcall1(fn, n.Type, init, typename(n.Left.Type.Elem()), ptrL, lenL, ptrR, lenR)
        }
 
@@ -3111,9 +3112,9 @@ func copyany(n *Node, init *Nodes, runtimecall bool) *Node {
                // n.Right can be a slice or string.
 
                n.Left = cheapexpr(n.Left, init)
-               ptrL, lenL := n.Left.backingArrayPtrLen()
+               ptrL, lenL := backingArrayPtrLen(n.Left)
                n.Right = cheapexpr(n.Right, init)
-               ptrR, lenR := n.Right.backingArrayPtrLen()
+               ptrR, lenR := backingArrayPtrLen(n.Right)
 
                fn := syslook("slicecopy")
                fn = substArgTypes(fn, ptrL.Type.Elem(), ptrR.Type.Elem())
@@ -3125,36 +3126,36 @@ func copyany(n *Node, init *Nodes, runtimecall bool) *Node {
        n.Right = walkexpr(n.Right, init)
        nl := temp(n.Left.Type)
        nr := temp(n.Right.Type)
-       var l []*Node
-       l = append(l, nod(OAS, nl, n.Left))
-       l = append(l, nod(OAS, nr, n.Right))
+       var l []*ir.Node
+       l = append(l, ir.Nod(ir.OAS, nl, n.Left))
+       l = append(l, ir.Nod(ir.OAS, nr, n.Right))
 
-       nfrm := nod(OSPTR, nr, nil)
-       nto := nod(OSPTR, nl, nil)
+       nfrm := ir.Nod(ir.OSPTR, nr, nil)
+       nto := ir.Nod(ir.OSPTR, nl, nil)
 
-       nlen := temp(types.Types[TINT])
+       nlen := temp(types.Types[types.TINT])
 
        // n = len(to)
-       l = append(l, nod(OAS, nlen, nod(OLEN, nl, nil)))
+       l = append(l, ir.Nod(ir.OAS, nlen, ir.Nod(ir.OLEN, nl, nil)))
 
        // if n > len(frm) { n = len(frm) }
-       nif := nod(OIF, nil, nil)
+       nif := ir.Nod(ir.OIF, nil, nil)
 
-       nif.Left = nod(OGT, nlen, nod(OLEN, nr, nil))
-       nif.Nbody.Append(nod(OAS, nlen, nod(OLEN, nr, nil)))
+       nif.Left = ir.Nod(ir.OGT, nlen, ir.Nod(ir.OLEN, nr, nil))
+       nif.Nbody.Append(ir.Nod(ir.OAS, nlen, ir.Nod(ir.OLEN, nr, nil)))
        l = append(l, nif)
 
        // if to.ptr != frm.ptr { memmove( ... ) }
-       ne := nod(OIF, nod(ONE, nto, nfrm), nil)
+       ne := ir.Nod(ir.OIF, ir.Nod(ir.ONE, nto, nfrm), nil)
        ne.SetLikely(true)
        l = append(l, ne)
 
        fn := syslook("memmove")
        fn = substArgTypes(fn, nl.Type.Elem(), nl.Type.Elem())
-       nwid := temp(types.Types[TUINTPTR])
-       setwid := nod(OAS, nwid, conv(nlen, types.Types[TUINTPTR]))
+       nwid := temp(types.Types[types.TUINTPTR])
+       setwid := ir.Nod(ir.OAS, nwid, conv(nlen, types.Types[types.TUINTPTR]))
        ne.Nbody.Append(setwid)
-       nwid = nod(OMUL, nwid, nodintconst(nl.Type.Elem().Width))
+       nwid = ir.Nod(ir.OMUL, nwid, nodintconst(nl.Type.Elem().Width))
        call := mkcall1(fn, nil, init, nto, nfrm, nwid)
        ne.Nbody.Append(call)
 
@@ -3164,7 +3165,7 @@ func copyany(n *Node, init *Nodes, runtimecall bool) *Node {
        return nlen
 }
 
-func eqfor(t *types.Type) (n *Node, needsize bool) {
+func eqfor(t *types.Type) (n *ir.Node, needsize bool) {
        // Should only arrive here with large memory or
        // a struct/array containing a non-memory field/element.
        // Small memory is handled inline, and single non-memory
@@ -3176,13 +3177,13 @@ func eqfor(t *types.Type) (n *Node, needsize bool) {
                return n, true
        case ASPECIAL:
                sym := typesymprefix(".eq", t)
-               n := newname(sym)
+               n := NewName(sym)
                setNodeNameFunc(n)
-               n.Type = functype(nil, []*Node{
+               n.Type = functype(nil, []*ir.Node{
                        anonfield(types.NewPtr(t)),
                        anonfield(types.NewPtr(t)),
-               }, []*Node{
-                       anonfield(types.Types[TBOOL]),
+               }, []*ir.Node{
+                       anonfield(types.Types[types.TBOOL]),
                })
                return n, false
        }
@@ -3192,8 +3193,8 @@ func eqfor(t *types.Type) (n *Node, needsize bool) {
 
 // The result of walkcompare MUST be assigned back to n, e.g.
 //     n.Left = walkcompare(n.Left, init)
-func walkcompare(n *Node, init *Nodes) *Node {
-       if n.Left.Type.IsInterface() && n.Right.Type.IsInterface() && n.Left.Op != ONIL && n.Right.Op != ONIL {
+func walkcompare(n *ir.Node, init *ir.Nodes) *ir.Node {
+       if n.Left.Type.IsInterface() && n.Right.Type.IsInterface() && n.Left.Op != ir.ONIL && n.Right.Op != ir.ONIL {
                return walkcompareInterface(n, init)
        }
 
@@ -3218,31 +3219,31 @@ func walkcompare(n *Node, init *Nodes) *Node {
 
                // Handle both == and !=.
                eq := n.Op
-               andor := OOROR
-               if eq == OEQ {
-                       andor = OANDAND
+               andor := ir.OOROR
+               if eq == ir.OEQ {
+                       andor = ir.OANDAND
                }
                // Check for types equal.
                // For empty interface, this is:
                //   l.tab == type(r)
                // For non-empty interface, this is:
                //   l.tab != nil && l.tab._type == type(r)
-               var eqtype *Node
-               tab := nod(OITAB, l, nil)
+               var eqtype *ir.Node
+               tab := ir.Nod(ir.OITAB, l, nil)
                rtyp := typename(r.Type)
                if l.Type.IsEmptyInterface() {
-                       tab.Type = types.NewPtr(types.Types[TUINT8])
+                       tab.Type = types.NewPtr(types.Types[types.TUINT8])
                        tab.SetTypecheck(1)
-                       eqtype = nod(eq, tab, rtyp)
+                       eqtype = ir.Nod(eq, tab, rtyp)
                } else {
-                       nonnil := nod(brcom(eq), nodnil(), tab)
-                       match := nod(eq, itabType(tab), rtyp)
-                       eqtype = nod(andor, nonnil, match)
+                       nonnil := ir.Nod(brcom(eq), nodnil(), tab)
+                       match := ir.Nod(eq, itabType(tab), rtyp)
+                       eqtype = ir.Nod(andor, nonnil, match)
                }
                // Check for data equal.
-               eqdata := nod(eq, ifaceData(n.Pos, l, r.Type), r)
+               eqdata := ir.Nod(eq, ifaceData(n.Pos, l, r.Type), r)
                // Put it all together.
-               expr := nod(andor, eqtype, eqdata)
+               expr := ir.Nod(andor, eqtype, eqdata)
                n = finishcompare(n, expr, init)
                return n
        }
@@ -3272,10 +3273,10 @@ func walkcompare(n *Node, init *Nodes) *Node {
                        // instead, and arrange for the constant
                        // operand to be the first argument.
                        l, r := n.Left, n.Right
-                       if r.Op == OLITERAL {
+                       if r.Op == ir.OLITERAL {
                                l, r = r, l
                        }
-                       constcmp := l.Op == OLITERAL && r.Op != OLITERAL
+                       constcmp := l.Op == ir.OLITERAL && r.Op != ir.OLITERAL
 
                        var fn string
                        var paramType *types.Type
@@ -3285,44 +3286,44 @@ func walkcompare(n *Node, init *Nodes) *Node {
                                if constcmp {
                                        fn = "libfuzzerTraceConstCmp1"
                                }
-                               paramType = types.Types[TUINT8]
+                               paramType = types.Types[types.TUINT8]
                        case 2:
                                fn = "libfuzzerTraceCmp2"
                                if constcmp {
                                        fn = "libfuzzerTraceConstCmp2"
                                }
-                               paramType = types.Types[TUINT16]
+                               paramType = types.Types[types.TUINT16]
                        case 4:
                                fn = "libfuzzerTraceCmp4"
                                if constcmp {
                                        fn = "libfuzzerTraceConstCmp4"
                                }
-                               paramType = types.Types[TUINT32]
+                               paramType = types.Types[types.TUINT32]
                        case 8:
                                fn = "libfuzzerTraceCmp8"
                                if constcmp {
                                        fn = "libfuzzerTraceConstCmp8"
                                }
-                               paramType = types.Types[TUINT64]
+                               paramType = types.Types[types.TUINT64]
                        default:
                                base.Fatalf("unexpected integer size %d for %v", t.Size(), t)
                        }
                        init.Append(mkcall(fn, nil, init, tracecmpArg(l, paramType, init), tracecmpArg(r, paramType, init)))
                }
                return n
-       case TARRAY:
+       case types.TARRAY:
                // We can compare several elements at once with 2/4/8 byte integer compares
                inline = t.NumElem() <= 1 || (issimple[t.Elem().Etype] && (t.NumElem() <= 4 || t.Elem().Width*t.NumElem() <= maxcmpsize))
-       case TSTRUCT:
+       case types.TSTRUCT:
                inline = t.NumComponents(types.IgnoreBlankFields) <= 4
        }
 
        cmpl := n.Left
-       for cmpl != nil && cmpl.Op == OCONVNOP {
+       for cmpl != nil && cmpl.Op == ir.OCONVNOP {
                cmpl = cmpl.Left
        }
        cmpr := n.Right
-       for cmpr != nil && cmpr.Op == OCONVNOP {
+       for cmpr != nil && cmpr.Op == ir.OCONVNOP {
                cmpr = cmpr.Left
        }
 
@@ -3334,32 +3335,32 @@ func walkcompare(n *Node, init *Nodes) *Node {
                }
 
                fn, needsize := eqfor(t)
-               call := nod(OCALL, fn, nil)
-               call.List.Append(nod(OADDR, cmpl, nil))
-               call.List.Append(nod(OADDR, cmpr, nil))
+               call := ir.Nod(ir.OCALL, fn, nil)
+               call.List.Append(ir.Nod(ir.OADDR, cmpl, nil))
+               call.List.Append(ir.Nod(ir.OADDR, cmpr, nil))
                if needsize {
                        call.List.Append(nodintconst(t.Width))
                }
                res := call
-               if n.Op != OEQ {
-                       res = nod(ONOT, res, nil)
+               if n.Op != ir.OEQ {
+                       res = ir.Nod(ir.ONOT, res, nil)
                }
                n = finishcompare(n, res, init)
                return n
        }
 
        // inline: build boolean expression comparing element by element
-       andor := OANDAND
-       if n.Op == ONE {
-               andor = OOROR
+       andor := ir.OANDAND
+       if n.Op == ir.ONE {
+               andor = ir.OOROR
        }
-       var expr *Node
-       compare := func(el, er *Node) {
-               a := nod(n.Op, el, er)
+       var expr *ir.Node
+       compare := func(el, er *ir.Node) {
+               a := ir.Nod(n.Op, el, er)
                if expr == nil {
                        expr = a
                } else {
-                       expr = nod(andor, expr, a)
+                       expr = ir.Nod(andor, expr, a)
                }
        }
        cmpl = safeexpr(cmpl, init)
@@ -3371,8 +3372,8 @@ func walkcompare(n *Node, init *Nodes) *Node {
                                continue
                        }
                        compare(
-                               nodSym(OXDOT, cmpl, sym),
-                               nodSym(OXDOT, cmpr, sym),
+                               nodSym(ir.OXDOT, cmpl, sym),
+                               nodSym(ir.OXDOT, cmpr, sym),
                        )
                }
        } else {
@@ -3385,45 +3386,45 @@ func walkcompare(n *Node, init *Nodes) *Node {
                        var convType *types.Type
                        switch {
                        case remains >= 8 && combine64bit:
-                               convType = types.Types[TINT64]
+                               convType = types.Types[types.TINT64]
                                step = 8 / t.Elem().Width
                        case remains >= 4 && combine32bit:
-                               convType = types.Types[TUINT32]
+                               convType = types.Types[types.TUINT32]
                                step = 4 / t.Elem().Width
                        case remains >= 2 && combine16bit:
-                               convType = types.Types[TUINT16]
+                               convType = types.Types[types.TUINT16]
                                step = 2 / t.Elem().Width
                        default:
                                step = 1
                        }
                        if step == 1 {
                                compare(
-                                       nod(OINDEX, cmpl, nodintconst(i)),
-                                       nod(OINDEX, cmpr, nodintconst(i)),
+                                       ir.Nod(ir.OINDEX, cmpl, nodintconst(i)),
+                                       ir.Nod(ir.OINDEX, cmpr, nodintconst(i)),
                                )
                                i++
                                remains -= t.Elem().Width
                        } else {
                                elemType := t.Elem().ToUnsigned()
-                               cmplw := nod(OINDEX, cmpl, nodintconst(i))
+                               cmplw := ir.Nod(ir.OINDEX, cmpl, nodintconst(i))
                                cmplw = conv(cmplw, elemType) // convert to unsigned
                                cmplw = conv(cmplw, convType) // widen
-                               cmprw := nod(OINDEX, cmpr, nodintconst(i))
+                               cmprw := ir.Nod(ir.OINDEX, cmpr, nodintconst(i))
                                cmprw = conv(cmprw, elemType)
                                cmprw = conv(cmprw, convType)
                                // For code like this:  uint32(s[0]) | uint32(s[1])<<8 | uint32(s[2])<<16 ...
                                // ssa will generate a single large load.
                                for offset := int64(1); offset < step; offset++ {
-                                       lb := nod(OINDEX, cmpl, nodintconst(i+offset))
+                                       lb := ir.Nod(ir.OINDEX, cmpl, nodintconst(i+offset))
                                        lb = conv(lb, elemType)
                                        lb = conv(lb, convType)
-                                       lb = nod(OLSH, lb, nodintconst(8*t.Elem().Width*offset))
-                                       cmplw = nod(OOR, cmplw, lb)
-                                       rb := nod(OINDEX, cmpr, nodintconst(i+offset))
+                                       lb = ir.Nod(ir.OLSH, lb, nodintconst(8*t.Elem().Width*offset))
+                                       cmplw = ir.Nod(ir.OOR, cmplw, lb)
+                                       rb := ir.Nod(ir.OINDEX, cmpr, nodintconst(i+offset))
                                        rb = conv(rb, elemType)
                                        rb = conv(rb, convType)
-                                       rb = nod(OLSH, rb, nodintconst(8*t.Elem().Width*offset))
-                                       cmprw = nod(OOR, cmprw, rb)
+                                       rb = ir.Nod(ir.OLSH, rb, nodintconst(8*t.Elem().Width*offset))
+                                       cmprw = ir.Nod(ir.OOR, cmprw, rb)
                                }
                                compare(cmplw, cmprw)
                                i += step
@@ -3432,13 +3433,13 @@ func walkcompare(n *Node, init *Nodes) *Node {
                }
        }
        if expr == nil {
-               expr = nodbool(n.Op == OEQ)
+               expr = nodbool(n.Op == ir.OEQ)
                // We still need to use cmpl and cmpr, in case they contain
                // an expression which might panic. See issue 23837.
                t := temp(cmpl.Type)
-               a1 := nod(OAS, t, cmpl)
+               a1 := ir.Nod(ir.OAS, t, cmpl)
                a1 = typecheck(a1, ctxStmt)
-               a2 := nod(OAS, t, cmpr)
+               a2 := ir.Nod(ir.OAS, t, cmpr)
                a2 = typecheck(a2, ctxStmt)
                init.Append(a1, a2)
        }
@@ -3446,39 +3447,39 @@ func walkcompare(n *Node, init *Nodes) *Node {
        return n
 }
 
-func tracecmpArg(n *Node, t *types.Type, init *Nodes) *Node {
+func tracecmpArg(n *ir.Node, t *types.Type, init *ir.Nodes) *ir.Node {
        // Ugly hack to avoid "constant -1 overflows uintptr" errors, etc.
-       if n.Op == OLITERAL && n.Type.IsSigned() && n.Int64Val() < 0 {
+       if n.Op == ir.OLITERAL && n.Type.IsSigned() && n.Int64Val() < 0 {
                n = copyexpr(n, n.Type, init)
        }
 
        return conv(n, t)
 }
 
-func walkcompareInterface(n *Node, init *Nodes) *Node {
+func walkcompareInterface(n *ir.Node, init *ir.Nodes) *ir.Node {
        n.Right = cheapexpr(n.Right, init)
        n.Left = cheapexpr(n.Left, init)
        eqtab, eqdata := eqinterface(n.Left, n.Right)
-       var cmp *Node
-       if n.Op == OEQ {
-               cmp = nod(OANDAND, eqtab, eqdata)
+       var cmp *ir.Node
+       if n.Op == ir.OEQ {
+               cmp = ir.Nod(ir.OANDAND, eqtab, eqdata)
        } else {
-               eqtab.Op = ONE
-               cmp = nod(OOROR, eqtab, nod(ONOT, eqdata, nil))
+               eqtab.Op = ir.ONE
+               cmp = ir.Nod(ir.OOROR, eqtab, ir.Nod(ir.ONOT, eqdata, nil))
        }
        return finishcompare(n, cmp, init)
 }
 
-func walkcompareString(n *Node, init *Nodes) *Node {
+func walkcompareString(n *ir.Node, init *ir.Nodes) *ir.Node {
        // Rewrite comparisons to short constant strings as length+byte-wise comparisons.
-       var cs, ncs *Node // const string, non-const string
+       var cs, ncs *ir.Node // const string, non-const string
        switch {
-       case Isconst(n.Left, constant.String) && Isconst(n.Right, constant.String):
+       case ir.IsConst(n.Left, constant.String) && ir.IsConst(n.Right, constant.String):
                // ignore; will be constant evaluated
-       case Isconst(n.Left, constant.String):
+       case ir.IsConst(n.Left, constant.String):
                cs = n.Left
                ncs = n.Right
-       case Isconst(n.Right, constant.String):
+       case ir.IsConst(n.Right, constant.String):
                cs = n.Right
                ncs = n.Left
        }
@@ -3487,7 +3488,7 @@ func walkcompareString(n *Node, init *Nodes) *Node {
                // Our comparison below assumes that the non-constant string
                // is on the left hand side, so rewrite "" cmp x to x cmp "".
                // See issue 24817.
-               if Isconst(n.Left, constant.String) {
+               if ir.IsConst(n.Left, constant.String) {
                        cmp = brrev(cmp)
                }
 
@@ -3506,12 +3507,12 @@ func walkcompareString(n *Node, init *Nodes) *Node {
                        combine64bit = thearch.LinkArch.RegSize >= 8
                }
 
-               var and Op
+               var and ir.Op
                switch cmp {
-               case OEQ:
-                       and = OANDAND
-               case ONE:
-                       and = OOROR
+               case ir.OEQ:
+                       and = ir.OANDAND
+               case ir.ONE:
+                       and = ir.OOROR
                default:
                        // Don't do byte-wise comparisons for <, <=, etc.
                        // They're fairly complicated.
@@ -3522,13 +3523,13 @@ func walkcompareString(n *Node, init *Nodes) *Node {
                        if len(s) > 0 {
                                ncs = safeexpr(ncs, init)
                        }
-                       r := nod(cmp, nod(OLEN, ncs, nil), nodintconst(int64(len(s))))
+                       r := ir.Nod(cmp, ir.Nod(ir.OLEN, ncs, nil), nodintconst(int64(len(s))))
                        remains := len(s)
                        for i := 0; remains > 0; {
                                if remains == 1 || !canCombineLoads {
                                        cb := nodintconst(int64(s[i]))
-                                       ncb := nod(OINDEX, ncs, nodintconst(int64(i)))
-                                       r = nod(and, r, nod(cmp, ncb, cb))
+                                       ncb := ir.Nod(ir.OINDEX, ncs, nodintconst(int64(i)))
+                                       r = ir.Nod(and, r, ir.Nod(cmp, ncb, cb))
                                        remains--
                                        i++
                                        continue
@@ -3537,31 +3538,31 @@ func walkcompareString(n *Node, init *Nodes) *Node {
                                var convType *types.Type
                                switch {
                                case remains >= 8 && combine64bit:
-                                       convType = types.Types[TINT64]
+                                       convType = types.Types[types.TINT64]
                                        step = 8
                                case remains >= 4:
-                                       convType = types.Types[TUINT32]
+                                       convType = types.Types[types.TUINT32]
                                        step = 4
                                case remains >= 2:
-                                       convType = types.Types[TUINT16]
+                                       convType = types.Types[types.TUINT16]
                                        step = 2
                                }
-                               ncsubstr := nod(OINDEX, ncs, nodintconst(int64(i)))
+                               ncsubstr := ir.Nod(ir.OINDEX, ncs, nodintconst(int64(i)))
                                ncsubstr = conv(ncsubstr, convType)
                                csubstr := int64(s[i])
                                // Calculate large constant from bytes as sequence of shifts and ors.
                                // Like this:  uint32(s[0]) | uint32(s[1])<<8 | uint32(s[2])<<16 ...
                                // ssa will combine this into a single large load.
                                for offset := 1; offset < step; offset++ {
-                                       b := nod(OINDEX, ncs, nodintconst(int64(i+offset)))
+                                       b := ir.Nod(ir.OINDEX, ncs, nodintconst(int64(i+offset)))
                                        b = conv(b, convType)
-                                       b = nod(OLSH, b, nodintconst(int64(8*offset)))
-                                       ncsubstr = nod(OOR, ncsubstr, b)
+                                       b = ir.Nod(ir.OLSH, b, nodintconst(int64(8*offset)))
+                                       ncsubstr = ir.Nod(ir.OOR, ncsubstr, b)
                                        csubstr |= int64(s[i+offset]) << uint8(8*offset)
                                }
                                csubstrPart := nodintconst(csubstr)
                                // Compare "step" bytes as once
-                               r = nod(and, r, nod(cmp, csubstrPart, ncsubstr))
+                               r = ir.Nod(and, r, ir.Nod(cmp, csubstrPart, ncsubstr))
                                remains -= step
                                i += step
                        }
@@ -3569,26 +3570,26 @@ func walkcompareString(n *Node, init *Nodes) *Node {
                }
        }
 
-       var r *Node
-       if n.Op == OEQ || n.Op == ONE {
+       var r *ir.Node
+       if n.Op == ir.OEQ || n.Op == ir.ONE {
                // prepare for rewrite below
                n.Left = cheapexpr(n.Left, init)
                n.Right = cheapexpr(n.Right, init)
                eqlen, eqmem := eqstring(n.Left, n.Right)
                // quick check of len before full compare for == or !=.
                // memequal then tests equality up to length len.
-               if n.Op == OEQ {
+               if n.Op == ir.OEQ {
                        // len(left) == len(right) && memequal(left, right, len)
-                       r = nod(OANDAND, eqlen, eqmem)
+                       r = ir.Nod(ir.OANDAND, eqlen, eqmem)
                } else {
                        // len(left) != len(right) || !memequal(left, right, len)
-                       eqlen.Op = ONE
-                       r = nod(OOROR, eqlen, nod(ONOT, eqmem, nil))
+                       eqlen.Op = ir.ONE
+                       r = ir.Nod(ir.OOROR, eqlen, ir.Nod(ir.ONOT, eqmem, nil))
                }
        } else {
                // sys_cmpstring(s1, s2) :: 0
-               r = mkcall("cmpstring", types.Types[TINT], init, conv(n.Left, types.Types[TSTRING]), conv(n.Right, types.Types[TSTRING]))
-               r = nod(n.Op, r, nodintconst(0))
+               r = mkcall("cmpstring", types.Types[types.TINT], init, conv(n.Left, types.Types[types.TSTRING]), conv(n.Right, types.Types[types.TSTRING]))
+               r = ir.Nod(n.Op, r, nodintconst(0))
        }
 
        return finishcompare(n, r, init)
@@ -3596,7 +3597,7 @@ func walkcompareString(n *Node, init *Nodes) *Node {
 
 // The result of finishcompare MUST be assigned back to n, e.g.
 //     n.Left = finishcompare(n.Left, x, r, init)
-func finishcompare(n, r *Node, init *Nodes) *Node {
+func finishcompare(n, r *ir.Node, init *ir.Nodes) *ir.Node {
        r = typecheck(r, ctxExpr)
        r = conv(r, n.Type)
        r = walkexpr(r, init)
@@ -3604,7 +3605,7 @@ func finishcompare(n, r *Node, init *Nodes) *Node {
 }
 
 // return 1 if integer n must be in range [0, max), 0 otherwise
-func bounded(n *Node, max int64) bool {
+func bounded(n *ir.Node, max int64) bool {
        if n.Type == nil || !n.Type.IsInteger() {
                return false
        }
@@ -3618,14 +3619,14 @@ func bounded(n *Node, max int64) bool {
        }
 
        switch n.Op {
-       case OAND, OANDNOT:
+       case ir.OAND, ir.OANDNOT:
                v := int64(-1)
                switch {
                case smallintconst(n.Left):
                        v = n.Left.Int64Val()
                case smallintconst(n.Right):
                        v = n.Right.Int64Val()
-                       if n.Op == OANDNOT {
+                       if n.Op == ir.OANDNOT {
                                v = ^v
                                if !sign {
                                        v &= 1<<uint(bits) - 1
@@ -3636,7 +3637,7 @@ func bounded(n *Node, max int64) bool {
                        return true
                }
 
-       case OMOD:
+       case ir.OMOD:
                if !sign && smallintconst(n.Right) {
                        v := n.Right.Int64Val()
                        if 0 <= v && v <= max {
@@ -3644,7 +3645,7 @@ func bounded(n *Node, max int64) bool {
                        }
                }
 
-       case ODIV:
+       case ir.ODIV:
                if !sign && smallintconst(n.Right) {
                        v := n.Right.Int64Val()
                        for bits > 0 && v >= 2 {
@@ -3653,7 +3654,7 @@ func bounded(n *Node, max int64) bool {
                        }
                }
 
-       case ORSH:
+       case ir.ORSH:
                if !sign && smallintconst(n.Right) {
                        v := n.Right.Int64Val()
                        if v > int64(bits) {
@@ -3671,7 +3672,7 @@ func bounded(n *Node, max int64) bool {
 }
 
 // usemethod checks interface method calls for uses of reflect.Type.Method.
-func usemethod(n *Node) {
+func usemethod(n *ir.Node) {
        t := n.Left.Type
 
        // Looking for either of:
@@ -3694,7 +3695,7 @@ func usemethod(n *Node) {
        }
 
        if res1 == nil {
-               if p0.Type.Etype != TINT {
+               if p0.Type.Etype != types.TINT {
                        return
                }
        } else {
@@ -3712,11 +3713,11 @@ func usemethod(n *Node) {
        if s := res0.Type.Sym; s != nil && s.Name == "Method" && isReflectPkg(s.Pkg) {
                Curfn.Func.SetReflectMethod(true)
                // The LSym is initialized at this point. We need to set the attribute on the LSym.
-               Curfn.Func.lsym.Set(obj.AttrReflectMethod, true)
+               Curfn.Func.LSym.Set(obj.AttrReflectMethod, true)
        }
 }
 
-func usefield(n *Node) {
+func usefield(n *ir.Node) {
        if objabi.Fieldtrack_enabled == 0 {
                return
        }
@@ -3725,7 +3726,7 @@ func usefield(n *Node) {
        default:
                base.Fatalf("usefield %v", n.Op)
 
-       case ODOT, ODOTPTR:
+       case ir.ODOT, ir.ODOTPTR:
                break
        }
        if n.Sym == nil {
@@ -3767,7 +3768,7 @@ func usefield(n *Node) {
        Curfn.Func.FieldTrack[sym] = struct{}{}
 }
 
-func candiscardlist(l Nodes) bool {
+func candiscardlist(l ir.Nodes) bool {
        for _, n := range l.Slice() {
                if !candiscard(n) {
                        return false
@@ -3776,7 +3777,7 @@ func candiscardlist(l Nodes) bool {
        return true
 }
 
-func candiscard(n *Node) bool {
+func candiscard(n *ir.Node) bool {
        if n == nil {
                return true
        }
@@ -3786,80 +3787,80 @@ func candiscard(n *Node) bool {
                return false
 
                // Discardable as long as the subpieces are.
-       case ONAME,
-               ONONAME,
-               OTYPE,
-               OPACK,
-               OLITERAL,
-               ONIL,
-               OADD,
-               OSUB,
-               OOR,
-               OXOR,
-               OADDSTR,
-               OADDR,
-               OANDAND,
-               OBYTES2STR,
-               ORUNES2STR,
-               OSTR2BYTES,
-               OSTR2RUNES,
-               OCAP,
-               OCOMPLIT,
-               OMAPLIT,
-               OSTRUCTLIT,
-               OARRAYLIT,
-               OSLICELIT,
-               OPTRLIT,
-               OCONV,
-               OCONVIFACE,
-               OCONVNOP,
-               ODOT,
-               OEQ,
-               ONE,
-               OLT,
-               OLE,
-               OGT,
-               OGE,
-               OKEY,
-               OSTRUCTKEY,
-               OLEN,
-               OMUL,
-               OLSH,
-               ORSH,
-               OAND,
-               OANDNOT,
-               ONEW,
-               ONOT,
-               OBITNOT,
-               OPLUS,
-               ONEG,
-               OOROR,
-               OPAREN,
-               ORUNESTR,
-               OREAL,
-               OIMAG,
-               OCOMPLEX:
+       case ir.ONAME,
+               ir.ONONAME,
+               ir.OTYPE,
+               ir.OPACK,
+               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:
                break
 
                // Discardable as long as we know it's not division by zero.
-       case ODIV, OMOD:
-               if n.Right.Op == OLITERAL && constant.Sign(n.Right.Val()) != 0 {
+       case ir.ODIV, ir.OMOD:
+               if n.Right.Op == ir.OLITERAL && constant.Sign(n.Right.Val()) != 0 {
                        break
                }
                return false
 
                // Discardable as long as we know it won't fail because of a bad size.
-       case OMAKECHAN, OMAKEMAP:
-               if Isconst(n.Left, constant.Int) && constant.Sign(n.Left.Val()) == 0 {
+       case ir.OMAKECHAN, ir.OMAKEMAP:
+               if ir.IsConst(n.Left, constant.Int) && constant.Sign(n.Left.Val()) == 0 {
                        break
                }
                return false
 
                // Difficult to tell what sizes are okay.
-       case OMAKESLICE:
+       case ir.OMAKESLICE:
                return false
 
-       case OMAKESLICECOPY:
+       case ir.OMAKESLICECOPY:
                return false
        }
 
@@ -3890,29 +3891,29 @@ var wrapCall_prgen int
 
 // The result of wrapCall MUST be assigned back to n, e.g.
 //     n.Left = wrapCall(n.Left, init)
-func wrapCall(n *Node, init *Nodes) *Node {
+func wrapCall(n *ir.Node, init *ir.Nodes) *ir.Node {
        if n.Ninit.Len() != 0 {
                walkstmtlist(n.Ninit.Slice())
                init.AppendNodes(&n.Ninit)
        }
 
-       isBuiltinCall := n.Op != OCALLFUNC && n.Op != OCALLMETH && n.Op != OCALLINTER
+       isBuiltinCall := n.Op != ir.OCALLFUNC && n.Op != ir.OCALLMETH && n.Op != ir.OCALLINTER
 
        // Turn f(a, b, []T{c, d, e}...) back into f(a, b, c, d, e).
        if !isBuiltinCall && n.IsDDD() {
                last := n.List.Len() - 1
-               if va := n.List.Index(last); va.Op == OSLICELIT {
+               if va := n.List.Index(last); va.Op == ir.OSLICELIT {
                        n.List.Set(append(n.List.Slice()[:last], va.List.Slice()...))
                        n.SetIsDDD(false)
                }
        }
 
        // origArgs keeps track of what argument is uintptr-unsafe/unsafe-uintptr conversion.
-       origArgs := make([]*Node, n.List.Len())
-       t := nod(OTFUNC, nil, nil)
+       origArgs := make([]*ir.Node, n.List.Len())
+       t := ir.Nod(ir.OTFUNC, nil, nil)
        for i, arg := range n.List.Slice() {
                s := lookupN("a", i)
-               if !isBuiltinCall && arg.Op == OCONVNOP && arg.Type.IsUintptr() && arg.Left.Type.IsUnsafePtr() {
+               if !isBuiltinCall && arg.Op == ir.OCONVNOP && arg.Type.IsUintptr() && arg.Left.Type.IsUnsafePtr() {
                        origArgs[i] = arg
                        arg = arg.Left
                        n.List.SetIndex(i, arg)
@@ -3929,13 +3930,13 @@ func wrapCall(n *Node, init *Nodes) *Node {
                if origArg == nil {
                        continue
                }
-               arg := nod(origArg.Op, args[i], nil)
+               arg := ir.Nod(origArg.Op, args[i], nil)
                arg.Type = origArg.Type
                args[i] = arg
        }
-       call := nod(n.Op, nil, nil)
+       call := ir.Nod(n.Op, nil, nil)
        if !isBuiltinCall {
-               call.Op = OCALL
+               call.Op = ir.OCALL
                call.Left = n.Left
                call.SetIsDDD(n.IsDDD())
        }
@@ -3948,7 +3949,7 @@ func wrapCall(n *Node, init *Nodes) *Node {
        typecheckslice(fn.Nbody.Slice(), ctxStmt)
        xtop = append(xtop, fn)
 
-       call = nod(OCALL, nil, nil)
+       call = ir.Nod(ir.OCALL, nil, nil)
        call.Left = fn.Func.Nname
        call.List.Set(n.List.Slice())
        call = typecheck(call, ctxStmt)
@@ -3961,8 +3962,8 @@ func wrapCall(n *Node, init *Nodes) *Node {
 // type syntax expression n.Type.
 // The result of substArgTypes MUST be assigned back to old, e.g.
 //     n.Left = substArgTypes(n.Left, t1, t2)
-func substArgTypes(old *Node, types_ ...*types.Type) *Node {
-       n := old.copy()
+func substArgTypes(old *ir.Node, types_ ...*types.Type) *ir.Node {
+       n := ir.Copy(old)
 
        for _, t := range types_ {
                dowidth(t)
@@ -3991,11 +3992,11 @@ func canMergeLoads() bool {
 
 // isRuneCount reports whether n is of the form len([]rune(string)).
 // These are optimized into a call to runtime.countrunes.
-func isRuneCount(n *Node) bool {
-       return base.Flag.N == 0 && !instrumenting && n.Op == OLEN && n.Left.Op == OSTR2RUNES
+func isRuneCount(n *ir.Node) bool {
+       return base.Flag.N == 0 && !instrumenting && n.Op == ir.OLEN && n.Left.Op == ir.OSTR2RUNES
 }
 
-func walkCheckPtrAlignment(n *Node, init *Nodes, count *Node) *Node {
+func walkCheckPtrAlignment(n *ir.Node, init *ir.Nodes, count *ir.Node) *ir.Node {
        if !n.Type.IsPtr() {
                base.Fatalf("expected pointer type: %v", n.Type)
        }
@@ -4017,13 +4018,13 @@ func walkCheckPtrAlignment(n *Node, init *Nodes, count *Node) *Node {
        }
 
        n.Left = cheapexpr(n.Left, init)
-       init.Append(mkcall("checkptrAlignment", nil, init, convnop(n.Left, types.Types[TUNSAFEPTR]), typename(elem), conv(count, types.Types[TUINTPTR])))
+       init.Append(mkcall("checkptrAlignment", nil, init, convnop(n.Left, types.Types[types.TUNSAFEPTR]), typename(elem), conv(count, types.Types[types.TUINTPTR])))
        return n
 }
 
 var walkCheckPtrArithmeticMarker byte
 
-func walkCheckPtrArithmetic(n *Node, init *Nodes) *Node {
+func walkCheckPtrArithmetic(n *ir.Node, init *ir.Nodes) *ir.Node {
        // Calling cheapexpr(n, init) below leads to a recursive call
        // to walkexpr, which leads us back here again. Use n.Opt to
        // prevent infinite loops.
@@ -4040,11 +4041,11 @@ func walkCheckPtrArithmetic(n *Node, init *Nodes) *Node {
        // TODO(mdempsky): Make stricter. We only need to exempt
        // reflect.Value.Pointer and reflect.Value.UnsafeAddr.
        switch n.Left.Op {
-       case OCALLFUNC, OCALLMETH, OCALLINTER:
+       case ir.OCALLFUNC, ir.OCALLMETH, ir.OCALLINTER:
                return n
        }
 
-       if n.Left.Op == ODOTPTR && isReflectHeaderDataField(n.Left) {
+       if n.Left.Op == ir.ODOTPTR && isReflectHeaderDataField(n.Left) {
                return n
        }
 
@@ -4054,19 +4055,19 @@ func walkCheckPtrArithmetic(n *Node, init *Nodes) *Node {
        // "It is valid both to add and to subtract offsets from a
        // pointer in this way. It is also valid to use &^ to round
        // pointers, usually for alignment."
-       var originals []*Node
-       var walk func(n *Node)
-       walk = func(n *Node) {
+       var originals []*ir.Node
+       var walk func(n *ir.Node)
+       walk = func(n *ir.Node) {
                switch n.Op {
-               case OADD:
+               case ir.OADD:
                        walk(n.Left)
                        walk(n.Right)
-               case OSUB, OANDNOT:
+               case ir.OSUB, ir.OANDNOT:
                        walk(n.Left)
-               case OCONVNOP:
+               case ir.OCONVNOP:
                        if n.Left.Type.IsUnsafePtr() {
                                n.Left = cheapexpr(n.Left, init)
-                               originals = append(originals, convnop(n.Left, types.Types[TUNSAFEPTR]))
+                               originals = append(originals, convnop(n.Left, types.Types[types.TUNSAFEPTR]))
                        }
                }
        }
@@ -4074,10 +4075,10 @@ func walkCheckPtrArithmetic(n *Node, init *Nodes) *Node {
 
        n = cheapexpr(n, init)
 
-       slice := mkdotargslice(types.NewSlice(types.Types[TUNSAFEPTR]), originals)
+       slice := mkdotargslice(types.NewSlice(types.Types[types.TUNSAFEPTR]), originals)
        slice.Esc = EscNone
 
-       init.Append(mkcall("checkptrArithmetic", nil, init, convnop(n, types.Types[TUNSAFEPTR]), slice))
+       init.Append(mkcall("checkptrArithmetic", nil, init, convnop(n, types.Types[types.TUNSAFEPTR]), slice))
        // TODO(khr): Mark backing store of slice as dead. This will allow us to reuse
        // the backing store for multiple calls to checkptrArithmetic.
 
@@ -4087,6 +4088,6 @@ func walkCheckPtrArithmetic(n *Node, init *Nodes) *Node {
 // checkPtr reports whether pointer checking should be enabled for
 // function fn at a given level. See debugHelpFooter for defined
 // levels.
-func checkPtr(fn *Node, level int) bool {
-       return base.Debug.Checkptr >= level && fn.Func.Pragma&NoCheckPtr == 0
+func checkPtr(fn *ir.Node, level int) bool {
+       return base.Debug.Checkptr >= level && fn.Func.Pragma&ir.NoCheckPtr == 0
 }
similarity index 99%
rename from src/cmd/compile/internal/gc/bitset.go
rename to src/cmd/compile/internal/ir/bitset.go
index ed5eea0a11be9a559b2b237ba9c0c8db88706804..29f136296fd1ebc7c81c89f3e389f0f84f8cfa50 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-package gc
+package ir
 
 type bitset8 uint8
 
similarity index 98%
rename from src/cmd/compile/internal/gc/class_string.go
rename to src/cmd/compile/internal/ir/class_string.go
index a4084a7535209505093583c7b2745520c68772fd..866bf1a6b5b78ed86b810c648dc342d5e388e287 100644 (file)
@@ -1,6 +1,6 @@
 // Code generated by "stringer -type=Class"; DO NOT EDIT.
 
-package gc
+package ir
 
 import "strconv"
 
similarity index 96%
rename from src/cmd/compile/internal/gc/dump.go
rename to src/cmd/compile/internal/ir/dump.go
index 56dc47446573781641638e34f20ed97e61d3c155..9306366e8ad317a60293a7f997f7584a6dc96fde 100644 (file)
@@ -6,22 +6,23 @@
 // for debugging purposes. The code is customized for Node graphs
 // and may be used for an alternative view of the node structure.
 
-package gc
+package ir
 
 import (
-       "cmd/compile/internal/base"
-       "cmd/compile/internal/types"
-       "cmd/internal/src"
        "fmt"
        "io"
        "os"
        "reflect"
        "regexp"
+
+       "cmd/compile/internal/base"
+       "cmd/compile/internal/types"
+       "cmd/internal/src"
 )
 
 // dump is like fdump but prints to stderr.
-func dump(root interface{}, filter string, depth int) {
-       fdump(os.Stderr, root, filter, depth)
+func DumpAny(root interface{}, filter string, depth int) {
+       FDumpAny(os.Stderr, root, filter, depth)
 }
 
 // fdump prints the structure of a rooted data structure
@@ -41,7 +42,7 @@ func dump(root interface{}, filter string, depth int) {
 // rather than their type; struct fields with zero values or
 // non-matching field names are omitted, and "…" means recursion
 // depth has been reached or struct fields have been omitted.
-func fdump(w io.Writer, root interface{}, filter string, depth int) {
+func FDumpAny(w io.Writer, root interface{}, filter string, depth int) {
        if root == nil {
                fmt.Fprintln(w, "nil")
                return
@@ -151,7 +152,7 @@ func (p *dumper) dump(x reflect.Value, depth int) {
                return
 
        case *types.Node:
-               x = reflect.ValueOf(asNode(v))
+               x = reflect.ValueOf(AsNode(v))
        }
 
        switch x.Kind() {
similarity index 87%
rename from src/cmd/compile/internal/gc/fmt.go
rename to src/cmd/compile/internal/ir/fmt.go
index 9248eb22aa28dd424e7cfe723ce1c8bdcd37a5d5..5dea0880fc140818a313d6d389863408262e2e4d 100644 (file)
@@ -2,13 +2,10 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-package gc
+package ir
 
 import (
        "bytes"
-       "cmd/compile/internal/base"
-       "cmd/compile/internal/types"
-       "cmd/internal/src"
        "fmt"
        "go/constant"
        "io"
@@ -16,6 +13,10 @@ import (
        "strings"
        "sync"
        "unicode/utf8"
+
+       "cmd/compile/internal/base"
+       "cmd/compile/internal/types"
+       "cmd/internal/src"
 )
 
 // A FmtFlag value is a set of flags (or 0).
@@ -98,7 +99,7 @@ func fmtFlag(s fmt.State, verb rune) FmtFlag {
 
 // *types.Sym, *types.Type, and *Node types use the flags below to set the format mode
 const (
-       FErr fmtMode = iota
+       FErr FmtMode = iota
        FDbg
        FTypeId
        FTypeIdName // same as FTypeId, but use package name instead of prefix
@@ -131,7 +132,7 @@ const (
 //   %- v   type identifiers with package name instead of prefix (typesym, dcommontype, typehash)
 
 // update returns the results of applying f to mode.
-func (f FmtFlag) update(mode fmtMode) (FmtFlag, fmtMode) {
+func (f FmtFlag) update(mode FmtMode) (FmtFlag, FmtMode) {
        switch {
        case f&FmtSign != 0:
                mode = FDbg
@@ -147,7 +148,7 @@ func (f FmtFlag) update(mode fmtMode) (FmtFlag, fmtMode) {
        return f, mode
 }
 
-var goopnames = []string{
+var OpNames = []string{
        OADDR:     "&",
        OADD:      "+",
        OADDSTR:   "+",
@@ -217,7 +218,7 @@ func (o Op) GoString() string {
        return fmt.Sprintf("%#v", o)
 }
 
-func (o Op) format(s fmt.State, verb rune, mode fmtMode) {
+func (o Op) format(s fmt.State, verb rune, mode FmtMode) {
        switch verb {
        case 'v':
                o.oconv(s, fmtFlag(s, verb), mode)
@@ -227,10 +228,10 @@ func (o Op) format(s fmt.State, verb rune, mode fmtMode) {
        }
 }
 
-func (o Op) oconv(s fmt.State, flag FmtFlag, mode fmtMode) {
+func (o Op) oconv(s fmt.State, flag FmtFlag, mode FmtMode) {
        if flag&FmtSharp != 0 || mode != FDbg {
-               if int(o) < len(goopnames) && goopnames[o] != "" {
-                       fmt.Fprint(s, goopnames[o])
+               if int(o) < len(OpNames) && OpNames[o] != "" {
+                       fmt.Fprint(s, OpNames[o])
                        return
                }
        }
@@ -239,66 +240,73 @@ func (o Op) oconv(s fmt.State, flag FmtFlag, mode fmtMode) {
        fmt.Fprint(s, o.String())
 }
 
-type fmtMode int
+type FmtMode int
 
 type fmtNode struct {
        x *Node
-       m fmtMode
+       m FmtMode
 }
 
 func (f *fmtNode) Format(s fmt.State, verb rune) { f.x.format(s, verb, f.m) }
 
 type fmtOp struct {
        x Op
-       m fmtMode
+       m FmtMode
 }
 
 func (f *fmtOp) Format(s fmt.State, verb rune) { f.x.format(s, verb, f.m) }
 
 type fmtType struct {
        x *types.Type
-       m fmtMode
+       m FmtMode
 }
 
 func (f *fmtType) Format(s fmt.State, verb rune) { typeFormat(f.x, s, verb, f.m) }
 
 type fmtSym struct {
        x *types.Sym
-       m fmtMode
+       m FmtMode
 }
 
 func (f *fmtSym) Format(s fmt.State, verb rune) { symFormat(f.x, s, verb, f.m) }
 
 type fmtNodes struct {
        x Nodes
-       m fmtMode
+       m FmtMode
 }
 
 func (f *fmtNodes) Format(s fmt.State, verb rune) { f.x.format(s, verb, f.m) }
 
-func (n *Node) Format(s fmt.State, verb rune) { n.format(s, verb, FErr) }
-func (o Op) Format(s fmt.State, verb rune)    { o.format(s, verb, FErr) }
+func (n *Node) Format(s fmt.State, verb rune) {
+       FmtNode(n, s, verb)
+}
+
+func FmtNode(n *Node, s fmt.State, verb rune) {
+       n.format(s, verb, FErr)
+}
+
+func (o Op) Format(s fmt.State, verb rune) { o.format(s, verb, FErr) }
 
 // func (t *types.Type) Format(s fmt.State, verb rune)     // in package types
 // func (y *types.Sym) Format(s fmt.State, verb rune)            // in package types  { y.format(s, verb, FErr) }
 func (n Nodes) Format(s fmt.State, verb rune) { n.format(s, verb, FErr) }
 
-func (m fmtMode) Fprintf(s fmt.State, format string, args ...interface{}) {
+func (m FmtMode) Fprintf(s fmt.State, format string, args ...interface{}) {
        m.prepareArgs(args)
        fmt.Fprintf(s, format, args...)
 }
 
-func (m fmtMode) Sprintf(format string, args ...interface{}) string {
+func (m FmtMode) Sprintf(format string, args ...interface{}) string {
        m.prepareArgs(args)
        return fmt.Sprintf(format, args...)
 }
 
-func (m fmtMode) Sprint(args ...interface{}) string {
+func (m FmtMode) Sprint(args ...interface{}) string {
        m.prepareArgs(args)
        return fmt.Sprint(args...)
 }
 
-func (m fmtMode) prepareArgs(args []interface{}) {
+func (m FmtMode) prepareArgs(args []interface{}) {
        for i, arg := range args {
                switch arg := arg.(type) {
                case Op:
@@ -319,13 +327,13 @@ func (m fmtMode) prepareArgs(args []interface{}) {
        }
 }
 
-func (n *Node) format(s fmt.State, verb rune, mode fmtMode) {
+func (n *Node) format(s fmt.State, verb rune, mode FmtMode) {
        switch verb {
        case 'v', 'S', 'L':
-               n.nconv(s, fmtFlag(s, verb), mode)
+               nconvFmt(n, s, fmtFlag(s, verb), mode)
 
        case 'j':
-               n.jconv(s, fmtFlag(s, verb))
+               jconvFmt(n, s, fmtFlag(s, verb))
 
        default:
                fmt.Fprintf(s, "%%!%c(*Node=%p)", verb, n)
@@ -336,7 +344,7 @@ func (n *Node) format(s fmt.State, verb rune, mode fmtMode) {
 var EscFmt func(n *Node, short bool) string
 
 // *Node details
-func (n *Node) jconv(s fmt.State, flag FmtFlag) {
+func jconvFmt(n *Node, s fmt.State, flag FmtFlag) {
        short := flag&FmtShort != 0
 
        // Useful to see which nodes in an AST printout are actually identical
@@ -363,7 +371,7 @@ func (n *Node) jconv(s fmt.State, flag FmtFlag) {
                fmt.Fprintf(s, " l(%s%d)", pfx, n.Pos.Line())
        }
 
-       if !short && n.Xoffset != BADWIDTH {
+       if !short && n.Xoffset != types.BADWIDTH {
                fmt.Fprintf(s, " x(%d)", n.Xoffset)
        }
 
@@ -430,7 +438,7 @@ func (n *Node) jconv(s fmt.State, flag FmtFlag) {
        }
 }
 
-func vconv(v constant.Value, flag FmtFlag) string {
+func FmtConst(v constant.Value, flag FmtFlag) string {
        if flag&FmtSharp == 0 && v.Kind() == constant.Complex {
                real, imag := constant.Real(v), constant.Imag(v)
 
@@ -473,17 +481,17 @@ s%^       ........*\]%&~%g
 s%~    %%g
 */
 
-func symfmt(b *bytes.Buffer, s *types.Sym, flag FmtFlag, mode fmtMode) {
+func symfmt(b *bytes.Buffer, s *types.Sym, flag FmtFlag, mode FmtMode) {
        if flag&FmtShort == 0 {
                switch mode {
                case FErr: // This is for the user
-                       if s.Pkg == builtinpkg || s.Pkg == localpkg {
+                       if s.Pkg == BuiltinPkg || s.Pkg == LocalPkg {
                                b.WriteString(s.Name)
                                return
                        }
 
                        // If the name was used by multiple packages, display the full path,
-                       if s.Pkg.Name != "" && numImport[s.Pkg.Name] > 1 {
+                       if s.Pkg.Name != "" && NumImport[s.Pkg.Name] > 1 {
                                fmt.Fprintf(b, "%q.%s", s.Pkg.Path, s.Name)
                                return
                        }
@@ -534,28 +542,28 @@ func symfmt(b *bytes.Buffer, s *types.Sym, flag FmtFlag, mode fmtMode) {
        b.WriteString(s.Name)
 }
 
-var basicnames = []string{
-       TINT:        "int",
-       TUINT:       "uint",
-       TINT8:       "int8",
-       TUINT8:      "uint8",
-       TINT16:      "int16",
-       TUINT16:     "uint16",
-       TINT32:      "int32",
-       TUINT32:     "uint32",
-       TINT64:      "int64",
-       TUINT64:     "uint64",
-       TUINTPTR:    "uintptr",
-       TFLOAT32:    "float32",
-       TFLOAT64:    "float64",
-       TCOMPLEX64:  "complex64",
-       TCOMPLEX128: "complex128",
-       TBOOL:       "bool",
-       TANY:        "any",
-       TSTRING:     "string",
-       TNIL:        "nil",
-       TIDEAL:      "untyped number",
-       TBLANK:      "blank",
+var BasicTypeNames = []string{
+       types.TINT:        "int",
+       types.TUINT:       "uint",
+       types.TINT8:       "int8",
+       types.TUINT8:      "uint8",
+       types.TINT16:      "int16",
+       types.TUINT16:     "uint16",
+       types.TINT32:      "int32",
+       types.TUINT32:     "uint32",
+       types.TINT64:      "int64",
+       types.TUINT64:     "uint64",
+       types.TUINTPTR:    "uintptr",
+       types.TFLOAT32:    "float32",
+       types.TFLOAT64:    "float64",
+       types.TCOMPLEX64:  "complex64",
+       types.TCOMPLEX128: "complex128",
+       types.TBOOL:       "bool",
+       types.TANY:        "any",
+       types.TSTRING:     "string",
+       types.TNIL:        "nil",
+       types.TIDEAL:      "untyped number",
+       types.TBLANK:      "blank",
 }
 
 var fmtBufferPool = sync.Pool{
@@ -564,7 +572,7 @@ var fmtBufferPool = sync.Pool{
        },
 }
 
-func tconv(t *types.Type, flag FmtFlag, mode fmtMode) string {
+func tconv(t *types.Type, flag FmtFlag, mode FmtMode) string {
        buf := fmtBufferPool.Get().(*bytes.Buffer)
        buf.Reset()
        defer fmtBufferPool.Put(buf)
@@ -577,7 +585,7 @@ func tconv(t *types.Type, flag FmtFlag, mode fmtMode) string {
 // flag and mode control exactly what is printed.
 // Any types x that are already in the visited map get printed as @%d where %d=visited[x].
 // See #16897 before changing the implementation of tconv.
-func tconv2(b *bytes.Buffer, t *types.Type, flag FmtFlag, mode fmtMode, visited map[*types.Type]int) {
+func tconv2(b *bytes.Buffer, t *types.Type, flag FmtFlag, mode FmtMode, visited map[*types.Type]int) {
        if off, ok := visited[t]; ok {
                // We've seen this type before, so we're trying to print it recursively.
                // Print a reference to it instead.
@@ -648,7 +656,7 @@ func tconv2(b *bytes.Buffer, t *types.Type, flag FmtFlag, mode fmtMode, visited
                                return
                        }
 
-                       if t.Sym.Pkg == localpkg && t.Vargen != 0 {
+                       if t.Sym.Pkg == LocalPkg && t.Vargen != 0 {
                                b.WriteString(mode.Sprintf("%v·%d", t.Sym, t.Vargen))
                                return
                        }
@@ -658,7 +666,7 @@ func tconv2(b *bytes.Buffer, t *types.Type, flag FmtFlag, mode fmtMode, visited
                return
        }
 
-       if int(t.Etype) < len(basicnames) && basicnames[t.Etype] != "" {
+       if int(t.Etype) < len(BasicTypeNames) && BasicTypeNames[t.Etype] != "" {
                var name string
                switch t {
                case types.UntypedBool:
@@ -674,7 +682,7 @@ func tconv2(b *bytes.Buffer, t *types.Type, flag FmtFlag, mode fmtMode, visited
                case types.UntypedComplex:
                        name = "untyped complex"
                default:
-                       name = basicnames[t.Etype]
+                       name = BasicTypeNames[t.Etype]
                }
                b.WriteString(name)
                return
@@ -701,7 +709,7 @@ func tconv2(b *bytes.Buffer, t *types.Type, flag FmtFlag, mode fmtMode, visited
        defer delete(visited, t)
 
        switch t.Etype {
-       case TPTR:
+       case types.TPTR:
                b.WriteByte('*')
                switch mode {
                case FTypeId, FTypeIdName:
@@ -712,17 +720,17 @@ func tconv2(b *bytes.Buffer, t *types.Type, flag FmtFlag, mode fmtMode, visited
                }
                tconv2(b, t.Elem(), 0, mode, visited)
 
-       case TARRAY:
+       case types.TARRAY:
                b.WriteByte('[')
                b.WriteString(strconv.FormatInt(t.NumElem(), 10))
                b.WriteByte(']')
                tconv2(b, t.Elem(), 0, mode, visited)
 
-       case TSLICE:
+       case types.TSLICE:
                b.WriteString("[]")
                tconv2(b, t.Elem(), 0, mode, visited)
 
-       case TCHAN:
+       case types.TCHAN:
                switch t.ChanDir() {
                case types.Crecv:
                        b.WriteString("<-chan ")
@@ -741,13 +749,13 @@ func tconv2(b *bytes.Buffer, t *types.Type, flag FmtFlag, mode fmtMode, visited
                        }
                }
 
-       case TMAP:
+       case types.TMAP:
                b.WriteString("map[")
                tconv2(b, t.Key(), 0, mode, visited)
                b.WriteByte(']')
                tconv2(b, t.Elem(), 0, mode, visited)
 
-       case TINTER:
+       case types.TINTER:
                if t.IsEmptyInterface() {
                        b.WriteString("interface {}")
                        break
@@ -779,7 +787,7 @@ func tconv2(b *bytes.Buffer, t *types.Type, flag FmtFlag, mode fmtMode, visited
                }
                b.WriteByte('}')
 
-       case TFUNC:
+       case types.TFUNC:
                if flag&FmtShort != 0 {
                        // no leading func
                } else {
@@ -805,7 +813,7 @@ func tconv2(b *bytes.Buffer, t *types.Type, flag FmtFlag, mode fmtMode, visited
                        tconv2(b, t.Results(), 0, mode, visited)
                }
 
-       case TSTRUCT:
+       case types.TSTRUCT:
                if m := t.StructType().Map; m != nil {
                        mt := m.MapType()
                        // Format the bucket struct for map[x]y as map.bucket[x]y.
@@ -856,17 +864,17 @@ func tconv2(b *bytes.Buffer, t *types.Type, flag FmtFlag, mode fmtMode, visited
                        b.WriteByte('}')
                }
 
-       case TFORW:
+       case types.TFORW:
                b.WriteString("undefined")
                if t.Sym != nil {
                        b.WriteByte(' ')
                        sconv2(b, t.Sym, 0, mode)
                }
 
-       case TUNSAFEPTR:
+       case types.TUNSAFEPTR:
                b.WriteString("unsafe.Pointer")
 
-       case Txxx:
+       case types.Txxx:
                b.WriteString("Txxx")
        default:
                // Don't know how to handle - fall back to detailed prints.
@@ -875,7 +883,7 @@ func tconv2(b *bytes.Buffer, t *types.Type, flag FmtFlag, mode fmtMode, visited
 }
 
 // Statements which may be rendered with a simplestmt as init.
-func stmtwithinit(op Op) bool {
+func StmtWithInit(op Op) bool {
        switch op {
        case OIF, OFOR, OFORUNTIL, OSWITCH:
                return true
@@ -884,20 +892,20 @@ func stmtwithinit(op Op) bool {
        return false
 }
 
-func (n *Node) stmtfmt(s fmt.State, mode fmtMode) {
+func stmtFmt(n *Node, s fmt.State, mode FmtMode) {
        // some statements allow for an init, but at most one,
        // but we may have an arbitrary number added, eg by typecheck
        // and inlining. If it doesn't fit the syntax, emit an enclosing
        // block starting with the init statements.
 
        // if we can just say "for" n->ninit; ... then do so
-       simpleinit := n.Ninit.Len() == 1 && n.Ninit.First().Ninit.Len() == 0 && stmtwithinit(n.Op)
+       simpleinit := n.Ninit.Len() == 1 && n.Ninit.First().Ninit.Len() == 0 && StmtWithInit(n.Op)
 
        // otherwise, print the inits as separate statements
        complexinit := n.Ninit.Len() != 0 && !simpleinit && (mode != FErr)
 
        // but if it was for if/for/switch, put in an extra surrounding block to limit the scope
-       extrablock := complexinit && stmtwithinit(n.Op)
+       extrablock := complexinit && StmtWithInit(n.Op)
 
        if extrablock {
                fmt.Fprint(s, "{")
@@ -1064,7 +1072,7 @@ func (n *Node) stmtfmt(s fmt.State, mode fmtMode) {
        }
 }
 
-var opprec = []int{
+var OpPrec = []int{
        OALIGNOF:       8,
        OAPPEND:        8,
        OBYTES2STR:     8,
@@ -1184,7 +1192,7 @@ var opprec = []int{
        OEND: 0,
 }
 
-func (n *Node) exprfmt(s fmt.State, prec int, mode fmtMode) {
+func exprFmt(n *Node, s fmt.State, prec int, mode FmtMode) {
        for n != nil && n.Implicit() && (n.Op == ODEREF || n.Op == OADDR) {
                n = n.Left
        }
@@ -1194,7 +1202,7 @@ func (n *Node) exprfmt(s fmt.State, prec int, mode fmtMode) {
                return
        }
 
-       nprec := opprec[n.Op]
+       nprec := OpPrec[n.Op]
        if n.Op == OTYPE && n.Sym != nil {
                nprec = 8
        }
@@ -1214,7 +1222,7 @@ func (n *Node) exprfmt(s fmt.State, prec int, mode fmtMode) {
        case OLITERAL: // this is a bit of a mess
                if mode == FErr {
                        if n.Orig != nil && n.Orig != n {
-                               n.Orig.exprfmt(s, prec, mode)
+                               exprFmt(n.Orig, s, prec, mode)
                                return
                        }
                        if n.Sym != nil {
@@ -1252,7 +1260,7 @@ func (n *Node) exprfmt(s fmt.State, prec int, mode fmtMode) {
                                fmt.Fprintf(s, "'\\U%08x'", uint64(x))
                        }
                } else {
-                       fmt.Fprint(s, vconv(n.Val(), fmtFlag(s, 'v')))
+                       fmt.Fprint(s, FmtConst(n.Val(), fmtFlag(s, 'v')))
                }
 
                if needUnparen {
@@ -1369,7 +1377,7 @@ func (n *Node) exprfmt(s fmt.State, prec int, mode fmtMode) {
                mode.Fprintf(s, "%v:%v", n.Sym, n.Left)
 
        case OCALLPART:
-               n.Left.exprfmt(s, nprec, mode)
+               exprFmt(n.Left, s, nprec, mode)
                if n.Right == nil || n.Right.Sym == nil {
                        fmt.Fprint(s, ".<nil>")
                        return
@@ -1377,7 +1385,7 @@ func (n *Node) exprfmt(s fmt.State, prec int, mode fmtMode) {
                mode.Fprintf(s, ".%0S", n.Right.Sym)
 
        case OXDOT, ODOT, ODOTPTR, ODOTINTER, ODOTMETH:
-               n.Left.exprfmt(s, nprec, mode)
+               exprFmt(n.Left, s, nprec, mode)
                if n.Sym == nil {
                        fmt.Fprint(s, ".<nil>")
                        return
@@ -1385,7 +1393,7 @@ func (n *Node) exprfmt(s fmt.State, prec int, mode fmtMode) {
                mode.Fprintf(s, ".%0S", n.Sym)
 
        case ODOTTYPE, ODOTTYPE2:
-               n.Left.exprfmt(s, nprec, mode)
+               exprFmt(n.Left, s, nprec, mode)
                if n.Right != nil {
                        mode.Fprintf(s, ".(%v)", n.Right)
                        return
@@ -1393,24 +1401,24 @@ func (n *Node) exprfmt(s fmt.State, prec int, mode fmtMode) {
                mode.Fprintf(s, ".(%v)", n.Type)
 
        case OINDEX, OINDEXMAP:
-               n.Left.exprfmt(s, nprec, mode)
+               exprFmt(n.Left, s, nprec, mode)
                mode.Fprintf(s, "[%v]", n.Right)
 
        case OSLICE, OSLICESTR, OSLICEARR, OSLICE3, OSLICE3ARR:
-               n.Left.exprfmt(s, nprec, mode)
+               exprFmt(n.Left, s, nprec, mode)
                fmt.Fprint(s, "[")
                low, high, max := n.SliceBounds()
                if low != nil {
-                       fmt.Fprint(s, low.modeString(mode))
+                       fmt.Fprint(s, modeString(low, mode))
                }
                fmt.Fprint(s, ":")
                if high != nil {
-                       fmt.Fprint(s, high.modeString(mode))
+                       fmt.Fprint(s, modeString(high, mode))
                }
                if n.Op.IsSlice3() {
                        fmt.Fprint(s, ":")
                        if max != nil {
-                               fmt.Fprint(s, max.modeString(mode))
+                               fmt.Fprint(s, modeString(max, mode))
                        }
                }
                fmt.Fprint(s, "]")
@@ -1474,7 +1482,7 @@ func (n *Node) exprfmt(s fmt.State, prec int, mode fmtMode) {
                mode.Fprintf(s, "%#v(%.v)", n.Op, n.List)
 
        case OCALL, OCALLFUNC, OCALLINTER, OCALLMETH, OGETG:
-               n.Left.exprfmt(s, nprec, mode)
+               exprFmt(n.Left, s, nprec, mode)
                if n.IsDDD() {
                        mode.Fprintf(s, "(%.v...)", n.List)
                        return
@@ -1505,7 +1513,7 @@ func (n *Node) exprfmt(s fmt.State, prec int, mode fmtMode) {
                if n.Left != nil && n.Left.Op == n.Op {
                        fmt.Fprint(s, " ")
                }
-               n.Left.exprfmt(s, nprec+1, mode)
+               exprFmt(n.Left, s, nprec+1, mode)
 
                // Binary
        case OADD,
@@ -1528,16 +1536,16 @@ func (n *Node) exprfmt(s fmt.State, prec int, mode fmtMode) {
                OSEND,
                OSUB,
                OXOR:
-               n.Left.exprfmt(s, nprec, mode)
+               exprFmt(n.Left, s, nprec, mode)
                mode.Fprintf(s, " %#v ", n.Op)
-               n.Right.exprfmt(s, nprec+1, mode)
+               exprFmt(n.Right, s, nprec+1, mode)
 
        case OADDSTR:
                for i, n1 := range n.List.Slice() {
                        if i != 0 {
                                fmt.Fprint(s, " + ")
                        }
-                       n1.exprfmt(s, nprec, mode)
+                       exprFmt(n1, s, nprec, mode)
                }
        case ODDD:
                mode.Fprintf(s, "...")
@@ -1546,7 +1554,7 @@ func (n *Node) exprfmt(s fmt.State, prec int, mode fmtMode) {
        }
 }
 
-func (n *Node) nodefmt(s fmt.State, flag FmtFlag, mode fmtMode) {
+func nodeFmt(n *Node, s fmt.State, flag FmtFlag, mode FmtMode) {
        t := n.Type
 
        // We almost always want the original.
@@ -1556,7 +1564,7 @@ func (n *Node) nodefmt(s fmt.State, flag FmtFlag, mode fmtMode) {
        }
 
        if flag&FmtLong != 0 && t != nil {
-               if t.Etype == TNIL {
+               if t.Etype == types.TNIL {
                        fmt.Fprint(s, "nil")
                } else if n.Op == ONAME && n.Name.AutoTemp() {
                        mode.Fprintf(s, "%v value", t)
@@ -1568,15 +1576,15 @@ func (n *Node) nodefmt(s fmt.State, flag FmtFlag, mode fmtMode) {
 
        // TODO inlining produces expressions with ninits. we can't print these yet.
 
-       if opprec[n.Op] < 0 {
-               n.stmtfmt(s, mode)
+       if OpPrec[n.Op] < 0 {
+               stmtFmt(n, s, mode)
                return
        }
 
-       n.exprfmt(s, 0, mode)
+       exprFmt(n, s, 0, mode)
 }
 
-func (n *Node) nodedump(s fmt.State, flag FmtFlag, mode fmtMode) {
+func nodeDumpFmt(n *Node, s fmt.State, flag FmtFlag, mode FmtMode) {
        recur := flag&FmtShort == 0
 
        if recur {
@@ -1647,7 +1655,7 @@ func (n *Node) nodedump(s fmt.State, flag FmtFlag, mode fmtMode) {
                if n.Op == ODCLFUNC && n.Func != nil && n.Func.Dcl != nil && len(n.Func.Dcl) != 0 {
                        indent(s)
                        // The dcls for a func or closure
-                       mode.Fprintf(s, "%v-dcl%v", n.Op, asNodes(n.Func.Dcl))
+                       mode.Fprintf(s, "%v-dcl%v", n.Op, AsNodes(n.Func.Dcl))
                }
                if n.List.Len() != 0 {
                        indent(s)
@@ -1667,7 +1675,7 @@ func (n *Node) nodedump(s fmt.State, flag FmtFlag, mode fmtMode) {
 }
 
 // "%S" suppresses qualifying with package
-func symFormat(s *types.Sym, f fmt.State, verb rune, mode fmtMode) {
+func symFormat(s *types.Sym, f fmt.State, verb rune, mode FmtMode) {
        switch verb {
        case 'v', 'S':
                fmt.Fprint(f, sconv(s, fmtFlag(f, verb), mode))
@@ -1677,10 +1685,10 @@ func symFormat(s *types.Sym, f fmt.State, verb rune, mode fmtMode) {
        }
 }
 
-func smodeString(s *types.Sym, mode fmtMode) string { return sconv(s, 0, mode) }
+func smodeString(s *types.Sym, mode FmtMode) string { return sconv(s, 0, mode) }
 
 // See #16897 before changing the implementation of sconv.
-func sconv(s *types.Sym, flag FmtFlag, mode fmtMode) string {
+func sconv(s *types.Sym, flag FmtFlag, mode FmtMode) string {
        if flag&FmtLong != 0 {
                panic("linksymfmt")
        }
@@ -1701,7 +1709,7 @@ func sconv(s *types.Sym, flag FmtFlag, mode fmtMode) string {
        return types.InternString(buf.Bytes())
 }
 
-func sconv2(b *bytes.Buffer, s *types.Sym, flag FmtFlag, mode fmtMode) {
+func sconv2(b *bytes.Buffer, s *types.Sym, flag FmtFlag, mode FmtMode) {
        if flag&FmtLong != 0 {
                panic("linksymfmt")
        }
@@ -1718,7 +1726,7 @@ func sconv2(b *bytes.Buffer, s *types.Sym, flag FmtFlag, mode fmtMode) {
        symfmt(b, s, flag, mode)
 }
 
-func fldconv(b *bytes.Buffer, f *types.Field, flag FmtFlag, mode fmtMode, visited map[*types.Type]int, funarg types.Funarg) {
+func fldconv(b *bytes.Buffer, f *types.Field, flag FmtFlag, mode FmtMode, visited map[*types.Type]int, funarg types.Funarg) {
        if f == nil {
                b.WriteString("<T>")
                return
@@ -1734,12 +1742,12 @@ func fldconv(b *bytes.Buffer, f *types.Field, flag FmtFlag, mode fmtMode, visite
 
                // Take the name from the original.
                if mode == FErr {
-                       s = origSym(s)
+                       s = OrigSym(s)
                }
 
                if s != nil && f.Embedded == 0 {
                        if funarg != types.FunargNone {
-                               name = asNode(f.Nname).modeString(mode)
+                               name = modeString(AsNode(f.Nname), mode)
                        } else if flag&FmtLong != 0 {
                                name = mode.Sprintf("%0S", s)
                                if !types.IsExported(name) && flag&FmtUnsigned == 0 {
@@ -1775,7 +1783,7 @@ func fldconv(b *bytes.Buffer, f *types.Field, flag FmtFlag, mode fmtMode, visite
 
 // "%L"  print definition, not name
 // "%S"  omit 'func' and receiver from function types, short type names
-func typeFormat(t *types.Type, s fmt.State, verb rune, mode fmtMode) {
+func typeFormat(t *types.Type, s fmt.State, verb rune, mode FmtMode) {
        switch verb {
        case 'v', 'S', 'L':
                fmt.Fprint(s, tconv(t, fmtFlag(s, verb), mode))
@@ -1784,12 +1792,12 @@ func typeFormat(t *types.Type, s fmt.State, verb rune, mode fmtMode) {
        }
 }
 
-func (n *Node) String() string                 { return fmt.Sprint(n) }
-func (n *Node) modeString(mode fmtMode) string { return mode.Sprint(n) }
+func (n *Node) String() string                { return fmt.Sprint(n) }
+func modeString(n *Node, mode FmtMode) string { return mode.Sprint(n) }
 
 // "%L"  suffix with "(type %T)" where possible
 // "%+S" in debug mode, don't recurse, no multiline output
-func (n *Node) nconv(s fmt.State, flag FmtFlag, mode fmtMode) {
+func nconvFmt(n *Node, s fmt.State, flag FmtFlag, mode FmtMode) {
        if n == nil {
                fmt.Fprint(s, "<N>")
                return
@@ -1799,11 +1807,11 @@ func (n *Node) nconv(s fmt.State, flag FmtFlag, mode fmtMode) {
 
        switch mode {
        case FErr:
-               n.nodefmt(s, flag, mode)
+               nodeFmt(n, s, flag, mode)
 
        case FDbg:
                dumpdepth++
-               n.nodedump(s, flag, mode)
+               nodeDumpFmt(n, s, flag, mode)
                dumpdepth--
 
        default:
@@ -1811,7 +1819,7 @@ func (n *Node) nconv(s fmt.State, flag FmtFlag, mode fmtMode) {
        }
 }
 
-func (l Nodes) format(s fmt.State, verb rune, mode fmtMode) {
+func (l Nodes) format(s fmt.State, verb rune, mode FmtMode) {
        switch verb {
        case 'v':
                l.hconv(s, fmtFlag(s, verb), mode)
@@ -1826,7 +1834,7 @@ func (n Nodes) String() string {
 }
 
 // Flags: all those of %N plus '.': separate with comma's instead of semicolons.
-func (l Nodes) hconv(s fmt.State, flag FmtFlag, mode fmtMode) {
+func (l Nodes) hconv(s fmt.State, flag FmtFlag, mode FmtMode) {
        if l.Len() == 0 && mode == FDbg {
                fmt.Fprint(s, "<nil>")
                return
@@ -1841,18 +1849,18 @@ func (l Nodes) hconv(s fmt.State, flag FmtFlag, mode fmtMode) {
        }
 
        for i, n := range l.Slice() {
-               fmt.Fprint(s, n.modeString(mode))
+               fmt.Fprint(s, modeString(n, mode))
                if i+1 < l.Len() {
                        fmt.Fprint(s, sep)
                }
        }
 }
 
-func dumplist(s string, l Nodes) {
+func DumpList(s string, l Nodes) {
        fmt.Printf("%s%+v\n", s, l)
 }
 
-func fdumplist(w io.Writer, s string, l Nodes) {
+func FDumpList(w io.Writer, s string, l Nodes) {
        fmt.Fprintf(w, "%s%+v\n", s, l)
 }
 
@@ -1877,3 +1885,30 @@ func ellipsisIf(b bool) string {
        }
        return ""
 }
+
+// numImport tracks how often a package with a given name is imported.
+// It is used to provide a better error message (by using the package
+// path to disambiguate) if a package that appears multiple times with
+// the same name appears in an error message.
+var NumImport = make(map[string]int)
+
+func InstallTypeFormats() {
+       types.Sconv = func(s *types.Sym, flag, mode int) string {
+               return sconv(s, FmtFlag(flag), FmtMode(mode))
+       }
+       types.Tconv = func(t *types.Type, flag, mode int) string {
+               return tconv(t, FmtFlag(flag), FmtMode(mode))
+       }
+       types.FormatSym = func(sym *types.Sym, s fmt.State, verb rune, mode int) {
+               symFormat(sym, s, verb, FmtMode(mode))
+       }
+       types.FormatType = func(t *types.Type, s fmt.State, verb rune, mode int) {
+               typeFormat(t, s, verb, FmtMode(mode))
+       }
+}
+
+// Line returns n's position as a string. If n has been inlined,
+// it uses the outermost position where n has been inlined.
+func Line(n *Node) string {
+       return base.FmtPos(n.Pos)
+}
diff --git a/src/cmd/compile/internal/ir/ir.go b/src/cmd/compile/internal/ir/ir.go
new file mode 100644 (file)
index 0000000..ad7f692
--- /dev/null
@@ -0,0 +1,12 @@
+// 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 ir
+
+import "cmd/compile/internal/types"
+
+var LocalPkg *types.Pkg // package being compiled
+
+// builtinpkg is a fake package that declares the universe block.
+var BuiltinPkg *types.Pkg
similarity index 82%
rename from src/cmd/compile/internal/gc/syntax.go
rename to src/cmd/compile/internal/ir/node.go
index 11671fc54a05d0bea13d9cf93197749529576192..e6ed178f495eb382955666557da58af82b34461a 100644 (file)
@@ -4,17 +4,20 @@
 
 // “Abstract” syntax representation.
 
-package gc
+package ir
 
 import (
+       "go/constant"
+       "sort"
+       "strings"
+       "unsafe"
+
        "cmd/compile/internal/base"
        "cmd/compile/internal/ssa"
        "cmd/compile/internal/types"
        "cmd/internal/obj"
        "cmd/internal/objabi"
        "cmd/internal/src"
-       "go/constant"
-       "sort"
 )
 
 // A Node is a single node in the syntax tree.
@@ -290,7 +293,7 @@ func (n *Node) SetVal(v constant.Value) {
                base.Fatalf("have Opt")
        }
        if n.Op == OLITERAL {
-               assertRepresents(n.Type, v)
+               AssertValidTypeForConst(n.Type, v)
        }
        n.SetHasVal(true)
        n.E = &v
@@ -333,7 +336,7 @@ func (n *Node) SetIota(x int64) {
 
 // mayBeShared reports whether n may occur in multiple places in the AST.
 // Extra care must be taken when mutating such a node.
-func (n *Node) mayBeShared() bool {
+func MayBeShared(n *Node) bool {
        switch n.Op {
        case ONAME, OLITERAL, ONIL, OTYPE:
                return true
@@ -342,7 +345,7 @@ func (n *Node) mayBeShared() bool {
 }
 
 // funcname returns the name (without the package) of the function n.
-func (n *Node) funcname() string {
+func FuncName(n *Node) string {
        if n == nil || n.Func == nil || n.Func.Nname == nil {
                return "<nil>"
        }
@@ -353,7 +356,7 @@ func (n *Node) funcname() string {
 // This differs from the compiler's internal convention where local functions lack a package
 // because the ultimate consumer of this is a human looking at an IDE; package is only empty
 // if the compilation package is actually the empty string.
-func (n *Node) pkgFuncName() string {
+func PkgFuncName(n *Node) string {
        var s *types.Sym
        if n == nil {
                return "<nil>"
@@ -681,7 +684,7 @@ type Func struct {
 
        FieldTrack map[*types.Sym]struct{}
        DebugInfo  *ssa.FuncDebug
-       lsym       *obj.LSym
+       LSym       *obj.LSym
 
        Inl *Inline
 
@@ -693,13 +696,13 @@ type Func struct {
        Pragma PragmaFlag // go:xxx function annotations
 
        flags      bitset16
-       numDefers  int // number of defer calls in the function
-       numReturns int // number of explicit returns in the function
+       NumDefers  int // number of defer calls in the function
+       NumReturns int // number of explicit returns in the function
 
        // nwbrCalls records the LSyms of functions called by this
        // function for go:nowritebarrierrec analysis. Only filled in
        // if nowritebarrierrecCheck != nil.
-       nwbrCalls *[]nowritebarrierrecCallSym
+       NWBRCalls *[]SymAndPos
 }
 
 // An Inline holds fields used for function bodies that can be inlined.
@@ -764,7 +767,7 @@ func (f *Func) SetExportInline(b bool)             { f.flags.set(funcExportInlin
 func (f *Func) SetInstrumentBody(b bool)           { f.flags.set(funcInstrumentBody, b) }
 func (f *Func) SetOpenCodedDeferDisallowed(b bool) { f.flags.set(funcOpenCodedDeferDisallowed, b) }
 
-func (f *Func) setWBPos(pos src.XPos) {
+func (f *Func) SetWBPos(pos src.XPos) {
        if base.Debug.WB != 0 {
                base.WarnfAt(pos, "write barrier")
        }
@@ -996,7 +999,7 @@ const (
 type Nodes struct{ slice *[]*Node }
 
 // asNodes returns a slice of *Node as a Nodes value.
-func asNodes(s []*Node) Nodes {
+func AsNodes(s []*Node) Nodes {
        return Nodes{&s}
 }
 
@@ -1136,38 +1139,38 @@ func (n *Nodes) AppendNodes(n2 *Nodes) {
 
 // inspect invokes f on each node in an AST in depth-first order.
 // If f(n) returns false, inspect skips visiting n's children.
-func inspect(n *Node, f func(*Node) bool) {
+func Inspect(n *Node, f func(*Node) bool) {
        if n == nil || !f(n) {
                return
        }
-       inspectList(n.Ninit, f)
-       inspect(n.Left, f)
-       inspect(n.Right, f)
-       inspectList(n.List, f)
-       inspectList(n.Nbody, f)
-       inspectList(n.Rlist, f)
+       InspectList(n.Ninit, f)
+       Inspect(n.Left, f)
+       Inspect(n.Right, f)
+       InspectList(n.List, f)
+       InspectList(n.Nbody, f)
+       InspectList(n.Rlist, f)
 }
 
-func inspectList(l Nodes, f func(*Node) bool) {
+func InspectList(l Nodes, f func(*Node) bool) {
        for _, n := range l.Slice() {
-               inspect(n, f)
+               Inspect(n, f)
        }
 }
 
 // nodeQueue is a FIFO queue of *Node. The zero value of nodeQueue is
 // a ready-to-use empty queue.
-type nodeQueue struct {
+type NodeQueue struct {
        ring       []*Node
        head, tail int
 }
 
 // empty reports whether q contains no Nodes.
-func (q *nodeQueue) empty() bool {
+func (q *NodeQueue) Empty() bool {
        return q.head == q.tail
 }
 
 // pushRight appends n to the right of the queue.
-func (q *nodeQueue) pushRight(n *Node) {
+func (q *NodeQueue) PushRight(n *Node) {
        if len(q.ring) == 0 {
                q.ring = make([]*Node, 16)
        } else if q.head+len(q.ring) == q.tail {
@@ -1191,8 +1194,8 @@ func (q *nodeQueue) pushRight(n *Node) {
 
 // popLeft pops a node from the left of the queue. It panics if q is
 // empty.
-func (q *nodeQueue) popLeft() *Node {
-       if q.empty() {
+func (q *NodeQueue) PopLeft() *Node {
+       if q.Empty() {
                panic("dequeue empty")
        }
        n := q.ring[q.head%len(q.ring)]
@@ -1226,3 +1229,342 @@ func (s NodeSet) Sorted(less func(*Node, *Node) bool) []*Node {
        sort.Slice(res, func(i, j int) bool { return less(res[i], res[j]) })
        return res
 }
+
+func Nod(op Op, nleft, nright *Node) *Node {
+       return NodAt(base.Pos, op, nleft, nright)
+}
+
+func NodAt(pos src.XPos, op Op, nleft, nright *Node) *Node {
+       var n *Node
+       switch op {
+       case ODCLFUNC:
+               var x struct {
+                       n Node
+                       f Func
+               }
+               n = &x.n
+               n.Func = &x.f
+               n.Func.Decl = n
+       case ONAME:
+               base.Fatalf("use newname instead")
+       case OLABEL, OPACK:
+               var x struct {
+                       n Node
+                       m Name
+               }
+               n = &x.n
+               n.Name = &x.m
+       default:
+               n = new(Node)
+       }
+       n.Op = op
+       n.Left = nleft
+       n.Right = nright
+       n.Pos = pos
+       n.Xoffset = types.BADWIDTH
+       n.Orig = n
+       return n
+}
+
+// newnamel returns a new ONAME Node associated with symbol s at position pos.
+// The caller is responsible for setting n.Name.Curfn.
+func NewNameAt(pos src.XPos, s *types.Sym) *Node {
+       if s == nil {
+               base.Fatalf("newnamel nil")
+       }
+
+       var x struct {
+               n Node
+               m Name
+               p Param
+       }
+       n := &x.n
+       n.Name = &x.m
+       n.Name.Param = &x.p
+
+       n.Op = ONAME
+       n.Pos = pos
+       n.Orig = n
+
+       n.Sym = s
+       return n
+}
+
+// The Class of a variable/function describes the "storage class"
+// of a variable or function. During parsing, storage classes are
+// called declaration contexts.
+type Class uint8
+
+//go:generate stringer -type=Class
+const (
+       Pxxx      Class = iota // no class; used during ssa conversion to indicate pseudo-variables
+       PEXTERN                // global variables
+       PAUTO                  // local variables
+       PAUTOHEAP              // local variables or parameters moved to heap
+       PPARAM                 // input arguments
+       PPARAMOUT              // output results
+       PFUNC                  // global functions
+
+       // Careful: Class is stored in three bits in Node.flags.
+       _ = uint((1 << 3) - iota) // static assert for iota <= (1 << 3)
+)
+
+type PragmaFlag int16
+
+const (
+       // Func pragmas.
+       Nointerface    PragmaFlag = 1 << iota
+       Noescape                  // func parameters don't escape
+       Norace                    // func must not have race detector annotations
+       Nosplit                   // func should not execute on separate stack
+       Noinline                  // func should not be inlined
+       NoCheckPtr                // func should not be instrumented by checkptr
+       CgoUnsafeArgs             // treat a pointer to one arg as a pointer to them all
+       UintptrEscapes            // pointers converted to uintptr escape
+
+       // Runtime-only func pragmas.
+       // See ../../../../runtime/README.md for detailed descriptions.
+       Systemstack        // func must run on system stack
+       Nowritebarrier     // emit compiler error instead of write barrier
+       Nowritebarrierrec  // error on write barrier in this or recursive callees
+       Yeswritebarrierrec // cancels Nowritebarrierrec in this function and callees
+
+       // Runtime and cgo type pragmas
+       NotInHeap // values of this type must not be heap allocated
+
+       // Go command pragmas
+       GoBuildPragma
+)
+
+type SymAndPos struct {
+       Sym *obj.LSym // LSym of callee
+       Pos src.XPos  // line of call
+}
+
+func AsNode(n *types.Node) *Node { return (*Node)(unsafe.Pointer(n)) }
+
+func AsTypesNode(n *Node) *types.Node { return (*types.Node)(unsafe.Pointer(n)) }
+
+var BlankNode *Node
+
+// origSym returns the original symbol written by the user.
+func OrigSym(s *types.Sym) *types.Sym {
+       if s == nil {
+               return nil
+       }
+
+       if len(s.Name) > 1 && s.Name[0] == '~' {
+               switch s.Name[1] {
+               case 'r': // originally an unnamed result
+                       return nil
+               case 'b': // originally the blank identifier _
+                       // TODO(mdempsky): Does s.Pkg matter here?
+                       return BlankNode.Sym
+               }
+               return s
+       }
+
+       if strings.HasPrefix(s.Name, ".anon") {
+               // originally an unnamed or _ name (see subr.go: structargs)
+               return nil
+       }
+
+       return s
+}
+
+// SliceBounds returns n's slice bounds: low, high, and max in expr[low:high:max].
+// n must be a slice expression. max is nil if n is a simple slice expression.
+func (n *Node) SliceBounds() (low, high, max *Node) {
+       if n.List.Len() == 0 {
+               return nil, nil, nil
+       }
+
+       switch n.Op {
+       case OSLICE, OSLICEARR, OSLICESTR:
+               s := n.List.Slice()
+               return s[0], s[1], nil
+       case OSLICE3, OSLICE3ARR:
+               s := n.List.Slice()
+               return s[0], s[1], s[2]
+       }
+       base.Fatalf("SliceBounds op %v: %v", n.Op, n)
+       return nil, nil, nil
+}
+
+// SetSliceBounds sets n's slice bounds, where n is a slice expression.
+// n must be a slice expression. If max is non-nil, n must be a full slice expression.
+func (n *Node) SetSliceBounds(low, high, max *Node) {
+       switch n.Op {
+       case OSLICE, OSLICEARR, OSLICESTR:
+               if max != nil {
+                       base.Fatalf("SetSliceBounds %v given three bounds", n.Op)
+               }
+               s := n.List.Slice()
+               if s == nil {
+                       if low == nil && high == nil {
+                               return
+                       }
+                       n.List.Set2(low, high)
+                       return
+               }
+               s[0] = low
+               s[1] = high
+               return
+       case OSLICE3, OSLICE3ARR:
+               s := n.List.Slice()
+               if s == nil {
+                       if low == nil && high == nil && max == nil {
+                               return
+                       }
+                       n.List.Set3(low, high, max)
+                       return
+               }
+               s[0] = low
+               s[1] = high
+               s[2] = max
+               return
+       }
+       base.Fatalf("SetSliceBounds op %v: %v", n.Op, n)
+}
+
+// IsSlice3 reports whether o is a slice3 op (OSLICE3, OSLICE3ARR).
+// o must be a slicing op.
+func (o Op) IsSlice3() bool {
+       switch o {
+       case OSLICE, OSLICEARR, OSLICESTR:
+               return false
+       case OSLICE3, OSLICE3ARR:
+               return true
+       }
+       base.Fatalf("IsSlice3 op %v", o)
+       return false
+}
+
+func IsConst(n *Node, ct constant.Kind) bool {
+       return ConstType(n) == ct
+}
+
+// Int64Val returns n as an int64.
+// n must be an integer or rune constant.
+func (n *Node) Int64Val() int64 {
+       if !IsConst(n, constant.Int) {
+               base.Fatalf("Int64Val(%v)", n)
+       }
+       x, ok := constant.Int64Val(n.Val())
+       if !ok {
+               base.Fatalf("Int64Val(%v)", n)
+       }
+       return x
+}
+
+// CanInt64 reports whether it is safe to call Int64Val() on n.
+func (n *Node) CanInt64() bool {
+       if !IsConst(n, constant.Int) {
+               return false
+       }
+
+       // if the value inside n cannot be represented as an int64, the
+       // return value of Int64 is undefined
+       _, ok := constant.Int64Val(n.Val())
+       return ok
+}
+
+// Uint64Val returns n as an uint64.
+// n must be an integer or rune constant.
+func (n *Node) Uint64Val() uint64 {
+       if !IsConst(n, constant.Int) {
+               base.Fatalf("Uint64Val(%v)", n)
+       }
+       x, ok := constant.Uint64Val(n.Val())
+       if !ok {
+               base.Fatalf("Uint64Val(%v)", n)
+       }
+       return x
+}
+
+// BoolVal returns n as a bool.
+// n must be a boolean constant.
+func (n *Node) BoolVal() bool {
+       if !IsConst(n, constant.Bool) {
+               base.Fatalf("BoolVal(%v)", n)
+       }
+       return constant.BoolVal(n.Val())
+}
+
+// StringVal returns the value of a literal string Node as a string.
+// n must be a string constant.
+func (n *Node) StringVal() string {
+       if !IsConst(n, constant.String) {
+               base.Fatalf("StringVal(%v)", n)
+       }
+       return constant.StringVal(n.Val())
+}
+
+// rawcopy returns a shallow copy of n.
+// Note: copy or sepcopy (rather than rawcopy) is usually the
+//       correct choice (see comment with Node.copy, below).
+func (n *Node) RawCopy() *Node {
+       copy := *n
+       return &copy
+}
+
+// sepcopy returns a separate shallow copy of n, with the copy's
+// Orig pointing to itself.
+func SepCopy(n *Node) *Node {
+       copy := *n
+       copy.Orig = &copy
+       return &copy
+}
+
+// copy returns shallow copy of n and adjusts the copy's Orig if
+// necessary: In general, if n.Orig points to itself, the copy's
+// Orig should point to itself as well. Otherwise, if n is modified,
+// the copy's Orig node appears modified, too, and then doesn't
+// represent the original node anymore.
+// (This caused the wrong complit Op to be used when printing error
+// messages; see issues #26855, #27765).
+func Copy(n *Node) *Node {
+       copy := *n
+       if n.Orig == n {
+               copy.Orig = &copy
+       }
+       return &copy
+}
+
+// isNil reports whether n represents the universal untyped zero value "nil".
+func IsNil(n *Node) bool {
+       // Check n.Orig because constant propagation may produce typed nil constants,
+       // which don't exist in the Go spec.
+       return n.Orig.Op == ONIL
+}
+
+func IsBlank(n *Node) bool {
+       if n == nil {
+               return false
+       }
+       return n.Sym.IsBlank()
+}
+
+// IsMethod reports whether n is a method.
+// n must be a function or a method.
+func IsMethod(n *Node) bool {
+       return n.Type.Recv() != nil
+}
+
+func (n *Node) Typ() *types.Type {
+       return n.Type
+}
+
+func (n *Node) StorageClass() ssa.StorageClass {
+       switch n.Class() {
+       case PPARAM:
+               return ssa.ClassParam
+       case PPARAMOUT:
+               return ssa.ClassParamOut
+       case PAUTO:
+               return ssa.ClassAuto
+       default:
+               base.Fatalf("untranslatable storage class for %v: %s", n, n.Class())
+               return 0
+       }
+}
similarity index 99%
rename from src/cmd/compile/internal/gc/op_string.go
rename to src/cmd/compile/internal/ir/op_string.go
index 16fd79e4778807994adf7f703034e2a81d249e3a..d0d3778357e6735ae68b9b9d7895624ae802d67e 100644 (file)
@@ -1,6 +1,6 @@
 // Code generated by "stringer -type=Op -trimprefix=O"; DO NOT EDIT.
 
-package gc
+package ir
 
 import "strconv"
 
similarity index 98%
rename from src/cmd/compile/internal/gc/sizeof_test.go
rename to src/cmd/compile/internal/ir/sizeof_test.go
index 2f2eba4c6755c22c7e7690c7b1a2821bdb966510..c5169b9092a0e715b52c085e09093c004f09a554 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-package gc
+package ir
 
 import (
        "reflect"
diff --git a/src/cmd/compile/internal/ir/val.go b/src/cmd/compile/internal/ir/val.go
new file mode 100644 (file)
index 0000000..00b5bfd
--- /dev/null
@@ -0,0 +1,120 @@
+// 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 ir
+
+import (
+       "go/constant"
+       "math"
+
+       "cmd/compile/internal/base"
+       "cmd/compile/internal/types"
+)
+
+func ConstType(n *Node) constant.Kind {
+       if n == nil || n.Op != OLITERAL {
+               return constant.Unknown
+       }
+       return n.Val().Kind()
+}
+
+// ValueInterface returns the constant value stored in n as an interface{}.
+// It returns int64s for ints and runes, float64s for floats,
+// and complex128s for complex values.
+func ConstValue(n *Node) interface{} {
+       switch v := n.Val(); v.Kind() {
+       default:
+               base.Fatalf("unexpected constant: %v", v)
+               panic("unreachable")
+       case constant.Bool:
+               return constant.BoolVal(v)
+       case constant.String:
+               return constant.StringVal(v)
+       case constant.Int:
+               return Int64Val(n.Type, v)
+       case constant.Float:
+               return Float64Val(v)
+       case constant.Complex:
+               return complex(Float64Val(constant.Real(v)), Float64Val(constant.Imag(v)))
+       }
+}
+
+// int64Val returns v converted to int64.
+// Note: if t is uint64, very large values will be converted to negative int64.
+func Int64Val(t *types.Type, v constant.Value) int64 {
+       if t.IsUnsigned() {
+               if x, ok := constant.Uint64Val(v); ok {
+                       return int64(x)
+               }
+       } else {
+               if x, ok := constant.Int64Val(v); ok {
+                       return x
+               }
+       }
+       base.Fatalf("%v out of range for %v", v, t)
+       panic("unreachable")
+}
+
+func Float64Val(v constant.Value) float64 {
+       if x, _ := constant.Float64Val(v); !math.IsInf(x, 0) {
+               return x + 0 // avoid -0 (should not be needed, but be conservative)
+       }
+       base.Fatalf("bad float64 value: %v", v)
+       panic("unreachable")
+}
+
+func AssertValidTypeForConst(t *types.Type, v constant.Value) {
+       if !ValidTypeForConst(t, v) {
+               base.Fatalf("%v does not represent %v", t, v)
+       }
+}
+
+func ValidTypeForConst(t *types.Type, v constant.Value) bool {
+       switch v.Kind() {
+       case constant.Unknown:
+               return OKForConst[t.Etype]
+       case constant.Bool:
+               return t.IsBoolean()
+       case constant.String:
+               return t.IsString()
+       case constant.Int:
+               return t.IsInteger()
+       case constant.Float:
+               return t.IsFloat()
+       case constant.Complex:
+               return t.IsComplex()
+       }
+
+       base.Fatalf("unexpected constant kind: %v", v)
+       panic("unreachable")
+}
+
+// nodlit returns a new untyped constant with value v.
+func NewLiteral(v constant.Value) *Node {
+       n := Nod(OLITERAL, nil, nil)
+       if k := v.Kind(); k != constant.Unknown {
+               n.Type = idealType(k)
+               n.SetVal(v)
+       }
+       return n
+}
+
+func idealType(ct constant.Kind) *types.Type {
+       switch ct {
+       case constant.String:
+               return types.UntypedString
+       case constant.Bool:
+               return types.UntypedBool
+       case constant.Int:
+               return types.UntypedInt
+       case constant.Float:
+               return types.UntypedFloat
+       case constant.Complex:
+               return types.UntypedComplex
+       }
+       base.Fatalf("unexpected Ctype: %v", ct)
+       return nil
+}
+
+var OKForConst [types.NTYPE]bool
index c37a2e07149d905027c5e1cefa8d832ec5e48ba1..87e6f5b0c7ae2ca2a064aca45d8109b8202e9d86 100644 (file)
@@ -9,6 +9,7 @@ import (
 
        "cmd/compile/internal/base"
        "cmd/compile/internal/gc"
+       "cmd/compile/internal/ir"
        "cmd/compile/internal/logopt"
        "cmd/compile/internal/ssa"
        "cmd/compile/internal/types"
@@ -288,7 +289,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                case *obj.LSym:
                        wantreg = "SB"
                        gc.AddAux(&p.From, v)
-               case *gc.Node:
+               case *ir.Node:
                        wantreg = "SP"
                        gc.AddAux(&p.From, v)
                case nil:
index a7c10d8869b5d1b0f4dd74ae6af26bbdce6c95fe..ea22c488aab9732e834d38e08aabc2e4c38362eb 100644 (file)
@@ -9,6 +9,7 @@ import (
 
        "cmd/compile/internal/base"
        "cmd/compile/internal/gc"
+       "cmd/compile/internal/ir"
        "cmd/compile/internal/logopt"
        "cmd/compile/internal/ssa"
        "cmd/compile/internal/types"
@@ -262,7 +263,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                case *obj.LSym:
                        wantreg = "SB"
                        gc.AddAux(&p.From, v)
-               case *gc.Node:
+               case *ir.Node:
                        wantreg = "SP"
                        gc.AddAux(&p.From, v)
                case nil:
index e3f0ee1a932f7621a9d46a295fabd61ea8954293..848f27af843f49bdd23518d76908431a9aa679a6 100644 (file)
@@ -7,6 +7,7 @@ package ppc64
 import (
        "cmd/compile/internal/base"
        "cmd/compile/internal/gc"
+       "cmd/compile/internal/ir"
        "cmd/compile/internal/logopt"
        "cmd/compile/internal/ssa"
        "cmd/compile/internal/types"
@@ -751,7 +752,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                                p.To.Reg = v.Reg()
                        }
 
-               case *obj.LSym, *gc.Node:
+               case *obj.LSym, *ir.Node:
                        p := s.Prog(ppc64.AMOVD)
                        p.From.Type = obj.TYPE_ADDR
                        p.From.Reg = v.Args[0].Reg()
index 5a71b33c00cb6509f7faa43f173b1e1b9e63cefd..a3dc07fe030296d79d8399acee4cf8a17472b5be 100644 (file)
@@ -7,6 +7,7 @@ package riscv64
 import (
        "cmd/compile/internal/base"
        "cmd/compile/internal/gc"
+       "cmd/compile/internal/ir"
        "cmd/compile/internal/ssa"
        "cmd/compile/internal/types"
        "cmd/internal/obj"
@@ -323,7 +324,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                case *obj.LSym:
                        wantreg = "SB"
                        gc.AddAux(&p.From, v)
-               case *gc.Node:
+               case *ir.Node:
                        wantreg = "SP"
                        gc.AddAux(&p.From, v)
                case nil:
index 373dc431e54c688e64d9b9fdb5e0e4e709f26a7f..1a8b5691ef09a012f57c3cfaa549fc88ac67fe9e 100644 (file)
@@ -7,6 +7,7 @@ package wasm
 import (
        "cmd/compile/internal/base"
        "cmd/compile/internal/gc"
+       "cmd/compile/internal/ir"
        "cmd/compile/internal/logopt"
        "cmd/compile/internal/ssa"
        "cmd/compile/internal/types"
@@ -236,7 +237,7 @@ func ssaGenValueOnStack(s *gc.SSAGenState, v *ssa.Value, extend bool) {
                switch v.Aux.(type) {
                case *obj.LSym:
                        gc.AddAux(&p.From, v)
-               case *gc.Node:
+               case *ir.Node:
                        p.From.Reg = v.Args[0].Reg()
                        gc.AddAux(&p.From, v)
                default:
index f8e1f2f95131ce87b1d6767b5330272ab2e99ccd..839579349a28de43d17568ea9b89e10d1d41faed 100644 (file)
@@ -42,6 +42,7 @@ var bootstrapDirs = []string{
        "cmd/compile/internal/arm",
        "cmd/compile/internal/arm64",
        "cmd/compile/internal/gc",
+       "cmd/compile/internal/ir",
        "cmd/compile/internal/logopt",
        "cmd/compile/internal/mips",
        "cmd/compile/internal/mips64",