mirror of
https://github.com/golang/go
synced 2024-11-12 04:40:22 -07:00
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/20281 Reviewed-by: Matthew Dempsky <mdempsky@google.com> Run-TryBot: Dave Cheney <dave@cheney.net> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
211cc40b11
commit
dbe54d23fe
@ -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
|
||||
}
|
||||
return copysub(&p.To, v, s, 1)
|
||||
if copysub(&p.To, v, s, true) {
|
||||
return 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
|
||||
}
|
||||
return copysub1(p, v, s, 1)
|
||||
if copysub1(p, v, s, true) {
|
||||
return 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
|
||||
}
|
||||
return copysub1(p, v, s, 1)
|
||||
if copysub1(p, v, s, true) {
|
||||
return 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 regtyp(v) && v.Reg != 0 && p.Reg == v.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 false
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
// 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
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
}
|
||||
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 regtyp(v) && v.Reg != 0 && p.Reg == v.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 false
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
// 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
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
}
|
||||
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
|
||||
}
|
||||
return copysub(&p.To, v, s, 1)
|
||||
if copysub(&p.To, v, s, true) {
|
||||
return 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 regtyp(v) && v.Reg != 0 && p.Reg == v.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 false
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
// 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
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
}
|
||||
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
|
||||
}
|
||||
return copysub(&p.To, v, s, 1)
|
||||
if copysub(&p.To, v, s, true) {
|
||||
return 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
|
||||
|
Loading…
Reference in New Issue
Block a user