mirror of
https://github.com/golang/go
synced 2024-11-19 07:34:44 -07:00
cmd/internal/gc: change proginfo to return ProgInfo instead of writing to param
This avoids the argument appearing to escape (due to the fact that proginfo is always called via a function pointer). Change-Id: Ib9351ba18c80fd89e6a1d4f19dea386d4c657337 Reviewed-on: https://go-review.googlesource.com/6518 Reviewed-by: Rob Pike <r@golang.org>
This commit is contained in:
parent
175929b9fe
commit
4bbd7ae8e0
@ -266,7 +266,7 @@ func subprop(r0 *gc.Flow) bool {
|
|||||||
if p.As == obj.AVARDEF || p.As == obj.AVARKILL {
|
if p.As == obj.AVARDEF || p.As == obj.AVARKILL {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
proginfo(&info, p)
|
info = proginfo(p)
|
||||||
if info.Flags&gc.Call != 0 {
|
if info.Flags&gc.Call != 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -133,8 +133,8 @@ var progtable = [arm.ALAST]gc.ProgInfo{
|
|||||||
obj.ARET: gc.ProgInfo{gc.Break, 0, 0, 0},
|
obj.ARET: gc.ProgInfo{gc.Break, 0, 0, 0},
|
||||||
}
|
}
|
||||||
|
|
||||||
func proginfo(info *gc.ProgInfo, p *obj.Prog) {
|
func proginfo(p *obj.Prog) (info gc.ProgInfo) {
|
||||||
*info = progtable[p.As]
|
info = progtable[p.As]
|
||||||
if info.Flags == 0 {
|
if info.Flags == 0 {
|
||||||
gc.Fatal("unknown instruction %v", p)
|
gc.Fatal("unknown instruction %v", p)
|
||||||
}
|
}
|
||||||
@ -160,4 +160,6 @@ func proginfo(info *gc.ProgInfo, p *obj.Prog) {
|
|||||||
arm.AMODU:
|
arm.AMODU:
|
||||||
info.Regset |= RtoB(arm.REG_R12)
|
info.Regset |= RtoB(arm.REG_R12)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ func needc(p *obj.Prog) bool {
|
|||||||
var info gc.ProgInfo
|
var info gc.ProgInfo
|
||||||
|
|
||||||
for p != nil {
|
for p != nil {
|
||||||
proginfo(&info, p)
|
info = proginfo(p)
|
||||||
if info.Flags&gc.UseCarry != 0 {
|
if info.Flags&gc.UseCarry != 0 {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -514,7 +514,7 @@ func prevl(r0 *gc.Flow, reg int) bool {
|
|||||||
for r := (*gc.Flow)(gc.Uniqp(r0)); r != nil; r = gc.Uniqp(r) {
|
for r := (*gc.Flow)(gc.Uniqp(r0)); r != nil; r = gc.Uniqp(r) {
|
||||||
p = r.Prog
|
p = r.Prog
|
||||||
if p.To.Type == obj.TYPE_REG && int(p.To.Reg) == reg {
|
if p.To.Type == obj.TYPE_REG && int(p.To.Reg) == reg {
|
||||||
proginfo(&info, p)
|
info = proginfo(p)
|
||||||
if info.Flags&gc.RightWrite != 0 {
|
if info.Flags&gc.RightWrite != 0 {
|
||||||
if info.Flags&gc.SizeL != 0 {
|
if info.Flags&gc.SizeL != 0 {
|
||||||
return true
|
return true
|
||||||
@ -578,7 +578,7 @@ func subprop(r0 *gc.Flow) bool {
|
|||||||
if p.As == obj.AVARDEF || p.As == obj.AVARKILL {
|
if p.As == obj.AVARDEF || p.As == obj.AVARKILL {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
proginfo(&info, p)
|
info = proginfo(p)
|
||||||
if info.Flags&gc.Call != 0 {
|
if info.Flags&gc.Call != 0 {
|
||||||
if gc.Debug['P'] != 0 && gc.Debug['v'] != 0 {
|
if gc.Debug['P'] != 0 && gc.Debug['v'] != 0 {
|
||||||
fmt.Printf("\tfound %v; return 0\n", p)
|
fmt.Printf("\tfound %v; return 0\n", p)
|
||||||
@ -826,7 +826,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
var info gc.ProgInfo
|
var info gc.ProgInfo
|
||||||
proginfo(&info, 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
|
||||||
|
@ -237,8 +237,8 @@ var progtable = [x86.ALAST]gc.ProgInfo{
|
|||||||
x86.AXORW: gc.ProgInfo{gc.SizeW | gc.LeftRead | RightRdwr | gc.SetCarry, 0, 0, 0},
|
x86.AXORW: gc.ProgInfo{gc.SizeW | gc.LeftRead | RightRdwr | gc.SetCarry, 0, 0, 0},
|
||||||
}
|
}
|
||||||
|
|
||||||
func proginfo(info *gc.ProgInfo, p *obj.Prog) {
|
func proginfo(p *obj.Prog) (info gc.ProgInfo) {
|
||||||
*info = progtable[p.As]
|
info = progtable[p.As]
|
||||||
if info.Flags == 0 {
|
if info.Flags == 0 {
|
||||||
gc.Fatal("unknown instruction %v", p)
|
gc.Fatal("unknown instruction %v", p)
|
||||||
}
|
}
|
||||||
@ -269,4 +269,6 @@ func proginfo(info *gc.ProgInfo, p *obj.Prog) {
|
|||||||
if p.To.Index != x86.REG_NONE {
|
if p.To.Index != x86.REG_NONE {
|
||||||
info.Regindex |= RtoB(int(p.To.Index))
|
info.Regindex |= RtoB(int(p.To.Index))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ func needc(p *obj.Prog) bool {
|
|||||||
var info gc.ProgInfo
|
var info gc.ProgInfo
|
||||||
|
|
||||||
for p != nil {
|
for p != nil {
|
||||||
proginfo(&info, p)
|
info = proginfo(p)
|
||||||
if info.Flags&gc.UseCarry != 0 {
|
if info.Flags&gc.UseCarry != 0 {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -382,7 +382,7 @@ func subprop(r0 *gc.Flow) bool {
|
|||||||
if p.As == obj.AVARDEF || p.As == obj.AVARKILL {
|
if p.As == obj.AVARDEF || p.As == obj.AVARKILL {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
proginfo(&info, p)
|
info = proginfo(p)
|
||||||
if info.Flags&gc.Call != 0 {
|
if info.Flags&gc.Call != 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -611,7 +611,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
var info gc.ProgInfo
|
var info gc.ProgInfo
|
||||||
proginfo(&info, 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
|
||||||
|
@ -256,8 +256,8 @@ var progtable = [i386.ALAST]gc.ProgInfo{
|
|||||||
i386.AXORW: gc.ProgInfo{gc.SizeW | gc.LeftRead | RightRdwr | gc.SetCarry, 0, 0, 0},
|
i386.AXORW: gc.ProgInfo{gc.SizeW | gc.LeftRead | RightRdwr | gc.SetCarry, 0, 0, 0},
|
||||||
}
|
}
|
||||||
|
|
||||||
func proginfo(info *gc.ProgInfo, p *obj.Prog) {
|
func proginfo(p *obj.Prog) (info gc.ProgInfo) {
|
||||||
*info = progtable[p.As]
|
info = progtable[p.As]
|
||||||
if info.Flags == 0 {
|
if info.Flags == 0 {
|
||||||
gc.Fatal("unknown instruction %v", p)
|
gc.Fatal("unknown instruction %v", p)
|
||||||
}
|
}
|
||||||
@ -288,4 +288,6 @@ func proginfo(info *gc.ProgInfo, p *obj.Prog) {
|
|||||||
if p.To.Index != i386.REG_NONE {
|
if p.To.Index != i386.REG_NONE {
|
||||||
info.Regindex |= RtoB(int(p.To.Index))
|
info.Regindex |= RtoB(int(p.To.Index))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return info
|
||||||
}
|
}
|
||||||
|
@ -416,7 +416,7 @@ func subprop(r0 *gc.Flow) bool {
|
|||||||
if p.As == obj.AVARDEF || p.As == obj.AVARKILL {
|
if p.As == obj.AVARDEF || p.As == obj.AVARKILL {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
proginfo(&info, p)
|
info = proginfo(p)
|
||||||
if info.Flags&gc.Call != 0 {
|
if info.Flags&gc.Call != 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -133,12 +133,12 @@ func initproginfo() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func proginfo(info *gc.ProgInfo, p *obj.Prog) {
|
func proginfo(p *obj.Prog) (info gc.ProgInfo) {
|
||||||
initproginfo()
|
initproginfo()
|
||||||
|
|
||||||
*info = progtable[p.As]
|
info = progtable[p.As]
|
||||||
if info.Flags == 0 {
|
if info.Flags == 0 {
|
||||||
*info = progtable[ppc64.AADD]
|
info = progtable[ppc64.AADD]
|
||||||
gc.Fatal("proginfo: unknown instruction %v", p)
|
gc.Fatal("proginfo: unknown instruction %v", p)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,6 +177,8 @@ func proginfo(info *gc.ProgInfo, p *obj.Prog) {
|
|||||||
|
|
||||||
info.Regset |= RtoB(ppc64.REG_R3) | RtoB(ppc64.REG_R4)
|
info.Regset |= RtoB(ppc64.REG_R3) | RtoB(ppc64.REG_R4)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Instruction variants table. Initially this contains entries only
|
// Instruction variants table. Initially this contains entries only
|
||||||
|
@ -1138,7 +1138,7 @@ type Arch struct {
|
|||||||
Igen func(*Node, *Node, *Node)
|
Igen func(*Node, *Node, *Node)
|
||||||
Linkarchinit func()
|
Linkarchinit func()
|
||||||
Peep func(*obj.Prog)
|
Peep func(*obj.Prog)
|
||||||
Proginfo func(*ProgInfo, *obj.Prog)
|
Proginfo func(*obj.Prog) ProgInfo
|
||||||
Regalloc func(*Node, *Type, *Node)
|
Regalloc func(*Node, *Type, *Node)
|
||||||
Regfree func(*Node)
|
Regfree func(*Node)
|
||||||
Regtyp func(*obj.Addr) bool
|
Regtyp func(*obj.Addr) bool
|
||||||
|
@ -1931,7 +1931,10 @@ func getr() int32 {
|
|||||||
r, w := utf8.DecodeRune(buf[:i+1])
|
r, w := utf8.DecodeRune(buf[:i+1])
|
||||||
if r == utf8.RuneError && w == 1 {
|
if r == utf8.RuneError && w == 1 {
|
||||||
lineno = lexlineno
|
lineno = lexlineno
|
||||||
Yyerror("illegal UTF-8 sequence % x", buf[:i+1])
|
// The string conversion here makes a copy for passing
|
||||||
|
// to fmt.Printf, so that buf itself does not escape and can
|
||||||
|
// be allocated on the stack.
|
||||||
|
Yyerror("illegal UTF-8 sequence % x", string(buf[:i+1]))
|
||||||
}
|
}
|
||||||
return int32(r)
|
return int32(r)
|
||||||
}
|
}
|
||||||
|
@ -562,7 +562,7 @@ func progeffects(prog *obj.Prog, vars []*Node, uevar *Bvec, varkill *Bvec, avari
|
|||||||
bvresetall(varkill)
|
bvresetall(varkill)
|
||||||
bvresetall(avarinit)
|
bvresetall(avarinit)
|
||||||
|
|
||||||
Thearch.Proginfo(&info, 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
|
||||||
|
@ -362,6 +362,8 @@ func fixjmp(firstp *obj.Prog) {
|
|||||||
// to allocate in every f->data field, for use by the client.
|
// to allocate in every f->data field, for use by the client.
|
||||||
// If size == 0, f->data will be nil.
|
// If size == 0, f->data will be nil.
|
||||||
|
|
||||||
|
var flowmark int
|
||||||
|
|
||||||
func Flowstart(firstp *obj.Prog, newData func() interface{}) *Graph {
|
func Flowstart(firstp *obj.Prog, newData func() interface{}) *Graph {
|
||||||
var info ProgInfo
|
var info ProgInfo
|
||||||
|
|
||||||
@ -370,11 +372,11 @@ func Flowstart(firstp *obj.Prog, newData func() interface{}) *Graph {
|
|||||||
|
|
||||||
for p := firstp; p != nil; p = p.Link {
|
for p := firstp; p != nil; p = p.Link {
|
||||||
p.Opt = nil // should be already, but just in case
|
p.Opt = nil // should be already, but just in case
|
||||||
Thearch.Proginfo(&info, p)
|
info = Thearch.Proginfo(p)
|
||||||
if info.Flags&Skip != 0 {
|
if info.Flags&Skip != 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
p.Opt = interface{}(1)
|
p.Opt = &flowmark
|
||||||
nf++
|
nf++
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -417,7 +419,7 @@ func Flowstart(firstp *obj.Prog, newData func() interface{}) *Graph {
|
|||||||
var p *obj.Prog
|
var p *obj.Prog
|
||||||
for f := start; f != nil; f = f.Link {
|
for f := start; f != nil; f = f.Link {
|
||||||
p = f.Prog
|
p = f.Prog
|
||||||
Thearch.Proginfo(&info, p)
|
info = Thearch.Proginfo(p)
|
||||||
if info.Flags&Break == 0 {
|
if info.Flags&Break == 0 {
|
||||||
f1 = f.Link
|
f1 = f.Link
|
||||||
f.S1 = f1
|
f.S1 = f1
|
||||||
@ -726,7 +728,7 @@ func mergetemp(firstp *obj.Prog) {
|
|||||||
var info ProgInfo
|
var info ProgInfo
|
||||||
for f := g.Start; f != nil; f = f.Link {
|
for f := g.Start; f != nil; f = f.Link {
|
||||||
p = f.Prog
|
p = f.Prog
|
||||||
Thearch.Proginfo(&info, p)
|
info = Thearch.Proginfo(p)
|
||||||
|
|
||||||
if p.From.Node != nil && ((p.From.Node).(*Node)).Opt != nil && p.To.Node != nil && ((p.To.Node).(*Node)).Opt != nil {
|
if p.From.Node != nil && ((p.From.Node).(*Node)).Opt != nil && p.To.Node != nil && ((p.To.Node).(*Node)).Opt != nil {
|
||||||
Fatal("double node %v", p)
|
Fatal("double node %v", p)
|
||||||
@ -774,7 +776,7 @@ func mergetemp(firstp *obj.Prog) {
|
|||||||
f = v.use
|
f = v.use
|
||||||
if f != nil && f.Data.(*Flow) == nil {
|
if f != nil && f.Data.(*Flow) == nil {
|
||||||
p = f.Prog
|
p = f.Prog
|
||||||
Thearch.Proginfo(&info, p)
|
info = Thearch.Proginfo(p)
|
||||||
if p.To.Node == v.node && (info.Flags&RightWrite != 0) && info.Flags&RightRead == 0 {
|
if p.To.Node == v.node && (info.Flags&RightWrite != 0) && info.Flags&RightRead == 0 {
|
||||||
p.As = obj.ANOP
|
p.As = obj.ANOP
|
||||||
p.To = obj.Addr{}
|
p.To = obj.Addr{}
|
||||||
@ -794,9 +796,9 @@ func mergetemp(firstp *obj.Prog) {
|
|||||||
f = v.use
|
f = v.use
|
||||||
if f != nil && f.Link == f.Data.(*Flow) && (f.Data.(*Flow)).Data.(*Flow) == nil && Uniqp(f.Link) == f {
|
if f != nil && f.Link == f.Data.(*Flow) && (f.Data.(*Flow)).Data.(*Flow) == nil && Uniqp(f.Link) == f {
|
||||||
p = f.Prog
|
p = f.Prog
|
||||||
Thearch.Proginfo(&info, p)
|
info = Thearch.Proginfo(p)
|
||||||
p1 = f.Link.Prog
|
p1 = f.Link.Prog
|
||||||
Thearch.Proginfo(&info1, p1)
|
info1 = Thearch.Proginfo(p1)
|
||||||
const (
|
const (
|
||||||
SizeAny = SizeB | SizeW | SizeL | SizeQ | SizeF | SizeD
|
SizeAny = SizeB | SizeW | SizeL | SizeQ | SizeF | SizeD
|
||||||
)
|
)
|
||||||
@ -1122,7 +1124,7 @@ func nilwalkback(fcheck *Flow) {
|
|||||||
|
|
||||||
for f := fcheck; f != nil; f = Uniqp(f) {
|
for f := fcheck; f != nil; f = Uniqp(f) {
|
||||||
p = f.Prog
|
p = f.Prog
|
||||||
Thearch.Proginfo(&info, p)
|
info = Thearch.Proginfo(p)
|
||||||
if (info.Flags&RightWrite != 0) && Thearch.Sameaddr(&p.To, &fcheck.Prog.From) {
|
if (info.Flags&RightWrite != 0) && Thearch.Sameaddr(&p.To, &fcheck.Prog.From) {
|
||||||
// Found initialization of value we're checking for nil.
|
// Found initialization of value we're checking for nil.
|
||||||
// without first finding the check, so this one is unchecked.
|
// without first finding the check, so this one is unchecked.
|
||||||
@ -1191,7 +1193,7 @@ func nilwalkfwd(fcheck *Flow) {
|
|||||||
|
|
||||||
for f := Uniqs(fcheck); f != nil; f = Uniqs(f) {
|
for f := Uniqs(fcheck); f != nil; f = Uniqs(f) {
|
||||||
p = f.Prog
|
p = f.Prog
|
||||||
Thearch.Proginfo(&info, p)
|
info = Thearch.Proginfo(p)
|
||||||
|
|
||||||
if (info.Flags&LeftRead != 0) && Thearch.Smallindir(&p.From, &fcheck.Prog.From) {
|
if (info.Flags&LeftRead != 0) && Thearch.Smallindir(&p.From, &fcheck.Prog.From) {
|
||||||
fcheck.Data = &killed
|
fcheck.Data = &killed
|
||||||
|
@ -983,7 +983,7 @@ func regopt(firstp *obj.Prog) {
|
|||||||
if p.As == obj.AVARDEF || p.As == obj.AVARKILL {
|
if p.As == obj.AVARDEF || p.As == obj.AVARKILL {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
Thearch.Proginfo(&info, p)
|
info = Thearch.Proginfo(p)
|
||||||
|
|
||||||
// Avoid making variables for direct-called functions.
|
// Avoid making variables for direct-called functions.
|
||||||
if p.As == obj.ACALL && p.To.Type == obj.TYPE_MEM && p.To.Name == obj.NAME_EXTERN {
|
if p.As == obj.ACALL && p.To.Type == obj.TYPE_MEM && p.To.Name == obj.NAME_EXTERN {
|
||||||
|
Loading…
Reference in New Issue
Block a user