cmd/internal/gc: manual goto removal + grind to move var decls
Also change gc.Naddr to return the Addr instead of filling it in.
Change-Id: I98a86705d23bee49626a12a042a4d51cabe290ea
Reviewed-on: https://go-review.googlesource.com/6601
Reviewed-by: Rob Pike <r@golang.org>
diff --git a/src/cmd/internal/gc/walk.go b/src/cmd/internal/gc/walk.go
index ed46809..0992c18 100644
--- a/src/cmd/internal/gc/walk.go
+++ b/src/cmd/internal/gc/walk.go
@@ -3235,9 +3235,6 @@
// Checking src[lb:hb:cb] or src[lb:hb].
// if chk0 || chk1 || chk2 { panicslice() }
- var chk0 *Node // cap(src) < cb
- var chk1 *Node // cb < hb for src[lb:hb:cb]; cap(src) < hb for src[lb:hb]
- var chk2 *Node // hb < lb
// All comparisons are unsigned to avoid testing < 0.
bt := Types[Simtype[TUINT]]
@@ -3254,6 +3251,7 @@
bound = cheapexpr(conv(bound, bt), init)
+ var chk0 *Node // cap(src) < cb
if cb != nil {
cb = cheapexpr(conv(cb, bt), init)
if bounded == 0 {
@@ -3264,6 +3262,7 @@
Fatal("slice3 with cb == N") // rejected by parser
}
+ var chk1 *Node // cb < hb for src[lb:hb:cb]; cap(src) < hb for src[lb:hb]
if hb != nil {
hb = cheapexpr(conv(hb, bt), init)
if bounded == 0 {
@@ -3285,6 +3284,7 @@
hb = cheapexpr(conv(hb, bt), init)
}
+ var chk2 *Node // hb < lb
if lb != nil {
lb = cheapexpr(conv(lb, bt), init)
if bounded == 0 {
@@ -3432,14 +3432,6 @@
r = n.Left
}
- var call *Node
- var a *Node
- var cmpl *Node
- var cmpr *Node
- var andor int
- var expr *Node
- var needsize int
- var t *Type
if l != nil {
x := temp(r.Type)
ok := temp(Types[TBOOL])
@@ -3464,12 +3456,13 @@
r = Nod(OOROR, Nod(ONOT, ok, nil), Nod(ONE, x, r))
}
*init = list(*init, expr)
- goto ret
+ finishcompare(np, n, r, init)
+ return
}
// Must be comparison of array or struct.
// Otherwise back end handles it.
- t = n.Left.Type
+ t := n.Left.Type
switch t.Etype {
default:
@@ -3484,11 +3477,11 @@
break
}
- cmpl = n.Left
+ cmpl := n.Left
for cmpl != nil && cmpl.Op == OCONVNOP {
cmpl = cmpl.Left
}
- cmpr = n.Right
+ cmpr := n.Right
for cmpr != nil && cmpr.Op == OCONVNOP {
cmpr = cmpr.Left
}
@@ -3498,7 +3491,7 @@
}
l = temp(Ptrto(t))
- a = Nod(OAS, l, Nod(OADDR, cmpl, nil))
+ a := Nod(OAS, l, Nod(OADDR, cmpl, nil))
a.Right.Etype = 1 // addr does not escape
typecheck(&a, Etop)
*init = list(*init, a)
@@ -3509,12 +3502,12 @@
typecheck(&a, Etop)
*init = list(*init, a)
- expr = nil
- andor = OANDAND
+ andor := OANDAND
if n.Op == ONE {
andor = OOROR
}
+ var expr *Node
if t.Etype == TARRAY && t.Bound <= 4 && issimple[t.Type.Etype] {
// Four or fewer elements of a basic type.
// Unroll comparisons.
@@ -3534,8 +3527,8 @@
if expr == nil {
expr = Nodbool(n.Op == OEQ)
}
- r = expr
- goto ret
+ finishcompare(np, n, expr, init)
+ return
}
if t.Etype == TSTRUCT && countfield(t) <= 4 {
@@ -3560,12 +3553,13 @@
if expr == nil {
expr = Nodbool(n.Op == OEQ)
}
- r = expr
- goto ret
+ finishcompare(np, n, expr, init)
+ return
}
// Chose not to inline. Call equality function directly.
- call = Nod(OCALL, eqfor(t, &needsize), nil)
+ var needsize int
+ call := Nod(OCALL, eqfor(t, &needsize), nil)
call.List = list(call.List, l)
call.List = list(call.List, r)
@@ -3576,19 +3570,23 @@
if n.Op != OEQ {
r = Nod(ONOT, r, nil)
}
- goto ret
-ret:
- typecheck(&r, Erv)
- walkexpr(&r, init)
+ finishcompare(np, n, r, init)
+ return
+}
+
+func finishcompare(np **Node, n, r *Node, init **NodeList) {
+ // Using np here to avoid passing &r to typecheck.
+ *np = r
+ typecheck(np, Erv)
+ walkexpr(np, init)
+ r = *np
if r.Type != n.Type {
r = Nod(OCONVNOP, r, nil)
r.Type = n.Type
r.Typecheck = 1
+ *np = r
}
-
- *np = r
- return
}
func samecheap(a *Node, b *Node) bool {