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: 's 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:
if p.As == x86.AMOVLQZX {
if regtyp(&p.From) {
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)
}
}
......@@ -505,10 +505,10 @@ func regconsttyp(a *obj.Addr) bool {
}
// 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) {
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)
if flags&gc.RightWrite != 0 {
if flags&gc.SizeL != 0 {
......@@ -518,7 +518,6 @@ func prevl(r0 *gc.Flow, reg int) bool {
}
}
}
return false
}
......@@ -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 {
copysub(&p.To, v1, v2, 1)
copysub(&p.To, v1, v2, true)
if gc.Debug['P'] != 0 {
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 {
......@@ -598,8 +597,8 @@ func subprop(r0 *gc.Flow) bool {
for r = gc.Uniqs(r); r != r0; r = gc.Uniqs(r) {
p = r.Prog
copysub(&p.From, v1, v2, 1)
copysub(&p.To, v1, v2, 1)
copysub(&p.From, v1, v2, true)
copysub(&p.To, v1, v2, true)
if gc.Debug['P'] != 0 {
fmt.Printf("%v\n", r.Prog)
}
......@@ -619,7 +618,7 @@ func subprop(r0 *gc.Flow) bool {
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 {
fmt.Printf("\tcopysub failed\n")
}
......@@ -656,10 +655,10 @@ func copyprop(g *gc.Graph, r0 *gc.Flow) bool {
return true
}
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 gc.Debug['P'] != 0 {
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 {
r.Active = int32(gactive)
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 {
p = r.Prog
p := r.Prog
if gc.Debug['P'] != 0 {
fmt.Printf("%v", p)
}
if f == 0 && gc.Uniqp(r) == nil {
f = 1
if !f && gc.Uniqp(r) == nil {
f = true
if gc.Debug['P'] != 0 {
fmt.Printf("; merge; f=%d", f)
fmt.Printf("; merge; f=%v", f)
}
}
t = copyu(p, v2, nil)
switch t {
switch t := copyu(p, v2, nil); t {
case 2: /* rar, can't split */
if gc.Debug['P'] != 0 {
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 {
case 1, /* used, substitute */
4: /* use and set */
if f != 0 {
if f {
if gc.Debug['P'] == 0 {
return false
}
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 {
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
}
......@@ -731,12 +727,12 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool {
}
}
if f == 0 {
t = copyu(p, v1, nil)
if f == 0 && (t == 2 || t == 3 || t == 4) {
f = 1
if !f {
t := copyu(p, v1, nil)
if t == 2 || t == 3 || t == 4 {
f = true
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 {
}
}
}
return true
}
......@@ -766,7 +761,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
switch p.As {
case obj.AJMP:
if s != nil {
if copysub(&p.To, v, s, 1) != 0 {
if copysub(&p.To, v, s, true) {
return 1
}
return 0
......@@ -795,7 +790,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
}
if s != nil {
if copysub(&p.To, v, s, 1) != 0 {
if copysub(&p.To, v, s, true) {
return 1
}
return 0
......@@ -840,7 +835,10 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
if p.Info.Flags&gc.RightWrite != 0 {
if copyas(&p.To, v) {
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) {
return 4
......@@ -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 s != nil {
if copysub(&p.From, v, s, 1) != 0 {
if copysub(&p.From, v, s, true) {
return 1
}
if copysub(&p.To, v, s, true) {
return 1
}
return copysub(&p.To, v, s, 1)
return 0
}
if copyau(&p.From, v) {
......@@ -864,7 +865,6 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
return 1
}
}
return 0
}
......@@ -936,48 +936,40 @@ func copyau(a *obj.Addr, v *obj.Addr) bool {
return true
}
}
return false
}
/*
* substitute s for v in a
* return failure to substitute
*/
func copysub(a *obj.Addr, v *obj.Addr, s *obj.Addr, f int) int {
// copysub substitute s for v in a.
// copysub returns true on failure to substitute. TODO(dfc) reverse this logic, copysub should return false on failure
func copysub(a *obj.Addr, v *obj.Addr, s *obj.Addr, f bool) bool {
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 f != 0 {
if f {
a.Reg = s.Reg
}
}
return 0
return false
}
if regtyp(v) {
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 {
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
}
}
if a.Index == v.Reg {
if f != 0 {
if f {
a.Index = s.Reg
}
return 0
}
return 0
}
return 0
return false
}
func conprop(r0 *gc.Flow) {
var p *obj.Prog
var t int
p0 := r0.Prog
v0 := &p0.To
r := r0
......@@ -991,8 +983,8 @@ loop:
return
}
p = r.Prog
t = copyu(p, v0, nil)
p := r.Prog
t := copyu(p, v0, nil)
switch t {
case 0, // miss
1: // use
......
......@@ -47,7 +47,6 @@ func peep(firstp *obj.Prog) {
}
gactive = 0
var r *gc.Flow
var p *obj.Prog
var t int
loop1:
......@@ -56,7 +55,7 @@ loop1:
}
t = 0
for r = g.Start; r != nil; r = r.Link {
for r := g.Start; r != nil; r = r.Link {
p = r.Prog
switch p.As {
/*
......@@ -289,7 +288,7 @@ func subprop(r0 *gc.Flow) bool {
if p.To.Type == v1.Type {
if p.To.Reg == v1.Reg {
if p.Scond == arm.C_SCOND_NONE {
copysub(&p.To, v1, v2, 1)
copysub(&p.To, v1, v2, true)
if gc.Debug['P'] != 0 {
fmt.Printf("gotit: %v->%v\n%v", gc.Ctxt.Dconv(v1), gc.Ctxt.Dconv(v2), r.Prog)
if p.From.Type == v2.Type {
......@@ -300,9 +299,9 @@ func subprop(r0 *gc.Flow) bool {
for r = gc.Uniqs(r); r != r0; r = gc.Uniqs(r) {
p = r.Prog
copysub(&p.From, v1, v2, 1)
copysub1(p, v1, v2, 1)
copysub(&p.To, v1, v2, 1)
copysub(&p.From, v1, v2, true)
copysub1(p, v1, v2, true)
copysub(&p.To, v1, v2, true)
if gc.Debug['P'] != 0 {
fmt.Printf("%v\n", r.Prog)
}
......@@ -321,7 +320,7 @@ func subprop(r0 *gc.Flow) bool {
if copyau(&p.From, v2) || copyau1(p, v2) || copyau(&p.To, v2) {
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
}
}
......@@ -349,10 +348,10 @@ func copyprop(g *gc.Graph, r0 *gc.Flow) bool {
return true
}
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 gc.Debug['P'] != 0 {
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 {
r.Active = int32(gactive)
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 {
p = r.Prog
p := r.Prog
if gc.Debug['P'] != 0 {
fmt.Printf("%v", p)
}
if f == 0 && gc.Uniqp(r) == nil {
f = 1
if !f && gc.Uniqp(r) == nil {
f = true
if gc.Debug['P'] != 0 {
fmt.Printf("; merge; f=%d", f)
fmt.Printf("; merge; f=%v", f)
}
}
t = copyu(p, v2, nil)
switch t {
switch t := copyu(p, v2, nil); t {
case 2: /* rar, can't split */
if gc.Debug['P'] != 0 {
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 {
case 1, /* used, substitute */
4: /* use and set */
if f != 0 {
if f {
if gc.Debug['P'] == 0 {
return false
}
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 {
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
}
......@@ -424,12 +420,12 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool {
}
}
if f == 0 {
t = copyu(p, v1, nil)
if f == 0 && (t == 2 || t == 3 || t == 4) {
f = 1
if !f {
t := copyu(p, v1, nil)
if t == 2 || t == 3 || t == 4 {
f = true
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 {
}
}
}
return true
}
......@@ -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 {
return 1
}
if copysub(&p.To, v, s, 1) != 0 {
if copysub(&p.To, v, s, true) {
return 1
}
return 0
......@@ -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 {
return 1
}
if copysub(&p.From, v, s, 1) != 0 {
if copysub(&p.From, v, s, true) {
return 1
}
return 0
......@@ -1129,11 +1124,11 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
}
if s != nil {
if copysub(&p.From, v, s, 1) != 0 {
if copysub(&p.From, v, s, true) {
return 1
}
if !copyas(&p.To, v) {
if copysub(&p.To, v, s, 1) != 0 {
if copysub(&p.To, v, s, true) {
return 1
}
}
......@@ -1198,14 +1193,14 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
arm.ATST:
/* read,, */
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, 1) != 0 {
if copysub1(p, v, s, true) {
return 1
}
if !copyas(&p.To, v) {
if copysub(&p.To, v, s, 1) != 0 {
if copysub(&p.To, v, s, true) {
return 1
}
}
......@@ -1256,10 +1251,13 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
arm.ABGT,
arm.ABLE:
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 copysub1(p, v, s, 1)
return 0
}
if copyau(&p.From, v) {
......@@ -1272,12 +1270,11 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
case arm.AB: /* funny */
if s != nil {
if copysub(&p.To, v, s, 1) != 0 {
if copysub(&p.To, v, s, true) {
return 1
}
return 0
}
if copyau(&p.To, v) {
return 1
}
......@@ -1312,7 +1309,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
}
if s != nil {
if copysub(&p.To, v, s, 1) != 0 {
if copysub(&p.To, v, s, true) {
return 1
}
return 0
......@@ -1323,7 +1320,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
}
return 3
// R0 is zero, used by DUFFZERO, cannot be substituted.
// R0 is zero, used by DUFFZERO, cannot be substituted.
// R1 is ptr to memory, used and set, cannot be substituted.
case obj.ADUFFZERO:
if v.Type == obj.TYPE_REG {
......@@ -1337,7 +1334,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
return 0
// R0 is scratch, set by DUFFCOPY, cannot be substituted.
// R0 is scratch, set by DUFFCOPY, cannot be substituted.
// R1, R2 areptr to src, dst, used and set, cannot be substituted.
case obj.ADUFFCOPY:
if v.Type == obj.TYPE_REG {
......@@ -1461,43 +1458,38 @@ func copyau1(p *obj.Prog, v *obj.Addr) bool {
return p.Reg == v.Reg
}
/*
* substitute s for v in a
* return failure to substitute
*/
func copysub(a *obj.Addr, v *obj.Addr, s *obj.Addr, f int) int {
if f != 0 {
if copyau(a, v) {
if a.Type == obj.TYPE_SHIFT {
if a.Offset&0xf == int64(v.Reg-arm.REG_R0) {
a.Offset = a.Offset&^0xf | int64(s.Reg)&0xf
}
if (a.Offset&(1<<4) != 0) && (a.Offset>>8)&0xf == int64(v.Reg-arm.REG_R0) {
a.Offset = a.Offset&^(0xf<<8) | (int64(s.Reg)&0xf)<<8
}
} else if a.Type == obj.TYPE_REGREG || a.Type == obj.TYPE_REGREG2 {
if a.Offset == int64(v.Reg) {
a.Offset = int64(s.Reg)
}
if a.Reg == v.Reg {
a.Reg = s.Reg
}
} else {
// copysub substitute s for v in a.
// copysub returns true on 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 {
if f && copyau(a, v) {
if a.Type == obj.TYPE_SHIFT {
if a.Offset&0xf == int64(v.Reg-arm.REG_R0) {
a.Offset = a.Offset&^0xf | int64(s.Reg)&0xf
}
if (a.Offset&(1<<4) != 0) && (a.Offset>>8)&0xf == int64(v.Reg-arm.REG_R0) {
a.Offset = a.Offset&^(0xf<<8) | (int64(s.Reg)&0xf)<<8
}
} else if a.Type == obj.TYPE_REGREG || a.Type == obj.TYPE_REGREG2 {
if a.Offset == int64(v.Reg) {
a.Offset = int64(s.Reg)
}
if a.Reg == v.Reg {
a.Reg = s.Reg
}
} else {
a.Reg = s.Reg
}
}
return 0
return false
}
func copysub1(p1 *obj.Prog, v *obj.Addr, s *obj.Addr, f int) int {
if f != 0 {
if copyau1(p1, v) {
p1.Reg = s.Reg
}
// TODO(dfc) remove unused return value, remove calls with f=false as they do nothing.
func copysub1(p1 *obj.Prog, v *obj.Addr, s *obj.Addr, f bool) bool {
if f && copyau1(p1, v) {
p1.Reg = s.Reg
}
return 0
return false
}
var predinfo = []struct {
......@@ -1650,9 +1642,8 @@ func joinsplit(r *gc.Flow, j *Joininfo) int {
func successor(r *gc.Flow) *gc.Flow {
if r.S1 != nil {
return r.S1
} else {
return r.S2
}
return r.S2
}
func applypred(rstart *gc.Flow, j *Joininfo, cond int, branch int) {
......
......@@ -234,7 +234,7 @@ func subprop(r0 *gc.Flow) bool {
if p.Info.Flags&(gc.RightRead|gc.RightWrite) == gc.RightWrite {
if p.To.Type == v1.Type {
if p.To.Reg == v1.Reg {
copysub(&p.To, v1, v2, 1)
copysub(&p.To, v1, v2, true)
if gc.Debug['P'] != 0 {
fmt.Printf("gotit: %v->%v\n%v", gc.Ctxt.Dconv(v1), gc.Ctxt.Dconv(v2), r.Prog)
if p.From.Type == v2.Type {
......@@ -245,9 +245,9 @@ func subprop(r0 *gc.Flow) bool {
for r = gc.Uniqs(r); r != r0; r = gc.Uniqs(r) {
p = r.Prog
copysub(&p.From, v1, v2, 1)
copysub1(p, v1, v2, 1)
copysub(&p.To, v1, v2, 1)
copysub(&p.From, v1, v2, true)
copysub1(p, v1, v2, true)
copysub(&p.To, v1, v2, true)
if gc.Debug['P'] != 0 {
fmt.Printf("%v\n", r.Prog)
}
......@@ -265,7 +265,7 @@ func subprop(r0 *gc.Flow) bool {
if copyau(&p.From, v2) || copyau1(p, v2) || copyau(&p.To, v2) {
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
}
}
......@@ -300,12 +300,12 @@ func copyprop(r0 *gc.Flow) bool {
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)
}
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
// 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 gc.Debug['P'] != 0 {
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 {
r.Active = int32(gactive)
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 {
p = r.Prog
p := r.Prog
if gc.Debug['P'] != 0 {
fmt.Printf("%v", p)
}
if f == 0 && gc.Uniqp(r) == nil {
if !f && gc.Uniqp(r) == nil {
// Multiple predecessors; conservatively
// assume v1 was set on other path
f = 1
f = true
if gc.Debug['P'] != 0 {
fmt.Printf("; merge; f=%d", f)
fmt.Printf("; merge; f=%v", f)
}
}
t = copyu(p, v2, nil)
switch t {
switch t := copyu(p, v2, nil); t {
case 2: /* rar, can't split */
if gc.Debug['P'] != 0 {
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 {
case 1, /* used, substitute */
4: /* use and set */
if f != 0 {
if f {
if gc.Debug['P'] == 0 {
return false
}
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 {
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
}
......@@ -380,12 +377,12 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool {
}
}
if f == 0 {
t = copyu(p, v1, nil)
if f == 0 && (t == 2 || t == 3 || t == 4) {
f = 1
if !f {
t := copyu(p, v1, nil)
if t == 2 || t == 3 || t == 4 {
f = true
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 {
}
}
}
return true
}
......@@ -464,13 +460,13 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
arm64.AFMOVD:
if p.Scond == 0 {
if s != nil {
if copysub(&p.From, v, s, 1) != 0 {
if copysub(&p.From, v, s, true) {
return 1
}
// Update only indirect uses of v in p->to
if !copyas(&p.To, v) {
if copysub(&p.To, v, s, 1) != 0 {
if copysub(&p.To, v, s, true) {
return 1
}
}
......@@ -508,7 +504,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
}
if s != nil {
if copysub(&p.To, v, s, 1) != 0 {
if copysub(&p.To, v, s, true) {
return 1
}
return 0
......@@ -522,7 +518,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
return 2
}
if s != nil {
if copysub(&p.From, v, s, 1) != 0 {
if copysub(&p.From, v, s, true) {
return 1
}
return 0
......@@ -561,16 +557,16 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
arm64.AFDIVD,
arm64.AFDIVS:
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, 1) != 0 {
if copysub1(p, v, s, true) {
return 1
}
// Update only indirect uses of v in p->to
if !copyas(&p.To, v) {
if copysub(&p.To, v, s, 1) != 0 {
if copysub(&p.To, v, s, true) {
return 1
}
}
......@@ -622,10 +618,13 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
arm64.AFCMPD,
arm64.AFCMPS:
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 copysub1(p, v, s, 1)
return 0
}
if copyau(&p.From, v) {
......@@ -638,7 +637,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
case arm64.AB: /* read p->to */
if s != nil {
if copysub(&p.To, v, s, 1) != 0 {
if copysub(&p.To, v, s, true) {
return 1
}
return 0
......@@ -664,7 +663,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
}
if s != nil {
if copysub(&p.To, v, s, 1) != 0 {
if copysub(&p.To, v, s, true) {
return 1
}
return 0
......@@ -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
// register in v. If a is the to operand, this means this operation
// writes the register in v.
func copyas(a *obj.Addr, v *obj.Addr) bool {
if regtyp(v) {
if a.Type == v.Type {
if a.Reg == v.Reg {
return true
}
}
}
return false
return regtyp(v) && a.Type == v.Type && a.Reg == v.Reg
}
// 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.
//
// 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 {
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.
func copyau1(p *obj.Prog, v *obj.Addr) bool {
if regtyp(v) && v.Reg != 0 {
if p.Reg == v.Reg {
return true
}
}
return false
return regtyp(v) && v.Reg != 0 && p.Reg == v.Reg
}
// copysub replaces v with s in a if f!=0 or indicates it if could if f==0.
// Returns 1 on failure to substitute (it always succeeds on arm64).
func copysub(a *obj.Addr, v *obj.Addr, s *obj.Addr, f int) int {
if f != 0 {
if copyau(a, v) {
a.Reg = s.Reg
}
// copysub replaces v with s in a if f==true or indicates it if could if f==false.
// Returns true on failure to substitute (it always succeeds on arm64).
// 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 {
if f && copyau(a, v) {
a.Reg = s.Reg
}
return 0
return false
}
// copysub1 replaces v with s in p1->reg if f!=0 or indicates if it could if f==0.
// Returns 1 on failure to substitute (it always succeeds on arm64).
func copysub1(p1 *obj.Prog, v *obj.Addr, s *obj.Addr, f int) int {
if f != 0 {
if copyau1(p1, v) {
p1.Reg = s.Reg
}
// copysub1 replaces v with s in p1->reg if f==true or indicates if it could if f==false.
// Returns true on failure to substitute (it always succeeds on arm64).
// TODO(dfc) remove unused return value, remove calls with f=false as they do nothing.
func copysub1(p1 *obj.Prog, v *obj.Addr, s *obj.Addr, f bool) bool {
if f && copyau1(p1, v) {
p1.Reg = s.Reg
}
return 0
return false
}
func sameaddr(a *obj.Addr, v *obj.Addr) bool {
......
......@@ -81,7 +81,7 @@ loop1:
// Convert uses to $0 to uses of R0 and
// propagate R0
if regzer(&p.From) != 0 {
if regzer(&p.From) {
if p.To.Type == obj.TYPE_REG && !isfreg(&p.To) {
p.From.Type = obj.TYPE_REG
p.From.Reg = mips.REGZERO
......@@ -153,23 +153,16 @@ func excise(r *gc.Flow) {
gc.Ostats.Ndelmov++
}
/*
* regzer returns 1 if a's value is 0 (a is R0 or $0)
*/
func regzer(a *obj.Addr) int {
// regzer returns true if a's value is 0 (a is R0 or $0)
func regzer(a *obj.Addr) bool {
if a.Type == obj.TYPE_CONST || a.Type == obj.TYPE_ADDR {
if a.Sym == nil && a.Reg == 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 {
......@@ -223,7 +216,7 @@ func subprop(r0 *gc.Flow) bool {
if p.Info.Flags&(gc.RightRead|gc.RightWrite) == gc.RightWrite {
if p.To.Type == v1.Type {
if p.To.Reg == v1.Reg {
copysub(&p.To, v1, v2, 1)
copysub(&p.To, v1, v2, true)
if gc.Debug['P'] != 0 {
fmt.Printf("gotit: %v->%v\n%v", gc.Ctxt.Dconv(v1), gc.Ctxt.Dconv(v2), r.Prog)
if p.From.Type == v2.Type {
......@@ -234,9 +227,9 @@ func subprop(r0 *gc.Flow) bool {
for r = gc.Uniqs(r); r != r0; r = gc.Uniqs(r) {
p = r.Prog
copysub(&p.From, v1, v2, 1)
copysub1(p, v1, v2, 1)
copysub(&p.To, v1, v2, 1)
copysub(&p.From, v1, v2, true)
copysub1(p, v1, v2, true)
copysub(&p.To, v1, v2, true)
if gc.Debug['P'] != 0 {
fmt.Printf("%v\n", r.Prog)
}
......@@ -254,7 +247,7 @@ func subprop(r0 *gc.Flow) bool {
if copyau(&p.From, v2) || copyau1(p, v2) || copyau(&p.To, v2) {
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
}
}
......@@ -289,12 +282,12 @@ func copyprop(r0 *gc.Flow) bool {
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)
}
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.
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 gc.Debug['P'] != 0 {
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 {
r.Active = int32(gactive)
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 {
p = r.Prog
p := r.Prog
if gc.Debug['P'] != 0 {
fmt.Printf("%v", p)
}
if f == 0 && gc.Uniqp(r) == nil {
if !f && gc.Uniqp(r) == nil {
// Multiple predecessors; conservatively
// assume v1 was set on other path
f = 1
f = true
if gc.Debug['P'] != 0 {
fmt.Printf("; merge; f=%d", f)
fmt.Printf("; merge; f=%v", f)
}
}
t = copyu(p, v2, nil)
switch t {
switch t := copyu(p, v2, nil); t {
case 2: /* rar, can't split */
if gc.Debug['P'] != 0 {
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 {
case 1, /* used, substitute */
4: /* use and set */
if f != 0 {
if f {
if gc.Debug['P'] == 0 {
return false
}
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 {
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
}
......@@ -369,12 +359,12 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool {
}
}
if f == 0 {
t = copyu(p, v1, nil)
if f == 0 && (t == 2 || t == 3 || t == 4) {
f = 1
if !f {
t := copyu(p, v1, nil)
if t == 2 || t == 3 || t == 4 {
f = true
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 {
mips.ATRUNCFW,
mips.ATRUNCDW:
if s != nil {
if copysub(&p.From, v, s, 1) != 0 {
if copysub(&p.From, v, s, true) {
return 1
}
// Update only indirect uses of v in p->to
if !copyas(&p.To, v) {
if copysub(&p.To, v, s, 1) != 0 {
if copysub(&p.To, v, s, true) {
return 1
}
}
......@@ -506,16 +496,16 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
mips.ADIVF,
mips.ADIVD:
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, 1) != 0 {
if copysub1(p, v, s, true) {
return 1
}
// Update only indirect uses of v in p->to
if !copyas(&p.To, v) {
if copysub(&p.To, v, s, 1) != 0 {
if copysub(&p.To, v, s, true) {
return 1
}
}
......@@ -576,10 +566,13 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
mips.ADIVV,
mips.ADIVVU:
if s != nil {
if copysub(&p.From, v, s, 1) != 0 {
if copysub(&p.From, v, s, true) {
return 1
}
return copysub1(p, v, s, 1)
if copysub1(p, v, s, true) {
return 1
}
return 0
}
if copyau(&p.From, v) {
......@@ -592,7 +585,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
case mips.AJMP: /* read p->to */
if s != nil {
if copysub(&p.To, v, s, 1) != 0 {
if copysub(&p.To, v, s, true) {
return 1
}
return 0
......@@ -635,7 +628,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
}
if s != nil {
if copysub(&p.To, v, s, 1) != 0 {
if copysub(&p.To, v, s, true) {
return 1
}
return 0
......@@ -729,37 +722,30 @@ func copyau(a *obj.Addr, v *obj.Addr) bool {
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.
func copyau1(p *obj.Prog, v *obj.Addr) bool {
if regtyp(v) && v.Reg != 0 {
if p.Reg == v.Reg {
return true
}
}
return false
return regtyp(v) && v.Reg != 0 && p.Reg == v.Reg
}
// copysub replaces v with s in a if f!=0 or indicates it if could if f==0.
// Returns 1 on failure to substitute (it always succeeds on mips).
func copysub(a *obj.Addr, v *obj.Addr, s *obj.Addr, f int) int {
if f != 0 {
if copyau(a, v) {
a.Reg = s.Reg
}
// copysub replaces v with s in a if f==true or indicates it if could if f==false.
// Returns true on failure to substitute (it always succeeds on mips).
// 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 {
if f && copyau(a, v) {
a.Reg = s.Reg
}
return 0
return false
}
// copysub1 replaces v with s in p1->reg if f!=0 or indicates if it could if f==0.
// Returns 1 on failure to substitute (it always succeeds on mips).
func copysub1(p1 *obj.Prog, v *obj.Addr, s *obj.Addr, f int) int {
if f != 0 {
if copyau1(p1, v) {
p1.Reg = s.Reg
}
// copysub1 replaces v with s in p1->reg if f==true or indicates if it could if f==false.
// Returns true on failure to substitute (it always succeeds on mips).
// TODO(dfc) remove unused return value, remove calls with f=false as they do nothing.
func copysub1(p1 *obj.Prog, v *obj.Addr, s *obj.Addr, f bool) bool {
if f && copyau1(p1, v) {
p1.Reg = s.Reg
}
return 0
return false
}
func sameaddr(a *obj.Addr, v *obj.Addr) bool {
......
......@@ -81,7 +81,7 @@ loop1:
// Convert uses to $0 to uses of R0 and
// propagate R0
if regzer(&p.From) != 0 {
if regzer(&p.From) {
if p.To.Type == obj.TYPE_REG {
p.From.Type = obj.TYPE_REG
p.From.Reg = ppc64.REGZERO
......@@ -154,7 +154,7 @@ loop1:
switch p.As {
case ppc64.ACMP,
ppc64.ACMPW: /* always safe? */
if regzer(&p.To) == 0 {
if !regzer(&p.To) {
continue
}
r1 = r.S1
......@@ -356,23 +356,16 @@ func excise(r *gc.Flow) {
gc.Ostats.Ndelmov++
}
/*
* regzer returns 1 if a's value is 0 (a is R0 or $0)
*/
func regzer(a *obj.Addr) int {
// regzer returns true if a's value is 0 (a is R0 or $0)
func regzer(a *obj.Addr) bool {
if a.Type == obj.TYPE_CONST || a.Type == obj.TYPE_ADDR {
if a.Sym == nil && a.Reg == 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 {
......@@ -422,7 +415,7 @@ func subprop(r0 *gc.Flow) bool {
if p.Info.Flags&(gc.RightRead|gc.RightWrite) == gc.RightWrite {
if p.To.Type == v1.Type {
if p.To.Reg == v1.Reg {
copysub(&p.To, v1, v2, 1)
copysub(&p.To, v1, v2, true)
if gc.Debug['P'] != 0 {
fmt.Printf("gotit: %v->%v\n%v", gc.Ctxt.Dconv(v1), gc.Ctxt.Dconv(v2), r.Prog)
if p.From.Type == v2.Type {
......@@ -433,9 +426,9 @@ func subprop(r0 *gc.Flow) bool {
for r = gc.Uniqs(r); r != r0; r = gc.Uniqs(r) {
p = r.Prog
copysub(&p.From, v1, v2, 1)
copysub1(p, v1, v2, 1)
copysub(&p.To, v1, v2, 1)
copysub(&p.From, v1, v2, true)
copysub1(p, v1, v2, true)
copysub(&p.To, v1, v2, true)
if gc.Debug['P'] != 0 {
fmt.Printf("%v\n", r.Prog)
}
......@@ -453,7 +446,7 @@ func subprop(r0 *gc.Flow) bool {
if copyau(&p.From, v2) || copyau1(p, v2) || copyau(&p.To, v2) {
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
}
}
......@@ -488,12 +481,12 @@ func copyprop(r0 *gc.Flow) bool {
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)
}
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
// 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 gc.Debug['P'] != 0 {
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 {
r.Active = int32(gactive)
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 {
p = r.Prog
p := r.Prog
if gc.Debug['P'] != 0 {
fmt.Printf("%v", p)
}
if f == 0 && gc.Uniqp(r) == nil {
if !f && gc.Uniqp(r) == nil {
// Multiple predecessors; conservatively
// assume v1 was set on other path
f = 1
f = true
if gc.Debug['P'] != 0 {
fmt.Printf("; merge; f=%d", f)
fmt.Printf("; merge; f=%v", f)
}
}
t = copyu(p, v2, nil)
switch t {
switch t := copyu(p, v2, nil); t {
case 2: /* rar, can't split */
if gc.Debug['P'] != 0 {
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 {
case 1, /* used, substitute */
4: /* use and set */
if f != 0 {
if f {
if gc.Debug['P'] == 0 {
return false
}
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 {
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
}
......@@ -568,12 +558,12 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool {
}
}
if f == 0 {
t = copyu(p, v1, nil)
if f == 0 && (t == 2 || t == 3 || t == 4) {
f = 1
if !f {
t := copyu(p, v1, nil)
if t == 2 || t == 3 || t == 4 {
f = true
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 {
ppc64.AFNEG,
ppc64.AFNEGCC:
if s != nil {
if copysub(&p.From, v, s, 1) != 0 {
if copysub(&p.From, v, s, true) {
return 1
}
// Update only indirect uses of v in p->to
if !copyas(&p.To, v) {
if copysub(&p.To, v, s, 1) != 0 {
if copysub(&p.To, v, s, true) {
return 1
}
}
......@@ -692,7 +682,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
}
if s != nil {
if copysub(&p.To, v, s, 1) != 0 {
if copysub(&p.To, v, s, true) {
return 1
}
return 0
......@@ -706,7 +696,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
return 2
}
if s != nil {
if copysub(&p.From, v, s, 1) != 0 {
if copysub(&p.From, v, s, true) {
return 1
}
return 0
......@@ -776,16 +766,16 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
ppc64.AFDIVS,
ppc64.AFDIV:
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, 1) != 0 {
if copysub1(p, v, s, true) {
return 1
}
// Update only indirect uses of v in p->to
if !copyas(&p.To, v) {
if copysub(&p.To, v, s, 1) != 0 {
if copysub(&p.To, v, s, true) {
return 1
}
}
......@@ -838,10 +828,13 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
ppc64.AFCMPO,
ppc64.AFCMPU:
if s != nil {
if copysub(&p.From, v, s, 1) != 0 {
if copysub(&p.From, v, s, true) {
return 1
}
if copysub(&p.To, v, s, true) {
return 1
}
return copysub(&p.To, v, s, 1)
return 0
}
if copyau(&p.From, v) {
......@@ -857,7 +850,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
// mov and a branch).
case ppc64.ABR: /* read p->to */
if s != nil {
if copysub(&p.To, v, s, 1) != 0 {
if copysub(&p.To, v, s, true) {
return 1
}
return 0
......@@ -900,12 +893,11 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
}
if s != nil {
if copysub(&p.To, v, s, 1) != 0 {
if copysub(&p.To, v, s, true) {
return 1
}
return 0
}
if copyau(&p.To, v) {
return 4
}
......@@ -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
// register in v. If a is the to operand, this means this operation
// writes the register in v.
func copyas(a *obj.Addr, v *obj.Addr) bool {
if regtyp(v) {
if a.Type == v.Type {
if a.Reg == v.Reg {
return true
}
}
}
return false
return regtyp(v) && a.Type == v.Type && a.Reg == v.Reg
}
// 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.
//
// 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 {
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.
func copyau1(p *obj.Prog, v *obj.Addr) bool {
if regtyp(v) && v.Reg != 0 {
if p.Reg == v.Reg {
return true
}
}
return false
return regtyp(v) && v.Reg != 0 && p.Reg == v.Reg
}
// copysub replaces v with s in a if f!=0 or indicates it if could if f==0.
// Returns 1 on failure to substitute (it always succeeds on ppc64).
func copysub(a *obj.Addr, v *obj.Addr, s *obj.Addr, f int) int {
if f != 0 {
if copyau(a, v) {
a.Reg = s.Reg
}
// copysub replaces v with s in a if f==true or indicates it if could if f==false.
// Returns true on failure to substitute (it always succeeds on ppc64).
// TODO(dfc) remove unused return value and callers where f=false.
func copysub(a *obj.Addr, v *obj.Addr, s *obj.Addr, f bool) bool {
if f && copyau(a, v) {
a.Reg = s.Reg
}
return 0
return false
}
// copysub1 replaces v with s in p1->reg if f!=0 or indicates if it could if f==0.
// Returns 1 on failure to substitute (it always succeeds on ppc64).
func copysub1(p1 *obj.Prog, v *obj.Addr, s *obj.Addr, f int) int {
if f != 0 {
if copyau1(p1, v) {
p1.Reg = s.Reg
}
// copysub1 replaces v with s in p1->reg if f==true or indicates if it could if f==false.
// Returns true on failure to substitute (it always succeeds on ppc64).
// TODO(dfc) remove unused return value and callers where f=false.
func copysub1(p1 *obj.Prog, v *obj.Addr, s *obj.Addr, f bool) bool {
if f && copyau1(p1, v) {
p1.Reg = s.Reg
}
return 0
return false
}
func sameaddr(a *obj.Addr, v *obj.Addr) 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 {
copysub(&p.To, v1, v2, 1)
copysub(&p.To, v1, v2, true)
if gc.Debug['P'] != 0 {
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 {
......@@ -398,8 +398,8 @@ func subprop(r0 *gc.Flow) bool {
for r = gc.Uniqs(r); r != r0; r = gc.Uniqs(r) {
p = r.Prog
copysub(&p.From, v1, v2, 1)
copysub(&p.To, v1, v2, 1)
copysub(&p.From, v1, v2, true)
copysub(&p.To, v1, v2, true)
if gc.Debug['P'] != 0 {
fmt.Printf("%v\n", r.Prog)
}
......@@ -417,7 +417,7 @@ func subprop(r0 *gc.Flow) bool {
if copyau(&p.From, v2) || copyau(&p.To, v2) {
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
}
}
......@@ -445,10 +445,10 @@ func copyprop(g *gc.Graph, r0 *gc.Flow) bool {
return true
}
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 gc.Debug['P'] != 0 {
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 {
r.Active = int32(gactive)
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 {
p = r.Prog
p := r.Prog
if gc.Debug['P'] != 0 {
fmt.Printf("%v", p)
}
if f == 0 && gc.Uniqp(r) == nil {
f = 1
if !f && gc.Uniqp(r) == nil {
f = true
if gc.Debug['P'] != 0 {
fmt.Printf("; merge; f=%d", f)
fmt.Printf("; merge; f=%v", f)
}
}
t = copyu(p, v2, nil)
switch t {
switch t := copyu(p, v2, nil); t {
case 2: /* rar, can't split */
if gc.Debug['P'] != 0 {
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 {
case 1, /* used, substitute */
4: /* use and set */
if f != 0 {
if f {
if gc.Debug['P'] == 0 {
return false
}
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 {
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
}
......@@ -520,12 +517,12 @@ func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool {
}
}
if f == 0 {
t = copyu(p, v1, nil)
if f == 0 && (t == 2 || t == 3 || t == 4) {
f = 1
if !f {
t := copyu(p, v1, nil)
if t == 2 || t == 3 || t == 4 {
f = true
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 {
}
}
}
return true
}
......@@ -555,7 +551,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
switch p.As {
case obj.AJMP:
if s != nil {
if copysub(&p.To, v, s, 1) != 0 {
if copysub(&p.To, v, s, true) {
return 1
}
return 0
......@@ -584,7 +580,7 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
}
if s != nil {
if copysub(&p.To, v, s, 1) != 0 {
if copysub(&p.To, v, s, true) {
return 1
}
return 0
......@@ -625,7 +621,10 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
if p.Info.Flags&gc.RightWrite != 0 {
if copyas(&p.To, v) {
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) {
return 4
......@@ -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 s != nil {
if copysub(&p.From, v, s, 1) != 0 {
if copysub(&p.From, v, s, true) {
return 1
}
if copysub(&p.To, v, s, true) {
return 1
}
return copysub(&p.To, v, s, 1)
return 0
}
if copyau(&p.From, v) {
return 1
}
......@@ -649,7 +650,6 @@ func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
return 1
}
}
return 0
}
......@@ -714,50 +714,40 @@ func copyau(a *obj.Addr, v *obj.Addr) bool {
return false
}
/*
* substitute s for v in a
* return failure to substitute
*/
func copysub(a *obj.Addr, v *obj.Addr, s *obj.Addr, f int) int {
// copysub substitute s for v in a.
// copysub returns true on 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 {
if copyas(a, v) {
reg := int(s.Reg)
if reg >= x86.REG_AX && reg <= x86.REG_DI || reg >= x86.REG_X0 && reg <= x86.REG_X7 {
if f != 0 {
a.Reg = int16(reg)
if s.Reg >= x86.REG_AX && s.Reg <= x86.REG_DI || s.Reg >= x86.REG_X0 && s.Reg <= x86.REG_X7 {
if f {
a.Reg = s.Reg
}
}
return 0
return false
}
if regtyp(v) {
reg := int(v.Reg)
if (a.Type == obj.TYPE_MEM || a.Type == obj.TYPE_ADDR) && int(a.Reg) == reg {
if (a.Type == obj.TYPE_MEM || a.Type == obj.TYPE_ADDR) && a.Reg == v.Reg {
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
}
}
// return 0;
if int(a.Index) == reg {
if f != 0 {
if a.Index == v.Reg {
if f {
a.Index = s.Reg
}
return 0
}
return 0
}
return 0
return false
}
func conprop(r0 *gc.Flow) {
var p *obj.Prog
var t int
p0 := r0.Prog
v0 := &p0.To
......@@ -773,8 +763,7 @@ loop:
}
p = r.Prog
t = copyu(p, v0, nil)
switch t {
switch copyu(p, v0, nil) {
case 0, // miss
1: // use
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