128 |
(* at the end of a block, we need to assign any pending expressions to locals. The |
(* at the end of a block, we need to assign any pending expressions to locals. The |
129 |
* blkStms list and the resulting statement list are in reverse order. |
* blkStms list and the resulting statement list are in reverse order. |
130 |
*) |
*) |
131 |
fun endBlock (E{tbl, locals}, blkStms) = let |
fun flushPending (E{tbl, locals}, blkStms) = let |
132 |
fun doVar (x, TREE e, (locals, stms)) = let |
fun doVar (x, TREE e, (locals, stms)) = let |
133 |
val t = newLocal x |
val t = newLocal x |
134 |
in |
in |
225 |
fun trCFG (env, prefix, finish, cfg) = let |
fun trCFG (env, prefix, finish, cfg) = let |
226 |
fun join (env, [], _, IL.JOIN _) = raise Fail "JOIN with no open if" |
fun join (env, [], _, IL.JOIN _) = raise Fail "JOIN with no open if" |
227 |
| join (env, [], _, _) = raise Fail "no path to exit unimplemented" (* FIXME *) |
| join (env, [], _, _) = raise Fail "no path to exit unimplemented" (* FIXME *) |
228 |
| join (env, THEN_BR(stms1, cond, elseBr)::stk, stms, k) = |
| join (env, THEN_BR(stms1, cond, elseBr)::stk, thenBlk, k) = let |
229 |
doNode (env, ELSE_BR(stms1, cond, stms, k)::stk, [], elseBr) |
val (env, thenBlk) = flushPending (env, thenBlk) |
230 |
| join (env, ELSE_BR(stms, cond, stms1, k1)::stk, stms2, k2) = let |
in |
231 |
val (env, thenBlk) = endBlock (env, stms1) |
doNode (env, ELSE_BR(stms1, cond, thenBlk, k)::stk, [], elseBr) |
232 |
val (env, elseBlk) = endBlock (env, stms2) |
end |
233 |
|
| join (env, ELSE_BR(stms, cond, thenBlk, k1)::stk, elseBlk, k2) = let |
234 |
|
val (env, elseBlk) = flushPending (env, elseBlk) |
235 |
in |
in |
236 |
case (k1, k2) |
case (k1, k2) |
237 |
of (IL.JOIN{phis, succ, ...}, IL.JOIN _) => let |
of (IL.JOIN{phis, succ, ...}, IL.JOIN _) => let |
261 |
of IL.NULL => raise Fail "unexpected NULL" |
of IL.NULL => raise Fail "unexpected NULL" |
262 |
| IL.ENTRY{succ} => doNode (env, ifStk, stms, !succ) |
| IL.ENTRY{succ} => doNode (env, ifStk, stms, !succ) |
263 |
| k as IL.JOIN{phis, succ, ...} => join (env, ifStk, stms, k) |
| k as IL.JOIN{phis, succ, ...} => join (env, ifStk, stms, k) |
264 |
| IL.COND{cond, trueBranch, falseBranch, ...} => |
| IL.COND{cond, trueBranch, falseBranch, ...} => let |
265 |
doNode (env, THEN_BR(stms, useVar env cond, !falseBranch)::ifStk, [], !trueBranch) |
val cond = useVar env cond |
266 |
|
val (env, stms) = flushPending (env, stms) |
267 |
|
in |
268 |
|
doNode (env, THEN_BR(stms, cond, !falseBranch)::ifStk, [], !trueBranch) |
269 |
|
end |
270 |
| IL.COM {text, succ, ...} => |
| IL.COM {text, succ, ...} => |
271 |
doNode (env, ifStk, T.S_Comment text :: stms, !succ) |
doNode (env, ifStk, T.S_Comment text :: stms, !succ) |
272 |
| IL.ASSIGN{stm, succ, ...} => let |
| IL.ASSIGN{stm, succ, ...} => let |