# HG changeset patch # User Adam Chlipala # Date 1256489330 14400 # Node ID 34ba25d6af3bc2c1ead2d8a65d6ad70aaa166c55 # Parent 065ce32520906f062669918871fc4538b480b17d Inlining threshold for Mono_reduce diff -r 065ce3252090 -r 34ba25d6af3b src/compiler.sig --- a/src/compiler.sig Sun Oct 25 12:08:21 2009 -0400 +++ b/src/compiler.sig Sun Oct 25 12:48:50 2009 -0400 @@ -139,6 +139,7 @@ val toMono_reduce2 : (string, Mono.file) transform val toMono_shake2 : (string, Mono.file) transform val toMono_opt4 : (string, Mono.file) transform + val toMono_reduce3 : (string, Mono.file) transform val toFuse2 : (string, Mono.file) transform val toUntangle3 : (string, Mono.file) transform val toMono_shake3 : (string, Mono.file) transform diff -r 065ce3252090 -r 34ba25d6af3b src/compiler.sml --- a/src/compiler.sml Sun Oct 25 12:08:21 2009 -0400 +++ b/src/compiler.sml Sun Oct 25 12:48:50 2009 -0400 @@ -862,7 +862,8 @@ val toMono_reduce2 = transform mono_reduce "mono_reduce2" o toUntangle2 val toMono_shake2 = transform mono_shake "mono_shake2" o toMono_reduce2 val toMono_opt4 = transform mono_opt "mono_opt4" o toMono_shake2 -val toFuse2 = transform fuse "shake2" o toMono_opt4 +val toMono_reduce3 = transform mono_reduce "mono_reduce3" o toMono_opt4 +val toFuse2 = transform fuse "shake2" o toMono_reduce3 val toUntangle3 = transform untangle "untangle3" o toFuse2 val toMono_shake3 = transform mono_shake "mono_shake3" o toUntangle3 diff -r 065ce3252090 -r 34ba25d6af3b src/mono_reduce.sml --- a/src/mono_reduce.sml Sun Oct 25 12:08:21 2009 -0400 +++ b/src/mono_reduce.sml Sun Oct 25 12:48:50 2009 -0400 @@ -337,6 +337,23 @@ end) (IS.empty, IS.empty, IM.empty) file + val uses = U.File.fold {typ = fn (_, m) => m, + exp = fn (e, m) => + case e of + ENamed n => IM.insert (m, n, 1 + Option.getOpt (IM.find (m, n), 0)) + | _ => m, + decl = fn (_, m) => m} + IM.empty file + + val size = U.Exp.fold {typ = fn (_, n) => n, + exp = fn (_, n) => n + 1} 0 + + fun mayInline (n, e) = + case IM.find (uses, n) of + NONE => false + | SOME count => count <= 1 + orelse size e <= Settings.getMonoInline () + fun summarize d (e, _) = let val s = @@ -452,6 +469,84 @@ let (*val () = Print.prefaces "exp" [("e", MonoPrint.p_exp env (e, ErrorMsg.dummySpan))]*) + fun doLet (x, t, e', b) = + let + fun doSub () = + let + val r = subExpInExp (0, e') b + in + (*Print.prefaces "doSub" [("e'", MonoPrint.p_exp env e'), + ("b", MonoPrint.p_exp (E.pushERel env x t NONE) b), + ("r", MonoPrint.p_exp env r)];*) + #1 (reduceExp env r) + end + + fun trySub () = + ((*Print.prefaces "trySub" + [("e", MonoPrint.p_exp env (e, ErrorMsg.dummySpan))];*) + case t of + (TFfi ("Basis", "string"), _) => doSub () + | (TSignal _, _) => e + | _ => + case e' of + (ECase _, _) => e + | _ => doSub ()) + in + if impure env e' then + let + val effs_e' = summarize 0 e' + val effs_e' = List.filter (fn x => x <> UseRel) effs_e' + val effs_b = summarize 0 b + + (*val () = Print.prefaces "Try" + [("e", MonoPrint.p_exp env (e, ErrorMsg.dummySpan)), + ("e'", MonoPrint.p_exp env e'), + ("b", MonoPrint.p_exp (E.pushERel env x t NONE) b), + ("e'_eff", p_events effs_e'), + ("b_eff", p_events effs_b)]*) + + fun does eff = List.exists (fn eff' => eff' = eff) effs_e' + val writesPage = does WritePage + val readsDb = does ReadDb + val writesDb = does WriteDb + + fun verifyUnused eff = + case eff of + UseRel => false + | _ => true + + fun verifyCompatible effs = + case effs of + [] => false + | eff :: effs => + case eff of + Unsure => false + | UseRel => List.all verifyUnused effs + | WritePage => not writesPage andalso verifyCompatible effs + | ReadDb => not writesDb andalso verifyCompatible effs + | WriteDb => not writesDb andalso not readsDb andalso verifyCompatible effs + in + (*Print.prefaces "verifyCompatible" + [("e'", MonoPrint.p_exp env e'), + ("b", MonoPrint.p_exp (E.pushERel env x t NONE) b), + ("effs_e'", Print.p_list p_event effs_e'), + ("effs_b", Print.p_list p_event effs_b)];*) + if (List.null effs_e' + orelse (List.all (fn eff => eff <> Unsure) effs_e' + andalso verifyCompatible effs_b) + orelse (case effs_b of + UseRel :: effs => List.all verifyUnused effs + | _ => false)) + andalso countFree 0 0 b = 1 + andalso not (freeInAbs b) then + trySub () + else + e + end + else + trySub () + end + val r = case e of ERel n => @@ -546,90 +641,14 @@ #1 (reduceExp env (ELet (x, t, e, (EApp (b, liftExpInExp 0 e'), loc)), loc)) - | ELet (x, t, e', (EAbs (x', t' as (TRecord [], _), ran, e''), loc)) => + | ELet (x, t, e', b as (EAbs (x', t' as (TRecord [], _), ran, e''), loc)) => if impure env e' then - e + doLet (x, t, e', b) else EAbs (x', t', ran, reduceExp (E.pushERel env x' t' NONE) (ELet (x, t, liftExpInExp 0 e', swapExpVars 0 e''), loc)) - | ELet (x, t, e', b) => - let - fun doSub () = - let - val r = subExpInExp (0, e') b - in - (*Print.prefaces "doSub" [("e'", MonoPrint.p_exp env e'), - ("b", MonoPrint.p_exp (E.pushERel env x t NONE) b), - ("r", MonoPrint.p_exp env r)];*) - #1 (reduceExp env r) - end - - fun trySub () = - ((*Print.prefaces "trySub" - [("e", MonoPrint.p_exp env (e, ErrorMsg.dummySpan))];*) - case t of - (TFfi ("Basis", "string"), _) => doSub () - | (TSignal _, _) => e - | _ => - case e' of - (ECase _, _) => e - | _ => doSub ()) - in - if impure env e' then - let - val effs_e' = summarize 0 e' - val effs_e' = List.filter (fn x => x <> UseRel) effs_e' - val effs_b = summarize 0 b - - (*val () = Print.prefaces "Try" - [(*("e", MonoPrint.p_exp env (e, ErrorMsg.dummySpan)),*) - ("e'", MonoPrint.p_exp env e'), - ("b", MonoPrint.p_exp (E.pushERel env x t NONE) b), - ("e'_eff", p_events effs_e'), - ("b", p_events effs_b)]*) - - fun does eff = List.exists (fn eff' => eff' = eff) effs_e' - val writesPage = does WritePage - val readsDb = does ReadDb - val writesDb = does WriteDb - - fun verifyUnused eff = - case eff of - UseRel => false - | _ => true - - fun verifyCompatible effs = - case effs of - [] => false - | eff :: effs => - case eff of - Unsure => false - | UseRel => List.all verifyUnused effs - | WritePage => not writesPage andalso verifyCompatible effs - | ReadDb => not writesDb andalso verifyCompatible effs - | WriteDb => not writesDb andalso not readsDb andalso verifyCompatible effs - in - (*Print.prefaces "verifyCompatible" - [("e'", MonoPrint.p_exp env e'), - ("b", MonoPrint.p_exp (E.pushERel env x t NONE) b), - ("effs_e'", Print.p_list p_event effs_e'), - ("effs_b", Print.p_list p_event effs_b)];*) - if (List.null effs_e' - orelse (List.all (fn eff => eff <> Unsure) effs_e' - andalso verifyCompatible effs_b) - orelse (case effs_b of - UseRel :: effs => List.all verifyUnused effs - | _ => false)) - andalso countFree 0 0 b = 1 - andalso not (freeInAbs b) then - trySub () - else - e - end - else - trySub () - end + | ELet (x, t, e', b) => doLet (x, t, e', b) | EStrcat ((EPrim (Prim.String s1), _), (EPrim (Prim.String s2), _)) => EPrim (Prim.String (s1 ^ s2)) @@ -648,7 +667,17 @@ case b of U.Decl.Datatype (x, n, xncs) => E.pushDatatype env x n xncs | U.Decl.RelE (x, t) => E.pushERel env x t NONE - | U.Decl.NamedE (x, n, t, eo, s) => E.pushENamed env x n t (Option.map (reduceExp env) eo) s + | U.Decl.NamedE (x, n, t, eo, s) => + let + val eo = case eo of + NONE => NONE + | SOME e => if mayInline (n, e) then + SOME e + else + NONE + in + E.pushENamed env x n t (Option.map (reduceExp env) eo) s + end and reduceExp env = U.Exp.mapB {typ = typ, exp = exp, bind = bind} env diff -r 065ce3252090 -r 34ba25d6af3b src/unnest.sml --- a/src/unnest.sml Sun Oct 25 12:08:21 2009 -0400 +++ b/src/unnest.sml Sun Oct 25 12:48:50 2009 -0400 @@ -339,7 +339,7 @@ (*Print.prefaces "Have a vi" [("x", Print.PD.string x), ("e", ElabPrint.p_exp ElabEnv.empty e)];*) - (x, n, t, e) + ("$" ^ x, n, t, e) end) vis