[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