16 |
val called : info -> bool (* known call uses *) |
val called : info -> bool (* known call uses *) |
17 |
val dead : info -> bool (* usenb = 0 ? *) |
val dead : info -> bool (* usenb = 0 ? *) |
18 |
val usenb : info -> int (* total nb of uses *) |
val usenb : info -> int (* total nb of uses *) |
19 |
val actuals : info -> (FLINT.value option list) (* constant args *) |
val callnb : info -> int (* total nb of calls *) |
20 |
|
|
21 |
(* self-referential (i.e. internal) uses *) |
(* self-referential (i.e. internal) uses *) |
22 |
val iusenb : info -> int |
val iusenb : info -> int |
99 |
|
|
100 |
datatype info |
datatype info |
101 |
(* we keep track of calls and escaping uses *) |
(* we keep track of calls and escaping uses *) |
102 |
= Info of {calls: int ref, uses: int ref, int: (int * int) ref, |
= Info of {calls: int ref, uses: int ref, int: (int * int) ref} |
|
args: (FLINT.lvar * (FLINT.value option)) option list ref option} |
|
103 |
|
|
104 |
exception NotFound |
exception NotFound |
105 |
|
|
106 |
val m : info M.intmap = M.new(128, NotFound) |
val m : info M.intmap = M.new(128, NotFound) |
107 |
|
|
108 |
fun new args lv = |
fun new args lv = |
109 |
let val i = Info{uses=ref 0, calls=ref 0, int=ref(0,0), |
let val i = Info{uses=ref 0, calls=ref 0, int=ref(0,0)} |
|
args=case args |
|
|
of SOME args => |
|
|
SOME(ref(map (fn a => SOME(a, NONE)) args)) |
|
|
| NONE => NONE} |
|
110 |
in M.add m (lv, i); i |
in M.add m (lv, i); i |
111 |
end |
end |
112 |
|
|
150 |
| mergearg (SOME(fv,SOME b),a) = |
| mergearg (SOME(fv,SOME b),a) = |
151 |
if a = b orelse a = F.VAR fv then SOME(fv,SOME b) else NONE |
if a = b orelse a = F.VAR fv then SOME(fv,SOME b) else NONE |
152 |
|
|
153 |
fun actuals (Info{args=NONE,...}) = bug "no actuals (maybe a var?)" |
fun use call (Info{uses,calls,...}) = |
|
| actuals (Info{args=SOME args,...}) = map (fn SOME(_,v) => v | _ => NONE) (!args) |
|
|
|
|
|
fun use call (Info{uses,calls,args,...}) = |
|
154 |
(inc uses; |
(inc uses; |
155 |
case call |
case call |
156 |
of NONE => (case args of SOME args => args := map (fn _ => NONE) (!args) |
of NONE => () |
|
| _ => ()) |
|
157 |
| SOME vals => |
| SOME vals => |
158 |
(inc calls; |
inc calls) |
|
case args of SOME args => args := ListPair.map mergearg (!args, vals) |
|
|
| _ => ())) |
|
159 |
|
|
160 |
fun unuse call (Info{uses,calls,...}) = |
fun unuse call (Info{uses,calls,...}) = |
161 |
(* notice the calls could be dec'd to negative values because a |
(* notice the calls could be dec'd to negative values because a |
169 |
else !uses = 0) |
else !uses = 0) |
170 |
|
|
171 |
fun usenb (Info{uses=ref uses,...}) = uses |
fun usenb (Info{uses=ref uses,...}) = uses |
172 |
|
fun callnb (Info{calls=ref calls,...}) = calls |
173 |
fun used (Info{uses,...}) = !uses > 0 |
fun used (Info{uses,...}) = !uses > 0 |
174 |
fun dead (Info{uses,...}) = !uses = 0 |
fun dead (Info{uses,...}) = !uses = 0 |
175 |
fun escaping (Info{uses,calls,...}) = !uses > !calls |
fun escaping (Info{uses,calls,...}) = !uses > !calls |