2015-03-23 17:02:11 -07: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
|
|
|
|
|
|
|
|
|
|
// fuse simplifies control flow by joining basic blocks.
|
|
|
|
|
func fuse(f *Func) {
|
|
|
|
|
for _, b := range f.Blocks {
|
|
|
|
|
if b.Kind != BlockPlain {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
c := b.Succs[0]
|
|
|
|
|
if len(c.Preds) != 1 {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// move all of b's values to c.
|
|
|
|
|
for _, v := range b.Values {
|
|
|
|
|
v.Block = c
|
|
|
|
|
c.Values = append(c.Values, v)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// replace b->c edge with preds(b) -> c
|
|
|
|
|
c.Preds = b.Preds
|
|
|
|
|
for _, p := range c.Preds {
|
|
|
|
|
for i, q := range p.Succs {
|
|
|
|
|
if q == b {
|
|
|
|
|
p.Succs[i] = c
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-04-15 15:51:25 -07:00
|
|
|
if f.Entry == b {
|
|
|
|
|
f.Entry = c
|
|
|
|
|
}
|
2015-03-23 17:02:11 -07:00
|
|
|
|
|
|
|
|
// trash b, just in case
|
2015-08-18 14:39:26 -04:00
|
|
|
b.Kind = BlockInvalid
|
2015-03-23 17:02:11 -07:00
|
|
|
b.Values = nil
|
|
|
|
|
b.Preds = nil
|
|
|
|
|
b.Succs = nil
|
|
|
|
|
}
|
|
|
|
|
}
|