FindIfElse returns the first occurrence of a 2-way conditional statement in g, and a boolean indicating if such a primitive was found.
(g graph.Directed, dom cfg.DominatorTree)
| 79 | // FindIfElse returns the first occurrence of a 2-way conditional statement in |
| 80 | // g, and a boolean indicating if such a primitive was found. |
| 81 | func FindIfElse(g graph.Directed, dom cfg.DominatorTree) (prim IfElse, ok bool) { |
| 82 | // Range through cond node candidates. |
| 83 | for _, cond := range g.Nodes() { |
| 84 | // Verify that cond has two successors (body_true and body_false). |
| 85 | condSuccs := g.From(cond) |
| 86 | if len(condSuccs) != 2 { |
| 87 | continue |
| 88 | } |
| 89 | prim.Cond = cond |
| 90 | |
| 91 | // Select body_true and body_false node candidates. |
| 92 | prim.BodyTrue, prim.BodyFalse = condSuccs[0], condSuccs[1] |
| 93 | |
| 94 | // Verify that body_true has one successor (exit). |
| 95 | bodyTrueSuccs := g.From(prim.BodyTrue) |
| 96 | if len(bodyTrueSuccs) != 1 { |
| 97 | continue |
| 98 | } |
| 99 | |
| 100 | // Select exit node candidate. |
| 101 | prim.Exit = bodyTrueSuccs[0] |
| 102 | if prim.IsValid(g, dom) { |
| 103 | return prim, true |
| 104 | } |
| 105 | } |
| 106 | return IfElse{}, false |
| 107 | } |
| 108 | |
| 109 | // IsValid reports whether the cond, body_true, body_false and exit node |
| 110 | // candidates of prim form a valid 2-way conditional statement in g. |