1 |
(* ssa.sml |
(* ssa-fn.sml |
2 |
* |
* |
3 |
* COPYRIGHT (c) 2010 The Diderot Project (http://diderot.cs.uchicago.edu) |
* COPYRIGHT (c) 2010 The Diderot Project (http://diderot.cs.uchicago.edu) |
4 |
* All rights reserved. |
* All rights reserved. |
5 |
|
* |
6 |
|
* The IL is a combination of a block-structured tree and an SSA control-flow |
7 |
|
* graph of blocks. |
8 |
*) |
*) |
9 |
|
|
10 |
functor SSAFn (Op : OPERATORS) = |
signature SSA = |
11 |
|
sig |
12 |
|
structure Op : OPERATORS |
13 |
|
|
14 |
|
datatype var = V of { |
15 |
|
name : string, (* name *) |
16 |
|
id : Stamp.stamp, (* unique ID *) |
17 |
|
useCnt : int ref, (* count of uses *) |
18 |
|
props : PropList.holder |
19 |
|
} |
20 |
|
|
21 |
|
datatype stmt |
22 |
|
= BLOCK of block |
23 |
|
| SEQ of stmt list |
24 |
|
| IF of { |
25 |
|
pre : block, |
26 |
|
cond : var, |
27 |
|
trueBranch : stmt |
28 |
|
falseBranch : stmt |
29 |
|
} |
30 |
|
| WHILE of { |
31 |
|
hdr : block, |
32 |
|
cond : var, |
33 |
|
body : stmt |
34 |
|
} |
35 |
|
|
36 |
|
and block = BLK of { |
37 |
|
parent : stmt ref, (* parent statement of this block *) |
38 |
|
id : Stamp.stamp, (* unique ID *) |
39 |
|
preds : block list ref, (* list of predecessor blocks in the CFG *) |
40 |
|
phi : (var * var list) list ref, (* phi statements *) |
41 |
|
body : simple_stmt list ref, |
42 |
|
succs : block list ref (* successor blocks in the CFG *) |
43 |
|
} |
44 |
|
|
45 |
|
and simple_stmt |
46 |
|
= ASSIGN of var * rhs |
47 |
|
| DIE |
48 |
|
| STABILIZE |
49 |
|
| RETURN |
50 |
|
|
51 |
|
and rhs |
52 |
|
= VAR of var |
53 |
|
| OP of Op.rator * var list |
54 |
|
|
55 |
|
val newVar : string -> var |
56 |
|
val newBlock : unit -> block |
57 |
|
|
58 |
|
end |
59 |
|
|
60 |
|
functor SSAFn (Op : OPERATORS) : SSA = |
61 |
struct |
struct |
62 |
|
|
63 |
datatype var = V of { |
datatype var = V of { |
64 |
name : string |
name : string, (* name *) |
65 |
|
id : Stamp.stamp, (* unique ID *) |
66 |
|
useCnt : int ref, (* count of uses *) |
67 |
|
props : PropList.holder |
68 |
} |
} |
69 |
|
|
70 |
datatype block = BLK of { |
datatype stmt |
71 |
id : label, |
= BLOCK of block |
72 |
preds : block list ref, |
| SEQ of stmt list |
73 |
phi : (var * var list) list ref, |
| IF of { |
74 |
stms : stm list ref, |
pre : block, |
75 |
xfer : transfer ref |
cond : var, |
76 |
|
trueBranch : stmt |
77 |
|
falseBranch : stmt |
78 |
|
} |
79 |
|
| WHILE of { |
80 |
|
hdr : block, |
81 |
|
cond : var, |
82 |
|
body : stmt |
83 |
} |
} |
84 |
|
|
85 |
and stm |
and block = BLK of { |
86 |
= ASSIGN of var * exp |
parent : stmt ref, (* parent statement of this block *) |
87 |
|
id : Stamp.stamp, (* unique ID *) |
88 |
|
preds : block list ref, (* list of predecessor blocks in the CFG *) |
89 |
|
phi : (var * var list) list ref, (* phi statements *) |
90 |
|
body : simple_stmt list ref, |
91 |
|
succs : block list ref (* successor blocks in the CFG *) |
92 |
|
} |
93 |
|
|
94 |
and xfer |
and simple_stmt |
95 |
= GOTO of label (* unconditional transfer *) |
= ASSIGN of var * rhs |
96 |
| COND of var * label * label (* conditional transfer *) |
| DIE |
97 |
| DIE (* actor termination *) |
| STABILIZE |
98 |
| STABILIZE (* actor stabilization node *) |
| RETURN |
|
| EXIT (* exit node *) |
|
99 |
|
|
100 |
and exp |
and rhs |
101 |
= VAR of var |
= VAR of var |
102 |
| OP of Op.rator * var list |
| OP of Op.rator * var list |
103 |
|
|
104 |
|
(* block properties *) |
105 |
|
fun parentOf (BLK{parent, ...}) = !parent |
106 |
|
fun predsOf (BLK{preds, ...}) = !preds |
107 |
|
fun succsOf (BLK{succs, ...}) = !succs |
108 |
|
|
109 |
|
(* IL construction code *) |
110 |
|
fun newVar name = V{ |
111 |
|
name = name, |
112 |
|
id = Stamp.new(), |
113 |
|
useCnt = ref 0, |
114 |
|
props = PropList.newHolder() |
115 |
|
} |
116 |
|
|
117 |
|
fun newBlock () = BLK{ |
118 |
|
parent = ref(SEQ[]), |
119 |
|
id = Stamp.new(), |
120 |
|
preds = ref[], |
121 |
|
phi = ref[], |
122 |
|
body = ref[], |
123 |
|
succs = ref[] |
124 |
|
} |
125 |
|
|
126 |
|
local |
127 |
|
fun setParent (BKL{parent, ...}, s) = (parent := s) |
128 |
|
in |
129 |
|
fun mkBLOCK blk = let |
130 |
|
val s = BLOCK blk |
131 |
|
in |
132 |
|
setParent (blk, s); |
133 |
|
s |
134 |
|
end |
135 |
|
|
136 |
|
fun mkIF (pre, cond, t, f) = let |
137 |
|
val s = IF{pre=pre, cond=cond, trueBranch=t, falseBranch=f} |
138 |
|
in |
139 |
|
setParent (pre, s); |
140 |
|
s |
141 |
|
end |
142 |
|
|
143 |
|
fun mkWHILE (hdr, cond, body) = let |
144 |
|
val s = WHILE{hdr=hdr, cond=cond, body=body} |
145 |
|
in |
146 |
|
setParent (hdr, s); |
147 |
|
s |
148 |
|
end |
149 |
|
|
150 |
|
end (* local *) |
151 |
|
|
152 |
end |
end |