[Git][ghc/ghc][wip/marge_bot_batch_merge_job] 6 commits: Add an example to liftIO and explain its purpose
Marge Bot
gitlab at gitlab.haskell.org
Fri Apr 10 15:48:25 UTC 2020
Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
045139f4 by Hécate at 2020-04-09T23:10:44-04:00
Add an example to liftIO and explain its purpose
- - - - -
101fab6e by Sebastian Graf at 2020-04-09T23:11:21-04:00
Special case `isConstraintKindCon` on `AlgTyCon`
Previously, the `tyConUnique` record selector would unfold into a huge
case expression that would be inlined in all call sites, such as the
`INLINE`-annotated `coreView`, see #18026. `constraintKindTyConKey` only
occurs as the `Unique` of an `AlgTyCon` anyway, so we can make the code
a lot more compact, but have to move it to GHC.Core.TyCon.
Metric Decrease:
T12150
T12234
- - - - -
f5212dfc by Sebastian Graf at 2020-04-09T23:11:57-04:00
DmdAnal: No need to attach a StrictSig to DataCon workers
In GHC.Types.Id.Make we were giving a strictness signature to every data
constructor wrapper Id that we weren't looking at in demand analysis
anyway. We used to use its CPR info, but that has its own CPR signature
now.
`Note [Data-con worker strictness]` then felt very out of place, so I
moved it to GHC.Core.DataCon.
- - - - -
75a185dc by Sylvain Henry at 2020-04-09T23:12:37-04:00
Hadrian: fix --summary
- - - - -
723062ed by Ömer Sinan Ağacan at 2020-04-10T09:18:14+03:00
testsuite: Move no_lint to the top level, tweak hie002
- We don't want to benchmark linting so disable lints in hie002 perf
test
- Move no_lint to the top-level to be able to use it in tests other than
those in `testsuite/tests/perf/compiler`.
- Filter out -dstg-lint in no_lint.
- hie002 allocation numbers on 32-bit are unstable, so skip it on 32-bit
Metric Decrease:
hie002
ManyConstructors
T12150
T12234
T13035
T1969
T4801
T9233
T9961
- - - - -
7ac4eba1 by Peter Trommler at 2020-04-10T11:48:17-04:00
Testsuite: mark T11531 fragile
The test depends on a link editor allowing undefined symbols in an ELF
shared object. This is the standard but it seems some distributions
patch their link editor. See the report by @hsyl20 in #11531.
Fixes #11531
- - - - -
14 changed files:
- compiler/GHC/Core/DataCon.hs
- compiler/GHC/Core/Op/DmdAnal.hs
- compiler/GHC/Core/Op/Simplify.hs
- compiler/GHC/Core/TyCon.hs
- compiler/GHC/Core/Type.hs
- compiler/GHC/Types/Demand.hs
- compiler/GHC/Types/Id/Make.hs
- compiler/prelude/TysWiredIn.hs
- hadrian/src/Settings/Builders/RunTest.hs
- libraries/base/Control/Monad/IO/Class.hs
- testsuite/driver/testlib.py
- testsuite/tests/ghci/linking/all.T
- testsuite/tests/hiefile/should_compile/all.T
- testsuite/tests/perf/compiler/all.T
Changes:
=====================================
compiler/GHC/Core/DataCon.hs
=====================================
@@ -614,7 +614,7 @@ data DataConRep
-- and *including* all evidence args
, dcr_stricts :: [StrictnessMark] -- 1-1 with dcr_arg_tys
- -- See also Note [Data-con worker strictness] in GHC.Types.Id.Make
+ -- See also Note [Data-con worker strictness]
, dcr_bangs :: [HsImplBang] -- The actual decisions made (including failures)
-- about the original arguments; 1-1 with orig_arg_tys
@@ -715,8 +715,26 @@ filterEqSpec eq_spec
instance Outputable EqSpec where
ppr (EqSpec tv ty) = ppr (tv, ty)
-{- Note [Bangs on data constructor arguments]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+{- Note [Data-con worker strictness]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Notice that we do *not* say the worker Id is strict even if the data
+constructor is declared strict
+ e.g. data T = MkT !(Int,Int)
+Why? Because the *wrapper* $WMkT is strict (and its unfolding has case
+expressions that do the evals) but the *worker* MkT itself is not. If we
+pretend it is strict then when we see
+ case x of y -> MkT y
+the simplifier thinks that y is "sure to be evaluated" (because the worker MkT
+is strict) and drops the case. No, the workerId MkT is not strict.
+
+However, the worker does have StrictnessMarks. When the simplifier sees a
+pattern
+ case e of MkT x -> ...
+it uses the dataConRepStrictness of MkT to mark x as evaluated; but that's
+fine... dataConRepStrictness comes from the data con not from the worker Id.
+
+Note [Bangs on data constructor arguments]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Consider
data T = MkT !Int {-# UNPACK #-} !Int Bool
=====================================
compiler/GHC/Core/Op/DmdAnal.hs
=====================================
@@ -454,7 +454,7 @@ dmdTransform :: AnalEnv -- The strictness environment
dmdTransform env var dmd
| isDataConWorkId var -- Data constructor
- = dmdTransformDataConSig (idArity var) (idStrictness var) dmd
+ = dmdTransformDataConSig (idArity var) dmd
| gopt Opt_DmdTxDictSel (ae_dflags env),
Just _ <- isClassOpId_maybe var -- Dictionary component selector
=====================================
compiler/GHC/Core/Op/Simplify.hs
=====================================
@@ -2758,7 +2758,7 @@ a case pattern. This is *important*. Consider
We really must record that b is already evaluated so that we don't
go and re-evaluate it when constructing the result.
-See Note [Data-con worker strictness] in GHC.Types.Id.Make
+See Note [Data-con worker strictness] in GHC.Core.DataCon
NB: simplLamBndrs preserves this eval info
=====================================
compiler/GHC/Core/TyCon.hs
=====================================
@@ -45,7 +45,7 @@ module GHC.Core.TyCon(
noTcTyConScopedTyVars,
-- ** Predicates on TyCons
- isAlgTyCon, isVanillaAlgTyCon,
+ isAlgTyCon, isVanillaAlgTyCon, isConstraintKindCon,
isClassTyCon, isFamInstTyCon,
isFunTyCon,
isPrimTyCon,
@@ -1868,6 +1868,15 @@ isVanillaAlgTyCon :: TyCon -> Bool
isVanillaAlgTyCon (AlgTyCon { algTcParent = VanillaAlgTyCon _ }) = True
isVanillaAlgTyCon _ = False
+-- | Returns @True@ for the 'TyCon' of the 'Constraint' kind.
+isConstraintKindCon :: TyCon -> Bool
+-- NB: We intentionally match on AlgTyCon, because 'constraintKindTyCon' is
+-- always an AlgTyCon (see 'pcTyCon' in TysWiredIn) and the record selector
+-- for 'tyConUnique' would generate unreachable code for every other data
+-- constructor of TyCon (see #18026).
+isConstraintKindCon AlgTyCon { tyConUnique = u } = u == constraintKindTyConKey
+isConstraintKindCon _ = False
+
isDataTyCon :: TyCon -> Bool
-- ^ Returns @True@ for data types that are /definitely/ represented by
-- heap-allocated constructors. These are scrutinised by Core-level
=====================================
compiler/GHC/Core/Type.hs
=====================================
@@ -2924,9 +2924,6 @@ distinct uniques, they are treated as equal at all times except
during type inference.
-}
-isConstraintKindCon :: TyCon -> Bool
-isConstraintKindCon tc = tyConUnique tc == constraintKindTyConKey
-
-- | Tests whether the given kind (which should look like @TYPE x@)
-- is something other than a constructor tree (that is, constructors at every node).
-- E.g. True of TYPE k, TYPE (F Int)
=====================================
compiler/GHC/Types/Demand.hs
=====================================
@@ -1666,17 +1666,15 @@ dmdTransformSig (StrictSig dmd_ty@(DmdType _ arg_ds _)) cd
= postProcessUnsat (peelManyCalls (length arg_ds) cd) dmd_ty
-- see Note [Demands from unsaturated function calls]
-dmdTransformDataConSig :: Arity -> StrictSig -> CleanDemand -> DmdType
+dmdTransformDataConSig :: Arity -> CleanDemand -> DmdType
-- Same as dmdTransformSig but for a data constructor (worker),
-- which has a special kind of demand transformer.
-- If the constructor is saturated, we feed the demand on
-- the result into the constructor arguments.
-dmdTransformDataConSig arity (StrictSig (DmdType _ _ con_res))
- (JD { sd = str, ud = abs })
+dmdTransformDataConSig arity (JD { sd = str, ud = abs })
| Just str_dmds <- go_str arity str
, Just abs_dmds <- go_abs arity abs
- = DmdType emptyDmdEnv (mkJointDmds str_dmds abs_dmds) con_res
- -- Must remember whether it's a product, hence con_res, not TopRes
+ = DmdType emptyDmdEnv (mkJointDmds str_dmds abs_dmds) topDiv
| otherwise -- Not saturated
= nopDmdType
=====================================
compiler/GHC/Types/Id/Make.hs
=====================================
@@ -506,10 +506,9 @@ mkDataConWorkId wkr_name data_con
tycon = dataConTyCon data_con -- The representation TyCon
wkr_ty = dataConRepType data_con
- ----------- Workers for data types --------------
+ ----------- Workers for data types --------------
alg_wkr_info = noCafIdInfo
`setArityInfo` wkr_arity
- `setStrictnessInfo` wkr_sig
`setCprInfo` mkCprSig wkr_arity (dataConCPR data_con)
`setUnfoldingInfo` evaldUnfolding -- Record that it's evaluated,
-- even if arity = 0
@@ -518,27 +517,7 @@ mkDataConWorkId wkr_name data_con
-- setNeverLevPoly
wkr_arity = dataConRepArity data_con
- wkr_sig = mkClosedStrictSig (replicate wkr_arity topDmd) topDiv
- -- Note [Data-con worker strictness]
- -- Notice that we do *not* say the worker Id is strict
- -- even if the data constructor is declared strict
- -- e.g. data T = MkT !(Int,Int)
- -- Why? Because the *wrapper* $WMkT is strict (and its unfolding has
- -- case expressions that do the evals) but the *worker* MkT itself is
- -- not. If we pretend it is strict then when we see
- -- case x of y -> MkT y
- -- the simplifier thinks that y is "sure to be evaluated" (because
- -- the worker MkT is strict) and drops the case. No, the workerId
- -- MkT is not strict.
- --
- -- However, the worker does have StrictnessMarks. When the simplifier
- -- sees a pattern
- -- case e of MkT x -> ...
- -- it uses the dataConRepStrictness of MkT to mark x as evaluated;
- -- but that's fine... dataConRepStrictness comes from the data con
- -- not from the worker Id.
-
- ----------- Workers for newtypes --------------
+ ----------- Workers for newtypes --------------
univ_tvs = dataConUnivTyVars data_con
arg_tys = dataConRepArgTys data_con -- Should be same as dataConOrigArgTys
nt_work_info = noCafIdInfo -- The NoCaf-ness is set by noCafIdInfo
=====================================
compiler/prelude/TysWiredIn.hs
=====================================
@@ -639,6 +639,7 @@ typeNatKind = mkTyConTy typeNatKindCon
typeSymbolKind = mkTyConTy typeSymbolKindCon
constraintKindTyCon :: TyCon
+-- 'TyCon.isConstraintKindCon' assumes that this is an AlgTyCon!
constraintKindTyCon = pcTyCon constraintKindTyConName Nothing [] []
liftedTypeKind, typeToTypeKind, constraintKind :: Kind
=====================================
hadrian/src/Settings/Builders/RunTest.hs
=====================================
@@ -165,7 +165,7 @@ getTestArgs = do
brokenTestArgs = concat [ ["--broken-test", t] | t <- brokenTests args ]
speedArg = ["-e", "config.speed=" ++ setTestSpeed (testSpeed args)]
summaryArg = case testSummary args of
- Just filepath -> Just $ "--summary-file " ++ show filepath
+ Just filepath -> Just $ "--summary-file=" ++ filepath
Nothing -> Just $ "--summary-file=testsuite_summary.txt"
junitArg = case testJUnit args of
Just filepath -> Just $ "--junit=" ++ filepath
=====================================
libraries/base/Control/Monad/IO/Class.hs
=====================================
@@ -30,8 +30,42 @@ module Control.Monad.IO.Class (
class (Monad m) => MonadIO m where
-- | Lift a computation from the 'IO' monad.
+ -- This allows us to run IO computations in any monadic stack, so long as it supports these kinds of operations
+ -- (i.e. 'IO' is the base monad for the stack).
+ --
+ -- === __Example__
+ --
+ --
+ -- > import Control.Monad.Trans.State -- from the "transformers" library
+ -- >
+ -- > printState :: Show s => StateT s IO ()
+ -- > printState = do
+ -- > state <- get
+ -- > liftIO $ print state
+ --
+ --
+ -- Had we omitted @'liftIO'@, we would have ended up with this error:
+ --
+ -- > • Couldn't match type ‘IO’ with ‘StateT s IO’
+ -- > Expected type: StateT s IO ()
+ -- > Actual type: IO ()
+ --
+ -- The important part here is the mismatch between @StateT s IO ()@ and @'IO' ()@.
+ --
+ -- Luckily, we know of a function that takes an @'IO' a@ and returns an @(m a)@: @'liftIO'@,
+ -- enabling us to run the program and see the expected results:
+ --
+ -- @
+ -- > evalStateT printState "hello"
+ -- "hello"
+ --
+ -- > evalStateT printState 3
+ -- 3
+ -- @
+ --
liftIO :: IO a -> m a
-- | @since 4.9.0.0
instance MonadIO IO where
liftIO = id
+
=====================================
testsuite/driver/testlib.py
=====================================
@@ -116,6 +116,12 @@ def expect_fail( name, opts ):
# future.
opts.expect = 'fail';
+def no_lint( name, opts ):
+ """Disable Core, STG and Cmm lints. Useful when testing compiler perf."""
+ opts.compiler_always_flags = \
+ [opt for opt in opts.compiler_always_flags \
+ if opt not in ['-dcore-lint', '-dstg-lint', '-dcmm-lint']]
+
def reqlib( lib ):
return lambda name, opts, l=lib: _reqlib (name, opts, l )
=====================================
testsuite/tests/ghci/linking/all.T
=====================================
@@ -46,7 +46,8 @@ test('T3333',
test('T11531',
[extra_files(['T11531.hs', 'T11531.c', 'T11531.h']),
unless(doing_ghci, skip),
- unless(opsys('linux'), skip)],
+ unless(opsys('linux'), skip),
+ fragile(11531)],
makefile_test, ['T11531'])
test('T14708',
=====================================
testsuite/tests/hiefile/should_compile/all.T
=====================================
@@ -1,6 +1,12 @@
test('hie001', normal, compile, ['-fno-code -fwrite-ide-info -fvalidate-ide-info'])
-test('hie002', collect_compiler_stats('bytes allocated',10),
- compile, ['-fno-code -fwrite-ide-info'])
+test('hie002',
+ [# Allocation numbers unstable on 32-bit, skip:
+ when(wordsize(32), skip),
+ # No linting in perf tests:
+ no_lint,
+ collect_compiler_stats('bytes allocated',10)],
+ compile,
+ ['-fno-code -fwrite-ide-info'])
test('hie003', normal, compile, ['-fno-code -fwrite-ide-info -fvalidate-ide-info'])
test('hie004', normal, compile, ['-fno-code -fwrite-ide-info -fvalidate-ide-info'])
test('hie005', normal, compile, ['-fno-code -fwrite-ide-info -fvalidate-ide-info'])
=====================================
testsuite/tests/perf/compiler/all.T
=====================================
@@ -1,10 +1,5 @@
# Tests that call 'collect_compiler_stats' are skipped when debugging is on.
# See testsuite/driver/testlib.py.
-
-def no_lint(name, opts):
- opts.compiler_always_flags = \
- [opt for opt in opts.compiler_always_flags if opt != '-dcore-lint' and opt != '-dcmm-lint']
-
setTestOpts(no_lint)
test('T1969',
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2a829409461c65ca783bb93c7fc1b5978ba33ecf...7ac4eba1ab1c11c0dc079bb1c68e103675cb6c49
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2a829409461c65ca783bb93c7fc1b5978ba33ecf...7ac4eba1ab1c11c0dc079bb1c68e103675cb6c49
You're receiving this email because of your account on gitlab.haskell.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20200410/5ec33b48/attachment-0001.html>
More information about the ghc-commits
mailing list