]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: remove Symbol wrappers from Aux fields
authorKeith Randall <khr@golang.org>
Mon, 18 Sep 2017 21:53:56 +0000 (14:53 -0700)
committerKeith Randall <khr@golang.org>
Tue, 19 Sep 2017 22:03:10 +0000 (22:03 +0000)
We used to have {Arg,Auto,Extern}Symbol structs with which we wrapped
a *gc.Node or *obj.LSym before storing them in the Aux field
of an ssa.Value.  This let the SSA part of the compiler distinguish
between autos and args, for example.  We no longer need the wrappers
as we can query the underlying objects directly.

There was also some sloppy usage, where VarDef had a *gc.Node
directly in its Aux field, whereas the use of that variable had
that *gc.Node wrapped in an AutoSymbol. Thus the Aux fields didn't
match (using ==) when they probably should.
This sloppy usage cleanup is the only thing in the CL that changes the
generated code - we can get rid of some more unused auto variables if
the matching happens reliably.

Removing this wrapper also lets us get rid of the varsyms cache
(which was used to prevent wrapping the same *gc.Node twice).

Change-Id: I0dedf8f82f84bfee413d310342b777316bd1d478
Reviewed-on: https://go-review.googlesource.com/64452
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
18 files changed:
src/cmd/compile/fmt_test.go
src/cmd/compile/internal/arm/ssa.go
src/cmd/compile/internal/arm64/ssa.go
src/cmd/compile/internal/gc/pgen.go
src/cmd/compile/internal/gc/plive.go
src/cmd/compile/internal/gc/ssa.go
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/ssa/config.go
src/cmd/compile/internal/ssa/deadstore.go
src/cmd/compile/internal/ssa/export_test.go
src/cmd/compile/internal/ssa/gen/genericOps.go
src/cmd/compile/internal/ssa/op.go
src/cmd/compile/internal/ssa/opGen.go
src/cmd/compile/internal/ssa/rewrite.go
src/cmd/compile/internal/ssa/value.go
src/cmd/compile/internal/ssa/writebarrier.go

