Home My Page Projects Code Snippets Project Openings diderot
Summary Activity Tracker Tasks SCM

SCM Repository

[diderot] Annotation of /branches/pure-cfg/src/compiler/IL/dom-tree-fn.sml
ViewVC logotype

Annotation of /branches/pure-cfg/src/compiler/IL/dom-tree-fn.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 740 - (view) (download)

1 : jhr 740 (* dom-tree-fn.sml
2 :     *
3 :     * COPYRIGHT (c) 2011 The Diderot Project (http://diderot-language.cs.uchicago.edu)
4 :     * All rights reserved.
5 :     *)
6 :    
7 :     signature DOMINANCE_TREE =
8 :     sig
9 :    
10 :     structure IL : SSA
11 :    
12 :     (* compute the dominance-tree information for a CFG *)
13 :     val computeTree : IL.cfg -> unit
14 :    
15 :     (* get the dominance-tree children associated with a given node *)
16 :     val children : IL.node -> IL.node list
17 :    
18 :     (* cleanup the node properties used to store information about the tree *)
19 :     val clear : IL.cfg -> unit
20 :    
21 :     end
22 :    
23 :     functor DomTreeFn (IL : SSA) : DOMINANCE_TREE = struct
24 :    
25 :     structure IL = IL
26 :     structure Nd = IL.Node
27 :    
28 :     (* a property for COND nodes that maps them to their associated JOIN node
29 :     * (if one exists).
30 :     *)
31 :     val {
32 :     peekFn = getJoin : IL.node -> IL.node option,
33 :     setFn = setJoin, clrFn = clrJoin, ...
34 :     } = Nd.newProp (fn _ => raise Fail "join property")
35 :    
36 :     (* an element on the stack of open COND nodes. *)
37 :     datatype open_if
38 :     = THEN_BR of {cond : IL.node, elseBr : IL.node}
39 :     | ELSE_BR of {cond : IL.node}
40 :    
41 :     (* compute the dominance-tree information for a CFG. Most of the immediate
42 :     * dominator info is already present in the tree, since JOIN nodes are the
43 :     * only ones with multiple predecessors, but we also need tree edges from
44 :     * COND nodes to their matching JOIN (it it exists). We use properties
45 :     * to implemented these edges
46 :     *)
47 :     fun computeTree cfg = let
48 :     fun walk (ifStk : open_if list, nd) = (case Nd.kind nd
49 :     of IL.NULL => raise Fail "unexpected NULL node"
50 :     | IL.ENTRY{succ} => walk (ifStk, !succ)
51 :     | IL.JOIN{succ, ...} => (case ifStk
52 :     of [] => raise Fail "unmatched JOIN"
53 :     | THEN_BR{cond, elseBr}::r => (
54 :     setJoin(cond, nd);
55 :     walk (ELSE_BR{cond=cond}::r, elseBr))
56 :     | ELSE_BR{cond}::r => (
57 :     setJoin(cond, nd); (* may be redundant *)
58 :     walk (r, !succ))
59 :     (* end case *))
60 :     | IL.COND{trueBranch, falseBranch, ...} =>
61 :     walk (THEN_BR{cond=nd, elseBr = !falseBranch}::ifStk, !trueBranch)
62 :     | IL.COM{succ, ...} => walk (ifStk, !succ)
63 :     | IL.ASSIGN{succ, ...} => walk (ifStk, !succ)
64 :     | IL.NEW{succ, ...} => walk (ifStk, !succ)
65 :     | IL.EXIT _ => resume ifStk
66 :     (* end case *))
67 :     and resume [] = ()
68 :     | resume (THEN_BR{cond, elseBr}::r) = walk (ELSE_BR{cond=cond}::r, elseBr)
69 :     | resume (ELSE_BR{cond}::r) = (case getJoin cond
70 :     of NONE => resume r
71 :     | SOME nd' => walk(r, nd')
72 :     (* end case *))
73 :     in
74 :     walk ([], IL.CFG.entry cfg)
75 :     end
76 :    
77 :     (* get the dominance-tree children associated with a given node *)
78 :     fun children nd = let
79 :     (* check to see if a successor node is immediately dominated by nd. *)
80 :     fun maybeSucc (ref nd') = (case Nd.kind nd'
81 :     of IL.JOIN{preds, ...} => (case !preds
82 :     of [_] => [nd'] (* JOIN with single predecessor *)
83 :     | _ => []
84 :     (* end case *))
85 :     | IL.COM{succ, ...} => maybeSucc succ (* skip comments *)
86 :     | _ => [nd']
87 :     (* end case *))
88 :     in
89 :     case Nd.kind nd
90 :     of IL.NULL => raise Fail "unexpected NULL node"
91 :     | IL.ENTRY{succ} => maybeSucc succ
92 :     | IL.JOIN{succ, ...} => maybeSucc succ
93 :     | IL.COND{trueBranch, falseBranch, ...} => (case getJoin nd
94 :     of SOME nd' => [!trueBranch, !falseBranch, nd']
95 :     | NONE => [!trueBranch, !falseBranch]
96 :     (* end case *))
97 :     | IL.COM{succ, ...} => maybeSucc succ
98 :     | IL.ASSIGN{succ, ...} => maybeSucc succ
99 :     | IL.NEW{succ, ...} => maybeSucc succ
100 :     | IL.EXIT _ => []
101 :     (* end case *)
102 :     end
103 :    
104 :     (* cleanup the node properties used to store information about the tree *)
105 :     fun clear cfg = IL.CFG.apply clrJoin cfg
106 :    
107 :     end

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0