1
0
mirror of https://github.com/golang/go synced 2024-11-19 06:54:39 -07:00

cmd/internal/gc: change Naddr to take a *Addr to fill in

This allows gins to let Naddr fill in p.From and p.To directly,
avoiding the zeroing and copying of a temporary.

Change-Id: I96d120afe266e68f94d5e82b00886bf6bd458f85
Reviewed-on: https://go-review.googlesource.com/7742
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
This commit is contained in:
Russ Cox 2015-03-16 15:27:19 -04:00
parent a5e18416fc
commit 8b9a3d4752
10 changed files with 50 additions and 106 deletions

View File

@ -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")
p.To = gc.Naddr(f) gc.Naddr(&p.To, f)
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 {

View File

@ -842,22 +842,11 @@ func gins(as int, f *gc.Node, t *gc.Node) *obj.Prog {
// constnode.vconst = v; // constnode.vconst = v;
// idx.reg = nod.reg; // idx.reg = nod.reg;
// regfree(&nod); // regfree(&nod);
var af obj.Addr
var at obj.Addr
if f != nil {
af = gc.Naddr(f)
}
if t != nil {
at = gc.Naddr(t)
}
p := gc.Prog(as) p := gc.Prog(as)
if f != nil { gc.Naddr(&p.From, f)
p.From = af gc.Naddr(&p.To, t)
}
if t != nil {
p.To = at
}
if gc.Debug['g'] != 0 { if gc.Debug['g'] != 0 {
fmt.Printf("%v\n", p) fmt.Printf("%v\n", p)
} }
@ -869,8 +858,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(&a, n)
a = gc.Naddr(n)
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))
@ -1306,7 +1294,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
*a = gc.Naddr(n) gc.Naddr(a, n)
return true return true
case gc.ODOT, case gc.ODOT,
@ -1330,7 +1318,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]
*a = gc.Naddr(&n1) gc.Naddr(a, &n1)
return true return true
} }
@ -1358,7 +1346,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
*a = gc.Naddr(&n1) gc.Naddr(a, &n1)
return true return true
case gc.OINDEX: case gc.OINDEX:

View File

@ -746,21 +746,10 @@ func gins(as int, f *gc.Node, t *gc.Node) *obj.Prog {
} }
} }
var af obj.Addr
if f != nil {
af = gc.Naddr(f)
}
var at obj.Addr
if t != nil {
at = gc.Naddr(t)
}
p := gc.Prog(as) p := gc.Prog(as)
if f != nil { gc.Naddr(&p.From, f)
p.From = af gc.Naddr(&p.To, t)
}
if t != nil {
p.To = at
}
if gc.Debug['g'] != 0 { if gc.Debug['g'] != 0 {
fmt.Printf("%v\n", p) fmt.Printf("%v\n", p)
} }
@ -780,10 +769,10 @@ func gins(as int, f *gc.Node, t *gc.Node) *obj.Prog {
w = 8 w = 8
} }
if w != 0 && ((f != nil && af.Width < int64(w)) || (t != nil && at.Width > int64(w))) { if w != 0 && ((f != nil && p.From.Width < int64(w)) || (t != nil && p.To.Width > int64(w))) {
gc.Dump("f", f) gc.Dump("f", f)
gc.Dump("t", t) gc.Dump("t", t)
gc.Fatal("bad width: %v (%d, %d)\n", p, af.Width, at.Width) gc.Fatal("bad width: %v (%d, %d)\n", p, p.From.Width, p.To.Width)
} }
if p.To.Type == obj.TYPE_ADDR && w > 0 { if p.To.Type == obj.TYPE_ADDR && w > 0 {
@ -1405,7 +1394,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
*a = gc.Naddr(n) gc.Naddr(a, n)
return true return true
case gc.ODOT, case gc.ODOT,
@ -1429,7 +1418,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]
*a = gc.Naddr(&n1) gc.Naddr(a, &n1)
return true return true
} }
@ -1457,7 +1446,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)
*a = gc.Naddr(&n1) gc.Naddr(a, &n1)
return true return true
case gc.OINDEX: case gc.OINDEX:

View File

