]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: eliminate PPARAMREF
authorRuss Cox <rsc@golang.org>
Wed, 25 May 2016 14:29:50 +0000 (10:29 -0400)
committerRuss Cox <rsc@golang.org>
Fri, 27 May 2016 05:16:16 +0000 (05:16 +0000)
As in the elimination of PHEAP|PPARAM in CL 23393,
this is something the front end can trivially take care of
and then not bother the back ends with.
It also eliminates some suspect (and only lightly exercised)
code paths in the back ends.

I don't have a smoking gun for this one but it seems
more clearly correct.

Change-Id: I3b3f5e669b3b81d091ff1e2fb13226a6f14c69d5
Reviewed-on: https://go-review.googlesource.com/23431
Reviewed-by: Keith Randall <khr@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>

16 files changed:
src/cmd/compile/internal/arm/gsubr.go
src/cmd/compile/internal/gc/cgen.go
src/cmd/compile/internal/gc/closure.go
src/cmd/compile/internal/gc/cplx.go
src/cmd/compile/internal/gc/dcl.go
src/cmd/compile/internal/gc/esc.go
src/cmd/compile/internal/gc/fmt.go
src/cmd/compile/internal/gc/gen.go
src/cmd/compile/internal/gc/go.go
src/cmd/compile/internal/gc/racewalk.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/syntax.go
src/cmd/compile/internal/gc/walk.go
src/cmd/compile/internal/x86/gsubr.go

index 9ac999167e1dbb75eb76ccde5ed0b90d6935cb28..b5d7bc05c405e4d37302e35b38b088feae5cb291 100644 (file)
@@ -86,17 +86,8 @@ func split64(n *gc.Node, lo *gc.Node, hi *gc.Node) {
 
                        n = &n1
 
-               case gc.ONAME:
-                       if n.Class == gc.PPARAMREF {
-                               var n1 gc.Node
-                               gc.Cgen(n.Name.Heapaddr, &n1)
-                               sclean[nsclean-1] = n1
-                               n = &n1
-                       }
-
+               case gc.ONAME, gc.OINDREG:
                        // nothing
-               case gc.OINDREG:
-                       break
                }
 
                *lo = *n
