mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile: construct typename in walk instead of SSA conversion
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>
This commit is contained in:
parent
579297e1e1
commit
a0d6d3855f
5 changed files with 38 additions and 20 deletions
|
|
@ -2156,9 +2156,7 @@ func (s *state) append(n *Node, inplace bool) *ssa.Value {
|
||||||
|
|
||||||
// Call growslice
|
// Call growslice
|
||||||
s.startBlock(grow)
|
s.startBlock(grow)
|
||||||
sym := s.lookupSymbol(n, &ssa.ExternSymbol{Typ: Types[TUINTPTR], Sym: Linksym(typenamesym(n.Type.Elem()))})
|
taddr := s.expr(n.Left)
|
||||||
taddr := s.newValue1A(ssa.OpAddr, Types[TUINTPTR], sym, s.sb)
|
|
||||||
|
|
||||||
r := s.rtcall(growslice, true, []*Type{pt, Types[TINT], Types[TINT]}, taddr, p, l, c, nl)
|
r := s.rtcall(growslice, true, []*Type{pt, Types[TINT], Types[TINT]}, taddr, p, l, c, nl)
|
||||||
|
|
||||||
if inplace {
|
if inplace {
|
||||||
|
|
@ -3970,8 +3968,7 @@ func (s *state) floatToUint(cvttab *f2uCvtTab, n *Node, x *ssa.Value, ft, tt *Ty
|
||||||
// If commaok is false, resok will be nil.
|
// 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 *Node, commaok bool) (res, resok *ssa.Value) {
|
||||||
iface := s.expr(n.Left) // input interface
|
iface := s.expr(n.Left) // input interface
|
||||||
lineno = n.Pos // for typename call
|
target := s.expr(n.Right) // target type
|
||||||
target := s.expr(typename(n.Type)) // target type
|
|
||||||
byteptr := s.f.Config.Types.BytePtr
|
byteptr := s.f.Config.Types.BytePtr
|
||||||
|
|
||||||
if n.Type.IsInterface() {
|
if n.Type.IsInterface() {
|
||||||
|
|
@ -4105,8 +4102,7 @@ func (s *state) dottype(n *Node, commaok bool) (res, resok *ssa.Value) {
|
||||||
if !commaok {
|
if !commaok {
|
||||||
// on failure, panic by calling panicdottype
|
// on failure, panic by calling panicdottype
|
||||||
s.startBlock(bFail)
|
s.startBlock(bFail)
|
||||||
sym := s.lookupSymbol(n, &ssa.ExternSymbol{Typ: byteptr, Sym: Linksym(typenamesym(n.Left.Type))})
|
taddr := s.expr(n.Right.Right)
|
||||||
taddr := s.newValue1A(ssa.OpAddr, byteptr, sym, s.sb)
|
|
||||||
if n.Left.Type.IsEmptyInterface() {
|
if n.Left.Type.IsEmptyInterface() {
|
||||||
s.rtcall(panicdottypeE, false, nil, itab, target, taddr)
|
s.rtcall(panicdottypeE, false, nil, itab, target, taddr)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -1980,6 +1980,15 @@ func liststmt(l []*Node) *Node {
|
||||||
return n
|
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 {
|
func ngotype(n *Node) *Sym {
|
||||||
if n.Type != nil {
|
if n.Type != nil {
|
||||||
return typenamesym(n.Type)
|
return typenamesym(n.Type)
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,9 @@
|
||||||
|
|
||||||
package gc
|
package gc
|
||||||
|
|
||||||
import "sort"
|
import (
|
||||||
|
"sort"
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// expression switch
|
// expression switch
|
||||||
|
|
@ -825,16 +827,16 @@ func (s *typeSwitch) walk(sw *Node) {
|
||||||
// case body if the variable is of type t.
|
// case body if the variable is of type t.
|
||||||
func (s *typeSwitch) typeone(t *Node) *Node {
|
func (s *typeSwitch) typeone(t *Node) *Node {
|
||||||
var name *Node
|
var name *Node
|
||||||
var init []*Node
|
var init Nodes
|
||||||
if t.Rlist.Len() == 0 {
|
if t.Rlist.Len() == 0 {
|
||||||
name = nblank
|
name = nblank
|
||||||
nblank = typecheck(nblank, Erv|Easgn)
|
nblank = typecheck(nblank, Erv|Easgn)
|
||||||
} else {
|
} else {
|
||||||
name = t.Rlist.First()
|
name = t.Rlist.First()
|
||||||
init = []*Node{nod(ODCL, name, nil)}
|
init.Append(nod(ODCL, name, nil))
|
||||||
a := nod(OAS, name, nil)
|
a := nod(OAS, name, nil)
|
||||||
a = typecheck(a, Etop)
|
a = typecheck(a, Etop)
|
||||||
init = append(init, a)
|
init.Append(a)
|
||||||
}
|
}
|
||||||
|
|
||||||
a := nod(OAS2, nil, nil)
|
a := nod(OAS2, nil, nil)
|
||||||
|
|
@ -843,13 +845,15 @@ func (s *typeSwitch) typeone(t *Node) *Node {
|
||||||
b.Type = t.Left.Type // interface.(type)
|
b.Type = t.Left.Type // interface.(type)
|
||||||
a.Rlist.Set1(b)
|
a.Rlist.Set1(b)
|
||||||
a = typecheck(a, Etop)
|
a = typecheck(a, Etop)
|
||||||
init = append(init, a)
|
a = walkexpr(a, &init)
|
||||||
|
init.Append(a)
|
||||||
|
|
||||||
c := nod(OIF, nil, nil)
|
c := nod(OIF, nil, nil)
|
||||||
c.Left = s.okname
|
c.Left = s.okname
|
||||||
c.Nbody.Set1(t.Right) // if ok { goto l }
|
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.
|
// walkCases generates an AST implementing the cases in cc.
|
||||||
|
|
|
||||||
|
|
@ -382,7 +382,7 @@ const (
|
||||||
OADDSTR // +{List} (string addition, list elements are strings)
|
OADDSTR // +{List} (string addition, list elements are strings)
|
||||||
OADDR // &Left
|
OADDR // &Left
|
||||||
OANDAND // Left && Right
|
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)
|
OARRAYBYTESTR // Type(Left) (Type is string, Left is a []byte)
|
||||||
OARRAYBYTESTRTMP // Type(Left) (Type is string, Left is a []byte, ephemeral)
|
OARRAYBYTESTRTMP // Type(Left) (Type is string, Left is a []byte, ephemeral)
|
||||||
OARRAYRUNESTR // Type(Left) (Type is string, Left is a []rune)
|
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)
|
ODOTMETH // Left.Sym (Left is non-interface, Right is method name)
|
||||||
ODOTINTER // Left.Sym (Left is 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)
|
OXDOT // Left.Sym (before rewrite to one of the preceding)
|
||||||
ODOTTYPE // Left.Right or Left.Type (.Right during parsing, .Type once resolved)
|
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)
|
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
|
OEQ // Left == Right
|
||||||
ONE // Left != Right
|
ONE // Left != Right
|
||||||
OLT // Left < Right
|
OLT // Left < Right
|
||||||
|
|
|
||||||
|
|
@ -504,7 +504,7 @@ opswitch:
|
||||||
// TODO(mdempsky): Just return n; see discussion on CL 38655.
|
// TODO(mdempsky): Just return n; see discussion on CL 38655.
|
||||||
|
|
||||||
case ONOT, OMINUS, OPLUS, OCOM, OREAL, OIMAG, ODOTMETH, ODOTINTER,
|
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)
|
n.Left = walkexpr(n.Left, init)
|
||||||
|
|
||||||
case OEFACE, OAND, OSUB, OMUL, OLT, OLE, OGE, OGT, OADD, OOR, OXOR:
|
case OEFACE, OAND, OSUB, OMUL, OLT, OLE, OGE, OGT, OADD, OOR, OXOR:
|
||||||
|
|
@ -515,6 +515,14 @@ opswitch:
|
||||||
usefield(n)
|
usefield(n)
|
||||||
n.Left = walkexpr(n.Left, init)
|
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:
|
case ODOTPTR:
|
||||||
usefield(n)
|
usefield(n)
|
||||||
if n.Op == ODOTPTR && n.Left.Type.Elem().Width == 0 {
|
if n.Op == ODOTPTR && n.Left.Type.Elem().Width == 0 {
|
||||||
|
|
@ -706,6 +714,8 @@ opswitch:
|
||||||
if r.Op == OAPPEND {
|
if r.Op == OAPPEND {
|
||||||
// Left in place for back end.
|
// Left in place for back end.
|
||||||
// Do not add a new write barrier.
|
// Do not add a new write barrier.
|
||||||
|
// Set up address of type for back end.
|
||||||
|
r.Left = typename(r.Type.Elem())
|
||||||
break opswitch
|
break opswitch
|
||||||
}
|
}
|
||||||
// Otherwise, lowered for race detector.
|
// Otherwise, lowered for race detector.
|
||||||
|
|
@ -839,8 +849,7 @@ opswitch:
|
||||||
|
|
||||||
case OAS2DOTTYPE:
|
case OAS2DOTTYPE:
|
||||||
walkexprlistsafe(n.List.Slice(), init)
|
walkexprlistsafe(n.List.Slice(), init)
|
||||||
e := n.Rlist.First() // i.(T)
|
n.Rlist.SetFirst(walkexpr(n.Rlist.First(), init))
|
||||||
e.Left = walkexpr(e.Left, init)
|
|
||||||
|
|
||||||
case OCONVIFACE:
|
case OCONVIFACE:
|
||||||
n.Left = walkexpr(n.Left, init)
|
n.Left = walkexpr(n.Left, init)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue