Skip to content

Commit

Permalink
cmd/compile/internal/gc: represent labels as bare Syms
Browse files Browse the repository at this point in the history
Avoids allocating an ONAME for OLABEL, OGOTO, and named OBREAK and
OCONTINUE nodes.

Passes toolstash-check.

Change-Id: I359142cd48e8987b5bf29ac100752f8c497261c1
Reviewed-on: https://go-review.googlesource.com/c/145200
Run-TryBot: Matthew Dempsky <[email protected]>
TryBot-Result: Gobot Gobot <[email protected]>
Reviewed-by: Robert Griesemer <[email protected]>
  • Loading branch information
mdempsky committed Oct 27, 2018
1 parent c68e3bc commit 2dda040
Show file tree
Hide file tree
Showing 11 changed files with 47 additions and 39 deletions.
17 changes: 9 additions & 8 deletions src/cmd/compile/internal/gc/esc.go
Original file line number Diff line number Diff line change
Expand Up @@ -621,23 +621,23 @@ func (e *EscState) escloopdepth(n *Node) {

switch n.Op {
case OLABEL:
if n.Left == nil || n.Left.Sym == nil {
if n.Sym == nil {
Fatalf("esc:label without label: %+v", n)
}

// Walk will complain about this label being already defined, but that's not until
// after escape analysis. in the future, maybe pull label & goto analysis out of walk and put before esc
n.Left.Sym.Label = asTypesNode(&nonlooping)
n.Sym.Label = asTypesNode(&nonlooping)

case OGOTO:
if n.Left == nil || n.Left.Sym == nil {
if n.Sym == nil {
Fatalf("esc:goto without label: %+v", n)
}

// If we come past one that's uninitialized, this must be a (harmless) forward jump
// but if it's set to nonlooping the label must have preceded this goto.
if asNode(n.Left.Sym.Label) == &nonlooping {
n.Left.Sym.Label = asTypesNode(&looping)
if asNode(n.Sym.Label) == &nonlooping {
n.Sym.Label = asTypesNode(&looping)
}
}

Expand Down Expand Up @@ -851,18 +851,19 @@ opSwitch:
}

case OLABEL:
if asNode(n.Left.Sym.Label) == &nonlooping {
switch asNode(n.Sym.Label) {
case &nonlooping:
if Debug['m'] > 2 {
fmt.Printf("%v:%v non-looping label\n", linestr(lineno), n)
}
} else if asNode(n.Left.Sym.Label) == &looping {
case &looping:
if Debug['m'] > 2 {
fmt.Printf("%v: %v looping label\n", linestr(lineno), n)
}
e.loopdepth++
}

n.Left.Sym.Label = nil
n.Sym.Label = nil

case ORANGE:
if n.List.Len() >= 2 {
Expand Down
6 changes: 3 additions & 3 deletions src/cmd/compile/internal/gc/fmt.go
Original file line number Diff line number Diff line change
Expand Up @@ -1045,8 +1045,8 @@ func (n *Node) stmtfmt(s fmt.State, mode fmtMode) {
mode.Fprintf(s, ": %v", n.Nbody)

case OBREAK, OCONTINUE, OGOTO, OFALL:
if n.Left != nil {
mode.Fprintf(s, "%#v %v", n.Op, n.Left)
if n.Sym != nil {
mode.Fprintf(s, "%#v %v", n.Op, n.Sym)
} else {
mode.Fprintf(s, "%#v", n.Op)
}
Expand All @@ -1055,7 +1055,7 @@ func (n *Node) stmtfmt(s fmt.State, mode fmtMode) {
break

case OLABEL:
mode.Fprintf(s, "%v: ", n.Left)
mode.Fprintf(s, "%v: ", n.Sym)
}

if extrablock {
Expand Down
3 changes: 2 additions & 1 deletion src/cmd/compile/internal/gc/iexport.go
Original file line number Diff line number Diff line change
Expand Up @@ -1102,7 +1102,8 @@ func (w *exportWriter) stmt(n *Node) {
case OGOTO, OLABEL:
w.op(op)
w.pos(n.Pos)
w.expr(n.Left)
w.op(ONAME) // TODO(mdempsky): Remove toolstash hack.
w.string(n.Sym.Name)

default:
Fatalf("exporter: CANNOT EXPORT: %v\nPlease notify gri@\n", n.Op)
Expand Down
7 changes: 6 additions & 1 deletion src/cmd/compile/internal/gc/iimport.go
Original file line number Diff line number Diff line change
Expand Up @@ -1043,7 +1043,12 @@ func (r *importReader) node() *Node {
// unreachable - not emitted by exporter

case OGOTO, OLABEL:
return nodl(r.pos(), op, newname(r.expr().Sym), nil)
n := nodl(r.pos(), op, nil, nil)
if op := r.op(); op != ONAME { // TODO(mdempsky): Remove toolstash check.
Fatalf("got %v, want ONAME", op)
}
n.Sym = lookup(r.string())
return n

case OEND:
return nil
Expand Down
10 changes: 5 additions & 5 deletions src/cmd/compile/internal/gc/inl.go
Original file line number Diff line number Diff line change
Expand Up @@ -1072,7 +1072,7 @@ func mkinlcall(n, fn *Node, maxCost int32) *Node {

body := subst.list(asNodes(fn.Func.Inl.Body))

lab := nod(OLABEL, retlabel, nil)
lab := nodSym(OLABEL, nil, retlabel)
body = append(body, lab)

typecheckslice(body, Etop)
Expand Down Expand Up @@ -1158,7 +1158,7 @@ func argvar(t *types.Type, i int) *Node {
// function call.
type inlsubst struct {
// Target of the goto substituted in place of a return.
retlabel *Node
retlabel *types.Sym

// Temporary result variables.
retvars []*Node
Expand Down Expand Up @@ -1218,7 +1218,7 @@ func (subst *inlsubst) node(n *Node) *Node {

// dump("Return before substitution", n);
case ORETURN:
m := nod(OGOTO, subst.retlabel, nil)
m := nodSym(OGOTO, nil, subst.retlabel)
m.Ninit.Set(subst.list(n.Ninit))

if len(subst.retvars) != 0 && n.List.Len() != 0 {
Expand All @@ -1245,8 +1245,8 @@ func (subst *inlsubst) node(n *Node) *Node {
m := n.copy()
m.Pos = subst.updatedPos(m.Pos)
m.Ninit.Set(nil)
p := fmt.Sprintf("%s·%d", n.Left.Sym.Name, inlgen)
m.Left = newname(lookup(p))
p := fmt.Sprintf("%s·%d", n.Sym.Name, inlgen)
m.Sym = lookup(p)

return m
}
Expand Down
4 changes: 2 additions & 2 deletions src/cmd/compile/internal/gc/noder.go
Original file line number Diff line number Diff line change
Expand Up @@ -941,7 +941,7 @@ func (p *noder) stmtFall(stmt syntax.Stmt, fallOK bool) *Node {
}
n := p.nod(stmt, op, nil, nil)
if stmt.Label != nil {
n.Left = p.newname(stmt.Label)
n.Sym = p.name(stmt.Label)
}
return n
case *syntax.CallStmt:
Expand Down Expand Up @@ -1205,7 +1205,7 @@ func (p *noder) commClauses(clauses []*syntax.CommClause, rbrace syntax.Pos) []*
}

func (p *noder) labeledStmt(label *syntax.LabeledStmt, fallOK bool) *Node {
lhs := p.nod(label, OLABEL, p.newname(label.Label), nil)
lhs := p.nodSym(label, OLABEL, nil, p.name(label.Label))

var ls *Node
if label.Stmt != nil { // TODO(mdempsky): Should always be present.
Expand Down
8 changes: 4 additions & 4 deletions src/cmd/compile/internal/gc/ssa.go
Original file line number Diff line number Diff line change
Expand Up @@ -845,7 +845,7 @@ func (s *state) stmt(n *Node) {
}

case OLABEL:
sym := n.Left.Sym
sym := n.Sym
lab := s.label(sym)

// Associate label with its control flow node, if any
Expand All @@ -867,7 +867,7 @@ func (s *state) stmt(n *Node) {
s.startBlock(lab.target)

case OGOTO:
sym := n.Left.Sym
sym := n.Sym

lab := s.label(sym)
if lab.target == nil {
Expand Down Expand Up @@ -1033,7 +1033,7 @@ func (s *state) stmt(n *Node) {

case OCONTINUE, OBREAK:
var to *ssa.Block
if n.Left == nil {
if n.Sym == nil {
// plain break/continue
switch n.Op {
case OCONTINUE:
Expand All @@ -1043,7 +1043,7 @@ func (s *state) stmt(n *Node) {
}
} else {
// labeled break/continue; look up the target
sym := n.Left.Sym
sym := n.Sym
lab := s.label(sym)
switch n.Op {
case OCONTINUE:
Expand Down
4 changes: 2 additions & 2 deletions src/cmd/compile/internal/gc/subr.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ func lookupN(prefix string, n int) *types.Sym {
// to help with debugging.
// It should begin with "." to avoid conflicts with
// user labels.
func autolabel(prefix string) *Node {
func autolabel(prefix string) *types.Sym {
if prefix[0] != '.' {
Fatalf("autolabel prefix must start with '.', have %q", prefix)
}
Expand All @@ -244,7 +244,7 @@ func autolabel(prefix string) *Node {
}
n := fn.Func.Label
fn.Func.Label++
return newname(lookupN(prefix, int(n)))
return lookupN(prefix, int(n))
}

func restrictlookup(name string, pkg *types.Pkg) *types.Sym {
Expand Down
9 changes: 5 additions & 4 deletions src/cmd/compile/internal/gc/swt.go
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,8 @@ func casebody(sw *Node, typeswvar *Node) {
n.Op = OCASE
needvar := n.List.Len() != 1 || n.List.First().Op == OLITERAL

jmp := nod(OGOTO, autolabel(".s"), nil)
lbl := autolabel(".s")
jmp := nodSym(OGOTO, nil, lbl)
switch n.List.Len() {
case 0:
// default
Expand Down Expand Up @@ -486,7 +487,7 @@ func casebody(sw *Node, typeswvar *Node) {
}
}

stat = append(stat, nod(OLABEL, jmp.Left, nil))
stat = append(stat, nodSym(OLABEL, nil, lbl))
if typeswvar != nil && needvar && n.Rlist.Len() != 0 {
l := []*Node{
nod(ODCL, n.Rlist.First(), nil),
Expand Down Expand Up @@ -778,10 +779,10 @@ func (s *typeSwitch) walk(sw *Node) {
} else {
// Jump to default case.
lbl := autolabel(".s")
i.Nbody.Set1(nod(OGOTO, lbl, nil))
i.Nbody.Set1(nodSym(OGOTO, nil, lbl))
// Wrap default case with label.
blk := nod(OBLOCK, nil, nil)
blk.List.Set2(nod(OLABEL, lbl, nil), def)
blk.List.Set2(nodSym(OLABEL, nil, lbl), def)
def = blk
}
i.Left = typecheck(i.Left, Erv)
Expand Down
8 changes: 4 additions & 4 deletions src/cmd/compile/internal/gc/syntax.go
Original file line number Diff line number Diff line change
Expand Up @@ -698,10 +698,10 @@ const (

// statements
OBLOCK // { List } (block of code)
OBREAK // break
OBREAK // break [Sym]
OCASE // case Left or List[0]..List[1]: Nbody (select case after processing; Left==nil and List==nil means default)
OXCASE // case List: Nbody (select case before processing; List==nil means default)
OCONTINUE // continue
OCONTINUE // continue [Sym]
ODEFER // defer Left (Left must be call)
OEMPTY // no-op (empty statement)
OFALL // fallthrough
Expand All @@ -716,9 +716,9 @@ const (
// }
// OFORUNTIL is created by walk. There's no way to write this in Go code.
OFORUNTIL
OGOTO // goto Left
OGOTO // goto Sym
OIF // if Ninit; Left { Nbody } else { Rlist }
OLABEL // Left:
OLABEL // Sym:
OPROC // go Left (Left must be call)
ORANGE // for List = range Right { Nbody }
ORETURN // return List
Expand Down
10 changes: 5 additions & 5 deletions src/cmd/compile/internal/gc/typecheck.go
Original file line number Diff line number Diff line change
Expand Up @@ -1984,7 +1984,7 @@ func typecheck1(n *Node, top int) *Node {
case OLABEL:
ok |= Etop
decldepth++
if n.Left.Sym.IsBlank() {
if n.Sym.IsBlank() {
// Empty identifier is valid but useless.
// Eliminate now to simplify life later.
// See issues 7538, 11589, 11593.
Expand Down Expand Up @@ -3831,12 +3831,12 @@ func markbreak(n *Node, implicit *Node) {

switch n.Op {
case OBREAK:
if n.Left == nil {
if n.Sym == nil {
if implicit != nil {
implicit.SetHasBreak(true)
}
} else {
lab := asNode(n.Left.Sym.Label)
lab := asNode(n.Sym.Label)
if lab != nil {
lab.SetHasBreak(true)
}
Expand Down Expand Up @@ -3864,9 +3864,9 @@ func markbreaklist(l Nodes, implicit *Node) {
if n.Op == OLABEL && i+1 < len(s) && n.Name.Defn == s[i+1] {
switch n.Name.Defn.Op {
case OFOR, OFORUNTIL, OSWITCH, OTYPESW, OSELECT, ORANGE:
n.Left.Sym.Label = asTypesNode(n.Name.Defn)
n.Sym.Label = asTypesNode(n.Name.Defn)
markbreak(n.Name.Defn, n.Name.Defn)
n.Left.Sym.Label = nil
n.Sym.Label = nil
i++
continue
}
Expand Down

0 comments on commit 2dda040

Please sign in to comment.