@ -77,7 +77,7 @@ func zerorange(p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog {
p.Reg = arm64.REGRT1 p.Reg = arm64.REGRT1
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")
p.To = gc.Naddr(f) gc.Naddr(&p.To, f)
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 {

View File

@ -615,22 +615,10 @@ func gins(as int, f *gc.Node, t *gc.Node) *obj.Prog {
// TODO(austin): Add self-move test like in 6g (but be careful // TODO(austin): Add self-move test like in 6g (but be careful
// of truncation moves) // of truncation moves)
af := obj.Addr(obj.Addr{}) p := gc.Prog(as)
gc.Naddr(&p.From, f)
gc.Naddr(&p.To, t)
at := obj.Addr(obj.Addr{})
if f != nil {
af = gc.Naddr(f)
}
if t != nil {
at = gc.Naddr(t)
}
p := (*obj.Prog)(gc.Prog(as))
if f != nil {
p.From = af
}
if t != nil {
p.To = at
}
if gc.Debug['g'] != 0 { if gc.Debug['g'] != 0 {
fmt.Printf("%v\n", p) fmt.Printf("%v\n", p)
} }
@ -650,16 +638,16 @@ func gins(as int, f *gc.Node, t *gc.Node) *obj.Prog {
w = 4 w = 4
case arm64.AMOVD: case arm64.AMOVD:
if af.Type == obj.TYPE_CONST || af.Type == obj.TYPE_ADDR { if p.From.Type == obj.TYPE_CONST || p.From.Type == obj.TYPE_ADDR {
break break
} }
w = 8 w = 8
} }
if w != 0 && ((f != nil && af.Width < int64(w)) || (t != nil && at.Type != obj.TYPE_REG && at.Width > int64(w))) { if w != 0 && ((f != nil && p.From.Width < int64(w)) || (t != nil && p.To.Type != obj.TYPE_REG && p.To.Width > int64(w))) {
gc.Dump("f", f) gc.Dump("f", f)
gc.Dump("t", t) gc.Dump("t", t)
gc.Fatal("bad width: %v (%d, %d)\n", p, af.Width, at.Width) gc.Fatal("bad width: %v (%d, %d)\n", p, p.From.Width, p.To.Width)
} }
return p return p
@ -690,7 +678,7 @@ func fixlargeoffset(n *gc.Node) {
func raddr(n *gc.Node, p *obj.Prog) { func raddr(n *gc.Node, p *obj.Prog) {
var a obj.Addr var a obj.Addr
a = gc.Naddr(n) gc.Naddr(&a, n)
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))

View File

@ -1844,21 +1844,10 @@ func gins(as int, f *gc.Node, t *gc.Node) *obj.Prog {
} }
} }
var af obj.Addr
var at obj.Addr
if f != nil {
af = gc.Naddr(f)
}
if t != nil {
at = gc.Naddr(t)
}
p := gc.Prog(as) p := gc.Prog(as)
if f != nil { gc.Naddr(&p.From, f)
p.From = af gc.Naddr(&p.To, t)
}
if t != nil {
p.To = at
}
if gc.Debug['g'] != 0 { if gc.Debug['g'] != 0 {
fmt.Printf("%v\n", p) fmt.Printf("%v\n", p)
} }
@ -1875,10 +1864,10 @@ func gins(as int, f *gc.Node, t *gc.Node) *obj.Prog {
w = 4 w = 4
} }
if true && w != 0 && f != nil && (af.Width > int64(w) || at.Width > int64(w)) { if true && w != 0 && f != nil && (p.From.Width > int64(w) || p.To.Width > int64(w)) {
gc.Dump("bad width from:", f) gc.Dump("bad width from:", f)
gc.Dump("bad width to:", t) gc.Dump("bad width to:", t)
gc.Fatal("bad width: %v (%d, %d)\n", p, af.Width, at.Width) gc.Fatal("bad width: %v (%d, %d)\n", p, p.From.Width, p.To.Width)
} }
if p.To.Type == obj.TYPE_ADDR && w > 0 { if p.To.Type == obj.TYPE_ADDR && w > 0 {

View File

@ -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")
p.To = gc.Naddr(f) gc.Naddr(&p.To, f)
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 {

View File

@ -696,22 +696,10 @@ func gins(as int, f *gc.Node, t *gc.Node) *obj.Prog {
// TODO(austin): Add self-move test like in 6g (but be careful // TODO(austin): Add self-move test like in 6g (but be careful
// of truncation moves) // of truncation moves)
af := obj.Addr(obj.Addr{}) p := gc.Prog(as)
gc.Naddr(&p.From, f)
gc.Naddr(&p.To, t)
at := obj.Addr(obj.Addr{})
if f != nil {
af = gc.Naddr(f)
}
if t != nil {
at = gc.Naddr(t)
}
p := (*obj.Prog)(gc.Prog(as))
if f != nil {
p.From = af
}
if t != nil {
p.To = at
}
if gc.Debug['g'] != 0 { if gc.Debug['g'] != 0 {
fmt.Printf("%v\n", p) fmt.Printf("%v\n", p)
} }
@ -738,16 +726,16 @@ func gins(as int, f *gc.Node, t *gc.Node) *obj.Prog {
case ppc64.AMOVD, case ppc64.AMOVD,
ppc64.AMOVDU: ppc64.AMOVDU:
if af.Type == obj.TYPE_CONST || af.Type == obj.TYPE_ADDR { if p.From.Type == obj.TYPE_CONST || p.From.Type == obj.TYPE_ADDR {
break break
} }
w = 8 w = 8
} }
if w != 0 && ((f != nil && af.Width < int64(w)) || (t != nil && at.Type != obj.TYPE_REG && at.Width > int64(w))) { if w != 0 && ((f != nil && p.From.Width < int64(w)) || (t != nil && p.To.Type != obj.TYPE_REG && p.To.Width > int64(w))) {
gc.Dump("f", f) gc.Dump("f", f)
gc.Dump("t", t) gc.Dump("t", t)
gc.Fatal("bad width: %v (%d, %d)\n", p, af.Width, at.Width) gc.Fatal("bad width: %v (%d, %d)\n", p, p.From.Width, p.To.Width)
} }
return p return p

View File

@ -273,7 +273,9 @@ func markautoused(p *obj.Prog) {
} }
} }
func Naddr(n *Node) (a obj.Addr) { // Naddr rewrites a to refer to n.
// It assumes that a is zeroed on entry.
func Naddr(a *obj.Addr, n *Node) {
if n == nil { if n == nil {
return return
} }
@ -293,7 +295,7 @@ func Naddr(n *Node) (a obj.Addr) {
switch n.Op { switch n.Op {
default: default:
a := a // copy to let escape into Ctxt.Dconv a := a // copy to let escape into Ctxt.Dconv
Fatal("naddr: bad %v %v", Oconv(int(n.Op), 0), Ctxt.Dconv(&a)) 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
@ -337,7 +339,7 @@ func Naddr(n *Node) (a obj.Addr) {
a.Offset = n.Xoffset a.Offset = n.Xoffset
case OCFUNC: case OCFUNC:
a = Naddr(n.Left) Naddr(a, n.Left)
a.Sym = Linksym(n.Left.Sym) a.Sym = Linksym(n.Left.Sym)
case ONAME: case ONAME:
@ -407,7 +409,7 @@ func Naddr(n *Node) (a obj.Addr) {
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
@ -421,20 +423,20 @@ func Naddr(n *Node) (a obj.Addr) {
} }
case OADDR: case OADDR:
a = Naddr(n.Left) Naddr(a, n.Left)
a.Etype = uint8(Tptr) a.Etype = uint8(Tptr)
if Thearch.Thechar != '5' && Thearch.Thechar != '7' && Thearch.Thechar != '9' { // TODO(rsc): Do this even for arm, ppc64. if Thearch.Thechar != '5' && Thearch.Thechar != '7' && 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 {
a := a // copy to let escape into Ctxt.Dconv a := a // copy to let escape into Ctxt.Dconv
Fatal("naddr: OADDR %v (from %v)", Ctxt.Dconv(&a), Oconv(int(n.Left.Op), 0)) 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:
a = Naddr(n.Left) Naddr(a, n.Left)
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 +446,7 @@ func Naddr(n *Node) (a obj.Addr) {
// pointer in a string or slice // pointer in a string or slice
case OSPTR: case OSPTR:
a = Naddr(n.Left) Naddr(a, n.Left)
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 +457,7 @@ func Naddr(n *Node) (a obj.Addr) {
// len of string or slice // len of string or slice
case OLEN: case OLEN:
a = Naddr(n.Left) Naddr(a, n.Left)
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 +473,7 @@ func Naddr(n *Node) (a obj.Addr) {
// cap of string or slice // cap of string or slice
case OCAP: case OCAP:
a = Naddr(n.Left) Naddr(a, n.Left)
if a.Type == obj.TYPE_CONST && a.Offset == 0 { if a.Type == obj.TYPE_CONST && a.Offset == 0 {
break // cap(nil) break // cap(nil)

View File

@ -1054,8 +1054,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
pcdata.From = Naddr(&from) Naddr(&pcdata.From, &from)
pcdata.To = Naddr(&to) Naddr(&pcdata.To, &to)
return pcdata return pcdata
} }