]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: construct typename in walk instead of SSA conversion
authorJosh Bleecher Snyder <josharian@gmail.com>
Mon, 27 Mar 2017 21:48:24 +0000 (14:48 -0700)
committerJosh Bleecher Snyder <josharian@gmail.com>
Mon, 27 Mar 2017 23:10:39 +0000 (23:10 +0000)
This eliminates references to lineno and
other globals from ssa conversion.

Passes toolstash-check.

Updates #15756

Change-Id: I9792074fab0036b42f454b79139d0b27db913fb5
Reviewed-on: https://go-review.googlesource.com/38721
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
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/syntax.go
src/cmd/compile/internal/gc/walk.go

index 23aa436543fa0b21c9faa8e4adffbcdefe44267a..608f6cce8d89abc8b3710559832fbec48b4feb2e 100644 (file)
@@ -2156,9 +2156,7 @@ func (s *state) append(n *Node, inplace bool) *ssa.Value {
 
        // Call growslice
        s.startBlock(grow)
-       sym := s.lookupSymbol(n, &ssa.ExternSymbol{Typ: Types[TUINTPTR], Sym: Linksym(typenamesym(n.Type.Elem()))})
-       taddr := s.newValue1A(ssa.OpAddr, Types[TUINTPTR], sym, s.sb)
-
+       taddr := s.expr(n.Left)
        r := s.rtcall(growslice, true, []*Type{pt, Types[TINT], Types[TINT]}, taddr, p, l, c, nl)
 
        if inplace {
@@ -3969,9 +3967,8 @@ func (s *state) floatToUint(cvttab *f2uCvtTab, n *Node, x *ssa.Value, ft, tt *Ty
 // 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) {
-       iface := s.expr(n.Left)            // input interface
-       lineno = n.Pos                     // for typename call
-       target := s.expr(typename(n.Type)) // target type
+       iface := s.expr(n.Left)   // input interface
+       target := s.expr(n.Right) // target type
        byteptr := s.f.Config.Types.BytePtr
 
        if n.Type.IsInterface() {
@@ -4105,8 +4102,7 @@ func (s *state) dottype(n *Node, commaok bool) (res, resok *ssa.Value) {
        if !commaok {
                // on failure, panic by calling panicdottype
                s.startBlock(bFail)
-               sym := s.lookupSymbol(n, &ssa.ExternSymbol{Typ: byteptr, Sym: Linksym(typenamesym(n.Left.Type))})
-               taddr := s.newValue1A(ssa.OpAddr, byteptr, sym, s.sb)
+               taddr := s.expr(n.Right.Right)
                if n.Left.Type.IsEmptyInterface() {
                        s.rtcall(panicdottypeE, false, nil, itab, target, taddr)
                } else {
index f98076ac05b1df9fcb437796bf8c6acf52cd39d2..13e85640c9cb1b650e5fa349765910f809b1c871 100644 (file)
@@ -1980,6 +1980,15 @@ func liststmt(l []*Node) *Node {
        return n
 }
 
+func (l Nodes) asblock() *Node {
+       n := nod(OBLOCK, nil, nil)
+       n.List = l
+       if l.Len() != 0 {
+               n.Pos = l.First().Pos
+       }
+       return n
+}
+
 func ngotype(n *Node) *Sym {
        if n.Type != nil {
                return typenamesym(n.Type)
index 679c14454581fc388c70131fc48ee3df0f09f34c..d9f196e85503cb27c0f6289f2981bf3937cac1c9 100644 (file)
@@ -4,7 +4,9 @@
 
 package gc
 
-import "sort"
+import (
+       "sort"
+)
 
 const (
        // expression switch
@@ -825,16 +827,16 @@ func (s *typeSwitch) walk(sw *Node) {
 // case body if the variable is of type t.
 func (s *typeSwitch) typeone(t *Node) *Node {
        var name *Node
-       var init []*Node
+       var init Nodes
        if t.Rlist.Len() == 0 {
                name = nblank
                nblank = typecheck(nblank, Erv|Easgn)
        } else {
                name = t.Rlist.First()
-               init = []*Node{nod(ODCL, name, nil)}
+               init.Append(nod(ODCL, name, nil))
                a := nod(OAS, name, nil)
                a = typecheck(a, Etop)
-               init = append(init, a)
+               init.Append(a)
        }
 
        a := nod(OAS2, nil, nil)
@@ -843,13 +845,15 @@ func (s *typeSwitch) typeone(t *Node) *Node {
        b.Type = t.Left.Type // interface.(type)
        a.Rlist.Set1(b)
        a = typecheck(a, Etop)
-       init = append(init, a)
+       a = walkexpr(a, &init)
+       init.Append(a)
 
        c := nod(OIF, nil, nil)
        c.Left = s.okname
        c.Nbody.Set1(t.Right) // if ok { goto l }
 
-       return liststmt(append(init, c))
+       init.Append(c)
+       return init.asblock()
 }
 
 // walkCases generates an AST implementing the cases in cc.
index b1cf6385301d98f03b52cb55d1864b7257de25f7..3bc3baee8a4b08bfe03d0d12659c257e7c07da81 100644 (file)
@@ -382,7 +382,7 @@ const (
        OADDSTR          // +{List} (string addition, list elements are strings)
        OADDR            // &Left
        OANDAND          // Left && Right
-       OAPPEND          // append(List)
+       OAPPEND          // append(List); after walk, Left may contain elem type descriptor
        OARRAYBYTESTR    // Type(Left) (Type is string, Left is a []byte)
        OARRAYBYTESTRTMP // Type(Left) (Type is string, Left is a []byte, ephemeral)
        OARRAYRUNESTR    // Type(Left) (Type is string, Left is a []rune)
@@ -430,8 +430,8 @@ const (
        ODOTMETH   // Left.Sym (Left is non-interface, Right is method name)
        ODOTINTER  // Left.Sym (Left is interface, Right is method name)
        OXDOT      // Left.Sym (before rewrite to one of the preceding)
-       ODOTTYPE   // Left.Right or Left.Type (.Right during parsing, .Type once resolved)
-       ODOTTYPE2  // Left.Right or Left.Type (.Right during parsing, .Type once resolved; on rhs of OAS2DOTTYPE)
+       ODOTTYPE   // Left.Right or Left.Type (.Right during parsing, .Type once resolved); after walk, .Right contains address of interface type descriptor and .Right.Right contains address of concrete type descriptor
+       ODOTTYPE2  // Left.Right or Left.Type (.Right during parsing, .Type once resolved; on rhs of OAS2DOTTYPE); after walk, .Right contains address of interface type descriptor
        OEQ        // Left == Right
        ONE        // Left != Right
        OLT        // Left < Right
index c7e35097b8f8ab22cdbeb254db5df233836e0975..92ecaed8ecf28cdcfc3cc8d32ed6639361b6799a 100644 (file)
@@ -504,7 +504,7 @@ opswitch:
                // TODO(mdempsky): Just return n; see discussion on CL 38655.
 
        case ONOT, OMINUS, OPLUS, OCOM, OREAL, OIMAG, ODOTMETH, ODOTINTER,
-               OIND, OSPTR, OITAB, OIDATA, ODOTTYPE, ODOTTYPE2, OADDR:
+               OIND, OSPTR, OITAB, OIDATA, OADDR:
                n.Left = walkexpr(n.Left, init)
 
        case OEFACE, OAND, OSUB, OMUL, OLT, OLE, OGE, OGT, OADD, OOR, OXOR:
@@ -515,6 +515,14 @@ opswitch:
                usefield(n)
                n.Left = walkexpr(n.Left, init)
 
+       case ODOTTYPE, ODOTTYPE2:
+               n.Left = walkexpr(n.Left, init)
+               // Set up interface type addresses for back end.
+               n.Right = typename(n.Type)
+               if n.Op == ODOTTYPE {
+                       n.Right.Right = typename(n.Left.Type)
+               }
+
        case ODOTPTR:
                usefield(n)
                if n.Op == ODOTPTR && n.Left.Type.Elem().Width == 0 {
@@ -706,6 +714,8 @@ opswitch:
                        if r.Op == OAPPEND {
                                // Left in place for back end.
                                // Do not add a new write barrier.
+                               // Set up address of type for back end.
+                               r.Left = typename(r.Type.Elem())
                                break opswitch
                        }
                        // Otherwise, lowered for race detector.
@@ -839,8 +849,7 @@ opswitch:
 
        case OAS2DOTTYPE:
                walkexprlistsafe(n.List.Slice(), init)
-               e := n.Rlist.First() // i.(T)
-               e.Left = walkexpr(e.Left, init)
+               n.Rlist.SetFirst(walkexpr(n.Rlist.First(), init))
 
        case OCONVIFACE:
                n.Left = walkexpr(n.Left, init)