comparison src/mono_reduce.sml @ 948:b03d48aac959

Find more opportunities for 'let' inlining with better purity information
author Adam Chlipala <adamc@hcoop.net>
date Thu, 17 Sep 2009 12:55:22 -0400
parents b8d7a47b8e0c
children 8fe576c0bee9
comparison
equal deleted inserted replaced
947:e2305dcc3965 948:b03d48aac959
36 36
37 structure IM = IntBinaryMap 37 structure IM = IntBinaryMap
38 structure IS = IntBinarySet 38 structure IS = IntBinarySet
39 39
40 40
41 val simpleTypeImpure = 41 fun simpleTypeImpure tsyms =
42 U.Typ.exists (fn TFun _ => true 42 U.Typ.exists (fn TFun _ => true
43 | TDatatype _ => true 43 | TDatatype (n, _) => IS.member (tsyms, n)
44 | _ => false) 44 | _ => false)
45 45
46 fun simpleImpure syms = 46 fun simpleImpure (tsyms, syms) =
47 U.Exp.existsB {typ = fn _ => false, 47 U.Exp.existsB {typ = fn _ => false,
48 exp = fn (env, e) => 48 exp = fn (env, e) =>
49 case e of 49 case e of
50 EWrite _ => true 50 EWrite _ => true
51 | EQuery _ => true 51 | EQuery _ => true
52 | EDml _ => true 52 | EDml _ => true
53 | ENextval _ => true 53 | ENextval _ => true
54 | EUnurlify _ => true
55 | EFfiApp (m, x, _) => Settings.isEffectful (m, x) 54 | EFfiApp (m, x, _) => Settings.isEffectful (m, x)
56 | EServerCall _ => true 55 | EServerCall _ => true
57 | ERecv _ => true 56 | ERecv _ => true
58 | ESleep _ => true 57 | ESleep _ => true
59 | ENamed n => IS.member (syms, n) 58 | ENamed n => IS.member (syms, n)
60 | ERel n => 59 | ERel n =>
61 let 60 let
62 val (_, t, _) = E.lookupERel env n 61 val (_, t, _) = E.lookupERel env n
63 in 62 in
64 simpleTypeImpure t 63 simpleTypeImpure tsyms t
65 end 64 end
66 | _ => false, 65 | _ => false,
67 bind = fn (env, b) => 66 bind = fn (env, b) =>
68 case b of 67 case b of
69 U.Exp.RelE (x, t) => E.pushERel env x t NONE 68 U.Exp.RelE (x, t) => E.pushERel env x t NONE
285 U.Exp.RelE _ => n + 1 284 U.Exp.RelE _ => n + 1
286 | _ => n} 0 0 285 | _ => n} 0 0
287 286
288 fun reduce file = 287 fun reduce file =
289 let 288 let
290 val (impures, absCounts) = 289 val (timpures, impures, absCounts) =
291 foldl (fn ((d, _), (impures, absCounts)) => 290 foldl (fn ((d, _), (timpures, impures, absCounts)) =>
292 let 291 let
293 fun countAbs (e, _) = 292 fun countAbs (e, _) =
294 case e of 293 case e of
295 EAbs (_, _, _, e) => 1 + countAbs e 294 EAbs (_, _, _, e) => 1 + countAbs e
296 | _ => 0 295 | _ => 0
297 in 296 in
298 case d of 297 case d of
299 DVal (_, n, _, e, _) => 298 DDatatype dts =>
300 (if simpleImpure impures E.empty e then 299 (if List.exists (fn (_, _, cs) =>
300 List.exists (fn (_, _, NONE) => false
301 | (_, _, SOME t) => simpleTypeImpure timpures t) cs)
302 dts then
303 IS.addList (timpures, map #2 dts)
304 else
305 timpures,
306 impures,
307 absCounts)
308 | DVal (_, n, _, e, _) =>
309 (timpures,
310 if simpleImpure (timpures, impures) E.empty e then
301 IS.add (impures, n) 311 IS.add (impures, n)
302 else 312 else
303 impures, 313 impures,
304 IM.insert (absCounts, n, countAbs e)) 314 IM.insert (absCounts, n, countAbs e))
305 | DValRec vis => 315 | DValRec vis =>
306 (if List.exists (fn (_, _, _, e, _) => simpleImpure impures E.empty e) vis then 316 (timpures,
317 if List.exists (fn (_, _, _, e, _) => simpleImpure (timpures, impures) E.empty e) vis then
307 foldl (fn ((_, n, _, _, _), impures) => 318 foldl (fn ((_, n, _, _, _), impures) =>
308 IS.add (impures, n)) impures vis 319 IS.add (impures, n)) impures vis
309 else 320 else
310 impures, 321 impures,
311 foldl (fn ((x, n, _, e, _), absCounts) => 322 foldl (fn ((x, n, _, e, _), absCounts) =>
312 IM.insert (absCounts, n, countAbs e)) 323 IM.insert (absCounts, n, countAbs e))
313 absCounts vis) 324 absCounts vis)
314 | _ => (impures, absCounts) 325 | _ => (timpures, impures, absCounts)
315 end) 326 end)
316 (IS.empty, IM.empty) file 327 (IS.empty, IS.empty, IM.empty) file
317 328
318 fun summarize d (e, _) = 329 fun summarize d (e, _) =
319 let 330 let
320 val s = 331 val s =
321 case e of 332 case e of
339 case e of 350 case e of
340 ENamed n => 351 ENamed n =>
341 let 352 let
342 val ls = rev ls 353 val ls = rev ls
343 in 354 in
344 case IM.find (absCounts, n) of 355 if IS.member (impures, n) then
345 NONE => [Unsure] 356 case IM.find (absCounts, n) of
346 | SOME len => 357 NONE => [Unsure]
347 if passed < len then 358 | SOME len =>
348 ls 359 if passed < len then
349 else 360 ls
350 ls @ [Unsure] 361 else
362 ls @ [Unsure]
363 else
364 ls
351 end 365 end
352 | ERel n => List.revAppend (ls, 366 | ERel n => List.revAppend (ls,
353 if n = d then 367 if n = d then
354 [UseRel, Unsure] 368 [UseRel, Unsure]
355 else 369 else
417 ("s", p_events s)];*) 431 ("s", p_events s)];*)
418 s 432 s
419 end 433 end
420 434
421 val impure = fn env => fn e => 435 val impure = fn env => fn e =>
422 simpleImpure impures env e andalso impure e 436 simpleImpure (timpures, impures) env e andalso impure e
423 andalso not (List.null (summarize ~1 e)) 437 andalso not (List.null (summarize ~1 e))
424 438
425 fun exp env e = 439 fun exp env e =
426 let 440 let
427 (*val () = Print.prefaces "exp" [("e", MonoPrint.p_exp env (e, ErrorMsg.dummySpan))]*) 441 (*val () = Print.prefaces "exp" [("e", MonoPrint.p_exp env (e, ErrorMsg.dummySpan))]*)