3 import "honnef.co/go/tools/ir"
5 type Loop struct{ *ir.BlockSet }
7 func FindLoops(fn *ir.Function) []Loop {
11 tree := fn.DomPreorder()
13 for _, h := range tree {
14 for _, n := range h.Preds {
18 // n is a back-edge to h
19 // h is the loop header
21 set := Loop{ir.NewBlockSet(len(fn.Blocks))}
23 sets = append(sets, set)
26 set := Loop{ir.NewBlockSet(len(fn.Blocks))}
29 for _, b := range allPredsBut(n, h, nil) {
32 sets = append(sets, set)
38 func allPredsBut(b, but *ir.BasicBlock, list []*ir.BasicBlock) []*ir.BasicBlock {
40 for _, pred := range b.Preds {
44 for _, p := range list {
45 // TODO improve big-o complexity of this function
50 list = append(list, pred)
51 list = allPredsBut(pred, but, list)