[commit: ghc] master: Do Worker/Wrapper for NOINLINE things (b572aad)
git at git.haskell.org
git at git.haskell.org
Mon Feb 6 03:54:52 UTC 2017
Repository : ssh://git@git.haskell.org/ghc
On branch : master
Link : http://ghc.haskell.org/trac/ghc/changeset/b572aadb20c2e41e2f6d7b48401bd0b4239ce9f8/ghc
>---------------------------------------------------------------
commit b572aadb20c2e41e2f6d7b48401bd0b4239ce9f8
Author: Eric Seidel <eric at seidel.io>
Date: Sun Feb 5 21:29:37 2017 -0500
Do Worker/Wrapper for NOINLINE things
Disabling worker/wrapper for NOINLINE things can cause unnecessary
reboxing of values. Consider
{-# NOINLINE f #-}
f :: Int -> a
f x = error (show x)
g :: Bool -> Bool -> Int -> Int
g True True p = f p
g False True p = p + 1
g b False p = g b True p
the strictness analysis will discover f and g are strict, but because f
has no wrapper, the worker for g will rebox p. So we get
$wg x y p# =
let p = I# p# in -- Yikes! Reboxing!
case x of
False ->
case y of
False -> $wg False True p#
True -> +# p# 1#
True ->
case y of
False -> $wg True True p#
True -> case f p of { }
g x y p = case p of (I# p#) -> $wg x y p#
Now, in this case the reboxing will float into the True branch, an so
the allocation will only happen on the error path. But it won't float
inwards if there are multiple branches that call (f p), so the reboxing
will happen on every call of g. Disaster.
Solution: do worker/wrapper even on NOINLINE things; but move the
NOINLINE pragma to the worker.
Test Plan: make test TEST="13143"
Reviewers: simonpj, bgamari, dfeuer, austin
Reviewed By: simonpj, bgamari
Subscribers: dfeuer, thomie
Differential Revision: https://phabricator.haskell.org/D3046
>---------------------------------------------------------------
b572aadb20c2e41e2f6d7b48401bd0b4239ce9f8
compiler/coreSyn/CoreUnfold.hs | 5 +-
compiler/stranal/WorkWrap.hs | 86 +++++++++++++--
testsuite/tests/perf/join_points/all.T | 4 +-
testsuite/tests/perf/should_run/all.T | 8 +-
testsuite/tests/simplCore/should_compile/T13143.hs | 10 ++
.../tests/simplCore/should_compile/T13143.stderr | 121 +++++++++++++++++++++
.../tests/simplCore/should_compile/T3772.stdout | 32 ++++--
.../tests/simplCore/should_compile/T7360.stderr | 10 +-
.../tests/simplCore/should_compile/T7865.stdout | 10 +-
testsuite/tests/simplCore/should_compile/all.T | 1 +
.../tests/stranal/should_compile/T10694.stderr | 55 ++++++----
.../stranal/sigs/BottomFromInnerLambda.stderr | 4 +-
12 files changed, 290 insertions(+), 56 deletions(-)
Diff suppressed because of size. To see it, use:
git diff-tree --root --patch-with-stat --no-color --find-copies-harder --ignore-space-at-eol --cc b572aadb20c2e41e2f6d7b48401bd0b4239ce9f8
More information about the ghc-commits
mailing list