Home My Page Projects Code Snippets Project Openings SML/NJ
Summary Activity Forums Tracker Lists Tasks Docs Surveys News SCM Files

SCM Repository

[smlnj] Annotation of /sml/trunk/src/compiler/CodeGen/cpscompile/memDisambig.sml
ViewVC logotype

Annotation of /sml/trunk/src/compiler/CodeGen/cpscompile/memDisambig.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 418 - (view) (download)
Original Path: sml/branches/SMLNJ/src/compiler/CodeGen/cpscompile/memDisambig.sml

1 : monnier 245 (* memDisambig.sml --- generate a table of regions *)
2 :    
3 :     signature MEM_DISAMBIGUATION = sig
4 :     val build : CPS.function list -> (int -> CPSRegions.region)
5 :     end
6 :    
7 :    
8 :    
9 :     functor MemDisambiguate(structure Cells: CELLS) : MEM_DISAMBIGUATION = struct
10 :     structure C = CPS
11 :     structure P = CPS.P
12 :     structure R = CPSRegions
13 :    
14 :     fun error msg = ErrorMsg.impossible ("MemDisambiguate." ^ msg)
15 :    
16 :     exception MemDisambig and FormalsTbl
17 :     val newRegion = Cells.newCell Cells.MEM
18 :    
19 :     fun build(frags) = let
20 :     (* mapping of lvars to a list of regions that define it *)
21 :     (* mappings can only be RVAR, COPY, or RECORD *)
22 :     val regionTbl : R.region Intmap.intmap = Intmap.new(16, MemDisambig)
23 :     val enterRegion = Intmap.add regionTbl
24 :     val lookupRegion = Intmap.map regionTbl
25 :     fun peekRegion v = SOME(Intmap.map regionTbl v) handle _ => NONE
26 :     fun addRegion(arg as (x,v)) = (Intmap.rmv regionTbl x; enterRegion arg)
27 :    
28 :     (* compute the size of a CPS assuming that the allocation
29 :     * pointer has been appropriately aligned.
30 :     *)
31 :     fun sizeOf(cexp, hp) = let
32 :     val storeListSz = 8
33 :     fun frecord len = let
34 :     val hp = if Word.andb(Word.fromInt hp, 0w4) <> 0w0 then hp+4 else hp
35 :     in hp + 8*len + 4
36 :     end
37 :     fun record len = 4 + 4*len
38 :     in
39 :     case cexp
40 :     of C.RECORD(C.RK_FBLOCK, vl, _, e) => sizeOf(e, frecord(length vl))
41 :     | C.RECORD(C.RK_FCONT, vl, _, e) => sizeOf(e, frecord(length vl))
42 :     | C.RECORD(C.RK_VECTOR, vl, _, e) => sizeOf(e, hp+record(length vl + 3))
43 :     | C.RECORD(_, vl, _, e) => sizeOf(e, hp + record(length vl))
44 :     | C.SELECT(_, _, _, _, e) => sizeOf(e, hp)
45 :     | C.OFFSET(_,_,_,e) => sizeOf(e, hp)
46 :     | C.SWITCH(_,_,el) =>
47 :     List.foldl Int.max 0 (map (fn e => sizeOf(e, hp)) el)
48 :     | C.SETTER(P.update,_,e) => sizeOf(e, hp+storeListSz)
49 :     | C.SETTER(P.boxedupdate,_,e) => sizeOf(e, hp+storeListSz)
50 :     | C.SETTER(_, _, e) => sizeOf(e, hp)
51 :     | C.PURE(P.fwrap, _, _, _, e) => sizeOf(e, hp+frecord(1))
52 :     | C.PURE(P.mkspecial, _, _, _, e) => sizeOf(e, hp+8)
53 :     | C.PURE(P.makeref, _, _, _, e) => sizeOf(e, hp+8)
54 :     | C.PURE(P.i32wrap, _, _, _, e) => sizeOf(e, hp+record(2))
55 :     | C.PURE(P.newarray0, _, _, _, e) => sizeOf(e, hp+(4*5))
56 :     | C.PURE(_, _, _, _, e) => sizeOf(e, hp)
57 :     | C.ARITH(_, _, _, _, e) => sizeOf(e, hp)
58 :     | C.LOOKER(_,_,_,_,e) => sizeOf(e, hp)
59 :     | C.BRANCH(_,_,_,a,b) => Int.max(sizeOf(a, hp), sizeOf(b, hp))
60 :     | C.APP _ => hp
61 :     | C.FIX _ => error "sizeOf: FIX"
62 :     end
63 :    
64 :     val offp0 = C.OFFp 0
65 :    
66 :     fun funBody(_, _, _, _, cexp) = let
67 :     val regionIdTbl =
68 :     Array.tabulate(Int.quot(sizeOf(cexp, 0), 4), fn _ => newRegion())
69 :    
70 :     fun regionId hp = R.RVAR(Array.sub(regionIdTbl, Int.quot(hp, 4)))
71 :    
72 :     fun traceRoot(C.LABEL _) = R.RO_MEM
73 :     | traceRoot(C.VAR v) = (lookupRegion v handle MemDisambig => R.RO_MEM)
74 :     | traceRoot _ = R.RO_MEM
75 :    
76 :     fun iter(cexp, hp) = let
77 :    
78 :     fun desc hp = (regionId(hp), R.RO_MEM, offp0)
79 :    
80 :     fun record(vl, x, e) = let
81 :     fun fields ([], _) = []
82 :     | fields ((v, ap)::vl, hp) =
83 :     (regionId(hp), traceRoot v, ap)::fields(vl, hp+4)
84 :     in
85 :     enterRegion(x, R.RECORD(desc(hp)::fields(vl, hp+4)));
86 :     iter(e, hp + 4 + 4*length vl)
87 :     end
88 :    
89 :     fun frecord(vl, x, e) = let
90 :     fun regionPair hp = R.REGIONS(regionId hp, regionId(hp+4))
91 :     fun fields([], _) = []
92 :     | fields((v, ap)::vl, hp) =
93 :     (regionPair hp, traceRoot v, ap) :: fields(vl, hp+8)
94 :     val hp = if Word.andb(Word.fromInt hp, 0w4) <> 0w0 then hp+4 else hp
95 :     in
96 :     enterRegion(x, R.RECORD(desc(hp)::fields(vl, hp+4)));
97 :     iter (e, hp + 4 + 8*length vl)
98 :     end
99 :    
100 :     fun recordSlots((d, R.RECORD vl, _)::rest) =
101 :     R.REGIONS(d, recordSlots (vl@rest))
102 :     | recordSlots((d, R.OFFSET(_, vl), _)::rest) =
103 :     R.REGIONS(d, recordSlots (vl@rest))
104 :     | recordSlots [(d, _, _)] = d
105 :     | recordSlots((d, _, _)::rest) = R.REGIONS(d, recordSlots rest)
106 :    
107 :     fun update(C.VAR a, C.VAR v, e) =
108 :     (case (peekRegion a, peekRegion v)
109 :     of (NONE, NONE) => enterRegion(a, R.MUTABLE(R.RW_MEM, R.RO_MEM))
110 :     | (NONE, SOME(R.RECORD rl)) =>
111 :     enterRegion(a, R.MUTABLE(R.RW_MEM, recordSlots rl))
112 :     | (SOME _, NONE) => ()
113 :     | (SOME(R.MUTABLE(def,use)), SOME(R.RECORD rl)) =>
114 :     addRegion(a, R.MUTABLE(def, R.REGIONS(use, recordSlots rl)))
115 :     (*esac*);
116 :     iter(e, hp))
117 :     | update(_, _, e) = iter(e, hp)
118 :    
119 :     fun select(C.VAR v, i, x, e) =
120 :     (case peekRegion v
121 :     of SOME(R.RECORD vl) => let
122 :     val (_, region, ap) = List.nth(vl, i+1)
123 :     in enterRegion(x, R.trace(region, ap))
124 :     end
125 :     | SOME(R.OFFSET(j, vl)) => let
126 :     val (_, region, ap) = List.nth(vl, i+j+1)
127 :     in enterRegion(x, R.trace(region, ap))
128 :     end
129 :     | SOME(R.MUTABLE _) => error "select"
130 :     | _ => ()
131 :     (*esac*);
132 :     iter(e, hp))
133 :     | select(_, _, _, e) = iter(e, hp)
134 :    
135 :     fun offset(C.VAR v, i, x, e) =
136 :     (case peekRegion v
137 :     of SOME(R.RECORD vl) => enterRegion(x, R.OFFSET(i, vl))
138 :     | SOME(R.OFFSET(j, vl)) => enterRegion(x, R.OFFSET(i+j, vl))
139 :     | SOME(R.MUTABLE _) => error "offset"
140 :     | _ => ()
141 :     (*esac*);
142 :     iter(e, hp))
143 :     | offset(_, _, _, e) = iter(e, hp)
144 :     in
145 :     case cexp
146 :     of C.RECORD(C.RK_FBLOCK, vl, x, e) => frecord(vl, x, e)
147 :     | C.RECORD(C.RK_FCONT, vl, x, e) => frecord(vl, x, e)
148 :     | C.RECORD(C.RK_VECTOR, vl, x, e) => let
149 :     val y = LambdaVar.mkLvar()
150 :     in
151 :     record (vl, y,
152 :     C.RECORD(
153 :     C.RK_RECORD, [(C.VAR y, offp0), (C.INT(length vl), offp0)],
154 :     x, e))
155 :     end
156 :     | C.RECORD(rk, vl, x, e) => record(vl, x, e)
157 :     | C.SELECT(i, v, x, _, e) => select(v, i, x, e)
158 :     | C.OFFSET(i, v, x, e) => offset(v, i, x, e)
159 :     | C.APP _ => ()
160 :     | C.FIX(fl, e) => error "FIX"
161 :     | C.SWITCH(_, _, el) => List.app (fn e => iter(e, hp)) el
162 :     | C.BRANCH(_, _, _, e1, e2) => (iter(e1, hp); iter(e2, hp))
163 :     | C.SETTER(P.update, [a,_,v], e) => update(a, v, e)
164 :     | C.SETTER(P.boxedupdate, [a,_,v], e) => update(a, v, e)
165 :     | C.SETTER(P.numupdate{kind=P.FLOAT 64}, [a,i,v], e) =>
166 :     update(a, v, e)
167 :     | C.SETTER(_, _, e) => iter(e, hp)
168 :     | C.LOOKER(_, _, _, _, e) => iter(e, hp)
169 :     | C.ARITH(_, _, _, _, e) => iter(e, hp)
170 :     | C.PURE(P.mkspecial, [i,v], x, _, e) => record([(v, offp0)], x, e)
171 :     | C.PURE(P.fwrap, [u], x, _, e) => frecord([(u, offp0)], x, e)
172 :     | C.PURE(P.i32wrap, [u], x, _, e) =>
173 :     record([(u, offp0),(C.INT 0, offp0)], x, e)
174 :     | C.PURE(P.makeref, [v], x, _, e) => let
175 :     val uses =
176 :     case v
177 :     of C.VAR lvar =>
178 :     (case peekRegion lvar
179 :     of NONE => R.RO_MEM
180 :     | SOME(R.RECORD vl) => recordSlots vl
181 :     | SOME(R.OFFSET(_, vl)) => recordSlots vl
182 :     | SOME(R.MUTABLE(def, use)) => def
183 :     | SOME r => r
184 :     (*esac*))
185 :     | _ => R.RO_MEM
186 :     val defs =
187 :     R.REGIONS(R.RW_MEM,
188 :     R.REGIONS(regionId(hp), regionId(hp+4)))
189 :     in
190 :     enterRegion(x, R.MUTABLE(defs, uses));
191 :     iter(e, hp+8)
192 :     end
193 :     | C.PURE(P.newarray0, _, w, _, e) => let
194 :     val y = LambdaVar.mkLvar()
195 :     in
196 :     iter (
197 :     C.RECORD(C.RK_RECORD, [(C.INT 0, offp0)], y,
198 :     C.RECORD(C.RK_RECORD, [(C.VAR y, offp0), (C.INT 0, offp0)], w, e)),
199 :     hp)
200 :     end
201 :     | C.PURE(_, _, _, _, e) => iter(e, hp)
202 :     (*esac*)
203 :     end
204 :     in iter(cexp, 0)
205 :     end (* funBody *)
206 :     in
207 :     app funBody frags;
208 :     fn v => lookupRegion v handle _ => R.RO_MEM
209 :     end (*memDisambig*)
210 :     end
211 :    
212 :    

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