96 |
env = env, arity = ref arity, nd = IL.Node.mkJOIN [], phiMap = ref VMap.empty, |
env = env, arity = ref arity, nd = IL.Node.mkJOIN [], phiMap = ref VMap.empty, |
97 |
predKill = Array.array(arity, false) |
predKill = Array.array(arity, false) |
98 |
} |
} |
|
(* create a new pending-join node with a given CFG Node *) |
|
|
fun newJoinWithNode (env, arity,node) = JOIN{ |
|
|
env = env, arity = ref arity, nd = node, phiMap = ref VMap.empty, |
|
|
predKill = Array.array(arity, false) |
|
|
} |
|
99 |
|
|
100 |
(* record that a path to the top join in the stack has been killed because f DIE or STABILIZE *) |
(* record that a path to the top join in the stack has been killed because f DIE or STABILIZE *) |
101 |
fun killPath ((i, JOIN{arity, predKill, ...}) :: _) = ( |
fun killPath ((i, JOIN{arity, predKill, ...}) :: _) = ( |
267 |
end |
end |
268 |
| S.S_Foreach(x,blk) => let |
| S.S_Foreach(x,blk) => let |
269 |
val x' = lookup env x |
val x' = lookup env x |
270 |
|
val join = newJoin (env, 1) |
271 |
|
val (cfg0, _) = cvtBlock (state, env, (0, join)::joinStk, blk) |
272 |
val forNode = IL.Node.mkFOREACH{ |
val forNode = IL.Node.mkFOREACH{ |
273 |
cond = x', |
cond = x', |
274 |
stmBranch = IL.Node.dummy |
stmBranch = IL.Node.dummy |
275 |
} |
} |
|
val join = newJoinWithNode(env, 1,forNode) |
|
|
val (cfg0, _) = cvtBlock (state, env, (0, join)::joinStk, blk) |
|
276 |
in |
in |
277 |
case commitJoin (joinStk, join) |
case commitJoin (joinStk, join) |
278 |
of (env, SOME joinNd) => ( |
of (env, SOME joinNd) => ( |
279 |
if IL.CFG.isEmpty cfg0 |
if IL.CFG.isEmpty cfg0 |
280 |
then ( |
then ( |
281 |
IL.Node.addEdge (IL.CFG.exit cfg, joinNd); |
()) |
|
IL.Node.setPred (joinNd, IL.CFG.exit cfg)) |
|
282 |
else ( |
else ( |
283 |
IL.Node.addEdge (IL.CFG.exit cfg, joinNd); |
IL.Node.addEdge (forNode,joinNd); |
284 |
IL.Node.setPred (IL.CFG.entry cfg0, joinNd); |
IL.Node.setPred (IL.CFG.entry cfg0, forNode); |
285 |
IL.Node.setStmBranch(forNode, IL.CFG.entry cfg0); |
IL.Node.setStmBranch(forNode, IL.CFG.entry cfg0); |
286 |
IL.Node.addEdge (IL.CFG.exit cfg0, joinNd)); |
IL.Node.addEdge (IL.CFG.exit cfg0, joinNd)); |
287 |
cvt ( |
cvt ( |
288 |
env, |
env, |
289 |
IL.CFG.concat ( |
IL.CFG.appendNode(cfg, joinNd), |
|
cfg, |
|
|
IL.CFG{entry = joinNd, exit = joinNd}), |
|
290 |
stms)) |
stms)) |
291 |
|
|
292 |
|
|
293 |
(* the join node has only zero predecessors, so |
(* the join node has only zero predecessors, so |
294 |
* it was killed. |
* it was killed. *) |
295 |
*) |
|
296 |
| (env, NONE) => raise Fail "unimplemented" (* FIXME *) |
| (env, NONE) => raise Fail "unimplemented" (* FIXME *) |
297 |
(* end case *) |
(* end case *) |
298 |
end |
end |