2015-03-03 13:38:14 -08:00
|
|
|
// Copyright 2015 The Go Authors. All rights reserved.
|
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
|
|
package ssa
|
|
|
|
|
|
|
|
|
|
// copyelim removes all copies from f.
|
|
|
|
|
func copyelim(f *Func) {
|
|
|
|
|
for _, b := range f.Blocks {
|
|
|
|
|
for _, v := range b.Values {
|
2016-02-11 20:46:43 +01:00
|
|
|
copyelimValue(v)
|
2015-03-03 13:38:14 -08:00
|
|
|
}
|
|
|
|
|
v := b.Control
|
2016-03-15 20:45:50 -07:00
|
|
|
if v != nil && v.Op == OpCopy {
|
2015-03-03 13:38:14 -08:00
|
|
|
for v.Op == OpCopy {
|
|
|
|
|
v = v.Args[0]
|
|
|
|
|
}
|
2016-03-15 20:45:50 -07:00
|
|
|
b.SetControl(v)
|
2015-03-03 13:38:14 -08:00
|
|
|
}
|
|
|
|
|
}
|
2016-01-05 14:56:26 -08:00
|
|
|
|
|
|
|
|
// Update named values.
|
|
|
|
|
for _, name := range f.Names {
|
|
|
|
|
values := f.NamedValues[name]
|
|
|
|
|
for i, v := range values {
|
|
|
|
|
x := v
|
|
|
|
|
for x.Op == OpCopy {
|
|
|
|
|
x = x.Args[0]
|
|
|
|
|
}
|
|
|
|
|
if x != v {
|
2016-03-08 20:09:48 -08:00
|
|
|
values[i] = x
|
2016-01-05 14:56:26 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-03-03 13:38:14 -08:00
|
|
|
}
|
2016-02-11 20:46:43 +01:00
|
|
|
|
2016-03-15 20:45:50 -07:00
|
|
|
func copyelimValue(v *Value) bool {
|
2016-02-11 20:46:43 +01:00
|
|
|
// elide any copies generated during rewriting
|
2016-03-15 20:45:50 -07:00
|
|
|
changed := false
|
2016-02-11 20:46:43 +01:00
|
|
|
for i, a := range v.Args {
|
|
|
|
|
if a.Op != OpCopy {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
// Rewriting can generate OpCopy loops.
|
|
|
|
|
// They are harmless (see removePredecessor),
|
|
|
|
|
// but take care to stop if we find a cycle.
|
|
|
|
|
slow := a // advances every other iteration
|
|
|
|
|
var advance bool
|
|
|
|
|
for a.Op == OpCopy {
|
|
|
|
|
a = a.Args[0]
|
|
|
|
|
if slow == a {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
if advance {
|
|
|
|
|
slow = slow.Args[0]
|
|
|
|
|
}
|
|
|
|
|
advance = !advance
|
|
|
|
|
}
|
2016-03-15 20:45:50 -07:00
|
|
|
v.SetArg(i, a)
|
|
|
|
|
changed = true
|
2016-02-11 20:46:43 +01:00
|
|
|
}
|
2016-03-15 20:45:50 -07:00
|
|
|
return changed
|
2016-02-11 20:46:43 +01:00
|
|
|
}
|