|
|
1.1 root 1: (* Copyright 1989 by AT&T Bell Laboratories *)
2: signature FREEMAP =
3: sig
4: val freemap : (CPS.lvar -> bool)
5: -> (CPS.lvar * CPS.lvar list -> unit)
6: -> (CPS.cexp -> CPS.lvar list)
7: val freemapClose : CPS.cexp * (CPS.lvar -> bool)
8: -> (CPS.lvar -> CPS.lvar list)
9: end
10:
11: structure FreeMap : FREEMAP =
12: struct
13: open CPS SortedList
14:
15: fun sublist test =
16: let fun subl(a::r) = if test a then a::(subl r) else subl r
17: | subl nil = nil
18: in subl
19: end
20:
21: fun freemap constant add =
22: let val clean = (sublist (not o constant)) o uniq
23: val enter = fn (x,y) => if constant x then y else enter(x,y)
24: fun setvars (w,free) = let val g = rem(w,free)
25: in add(w,g); g
26: end
27: val rec freevars =
28: fn APP(v,args) => enter(v,clean args)
29: | SWITCH(v,l) => enter(v,foldmerge (map freevars l))
30: | RECORD(l,w,ce) => merge(clean (map #1 l), setvars(w, freevars ce))
31: | SELECT(_,v,w,ce) => enter(v, setvars(w, freevars ce))
32: | OFFSET(_,v,w,ce) => enter(v, setvars(w, freevars ce))
33: | PRIMOP(_,args,ret,ce) =>
34: let fun f(nil,a) = a
35: | f(w::wl,a) = f(wl,setvars(w,a))
36: in merge(clean args,f(ret,foldmerge(map freevars ce)))
37: end
38: | FIX _ => ErrorMsg.impossible "FIX in Freemap.freemap"
39: in freevars
40: end
41:
42: (* Produces a free variable mapping at each function binding.
43: The mapping includes the functions bound at the FIX, but
44: not the arguments of the function.
45: It assumes that the only lvars which refer to constants
46: are the arguments of PRIMOPs, contents of RECORDs, and
47: arguments of APPs. In particular, the optimizer had better
48: get rid of SWITCHes on constants. *)
49: fun freemapClose(ce,constant) =
50: let exception Freemap
51: val vars : lvar list Intmap.intmap = Intmap.new(32, Freemap)
52: val notconst = sublist (not o constant)
53: fun setvars(v,l) = (Intmap.add vars (v,l); l)
54: val rec freevars =
55: fn FIX(l,ce) =>
56: let val functions = uniq(map #1 l)
57: val freel = map (fn(v,args,body) =>
58: setvars(v,remove(uniq args,freevars body)))
59: l
60: in remove(functions,foldmerge((freevars ce)::freel))
61: end
62: | APP(v,args) => enter(v,notconst(uniq args))
63: | SWITCH(v,l) => foldmerge ([v]::(map freevars l))
64: | RECORD(l,w,ce) => merge(notconst(uniq(map #1 l)),
65: rem(w,freevars ce))
66: | SELECT(_,v,w,ce) => enter(v,rem(w,freevars ce))
67: | OFFSET(_,v,w,ce) => enter(v,rem(w,freevars ce))
68: | PRIMOP(_,args,ret,ce) =>
69: let val args = notconst(uniq args)
70: in merge(args,remove(uniq ret,foldmerge(map freevars ce)))
71: end
72: in freevars ce; Intmap.map vars
73: end
74:
75: (* temporary, for debugging *)
76: fun timeit f a =
77: let val t = System.Timer.start_timer()
78: val r = f a
79: in System.Stats.update(System.Stats.freemap,System.Timer.check_timer t);
80: r
81: end
82: val freemap = timeit freemap
83: val freemapClose = timeit freemapClose
84:
85: end (* structure FreeMap *)
86:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.