aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/ssa/phielim.go
diff options
context:
space:
mode:
authorKeith Randall <khr@golang.org>2015-08-28 12:53:41 -0700
committerKeith Randall <khr@golang.org>2015-08-28 20:40:06 +0000
commitf8093b8f2491171c996c4820fe7b9a2796ac1084 (patch)
tree93adbc5dda7e761d76afcdcc157501892b1cc7f9 /src/cmd/compile/internal/ssa/phielim.go
parent525785885e42b26e6936e5d91386518218cff4d7 (diff)
downloadgo-f8093b8f2491171c996c4820fe7b9a2796ac1084.tar.gz
go-f8093b8f2491171c996c4820fe7b9a2796ac1084.zip
[dev.ssa] cmd/compile/internal/ssa: add arg-dominating check, fix phielim
Add a check to make sure value arguments dominate the value. Phi elim output used to fail this test. When eliminating redundant phis, phi elim was using one of the args and not the ultimate source. For example: b1: x = ... -> b2 b3 b2: y = Copy x b3: z = Copy x -> b4 -> b4 b4: w = phi y z Phi elim eliminates w, but it used to replace w with (Copy y). That's bad as b2 does not dominate b4. Instead we should replace w with (Copy x). Fixes #12347 Change-Id: I9f340cdabcda8e2e90359fb4f9250877b1fffe98 Reviewed-on: https://go-review.googlesource.com/13986 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.go26
1 files changed, 10 insertions, 16 deletions
diff --git a/src/cmd/compile/internal/ssa/phielim.go b/src/cmd/compile/internal/ssa/phielim.go
index 19c0d077e5..be9503248b 100644
--- a/src/cmd/compile/internal/ssa/phielim.go
+++ b/src/cmd/compile/internal/ssa/phielim.go
@@ -11,33 +11,27 @@ package ssa
// v = phi(x,x,x)
// v = phi(x,v,x,v)
func phielim(f *Func) {
- args := newSparseSet(f.NumValues())
+ argSet := newSparseSet(f.NumValues())
+ var args []*Value
for _, b := range f.Blocks {
for _, v := range b.Values {
if v.Op != OpPhi {
continue
}
- args.clear()
+ argSet.clear()
+ args = args[:0]
for _, x := range v.Args {
for x.Op == OpCopy {
x = x.Args[0]
}
- args.add(x.ID)
- }
- switch {
- case args.size() == 1:
- v.Op = OpCopy
- v.SetArgs1(v.Args[0])
- case args.size() == 2 && args.contains(v.ID):
- var w *Value
- for _, x := range v.Args {
- if x.ID != v.ID {
- w = x
- break
- }
+ if x != v && !argSet.contains(x.ID) {
+ argSet.add(x.ID)
+ args = append(args, x)
}
+ }
+ if len(args) == 1 {
v.Op = OpCopy
- v.SetArgs1(w)
+ v.SetArgs1(args[0])
}
}
}