FindPostLoop returns the first occurrence of a post-test loop in g, and a boolean indicating if such a primitive was found.
(g graph.Directed, dom cfg.DominatorTree)
| 64 | // FindPostLoop returns the first occurrence of a post-test loop in g, and a |
| 65 | // boolean indicating if such a primitive was found. |
| 66 | func FindPostLoop(g graph.Directed, dom cfg.DominatorTree) (prim PostLoop, ok bool) { |
| 67 | // Range through cond node candidates. |
| 68 | for _, cond := range g.Nodes() { |
| 69 | // Verify that cond has two successors (cond and exit). |
| 70 | condSuccs := g.From(cond) |
| 71 | if len(condSuccs) != 2 { |
| 72 | continue |
| 73 | } |
| 74 | prim.Cond = cond |
| 75 | |
| 76 | // Try the first exit node candidate. |
| 77 | prim.Exit = condSuccs[0] |
| 78 | if prim.IsValid(g, dom) { |
| 79 | return prim, true |
| 80 | } |
| 81 | |
| 82 | // Try the second exit node candidate. |
| 83 | prim.Exit = condSuccs[1] |
| 84 | if prim.IsValid(g, dom) { |
| 85 | return prim, true |
| 86 | } |
| 87 | } |
| 88 | return PostLoop{}, false |
| 89 | } |
| 90 | |
| 91 | // IsValid reports whether the cond and exit node candidates of prim form a |
| 92 | // valid post-test loop in g. |