84 |
end (* local *) |
end (* local *) |
85 |
|
|
86 |
fun rewriteCFG cfg = let |
fun rewriteCFG cfg = let |
|
(* in case the exit node get rewritten, we need to reset it *) |
|
|
val exitNd = ref(IR.CFG.exit cfg) |
|
87 |
(* rewrite or delete a node, if necessary. Note that we have already rewritten the JOIN nodes *) |
(* rewrite or delete a node, if necessary. Note that we have already rewritten the JOIN nodes *) |
88 |
fun doNode nd = (case IR.Node.kind nd |
fun doNode nd = (case IR.Node.kind nd |
89 |
of IR.COND{pred, cond, trueBranch, falseBranch} => |
of IR.COND{cond as ref x, ...} => |
90 |
if changed cond |
if changed x |
91 |
then let |
then cond := rename x |
92 |
val newNd = IR.Node.mkCOND (rename cond) |
else () |
93 |
in |
| IR.FOREACH{src as ref x, ...} => |
94 |
IR.Node.replaceInEdge {src = !pred, oldDst = nd, dst = newNd}; |
if changed x |
95 |
IR.Node.replaceOutEdge {oldSrc = nd, src = newNd, dst = !trueBranch}; |
then src := rename x |
|
IR.Node.replaceOutEdge {oldSrc = nd, src = newNd, dst = !falseBranch} |
|
|
end |
|
|
else () |
|
|
| IR.FOREACH{pred, phis, mask, var, src, bodyEntry, bodyExit, succ} => |
|
|
if changed src |
|
|
then let |
|
|
val newNd = IR.Node.mkFOREACH (var, rename src) |
|
|
in |
|
|
IR.Node.replaceInEdge {src = !pred, oldDst = nd, dst = newNd}; |
|
|
IR.Node.replaceInEdge {src = !bodyExit, oldDst = nd, dst = newNd}; |
|
|
IR.Node.replaceOutEdge {oldSrc = nd, src = newNd, dst = !bodyEntry}; |
|
|
IR.Node.replaceOutEdge {oldSrc = nd, src = newNd, dst = !succ} |
|
|
end |
|
96 |
else () |
else () |
97 |
| IR.ASSIGN{stm=(y, rhs), succ, ...} => |
| IR.ASSIGN{stm=(y, rhs), succ, ...} => |
98 |
if changed y |
if changed y |
133 |
if changed rhs |
if changed rhs |
134 |
then IR.CFG.replaceNode(nd, IR.Node.mkSAVE(lhs, rename rhs)) |
then IR.CFG.replaceNode(nd, IR.Node.mkSAVE(lhs, rename rhs)) |
135 |
else () |
else () |
|
| IR.EXIT{kind, ...} => () |
|
136 |
| _ => () |
| _ => () |
137 |
(* end case *)) |
(* end case *)) |
138 |
val _ = List.app doNode (IR.CFG.sort cfg) |
val _ = List.app doNode (IR.CFG.sort cfg) |
|
val cfg = IR.CFG{entry = IR.CFG.entry cfg, exit = !exitNd} |
|
139 |
in |
in |
140 |
IR.CFG.apply clearNode cfg; |
IR.CFG.apply clearNode cfg; |
141 |
cfg |
cfg |