Commit 4492811c authored by Russ Cox's avatar Russ Cox

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/6601Reviewed-by: default avatarRob Pike <r@golang.org>
parent d0b59deb
...@@ -78,7 +78,7 @@ func zerorange(p *obj.Prog, frame int64, lo int64, hi int64, r0 *uint32) *obj.Pr ...@@ -78,7 +78,7 @@ func zerorange(p *obj.Prog, frame int64, lo int64, hi int64, r0 *uint32) *obj.Pr
p.Reg = arm.REGSP p.Reg = arm.REGSP
p = appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_MEM, 0, 0) p = appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_MEM, 0, 0)
f := gc.Sysfunc("duffzero") f := gc.Sysfunc("duffzero")
gc.Naddr(f, &p.To, 1) p.To = gc.Naddr(f, 1)
gc.Afunclit(&p.To, f) gc.Afunclit(&p.To, f)
p.To.Offset = 4 * (128 - cnt/int64(gc.Widthptr)) p.To.Offset = 4 * (128 - cnt/int64(gc.Widthptr))
} else { } else {
......
...@@ -766,12 +766,14 @@ func gmove(f *gc.Node, t *gc.Node) { ...@@ -766,12 +766,14 @@ func gmove(f *gc.Node, t *gc.Node) {
// removed. // removed.
// requires register destination // requires register destination
rdst: rdst:
regalloc(&r1, t.Type, t) {
regalloc(&r1, t.Type, t)
gins(a, f, &r1) gins(a, f, &r1)
gmove(&r1, t) gmove(&r1, t)
regfree(&r1) regfree(&r1)
return return
}
// requires register intermediate // requires register intermediate
hard: hard:
...@@ -844,10 +846,10 @@ func gins(as int, f *gc.Node, t *gc.Node) *obj.Prog { ...@@ -844,10 +846,10 @@ func gins(as int, f *gc.Node, t *gc.Node) *obj.Prog {
var at obj.Addr var at obj.Addr
if f != nil { if f != nil {
gc.Naddr(f, &af, 1) af = gc.Naddr(f, 1)
} }
if t != nil { if t != nil {
gc.Naddr(t, &at, 1) at = gc.Naddr(t, 1)
} }
p := gc.Prog(as) p := gc.Prog(as)
if f != nil { if f != nil {
...@@ -868,7 +870,7 @@ func gins(as int, f *gc.Node, t *gc.Node) *obj.Prog { ...@@ -868,7 +870,7 @@ func gins(as int, f *gc.Node, t *gc.Node) *obj.Prog {
func raddr(n *gc.Node, p *obj.Prog) { func raddr(n *gc.Node, p *obj.Prog) {
var a obj.Addr var a obj.Addr
gc.Naddr(n, &a, 1) a = gc.Naddr(n, 1)
if a.Type != obj.TYPE_REG { if a.Type != obj.TYPE_REG {
if n != nil { if n != nil {
gc.Fatal("bad in raddr: %v", gc.Oconv(int(n.Op), 0)) gc.Fatal("bad in raddr: %v", gc.Oconv(int(n.Op), 0))
...@@ -1304,7 +1306,7 @@ func sudoaddable(as int, n *gc.Node, a *obj.Addr, w *int) bool { ...@@ -1304,7 +1306,7 @@ func sudoaddable(as int, n *gc.Node, a *obj.Addr, w *int) bool {
reg1 := &clean[cleani-2] reg1 := &clean[cleani-2]
reg.Op = gc.OEMPTY reg.Op = gc.OEMPTY
reg1.Op = gc.OEMPTY reg1.Op = gc.OEMPTY
gc.Naddr(n, a, 1) *a = gc.Naddr(n, 1)
return true return true
case gc.ODOT, case gc.ODOT,
...@@ -1328,7 +1330,7 @@ func sudoaddable(as int, n *gc.Node, a *obj.Addr, w *int) bool { ...@@ -1328,7 +1330,7 @@ func sudoaddable(as int, n *gc.Node, a *obj.Addr, w *int) bool {
n1.Type = n.Type n1.Type = n.Type
n1.Xoffset += oary[0] n1.Xoffset += oary[0]
gc.Naddr(&n1, a, 1) *a = gc.Naddr(&n1, 1)
return true return true
} }
...@@ -1356,7 +1358,7 @@ func sudoaddable(as int, n *gc.Node, a *obj.Addr, w *int) bool { ...@@ -1356,7 +1358,7 @@ func sudoaddable(as int, n *gc.Node, a *obj.Addr, w *int) bool {
a.Type = obj.TYPE_NONE a.Type = obj.TYPE_NONE
a.Name = obj.NAME_NONE a.Name = obj.NAME_NONE
n1.Type = n.Type n1.Type = n.Type
gc.Naddr(&n1, a, 1) *a = gc.Naddr(&n1, 1)
return true return true
case gc.OINDEX: case gc.OINDEX:
......
...@@ -1115,8 +1115,6 @@ func bgen(n *gc.Node, true_ bool, likely int, to *obj.Prog) { ...@@ -1115,8 +1115,6 @@ func bgen(n *gc.Node, true_ bool, likely int, to *obj.Prog) {
return return
} }
var nr *gc.Node
for n.Op == gc.OCONVNOP { for n.Op == gc.OCONVNOP {
n = n.Left n = n.Left
if n.Ninit != nil { if n.Ninit != nil {
...@@ -1125,6 +1123,7 @@ func bgen(n *gc.Node, true_ bool, likely int, to *obj.Prog) { ...@@ -1125,6 +1123,7 @@ func bgen(n *gc.Node, true_ bool, likely int, to *obj.Prog) {
} }
var nl *gc.Node var nl *gc.Node
var nr *gc.Node
switch n.Op { switch n.Op {
default: default:
goto def goto def
......
...@@ -503,7 +503,6 @@ func dodiv(op int, nl *gc.Node, nr *gc.Node, res *gc.Node) { ...@@ -503,7 +503,6 @@ func dodiv(op int, nl *gc.Node, nr *gc.Node, res *gc.Node) {
gmove(&n31, &n3) gmove(&n31, &n3)
} }
var p2 *obj.Prog
var n4 gc.Node var n4 gc.Node
if gc.Nacl { if gc.Nacl {
// Native Client does not relay the divide-by-zero trap // Native Client does not relay the divide-by-zero trap
...@@ -520,6 +519,7 @@ func dodiv(op int, nl *gc.Node, nr *gc.Node, res *gc.Node) { ...@@ -520,6 +519,7 @@ func dodiv(op int, nl *gc.Node, nr *gc.Node, res *gc.Node) {
gc.Patch(p1, gc.Pc) gc.Patch(p1, gc.Pc)
} }
var p2 *obj.Prog
if check != 0 { if check != 0 {
gc.Nodconst(&n4, t, -1) gc.Nodconst(&n4, t, -1)
gins(optoas(gc.OCMP, t), &n3, &n4) gins(optoas(gc.OCMP, t), &n3, &n4)
......
...@@ -314,7 +314,6 @@ func gmove(f *gc.Node, t *gc.Node) { ...@@ -314,7 +314,6 @@ func gmove(f *gc.Node, t *gc.Node) {
} }
// cannot have two memory operands // cannot have two memory operands
var r1 gc.Node
var a int var a int
if gc.Ismem(f) && gc.Ismem(t) { if gc.Ismem(f) && gc.Ismem(t) {
goto hard goto hard
...@@ -669,15 +668,19 @@ func gmove(f *gc.Node, t *gc.Node) { ...@@ -669,15 +668,19 @@ func gmove(f *gc.Node, t *gc.Node) {
// requires register destination // requires register destination
rdst: rdst:
regalloc(&r1, t.Type, t) {
var r1 gc.Node
regalloc(&r1, t.Type, t)
gins(a, f, &r1) gins(a, f, &r1)
gmove(&r1, t) gmove(&r1, t)
regfree(&r1) regfree(&r1)
return return
}
// requires register intermediate // requires register intermediate
hard: hard:
var r1 gc.Node
regalloc(&r1, cvt, t) regalloc(&r1, cvt, t)
gmove(f, &r1) gmove(f, &r1)
...@@ -744,12 +747,12 @@ func gins(as int, f *gc.Node, t *gc.Node) *obj.Prog { ...@@ -744,12 +747,12 @@ func gins(as int, f *gc.Node, t *gc.Node) *obj.Prog {
} }
var af obj.Addr var af obj.Addr
var at obj.Addr
if f != nil { if f != nil {
gc.Naddr(f, &af, 1) af = gc.Naddr(f, 1)
} }
var at obj.Addr
if t != nil { if t != nil {
gc.Naddr(t, &at, 1) at = gc.Naddr(t, 1)
} }
p := gc.Prog(as) p := gc.Prog(as)
if f != nil { if f != nil {
...@@ -1402,7 +1405,7 @@ func sudoaddable(as int, n *gc.Node, a *obj.Addr) bool { ...@@ -1402,7 +1405,7 @@ func sudoaddable(as int, n *gc.Node, a *obj.Addr) bool {
reg1 := &clean[cleani-2] reg1 := &clean[cleani-2]
reg.Op = gc.OEMPTY reg.Op = gc.OEMPTY
reg1.Op = gc.OEMPTY reg1.Op = gc.OEMPTY
gc.Naddr(n, a, 1) *a = gc.Naddr(n, 1)
return true return true
case gc.ODOT, case gc.ODOT,
...@@ -1426,7 +1429,7 @@ func sudoaddable(as int, n *gc.Node, a *obj.Addr) bool { ...@@ -1426,7 +1429,7 @@ func sudoaddable(as int, n *gc.Node, a *obj.Addr) bool {
n1.Type = n.Type n1.Type = n.Type
n1.Xoffset += oary[0] n1.Xoffset += oary[0]
gc.Naddr(&n1, a, 1) *a = gc.Naddr(&n1, 1)
return true return true
} }
...@@ -1454,7 +1457,7 @@ func sudoaddable(as int, n *gc.Node, a *obj.Addr) bool { ...@@ -1454,7 +1457,7 @@ func sudoaddable(as int, n *gc.Node, a *obj.Addr) bool {
a.Type = obj.TYPE_NONE a.Type = obj.TYPE_NONE
a.Index = obj.TYPE_NONE a.Index = obj.TYPE_NONE
fixlargeoffset(&n1) fixlargeoffset(&n1)
gc.Naddr(&n1, a, 1) *a = gc.Naddr(&n1, 1)
return true return true
case gc.OINDEX: case gc.OINDEX:
......
...@@ -825,8 +825,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int { ...@@ -825,8 +825,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
if p.As == obj.AVARDEF || p.As == obj.AVARKILL { if p.As == obj.AVARDEF || p.As == obj.AVARKILL {
return 0 return 0
} }
var info gc.ProgInfo info := proginfo(p)
info = proginfo(p)
if (info.Reguse|info.Regset)&RtoB(int(v.Reg)) != 0 { if (info.Reguse|info.Regset)&RtoB(int(v.Reg)) != 0 {
return 2 return 2
......
...@@ -1148,12 +1148,14 @@ rsrc: ...@@ -1148,12 +1148,14 @@ rsrc:
// requires register destination // requires register destination
rdst: rdst:
regalloc(&r1, t.Type, t) {
regalloc(&r1, t.Type, t)
gins(a, f, &r1) gins(a, f, &r1)
gmove(&r1, t) gmove(&r1, t)
regfree(&r1) regfree(&r1)
return return
}
// requires register intermediate // requires register intermediate
hard: hard:
...@@ -1845,10 +1847,10 @@ func gins(as int, f *gc.Node, t *gc.Node) *obj.Prog { ...@@ -1845,10 +1847,10 @@ func gins(as int, f *gc.Node, t *gc.Node) *obj.Prog {
var af obj.Addr var af obj.Addr
var at obj.Addr var at obj.Addr
if f != nil { if f != nil {
gc.Naddr(f, &af, 1) af = gc.Naddr(f, 1)
} }
if t != nil { if t != nil {
gc.Naddr(t, &at, 1) at = gc.Naddr(t, 1)
} }
p := gc.Prog(as) p := gc.Prog(as)
if f != nil { if f != nil {
......
...@@ -76,7 +76,7 @@ func zerorange(p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog { ...@@ -76,7 +76,7 @@ func zerorange(p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog {
p.Reg = ppc64.REGSP p.Reg = ppc64.REGSP
p = appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_MEM, 0, 0) p = appendpp(p, obj.ADUFFZERO, obj.TYPE_NONE, 0, 0, obj.TYPE_MEM, 0, 0)
f := gc.Sysfunc("duffzero") f := gc.Sysfunc("duffzero")
gc.Naddr(f, &p.To, 1) p.To = gc.Naddr(f, 1)
gc.Afunclit(&p.To, f) gc.Afunclit(&p.To, f)
p.To.Offset = 4 * (128 - cnt/int64(gc.Widthptr)) p.To.Offset = 4 * (128 - cnt/int64(gc.Widthptr))
} else { } else {
......
...@@ -669,12 +669,14 @@ func gmove(f *gc.Node, t *gc.Node) { ...@@ -669,12 +669,14 @@ func gmove(f *gc.Node, t *gc.Node) {
// requires register destination // requires register destination
rdst: rdst:
regalloc(&r1, t.Type, t) {
regalloc(&r1, t.Type, t)
gins(a, f, &r1) gins(a, f, &r1)
gmove(&r1, t) gmove(&r1, t)
regfree(&r1) regfree(&r1)
return return
}
// requires register intermediate // requires register intermediate
hard: hard:
...@@ -698,10 +700,10 @@ func gins(as int, f *gc.Node, t *gc.Node) *obj.Prog { ...@@ -698,10 +700,10 @@ func gins(as int, f *gc.Node, t *gc.Node) *obj.Prog {
at := obj.Addr(obj.Addr{}) at := obj.Addr(obj.Addr{})
if f != nil { if f != nil {
gc.Naddr(f, &af, 1) af = gc.Naddr(f, 1)
} }
if t != nil { if t != nil {
gc.Naddr(t, &at, 1) at = gc.Naddr(t, 1)
} }
p := (*obj.Prog)(gc.Prog(as)) p := (*obj.Prog)(gc.Prog(as))
if f != nil { if f != nil {
......
...@@ -596,7 +596,6 @@ func makepartialcall(fn *Node, t0 *Type, meth *Node) *Node { ...@@ -596,7 +596,6 @@ func makepartialcall(fn *Node, t0 *Type, meth *Node) *Node {
declare(xfunc.Nname, PFUNC) declare(xfunc.Nname, PFUNC)
// Declare and initialize variable holding receiver. // Declare and initialize variable holding receiver.
var body *NodeList
xfunc.Needctxt = true xfunc.Needctxt = true
cv := Nod(OCLOSUREVAR, nil, nil) cv := Nod(OCLOSUREVAR, nil, nil)
...@@ -613,6 +612,7 @@ func makepartialcall(fn *Node, t0 *Type, meth *Node) *Node { ...@@ -613,6 +612,7 @@ func makepartialcall(fn *Node, t0 *Type, meth *Node) *Node {
ptr.Used = 1 ptr.Used = 1
ptr.Curfn = xfunc ptr.Curfn = xfunc
xfunc.Dcl = list(xfunc.Dcl, ptr) xfunc.Dcl = list(xfunc.Dcl, ptr)
var body *NodeList
if Isptr[rcvrtype.Etype] || Isinter(rcvrtype) { if Isptr[rcvrtype.Etype] || Isinter(rcvrtype) {
ptr.Ntype = typenod(rcvrtype) ptr.Ntype = typenod(rcvrtype)
body = list(body, Nod(OAS, ptr, cv)) body = list(body, Nod(OAS, ptr, cv))
......
...@@ -313,7 +313,6 @@ func variter(vl *NodeList, t *Node, el *NodeList) *NodeList { ...@@ -313,7 +313,6 @@ func variter(vl *NodeList, t *Node, el *NodeList) *NodeList {
* new_name_list [[type] = expr_list] * new_name_list [[type] = expr_list]
*/ */
func constiter(vl *NodeList, t *Node, cl *NodeList) *NodeList { func constiter(vl *NodeList, t *Node, cl *NodeList) *NodeList {
var vv *NodeList
if cl == nil { if cl == nil {
if t != nil { if t != nil {
Yyerror("const declaration cannot have type without expression") Yyerror("const declaration cannot have type without expression")
...@@ -329,6 +328,7 @@ func constiter(vl *NodeList, t *Node, cl *NodeList) *NodeList { ...@@ -329,6 +328,7 @@ func constiter(vl *NodeList, t *Node, cl *NodeList) *NodeList {
var v *Node var v *Node
var c *Node var c *Node
var vv *NodeList
for ; vl != nil; vl = vl.Next { for ; vl != nil; vl = vl.Next {
if cl == nil { if cl == nil {
Yyerror("missing value in const declaration") Yyerror("missing value in const declaration")
......
...@@ -274,8 +274,7 @@ func markautoused(p *obj.Prog) { ...@@ -274,8 +274,7 @@ func markautoused(p *obj.Prog) {
} }
} }
func Naddr(n *Node, a *obj.Addr, canemitcode int) { func Naddr(n *Node, canemitcode int) (a obj.Addr) {
*a = obj.Addr{}
if n == nil { if n == nil {
return return
} }
...@@ -294,7 +293,8 @@ func Naddr(n *Node, a *obj.Addr, canemitcode int) { ...@@ -294,7 +293,8 @@ func Naddr(n *Node, a *obj.Addr, canemitcode int) {
switch n.Op { switch n.Op {
default: default:
Fatal("naddr: bad %v %v", Oconv(int(n.Op), 0), Ctxt.Dconv(a)) a := a // copy to let escape into Ctxt.Dconv
Fatal("naddr: bad %v %v", Oconv(int(n.Op), 0), Ctxt.Dconv(&a))
case OREGISTER: case OREGISTER:
a.Type = obj.TYPE_REG a.Type = obj.TYPE_REG
...@@ -338,7 +338,7 @@ func Naddr(n *Node, a *obj.Addr, canemitcode int) { ...@@ -338,7 +338,7 @@ func Naddr(n *Node, a *obj.Addr, canemitcode int) {
a.Offset = n.Xoffset a.Offset = n.Xoffset
case OCFUNC: case OCFUNC:
Naddr(n.Left, a, canemitcode) a = Naddr(n.Left, canemitcode)
a.Sym = Linksym(n.Left.Sym) a.Sym = Linksym(n.Left.Sym)
case ONAME: case ONAME:
...@@ -408,7 +408,7 @@ func Naddr(n *Node, a *obj.Addr, canemitcode int) { ...@@ -408,7 +408,7 @@ func Naddr(n *Node, a *obj.Addr, canemitcode int) {
a.Offset = Mpgetfix(n.Val.U.Xval) a.Offset = Mpgetfix(n.Val.U.Xval)
case CTSTR: case CTSTR:
datagostring(n.Val.U.Sval, a) datagostring(n.Val.U.Sval, &a)
case CTBOOL: case CTBOOL:
a.Sym = nil a.Sym = nil
...@@ -422,19 +422,20 @@ func Naddr(n *Node, a *obj.Addr, canemitcode int) { ...@@ -422,19 +422,20 @@ func Naddr(n *Node, a *obj.Addr, canemitcode int) {
} }
case OADDR: case OADDR:
Naddr(n.Left, a, canemitcode) a = Naddr(n.Left, canemitcode)
a.Etype = uint8(Tptr) a.Etype = uint8(Tptr)
if Thearch.Thechar != '5' && Thearch.Thechar != '9' { // TODO(rsc): Do this even for arm, ppc64. if Thearch.Thechar != '5' && Thearch.Thechar != '9' { // TODO(rsc): Do this even for arm, ppc64.
a.Width = int64(Widthptr) a.Width = int64(Widthptr)
} }
if a.Type != obj.TYPE_MEM { if a.Type != obj.TYPE_MEM {
Fatal("naddr: OADDR %v (from %v)", Ctxt.Dconv(a), Oconv(int(n.Left.Op), 0)) a := a // copy to let escape into Ctxt.Dconv
Fatal("naddr: OADDR %v (from %v)", Ctxt.Dconv(&a), Oconv(int(n.Left.Op), 0))
} }
a.Type = obj.TYPE_ADDR a.Type = obj.TYPE_ADDR
// itable of interface value // itable of interface value
case OITAB: case OITAB:
Naddr(n.Left, a, canemitcode) a = Naddr(n.Left, canemitcode)
if a.Type == obj.TYPE_CONST && a.Offset == 0 { if a.Type == obj.TYPE_CONST && a.Offset == 0 {
break // itab(nil) break // itab(nil)
...@@ -444,7 +445,7 @@ func Naddr(n *Node, a *obj.Addr, canemitcode int) { ...@@ -444,7 +445,7 @@ func Naddr(n *Node, a *obj.Addr, canemitcode int) {
// pointer in a string or slice // pointer in a string or slice
case OSPTR: case OSPTR:
Naddr(n.Left, a, canemitcode) a = Naddr(n.Left, canemitcode)
if a.Type == obj.TYPE_CONST && a.Offset == 0 { if a.Type == obj.TYPE_CONST && a.Offset == 0 {
break // ptr(nil) break // ptr(nil)
...@@ -455,7 +456,7 @@ func Naddr(n *Node, a *obj.Addr, canemitcode int) { ...@@ -455,7 +456,7 @@ func Naddr(n *Node, a *obj.Addr, canemitcode int) {
// len of string or slice // len of string or slice
case OLEN: case OLEN:
Naddr(n.Left, a, canemitcode) a = Naddr(n.Left, canemitcode)
if a.Type == obj.TYPE_CONST && a.Offset == 0 { if a.Type == obj.TYPE_CONST && a.Offset == 0 {
break // len(nil) break // len(nil)
...@@ -471,7 +472,7 @@ func Naddr(n *Node, a *obj.Addr, canemitcode int) { ...@@ -471,7 +472,7 @@ func Naddr(n *Node, a *obj.Addr, canemitcode int) {
// cap of string or slice // cap of string or slice
case OCAP: case OCAP:
Naddr(n.Left, a, canemitcode) a = Naddr(n.Left, canemitcode)
if a.Type == obj.TYPE_CONST && a.Offset == 0 { if a.Type == obj.TYPE_CONST && a.Offset == 0 {
break // cap(nil) break // cap(nil)
...@@ -485,6 +486,7 @@ func Naddr(n *Node, a *obj.Addr, canemitcode int) { ...@@ -485,6 +486,7 @@ func Naddr(n *Node, a *obj.Addr, canemitcode int) {
a.Width = int64(Widthint) a.Width = int64(Widthint)
} }
} }
return
} }
func newplist() *obj.Plist { func newplist() *obj.Plist {
......
...@@ -556,13 +556,11 @@ func isfunny(n *Node) bool { ...@@ -556,13 +556,11 @@ func isfunny(n *Node) bool {
// initialized, because any use of a variable must come after its // initialized, because any use of a variable must come after its
// initialization. // initialization.
func progeffects(prog *obj.Prog, vars []*Node, uevar *Bvec, varkill *Bvec, avarinit *Bvec) { func progeffects(prog *obj.Prog, vars []*Node, uevar *Bvec, varkill *Bvec, avarinit *Bvec) {
var info ProgInfo
bvresetall(uevar) bvresetall(uevar)
bvresetall(varkill) bvresetall(varkill)
bvresetall(avarinit) bvresetall(avarinit)
info = Thearch.Proginfo(prog) info := Thearch.Proginfo(prog)
if prog.As == obj.ARET { if prog.As == obj.ARET {
// Return instructions implicitly read all the arguments. For // Return instructions implicitly read all the arguments. For
// the sake of correctness, out arguments must be read. For the // the sake of correctness, out arguments must be read. For the
...@@ -1087,8 +1085,8 @@ func newpcdataprog(prog *obj.Prog, index int32) *obj.Prog { ...@@ -1087,8 +1085,8 @@ func newpcdataprog(prog *obj.Prog, index int32) *obj.Prog {
Nodconst(&to, Types[TINT32], int64(index)) Nodconst(&to, Types[TINT32], int64(index))
pcdata := unlinkedprog(obj.APCDATA) pcdata := unlinkedprog(obj.APCDATA)
pcdata.Lineno = prog.Lineno pcdata.Lineno = prog.Lineno
Naddr(&from, &pcdata.From, 0) pcdata.From = Naddr(&from, 0)
Naddr(&to, &pcdata.To, 0) pcdata.To = Naddr(&to, 0)
return pcdata return pcdata
} }
...@@ -1296,7 +1294,6 @@ func livenessepilogue(lv *Liveness) { ...@@ -1296,7 +1294,6 @@ func livenessepilogue(lv *Liveness) {
any := bvalloc(nvars) any := bvalloc(nvars)
all := bvalloc(nvars) all := bvalloc(nvars)
ambig := bvalloc(localswords() * obj.BitsPerPointer) ambig := bvalloc(localswords() * obj.BitsPerPointer)
var msg []string
nmsg := int32(0) nmsg := int32(0)
startmsg := int32(0) startmsg := int32(0)
...@@ -1392,6 +1389,7 @@ func livenessepilogue(lv *Liveness) { ...@@ -1392,6 +1389,7 @@ func livenessepilogue(lv *Liveness) {
var fmt_ string var fmt_ string
var next *obj.Prog var next *obj.Prog
var numlive int32 var numlive int32
var msg []string
for i := int32(0); i < int32(len(lv.cfg)); i++ { for i := int32(0); i < int32(len(lv.cfg)); i++ {
bb = lv.cfg[i] bb = lv.cfg[i]
......
...@@ -136,7 +136,6 @@ out: ...@@ -136,7 +136,6 @@ out:
func walkrange(n *Node) { func walkrange(n *Node) {
t := n.Type t := n.Type
var init *NodeList
a := n.Right a := n.Right
lno := int(setlineno(a)) lno := int(setlineno(a))
...@@ -154,9 +153,8 @@ func walkrange(n *Node) { ...@@ -154,9 +153,8 @@ func walkrange(n *Node) {
// to avoid erroneous processing by racewalk. // to avoid erroneous processing by racewalk.
n.List = nil n.List = nil
var hv2 *Node
var body *NodeList var body *NodeList
var init *NodeList
switch t.Etype { switch t.Etype {
default: default:
Fatal("walkrange") Fatal("walkrange")
...@@ -366,6 +364,7 @@ func walkrange(n *Node) { ...@@ -366,6 +364,7 @@ func walkrange(n *Node) {
init = list(init, Nod(OAS, hv1, nil)) init = list(init, Nod(OAS, hv1, nil))
var a *Node var a *Node
var hv2 *Node
if v2 == nil { if v2 == nil {
a = Nod(OAS, hv1, mkcall("stringiter", Types[TINT], nil, ha, hv1)) a = Nod(OAS, hv1, mkcall("stringiter", Types[TINT], nil, ha, hv1))
} else { } else {
......
This diff is collapsed.
...@@ -3235,9 +3235,6 @@ func sliceany(n *Node, init **NodeList) *Node { ...@@ -3235,9 +3235,6 @@ func sliceany(n *Node, init **NodeList) *Node {
// Checking src[lb:hb:cb] or src[lb:hb]. // Checking src[lb:hb:cb] or src[lb:hb].
// if chk0 || chk1 || chk2 { panicslice() } // 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. // All comparisons are unsigned to avoid testing < 0.
bt := Types[Simtype[TUINT]] bt := Types[Simtype[TUINT]]
...@@ -3254,6 +3251,7 @@ func sliceany(n *Node, init **NodeList) *Node { ...@@ -3254,6 +3251,7 @@ func sliceany(n *Node, init **NodeList) *Node {
bound = cheapexpr(conv(bound, bt), init) bound = cheapexpr(conv(bound, bt), init)
var chk0 *Node // cap(src) < cb
if cb != nil { if cb != nil {
cb = cheapexpr(conv(cb, bt), init) cb = cheapexpr(conv(cb, bt), init)
if bounded == 0 { if bounded == 0 {
...@@ -3264,6 +3262,7 @@ func sliceany(n *Node, init **NodeList) *Node { ...@@ -3264,6 +3262,7 @@ func sliceany(n *Node, init **NodeList) *Node {
Fatal("slice3 with cb == N") // rejected by parser 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 { if hb != nil {
hb = cheapexpr(conv(hb, bt), init) hb = cheapexpr(conv(hb, bt), init)
if bounded == 0 { if bounded == 0 {
...@@ -3285,6 +3284,7 @@ func sliceany(n *Node, init **NodeList) *Node { ...@@ -3285,6 +3284,7 @@ func sliceany(n *Node, init **NodeList) *Node {
hb = cheapexpr(conv(hb, bt), init) hb = cheapexpr(conv(hb, bt), init)
} }
var chk2 *Node // hb < lb
if lb != nil { if lb != nil {
lb = cheapexpr(conv(lb, bt), init) lb = cheapexpr(conv(lb, bt), init)
if bounded == 0 { if bounded == 0 {
...@@ -3432,14 +3432,6 @@ func walkcompare(np **Node, init **NodeList) { ...@@ -3432,14 +3432,6 @@ func walkcompare(np **Node, init **NodeList) {
r = n.Left 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 { if l != nil {
x := temp(r.Type) x := temp(r.Type)
ok := temp(Types[TBOOL]) ok := temp(Types[TBOOL])
...@@ -3464,12 +3456,13 @@ func walkcompare(np **Node, init **NodeList) { ...@@ -3464,12 +3456,13 @@ func walkcompare(np **Node, init **NodeList) {
r = Nod(OOROR, Nod(ONOT, ok, nil), Nod(ONE, x, r)) r = Nod(OOROR, Nod(ONOT, ok, nil), Nod(ONE, x, r))
} }
*init = list(*init, expr) *init = list(*init, expr)
goto ret finishcompare(np, n, r, init)
return
} }
// Must be comparison of array or struct. // Must be comparison of array or struct.
// Otherwise back end handles it. // Otherwise back end handles it.
t = n.Left.Type t := n.Left.Type
switch t.Etype { switch t.Etype {
default: default:
...@@ -3484,11 +3477,11 @@ func walkcompare(np **Node, init **NodeList) { ...@@ -3484,11 +3477,11 @@ func walkcompare(np **Node, init **NodeList) {
break break
} }
cmpl = n.Left cmpl := n.Left
for cmpl != nil && cmpl.Op == OCONVNOP { for cmpl != nil && cmpl.Op == OCONVNOP {
cmpl = cmpl.Left cmpl = cmpl.Left
} }
cmpr = n.Right cmpr := n.Right
for cmpr != nil && cmpr.Op == OCONVNOP { for cmpr != nil && cmpr.Op == OCONVNOP {
cmpr = cmpr.Left cmpr = cmpr.Left
} }
...@@ -3498,7 +3491,7 @@ func walkcompare(np **Node, init **NodeList) { ...@@ -3498,7 +3491,7 @@ func walkcompare(np **Node, init **NodeList) {
} }
l = temp(Ptrto(t)) 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 a.Right.Etype = 1 // addr does not escape
typecheck(&a, Etop) typecheck(&a, Etop)
*init = list(*init, a) *init = list(*init, a)
...@@ -3509,12 +3502,12 @@ func walkcompare(np **Node, init **NodeList) { ...@@ -3509,12 +3502,12 @@ func walkcompare(np **Node, init **NodeList) {
typecheck(&a, Etop) typecheck(&a, Etop)
*init = list(*init, a) *init = list(*init, a)
expr = nil andor := OANDAND
andor = OANDAND
if n.Op == ONE { if n.Op == ONE {
andor = OOROR andor = OOROR
} }
var expr *Node
if t.Etype == TARRAY && t.Bound <= 4 && issimple[t.Type.Etype] { if t.Etype == TARRAY && t.Bound <= 4 && issimple[t.Type.Etype] {
// Four or fewer elements of a basic type. // Four or fewer elements of a basic type.
// Unroll comparisons. // Unroll comparisons.
...@@ -3534,8 +3527,8 @@ func walkcompare(np **Node, init **NodeList) { ...@@ -3534,8 +3527,8 @@ func walkcompare(np **Node, init **NodeList) {
if expr == nil { if expr == nil {
expr = Nodbool(n.Op == OEQ) expr = Nodbool(n.Op == OEQ)
} }
r = expr finishcompare(np, n, expr, init)
goto ret return
} }
if t.Etype == TSTRUCT && countfield(t) <= 4 { if t.Etype == TSTRUCT && countfield(t) <= 4 {
...@@ -3560,12 +3553,13 @@ func walkcompare(np **Node, init **NodeList) { ...@@ -3560,12 +3553,13 @@ func walkcompare(np **Node, init **NodeList) {
if expr == nil { if expr == nil {
expr = Nodbool(n.Op == OEQ) expr = Nodbool(n.Op == OEQ)
} }
r = expr finishcompare(np, n, expr, init)
goto ret return
} }
// Chose not to inline. Call equality function directly. // 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, l)
call.List = list(call.List, r) call.List = list(call.List, r)
...@@ -3576,19 +3570,23 @@ func walkcompare(np **Node, init **NodeList) { ...@@ -3576,19 +3570,23 @@ func walkcompare(np **Node, init **NodeList) {
if n.Op != OEQ { if n.Op != OEQ {
r = Nod(ONOT, r, nil) r = Nod(ONOT, r, nil)
} }
goto ret
ret: finishcompare(np, n, r, init)
typecheck(&r, Erv) return
walkexpr(&r, init) }
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 { if r.Type != n.Type {
r = Nod(OCONVNOP, r, nil) r = Nod(OCONVNOP, r, nil)
r.Type = n.Type r.Type = n.Type
r.Typecheck = 1 r.Typecheck = 1
*np = r
} }
*np = r
return
} }
func samecheap(a *Node, b *Node) bool { func samecheap(a *Node, b *Node) bool {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment