summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Klebinger <klebinger.andreas@gmx.at>2022-04-16 00:41:40 +0200
committerZubin Duggal <zubin.duggal@gmail.com>2022-05-09 13:41:14 +0530
commit8ecdff137f98fd16086ea635b86239adb4005d59 (patch)
tree0d64d7173eb86bafdec23f3b6946949c3cadea47
parent7109045a103e060af6aca77ee70d32ff75d4d46f (diff)
downloadhaskell-wip/9.2.3-backports.tar.gz
Fix a shadowing issue in StgUnarise.wip/9.2.3-backports
For I assume performance reasons we don't record no-op replacements during unarise. This lead to problems with code like this: f = \(Eta_B0 :: VoidType) x1 x2 -> ... let foo = \(Eta_B0 :: LiftedType) -> g x y Eta_B0 in ... Here we would record the outer Eta_B0 as void rep, but would not shadow Eta_B0 inside `foo` because this arg is single-rep and so doesn't need to replaced. But this means when looking at occurence sites we would check the env and assume it's void rep based on the entry we made for the (no longer in scope) outer `Eta_B0`. Fixes #21396 and the ticket has a few more details. (cherry picked from commit 49bd758417fd539080469f2fc2a996ea6dc75d45)
-rw-r--r--compiler/GHC/Stg/Unarise.hs24
1 files changed, 23 insertions, 1 deletions
diff --git a/compiler/GHC/Stg/Unarise.hs b/compiler/GHC/Stg/Unarise.hs
index 39cac2ee32..f35e095b29 100644
--- a/compiler/GHC/Stg/Unarise.hs
+++ b/compiler/GHC/Stg/Unarise.hs
@@ -162,6 +162,18 @@ So we pass type arguments of the DataCon's TyCon in StgConApp to decide what
layout to use. Note that unlifted values can't be let-bound, so we don't need
types in StgRhsCon.
+Note [UnariseEnv]
+~~~~~~~~~~~~~~~~~~
+At any variable occurrence 'v',
+* If the UnariseEnv has a binding for 'v', the binding says what 'v' is bound to
+* If not, 'v' stands just for itself.
+
+Most variables are unaffected by unarisation, and (for efficiency) we don't put
+them in the UnariseEnv at all. But NB: when we go under a binding for 'v' we must
+remember to delete 'v' from the UnariseEnv, lest occurrences of 'v' see the outer
+binding for the variable (#21396).
+
+
Note [UnariseEnv can map to literals]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To avoid redundant case expressions when unarising unboxed sums, UnariseEnv
@@ -277,6 +289,8 @@ instance Outputable UnariseVal where
ppr (UnaryVal arg) = text "UnaryVal" <+> ppr arg
-- | Extend the environment, checking the UnariseEnv invariant.
+-- The id is mapped to one or more things.
+-- See Note [UnariseEnv]
extendRho :: UnariseEnv -> Id -> UnariseVal -> UnariseEnv
extendRho rho x (MultiVal args)
= ASSERT(all (isNvUnaryType . stgArgType) args)
@@ -284,6 +298,14 @@ extendRho rho x (MultiVal args)
extendRho rho x (UnaryVal val)
= ASSERT(isNvUnaryType (stgArgType val))
extendVarEnv rho x (UnaryVal val)
+-- Properly shadow things from an outer scope.
+-- See Note [UnariseEnv]
+
+-- The id stands for itself so we don't record a mapping.
+-- See Note [UnariseEnv]
+extendRhoWithoutValue :: UnariseEnv -> Id -> UnariseEnv
+extendRhoWithoutValue rho x = delVarEnv rho x
+
--------------------------------------------------------------------------------
@@ -693,7 +715,7 @@ unariseArgBinder is_con_arg rho x =
-> do x' <- mkId (mkFastString "us") (primRepToType rep)
return (extendRho rho x (MultiVal [StgVarArg x']), [x'])
| otherwise
- -> return (rho, [x])
+ -> return (extendRhoWithoutValue rho x, [x])
reps -> do
xs <- mkIds (mkFastString "us") (map primRepToType reps)