}
}
+ // 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] {
f.Fatalf("used block b%d in free list", id)
// 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
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)
}
}
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]