aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/ssa/phielim.go
diff options
context:
space:
mode:
authorAlexandru Moșoi <mosoi@google.com>2016-02-11 20:46:43 +0100
committerDavid Chase <drchase@google.com>2016-02-16 21:02:56 +0000
commit65855cf64022905c9b66abc26adc175e337193c9 (patch)
tree57aa129578ff98f2f75ded0c1e3118fa463a5c2e /src/cmd/compile/internal/ssa/phielim.go
parentadc8d491c2318b4b9e3b60ea868bd65c82ca13df (diff)
downloadgo-65855cf64022905c9b66abc26adc175e337193c9.tar.gz
go-65855cf64022905c9b66abc26adc175e337193c9.zip
[dev.ssa] cmd/compile/internal/ssa: factor out copyelimValue and phielimValue
* Merge copyelim into phielim. * Add phielimValue to rewrite. cgoIsGoPointer is, for example, 2 instructions smaller now. Change-Id: I8baeb206d1b3ef8aba4a6e3bcdc432959bcae2d5 Reviewed-on: https://go-review.googlesource.com/19462 Reviewed-by: David Chase <drchase@google.com>
Diffstat (limited to 'src/cmd/compile/internal/ssa/phielim.go')
-rw-r--r--src/cmd/compile/internal/ssa/phielim.go69
1 files changed, 36 insertions, 33 deletions
diff --git a/src/cmd/compile/internal/ssa/phielim.go b/src/cmd/compile/internal/ssa/phielim.go
index aaa0a0f238..20ce592030 100644
--- a/src/cmd/compile/internal/ssa/phielim.go
+++ b/src/cmd/compile/internal/ssa/phielim.go
@@ -18,44 +18,47 @@ package ssa
// and would that be useful?
func phielim(f *Func) {
for {
- changed := false
+ change := false
for _, b := range f.Blocks {
- nextv:
for _, v := range b.Values {
- if v.Op != OpPhi {
- continue
- }
- // If there are two distinct args of v which
- // are not v itself, then the phi must remain.
- // Otherwise, we can replace it with a copy.
- var w *Value
- for _, x := range v.Args {
- for x.Op == OpCopy {
- x = x.Args[0]
- }
- if x == v {
- continue
- }
- if x == w {
- continue
- }
- if w != nil {
- continue nextv
- }
- w = x
- }
- if w == nil {
- // v references only itself. It must be in
- // a dead code loop. Don't bother modifying it.
- continue
- }
- v.Op = OpCopy
- v.SetArgs1(w)
- changed = true
+ copyelimValue(v)
+ change = phielimValue(v) || change
}
}
- if !changed {
+ if !change {
break
}
}
}
+
+func phielimValue(v *Value) bool {
+ if v.Op != OpPhi {
+ return false
+ }
+
+ // If there are two distinct args of v which
+ // are not v itself, then the phi must remain.
+ // Otherwise, we can replace it with a copy.
+ var w *Value
+ for _, x := range v.Args {
+ if x == v {
+ continue
+ }
+ if x == w {
+ continue
+ }
+ if w != nil {
+ return false
+ }
+ w = x
+ }
+
+ if w == nil {
+ // v references only itself. It must be in
+ // a dead code loop. Don't bother modifying it.
+ return false
+ }
+ v.Op = OpCopy
+ v.SetArgs1(w)
+ return true
+}