diff options
author | Nicolas Frisby <nicolas.frisby@gmail.com> | 2013-04-11 12:48:11 +0100 |
---|---|---|
committer | Nicolas Frisby <nicolas.frisby@gmail.com> | 2013-04-11 18:47:57 +0100 |
commit | af12cf66d1a416a135cb98b86717aba2cd247e1a (patch) | |
tree | 8e17ace160216f6aab960132c8bd3629dbaf1849 /compiler/stranal | |
parent | 155d943cbbe0ee8c3443bb76c74dff99355b55aa (diff) | |
download | haskell-af12cf66d1a416a135cb98b86717aba2cd247e1a.tar.gz |
ignore RealWorld in size_expr; flag to keep w/w from creating sharing
size_expr now ignores RealWorld lambdas, arguments, and applications.
Worker-wrapper previously removed all lambdas from a function, if they
were all unused. Removing *all* value lambdas is no longer
allowed. Instead (\_ -> E) will become (\_void -> E), where it used to
become E. The previous behavior can be recovered via the new
-ffun-to-thunk flag.
Nofib notables:
----------------------------------------------------------------
Program O2 O2 newly ignoring RealWorld
and not turning function
closures into thunks
----------------------------------------------------------------
Allocations
comp_lab_zift 333090392% -5.0%
reverse-complem 155188304% -3.2%
rewrite 15380888% +4.0%
boyer2 3901064% +7.5%
rewrite previously benefited from fortunate LoopBreaker choice that is
now disrupted.
A function in boyer2 goes from $wonewayunify1 size 700 to size 650,
thus gets inlined into rewritelemmas, thus exposing a parameter
scrutinisation, thus allowing SpecConstr, which unfortunately involves
reboxing.
Run Time
fannkuch-redux 7.89% -15.9%
hpg 0.25% +5.6%
wang 0.21% +5.8%
/shrug
Diffstat (limited to 'compiler/stranal')
-rw-r--r-- | compiler/stranal/WwLib.lhs | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/compiler/stranal/WwLib.lhs b/compiler/stranal/WwLib.lhs index fb9396e5ea..810db2069b 100644 --- a/compiler/stranal/WwLib.lhs +++ b/compiler/stranal/WwLib.lhs @@ -140,7 +140,7 @@ mkWwBodies dflags fun_ty demands res_info one_shots -- Do CPR w/w. See Note [Always do CPR w/w] ; (wrap_fn_cpr, work_fn_cpr, cpr_res_ty) <- mkWWcpr res_ty res_info - ; let (work_lam_args, work_call_args) = mkWorkerArgs work_args all_one_shots cpr_res_ty + ; let (work_lam_args, work_call_args) = mkWorkerArgs dflags work_args all_one_shots cpr_res_ty ; return ([idDemandInfo v | v <- work_call_args, isId v], wrap_fn_args . wrap_fn_cpr . wrap_fn_str . applyToVars work_call_args . Var, mkLams work_lam_args. work_fn_str . work_fn_cpr . work_fn_args) } @@ -184,23 +184,39 @@ add a void argument. E.g. We use the state-token type which generates no code. \begin{code} -mkWorkerArgs :: [Var] +mkWorkerArgs :: DynFlags -> [Var] -> Bool -- Whether all arguments are one-shot -> Type -- Type of body -> ([Var], -- Lambda bound args [Var]) -- Args at call site -mkWorkerArgs args all_one_shot res_ty - | any isId args || not (isUnLiftedType res_ty) +mkWorkerArgs dflags args all_one_shot res_ty + | any isId args || not needsAValueLambda = (args, args) | otherwise = (args ++ [newArg], args ++ [realWorldPrimId]) where + needsAValueLambda = + isUnLiftedType res_ty + || not (gopt Opt_FunToThunk dflags) + -- see Note [Protecting the last value argument] + -- see Note [All One-Shot Arguments of a Worker] newArg = if all_one_shot then setOneShotLambda voidArgId else voidArgId \end{code} +Note [Protecting the last value argument] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If the user writes (\_ -> E), they might be intentionally disallowing +the sharing of E. Since absence analysis and worker-wrapper are keen +to remove such unused arguments, we add in a void argument to prevent +the function from becoming a thunk. + +The user can avoid that argument with the -ffun-to-thunk +flag. However, removing all the value argus may introduce space leaks. + Note [All One-Shot Arguments of a Worker] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |