comparison src/mono_reduce.sml @ 2084:0d48cfb59b29

More aggressive inlining of 'let' with record literals, plus some changes to Monoization of queries, to make inlining more common
author Adam Chlipala <adam@chlipala.net>
date Thu, 04 Dec 2014 02:47:24 -0500
parents 1b76ae703cbb
children 9e9c915f554c
comparison
equal deleted inserted replaced
2083:9f65e2188d3c 2084:0d48cfb59b29
37 structure U = MonoUtil 37 structure U = MonoUtil
38 38
39 structure IM = IntBinaryMap 39 structure IM = IntBinaryMap
40 structure IS = IntBinarySet 40 structure IS = IntBinarySet
41 41
42 structure SS = BinarySetFn(struct
43 type ord_key = string
44 val compare = String.compare
45 end)
42 46
43 fun simpleTypeImpure tsyms = 47 fun simpleTypeImpure tsyms =
44 U.Typ.exists (fn TFun _ => true 48 U.Typ.exists (fn TFun _ => true
45 | TDatatype (n, _) => IS.member (tsyms, n) 49 | TDatatype (n, _) => IS.member (tsyms, n)
46 | _ => false) 50 | _ => false)
590 | (TSignal _, _) => e 594 | (TSignal _, _) => e
591 | _ => 595 | _ =>
592 case e' of 596 case e' of
593 (ECase _, _) => e 597 (ECase _, _) => e
594 | _ => doSub ()) 598 | _ => doSub ())
599
600 fun isRecord () =
601 case #1 e' of
602 ERecord _ => true
603 | _ => false
604
605 fun whichProj i (e : exp) =
606 case #1 e of
607 EPrim _ => SOME SS.empty
608 | ERel i' => if i' = i then NONE else SOME SS.empty
609 | ENamed _ => SOME SS.empty
610 | ECon (_, _, NONE) => SOME SS.empty
611 | ECon (_, _, SOME e') => whichProj i e'
612 | ENone _ => SOME SS.empty
613 | ESome (_, e') => whichProj i e'
614 | EFfi _ => SOME SS.empty
615 | EFfiApp (_, _, es) => whichProjs i (map #1 es)
616 | EApp (e1, e2) => whichProjs i [e1, e2]
617 | EAbs (_, _, _, e) => whichProj (i + 1) e
618 | EUnop (_, e1) => whichProj i e1
619 | EBinop (_, _, e1, e2) => whichProjs i [e1, e2]
620 | ERecord xets => whichProjs i (map #2 xets)
621 | EField ((ERel i', _), s) =>
622 if i' = i then
623 SOME (SS.singleton s)
624 else
625 SOME SS.empty
626 | EField (e1, _) => whichProj i e1
627 | ECase (e1, pes, _) =>
628 whichProjs' i ((0, e1)
629 :: map (fn (p, e) => (patBinds p, e)) pes)
630 | EStrcat (e1, e2) => whichProjs i [e1, e2]
631 | EError (e1, _) => whichProj i e1
632 | EReturnBlob {blob = NONE, mimeType = e2, ...} => whichProj i e2
633 | EReturnBlob {blob = SOME e1, mimeType = e2, ...} => whichProjs i [e1, e2]
634 | ERedirect (e1, _) => whichProj i e1
635 | EWrite e1 => whichProj i e1
636 | ESeq (e1, e2) => whichProjs i [e1, e2]
637 | ELet (_, _, e1, e2) => whichProjs' i [(0, e1), (1, e2)]
638 | EClosure (_, es) => whichProjs i es
639 | EQuery {query = e1, body = e2, initial = e3, ...} =>
640 whichProjs' i [(0, e1), (2, e2), (0, e3)]
641 | EDml (e1, _) => whichProj i e1
642 | ENextval e1 => whichProj i e1
643 | ESetval (e1, e2) => whichProjs i [e1, e2]
644 | EUnurlify (e1, _, _) => whichProj i e1
645 | EJavaScript (_, e1) => whichProj i e1
646 | ESignalReturn e1 => whichProj i e1
647 | ESignalBind (e1, e2) => whichProjs i [e1, e2]
648 | ESignalSource e1 => whichProj i e1
649 | EServerCall (e1, _, _, _) => whichProj i e1
650 | ERecv (e1, _) => whichProj i e1
651 | ESleep e1 => whichProj i e1
652 | ESpawn e1 => whichProj i e1
653
654 and whichProjs i es =
655 whichProjs' i (map (fn e => (0, e)) es)
656
657 and whichProjs' i es =
658 case es of
659 [] => SOME SS.empty
660 | (n, e) :: es' =>
661 case (whichProj (i + n) e, whichProjs' i es') of
662 (SOME m1, SOME m2) =>
663 if SS.isEmpty (SS.intersection (m1, m2)) then
664 SOME (SS.union (m1, m2))
665 else
666 NONE
667 | _ => NONE
595 in 668 in
596 if impure env e' then 669 if impure env e' then
597 let 670 let
598 val effs_e' = summarize 0 e' 671 val effs_e' = summarize 0 e'
599 val effs_e' = List.filter (fn x => x <> UseRel) effs_e' 672 val effs_e' = List.filter (fn x => x <> UseRel) effs_e'
648 andalso not (freeInAbs b) then 721 andalso not (freeInAbs b) then
649 trySub () 722 trySub ()
650 else 723 else
651 e 724 e
652 end 725 end
653 else if countFree 0 0 b > 1 andalso not (!fullMode) andalso not (passive e') then 726 else if countFree 0 0 b > 1
727 andalso not (!fullMode)
728 andalso not (passive e')
729 andalso not (isRecord () andalso Option.isSome (whichProj 0 b)) then
654 e 730 e
655 else 731 else
656 trySub () 732 trySub ()
657 end 733 end
658 734