Commit dbe54d23 authored by Dave Cheney's avatar Dave Cheney

cmd/compile/internal: peep.go cleanups

More cleanups after CL 20089

- copysub, take a bool rather than an int for the f (force) parameter.
- copysub returns a bool rather than an int.
- prevl, reg is now int16, which reduces type conversion in its callers.
- copy1, reduce the scope of t and p variables.
- small simplifications in copyau1, copyas, etc.
- {mips64,ppc64}/regzer returns a bool.
- apply CL 20181 to x86/peep.go which was missed in the last CL.
- various comment fixes.

Change-Id: Ib73ffb768c979ce86f1614e5366fd576dea50986
Reviewed-on: https://go-review.googlesource.com/20281Reviewed-by: default avatarMatthew Dempsky <mdempsky@google.com>
Run-TryBot: Dave Cheney <dave@cheney.net>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 211cc40b
...@@ -266,7 +266,7 @@ loop1: ...@@ -266,7 +266,7 @@ loop1:
if p.As == x86.AMOVLQZX { if p.As == x86.AMOVLQZX {
if regtyp(&p.From) { if regtyp(&p.From) {
if p.From.Type == p.To.Type && p.From.Reg == p.To.Reg { if p.From.Type == p.To.Type && p.From.Reg == p.To.Reg {
if prevl(r, int(p.From.Reg)) { if prevl(r, p.From.Reg) {
excise(r) excise(r)
} }
} }
...@@ -505,10 +505,10 @@ func regconsttyp(a *obj.Addr) bool { ...@@ -505,10 +505,10 @@ func regconsttyp(a *obj.Addr) bool {
} }
// is reg guaranteed to be truncated by a previous L instruction? // is reg guaranteed to be truncated by a previous L instruction?
func prevl(r0 *gc.Flow, reg int) bool { func prevl(r0 *gc.Flow, reg int16) bool {
for r := gc.Uniqp(r0); r != nil; r = gc.Uniqp(r) { for r := 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 && p.To.Reg == reg {
flags := progflags(p) flags := progflags(p)
if flags&gc.RightWrite != 0 { if flags&gc.RightWrite != 0 {
if flags&gc.SizeL != 0 { if flags&gc.SizeL != 0 {
...@@ -518,7 +518,6 @@ func prevl(r0 *gc.Flow, reg int) bool { ...@@ -518,7 +518,6 @@ func prevl(r0 *gc.Flow, reg int) bool {
} }
} }
} }
return false return false
} }
...@@ -587,7 +586,7 @@ func subprop(r0 *gc.Flow) bool { ...@@ -587,7 +586,7 @@ func subprop(r0 *gc.Flow) bool {
} }
if (p.Info.Flags&gc.Move != 0) && (p.Info.Flags&(gc.SizeL|gc.SizeQ|gc.SizeF|gc.SizeD) != 0) && p.To.Type == v1.Type && p.To.Reg == v1.Reg { if (p.Info.Flags&gc.Move != 0) && (p.Info.Flags&(gc.SizeL|gc.SizeQ|gc.SizeF|gc.SizeD) != 0) && p.To.Type == v1.Type && p.To.Reg == v1.Reg {
copysub(&p.To, v1, v2, 1) copysub(&p.To, v1, v2, true)
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("gotit: %v->%v\n%v", gc.Ctxt.Dconv(v1), gc.Ctxt.Dconv(v2), r.Prog) fmt.Printf("gotit: %v->%v\n%v", gc.Ctxt.Dconv(v1), gc.Ctxt.Dconv(v2), r.Prog)
if p.From.Type == v2.Type && p.From.Reg == v2.Reg { if p.From.Type == v2.Type && p.From.Reg == v2.Reg {
...@@ -598,8 +597,8 @@ func subprop(r0 *gc.Flow) bool { ...@@ -598,8 +597,8 @@ func subprop(r0 *gc.Flow) bool {
for r = gc.Uniqs(r); r != r0; r = gc.Uniqs(r) { for r = gc.Uniqs(r); r != r0; r = gc.Uniqs(r) {
p = r.Prog p = r.Prog
copysub(&p.From, v1, v2, 1) copysub(&p.From, v1, v2, true)
copysub(&p.To, v1, v2, 1) copysub(&p.To, v1, v2, true)
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("%v\n", r.Prog) fmt.Printf("%v\n", r.Prog)
} }
...@@ -619,7 +618,7 @@ func subprop(r0 *gc.Flow) bool { ...@@ -619,7 +618,7 @@ func subprop(r0 *gc.Flow) bool {
break break
} }
if copysub(&p.From, v1, v2, 0) != 0 || copysub(&p.To, v1, v2, 0) != 0 { if copysub(&p.From, v1, v2, false) || copysub(&p.To, v1, v2, false) {
if gc.Debug['P'] != 0 && gc.Debug['v'] != 0 { if gc.Debug['P'] != 0 && gc.Debug['v'] != 0 {
fmt.Printf("\tcopysub failed\n") fmt.Printf("\tcopysub failed\n")
} }
...@@ -656,10 +655,10 @@ func copyprop(g *gc.Graph, r0 *gc.Flow) bool { ...@@ -656,10 +655,10 @@ func copyprop(g *gc.Graph, r0 *gc.Flow) bool {
return true return true
} }
gactive++ gactive++
return copy1(v1, v2, r0.S1, 0) return copy1(v1, v2, r0.S1, false)
} }
func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool { func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f bool) bool {
if uint32(r.Active) == gactive { if uint32(r.Active) == gactive {
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("act set; return 1\n") fmt.Printf("act set; return 1\n")
...@@ -669,24 +668,21 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool { ...@@ -669,24 +668,21 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool {
r.Active = int32(gactive) r.Active = int32(gactive)
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("copy %v->%v f=%d\n", gc.Ctxt.Dconv(v1), gc.Ctxt.Dconv(v2), f) fmt.Printf("copy %v->%v f=%v\n", gc.Ctxt.Dconv(v1), gc.Ctxt.Dconv(v2), f)
} }
var t int
var p *obj.Prog
for ; r != nil; r = r.S1 { for ; r != nil; r = r.S1 {
p = r.Prog p := r.Prog
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("%v", p) fmt.Printf("%v", p)
} }
if f == 0 && gc.Uniqp(r) == nil { if !f && gc.Uniqp(r) == nil {
f = 1 f = true
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("; merge; f=%d", f) fmt.Printf("; merge; f=%v", f)
} }
} }
t = copyu(p, v2, nil) switch t := copyu(p, v2, nil); t {
switch t {
case 2: /* rar, can't split */ case 2: /* rar, can't split */
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("; %v rar; return 0\n", gc.Ctxt.Dconv(v2)) fmt.Printf("; %v rar; return 0\n", gc.Ctxt.Dconv(v2))
...@@ -701,14 +697,14 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool { ...@@ -701,14 +697,14 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool {
case 1, /* used, substitute */ case 1, /* used, substitute */
4: /* use and set */ 4: /* use and set */
if f != 0 { if f {
if gc.Debug['P'] == 0 { if gc.Debug['P'] == 0 {
return false return false
} }
if t == 4 { if t == 4 {
fmt.Printf("; %v used+set and f=%d; return 0\n", gc.Ctxt.Dconv(v2), f) fmt.Printf("; %v used+set and f=%v; return 0\n", gc.Ctxt.Dconv(v2), f)
} else { } else {
fmt.Printf("; %v used and f=%d; return 0\n", gc.Ctxt.Dconv(v2), f) fmt.Printf("; %v used and f=%v; return 0\n", gc.Ctxt.Dconv(v2), f)
} }
return false return false
} }
...@@ -731,12 +727,12 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool { ...@@ -731,12 +727,12 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool {
} }
} }
if f == 0 { if !f {
t = copyu(p, v1, nil) t := copyu(p, v1, nil)
if f == 0 && (t == 2 || t == 3 || t == 4) { if t == 2 || t == 3 || t == 4 {
f = 1 f = true
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("; %v set and !f; f=%d", gc.Ctxt.Dconv(v1), f) fmt.Printf("; %v set and !f; f=%v", gc.Ctxt.Dconv(v1), f)
} }
} }
} }
...@@ -750,7 +746,6 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool { ...@@ -750,7 +746,6 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool {
} }
} }
} }
return true return true
} }
...@@ -766,7 +761,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int { ...@@ -766,7 +761,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
switch p.As { switch p.As {
case obj.AJMP: case obj.AJMP:
if s != nil { if s != nil {
if copysub(&p.To, v, s, 1) != 0 { if copysub(&p.To, v, s, true) {
return 1 return 1
} }
return 0 return 0
...@@ -795,7 +790,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int { ...@@ -795,7 +790,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
} }
if s != nil { if s != nil {
if copysub(&p.To, v, s, 1) != 0 { if copysub(&p.To, v, s, true) {
return 1 return 1
} }
return 0 return 0
...@@ -840,7 +835,10 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int { ...@@ -840,7 +835,10 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
if p.Info.Flags&gc.RightWrite != 0 { if p.Info.Flags&gc.RightWrite != 0 {
if copyas(&p.To, v) { if copyas(&p.To, v) {
if s != nil { if s != nil {
return copysub(&p.From, v, s, 1) if copysub(&p.From, v, s, true) {
return 1
}
return 0
} }
if copyau(&p.From, v) { if copyau(&p.From, v) {
return 4 return 4
...@@ -851,10 +849,13 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int { ...@@ -851,10 +849,13 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
if p.Info.Flags&(gc.LeftAddr|gc.LeftRead|gc.LeftWrite|gc.RightAddr|gc.RightRead|gc.RightWrite) != 0 { if p.Info.Flags&(gc.LeftAddr|gc.LeftRead|gc.LeftWrite|gc.RightAddr|gc.RightRead|gc.RightWrite) != 0 {
if s != nil { if s != nil {
if copysub(&p.From, v, s, 1) != 0 { if copysub(&p.From, v, s, true) {
return 1 return 1
} }
return copysub(&p.To, v, s, 1) if copysub(&p.To, v, s, true) {
return 1
}
return 0
} }
if copyau(&p.From, v) { if copyau(&p.From, v) {
...@@ -864,7 +865,6 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int { ...@@ -864,7 +865,6 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
return 1 return 1
} }
} }
return 0 return 0
} }
...@@ -936,48 +936,40 @@ func copyau(a *obj.Addr, v *obj.Addr) bool { ...@@ -936,48 +936,40 @@ func copyau(a *obj.Addr, v *obj.Addr) bool {
return true return true
} }
} }
return false return false
} }
/* // copysub substitute s for v in a.
* substitute s for v in a // copysub returns true on failure to substitute. TODO(dfc) reverse this logic, copysub should return false on failure
* return failure to substitute func copysub(a *obj.Addr, v *obj.Addr, s *obj.Addr, f bool) bool {
*/
func copysub(a *obj.Addr, v *obj.Addr, s *obj.Addr, f int) int {
if copyas(a, v) { if copyas(a, v) {
if s.Reg >= x86.REG_AX && s.Reg <= x86.REG_R15 || s.Reg >= x86.REG_X0 && s.Reg <= x86.REG_X0+15 { if s.Reg >= x86.REG_AX && s.Reg <= x86.REG_R15 || s.Reg >= x86.REG_X0 && s.Reg <= x86.REG_X0+15 {
if f != 0 { if f {
a.Reg = s.Reg a.Reg = s.Reg
} }
} }
return 0 return false
} }
if regtyp(v) { if regtyp(v) {
if a.Type == obj.TYPE_MEM && a.Reg == v.Reg { if a.Type == obj.TYPE_MEM && a.Reg == v.Reg {
if (s.Reg == x86.REG_BP || s.Reg == x86.REG_R13) && a.Index != x86.REG_NONE { if (s.Reg == x86.REG_BP || s.Reg == x86.REG_R13) && a.Index != x86.REG_NONE {
return 1 /* can't use BP-base with index */ return true /* can't use BP-base with index */
} }
if f != 0 { if f {
a.Reg = s.Reg a.Reg = s.Reg
} }
} }
if a.Index == v.Reg { if a.Index == v.Reg {
if f != 0 { if f {
a.Index = s.Reg a.Index = s.Reg
} }
return 0
} }
return 0
} }
return 0 return false
} }
func conprop(r0 *gc.Flow) { func conprop(r0 *gc.Flow) {
var p *obj.Prog
var t int
p0 := r0.Prog p0 := r0.Prog
v0 := &p0.To v0 := &p0.To
r := r0 r := r0
...@@ -991,8 +983,8 @@ loop: ...@@ -991,8 +983,8 @@ loop:
return return
} }
p = r.Prog p := r.Prog
t = copyu(p, v0, nil) t := copyu(p, v0, nil)
switch t { switch t {
case 0, // miss case 0, // miss
1: // use 1: // use
......
...@@ -47,7 +47,6 @@ func peep(firstp *obj.Prog) { ...@@ -47,7 +47,6 @@ func peep(firstp *obj.Prog) {
} }
gactive = 0 gactive = 0
var r *gc.Flow
var p *obj.Prog var p *obj.Prog
var t int var t int
loop1: loop1:
...@@ -56,7 +55,7 @@ loop1: ...@@ -56,7 +55,7 @@ loop1:
} }
t = 0 t = 0
for r = g.Start; r != nil; r = r.Link { for r := g.Start; r != nil; r = r.Link {
p = r.Prog p = r.Prog
switch p.As { switch p.As {
/* /*
...@@ -289,7 +288,7 @@ func subprop(r0 *gc.Flow) bool { ...@@ -289,7 +288,7 @@ func subprop(r0 *gc.Flow) bool {
if p.To.Type == v1.Type { if p.To.Type == v1.Type {
if p.To.Reg == v1.Reg { if p.To.Reg == v1.Reg {
if p.Scond == arm.C_SCOND_NONE { if p.Scond == arm.C_SCOND_NONE {
copysub(&p.To, v1, v2, 1) copysub(&p.To, v1, v2, true)
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("gotit: %v->%v\n%v", gc.Ctxt.Dconv(v1), gc.Ctxt.Dconv(v2), r.Prog) fmt.Printf("gotit: %v->%v\n%v", gc.Ctxt.Dconv(v1), gc.Ctxt.Dconv(v2), r.Prog)
if p.From.Type == v2.Type { if p.From.Type == v2.Type {
...@@ -300,9 +299,9 @@ func subprop(r0 *gc.Flow) bool { ...@@ -300,9 +299,9 @@ func subprop(r0 *gc.Flow) bool {
for r = gc.Uniqs(r); r != r0; r = gc.Uniqs(r) { for r = gc.Uniqs(r); r != r0; r = gc.Uniqs(r) {
p = r.Prog p = r.Prog
copysub(&p.From, v1, v2, 1) copysub(&p.From, v1, v2, true)
copysub1(p, v1, v2, 1) copysub1(p, v1, v2, true)
copysub(&p.To, v1, v2, 1) copysub(&p.To, v1, v2, true)
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("%v\n", r.Prog) fmt.Printf("%v\n", r.Prog)
} }
...@@ -321,7 +320,7 @@ func subprop(r0 *gc.Flow) bool { ...@@ -321,7 +320,7 @@ func subprop(r0 *gc.Flow) bool {
if copyau(&p.From, v2) || copyau1(p, v2) || copyau(&p.To, v2) { if copyau(&p.From, v2) || copyau1(p, v2) || copyau(&p.To, v2) {
break break
} }
if copysub(&p.From, v1, v2, 0) != 0 || copysub1(p, v1, v2, 0) != 0 || copysub(&p.To, v1, v2, 0) != 0 { if copysub(&p.From, v1, v2, false) || copysub1(p, v1, v2, false) || copysub(&p.To, v1, v2, false) {
break break
} }
} }
...@@ -349,10 +348,10 @@ func copyprop(g *gc.Graph, r0 *gc.Flow) bool { ...@@ -349,10 +348,10 @@ func copyprop(g *gc.Graph, r0 *gc.Flow) bool {
return true return true
} }
gactive++ gactive++
return copy1(v1, v2, r0.S1, 0) return copy1(v1, v2, r0.S1, false)
} }
func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool { func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f bool) bool {
if uint32(r.Active) == gactive { if uint32(r.Active) == gactive {
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("act set; return 1\n") fmt.Printf("act set; return 1\n")
...@@ -362,24 +361,21 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool { ...@@ -362,24 +361,21 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool {
r.Active = int32(gactive) r.Active = int32(gactive)
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("copy %v->%v f=%d\n", gc.Ctxt.Dconv(v1), gc.Ctxt.Dconv(v2), f) fmt.Printf("copy %v->%v f=%v\n", gc.Ctxt.Dconv(v1), gc.Ctxt.Dconv(v2), f)
} }
var t int
var p *obj.Prog
for ; r != nil; r = r.S1 { for ; r != nil; r = r.S1 {
p = r.Prog p := r.Prog
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("%v", p) fmt.Printf("%v", p)
} }
if f == 0 && gc.Uniqp(r) == nil { if !f && gc.Uniqp(r) == nil {
f = 1 f = true
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("; merge; f=%d", f) fmt.Printf("; merge; f=%v", f)
} }
} }
t = copyu(p, v2, nil) switch t := copyu(p, v2, nil); t {
switch t {
case 2: /* rar, can't split */ case 2: /* rar, can't split */
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("; %vrar; return 0\n", gc.Ctxt.Dconv(v2)) fmt.Printf("; %vrar; return 0\n", gc.Ctxt.Dconv(v2))
...@@ -394,14 +390,14 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool { ...@@ -394,14 +390,14 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool {
case 1, /* used, substitute */ case 1, /* used, substitute */
4: /* use and set */ 4: /* use and set */
if f != 0 { if f {
if gc.Debug['P'] == 0 { if gc.Debug['P'] == 0 {
return false return false
} }
if t == 4 { if t == 4 {
fmt.Printf("; %vused+set and f=%d; return 0\n", gc.Ctxt.Dconv(v2), f) fmt.Printf("; %vused+set and f=%v; return 0\n", gc.Ctxt.Dconv(v2), f)
} else { } else {
fmt.Printf("; %vused and f=%d; return 0\n", gc.Ctxt.Dconv(v2), f) fmt.Printf("; %vused and f=%v; return 0\n", gc.Ctxt.Dconv(v2), f)
} }
return false return false
} }
...@@ -424,12 +420,12 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool { ...@@ -424,12 +420,12 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool {
} }
} }
if f == 0 { if !f {
t = copyu(p, v1, nil) t := copyu(p, v1, nil)
if f == 0 && (t == 2 || t == 3 || t == 4) { if t == 2 || t == 3 || t == 4 {
f = 1 f = true
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("; %vset and !f; f=%d", gc.Ctxt.Dconv(v1), f) fmt.Printf("; %vset and !f; f=%v", gc.Ctxt.Dconv(v1), f)
} }
} }
} }
...@@ -443,7 +439,6 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool { ...@@ -443,7 +439,6 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool {
} }
} }
} }
return true return true
} }
...@@ -1053,7 +1048,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int { ...@@ -1053,7 +1048,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
if p.From.Offset&(1<<uint(v.Reg)) != 0 { if p.From.Offset&(1<<uint(v.Reg)) != 0 {
return 1 return 1
} }
if copysub(&p.To, v, s, 1) != 0 { if copysub(&p.To, v, s, true) {
return 1 return 1
} }
return 0 return 0
...@@ -1074,7 +1069,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int { ...@@ -1074,7 +1069,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
if p.To.Offset&(1<<uint(v.Reg)) != 0 { if p.To.Offset&(1<<uint(v.Reg)) != 0 {
return 1 return 1
} }
if copysub(&p.From, v, s, 1) != 0 { if copysub(&p.From, v, s, true) {
return 1 return 1
} }
return 0 return 0
...@@ -1129,11 +1124,11 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int { ...@@ -1129,11 +1124,11 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
} }
if s != nil { if s != nil {
if copysub(&p.From, v, s, 1) != 0 { if copysub(&p.From, v, s, true) {
return 1 return 1
} }
if !copyas(&p.To, v) { if !copyas(&p.To, v) {
if copysub(&p.To, v, s, 1) != 0 { if copysub(&p.To, v, s, true) {
return 1 return 1
} }
} }
...@@ -1198,14 +1193,14 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int { ...@@ -1198,14 +1193,14 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
arm.ATST: arm.ATST:
/* read,, */ /* read,, */
if s != nil { if s != nil {
if copysub(&p.From, v, s, 1) != 0 { if copysub(&p.From, v, s, true) {
return 1 return 1
} }
if copysub1(p, v, s, 1) != 0 { if copysub1(p, v, s, true) {
return 1 return 1
} }
if !copyas(&p.To, v) { if !copyas(&p.To, v) {
if copysub(&p.To, v, s, 1) != 0 { if copysub(&p.To, v, s, true) {
return 1 return 1
} }
} }
...@@ -1256,10 +1251,13 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int { ...@@ -1256,10 +1251,13 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
arm.ABGT, arm.ABGT,
arm.ABLE: arm.ABLE:
if s != nil { if s != nil {
if copysub(&p.From, v, s, 1) != 0 { if copysub(&p.From, v, s, true) {
return 1 return 1
} }
return copysub1(p, v, s, 1) if copysub1(p, v, s, true) {
return 1
}
return 0
} }
if copyau(&p.From, v) { if copyau(&p.From, v) {
...@@ -1272,12 +1270,11 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int { ...@@ -1272,12 +1270,11 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
case arm.AB: /* funny */ case arm.AB: /* funny */
if s != nil { if s != nil {
if copysub(&p.To, v, s, 1) != 0 { if copysub(&p.To, v, s, true) {
return 1 return 1
} }
return 0 return 0
} }
if copyau(&p.To, v) { if copyau(&p.To, v) {
return 1 return 1
} }
...@@ -1312,7 +1309,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int { ...@@ -1312,7 +1309,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
} }
if s != nil { if s != nil {
if copysub(&p.To, v, s, 1) != 0 { if copysub(&p.To, v, s, true) {
return 1 return 1
} }
return 0 return 0
...@@ -1461,13 +1458,11 @@ func copyau1(p *obj.Prog, v *obj.Addr) bool { ...@@ -1461,13 +1458,11 @@ func copyau1(p *obj.Prog, v *obj.Addr) bool {
return p.Reg == v.Reg return p.Reg == v.Reg
} }
/* // copysub substitute s for v in a.
* substitute s for v in a // copysub returns true on failure to substitute.
* return failure to substitute // TODO(dfc) remove unused return value, remove calls with f=false as they do nothing.
*/ func copysub(a *obj.Addr, v *obj.Addr, s *obj.Addr, f bool) bool {
func copysub(a *obj.Addr, v *obj.Addr, s *obj.Addr, f int) int { if f && copyau(a, v) {
if f != 0 {
if copyau(a, v) {
if a.Type == obj.TYPE_SHIFT { if a.Type == obj.TYPE_SHIFT {
if a.Offset&0xf == int64(v.Reg-arm.REG_R0) { if a.Offset&0xf == int64(v.Reg-arm.REG_R0) {
a.Offset = a.Offset&^0xf | int64(s.Reg)&0xf a.Offset = a.Offset&^0xf | int64(s.Reg)&0xf
...@@ -1486,18 +1481,15 @@ func copysub(a *obj.Addr, v *obj.Addr, s *obj.Addr, f int) int { ...@@ -1486,18 +1481,15 @@ func copysub(a *obj.Addr, v *obj.Addr, s *obj.Addr, f int) int {
a.Reg = s.Reg a.Reg = s.Reg
} }
} }
} return false
return 0
} }
func copysub1(p1 *obj.Prog, v *obj.Addr, s *obj.Addr, f int) int { // TODO(dfc) remove unused return value, remove calls with f=false as they do nothing.
if f != 0 { func copysub1(p1 *obj.Prog, v *obj.Addr, s *obj.Addr, f bool) bool {
if copyau1(p1, v) { if f && copyau1(p1, v) {
p1.Reg = s.Reg p1.Reg = s.Reg
} }
} return false
return 0
} }
var predinfo = []struct { var predinfo = []struct {
...@@ -1650,9 +1642,8 @@ func joinsplit(r *gc.Flow, j *Joininfo) int { ...@@ -1650,9 +1642,8 @@ func joinsplit(r *gc.Flow, j *Joininfo) int {
func successor(r *gc.Flow) *gc.Flow { func successor(r *gc.Flow) *gc.Flow {
if r.S1 != nil { if r.S1 != nil {
return r.S1 return r.S1
} else {
return r.S2
} }
return r.S2
} }
func applypred(rstart *gc.Flow, j *Joininfo, cond int, branch int) { func applypred(rstart *gc.Flow, j *Joininfo, cond int, branch int) {
......
...@@ -234,7 +234,7 @@ func subprop(r0 *gc.Flow) bool { ...@@ -234,7 +234,7 @@ func subprop(r0 *gc.Flow) bool {
if p.Info.Flags&(gc.RightRead|gc.RightWrite) == gc.RightWrite { if p.Info.Flags&(gc.RightRead|gc.RightWrite) == gc.RightWrite {
if p.To.Type == v1.Type { if p.To.Type == v1.Type {
if p.To.Reg == v1.Reg { if p.To.Reg == v1.Reg {
copysub(&p.To, v1, v2, 1) copysub(&p.To, v1, v2, true)
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("gotit: %v->%v\n%v", gc.Ctxt.Dconv(v1), gc.Ctxt.Dconv(v2), r.Prog) fmt.Printf("gotit: %v->%v\n%v", gc.Ctxt.Dconv(v1), gc.Ctxt.Dconv(v2), r.Prog)
if p.From.Type == v2.Type { if p.From.Type == v2.Type {
...@@ -245,9 +245,9 @@ func subprop(r0 *gc.Flow) bool { ...@@ -245,9 +245,9 @@ func subprop(r0 *gc.Flow) bool {
for r = gc.Uniqs(r); r != r0; r = gc.Uniqs(r) { for r = gc.Uniqs(r); r != r0; r = gc.Uniqs(r) {
p = r.Prog p = r.Prog
copysub(&p.From, v1, v2, 1) copysub(&p.From, v1, v2, true)
copysub1(p, v1, v2, 1) copysub1(p, v1, v2, true)
copysub(&p.To, v1, v2, 1) copysub(&p.To, v1, v2, true)
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("%v\n", r.Prog) fmt.Printf("%v\n", r.Prog)
} }
...@@ -265,7 +265,7 @@ func subprop(r0 *gc.Flow) bool { ...@@ -265,7 +265,7 @@ func subprop(r0 *gc.Flow) bool {
if copyau(&p.From, v2) || copyau1(p, v2) || copyau(&p.To, v2) { if copyau(&p.From, v2) || copyau1(p, v2) || copyau(&p.To, v2) {
break break
} }
if copysub(&p.From, v1, v2, 0) != 0 || copysub1(p, v1, v2, 0) != 0 || copysub(&p.To, v1, v2, 0) != 0 { if copysub(&p.From, v1, v2, false) || copysub1(p, v1, v2, false) || copysub(&p.To, v1, v2, false) {
break break
} }
} }
...@@ -300,12 +300,12 @@ func copyprop(r0 *gc.Flow) bool { ...@@ -300,12 +300,12 @@ func copyprop(r0 *gc.Flow) bool {
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("trying to eliminate %v->%v move from:\n%v\n", gc.Ctxt.Dconv(v1), gc.Ctxt.Dconv(v2), r0.Prog) fmt.Printf("trying to eliminate %v->%v move from:\n%v\n", gc.Ctxt.Dconv(v1), gc.Ctxt.Dconv(v2), r0.Prog)
} }
return copy1(v1, v2, r0.S1, 0) return copy1(v1, v2, r0.S1, false)
} }
// copy1 replaces uses of v2 with v1 starting at r and returns 1 if // copy1 replaces uses of v2 with v1 starting at r and returns 1 if
// all uses were rewritten. // all uses were rewritten.
func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool { func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f bool) bool {
if uint32(r.Active) == gactive { if uint32(r.Active) == gactive {
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("act set; return 1\n") fmt.Printf("act set; return 1\n")
...@@ -315,27 +315,24 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool { ...@@ -315,27 +315,24 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool {
r.Active = int32(gactive) r.Active = int32(gactive)
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("copy1 replace %v with %v f=%d\n", gc.Ctxt.Dconv(v2), gc.Ctxt.Dconv(v1), f) fmt.Printf("copy1 replace %v with %v f=%v\n", gc.Ctxt.Dconv(v2), gc.Ctxt.Dconv(v1), f)
} }
var t int
var p *obj.Prog
for ; r != nil; r = r.S1 { for ; r != nil; r = r.S1 {
p = r.Prog p := r.Prog
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("%v", p) fmt.Printf("%v", p)
} }
if f == 0 && gc.Uniqp(r) == nil { if !f && gc.Uniqp(r) == nil {
// Multiple predecessors; conservatively // Multiple predecessors; conservatively
// assume v1 was set on other path // assume v1 was set on other path
f = 1 f = true
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("; merge; f=%d", f) fmt.Printf("; merge; f=%v", f)
} }
} }
t = copyu(p, v2, nil) switch t := copyu(p, v2, nil); t {
switch t {
case 2: /* rar, can't split */ case 2: /* rar, can't split */
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("; %v rar; return 0\n", gc.Ctxt.Dconv(v2)) fmt.Printf("; %v rar; return 0\n", gc.Ctxt.Dconv(v2))
...@@ -350,14 +347,14 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool { ...@@ -350,14 +347,14 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool {
case 1, /* used, substitute */ case 1, /* used, substitute */
4: /* use and set */ 4: /* use and set */
if f != 0 { if f {
if gc.Debug['P'] == 0 { if gc.Debug['P'] == 0 {
return false return false
} }
if t == 4 { if t == 4 {
fmt.Printf("; %v used+set and f=%d; return 0\n", gc.Ctxt.Dconv(v2), f) fmt.Printf("; %v used+set and f=%v; return 0\n", gc.Ctxt.Dconv(v2), f)
} else { } else {
fmt.Printf("; %v used and f=%d; return 0\n", gc.Ctxt.Dconv(v2), f) fmt.Printf("; %v used and f=%v; return 0\n", gc.Ctxt.Dconv(v2), f)
} }
return false return false
} }
...@@ -380,12 +377,12 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool { ...@@ -380,12 +377,12 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool {
} }
} }
if f == 0 { if !f {
t = copyu(p, v1, nil) t := copyu(p, v1, nil)
if f == 0 && (t == 2 || t == 3 || t == 4) { if t == 2 || t == 3 || t == 4 {
f = 1 f = true
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("; %v set and !f; f=%d", gc.Ctxt.Dconv(v1), f) fmt.Printf("; %v set and !f; f=%v", gc.Ctxt.Dconv(v1), f)
} }
} }
} }
...@@ -399,7 +396,6 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool { ...@@ -399,7 +396,6 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool {
} }
} }
} }
return true return true
} }
...@@ -464,13 +460,13 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int { ...@@ -464,13 +460,13 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
arm64.AFMOVD: arm64.AFMOVD:
if p.Scond == 0 { if p.Scond == 0 {
if s != nil { if s != nil {
if copysub(&p.From, v, s, 1) != 0 { if copysub(&p.From, v, s, true) {
return 1 return 1
} }
// Update only indirect uses of v in p->to // Update only indirect uses of v in p->to
if !copyas(&p.To, v) { if !copyas(&p.To, v) {
if copysub(&p.To, v, s, 1) != 0 { if copysub(&p.To, v, s, true) {
return 1 return 1
} }
} }
...@@ -508,7 +504,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int { ...@@ -508,7 +504,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
} }
if s != nil { if s != nil {
if copysub(&p.To, v, s, 1) != 0 { if copysub(&p.To, v, s, true) {
return 1 return 1
} }
return 0 return 0
...@@ -522,7 +518,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int { ...@@ -522,7 +518,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
return 2 return 2
} }
if s != nil { if s != nil {
if copysub(&p.From, v, s, 1) != 0 { if copysub(&p.From, v, s, true) {
return 1 return 1
} }
return 0 return 0
...@@ -561,16 +557,16 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int { ...@@ -561,16 +557,16 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
arm64.AFDIVD, arm64.AFDIVD,
arm64.AFDIVS: arm64.AFDIVS:
if s != nil { if s != nil {
if copysub(&p.From, v, s, 1) != 0 { if copysub(&p.From, v, s, true) {
return 1 return 1
} }
if copysub1(p, v, s, 1) != 0 { if copysub1(p, v, s, true) {
return 1 return 1
} }
// Update only indirect uses of v in p->to // Update only indirect uses of v in p->to
if !copyas(&p.To, v) { if !copyas(&p.To, v) {
if copysub(&p.To, v, s, 1) != 0 { if copysub(&p.To, v, s, true) {
return 1 return 1
} }
} }
...@@ -622,10 +618,13 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int { ...@@ -622,10 +618,13 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
arm64.AFCMPD, arm64.AFCMPD,
arm64.AFCMPS: arm64.AFCMPS:
if s != nil { if s != nil {
if copysub(&p.From, v, s, 1) != 0 { if copysub(&p.From, v, s, true) {
return 1
}
if copysub1(p, v, s, true) {
return 1 return 1
} }
return copysub1(p, v, s, 1) return 0
} }
if copyau(&p.From, v) { if copyau(&p.From, v) {
...@@ -638,7 +637,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int { ...@@ -638,7 +637,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
case arm64.AB: /* read p->to */ case arm64.AB: /* read p->to */
if s != nil { if s != nil {
if copysub(&p.To, v, s, 1) != 0 { if copysub(&p.To, v, s, true) {
return 1 return 1
} }
return 0 return 0
...@@ -664,7 +663,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int { ...@@ -664,7 +663,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
} }
if s != nil { if s != nil {
if copysub(&p.To, v, s, 1) != 0 { if copysub(&p.To, v, s, true) {
return 1 return 1
} }
return 0 return 0
...@@ -715,23 +714,16 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int { ...@@ -715,23 +714,16 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
} }
} }
// copyas returns 1 if a and v address the same register. // copyas returns true if a and v address the same register.
// //
// If a is the from operand, this means this operation reads the // If a is the from operand, this means this operation reads the
// register in v. If a is the to operand, this means this operation // register in v. If a is the to operand, this means this operation
// writes the register in v. // writes the register in v.
func copyas(a *obj.Addr, v *obj.Addr) bool { func copyas(a *obj.Addr, v *obj.Addr) bool {
if regtyp(v) { return regtyp(v) && a.Type == v.Type && a.Reg == v.Reg
if a.Type == v.Type {
if a.Reg == v.Reg {
return true
}
}
}
return false
} }
// copyau returns 1 if a either directly or indirectly addresses the // copyau returns true if a either directly or indirectly addresses the
// same register as v. // same register as v.
// //
// If a is the from operand, this means this operation reads the // If a is the from operand, this means this operation reads the
...@@ -752,37 +744,30 @@ func copyau(a *obj.Addr, v *obj.Addr) bool { ...@@ -752,37 +744,30 @@ func copyau(a *obj.Addr, v *obj.Addr) bool {
return false return false
} }
// copyau1 returns 1 if p->reg references the same register as v and v // copyau1 returns true if p->reg references the same register as v and v
// is a direct reference. // is a direct reference.
func copyau1(p *obj.Prog, v *obj.Addr) bool { func copyau1(p *obj.Prog, v *obj.Addr) bool {
if regtyp(v) && v.Reg != 0 { return regtyp(v) && v.Reg != 0 && p.Reg == v.Reg
if p.Reg == v.Reg {
return true
}
}
return false
} }
// copysub replaces v with s in a if f!=0 or indicates it if could if f==0. // copysub replaces v with s in a if f==true or indicates it if could if f==false.
// Returns 1 on failure to substitute (it always succeeds on arm64). // Returns true on failure to substitute (it always succeeds on arm64).
func copysub(a *obj.Addr, v *obj.Addr, s *obj.Addr, f int) int { // TODO(dfc) remove unused return value, remove calls with f=false as they do nothing.
if f != 0 { func copysub(a *obj.Addr, v *obj.Addr, s *obj.Addr, f bool) bool {
if copyau(a, v) { if f && copyau(a, v) {
a.Reg = s.Reg a.Reg = s.Reg
} }
} return false
return 0
} }
// copysub1 replaces v with s in p1->reg if f!=0 or indicates if it could if f==0. // copysub1 replaces v with s in p1->reg if f==true or indicates if it could if f==false.
// Returns 1 on failure to substitute (it always succeeds on arm64). // Returns true on failure to substitute (it always succeeds on arm64).
func copysub1(p1 *obj.Prog, v *obj.Addr, s *obj.Addr, f int) int { // TODO(dfc) remove unused return value, remove calls with f=false as they do nothing.
if f != 0 { func copysub1(p1 *obj.Prog, v *obj.Addr, s *obj.Addr, f bool) bool {
if copyau1(p1, v) { if f && copyau1(p1, v) {
p1.Reg = s.Reg p1.Reg = s.Reg
} }
} return false
return 0
} }
func sameaddr(a *obj.Addr, v *obj.Addr) bool { func sameaddr(a *obj.Addr, v *obj.Addr) bool {
......
...@@ -81,7 +81,7 @@ loop1: ...@@ -81,7 +81,7 @@ loop1:
// Convert uses to $0 to uses of R0 and // Convert uses to $0 to uses of R0 and
// propagate R0 // propagate R0
if regzer(&p.From) != 0 { if regzer(&p.From) {
if p.To.Type == obj.TYPE_REG && !isfreg(&p.To) { if p.To.Type == obj.TYPE_REG && !isfreg(&p.To) {
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = mips.REGZERO p.From.Reg = mips.REGZERO
...@@ -153,23 +153,16 @@ func excise(r *gc.Flow) { ...@@ -153,23 +153,16 @@ func excise(r *gc.Flow) {
gc.Ostats.Ndelmov++ gc.Ostats.Ndelmov++
} }
/* // regzer returns true if a's value is 0 (a is R0 or $0)
* regzer returns 1 if a's value is 0 (a is R0 or $0) func regzer(a *obj.Addr) bool {
*/
func regzer(a *obj.Addr) int {
if a.Type == obj.TYPE_CONST || a.Type == obj.TYPE_ADDR { if a.Type == obj.TYPE_CONST || a.Type == obj.TYPE_ADDR {
if a.Sym == nil && a.Reg == 0 { if a.Sym == nil && a.Reg == 0 {
if a.Offset == 0 { if a.Offset == 0 {
return 1 return true
}
}
} }
if a.Type == obj.TYPE_REG {
if a.Reg == mips.REGZERO {
return 1
} }
} }
return 0 return a.Type == obj.TYPE_REG && a.Reg == mips.REGZERO
} }
func regtyp(a *obj.Addr) bool { func regtyp(a *obj.Addr) bool {
...@@ -223,7 +216,7 @@ func subprop(r0 *gc.Flow) bool { ...@@ -223,7 +216,7 @@ func subprop(r0 *gc.Flow) bool {
if p.Info.Flags&(gc.RightRead|gc.RightWrite) == gc.RightWrite { if p.Info.Flags&(gc.RightRead|gc.RightWrite) == gc.RightWrite {
if p.To.Type == v1.Type { if p.To.Type == v1.Type {
if p.To.Reg == v1.Reg { if p.To.Reg == v1.Reg {
copysub(&p.To, v1, v2, 1) copysub(&p.To, v1, v2, true)
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("gotit: %v->%v\n%v", gc.Ctxt.Dconv(v1), gc.Ctxt.Dconv(v2), r.Prog) fmt.Printf("gotit: %v->%v\n%v", gc.Ctxt.Dconv(v1), gc.Ctxt.Dconv(v2), r.Prog)
if p.From.Type == v2.Type { if p.From.Type == v2.Type {
...@@ -234,9 +227,9 @@ func subprop(r0 *gc.Flow) bool { ...@@ -234,9 +227,9 @@ func subprop(r0 *gc.Flow) bool {
for r = gc.Uniqs(r); r != r0; r = gc.Uniqs(r) { for r = gc.Uniqs(r); r != r0; r = gc.Uniqs(r) {
p = r.Prog p = r.Prog
copysub(&p.From, v1, v2, 1) copysub(&p.From, v1, v2, true)
copysub1(p, v1, v2, 1) copysub1(p, v1, v2, true)
copysub(&p.To, v1, v2, 1) copysub(&p.To, v1, v2, true)
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("%v\n", r.Prog) fmt.Printf("%v\n", r.Prog)
} }
...@@ -254,7 +247,7 @@ func subprop(r0 *gc.Flow) bool { ...@@ -254,7 +247,7 @@ func subprop(r0 *gc.Flow) bool {
if copyau(&p.From, v2) || copyau1(p, v2) || copyau(&p.To, v2) { if copyau(&p.From, v2) || copyau1(p, v2) || copyau(&p.To, v2) {
break break
} }
if copysub(&p.From, v1, v2, 0) != 0 || copysub1(p, v1, v2, 0) != 0 || copysub(&p.To, v1, v2, 0) != 0 { if copysub(&p.From, v1, v2, false) || copysub1(p, v1, v2, false) || copysub(&p.To, v1, v2, false) {
break break
} }
} }
...@@ -289,12 +282,12 @@ func copyprop(r0 *gc.Flow) bool { ...@@ -289,12 +282,12 @@ func copyprop(r0 *gc.Flow) bool {
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("trying to eliminate %v->%v move from:\n%v\n", gc.Ctxt.Dconv(v1), gc.Ctxt.Dconv(v2), r0.Prog) fmt.Printf("trying to eliminate %v->%v move from:\n%v\n", gc.Ctxt.Dconv(v1), gc.Ctxt.Dconv(v2), r0.Prog)
} }
return copy1(v1, v2, r0.S1, 0) return copy1(v1, v2, r0.S1, false)
} }
// copy1 replaces uses of v2 with v1 starting at r and returns 1 if // copy1 replaces uses of v2 with v1 starting at r and returns true if
// all uses were rewritten. // all uses were rewritten.
func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool { func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f bool) bool {
if uint32(r.Active) == gactive { if uint32(r.Active) == gactive {
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("act set; return 1\n") fmt.Printf("act set; return 1\n")
...@@ -304,27 +297,24 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool { ...@@ -304,27 +297,24 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool {
r.Active = int32(gactive) r.Active = int32(gactive)
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("copy1 replace %v with %v f=%d\n", gc.Ctxt.Dconv(v2), gc.Ctxt.Dconv(v1), f) fmt.Printf("copy1 replace %v with %v f=%v\n", gc.Ctxt.Dconv(v2), gc.Ctxt.Dconv(v1), f)
} }
var t int
var p *obj.Prog
for ; r != nil; r = r.S1 { for ; r != nil; r = r.S1 {
p = r.Prog p := r.Prog
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("%v", p) fmt.Printf("%v", p)
} }
if f == 0 && gc.Uniqp(r) == nil { if !f && gc.Uniqp(r) == nil {
// Multiple predecessors; conservatively // Multiple predecessors; conservatively
// assume v1 was set on other path // assume v1 was set on other path
f = 1 f = true
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("; merge; f=%d", f) fmt.Printf("; merge; f=%v", f)
} }
} }
t = copyu(p, v2, nil) switch t := copyu(p, v2, nil); t {
switch t {
case 2: /* rar, can't split */ case 2: /* rar, can't split */
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("; %v rar; return 0\n", gc.Ctxt.Dconv(v2)) fmt.Printf("; %v rar; return 0\n", gc.Ctxt.Dconv(v2))
...@@ -339,14 +329,14 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool { ...@@ -339,14 +329,14 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool {
case 1, /* used, substitute */ case 1, /* used, substitute */
4: /* use and set */ 4: /* use and set */
if f != 0 { if f {
if gc.Debug['P'] == 0 { if gc.Debug['P'] == 0 {
return false return false
} }
if t == 4 { if t == 4 {
fmt.Printf("; %v used+set and f=%d; return 0\n", gc.Ctxt.Dconv(v2), f) fmt.Printf("; %v used+set and f=%v; return 0\n", gc.Ctxt.Dconv(v2), f)
} else { } else {
fmt.Printf("; %v used and f=%d; return 0\n", gc.Ctxt.Dconv(v2), f) fmt.Printf("; %v used and f=%v; return 0\n", gc.Ctxt.Dconv(v2), f)
} }
return false return false
} }
...@@ -369,12 +359,12 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool { ...@@ -369,12 +359,12 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool {
} }
} }
if f == 0 { if !f {
t = copyu(p, v1, nil) t := copyu(p, v1, nil)
if f == 0 && (t == 2 || t == 3 || t == 4) { if t == 2 || t == 3 || t == 4 {
f = 1 f = true
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("; %v set and !f; f=%d", gc.Ctxt.Dconv(v1), f) fmt.Printf("; %v set and !f; f=%v", gc.Ctxt.Dconv(v1), f)
} }
} }
} }
...@@ -440,13 +430,13 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int { ...@@ -440,13 +430,13 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
mips.ATRUNCFW, mips.ATRUNCFW,
mips.ATRUNCDW: mips.ATRUNCDW:
if s != nil { if s != nil {
if copysub(&p.From, v, s, 1) != 0 { if copysub(&p.From, v, s, true) {
return 1 return 1
} }
// Update only indirect uses of v in p->to // Update only indirect uses of v in p->to
if !copyas(&p.To, v) { if !copyas(&p.To, v) {
if copysub(&p.To, v, s, 1) != 0 { if copysub(&p.To, v, s, true) {
return 1 return 1
} }
} }
...@@ -506,16 +496,16 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int { ...@@ -506,16 +496,16 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
mips.ADIVF, mips.ADIVF,
mips.ADIVD: mips.ADIVD:
if s != nil { if s != nil {
if copysub(&p.From, v, s, 1) != 0 { if copysub(&p.From, v, s, true) {
return 1 return 1
} }
if copysub1(p, v, s, 1) != 0 { if copysub1(p, v, s, true) {
return 1 return 1
} }
// Update only indirect uses of v in p->to // Update only indirect uses of v in p->to
if !copyas(&p.To, v) { if !copyas(&p.To, v) {
if copysub(&p.To, v, s, 1) != 0 { if copysub(&p.To, v, s, true) {
return 1 return 1
} }
} }
...@@ -576,10 +566,13 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int { ...@@ -576,10 +566,13 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
mips.ADIVV, mips.ADIVV,
mips.ADIVVU: mips.ADIVVU:
if s != nil { if s != nil {
if copysub(&p.From, v, s, 1) != 0 { if copysub(&p.From, v, s, true) {
return 1 return 1
} }
return copysub1(p, v, s, 1) if copysub1(p, v, s, true) {
return 1
}
return 0
} }
if copyau(&p.From, v) { if copyau(&p.From, v) {
...@@ -592,7 +585,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int { ...@@ -592,7 +585,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
case mips.AJMP: /* read p->to */ case mips.AJMP: /* read p->to */
if s != nil { if s != nil {
if copysub(&p.To, v, s, 1) != 0 { if copysub(&p.To, v, s, true) {
return 1 return 1
} }
return 0 return 0
...@@ -635,7 +628,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int { ...@@ -635,7 +628,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
} }
if s != nil { if s != nil {
if copysub(&p.To, v, s, 1) != 0 { if copysub(&p.To, v, s, true) {
return 1 return 1
} }
return 0 return 0
...@@ -729,37 +722,30 @@ func copyau(a *obj.Addr, v *obj.Addr) bool { ...@@ -729,37 +722,30 @@ func copyau(a *obj.Addr, v *obj.Addr) bool {
return false return false
} }
// copyau1 returns 1 if p->reg references the same register as v and v // copyau1 returns true if p->reg references the same register as v and v
// is a direct reference. // is a direct reference.
func copyau1(p *obj.Prog, v *obj.Addr) bool { func copyau1(p *obj.Prog, v *obj.Addr) bool {
if regtyp(v) && v.Reg != 0 { return regtyp(v) && v.Reg != 0 && p.Reg == v.Reg
if p.Reg == v.Reg {
return true
}
}
return false
} }
// copysub replaces v with s in a if f!=0 or indicates it if could if f==0. // copysub replaces v with s in a if f==true or indicates it if could if f==false.
// Returns 1 on failure to substitute (it always succeeds on mips). // Returns true on failure to substitute (it always succeeds on mips).
func copysub(a *obj.Addr, v *obj.Addr, s *obj.Addr, f int) int { // TODO(dfc) remove unused return value, remove calls with f=false as they do nothing.
if f != 0 { func copysub(a *obj.Addr, v *obj.Addr, s *obj.Addr, f bool) bool {
if copyau(a, v) { if f && copyau(a, v) {
a.Reg = s.Reg a.Reg = s.Reg
} }
} return false
return 0
} }
// copysub1 replaces v with s in p1->reg if f!=0 or indicates if it could if f==0. // copysub1 replaces v with s in p1->reg if f==true or indicates if it could if f==false.
// Returns 1 on failure to substitute (it always succeeds on mips). // Returns true on failure to substitute (it always succeeds on mips).
func copysub1(p1 *obj.Prog, v *obj.Addr, s *obj.Addr, f int) int { // TODO(dfc) remove unused return value, remove calls with f=false as they do nothing.
if f != 0 { func copysub1(p1 *obj.Prog, v *obj.Addr, s *obj.Addr, f bool) bool {
if copyau1(p1, v) { if f && copyau1(p1, v) {
p1.Reg = s.Reg p1.Reg = s.Reg
} }
} return false
return 0
} }
func sameaddr(a *obj.Addr, v *obj.Addr) bool { func sameaddr(a *obj.Addr, v *obj.Addr) bool {
......
...@@ -81,7 +81,7 @@ loop1: ...@@ -81,7 +81,7 @@ loop1:
// Convert uses to $0 to uses of R0 and // Convert uses to $0 to uses of R0 and
// propagate R0 // propagate R0
if regzer(&p.From) != 0 { if regzer(&p.From) {
if p.To.Type == obj.TYPE_REG { if p.To.Type == obj.TYPE_REG {
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = ppc64.REGZERO p.From.Reg = ppc64.REGZERO
...@@ -154,7 +154,7 @@ loop1: ...@@ -154,7 +154,7 @@ loop1:
switch p.As { switch p.As {
case ppc64.ACMP, case ppc64.ACMP,
ppc64.ACMPW: /* always safe? */ ppc64.ACMPW: /* always safe? */
if regzer(&p.To) == 0 { if !regzer(&p.To) {
continue continue
} }
r1 = r.S1 r1 = r.S1
...@@ -356,23 +356,16 @@ func excise(r *gc.Flow) { ...@@ -356,23 +356,16 @@ func excise(r *gc.Flow) {
gc.Ostats.Ndelmov++ gc.Ostats.Ndelmov++
} }
/* // regzer returns true if a's value is 0 (a is R0 or $0)
* regzer returns 1 if a's value is 0 (a is R0 or $0) func regzer(a *obj.Addr) bool {
*/
func regzer(a *obj.Addr) int {
if a.Type == obj.TYPE_CONST || a.Type == obj.TYPE_ADDR { if a.Type == obj.TYPE_CONST || a.Type == obj.TYPE_ADDR {
if a.Sym == nil && a.Reg == 0 { if a.Sym == nil && a.Reg == 0 {
if a.Offset == 0 { if a.Offset == 0 {
return 1 return true
}
}
} }
if a.Type == obj.TYPE_REG {
if a.Reg == ppc64.REGZERO {
return 1
} }
} }
return 0 return a.Type == obj.TYPE_REG && a.Reg == ppc64.REGZERO
} }
func regtyp(a *obj.Addr) bool { func regtyp(a *obj.Addr) bool {
...@@ -422,7 +415,7 @@ func subprop(r0 *gc.Flow) bool { ...@@ -422,7 +415,7 @@ func subprop(r0 *gc.Flow) bool {
if p.Info.Flags&(gc.RightRead|gc.RightWrite) == gc.RightWrite { if p.Info.Flags&(gc.RightRead|gc.RightWrite) == gc.RightWrite {
if p.To.Type == v1.Type { if p.To.Type == v1.Type {
if p.To.Reg == v1.Reg { if p.To.Reg == v1.Reg {
copysub(&p.To, v1, v2, 1) copysub(&p.To, v1, v2, true)
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("gotit: %v->%v\n%v", gc.Ctxt.Dconv(v1), gc.Ctxt.Dconv(v2), r.Prog) fmt.Printf("gotit: %v->%v\n%v", gc.Ctxt.Dconv(v1), gc.Ctxt.Dconv(v2), r.Prog)
if p.From.Type == v2.Type { if p.From.Type == v2.Type {
...@@ -433,9 +426,9 @@ func subprop(r0 *gc.Flow) bool { ...@@ -433,9 +426,9 @@ func subprop(r0 *gc.Flow) bool {
for r = gc.Uniqs(r); r != r0; r = gc.Uniqs(r) { for r = gc.Uniqs(r); r != r0; r = gc.Uniqs(r) {
p = r.Prog p = r.Prog
copysub(&p.From, v1, v2, 1) copysub(&p.From, v1, v2, true)
copysub1(p, v1, v2, 1) copysub1(p, v1, v2, true)
copysub(&p.To, v1, v2, 1) copysub(&p.To, v1, v2, true)
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("%v\n", r.Prog) fmt.Printf("%v\n", r.Prog)
} }
...@@ -453,7 +446,7 @@ func subprop(r0 *gc.Flow) bool { ...@@ -453,7 +446,7 @@ func subprop(r0 *gc.Flow) bool {
if copyau(&p.From, v2) || copyau1(p, v2) || copyau(&p.To, v2) { if copyau(&p.From, v2) || copyau1(p, v2) || copyau(&p.To, v2) {
break break
} }
if copysub(&p.From, v1, v2, 0) != 0 || copysub1(p, v1, v2, 0) != 0 || copysub(&p.To, v1, v2, 0) != 0 { if copysub(&p.From, v1, v2, false) || copysub1(p, v1, v2, false) || copysub(&p.To, v1, v2, false) {
break break
} }
} }
...@@ -488,12 +481,12 @@ func copyprop(r0 *gc.Flow) bool { ...@@ -488,12 +481,12 @@ func copyprop(r0 *gc.Flow) bool {
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("trying to eliminate %v->%v move from:\n%v\n", gc.Ctxt.Dconv(v1), gc.Ctxt.Dconv(v2), r0.Prog) fmt.Printf("trying to eliminate %v->%v move from:\n%v\n", gc.Ctxt.Dconv(v1), gc.Ctxt.Dconv(v2), r0.Prog)
} }
return copy1(v1, v2, r0.S1, 0) return copy1(v1, v2, r0.S1, false)
} }
// copy1 replaces uses of v2 with v1 starting at r and returns 1 if // copy1 replaces uses of v2 with v1 starting at r and returns 1 if
// all uses were rewritten. // all uses were rewritten.
func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool { func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f bool) bool {
if uint32(r.Active) == gactive { if uint32(r.Active) == gactive {
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("act set; return 1\n") fmt.Printf("act set; return 1\n")
...@@ -503,27 +496,24 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool { ...@@ -503,27 +496,24 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool {
r.Active = int32(gactive) r.Active = int32(gactive)
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("copy1 replace %v with %v f=%d\n", gc.Ctxt.Dconv(v2), gc.Ctxt.Dconv(v1), f) fmt.Printf("copy1 replace %v with %v f=%v\n", gc.Ctxt.Dconv(v2), gc.Ctxt.Dconv(v1), f)
} }
var t int
var p *obj.Prog
for ; r != nil; r = r.S1 { for ; r != nil; r = r.S1 {
p = r.Prog p := r.Prog
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("%v", p) fmt.Printf("%v", p)
} }
if f == 0 && gc.Uniqp(r) == nil { if !f && gc.Uniqp(r) == nil {
// Multiple predecessors; conservatively // Multiple predecessors; conservatively
// assume v1 was set on other path // assume v1 was set on other path
f = 1 f = true
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("; merge; f=%d", f) fmt.Printf("; merge; f=%v", f)
} }
} }
t = copyu(p, v2, nil) switch t := copyu(p, v2, nil); t {
switch t {
case 2: /* rar, can't split */ case 2: /* rar, can't split */
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("; %v rar; return 0\n", gc.Ctxt.Dconv(v2)) fmt.Printf("; %v rar; return 0\n", gc.Ctxt.Dconv(v2))
...@@ -538,14 +528,14 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool { ...@@ -538,14 +528,14 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool {
case 1, /* used, substitute */ case 1, /* used, substitute */
4: /* use and set */ 4: /* use and set */
if f != 0 { if f {
if gc.Debug['P'] == 0 { if gc.Debug['P'] == 0 {
return false return false
} }
if t == 4 { if t == 4 {
fmt.Printf("; %v used+set and f=%d; return 0\n", gc.Ctxt.Dconv(v2), f) fmt.Printf("; %v used+set and f=%v; return 0\n", gc.Ctxt.Dconv(v2), f)
} else { } else {
fmt.Printf("; %v used and f=%d; return 0\n", gc.Ctxt.Dconv(v2), f) fmt.Printf("; %v used and f=%v; return 0\n", gc.Ctxt.Dconv(v2), f)
} }
return false return false
} }
...@@ -568,12 +558,12 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool { ...@@ -568,12 +558,12 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool {
} }
} }
if f == 0 { if !f {
t = copyu(p, v1, nil) t := copyu(p, v1, nil)
if f == 0 && (t == 2 || t == 3 || t == 4) { if t == 2 || t == 3 || t == 4 {
f = 1 f = true
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("; %v set and !f; f=%d", gc.Ctxt.Dconv(v1), f) fmt.Printf("; %v set and !f; f=%v", gc.Ctxt.Dconv(v1), f)
} }
} }
} }
...@@ -644,13 +634,13 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int { ...@@ -644,13 +634,13 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
ppc64.AFNEG, ppc64.AFNEG,
ppc64.AFNEGCC: ppc64.AFNEGCC:
if s != nil { if s != nil {
if copysub(&p.From, v, s, 1) != 0 { if copysub(&p.From, v, s, true) {
return 1 return 1
} }
// Update only indirect uses of v in p->to // Update only indirect uses of v in p->to
if !copyas(&p.To, v) { if !copyas(&p.To, v) {
if copysub(&p.To, v, s, 1) != 0 { if copysub(&p.To, v, s, true) {
return 1 return 1
} }
} }
...@@ -692,7 +682,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int { ...@@ -692,7 +682,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
} }
if s != nil { if s != nil {
if copysub(&p.To, v, s, 1) != 0 { if copysub(&p.To, v, s, true) {
return 1 return 1
} }
return 0 return 0
...@@ -706,7 +696,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int { ...@@ -706,7 +696,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
return 2 return 2
} }
if s != nil { if s != nil {
if copysub(&p.From, v, s, 1) != 0 { if copysub(&p.From, v, s, true) {
return 1 return 1
} }
return 0 return 0
...@@ -776,16 +766,16 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int { ...@@ -776,16 +766,16 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
ppc64.AFDIVS, ppc64.AFDIVS,
ppc64.AFDIV: ppc64.AFDIV:
if s != nil { if s != nil {
if copysub(&p.From, v, s, 1) != 0 { if copysub(&p.From, v, s, true) {
return 1 return 1
} }
if copysub1(p, v, s, 1) != 0 { if copysub1(p, v, s, true) {
return 1 return 1
} }
// Update only indirect uses of v in p->to // Update only indirect uses of v in p->to
if !copyas(&p.To, v) { if !copyas(&p.To, v) {
if copysub(&p.To, v, s, 1) != 0 { if copysub(&p.To, v, s, true) {
return 1 return 1
} }
} }
...@@ -838,10 +828,13 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int { ...@@ -838,10 +828,13 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
ppc64.AFCMPO, ppc64.AFCMPO,
ppc64.AFCMPU: ppc64.AFCMPU:
if s != nil { if s != nil {
if copysub(&p.From, v, s, 1) != 0 { if copysub(&p.From, v, s, true) {
return 1 return 1
} }
return copysub(&p.To, v, s, 1) if copysub(&p.To, v, s, true) {
return 1
}
return 0
} }
if copyau(&p.From, v) { if copyau(&p.From, v) {
...@@ -857,7 +850,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int { ...@@ -857,7 +850,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
// mov and a branch). // mov and a branch).
case ppc64.ABR: /* read p->to */ case ppc64.ABR: /* read p->to */
if s != nil { if s != nil {
if copysub(&p.To, v, s, 1) != 0 { if copysub(&p.To, v, s, true) {
return 1 return 1
} }
return 0 return 0
...@@ -900,12 +893,11 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int { ...@@ -900,12 +893,11 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
} }
if s != nil { if s != nil {
if copysub(&p.To, v, s, 1) != 0 { if copysub(&p.To, v, s, true) {
return 1 return 1
} }
return 0 return 0
} }
if copyau(&p.To, v) { if copyau(&p.To, v) {
return 4 return 4
} }
...@@ -957,23 +949,16 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int { ...@@ -957,23 +949,16 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
} }
} }
// copyas returns 1 if a and v address the same register. // copyas returns true if a and v address the same register.
// //
// If a is the from operand, this means this operation reads the // If a is the from operand, this means this operation reads the
// register in v. If a is the to operand, this means this operation // register in v. If a is the to operand, this means this operation
// writes the register in v. // writes the register in v.
func copyas(a *obj.Addr, v *obj.Addr) bool { func copyas(a *obj.Addr, v *obj.Addr) bool {
if regtyp(v) { return regtyp(v) && a.Type == v.Type && a.Reg == v.Reg
if a.Type == v.Type {
if a.Reg == v.Reg {
return true
}
}
}
return false
} }
// copyau returns 1 if a either directly or indirectly addresses the // copyau returns true if a either directly or indirectly addresses the
// same register as v. // same register as v.
// //
// If a is the from operand, this means this operation reads the // If a is the from operand, this means this operation reads the
...@@ -994,37 +979,30 @@ func copyau(a *obj.Addr, v *obj.Addr) bool { ...@@ -994,37 +979,30 @@ func copyau(a *obj.Addr, v *obj.Addr) bool {
return false return false
} }
// copyau1 returns 1 if p->reg references the same register as v and v // copyau1 returns true if p->reg references the same register as v and v
// is a direct reference. // is a direct reference.
func copyau1(p *obj.Prog, v *obj.Addr) bool { func copyau1(p *obj.Prog, v *obj.Addr) bool {
if regtyp(v) && v.Reg != 0 { return regtyp(v) && v.Reg != 0 && p.Reg == v.Reg
if p.Reg == v.Reg {
return true
}
}
return false
} }
// copysub replaces v with s in a if f!=0 or indicates it if could if f==0. // copysub replaces v with s in a if f==true or indicates it if could if f==false.
// Returns 1 on failure to substitute (it always succeeds on ppc64). // Returns true on failure to substitute (it always succeeds on ppc64).
func copysub(a *obj.Addr, v *obj.Addr, s *obj.Addr, f int) int { // TODO(dfc) remove unused return value and callers where f=false.
if f != 0 { func copysub(a *obj.Addr, v *obj.Addr, s *obj.Addr, f bool) bool {
if copyau(a, v) { if f && copyau(a, v) {
a.Reg = s.Reg a.Reg = s.Reg
} }
} return false
return 0
} }
// copysub1 replaces v with s in p1->reg if f!=0 or indicates if it could if f==0. // copysub1 replaces v with s in p1->reg if f==true or indicates if it could if f==false.
// Returns 1 on failure to substitute (it always succeeds on ppc64). // Returns true on failure to substitute (it always succeeds on ppc64).
func copysub1(p1 *obj.Prog, v *obj.Addr, s *obj.Addr, f int) int { // TODO(dfc) remove unused return value and callers where f=false.
if f != 0 { func copysub1(p1 *obj.Prog, v *obj.Addr, s *obj.Addr, f bool) bool {
if copyau1(p1, v) { if f && copyau1(p1, v) {
p1.Reg = s.Reg p1.Reg = s.Reg
} }
} return false
return 0
} }
func sameaddr(a *obj.Addr, v *obj.Addr) bool { func sameaddr(a *obj.Addr, v *obj.Addr) bool {
......
...@@ -387,7 +387,7 @@ func subprop(r0 *gc.Flow) bool { ...@@ -387,7 +387,7 @@ func subprop(r0 *gc.Flow) bool {
} }
if (p.Info.Flags&gc.Move != 0) && (p.Info.Flags&(gc.SizeL|gc.SizeQ|gc.SizeF|gc.SizeD) != 0) && p.To.Type == v1.Type && p.To.Reg == v1.Reg { if (p.Info.Flags&gc.Move != 0) && (p.Info.Flags&(gc.SizeL|gc.SizeQ|gc.SizeF|gc.SizeD) != 0) && p.To.Type == v1.Type && p.To.Reg == v1.Reg {
copysub(&p.To, v1, v2, 1) copysub(&p.To, v1, v2, true)
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("gotit: %v->%v\n%v", gc.Ctxt.Dconv(v1), gc.Ctxt.Dconv(v2), r.Prog) fmt.Printf("gotit: %v->%v\n%v", gc.Ctxt.Dconv(v1), gc.Ctxt.Dconv(v2), r.Prog)
if p.From.Type == v2.Type && p.From.Reg == v2.Reg { if p.From.Type == v2.Type && p.From.Reg == v2.Reg {
...@@ -398,8 +398,8 @@ func subprop(r0 *gc.Flow) bool { ...@@ -398,8 +398,8 @@ func subprop(r0 *gc.Flow) bool {
for r = gc.Uniqs(r); r != r0; r = gc.Uniqs(r) { for r = gc.Uniqs(r); r != r0; r = gc.Uniqs(r) {
p = r.Prog p = r.Prog
copysub(&p.From, v1, v2, 1) copysub(&p.From, v1, v2, true)
copysub(&p.To, v1, v2, 1) copysub(&p.To, v1, v2, true)
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("%v\n", r.Prog) fmt.Printf("%v\n", r.Prog)
} }
...@@ -417,7 +417,7 @@ func subprop(r0 *gc.Flow) bool { ...@@ -417,7 +417,7 @@ func subprop(r0 *gc.Flow) bool {
if copyau(&p.From, v2) || copyau(&p.To, v2) { if copyau(&p.From, v2) || copyau(&p.To, v2) {
break break
} }
if copysub(&p.From, v1, v2, 0) != 0 || copysub(&p.To, v1, v2, 0) != 0 { if copysub(&p.From, v1, v2, false) || copysub(&p.To, v1, v2, false) {
break break
} }
} }
...@@ -445,10 +445,10 @@ func copyprop(g *gc.Graph, r0 *gc.Flow) bool { ...@@ -445,10 +445,10 @@ func copyprop(g *gc.Graph, r0 *gc.Flow) bool {
return true return true
} }
gactive++ gactive++
return copy1(v1, v2, r0.S1, 0) return copy1(v1, v2, r0.S1, false)
} }
func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool { func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f bool) bool {
if uint32(r.Active) == gactive { if uint32(r.Active) == gactive {
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("act set; return 1\n") fmt.Printf("act set; return 1\n")
...@@ -458,24 +458,21 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool { ...@@ -458,24 +458,21 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool {
r.Active = int32(gactive) r.Active = int32(gactive)
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("copy %v->%v f=%d\n", gc.Ctxt.Dconv(v1), gc.Ctxt.Dconv(v2), f) fmt.Printf("copy %v->%v f=%v\n", gc.Ctxt.Dconv(v1), gc.Ctxt.Dconv(v2), f)
} }
var t int
var p *obj.Prog
for ; r != nil; r = r.S1 { for ; r != nil; r = r.S1 {
p = r.Prog p := r.Prog
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("%v", p) fmt.Printf("%v", p)
} }
if f == 0 && gc.Uniqp(r) == nil { if !f && gc.Uniqp(r) == nil {
f = 1 f = true
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("; merge; f=%d", f) fmt.Printf("; merge; f=%v", f)
} }
} }
t = copyu(p, v2, nil) switch t := copyu(p, v2, nil); t {
switch t {
case 2: /* rar, can't split */ case 2: /* rar, can't split */
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("; %v rar; return 0\n", gc.Ctxt.Dconv(v2)) fmt.Printf("; %v rar; return 0\n", gc.Ctxt.Dconv(v2))
...@@ -490,14 +487,14 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool { ...@@ -490,14 +487,14 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool {
case 1, /* used, substitute */ case 1, /* used, substitute */
4: /* use and set */ 4: /* use and set */
if f != 0 { if f {
if gc.Debug['P'] == 0 { if gc.Debug['P'] == 0 {
return false return false
} }
if t == 4 { if t == 4 {
fmt.Printf("; %v used+set and f=%d; return 0\n", gc.Ctxt.Dconv(v2), f) fmt.Printf("; %v used+set and f=%v; return 0\n", gc.Ctxt.Dconv(v2), f)
} else { } else {
fmt.Printf("; %v used and f=%d; return 0\n", gc.Ctxt.Dconv(v2), f) fmt.Printf("; %v used and f=%v; return 0\n", gc.Ctxt.Dconv(v2), f)
} }
return false return false
} }
...@@ -520,12 +517,12 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool { ...@@ -520,12 +517,12 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool {
} }
} }
if f == 0 { if !f {
t = copyu(p, v1, nil) t := copyu(p, v1, nil)
if f == 0 && (t == 2 || t == 3 || t == 4) { if t == 2 || t == 3 || t == 4 {
f = 1 f = true
if gc.Debug['P'] != 0 { if gc.Debug['P'] != 0 {
fmt.Printf("; %v set and !f; f=%d", gc.Ctxt.Dconv(v1), f) fmt.Printf("; %v set and !f; f=%v", gc.Ctxt.Dconv(v1), f)
} }
} }
} }
...@@ -539,7 +536,6 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool { ...@@ -539,7 +536,6 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool {
} }
} }
} }
return true return true
} }
...@@ -555,7 +551,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int { ...@@ -555,7 +551,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
switch p.As { switch p.As {
case obj.AJMP: case obj.AJMP:
if s != nil { if s != nil {
if copysub(&p.To, v, s, 1) != 0 { if copysub(&p.To, v, s, true) {
return 1 return 1
} }
return 0 return 0
...@@ -584,7 +580,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int { ...@@ -584,7 +580,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
} }
if s != nil { if s != nil {
if copysub(&p.To, v, s, 1) != 0 { if copysub(&p.To, v, s, true) {
return 1 return 1
} }
return 0 return 0
...@@ -625,7 +621,10 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int { ...@@ -625,7 +621,10 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
if p.Info.Flags&gc.RightWrite != 0 { if p.Info.Flags&gc.RightWrite != 0 {
if copyas(&p.To, v) { if copyas(&p.To, v) {
if s != nil { if s != nil {
return copysub(&p.From, v, s, 1) if copysub(&p.From, v, s, true) {
return 1
}
return 0
} }
if copyau(&p.From, v) { if copyau(&p.From, v) {
return 4 return 4
...@@ -636,12 +635,14 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int { ...@@ -636,12 +635,14 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
if p.Info.Flags&(gc.LeftAddr|gc.LeftRead|gc.LeftWrite|gc.RightAddr|gc.RightRead|gc.RightWrite) != 0 { if p.Info.Flags&(gc.LeftAddr|gc.LeftRead|gc.LeftWrite|gc.RightAddr|gc.RightRead|gc.RightWrite) != 0 {
if s != nil { if s != nil {
if copysub(&p.From, v, s, 1) != 0 { if copysub(&p.From, v, s, true) {
return 1 return 1
} }
return copysub(&p.To, v, s, 1) if copysub(&p.To, v, s, true) {
return 1
}
return 0
} }
if copyau(&p.From, v) { if copyau(&p.From, v) {
return 1 return 1
} }
...@@ -649,7 +650,6 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int { ...@@ -649,7 +650,6 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
return 1 return 1
} }
} }
return 0 return 0
} }
...@@ -714,50 +714,40 @@ func copyau(a *obj.Addr, v *obj.Addr) bool { ...@@ -714,50 +714,40 @@ func copyau(a *obj.Addr, v *obj.Addr) bool {
return false return false
} }
/* // copysub substitute s for v in a.
* substitute s for v in a // copysub returns true on failure to substitute.
* return failure to substitute // TODO(dfc) reverse this logic to return false on sunstitution failure.
*/ func copysub(a *obj.Addr, v *obj.Addr, s *obj.Addr, f bool) bool {
func copysub(a *obj.Addr, v *obj.Addr, s *obj.Addr, f int) int {
if copyas(a, v) { if copyas(a, v) {
reg := int(s.Reg) if s.Reg >= x86.REG_AX && s.Reg <= x86.REG_DI || s.Reg >= x86.REG_X0 && s.Reg <= x86.REG_X7 {
if reg >= x86.REG_AX && reg <= x86.REG_DI || reg >= x86.REG_X0 && reg <= x86.REG_X7 { if f {
if f != 0 { a.Reg = s.Reg
a.Reg = int16(reg)
} }
} }
return false
return 0
} }
if regtyp(v) { if regtyp(v) {
reg := int(v.Reg) if (a.Type == obj.TYPE_MEM || a.Type == obj.TYPE_ADDR) && a.Reg == v.Reg {
if (a.Type == obj.TYPE_MEM || a.Type == obj.TYPE_ADDR) && int(a.Reg) == reg {
if (s.Reg == x86.REG_BP) && a.Index != x86.REG_NONE { if (s.Reg == x86.REG_BP) && a.Index != x86.REG_NONE {
return 1 /* can't use BP-base with index */ return true /* can't use BP-base with index */
} }
if f != 0 { if f {
a.Reg = s.Reg a.Reg = s.Reg
} }
} }
// return 0; if a.Index == v.Reg {
if int(a.Index) == reg { if f {
if f != 0 {
a.Index = s.Reg a.Index = s.Reg
} }
return 0
} }
return 0
} }
return false
return 0
} }
func conprop(r0 *gc.Flow) { func conprop(r0 *gc.Flow) {
var p *obj.Prog var p *obj.Prog
var t int
p0 := r0.Prog p0 := r0.Prog
v0 := &p0.To v0 := &p0.To
...@@ -773,8 +763,7 @@ loop: ...@@ -773,8 +763,7 @@ loop:
} }
p = r.Prog p = r.Prog
t = copyu(p, v0, nil) switch copyu(p, v0, nil) {
switch t {
case 0, // miss case 0, // miss
1: // use 1: // use
goto loop goto loop
......
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