IsValid reports whether the cond, body and exit node candidates of prim form a valid 1-way conditional statement in g. Control flow graph: cond ↓ ↘ ↓ body ↓ ↙ exit
(g graph.Directed, dom cfg.DominatorTree)
| 106 | // ↓ ↙ |
| 107 | // exit |
| 108 | func (prim If) IsValid(g graph.Directed, dom cfg.DominatorTree) bool { |
| 109 | // Dominator sanity check. |
| 110 | cond, body, exit := prim.Cond, prim.Body, prim.Exit |
| 111 | if !dom.Dominates(cond, body) || !dom.Dominates(cond, exit) { |
| 112 | return false |
| 113 | } |
| 114 | |
| 115 | // Verify that cond has two successors (body and exit). |
| 116 | condSuccs := g.From(cond) |
| 117 | if len(condSuccs) != 2 || !g.HasEdgeFromTo(cond, body) || !g.HasEdgeFromTo(cond, exit) { |
| 118 | return false |
| 119 | } |
| 120 | |
| 121 | // Verify that body has one predecessor (cond) and one successor (exit). |
| 122 | bodyPreds := g.To(body) |
| 123 | bodySuccs := g.From(body) |
| 124 | if len(bodyPreds) != 1 || len(bodySuccs) != 1 || !g.HasEdgeFromTo(body, exit) { |
| 125 | return false |
| 126 | } |
| 127 | |
| 128 | // Verify that exit has two predecessors (cond and body). |
| 129 | exitPreds := g.To(exit) |
| 130 | return len(exitPreds) == 2 |
| 131 | } |