comparison src/especialize.sml @ 1667:833402503855

Tweak Especialize heuristic to prevent non-termination
author Adam Chlipala <adam@chlipala.net>
date Mon, 09 Jan 2012 09:51:39 -0500
parents 0577be31a435
children 4cacced4a6da
comparison
equal deleted inserted replaced
1666:df8f18d50746 1667:833402503855
119 specialized : IS.set 119 specialized : IS.set
120 } 120 }
121 121
122 fun default (_, x, st) = (x, st) 122 fun default (_, x, st) = (x, st)
123 123
124 structure SS = BinarySetFn(struct
125 type ord_key = string
126 val compare = String.compare
127 end)
128
129 val mayNotSpec = ref SS.empty
130
131 val functionInside = U.Con.exists {kind = fn _ => false, 124 val functionInside = U.Con.exists {kind = fn _ => false,
132 con = fn TFun _ => true 125 con = fn TFun _ => true
133 | CFfi ("Basis", "transaction") => true 126 | CFfi ("Basis", "transaction") => true
134 | CFfi ("Basis", "eq") => true 127 | CFfi ("Basis", "eq") => true
135 | CFfi ("Basis", "num") => true 128 | CFfi ("Basis", "num") => true
349 342
350 val vts = map (fn n => #2 (List.nth (env, n))) (IS.listItems fvs) 343 val vts = map (fn n => #2 (List.nth (env, n))) (IS.listItems fvs)
351 val fxs' = map (squish (IS.listItems fvs)) fxs 344 val fxs' = map (squish (IS.listItems fvs)) fxs
352 345
353 val p_bool = Print.PD.string o Bool.toString 346 val p_bool = Print.PD.string o Bool.toString
347
348 fun bumpCount n =
349 if IS.member (#specialized st, f) then
350 n
351 else
352 5 + 2 *n
354 in 353 in
355 (*Print.prefaces "Func" [("name", Print.PD.string name), 354 (*Print.prefaces "Func" [("name", Print.PD.string name),
356 ("e", CorePrint.p_exp CoreEnv.empty e), 355 ("e", CorePrint.p_exp CoreEnv.empty e),
357 ("fxs'", Print.p_list (CorePrint.p_exp CoreEnv.empty) fxs')];*) 356 ("fxs'", Print.p_list (CorePrint.p_exp CoreEnv.empty) fxs')];*)
358 if not fin 357 if not fin
359 orelse List.all (fn (ERel _, _) => true 358 orelse List.all (fn (ERel _, _) => true
360 | _ => false) fxs' 359 | _ => false) fxs'
361 orelse List.exists (not o valueish) fxs' 360 orelse List.exists (not o valueish) fxs'
362 orelse (IS.numItems fvs >= length fxs 361 orelse IS.numItems fvs >= bumpCount (length fxs) then
363 andalso IS.exists (fn n => functionInside (#2 (List.nth (env, n)))) fvs) then
364 ((*Print.prefaces "No" [("name", Print.PD.string name), 362 ((*Print.prefaces "No" [("name", Print.PD.string name),
365 ("f", Print.PD.string (Int.toString f)), 363 ("f", Print.PD.string (Int.toString f)),
366 ("fxs'", 364 ("fxs'",
367 Print.p_list (CorePrint.p_exp CoreEnv.empty) fxs'), 365 Print.p_list (CorePrint.p_exp CoreEnv.empty) fxs'),
368 ("b1", p_bool (not fin)), 366 ("b1", p_bool (not fin)),
371 ("b3", p_bool (List.exists (not o valueish) fxs')), 369 ("b3", p_bool (List.exists (not o valueish) fxs')),
372 ("b4", p_bool (IS.numItems fvs >= length fxs 370 ("b4", p_bool (IS.numItems fvs >= length fxs
373 andalso IS.exists (fn n => functionInside (#2 (List.nth (env, n)))) fvs))];*) 371 andalso IS.exists (fn n => functionInside (#2 (List.nth (env, n)))) fvs))];*)
374 default ()) 372 default ())
375 else 373 else
376 case (KM.find (args, (vts, fxs')), 374 case KM.find (args, (vts, fxs')) of
377 SS.member (!mayNotSpec, name) (*orelse IS.member (#specialized st, f)*)) of 375 SOME f' =>
378 (SOME f', _) =>
379 let 376 let
380 val e = (ENamed f', loc) 377 val e = (ENamed f', loc)
381 val e = IS.foldr (fn (arg, e) => (EApp (e, (ERel arg, loc)), loc)) 378 val e = IS.foldr (fn (arg, e) => (EApp (e, (ERel arg, loc)), loc))
382 e fvs 379 e fvs
383 val e = foldl (fn (arg, e) => (EApp (e, arg), loc)) 380 val e = foldl (fn (arg, e) => (EApp (e, arg), loc))
385 in 382 in
386 (*Print.prefaces "Brand new (reuse)" 383 (*Print.prefaces "Brand new (reuse)"
387 [("e'", CorePrint.p_exp CoreEnv.empty e)];*) 384 [("e'", CorePrint.p_exp CoreEnv.empty e)];*)
388 (e, st) 385 (e, st)
389 end 386 end
390 | (_, true) => ((*Print.prefaces ("No!(" ^ name ^ ")") 387 | NONE =>
391 [("fxs'",
392 Print.p_list (CorePrint.p_exp CoreEnv.empty) fxs')];*)
393 default ())
394 | (NONE, false) =>
395 let 388 let
396 (*val () = Print.prefaces "New one" 389 (*val () = Print.prefaces "New one"
397 [("f", Print.PD.string (Int.toString f)), 390 [("name", Print.PD.string name),
398 ("mns", Print.p_list Print.PD.string 391 ("f", Print.PD.string (Int.toString f)),
399 (SS.listItems (!mayNotSpec)))]*) 392 ("|fvs|", Print.PD.string (Int.toString (IS.numItems fvs))),
393 ("|fxs|", Print.PD.string (Int.toString (length fxs))),
394 ("spec", Print.PD.string (Bool.toString (IS.member (#specialized st, f))))]*)
400 395
401 (*val () = Print.prefaces ("Yes(" ^ name ^ ")") 396 (*val () = Print.prefaces ("Yes(" ^ name ^ ")")
402 [("fxs'", 397 [("fxs'",
403 Print.p_list (CorePrint.p_exp CoreEnv.empty) fxs')]*) 398 Print.p_list (CorePrint.p_exp CoreEnv.empty) fxs')]*)
404 399
448 ((EAbs (x, xt, typ', body'), 443 ((EAbs (x, xt, typ', body'),
449 loc), 444 loc),
450 (TFun (xt, typ'), loc)) 445 (TFun (xt, typ'), loc))
451 end) 446 end)
452 (body', typ') fvs 447 (body', typ') fvs
453 val mns = !mayNotSpec
454 (*val () = mayNotSpec := SS.add (mns, name)*)
455 (*val () = print ("NEW: " ^ name ^ "__" ^ Int.toString f' ^ "\n");*) 448 (*val () = print ("NEW: " ^ name ^ "__" ^ Int.toString f' ^ "\n");*)
456 val body' = ReduceLocal.reduceExp body' 449 val body' = ReduceLocal.reduceExp body'
457 (*val () = Print.preface ("PRE", CorePrint.p_exp CoreEnv.empty body')*) 450 (*val () = Print.preface ("PRE", CorePrint.p_exp CoreEnv.empty body')*)
458 val (body', st) = exp (env, body', st) 451 val (body', st) = exp (env, body', st)
459 val () = mayNotSpec := mns
460 452
461 val e' = (ENamed f', loc) 453 val e' = (ENamed f', loc)
462 val e' = IS.foldr (fn (arg, e) => (EApp (e, (ERel arg, loc)), loc)) 454 val e' = IS.foldr (fn (arg, e) => (EApp (e, (ERel arg, loc)), loc))
463 e' fvs 455 e' fvs
464 val e' = foldl (fn (arg, e) => (EApp (e, arg), loc)) 456 val e' = foldl (fn (arg, e) => (EApp (e, arg), loc))
500 funcs = funcs, 492 funcs = funcs,
501 decls = [], 493 decls = [],
502 specialized = #specialized st} 494 specialized = #specialized st}
503 495
504 (*val () = Print.prefaces "decl" [("d", CorePrint.p_decl CoreEnv.empty d)]*) 496 (*val () = Print.prefaces "decl" [("d", CorePrint.p_decl CoreEnv.empty d)]*)
505
506 val () = mayNotSpec := SS.empty
507 497
508 val (d', st) = 498 val (d', st) =
509 if isPoly d then 499 if isPoly d then
510 (d, st) 500 (d, st)
511 else 501 else
534 CorePrint.p_con CoreEnv.empty (#3 vi)]) 524 CorePrint.p_con CoreEnv.empty (#3 vi)])
535 vis)*) 525 vis)*)
536 526
537 val (vis, st) = ListUtil.foldlMap (fn ((x, n, t, e, s), st) => 527 val (vis, st) = ListUtil.foldlMap (fn ((x, n, t, e, s), st) =>
538 let 528 let
539 val () = mayNotSpec := SS.empty
540 val (e, st) = exp ([], e, st) 529 val (e, st) = exp ([], e, st)
541 in 530 in
542 ((x, n, t, e, s), st) 531 ((x, n, t, e, s), st)
543 end) st vis 532 end) st vis
544 in 533 in
564 in 553 in
565 ((DTask (e1, e2), #2 d), st) 554 ((DTask (e1, e2), #2 d), st)
566 end 555 end
567 | _ => (d, st) 556 | _ => (d, st)
568 557
569 val () = mayNotSpec := SS.empty
570
571 (*val () = print "/decl\n"*) 558 (*val () = print "/decl\n"*)
572 559
573 val funcs = #funcs st 560 val funcs = #funcs st
574 val funcs = 561 val funcs =
575 case #1 d of 562 case #1 d of