SCM Repository
View of /trunk/src/compiler/IL/dom-tree-fn.sml
Parent Directory
|
Revision Log
Revision 1788 -
(download)
(annotate)
Tue Apr 3 13:25:57 2012 UTC (9 years ago) by jhr
File size: 3959 byte(s)
Tue Apr 3 13:25:57 2012 UTC (9 years ago) by jhr
File size: 3959 byte(s)
porting some fixes from the vis12 branch
(* dom-tree-fn.sml * * COPYRIGHT (c) 2011 The Diderot Project (http://diderot-language.cs.uchicago.edu) * All rights reserved. *) signature DOMINANCE_TREE = sig structure IL : SSA (* compute the dominance-tree information for a CFG *) val computeTree : IL.cfg -> unit (* return the dominance-tree children associated with a given node. Note that children, * which are immediate successors of the node, will be listed first. *) val children : IL.node -> IL.node list (* cleanup the node properties used to store information about the tree *) val clear : IL.cfg -> unit end functor DomTreeFn (IL : SSA) : DOMINANCE_TREE = struct structure IL = IL structure Nd = IL.Node (* a property for COND nodes that maps them to their associated JOIN node * (if one exists). *) val { peekFn = getJoin : IL.node -> IL.node option, setFn = setJoin, clrFn = clrJoin, ... } = Nd.newProp (fn _ => raise Fail "join property") (* an element on the stack of open COND nodes. *) datatype open_if = THEN_BR of {cond : IL.node, elseBr : IL.node} | ELSE_BR of {cond : IL.node} (* compute the dominance-tree information for a CFG. Most of the immediate * dominator info is already present in the tree, since JOIN nodes are the * only ones with multiple predecessors, but we also need tree edges from * COND nodes to their matching JOIN (it it exists). We use properties * to implemented these edges *) fun computeTree cfg = let fun walk (ifStk : open_if list, nd) = (case Nd.kind nd of IL.NULL => raise Fail "unexpected NULL node" | IL.ENTRY{succ} => walk (ifStk, !succ) | IL.JOIN{preds, succ, ...} => if (List.length(!preds) > 1) then (case ifStk of [] => raise Fail "unmatched JOIN" | THEN_BR{cond, elseBr}::r => ( setJoin(cond, nd); walk (ELSE_BR{cond=cond}::r, elseBr)) | ELSE_BR{cond}::r => ( walk (r, !succ)) (* end case *)) else walk(List.tl ifStk, !succ) | IL.COND{trueBranch, falseBranch, ...} => walk (THEN_BR{cond=nd, elseBr = !falseBranch}::ifStk, !trueBranch) | IL.COM{succ, ...} => walk (ifStk, !succ) | IL.ASSIGN{succ, ...} => walk (ifStk, !succ) | IL.MASSIGN{succ, ...} => walk (ifStk, !succ) | IL.NEW{succ, ...} => walk (ifStk, !succ) | IL.SAVE{succ, ...} => walk (ifStk, !succ) | IL.EXIT _ => resume ifStk (* end case *)) and resume [] = () | resume (THEN_BR{cond, elseBr}::r) = walk (ELSE_BR{cond=cond}::r, elseBr) | resume (ELSE_BR{cond}::r) = (case getJoin cond of NONE => resume r | SOME nd' => walk(r, nd') (* end case *)) in walk ([], IL.CFG.entry cfg) end (* get the dominance-tree children associated with a given node *) fun children nd = let (* check to see if a successor node is immediately dominated by nd. *) fun maybeSucc (ref nd') = (case Nd.kind nd' of IL.JOIN{preds, ...} => (case !preds of [_] => [nd'] (* JOIN with single predecessor *) | _ => [] (* end case *)) | IL.COM{succ, ...} => maybeSucc succ (* skip comments *) | _ => [nd'] (* end case *)) in case Nd.kind nd of IL.NULL => raise Fail "unexpected NULL node" | IL.ENTRY{succ} => maybeSucc succ | IL.JOIN{succ, ...} => maybeSucc succ | IL.COND{trueBranch, falseBranch, ...} => (case getJoin nd of SOME nd' => maybeSucc trueBranch @ maybeSucc falseBranch @ [nd'] | NONE => [!trueBranch, !falseBranch] (* end case *)) | IL.COM{succ, ...} => maybeSucc succ | IL.ASSIGN{succ, ...} => maybeSucc succ | IL.MASSIGN{succ, ...} => maybeSucc succ | IL.NEW{succ, ...} => maybeSucc succ | IL.SAVE{succ, ...} => maybeSucc succ | IL.EXIT _ => [] (* end case *) end (* cleanup the node properties used to store information about the tree *) fun clear cfg = IL.CFG.apply clrJoin cfg end
root@smlnj-gforge.cs.uchicago.edu | ViewVC Help |
Powered by ViewVC 1.0.0 |