summaryrefslogtreecommitdiff
path: root/compiler/GHC/Stg
diff options
context:
space:
mode:
authorAndreas Klebinger <klebinger.andreas@gmx.at>2022-05-04 10:50:04 +0200
committerMarge Bot <ben+marge-bot@smart-cactus.org>2022-06-27 08:01:39 -0400
commitac7a7fc88b51f9fb4e84499397e12eb0081ba79e (patch)
tree075714e3c20f6aa770e8a5cb508112436fe466b5 /compiler/GHC/Stg
parent38378be3506f0d4f597fcd5aa2d9db3124fbf535 (diff)
downloadhaskell-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.hs7
-rw-r--r--compiler/GHC/Stg/InferTags/Rewrite.hs2
-rw-r--r--compiler/GHC/Stg/Lint.hs2
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 $