作者:glycerin
项目:zygomy
func findu1(r *gc.Flow, v *obj.Addr) bool {
for ; r != nil; r = r.S1 {
if r.Active != 0 {
return false
}
r.Active = 1
switch copyu(r.Prog, v, nil) {
case 1, /* used */
2, /* read-alter-rewrite */
4: /* set and used */
return true
case 3: /* set */
return false
}
if r.S2 != nil {
if findu1(r.S2, v) {
return true
}
}
}
return false
}
作者:glycerin
项目:zygomy
// 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 {
if uint32(r.Active) == gactive {
return true
}
r.Active = int32(gactive)
for ; r != nil; r = r.S1 {
p := r.Prog
if f == 0 && gc.Uniqp(r) == nil {
// Multiple predecessors; conservatively
// assume v1 was set on other path
f = 1
}
t := copyu(p, v2, nil)
switch t {
case _ReadWriteSame:
return false
case _Write:
return true
case _Read, _ReadWriteDiff:
if f != 0 {
return false
}
if copyu(p, v2, v1) != 0 {
return false
}
if t == _ReadWriteDiff {
return true
}
}
if f == 0 {
switch copyu(p, v1, nil) {
case _ReadWriteSame, _ReadWriteDiff, _Write:
f = 1
}
}
if r.S2 != nil {
if !copy1(v1, v2, r.S2, f) {
return false
}
}
}
return true
}