diff options
author | Andreas Klebinger <klebinger.andreas@gmx.at> | 2022-05-04 10:50:04 +0200 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2022-06-27 08:01:39 -0400 |
commit | ac7a7fc88b51f9fb4e84499397e12eb0081ba79e (patch) | |
tree | 075714e3c20f6aa770e8a5cb508112436fe466b5 /compiler/GHC/Stg | |
parent | 38378be3506f0d4f597fcd5aa2d9db3124fbf535 (diff) | |
download | haskell-ac7a7fc88b51f9fb4e84499397e12eb0081ba79e.tar.gz |
Don't mark lambda binders as OtherCon
We used to put OtherCon unfoldings on lambda binders of workers
and sometimes also join points/specializations with with the
assumption that since the wrapper would force these arguments
once we execute the RHS they would indeed be in WHNF.
This was wrong for reasons detailed in #21472. So now we purge
evaluated unfoldings from *all* lambda binders.
This fixes #21472, but at the cost of sometimes not using as efficient a
calling convention. It can also change inlining behaviour as some
occurances will no longer look like value arguments when they did
before.
As consequence we also change how we compute CBV information for
arguments slightly. We now *always* determine the CBV convention
for arguments during tidy. Earlier in the pipeline we merely mark
functions as candidates for having their arguments treated as CBV.
As before the process is described in the relevant notes:
Note [CBV Function Ids]
Note [Attaching CBV Marks to ids]
Note [Never put `OtherCon` unfoldigns on lambda binders]
-------------------------
Metric Decrease:
T12425
T13035
T18223
T18223
T18923
MultiLayerModulesTH_OneShot
Metric Increase:
WWRec
-------------------------
Diffstat (limited to 'compiler/GHC/Stg')
-rw-r--r-- | compiler/GHC/Stg/InferTags.hs | 7 | ||||
-rw-r--r-- | compiler/GHC/Stg/InferTags/Rewrite.hs | 2 | ||||
-rw-r--r-- | compiler/GHC/Stg/Lint.hs | 2 |
3 files changed, 6 insertions, 5 deletions
diff --git a/compiler/GHC/Stg/InferTags.hs b/compiler/GHC/Stg/InferTags.hs index 6d28f447d5..9081f21006 100644 --- a/compiler/GHC/Stg/InferTags.hs +++ b/compiler/GHC/Stg/InferTags.hs @@ -82,7 +82,7 @@ and will be tagged with `001` or `010` respectively. It will never point to a thunk, nor will it be tagged `000` (meaning "might be a thunk"). NB: Note that the proper tag for some objects is indeed `000`. Currently this is the case for PAPs. -This works analogous to how `StrictWorkerId`s work. See also Note [Strict Worker Ids]. +This works analogous to how `WorkerLikeId`s work. See also Note [CBV Function Ids]. Why do we care? Because if we have code like: @@ -121,7 +121,7 @@ evaluated will allocate the constructor. So we do our best to establish that `x` is already tagged (which it almost always is) to avoid this cost. In my benchmarks I haven't seen any cases where this causes regressions. -Note that there are similar constraints around Note [Strict Worker Ids]. +Note that there are similar constraints around Note [CBV Function Ids]. Note [How untagged pointers can end up in strict fields] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -186,7 +186,8 @@ As it makes little difference for runtime performance I've treated functions as it made the code simpler. But besides implementation complexity there isn't any reason why we couldn't be more rigourous in dealing with functions. -NB: It turned out because of #21193 option two wouldn't really have been an option anyway. +NB: It turned in #21193 that PAPs get tag zero, so the tag check can't be omitted for functions. +So option two isn't really an option without reworking this anyway. Note [Tag inference debugging] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/compiler/GHC/Stg/InferTags/Rewrite.hs b/compiler/GHC/Stg/InferTags/Rewrite.hs index 8076507a1c..340ff2fff0 100644 --- a/compiler/GHC/Stg/InferTags/Rewrite.hs +++ b/compiler/GHC/Stg/InferTags/Rewrite.hs @@ -91,7 +91,7 @@ It's notable that the worker is called *undersatured* in the wrapper. At runtime what happens is that the wrapper will allocate a PAP which once fully applied will call the worker. And all is fine. -But what about a strict worker! Well the function returned by `f` would +But what about a call by value function! Well the function returned by `f` would be a unknown call, so we lose the ability to enfore the invariant that cbv marked arguments from StictWorkerId's are actually properly tagged as the annotations would be unavailable at the (unknown) call site. diff --git a/compiler/GHC/Stg/Lint.hs b/compiler/GHC/Stg/Lint.hs index cd9f3dff03..63154a48bd 100644 --- a/compiler/GHC/Stg/Lint.hs +++ b/compiler/GHC/Stg/Lint.hs @@ -382,7 +382,7 @@ lintAppCbvMarks e@(StgApp fun args) = do when (lf_unarised lf) $ do -- A function which expects a unlifted argument as n'th argument -- always needs to be applied to n arguments. - -- See Note [Strict Worker Ids]. + -- See Note [CBV Function Ids]. let marks = fromMaybe [] $ idCbvMarks_maybe fun when (length (dropWhileEndLE (not . isMarkedCbv) marks) > length args) $ do addErrL $ hang (text "Undersatured cbv marked ID in App" <+> ppr e ) 2 $ |