13 |
val init : IL.program -> unit |
val init : IL.program -> unit |
14 |
|
|
15 |
val inc : IL.var -> unit |
val inc : IL.var -> unit |
16 |
|
val dec : IL.var -> unit |
17 |
|
|
18 |
end = struct |
end = struct |
19 |
|
|
20 |
structure IL = IL |
structure IL = IL |
21 |
|
|
22 |
fun inc (IL.V{useCnt, ...}) = (useCnt := !useCnt + 1) |
fun inc (IL.V{useCnt, ...}) = (useCnt := !useCnt + 1) |
23 |
|
fun dec (IL.V{useCnt, ...}) = (useCnt := !useCnt - 1) |
24 |
fun setBinding (IL.V{bind, ...}, vb) = bind := vb |
fun setBinding (IL.V{bind, ...}, vb) = bind := vb |
25 |
|
|
26 |
fun init (IL.Program{globals, globalInit, strands}) = let |
fun init (IL.Program{globalInit, initially, strands}) = let |
27 |
fun clearVar (IL.V{useCnt, ...}) = useCnt := 0 |
fun clearVar (IL.V{useCnt, ...}) = useCnt := 0 |
28 |
(* clear the counts of the variables defined in a node *) |
(* clear the counts of the variables defined in a node *) |
29 |
fun clearNode (IL.ND{kind, ...}) = (case kind |
fun clearNode (IL.ND{kind, ...}) = (case kind |
30 |
of IL.JOIN{phis, ...} => List.app (fn (x, _) => clearVar x) (!phis) |
of IL.JOIN{phis, ...} => List.app (fn (x, _) => clearVar x) (!phis) |
31 |
| IL.BLOCK{body, ...} => List.app (fn (x, _) => clearVar x) (!body) |
| IL.ASSIGN{stm=(x, _), ...} => clearVar x |
32 |
| _ => () |
| _ => () |
33 |
(* end case *)) |
(* end case *)) |
34 |
|
(* clear the counts of the initially code *) |
35 |
|
fun clearInitially (IL.Initially{rangeInit, iters, create, ...}) = let |
36 |
|
fun clearIter (param, lo, hi) = clearVar param |
37 |
|
in |
38 |
|
IL.CFG.apply clearNode rangeInit; |
39 |
|
List.app clearIter iters; |
40 |
|
IL.CFG.apply clearNode (#1 create) |
41 |
|
end |
42 |
(* clear the counts of the variables defined in an strand *) |
(* clear the counts of the variables defined in an strand *) |
43 |
fun clearStrand (IL.Strand{params, state, stateInit, methods, ...}) = let |
fun clearStrand (IL.Strand{params, state, stateInit, methods, ...}) = let |
44 |
fun clearMethod (IL.Method{stateIn, body, ...}) = ( |
fun clearMethod (IL.Method{stateIn, body, ...}) = ( |
45 |
List.app clearVar stateIn; |
List.app clearVar stateIn; |
46 |
IL.applyToNodes clearNode body) |
IL.CFG.apply clearNode body) |
47 |
in |
in |
48 |
List.app clearVar params; |
List.app clearVar params; |
49 |
List.app clearVar state; |
List.app (clearVar o #2) state; |
50 |
IL.applyToNodes clearNode stateInit; |
IL.CFG.apply clearNode stateInit; |
51 |
List.app clearMethod methods |
List.app clearMethod methods |
52 |
end |
end |
53 |
(* increment the use counts of a list of variables *) |
(* increment the use counts of a list of variables *) |
62 |
List.app f (!phis) |
List.app f (!phis) |
63 |
end |
end |
64 |
| IL.COND{cond, ...} => inc cond |
| IL.COND{cond, ...} => inc cond |
65 |
| IL.BLOCK{body, ...} => let |
| IL.ASSIGN{stm = (y, rhs), ...} => ( |
|
fun incRHS (y, rhs) = ( |
|
66 |
setBinding (y, IL.VB_RHS rhs); |
setBinding (y, IL.VB_RHS rhs); |
67 |
case rhs |
case rhs |
68 |
of (IL.VAR x) => inc x |
of (IL.VAR x) => inc x |
69 |
| (IL.LIT _) => () |
| (IL.LIT _) => () |
70 |
| (IL.OP(_, args)) => incList args |
| (IL.OP(_, args)) => incList args |
71 |
| (IL.CONS args) => incList args |
| (IL.APPLY(_, args)) => incList args |
72 |
|
| (IL.CONS(_, args)) => incList args |
73 |
(* end case *)) |
(* end case *)) |
|
in |
|
|
List.app incRHS (!body) |
|
|
end |
|
74 |
| IL.NEW{args, ...} => incList args |
| IL.NEW{args, ...} => incList args |
75 |
|
| IL.EXIT{kind, live, ...} => (case kind |
76 |
|
of ExitKind.RETURN => () (* don't count the live variables as uses *) |
77 |
|
| ExitKind.DIE => () |
78 |
|
| _ => incList live |
79 |
|
(* end case *)) |
80 |
| _ => () |
| _ => () |
81 |
(* end case *)) |
(* end case *)) |
82 |
|
(* increment the counts of variables used in the initially code *) |
83 |
|
fun incInitially (IL.Initially{create, rangeInit, iters, ...}) = let |
84 |
|
fun incIter (param, lo, hi) = ( |
85 |
|
setBinding (param, IL.VB_PARAM); (* QUESTION: should there be a special kind for this? *) |
86 |
|
inc lo; inc hi) |
87 |
|
in |
88 |
|
IL.CFG.apply incNode rangeInit; |
89 |
|
List.app incIter iters; |
90 |
|
IL.CFG.apply incNode (#1 create); |
91 |
|
List.app inc (#3 create) |
92 |
|
end |
93 |
(* increment the counts of the variables used in a strand *) |
(* increment the counts of the variables used in a strand *) |
94 |
fun incStrand (IL.Strand{params, state, stateInit, methods, ...}) = let |
fun incStrand (IL.Strand{params, state, stateInit, methods, ...}) = let |
95 |
fun incMethod (IL.Method{stateIn, stateOut, body, ...}) = ( |
fun incMethod (IL.Method{stateIn, body, ...}) = ( |
96 |
List.app (fn x => setBinding(x, IL.VB_STATE_VAR)) stateIn; |
ListPair.app |
97 |
incList stateOut; |
(fn (x, (_, x')) => IL.Var.setBinding(x, IL.VB_RHS(IL.VAR x'))) |
98 |
IL.applyToNodes incNode body) |
(stateIn, state); |
99 |
|
IL.CFG.apply incNode body) |
100 |
in |
in |
101 |
List.app (fn x => setBinding(x, IL.VB_PARAM)) params; |
List.app (fn x => setBinding(x, IL.VB_PARAM)) params; |
102 |
IL.applyToNodes incNode stateInit; |
List.app (inc o #2) state; (* state variables are implicitly used *) |
103 |
|
IL.CFG.apply incNode stateInit; |
104 |
List.app incMethod methods |
List.app incMethod methods |
105 |
end |
end |
106 |
in |
in |
107 |
(* first clear the counts of all variables *) |
(* first clear the counts of all variables *) |
108 |
List.app clearVar globals; |
IL.CFG.apply clearNode globalInit; |
109 |
IL.applyToNodes clearNode globalInit; |
clearInitially initially; |
110 |
List.app clearStrand strands; |
List.app clearStrand strands; |
111 |
(* then count uses *) |
(* then count uses *) |
112 |
IL.applyToNodes incNode globalInit; |
IL.CFG.apply incNode globalInit; |
113 |
|
incInitially initially; |
114 |
List.app incStrand strands |
List.app incStrand strands |
115 |
end |
end |
116 |
|
|