1
0
mirror of https://github.com/golang/go synced 2024-10-05 16:41:21 -06:00

[dev.ssa] cmd/compile/internal/ssa: more checks on ssa structure

Make sure all referenced Blocks and Values are really there.
Fix deadcode to generate SSA graphs that pass this new test.

Change-Id: Ib002ce20e33490eb8c919bd189d209f769d61517
Reviewed-on: https://go-review.googlesource.com/13147
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
This commit is contained in:
Keith Randall 2015-08-04 21:59:15 -07:00
parent ddeee0eed3
commit cfd8dfaa10
2 changed files with 40 additions and 5 deletions

View File

@ -137,12 +137,35 @@ func checkFunc(f *Func) {
}
}
// Check to make sure all Blocks referenced are in the function.
if !blockMark[f.Entry.ID] {
f.Fatalf("entry block %v is missing", f.Entry)
}
for _, b := range f.Blocks {
if b.Control != nil {
if !valueMark[b.Control.ID] {
f.Fatalf("control value for %s is missing: %v", b, b.Control)
for _, c := range b.Preds {
if !blockMark[c.ID] {
f.Fatalf("predecessor block %v for %v is missing", c, b)
}
}
for _, c := range b.Succs {
if !blockMark[c.ID] {
f.Fatalf("successor block %v for %v is missing", c, b)
}
}
}
// Check to make sure all Values referenced are in the function.
for _, b := range f.Blocks {
for _, v := range b.Values {
for i, a := range v.Args {
if !valueMark[a.ID] {
f.Fatalf("%v, arg %d of %v, is missing", a, i, v)
}
}
}
if b.Control != nil && !valueMark[b.Control.ID] {
f.Fatalf("control value for %s is missing: %v", b, b.Control)
}
}
for _, id := range f.bid.free {
if blockMark[id] {

View File

@ -6,7 +6,6 @@ package ssa
// deadcode removes dead code from f.
func deadcode(f *Func) {
// Find all reachable basic blocks.
reachable := make([]bool, f.NumBlocks())
reachable[f.Entry.ID] = true
@ -85,6 +84,11 @@ func deadcode(f *Func) {
if len(b.Values) > 0 {
b.Fatalf("live values in unreachable block %v: %v", b, b.Values)
}
s := b.Succs
b.Succs = nil
for _, c := range s {
f.removePredecessor(b, c)
}
f.bid.put(b.ID)
}
}
@ -108,14 +112,22 @@ func (f *Func) removePredecessor(b, c *Block) {
b, c := work[0][0], work[0][1]
work = work[1:]
// find index of b in c's predecessor list
// Find index of b in c's predecessor list
// TODO: This could conceivably cause O(n^2) work. Imagine a very
// wide phi in (for example) the return block. If we determine that
// lots of panics won't happen, we remove each edge at a cost of O(n) each.
var i int
found := false
for j, p := range c.Preds {
if p == b {
i = j
found = true
break
}
}
if !found {
f.Fatalf("can't find predecessor %v of %v\n", b, c)
}
n := len(c.Preds) - 1
c.Preds[i] = c.Preds[n]