diff options
author | Sergei Trofimovich <slyfox@gentoo.org> | 2016-09-02 18:47:56 +0100 |
---|---|---|
committer | Sergei Trofimovich <siarheit@google.com> | 2016-09-02 21:42:44 +0100 |
commit | f93c363fab1ac8ce6f0b474f5967b0b097995827 (patch) | |
tree | 8c8b7f5d9ff70ad614fa6b66897d69df8563c620 /compiler/stranal | |
parent | 133a5cc6647a2ea5a63b8d81f9f357f89cb541ef (diff) | |
download | haskell-f93c363fab1ac8ce6f0b474f5967b0b097995827.tar.gz |
extend '-fmax-worker-args' limit to specialiser (Trac #11565)
It's a complementary change to
a48de37dcca98e7d477040b0ed298bcd1b3ab303
restore -fmax-worker-args handling (Trac #11565)
I don't have a small example but I've noticed another
discrepancy when was profiling GHC for performance
cmmExprNative :: ReferenceKind -> CmmExpr -> CmmOptM CmmExpr
was specialised by 'spec_one' down to a function with arity 159.
As a result 'perf record' pointed at it as at slowest
function in whole ghc library.
I've extended -fmax-worker-args effect to 'spec_one'
as it does the same worker/wrapper split to push
arguments to the heap.
The change decreases heap usage on a synth.bash benchmark
(Trac #9221) from 67G down to 64G (-4%). Benchmark runtime
decreased from 14.5 s down to 14.s (-7%).
Signed-off-by: Sergei Trofimovich <siarheit@google.com>
Reviewers: ezyang, simonpj, austin, goldfire, bgamari
Subscribers: thomie
Differential Revision: https://phabricator.haskell.org/D2507
GHC Trac Issues: #11565
Diffstat (limited to 'compiler/stranal')
-rw-r--r-- | compiler/stranal/WwLib.hs | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/compiler/stranal/WwLib.hs b/compiler/stranal/WwLib.hs index 1a096052db..64de0e0078 100644 --- a/compiler/stranal/WwLib.hs +++ b/compiler/stranal/WwLib.hs @@ -8,6 +8,7 @@ module WwLib ( mkWwBodies, mkWWstr, mkWorkerArgs , deepSplitProductType_maybe, findTypeShape + , isWorkerSmallEnough ) where #include "HsVersions.h" @@ -143,7 +144,8 @@ mkWwBodies dflags fam_envs fun_ty demands res_info wrapper_body = wrap_fn_args . wrap_fn_cpr . wrap_fn_str . applyToVars work_call_args . Var worker_body = mkLams work_lam_args. work_fn_str . work_fn_cpr . work_fn_args - ; if is_small_enough work_args && (useful1 && not only_one_void_argument || useful2) + ; if isWorkerSmallEnough dflags work_args + && (useful1 && not only_one_void_argument || useful2) then return (Just (worker_args_dmds, wrapper_body, worker_body)) else return Nothing } @@ -163,10 +165,12 @@ mkWwBodies dflags fam_envs fun_ty demands res_info = True | otherwise = False - is_small_enough args = count isId args <= maxWorkerArgs dflags - -- See Note [Limit w/w arity] - -- We count only Free variables (isId) to skip Type, Kind - -- variables which have no runtime representation. + +-- See Note [Limit w/w arity] +isWorkerSmallEnough :: DynFlags -> [Var] -> Bool +isWorkerSmallEnough dflags vars = count isId vars <= maxWorkerArgs dflags + -- We count only Free variables (isId) to skip Type, Kind + -- variables which have no runtime representation. {- Note [Always do CPR w/w] |