MCPcopy Create free account
hub / github.com/decomp/decomp / IsValid

Method IsValid

cfa/if_return.go:108–152  ·  view source on GitHub ↗

IsValid reports whether the cond, body and exit node candidates of prim form a valid 1-way conditional with a body return statement in g. Control flow graph: cond ↓ ↘ ↓ body ↓ exit

(g graph.Directed, dom cfg.DominatorTree)

Source from the content-addressed store, hash-verified

106// ↓
107// exit
108func (prim IfReturn) 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 zero successors.
122 bodyPreds := g.To(body)
123 bodySuccs := g.From(body)
124 if len(bodyPreds) != 1 || len(bodySuccs) != 0 {
125 return false
126 }
127
128 // Verify that exit has one predecessor (cond).
129 exitPreds := g.To(exit)
130 if len(exitPreds) != 1 {
131 return false
132 }
133
134 // Verify that the entry node (cond) has no predecessors dominated by cond,
135 // as that would indicate a loop construct.
136 //
137 // cond
138 // ↗ ↓ ↘
139 // ↑ ↓ body
140 // ↑ ↓
141 // ↑ exit
142 // ↖ ↓
143 // A
144 condPreds := g.To(cond)
145 for _, pred := range condPreds {
146 if dom.Dominates(cond, pred) {
147 return false
148 }
149 }
150
151 return true
152}

Callers 1

FindIfReturnFunction · 0.45

Calls 1

DominatesMethod · 0.80

Tested by

no test coverage detected