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/FLINT/clos/allocprof.sml
ViewVC logotype

Annotation of /sml/trunk/src/compiler/FLINT/clos/allocprof.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 419 - (view) (download)

1 : monnier 245 (* Copyright 1996 by Bell Laboratories *)
2 :     (* allocprof.sml *)
3 :    
4 :     structure AllocProf =
5 :     struct
6 :    
7 :     local open CPS
8 :    
9 :     structure CGoptions = Control.CG
10 :     structure P = CPS.P (* to avoid confusing SourceGroup *)
11 :     val mkLvar = LambdaVar.mkLvar
12 :    
13 :     val ARRAYS = 0
14 :     val ARRAYSIZE = 1
15 :     val STRINGS = 2
16 :     val STRINGSIZE = 3
17 :     val REFCELLS = 4
18 :     val REFLISTS = 5
19 :     val CLOSURES = 6
20 :     val CLOSURESLOTS = 11
21 :     val CLOSUREOVFL = (CLOSURES + CLOSURESLOTS)
22 :     val KCLOSURES = (CLOSUREOVFL + 1)
23 :     val KCLOSURESLOTS = 11
24 :     val KCLOSUREOVFL = (KCLOSURES + KCLOSURESLOTS)
25 :     val CCLOSURES = (KCLOSUREOVFL + 1)
26 :     val CCLOSURESLOTS = 11
27 :     val CCLOSUREOVFL = (CCLOSURES + CCLOSURESLOTS)
28 :     val LINKS = (CCLOSUREOVFL + 1)
29 :     val LINKSLOTS = 11
30 :     val LINKOVFL = (LINKS + LINKSLOTS)
31 :     val SPLINKS = (LINKOVFL + 1)
32 :     val SPLINKSLOTS = 11
33 :     val SPLINKOVFL = (SPLINKS + SPLINKSLOTS)
34 :     val RECORDS = (SPLINKOVFL + 1)
35 :     val RECORDSLOTS = 11
36 :     val RECORDOVFL = (RECORDS + RECORDSLOTS)
37 :     val SPILLS = (RECORDOVFL + 1)
38 :     val SPILLSLOTS = 21
39 :     val SPILLOVFL = (SPILLS + SPILLSLOTS)
40 :     val KNOWNCALLS = (SPILLOVFL + 1)
41 :     val STDKCALLS = (KNOWNCALLS + 1)
42 :     val STDCALLS = (STDKCALLS + 1)
43 :     val CNTCALLS = (STDCALLS + 1)
44 :     val CNTKCALLS = (CNTCALLS + 1)
45 :     val CSCNTCALLS = (CNTKCALLS + 1)
46 :     val CSCNTKCALLS = (CSCNTCALLS + 1)
47 :     val TLIMITCHECK = (CSCNTKCALLS+1)
48 :     val ALIMITCHECK = (TLIMITCHECK+1)
49 :     val ARITHOVH = (ALIMITCHECK+1)
50 :     val ARITHSLOTS = 5
51 :     (* Make sure the array assigned to varptr in the runtime system is at
52 :     least this big!! Test how big by doing an allocReset from batch. *)
53 :     val PROFSIZE = (ARITHOVH+ARITHSLOTS)
54 :    
55 :     val PROFREG = 0 (* use pseudo register 0 *)
56 :    
57 :     in
58 :    
59 :     local
60 :     fun prof(s,i) = (* Header to increment slot s by i *)
61 :     (fn ce => let val a1 = mkLvar() and a2 = mkLvar()
62 :     and x = mkLvar() and n = mkLvar()
63 :     in LOOKER(P.getpseudo,[INT PROFREG],a1,BOGt,
64 :     LOOKER(P.subscript,[VAR a1,INT s],x,INTt,
65 :     ARITH(P.iadd,[VAR x,INT i],n,INTt,
66 :     LOOKER(P.getpseudo,[INT PROFREG],a2,BOGt,
67 :     SETTER(P.unboxedupdate,[VAR a2,INT s,VAR n],ce)))))
68 :     end)
69 :    
70 :     fun profSlots(base,slots,ovfl) cost =
71 :     if cost < slots
72 :     then prof(base+cost,1)
73 :     else prof(base,1) o prof(ovfl,cost)
74 :    
75 :     val id = (fn x => x)
76 :     in
77 :    
78 :     local val profLinks0 = profSlots(LINKS,LINKSLOTS,LINKOVFL)
79 :     in
80 :     fun profLinks(cost) = if cost=0 then id else profLinks0 cost
81 :     end
82 :    
83 :     fun profRecLinks(l) = foldr (fn (cost,h) => profLinks(cost) o h) id l
84 :    
85 :     local val profRecord0 = profSlots(RECORDS,RECORDSLOTS,RECORDOVFL)
86 :     in
87 :     fun profRecord(cost) = if cost=0 then id else profRecord0 cost
88 :     end
89 :    
90 :     val profClosure = profSlots(CLOSURES,CLOSURESLOTS,CLOSUREOVFL)
91 :    
92 :     val profKClosure = profSlots(KCLOSURES,KCLOSURESLOTS,KCLOSUREOVFL)
93 :    
94 :     val profCClosure = profSlots(CCLOSURES,CCLOSURESLOTS,CCLOSUREOVFL)
95 :    
96 :     val profSpill = profSlots(SPILLS,SPILLSLOTS,SPILLOVFL)
97 :    
98 :     val profStdCall = prof(STDCALLS,1)
99 :    
100 :     val profStdkCall = prof(STDKCALLS,1)
101 :    
102 :     val profCntCall = prof(CNTCALLS,1)
103 :    
104 :     val profCntkCall = prof(CNTKCALLS,1)
105 :    
106 :     val profCSCntCall = prof(CSCNTCALLS,1)
107 :    
108 :     val profCSCntkCall = prof(CSCNTKCALLS,1)
109 :    
110 :     val profKnownCall = prof(KNOWNCALLS,1)
111 :    
112 :     fun profRefCell k = prof(REFCELLS,k)
113 :    
114 :     val profRefList = prof(REFLISTS,1)
115 :    
116 :     val profTLCHECK = prof(TLIMITCHECK,1)
117 :    
118 :     val profALCHECK = prof(ALIMITCHECK,1)
119 :    
120 :     end (* local *)
121 :    
122 :    
123 :     fun print_profile_info(outstrm) =
124 :     let val im = Int.toString
125 :     fun pr x = TextIO.output(outstrm,x)
126 :     val printf = app pr
127 :     (* Right justify st in a string of length w. *)
128 :     fun field (st,w) =
129 :     if w <= String.size st then st
130 :     else let val s = " " ^ st
131 :     in substring(s,String.size s - w, w)
132 :     end
133 :    
134 :     fun ifield(i,w) = field(im i,w)
135 :     (* Put a decimal point at position w in string st. *)
136 :     fun decimal(st,w) =
137 :     let val l = String.size st - w
138 :     val a = if (l <= 0) then "0" else substring(st,0,l)
139 :     val st' = "0000000000" ^ st
140 :     in a ^ "." ^ substring(st',String.size st' - w,w)
141 :     end
142 :     fun muldiv(i,j,k) =
143 :     (i*j div k) handle Overflow => muldiv(i,j div 2, k div 2)
144 :     fun decfield(n,j,k,w1,w2) =
145 :     field(decimal(im (muldiv(n,j,k)),w1)
146 :     handle Div => "",w2)
147 :     (* Returns the percentage i/j to 1 decimal place in a field of width k *)
148 :     fun percent(i,j,k) = decfield(1000,i,j,1,k)
149 :     (* Returns the percentage i/j to 2 decimal places in a field of width k*)
150 :     fun percent2(i,j,k) = decfield(10000,i,j,2,k)
151 :    
152 :     fun for(start,upto,f) =
153 :     let fun iter(i,cum:int) =
154 :     if i < upto then iter(i+1,cum + f(i)) else cum
155 :     in iter(start,0)
156 :     end
157 :     fun for'(start,upto,f) =
158 :     let fun iter(i) = if i < upto then (f(i); iter(i+1)) else ()
159 :     in iter(start)
160 :     end
161 :    
162 :    
163 :     val profvec : int array = Unsafe.getPseudo(PROFREG)
164 :     fun getprof(x) = Array.sub(profvec,x)
165 :     fun links(i) = getprof(LINKS+i)
166 :     fun closures(i) = getprof(CLOSURES+i)
167 :     fun kclosures(i) = getprof(KCLOSURES+i)
168 :     fun cclosures(i) = getprof(CCLOSURES+i)
169 :     fun records(i) = getprof(RECORDS+i)
170 :     fun spills(i) = getprof(SPILLS+i)
171 :    
172 :     val num_calls = getprof(KNOWNCALLS)
173 :     + getprof(STDKCALLS) + getprof(STDCALLS)
174 :     + getprof(CNTKCALLS) + getprof(CNTCALLS)
175 :     + getprof(CSCNTKCALLS) + getprof(CSCNTCALLS)
176 :    
177 :     val num_closures = for(0, CLOSURESLOTS,fn i => closures(i))
178 :     val space_closures = for(1, CLOSURESLOTS, fn i => closures(i) * (i+1))
179 :     val space_closures = space_closures + getprof(CLOSUREOVFL) + closures(0)
180 :    
181 :     val num_kclosures = for(0, KCLOSURESLOTS,fn i => kclosures(i))
182 :     val space_kclosures = for(1, KCLOSURESLOTS, fn i => kclosures(i) * (i+1))
183 :     val space_kclosures =
184 :     space_kclosures + getprof(KCLOSUREOVFL) + kclosures(0)
185 :    
186 :     val num_cclosures = for(0, CCLOSURESLOTS,fn i => cclosures(i))
187 :     val space_cclosures = for(1, CCLOSURESLOTS, fn i => cclosures(i) * (i+1))
188 :     val space_cclosures =
189 :     space_cclosures + getprof(CCLOSUREOVFL) + cclosures(0)
190 :    
191 :     val num_closure_accesses = for(0, LINKSLOTS, fn i => links(i))
192 :     val num_links_traced = for(1, LINKSLOTS, fn i => links(i) * i)
193 :     val num_links_traced = num_links_traced + getprof(LINKOVFL)
194 :    
195 :     val num_records = for(0, RECORDSLOTS, fn i => records(i))
196 :     val space_records = for(1, RECORDSLOTS, fn i => records(i) * (i+1))
197 :     val space_records = space_records + getprof(RECORDOVFL) + records(0)
198 :    
199 :     val num_spills = for(0, SPILLSLOTS, fn i => spills(i))
200 :     val space_spills = for(1, SPILLSLOTS, fn i => spills(i) * (i+1))
201 :     val space_spills = space_spills + getprof(SPILLOVFL) + spills(0)
202 :     val total = space_closures + space_kclosures + space_cclosures
203 :     + space_records + space_spills
204 :     + getprof(ARRAYSIZE) + getprof(ARRAYS)
205 :     + getprof(STRINGSIZE) + getprof(STRINGS)
206 :     + getprof(REFCELLS) * 2
207 :     + getprof(REFLISTS) * 2
208 :    
209 :     val descriptors = num_closures + num_kclosures + num_cclosures
210 :     + num_records + num_spills
211 :     + getprof(ARRAYS) + getprof(STRINGS)+ getprof(REFCELLS)
212 :    
213 :     val sgetprof = im o getprof
214 :    
215 :     fun printLinks() =
216 :     if num_closure_accesses>0 then
217 :     (for'(1, LINKSLOTS,
218 :     fn k =>
219 :     if links(k) > 0 then
220 :     printf[ifield(k,4),
221 :     ifield(links(k),13),
222 :     percent(links(k),num_closure_accesses,12),
223 :     "%",
224 :     ifield(links(k) * k,12),
225 :     percent(links(k) * k, num_links_traced, 9),
226 :     "%\n"]
227 :     else ());
228 :     if links(0) > 0 then
229 :     printf[">",
230 :     ifield(LINKSLOTS - 1,5),
231 :     ifield(links(0),9),
232 :     percent(links(0),num_closure_accesses,10),
233 :     "%",
234 :     ifield(getprof(LINKOVFL),13),
235 :     percent(getprof(LINKOVFL),num_links_traced,10),
236 :     "%\n"]
237 :     else ();
238 :    
239 :     printf[decfield(100,num_links_traced,num_closure_accesses,2,0),
240 :     " links were traced per access on average.\n\n"]
241 :     ) else printf["\n"] (* end function printLinks *)
242 :    
243 :     fun print1(num,name,slots,getstat,ovfl,space) =
244 :     if num>0 then
245 :     (printf[name,":\n"];
246 :     for'(1, slots,
247 :     fn k =>
248 :     if getstat(k) > 0 then
249 :     printf[ifield(k,6),
250 :     ifield(getstat(k),9),
251 :     percent(getstat(k),num,9),
252 :     "%",
253 :     ifield(getstat(k) * (k+1),13),
254 :     percent(getstat(k) * (k+1), total, 10),
255 :     "%\n"]
256 :     else ());
257 :     if getstat(0) > 0 then
258 :     printf[">",
259 :     ifield(slots - 1,5),
260 :     ifield(getstat(0),9),
261 :     percent(getstat(0),num,9),
262 :     "%",
263 :     ifield(getprof(ovfl)+getstat(0),13),
264 :     percent(getprof(ovfl)+getstat(0),total,10),
265 :     "%\n"]
266 :     else ();
267 :    
268 :     printf["total:",
269 :     ifield(num,9),
270 :     ifield(space,23),
271 :     percent(space,total,10),
272 :     "% Average size ",
273 :     decfield(100,space-num,num,2,0),
274 :     "\n\n"]
275 :     ) else if (String.size(name) > 12)
276 :     then printf[name,": 0\n\n"]
277 :     else printf[name,": ",
278 :     ifield(0,13 - String.size(name)),"\n\n"]
279 :     (* end function print1 *)
280 :    
281 :     fun print2(stat,size,name) =
282 :     if getprof(stat) <> 0 then
283 :     printf[name,
284 :     ifield(getprof(stat),6),
285 :     ifield(getprof(size) + getprof(stat), 23),
286 :     percent(getprof(size) + getprof(stat),total,10),
287 :     "% Average size ",
288 :     decfield(100,getprof(size),getprof(stat),2,0),
289 :     "\n"]
290 :     else printf[name,ifield(0,6),"\n"]
291 :    
292 :     fun print3(stat,name) =
293 :     if getprof(stat) <> 0 then
294 :     printf[name,
295 :     ifield(getprof(stat),6),
296 :     ifield(getprof(stat) * 2, 23),
297 :     percent(getprof(stat) * 2,total,10),
298 :     "%\n"]
299 :     else printf[name,ifield(0,6),"\n"]
300 :    
301 :     fun print4(stat,name) =
302 :     if getprof(stat) <> 0 then
303 :     printf[name, ifield(getprof(stat),10), "\n"]
304 :     else printf[name,ifield(0,12),"\n"]
305 :    
306 :     in pr "\n-------------------- ALLOCATION PROFILE --------------------\n\n";
307 :    
308 :     pr "\n ----- FUNCTION CALLS -----\n";
309 :     if (num_calls > 0) then
310 :     printf["Known functions: ",
311 :     ifield(getprof(KNOWNCALLS),10),
312 :     " (",
313 :     percent(getprof(KNOWNCALLS),num_calls,4),
314 :     "%)\n",
315 :    
316 :     "Escaping functions: ",
317 :     ifield(getprof(STDCALLS),10),
318 :     " (",
319 :     percent(getprof(STDCALLS),num_calls,4),
320 :     "%)\n",
321 :    
322 :    
323 :     "Known escaping functions: ",
324 :     ifield(getprof(STDKCALLS),10),
325 :     " (",
326 :     percent(getprof(STDKCALLS),num_calls,4),
327 :     "%)\n",
328 :    
329 :     "Continuations: ",
330 :     ifield(getprof(CNTCALLS),10),
331 :     " (",
332 :     percent(getprof(CNTCALLS),num_calls,4),
333 :     "%)\n",
334 :    
335 :     "Known continuations: ",
336 :     ifield(getprof(CNTKCALLS),10),
337 :     " (",
338 :     percent(getprof(CNTKCALLS),num_calls,4),
339 :     "%)\n",
340 :    
341 :     "Callee-save continuations: ",
342 :     ifield(getprof(CSCNTCALLS),10),
343 :     " (",
344 :     percent(getprof(CSCNTCALLS),num_calls,4),
345 :     "%)\n",
346 :    
347 :     "Known callee-save continuations: ",
348 :     ifield(getprof(CSCNTKCALLS),10),
349 :     " (",
350 :     percent(getprof(CSCNTKCALLS),num_calls,4),
351 :     "%)\n"]
352 :     else ();
353 :     printf["\nTotal function calls: ",
354 :     ifield(num_calls,10),"\n\n"];
355 :    
356 :    
357 :     pr "\n ----- CLOSURE ACCESSES -----\n";
358 :     printf["Closure elements were accessed ",
359 :     im num_closure_accesses,
360 :     " times through ",
361 :     im num_links_traced,
362 :     " links:\n",
363 :     "Size Accesses % accesses Links % links\n"];
364 :     printLinks();
365 :    
366 :     pr "\n ----- HEAP ALLOCATIONS -----\n";
367 :     pr " (only total sizes include descriptors)\n\n";
368 :     printf["TOTAL size ", im total];
369 :     if (total > 0) then (
370 :     printf["; ",
371 :     im descriptors, " descriptors accounted for ",
372 :     percent(descriptors,total,0), "%.\n\n"])
373 :     else printf[".\n\n"];
374 :    
375 :     printf[" Size Number % total Total size % TOTAL\n\n"];
376 :    
377 :     print1(num_closures,"Closures for escaping functions",
378 :     CLOSURESLOTS,closures,CLOSUREOVFL,space_closures);
379 :     print1(num_kclosures,"Closures for known functions",
380 :     KCLOSURESLOTS,kclosures,KCLOSUREOVFL,space_kclosures);
381 :     print1(num_cclosures,"Closures for callee-save continuations",
382 :     CCLOSURESLOTS,cclosures,CCLOSUREOVFL,space_cclosures);
383 :    
384 :     print1(num_records,"Records",RECORDSLOTS,records,
385 :     RECORDOVFL,space_records);
386 :     print1(num_spills,"Spills",SPILLSLOTS,spills,
387 :     SPILLOVFL,space_spills);
388 :    
389 :     print2(ARRAYS,ARRAYSIZE,"Arrays: ");
390 :     print2(STRINGS,STRINGSIZE,"Strings: ");
391 :    
392 :     print3(REFCELLS,"Refs: ");
393 :     print3(REFLISTS,"Ref\n list: ");
394 :    
395 :     print4(TLIMITCHECK,"Limit Checks for Continuations Only: ");
396 :     print4(ALIMITCHECK,"Limit Checks for Other allocations: ")
397 :    
398 :     end (* fun print_profile_info *)
399 :    
400 :    
401 :     fun reset() = (print "New alloc profvec, size ";
402 :     print (Int.toString PROFSIZE); print "\n";
403 :     Unsafe.setPseudo(Array.array(PROFSIZE,0),PROFREG))
404 :    
405 :     end (* toplevel local *)
406 :     end (* structure AllocProf *)
407 :    

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