summaryrefslogtreecommitdiff
path: root/compiler/GHC/Core/Utils.hs
diff options
context:
space:
mode:
authorSimon Peyton Jones <simonpj@microsoft.com>2022-07-07 14:21:41 +0100
committerSimon Peyton Jones <simonpj@microsoft.com>2022-08-25 08:38:16 +0100
commita90298cc7291677fddd9e374e222676306265c17 (patch)
tree8db696c8599547a2775eec15108d49304744f58f /compiler/GHC/Core/Utils.hs
parenta9f0e68ede36ad571d32e66a8e49e8c9f3b6a92b (diff)
downloadhaskell-wip/T21694a.tar.gz
Fix arityType: -fpedantic-bottoms, join points, etcwip/T21694a
This MR fixes #21694, #21755. It also makes sure that #21948 and fix to #21694. * For #21694 the underlying problem was that we were calling arityType on an expression that had free join points. This is a Bad Bad Idea. See Note [No free join points in arityType]. * To make "no free join points in arityType" work out I had to avoid trying to use eta-expansion for runRW#. This entailed a few changes in the Simplifier's treatment of runRW#. See GHC.Core.Opt.Simplify.Iteration Note [No eta-expansion in runRW#] * I also made andArityType work correctly with -fpedantic-bottoms; see Note [Combining case branches: andWithTail]. * Rewrote Note [Combining case branches: optimistic one-shot-ness] * arityType previously treated join points differently to other let-bindings. This patch makes them unform; arityType analyses the RHS of all bindings to get its ArityType, and extends am_sigs. I realised that, now we have am_sigs giving the ArityType for let-bound Ids, we don't need the (pre-dating) special code in arityType for join points. But instead we need to extend the env for Rec bindings, which weren't doing before. More uniform now. See Note [arityType for let-bindings]. This meant we could get rid of ae_joins, and in fact get rid of EtaExpandArity altogether. Simpler. * And finally, it was the strange treatment of join-point Ids in arityType (involving a fake ABot type) that led to a serious bug: #21755. Fixed by this refactoring, which treats them uniformly; but without breaking #18328. In fact, the arity for recursive join bindings is pretty tricky; see the long Note [Arity for recursive join bindings] in GHC.Core.Opt.Simplify.Utils. That led to more refactoring, including deciding that an Id could have an Arity that is bigger than its JoinArity; see Note [Invariants on join points], item 2(b) in GHC.Core * Make sure that the "demand threshold" for join points in DmdAnal is no bigger than the join-arity. In GHC.Core.Opt.DmdAnal see Note [Demand signatures are computed for a threshold arity based on idArity] * I moved GHC.Core.Utils.exprIsDeadEnd into GHC.Core.Opt.Arity, where it more properly belongs. * Remove an old, redundant hack in FloatOut. The old Note was Note [Bottoming floats: eta expansion] in GHC.Core.Opt.SetLevels. Compile time improves very slightly on average: Metrics: compile_time/bytes allocated --------------------------------------------------------------------------------------- T18223(normal) ghc/alloc 725,808,720 747,839,216 +3.0% BAD T6048(optasm) ghc/alloc 105,006,104 101,599,472 -3.2% GOOD geo. mean -0.2% minimum -3.2% maximum +3.0% For some reason Windows was better T10421(normal) ghc/alloc 125,888,360 124,129,168 -1.4% GOOD T18140(normal) ghc/alloc 85,974,520 83,884,224 -2.4% GOOD T18698b(normal) ghc/alloc 236,764,568 234,077,288 -1.1% GOOD T18923(normal) ghc/alloc 75,660,528 73,994,512 -2.2% GOOD T6048(optasm) ghc/alloc 112,232,512 108,182,520 -3.6% GOOD geo. mean -0.6% I had a quick look at T18223 but it is knee deep in coercions and the size of everything looks similar before and after. I decided to accept that 3% increase in exchange for goodness elsewhere. Metric Decrease: T10421 T18140 T18698b T18923 T6048 Metric Increase: T18223
Diffstat (limited to 'compiler/GHC/Core/Utils.hs')
-rw-r--r--compiler/GHC/Core/Utils.hs59
1 files changed, 2 insertions, 57 deletions
diff --git a/compiler/GHC/Core/Utils.hs b/compiler/GHC/Core/Utils.hs
index 30597dd8e5..57a1ccacc3 100644
--- a/compiler/GHC/Core/Utils.hs
+++ b/compiler/GHC/Core/Utils.hs
@@ -23,7 +23,7 @@ module GHC.Core.Utils (
-- * Properties of expressions
exprType, coreAltType, coreAltsType, mkLamType, mkLamTypes,
mkFunctionType,
- exprIsDupable, exprIsTrivial, getIdFromTrivialExpr, exprIsDeadEnd,
+ exprIsDupable, exprIsTrivial, getIdFromTrivialExpr,
getIdFromTrivialExpr_maybe,
exprIsCheap, exprIsExpandable, exprIsCheapX, CheapAppFun,
exprIsHNF, exprOkForSpeculation, exprOkForSideEffects, exprOkForSpecEval,
@@ -1073,63 +1073,8 @@ getIdFromTrivialExpr_maybe e
go (Var v) = Just v
go _ = Nothing
-{-
-exprIsDeadEnd is a very cheap and cheerful function; it may return
-False for bottoming expressions, but it never costs much to ask. See
-also GHC.Core.Opt.Arity.exprBotStrictness_maybe, but that's a bit more
-expensive.
--}
-exprIsDeadEnd :: CoreExpr -> Bool
--- See Note [Bottoming expressions]
-exprIsDeadEnd e
- | isEmptyTy (exprType e)
- = True
- | otherwise
- = go 0 e
- where
- go n (Var v) = isDeadEndAppSig (idDmdSig v) n
- go n (App e a) | isTypeArg a = go n e
- | otherwise = go (n+1) e
- go n (Tick _ e) = go n e
- go n (Cast e _) = go n e
- go n (Let _ e) = go n e
- go n (Lam v e) | isTyVar v = go n e
- go _ (Case _ _ _ alts) = null alts
- -- See Note [Empty case alternatives] in GHC.Core
- go _ _ = False
-
-{- Note [Bottoming expressions]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-A bottoming expression is guaranteed to diverge, or raise an
-exception. We can test for it in two different ways, and exprIsDeadEnd
-checks for both of these situations:
-
-* Visibly-bottom computations. For example
- (error Int "Hello")
- is visibly bottom. The strictness analyser also finds out if
- a function diverges or raises an exception, and puts that info
- in its strictness signature.
-
-* Empty types. If a type is empty, its only inhabitant is bottom.
- For example:
- data T
- f :: T -> Bool
- f = \(x:t). case x of Bool {}
- Since T has no data constructors, the case alternatives are of course
- empty. However note that 'x' is not bound to a visibly-bottom value;
- it's the *type* that tells us it's going to diverge.
-
-A GADT may also be empty even though it has constructors:
- data T a where
- T1 :: a -> T Bool
- T2 :: T Int
- ...(case (x::T Char) of {})...
-Here (T Char) is uninhabited. A more realistic case is (Int ~ Bool),
-which is likewise uninhabited.
-
-
-************************************************************************
+{- *********************************************************************
* *
exprIsDupable
* *