index dde80565b8e49e343de793ec178a56ebd560bed8..91cf0c80a335222246112713dda14506dde715c9 100644 (file)
@@ -622,6 +622,7 @@ var knownFormats = map[string]string{
        "byte %c":                                         "",
        "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.Ctype %d":                "",
        "cmd/compile/internal/gc.Ctype %v":                "",
index a70df6dd0ee146139c8b419fb59219a688de82b7..4655513fa5a63620dd1230fd5e90ac8ec8ed5f95 100644 (file)
@@ -493,10 +493,10 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                switch v.Aux.(type) {
                default:
                        v.Fatalf("aux is of unknown type %T", v.Aux)
-               case *ssa.ExternSymbol:
+               case *obj.LSym:
                        wantreg = "SB"
                        gc.AddAux(&p.From, v)
-               case *ssa.ArgSymbol, *ssa.AutoSymbol:
+               case *gc.Node:
                        wantreg = "SP"
                        gc.AddAux(&p.From, v)
                case nil:
index e74207b8569898e8e357bde01dbbd1d2f93401ed..3c140be97deca5c29c668109989aec2b5edceb8a 100644 (file)
@@ -273,10 +273,10 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                switch v.Aux.(type) {
                default:
                        v.Fatalf("aux is of unknown type %T", v.Aux)
-               case *ssa.ExternSymbol:
+               case *obj.LSym:
                        wantreg = "SB"
                        gc.AddAux(&p.From, v)
-               case *ssa.ArgSymbol, *ssa.AutoSymbol:
+               case *gc.Node:
                        wantreg = "SP"
                        gc.AddAux(&p.From, v)
                case nil:
index 79155f9ad605964bacd998bd96cd88a946f49f3d..54fdb30d108ee15f9b7d682f9da2e7d1189ef81c 100644 (file)
@@ -133,20 +133,21 @@ func (s *ssafn) AllocFrame(f *ssa.Func) {
        scratchUsed := false
        for _, b := range f.Blocks {
                for _, v := range b.Values {
-                       switch a := v.Aux.(type) {
-                       case *ssa.ArgSymbol:
-                               n := a.Node.(*Node)
-                               // Don't modify nodfp; it is a global.
-                               if n != nodfp {
+                       if n, ok := v.Aux.(*Node); ok {
+                               switch n.Class() {
+                               case PPARAM, PPARAMOUT:
+                                       // Don't modify nodfp; it is a global.
+                                       if n != nodfp {
+                                               n.Name.SetUsed(true)
+                                       }
+                               case PAUTO:
                                        n.Name.SetUsed(true)
                                }
-                       case *ssa.AutoSymbol:
-                               a.Node.(*Node).Name.SetUsed(true)
                        }
-
                        if !scratchUsed {
                                scratchUsed = v.Op.UsesScratch()
                        }
+
                }
        }
 
index 1bb714e837e5ba0f8c8bb207240a7ef694231e12..c3bc753d078dbf112dc754deefa83a5ae5862eee 100644 (file)
@@ -291,14 +291,7 @@ func affectedNode(v *ssa.Value) (*Node, ssa.SymEffect) {
                return n, ssa.SymWrite
 
        case ssa.OpVarLive:
-               switch a := v.Aux.(type) {
-               case *ssa.ArgSymbol:
-                       return a.Node.(*Node), ssa.SymRead
-               case *ssa.AutoSymbol:
-                       return a.Node.(*Node), ssa.SymRead
-               default:
-                       Fatalf("unknown VarLive aux type: %s", v.LongString())
-               }
+               return v.Aux.(*Node), ssa.SymRead
        case ssa.OpVarDef, ssa.OpVarKill:
                return v.Aux.(*Node), ssa.SymWrite
        case ssa.OpKeepAlive:
@@ -313,12 +306,10 @@ func affectedNode(v *ssa.Value) (*Node, ssa.SymEffect) {
 
        var n *Node
        switch a := v.Aux.(type) {
-       case nil, *ssa.ExternSymbol:
+       case nil, *obj.LSym:
                // ok, but no node
-       case *ssa.ArgSymbol:
-               n = a.Node.(*Node)
-       case *ssa.AutoSymbol:
-               n = a.Node.(*Node)
+       case *Node:
+               n = a
        default:
                Fatalf("weird aux: %s", v.LongString())
        }
@@ -931,13 +922,7 @@ func clobberWalk(b *ssa.Block, v *Node, offset int64, t *types.Type) {
 // clobberPtr generates a clobber of the pointer at offset offset in v.
 // The clobber instruction is added at the end of b.
 func clobberPtr(b *ssa.Block, v *Node, offset int64) {
-       var aux interface{}
-       if v.Class() == PAUTO {
-               aux = &ssa.AutoSymbol{Node: v}
-       } else {
-               aux = &ssa.ArgSymbol{Node: v}
-       }
-       b.NewValue0IA(src.NoXPos, ssa.OpClobber, types.TypeVoid, offset, aux)
+       b.NewValue0IA(src.NoXPos, ssa.OpClobber, types.TypeVoid, offset, v)
 }
 
 func (lv *Liveness) avarinitanyall(b *ssa.Block, any, all bvec) {
index 0ae0c26286a41b5f5ac2f0b617e50bd703f24b3a..04f1a9230e656b6ad63f37482532c778972cdceb 100644 (file)
@@ -163,15 +163,12 @@ func buildssa(fn *Node, worker int) *ssa.Func {
        s.startBlock(s.f.Entry)
        s.vars[&memVar] = s.startmem
 
-       s.varsyms = map[*Node]interface{}{}
-
        // Generate addresses of local declarations
        s.decladdrs = map[*Node]*ssa.Value{}
        for _, n := range fn.Func.Dcl {
                switch n.Class() {
                case PPARAM, PPARAMOUT:
-                       aux := s.lookupSymbol(n, &ssa.ArgSymbol{Node: n})
-                       s.decladdrs[n] = s.entryNewValue1A(ssa.OpAddr, types.NewPtr(n.Type), aux, s.sp)
+                       s.decladdrs[n] = s.entryNewValue1A(ssa.OpAddr, types.NewPtr(n.Type), n, s.sp)
                        if n.Class() == PPARAMOUT && s.canSSA(n) {
                                // Save ssa-able PPARAMOUT variables so we can
                                // store them back to the stack at the end of
@@ -259,9 +256,6 @@ type state struct {
        // addresses of PPARAM and PPARAMOUT variables.
        decladdrs map[*Node]*ssa.Value
 
-       // symbols for PEXTERN, PAUTO and PPARAMOUT variables so they can be reused.
-       varsyms map[*Node]interface{}
-
        // starting values. Memory, stack pointer, and globals pointer
        startmem *ssa.Value
        sp       *ssa.Value
@@ -937,16 +931,12 @@ func (s *state) stmt(n *Node) {
                if !n.Left.Addrtaken() {
                        s.Fatalf("VARLIVE variable %v must have Addrtaken set", n.Left)
                }
-               var aux interface{}
                switch n.Left.Class() {
-               case PAUTO:
-                       aux = s.lookupSymbol(n.Left, &ssa.AutoSymbol{Node: n.Left})
-               case PPARAM, PPARAMOUT:
-                       aux = s.lookupSymbol(n.Left, &ssa.ArgSymbol{Node: n.Left})
+               case PAUTO, PPARAM, PPARAMOUT:
                default:
                        s.Fatalf("VARLIVE variable %v must be Auto or Arg", n.Left)
                }
-               s.vars[&memVar] = s.newValue1A(ssa.OpVarLive, types.TypeMem, aux, s.mem())
+               s.vars[&memVar] = s.newValue1A(ssa.OpVarLive, types.TypeMem, n.Left, s.mem())
 
        case OCHECKNIL:
                p := s.expr(n.Left)
@@ -1420,14 +1410,13 @@ func (s *state) expr(n *Node) *ssa.Value {
                len := s.newValue1(ssa.OpStringLen, types.Types[TINT], str)
                return s.newValue3(ssa.OpSliceMake, n.Type, ptr, len, len)
        case OCFUNC:
-               aux := s.lookupSymbol(n, &ssa.ExternSymbol{Sym: n.Left.Sym.Linksym()})
+               aux := n.Left.Sym.Linksym()
                return s.entryNewValue1A(ssa.OpAddr, n.Type, aux, s.sb)
        case ONAME:
                if n.Class() == PFUNC {
                        // "value" of a function is the address of the function's closure
                        sym := funcsym(n.Sym).Linksym()
-                       aux := s.lookupSymbol(n, &ssa.ExternSymbol{Sym: sym})
-                       return s.entryNewValue1A(ssa.OpAddr, types.NewPtr(n.Type), aux, s.sb)
+                       return s.entryNewValue1A(ssa.OpAddr, types.NewPtr(n.Type), sym, s.sb)
                }
                if s.canSSA(n) {
                        return s.variable(n, n.Type)
@@ -2203,7 +2192,7 @@ func (s *state) append(n *Node, inplace bool) *ssa.Value {
        r := s.rtcall(growslice, true, []*types.Type{pt, types.Types[TINT], types.Types[TINT]}, taddr, p, l, c, nl)
 
        if inplace {
-               if sn.Op == ONAME {
+               if sn.Op == ONAME && sn.Class() != PEXTERN {
                        // Tell liveness we're about to build a new slice
                        s.vars[&memVar] = s.newValue1A(ssa.OpVarDef, types.TypeMem, sn, s.mem())
                }
@@ -2410,7 +2399,7 @@ func (s *state) assign(left *Node, right *ssa.Value, deref bool, skip skipMask)
        }
        // Left is not ssa-able. Compute its address.
        addr := s.addr(left, false)
-       if left.Op == ONAME && skip == 0 {
+       if left.Op == ONAME && left.Class() != PEXTERN && skip == 0 {
                s.vars[&memVar] = s.newValue1A(ssa.OpVarDef, types.TypeMem, left, s.mem())
        }
        if isReflectHeaderDataField(left) {
@@ -2879,7 +2868,7 @@ func init() {
                sys.ARM64)
        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 {
-                       aux := s.lookupSymbol(n, &ssa.ExternSymbol{Sym: syslook("support_popcnt").Sym.Linksym()})
+                       aux := syslook("support_popcnt").Sym.Linksym()
                        addr := s.entryNewValue1A(ssa.OpAddr, types.Types[TBOOL].PtrTo(), aux, s.sb)
                        v := s.newValue2(ssa.OpLoad, types.Types[TBOOL], addr, s.mem())
                        b := s.endBlock()
@@ -3231,24 +3220,6 @@ func etypesign(e types.EType) int8 {
        return 0
 }
 
-// lookupSymbol is used to retrieve the symbol (Extern, Arg or Auto) used for a particular node.
-// This improves the effectiveness of cse by using the same Aux values for the
-// same symbols.
-func (s *state) lookupSymbol(n *Node, sym interface{}) interface{} {
-       switch sym.(type) {
-       default:
-               s.Fatalf("sym %v is of unknown type %T", sym, sym)
-       case *ssa.ExternSymbol, *ssa.ArgSymbol, *ssa.AutoSymbol:
-               // these are the only valid types
-       }
-
-       if lsym, ok := s.varsyms[n]; ok {
-               return lsym
-       }
-       s.varsyms[n] = sym
-       return sym
-}
-
 // 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.
 // If bounded is true then this address does not require a nil check for its operand
@@ -3260,8 +3231,7 @@ func (s *state) addr(n *Node, bounded bool) *ssa.Value {
                switch n.Class() {
                case PEXTERN:
                        // global variable
-                       aux := s.lookupSymbol(n, &ssa.ExternSymbol{Sym: n.Sym.Linksym()})
-                       v := s.entryNewValue1A(ssa.OpAddr, t, aux, s.sb)
+                       v := s.entryNewValue1A(ssa.OpAddr, t, n.Sym.Linksym(), s.sb)
                        // TODO: Make OpAddr use AuxInt as well as Aux.
                        if n.Xoffset != 0 {
                                v = s.entryNewValue1I(ssa.OpOffPtr, v.Type, n.Xoffset, v)
@@ -3275,19 +3245,16 @@ func (s *state) addr(n *Node, bounded bool) *ssa.Value {
                        }
                        if n == nodfp {
                                // Special arg that points to the frame pointer (Used by ORECOVER).
-                               aux := s.lookupSymbol(n, &ssa.ArgSymbol{Node: n})
-                               return s.entryNewValue1A(ssa.OpAddr, t, aux, s.sp)
+                               return s.entryNewValue1A(ssa.OpAddr, t, n, s.sp)
                        }
                        s.Fatalf("addr of undeclared ONAME %v. declared: %v", n, s.decladdrs)
                        return nil
                case PAUTO:
-                       aux := s.lookupSymbol(n, &ssa.AutoSymbol{Node: n})
-                       return s.newValue1A(ssa.OpAddr, t, aux, s.sp)
+                       return s.newValue1A(ssa.OpAddr, t, n, s.sp)
                case PPARAMOUT: // Same as PAUTO -- cannot generate LEA early.
                        // ensure that we reuse symbols for out parameters so
                        // that cse works on their addresses
-                       aux := s.lookupSymbol(n, &ssa.ArgSymbol{Node: n})
-                       return s.newValue1A(ssa.OpAddr, t, aux, s.sp)
+                       return s.newValue1A(ssa.OpAddr, t, n, s.sp)
                default:
                        s.Fatalf("variable address class %v not implemented", classnames[n.Class()])
                        return nil
@@ -4672,10 +4639,11 @@ func AuxOffset(v *ssa.Value) (offset int64) {
        if v.Aux == nil {
                return 0
        }
-       switch sym := v.Aux.(type) {
-
-       case *ssa.AutoSymbol:
-               n := sym.Node.(*Node)
+       n, ok := v.Aux.(*Node)
+       if !ok {
+               v.Fatalf("bad aux type in %s\n", v.LongString())
+       }
+       if n.Class() == PAUTO {
                return n.Xoffset
        }
        return 0
@@ -4697,17 +4665,17 @@ func AddAux2(a *obj.Addr, v *ssa.Value, offset int64) {
                return
        }
        // Add symbol's offset from its base register.
-       switch sym := v.Aux.(type) {
-       case *ssa.ExternSymbol:
+       switch n := v.Aux.(type) {
+       case *obj.LSym:
                a.Name = obj.NAME_EXTERN
-               a.Sym = sym.Sym
-       case *ssa.ArgSymbol:
-               n := sym.Node.(*Node)
-               a.Name = obj.NAME_PARAM
-               a.Sym = n.Orig.Sym.Linksym()
-               a.Offset += n.Xoffset
-       case *ssa.AutoSymbol:
-               n := sym.Node.(*Node)
+               a.Sym = n
+       case *Node:
+               if n.Class() == PPARAM || n.Class() == PPARAMOUT {
+                       a.Name = obj.NAME_PARAM
+                       a.Sym = n.Orig.Sym.Linksym()
+                       a.Offset += n.Xoffset
+                       break
+               }
                a.Name = obj.NAME_AUTO
                a.Sym = n.Sym.Linksym()
                a.Offset += n.Xoffset
@@ -4922,9 +4890,8 @@ func (e *ssafn) StringData(s string) interface{} {
                e.strings = make(map[string]interface{})
        }
        data := stringsym(s)
-       aux := &ssa.ExternSymbol{Sym: data}
-       e.strings[s] = aux
-       return aux
+       e.strings[s] = data
+       return data
 }
 
 func (e *ssafn) Auto(pos src.XPos, t *types.Type) ssa.GCNode {
@@ -5141,3 +5108,16 @@ func (e *ssafn) Syslook(name string) *obj.LSym {
 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:
+               Fatalf("untranslateable storage class for %v: %s", n, n.Class())
+               return 0
+       }
+}
index e65515a85b0102876c4b6dd72952d34f8d02f43b..f7810ca49715e1f5ff677c6b31c8b635873289e1 100644 (file)
@@ -283,10 +283,10 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                switch v.Aux.(type) {
                default:
                        v.Fatalf("aux is of unknown type %T", v.Aux)
-               case *ssa.ExternSymbol:
+               case *obj.LSym:
                        wantreg = "SB"
                        gc.AddAux(&p.From, v)
-               case *ssa.ArgSymbol, *ssa.AutoSymbol:
+               case *gc.Node:
                        wantreg = "SP"
                        gc.AddAux(&p.From, v)
                case nil:
index db163f3e9d0776650062df3f4887b89fca2722b6..65314e48b606ae77c395488df7282446b4a924e3 100644 (file)
@@ -257,10 +257,10 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                switch v.Aux.(type) {
                default:
                        v.Fatalf("aux is of unknown type %T", v.Aux)
-               case *ssa.ExternSymbol:
+               case *obj.LSym:
                        wantreg = "SB"
                        gc.AddAux(&p.From, v)
-               case *ssa.ArgSymbol, *ssa.AutoSymbol:
+               case *gc.Node:
                        wantreg = "SP"
                        gc.AddAux(&p.From, v)
                case nil:
index 330d58becf724b585d6da61e6e4b0bb5db2eb0ae..1228da21277bed053189073cc52a496e07f57698 100644 (file)
@@ -628,10 +628,10 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                switch v.Aux.(type) {
                default:
                        v.Fatalf("aux is of unknown type %T", v.Aux)
-               case *ssa.ExternSymbol:
+               case *obj.LSym:
                        wantreg = "SB"
                        gc.AddAux(&p.From, v)
-               case *ssa.ArgSymbol, *ssa.AutoSymbol:
+               case *gc.Node:
                        wantreg = "SP"
                        gc.AddAux(&p.From, v)
                case nil:
index ad4b9114f3d12742eaeaaee6348bfca2a82bfa2d..c35221952387ba2cc12683f2c659a86e17ea2f0f 100644 (file)
@@ -133,13 +133,22 @@ type Frontend interface {
        UseWriteBarrier() bool
 }
 
-// interface used to hold *gc.Node. We'd use *gc.Node directly but
-// that would lead to an import cycle.
+// interface used to hold a *gc.Node (a stack variable).
+// We'd use *gc.Node directly but that would lead to an import cycle.
 type GCNode interface {
        Typ() *types.Type
        String() string
+       StorageClass() StorageClass
 }
 
+type StorageClass uint8
+
+const (
+       ClassAuto     StorageClass = iota // local stack variable
+       ClassParam                        // argument
+       ClassParamOut                     // return value
+)
+
 // NewConfig returns a new configuration object for the given architecture.
 func NewConfig(arch string, types Types, ctxt *obj.Link, optimize bool) *Config {
        c := &Config{arch: arch, Types: types}
index 7506df8b19f14e73f4a08935b9033dfd4ebd9fd5..bbeb990f174cce494f7c2636f6d549286c016615 100644 (file)
@@ -132,7 +132,8 @@ func dse(f *Func) {
        }
 }
 
-// elimUnreadAutos deletes stores to autos that are never read from.
+// elimUnreadAutos deletes stores (and associated bookkeeping ops VarDef and VarKill)
+// to autos that are never read from.
 func elimUnreadAutos(f *Func) {
        // Loop over all ops that affect autos taking note of which
        // autos we need and also stores that we might be able to
@@ -141,19 +142,21 @@ func elimUnreadAutos(f *Func) {
        var stores []*Value
        for _, b := range f.Blocks {
                for _, v := range b.Values {
-                       var sym *AutoSymbol
-                       sym, ok := v.Aux.(*AutoSymbol)
+                       n, ok := v.Aux.(GCNode)
                        if !ok {
                                continue
                        }
+                       if n.StorageClass() != ClassAuto {
+                               continue
+                       }
 
                        effect := v.Op.SymEffect()
                        switch effect {
-                       case SymWrite:
+                       case SymNone, SymWrite:
                                // If we haven't seen the auto yet
                                // then this might be a store we can
                                // eliminate.
-                               if !seen[sym.Node] {
+                               if !seen[n] {
                                        stores = append(stores, v)
                                }
                        default:
@@ -163,7 +166,7 @@ func elimUnreadAutos(f *Func) {
                                // because dead loads haven't been
                                // eliminated yet.
                                if v.Uses > 0 {
-                                       seen[sym.Node] = true
+                                       seen[n] = true
                                }
                        }
                }
@@ -171,8 +174,8 @@ func elimUnreadAutos(f *Func) {
 
        // Eliminate stores to unread autos.
        for _, store := range stores {
-               sym, _ := store.Aux.(*AutoSymbol)
-               if seen[sym.Node] {
+               n, _ := store.Aux.(GCNode)
+               if seen[n] {
                        continue
                }
 
index 54cd96beaaf41821d2c20a308dce5531a76080cd..ad69463bdd9f2dc269f91342de5e5144722f9234 100644 (file)
@@ -75,6 +75,10 @@ func (d *DummyAuto) String() string {
        return d.s
 }
 
+func (d *DummyAuto) StorageClass() StorageClass {
+       return ClassAuto
+}
+
 func (DummyFrontend) StringData(s string) interface{} {
        return nil
 }
index 9786a71c81466bc63eed48f4b33e93c524c43623..6f8d10a939fcf5f8b9b27caccc5371ac4862f119 100644 (file)
@@ -289,12 +289,13 @@ var genericOps = []opData{
 
        // Constant-like things
        {name: "InitMem"},                               // memory input to the function.
-       {name: "Arg", aux: "SymOff", symEffect: "None"}, // argument to the function.  aux=GCNode of arg, off = offset in that arg.
+       {name: "Arg", aux: "SymOff", symEffect: "Read"}, // argument to the function.  aux=GCNode of arg, off = offset in that arg.
 
-       // The address of a variable.  arg0 is the base pointer (SB or SP, depending
-       // on whether it is a global or stack variable).  The Aux field identifies the
-       // variable. It will be either an *ExternSymbol (with arg0=SB), *ArgSymbol (arg0=SP),
-       // or *AutoSymbol (arg0=SP).
+       // The address of a variable.  arg0 is the base pointer.
+       // If the variable is a global, the base pointer will be SB and
+       // the Aux field will be a *obj.LSym.
+       // If the variable is a local, the base pointer will be SP and
+       // the Aux field will be a *gc.Node.
        {name: "Addr", argLength: 1, aux: "Sym", symEffect: "Addr"}, // Address of a variable.  Arg0=SP or SB.  Aux identifies the variable.
 
        {name: "SP"},                 // stack pointer
@@ -418,7 +419,7 @@ var genericOps = []opData{
 
        {name: "VarDef", argLength: 1, aux: "Sym", typ: "Mem", symEffect: "None"}, // aux is a *gc.Node of a variable that is about to be initialized.  arg0=mem, returns mem
        {name: "VarKill", argLength: 1, aux: "Sym", symEffect: "None"},            // aux is a *gc.Node of a variable that is known to be dead.  arg0=mem, returns mem
-       {name: "VarLive", argLength: 1, aux: "Sym", symEffect: "None"},            // aux is a *gc.Node of a variable that must be kept live.  arg0=mem, returns mem
+       {name: "VarLive", argLength: 1, aux: "Sym", symEffect: "Read"},            // aux is a *gc.Node of a variable that must be kept live.  arg0=mem, returns mem
        {name: "KeepAlive", argLength: 2, typ: "Mem"},                             // arg[0] is a value that must be kept alive until this mark.  arg[1]=mem, returns mem
        {name: "RegKill"},                                                         // regalloc has determined that the value in this register is dead
 
index 37c24ee4cf44093b55c33e31ea5f79702f3d7c31..92560cdffb73a790acfdc51e8a34835a420c21c7 100644 (file)
@@ -67,7 +67,7 @@ const (
        auxFloat32              // auxInt is a float32 (encoded with math.Float64bits)
        auxFloat64              // auxInt is a float64 (encoded with math.Float64bits)
        auxString               // aux is a string
-       auxSym                  // aux is a symbol
+       auxSym                  // aux is a symbol (a *gc.Node for locals or an *obj.LSym for globals)
        auxSymOff               // aux is a symbol, auxInt is an offset
        auxSymValAndOff         // aux is a symbol, auxInt is a ValAndOff
        auxTyp                  // aux is a type
index 4493759ae93a821b9abaca6eecb270f70ca30f98..c99733e50039a98974e73245bf43dc8dd6f950c6 100644 (file)
@@ -22524,7 +22524,7 @@ var opcodeTable = [...]opInfo{
                name:      "Arg",
                auxType:   auxSymOff,
                argLen:    0,
-               symEffect: SymNone,
+               symEffect: SymRead,
                generic:   true,
        },
        {
@@ -22950,7 +22950,7 @@ var opcodeTable = [...]opInfo{
                name:      "VarLive",
                auxType:   auxSym,
                argLen:    1,
-               symEffect: SymNone,
+               symEffect: SymRead,
                generic:   true,
        },
        {
index 2002a1ab590dc17511ed022f888ce4d6b65e2932..b214f92bb95c6fa9ad6fd60293da41ba990eca29 100644 (file)
@@ -276,18 +276,6 @@ search:
        return true
 }
 
-// isArg returns whether s is an arg symbol
-func isArg(s interface{}) bool {
-       _, ok := s.(*ArgSymbol)
-       return ok
-}
-
-// isAuto returns whether s is an auto symbol
-func isAuto(s interface{}) bool {
-       _, ok := s.(*AutoSymbol)
-       return ok
-}
-
 // isSameSym returns whether sym is the same as the given named symbol
 func isSameSym(sym interface{}, name string) bool {
        s, ok := sym.(fmt.Stringer)
@@ -412,11 +400,11 @@ func uaddOvf(a, b int64) bool {
 // 'sym' is the symbol for the itab
 func devirt(v *Value, sym interface{}, offset int64) *obj.LSym {
        f := v.Block.Func
-       ext, ok := sym.(*ExternSymbol)
+       n, ok := sym.(*obj.LSym)
        if !ok {
                return nil
        }
-       lsym := f.fe.DerefItab(ext.Sym, offset)
+       lsym := f.fe.DerefItab(n, offset)
        if f.pass.debug > 0 {
                if lsym != nil {
                        f.Warnl(v.Pos, "de-virtualizing call")
index 73cb6a1b345bc9b2dd1f0b32b463b6509b81224d..fa6dcd4cd435ea932dd41d871edae2af19634937 100644 (file)
@@ -6,7 +6,6 @@ package ssa
 
 import (
        "cmd/compile/internal/types"
-       "cmd/internal/obj"
        "cmd/internal/src"
        "fmt"
        "math"
@@ -264,38 +263,6 @@ func (v *Value) isGenericIntConst() bool {
        return v != nil && (v.Op == OpConst64 || v.Op == OpConst32 || v.Op == OpConst16 || v.Op == OpConst8)
 }
 
-// ExternSymbol is an aux value that encodes a variable's
-// constant offset from the static base pointer.
-type ExternSymbol struct {
-       Sym *obj.LSym
-       // Note: the offset for an external symbol is not
-       // calculated until link time.
-}
-
-// ArgSymbol is an aux value that encodes an argument or result
-// variable's constant offset from FP (FP = SP + framesize).
-type ArgSymbol struct {
-       Node GCNode // A *gc.Node referring to the argument/result variable.
-}
-
-// AutoSymbol is an aux value that encodes a local variable's
-// constant offset from SP.
-type AutoSymbol struct {
-       Node GCNode // A *gc.Node referring to a local (auto) variable.
-}
-
-func (s *ExternSymbol) String() string {
-       return s.Sym.String()
-}
-
-func (s *ArgSymbol) String() string {
-       return s.Node.String()
-}
-
-func (s *AutoSymbol) String() string {
-       return s.Node.String()
-}
-
 // Reg returns the register assigned to v, in cmd/internal/obj/$ARCH numbering.
 func (v *Value) Reg() int16 {
        reg := v.Block.Func.RegAlloc[v.ID]
index cf22724a869ce9a58c7636c1ad9e5fe31da8747a..032a905abd271caa3ed00ceb86b0487b701c4178 100644 (file)
@@ -94,7 +94,7 @@ func writebarrier(f *Func) {
                        if sp == nil {
                                sp = f.Entry.NewValue0(initpos, OpSP, f.Config.Types.Uintptr)
                        }
-                       wbsym := &ExternSymbol{Sym: f.fe.Syslook("writeBarrier")}
+                       wbsym := f.fe.Syslook("writeBarrier")
                        wbaddr = f.Entry.NewValue1A(initpos, OpAddr, f.Config.Types.UInt32Ptr, wbsym, sb)
                        writebarrierptr = f.fe.Syslook("writebarrierptr")
                        typedmemmove = f.fe.Syslook("typedmemmove")
@@ -182,7 +182,7 @@ func writebarrier(f *Func) {
                        pos := w.Pos
 
                        var fn *obj.LSym
-                       var typ *ExternSymbol
+                       var typ *obj.LSym
                        var val *Value
                        switch w.Op {
                        case OpStoreWB:
@@ -191,10 +191,10 @@ func writebarrier(f *Func) {
                        case OpMoveWB:
                                fn = typedmemmove
                                val = w.Args[1]
-                               typ = &ExternSymbol{Sym: w.Aux.(*types.Type).Symbol()}
+                               typ = w.Aux.(*types.Type).Symbol()
                        case OpZeroWB:
                                fn = typedmemclr
-                               typ = &ExternSymbol{Sym: w.Aux.(*types.Type).Symbol()}
+                               typ = w.Aux.(*types.Type).Symbol()
                        case OpVarDef, OpVarLive, OpVarKill:
                        }
 
@@ -274,7 +274,7 @@ func writebarrier(f *Func) {
 
 // wbcall emits write barrier runtime call in b, returns memory.
 // if valIsVolatile, it moves val into temp space before making the call.
-func wbcall(pos src.XPos, b *Block, fn *obj.LSym, typ *ExternSymbol, ptr, val, mem, sp, sb *Value, valIsVolatile bool) *Value {
+func wbcall(pos src.XPos, b *Block, fn, typ *obj.LSym, ptr, val, mem, sp, sb *Value, valIsVolatile bool) *Value {
        config := b.Func.Config
 
        var tmp GCNode
@@ -284,9 +284,8 @@ func wbcall(pos src.XPos, b *Block, fn *obj.LSym, typ *ExternSymbol, ptr, val, m
                // value we're trying to move.
                t := val.Type.ElemType()
                tmp = b.Func.fe.Auto(val.Pos, t)
-               aux := &AutoSymbol{Node: tmp}
                mem = b.NewValue1A(pos, OpVarDef, types.TypeMem, tmp, mem)
-               tmpaddr := b.NewValue1A(pos, OpAddr, t.PtrTo(), aux, sp)
+               tmpaddr := b.NewValue1A(pos, OpAddr, t.PtrTo(), tmp, sp)
                siz := t.Size()
                mem = b.NewValue3I(pos, OpMove, types.TypeMem, siz, tmpaddr, val, mem)
                mem.Aux = t