index c01a8fbda7efc87a62fde60180bf33544c7325fb..dbefcc7a0bb52db0a95e884345c6351ba2940087 100644 (file)
@@ -518,8 +518,7 @@ func cgen_wb(n, res *Node, wb bool) {
        case ODOT,
                ODOTPTR,
                OINDEX,
-               OIND,
-               ONAME: // PPARAMREF var
+               OIND:
                var n1 Node
                Igen(n, &n1, res)
 
@@ -1545,6 +1544,7 @@ func Agen(n *Node, res *Node) {
 
        switch n.Op {
        default:
+               Dump("bad agen", n)
                Fatalf("agen: unknown op %v", Nconv(n, FmtShort|FmtSign))
 
        case OCALLMETH:
@@ -1571,24 +1571,6 @@ func Agen(n *Node, res *Node) {
                Thearch.Gmove(&n1, res)
                Regfree(&n1)
 
-       case ONAME:
-               // should only get here with names in this func.
-               if n.Name.Funcdepth > 0 && n.Name.Funcdepth != Funcdepth {
-                       Dump("bad agen", n)
-                       Fatalf("agen: bad ONAME funcdepth %d != %d", n.Name.Funcdepth, Funcdepth)
-               }
-
-               // should only get here for heap vars or paramref
-               if n.Class != PPARAMREF {
-                       Dump("bad agen", n)
-                       Fatalf("agen: bad ONAME class %#x", n.Class)
-               }
-
-               Cgen(n.Name.Heapaddr, res)
-               if n.Xoffset != 0 {
-                       addOffset(res, n.Xoffset)
-               }
-
        case OIND:
                Cgen(nl, res)
                if !nl.NonNil {
@@ -1646,8 +1628,9 @@ func Igen(n *Node, a *Node, res *Node) {
 
        switch n.Op {
        case ONAME:
-               if n.Class == PPARAMREF {
-                       break
+               if n.Class == PAUTOHEAP {
+                       Dump("igen", n)
+                       Fatalf("bad name")
                }
                *a = *n
                return
@@ -1702,11 +1685,11 @@ func Igen(n *Node, a *Node, res *Node) {
                a.Type = n.Type
                return
 
-               // Index of fixed-size array by constant can
-       // put the offset in the addressing.
-       // Could do the same for slice except that we need
-       // to use the real index for the bounds checking.
        case OINDEX:
+               // Index of fixed-size array by constant can
+               // put the offset in the addressing.
+               // Could do the same for slice except that we need
+               // to use the real index for the bounds checking.
                if n.Left.Type.IsArray() || (n.Left.Type.IsPtr() && n.Left.Left.Type.IsArray()) {
                        if Isconst(n.Right, CTINT) {
                                // Compute &a.
index 04fa250985851880068e897976c2f0bb6503a7db..238280f68adb75840fc75ef80c6a30bb93646f8f 100644 (file)
@@ -313,7 +313,7 @@ func transformclosure(xfunc *Node) {
                        } else {
                                // If v of type T is captured by reference,
                                // we introduce function param &v *T
-                               // and v remains PPARAMREF with &v heapaddr
+                               // and v remains PAUTOHEAP with &v heapaddr
                                // (accesses will implicitly deref &v).
                                addr := newname(Lookupf("&%s", v.Sym.Name))
                                addr.Type = Ptrto(v.Type)
index a5c04b2be5232555bc37332e1dc011fd9798babc..96a1dfb3c26abf20016d4e87d19acdb9e94cb1f4 100644 (file)
@@ -405,7 +405,6 @@ func Complexgen(n *Node, res *Node) {
                ODOTPTR,
                OINDEX,
                OIND,
-               ONAME, // PPARAMREF var
                OCALLFUNC,
                OCALLMETH,
                OCALLINTER:
index ba5b6b689cab014d6de8da4d9f311565a739ffaf..3b1822ffd97e3367152d16beff90678440dc92fc 100644 (file)
@@ -396,7 +396,8 @@ func oldname(s *Sym) *Node {
                        c := Nod(ONAME, nil, nil)
 
                        c.Sym = s
-                       c.Class = PPARAMREF
+                       c.Class = PAUTOHEAP
+                       c.setIsClosureParam(true)
                        c.Isddd = n.Isddd
                        c.Name.Defn = n
                        c.Addable = false
index 2991f6d2256aea87b87c011b21816e9baf318756..538c4842d90e81553d26fd249d3d78231a79e6c9 100644 (file)
@@ -1817,9 +1817,9 @@ func escwalkBody(e *EscState, level Level, dst *Node, src *Node, step *EscStep,
                        }
                }
 
-               // Treat a PPARAMREF closure variable as equivalent to the
+               // Treat a captured closure variable as equivalent to the
                // original variable.
-               if src.Class == PPARAMREF {
+               if src.isClosureParam() {
                        if leaks && Debug['m'] != 0 {
                                Warnl(src.Lineno, "leaking closure reference %v", Nconv(src, FmtShort))
                                step.describe(src)
index 3c4053e51f7e730a50645d9c54f5c79fbab8a1f6..02d93e2e470e3ab2b645568bef91725ef26c591f 100644 (file)
@@ -221,7 +221,6 @@ var classnames = []string{
        "PAUTOHEAP",
        "PPARAM",
        "PPARAMOUT",
-       "PPARAMREF",
        "PFUNC",
 }
 
index 2db253184ca61df866923a81b8475ffcbaf4ec44..ec4a3c8142af72de33ef09a41a217826f945361d 100644 (file)
@@ -43,9 +43,8 @@ func addrescapes(n *Node) {
                        break
                }
 
-               // A PPARAMREF is a closure reference.
-               // Mark the thing it refers to as escaping.
-               if n.Class == PPARAMREF {
+               // If a closure reference escapes, mark the outer variable as escaping.
+               if n.isClosureParam() {
                        addrescapes(n.Name.Defn)
                        break
                }
@@ -347,7 +346,7 @@ func cgen_discard(nr *Node) {
 
        switch nr.Op {
        case ONAME:
-               if nr.Class != PAUTOHEAP && nr.Class != PEXTERN && nr.Class != PFUNC && nr.Class != PPARAMREF {
+               if nr.Class != PAUTOHEAP && nr.Class != PEXTERN && nr.Class != PFUNC {
                        gused(nr)
                }
 
index 600b00dae2a56eab9e7ab42879a33b6d4a2e132b..fedc785aeedb9f407bb89fdbe5c51feaa32c2a49 100644 (file)
@@ -94,7 +94,6 @@ const (
        PAUTOHEAP       // local variable or parameter moved to heap
        PPARAM          // input arguments
        PPARAMOUT       // output results
-       PPARAMREF       // closure variable reference
        PFUNC           // global function
 
        PDISCARD // discard during parse of duplicate import
index 3b705c3f0c9642d5488ef20403d83c156ed2d6fd..4a658b197665e9fc0a474c31fdf216e7121d788c 100644 (file)
@@ -495,7 +495,7 @@ func callinstr(np **Node, init *Nodes, wr int, skip int) bool {
        // e.g. if we've got a local variable/method receiver
        // that has got a pointer inside. Whether it points to
        // the heap or not is impossible to know at compile time
-       if class == PAUTOHEAP || class == PPARAMREF || class == PEXTERN || b.Op == OINDEX || b.Op == ODOTPTR || b.Op == OIND {
+       if class == PAUTOHEAP || class == PEXTERN || b.Op == OINDEX || b.Op == ODOTPTR || b.Op == OIND {
                hascalls := 0
                foreach(n, hascallspred, &hascalls)
                if hascalls != 0 {
index 5d741a55db9d471cf64fcef221457a41fdefe566..4469d71f1c56ccc4beb606348e984eb6cd6a19b0 100644 (file)
@@ -516,7 +516,7 @@ func isliteral(n *Node) bool {
 }
 
 func (n *Node) isSimpleName() bool {
-       return n.Op == ONAME && n.Addable && n.Class != PAUTOHEAP && n.Class != PPARAMREF
+       return n.Op == ONAME && n.Addable && n.Class != PAUTOHEAP
 }
 
 func litas(l *Node, r *Node, init *Nodes) {
index 8d06f1e3ed50caf4134fc1a76f87fa2a8b7c80b0..a107f91ef3e70a33b68a0476a07a5bad047c7657 100644 (file)
@@ -2723,8 +2723,6 @@ func (s *state) addr(n *Node, bounded bool) *ssa.Value {
                        // that cse works on their addresses
                        aux := s.lookupSymbol(n, &ssa.ArgSymbol{Typ: n.Type, Node: n})
                        return s.newValue1A(ssa.OpAddr, t, aux, s.sp)
-               case PPARAMREF:
-                       return s.expr(n.Name.Heapaddr)
                default:
                        s.Unimplementedf("variable address class %v not implemented", classnames[n.Class])
                        return nil
@@ -2803,8 +2801,7 @@ func (s *state) canSSA(n *Node) bool {
                Fatalf("canSSA of PAUTOHEAP %v", n)
        }
        switch n.Class {
-       case PEXTERN, PPARAMREF:
-               // TODO: maybe treat PPARAMREF with an Arg-like op to read from closure?
+       case PEXTERN:
                return false
        case PPARAMOUT:
                if hasdefer {
index c78575a8c28da4ddca885a3288b691ad79c4a845..c2abff7b63487b7dc2c56147018a2fcdf437594d 100644 (file)
@@ -1231,7 +1231,7 @@ func ullmancalc(n *Node) {
        switch n.Op {
        case OREGISTER, OLITERAL, ONAME:
                ul = 1
-               if n.Class == PPARAMREF || n.Class == PAUTOHEAP {
+               if n.Class == PAUTOHEAP {
                        ul++
                }
                goto out
index c5c7b17f5768cb4ec97e57d35ed8847050372a59..89c96cb2d8b9ababe93ea0ff7473ebd791ee76da 100644 (file)
@@ -78,6 +78,7 @@ type Node struct {
 const (
        hasBreak = 1 << iota
        notLiveAtEnd
+       isClosureParam
 )
 
 func (n *Node) HasBreak() bool {
@@ -100,6 +101,16 @@ func (n *Node) SetNotLiveAtEnd(b bool) {
                n.flags &^= notLiveAtEnd
        }
 }
+func (n *Node) isClosureParam() bool {
+       return n.flags&isClosureParam != 0
+}
+func (n *Node) setIsClosureParam(b bool) {
+       if b {
+               n.flags |= isClosureParam
+       } else {
+               n.flags &^= isClosureParam
+       }
+}
 
 // Val returns the Val for the node.
 func (n *Node) Val() Val {
@@ -174,9 +185,9 @@ type Param struct {
        // ONAME PPARAM
        Field *Field // TFIELD in arg struct
 
-       // ONAME closure param with PPARAMREF
-       Outer   *Node // outer PPARAMREF in nested closure
-       Closure *Node // ONAME/PAUTOHEAP <-> ONAME/PPARAMREF
+       // ONAME closure linkage
+       Outer   *Node
+       Closure *Node
 }
 
 // Func holds Node fields used only with function-like nodes.
index 566decee45b68d9a3adc6b6744c16d683ecf55df..30fb170e500cf2983edfb383fc0f1942c99593c1 100644 (file)
@@ -647,9 +647,7 @@ opswitch:
                n.Addable = true
 
        case ONAME:
-               if n.Class != PPARAMREF {
-                       n.Addable = true
-               }
+               n.Addable = true
 
        case OCALLINTER:
                usemethod(n)
@@ -2536,7 +2534,7 @@ func vmatch1(l *Node, r *Node) bool {
        switch l.Op {
        case ONAME:
                switch l.Class {
-               case PPARAM, PPARAMREF, PAUTO:
+               case PPARAM, PAUTO:
                        break
 
                        // assignment to non-stack variable
index d91bafc4ea539fff748b5947643a4d75f3489750..6406326b60e0501cf13f06cfd61b8b726b8ce9c0 100644 (file)
@@ -724,17 +724,8 @@ func split64(n *gc.Node, lo *gc.Node, hi *gc.Node) {
 
                        n = &n1
 
-               case gc.ONAME:
-                       if n.Class == gc.PPARAMREF {
-                               var n1 gc.Node
-                               gc.Cgen(n.Name.Heapaddr, &n1)
-                               sclean[nsclean-1] = n1
-                               n = &n1
-                       }
-
+               case gc.ONAME, gc.OINDREG:
                        // nothing
-               case gc.OINDREG:
-                       break
                }
 
                *lo = *n