[project @ 2001-08-23 07:13:16 by simonpj]
------------------------------
Improve the demand analyser [case]
------------------------------
1. In the Case case of dmdAnal, I dealt with the case binder in a way that
was both clumsy and pessimistic. This commit fixes that:
-- Figure out whether the demand on the case binder is used, and use
-- that to set the scrut_dmd. This is utterly essential.
-- Consider f x = case x of y { (a,b) -> k y a }
-- If we just take scrut_demand = U(L,A), then we won't pass x to the
-- worker, so the worker will rebuild
-- x = (a, absent-error)
-- and that'll crash.
-- So at one stage I had:
-- dead_case_bndr = isAbsentDmd (idNewDemandInfo case_bndr')
-- keepity | dead_case_bndr = Drop
-- | otherwise = Keep
--
-- But then consider
-- case x of y { (a,b) -> h y + a }
-- where h : U(LL) -> T
-- The above code would compute a Keep for x, since y is not Abs, which is silly
-- The insight is, of course, that a demand on y is a demand on the
-- scrutinee, so we need to `both` it with the scrut demand
scrut_dmd = Seq Drop Now [idNewDemandInfo b | b <- bndrs', isId b]
`both`
idNewDemandInfo case_bndr'
-- There used to be a special case for when
-- ty == TyVarTy tv
-- (a not-uncommon case) in which case the substitution was dropped.
-- But the type-tidier changes the print-name of a type variable without
-- changing the unique, and that led to a bug. Why? Pre-tidying, we had
-- a type {Foo t}, where Foo is a one-method class. So Foo is really a newtype.
-- And it happened that t was the type variable of the class. Post-tiding,
2. 'defer' can be simplified to 'lub Abs', reducing the number of places
where things can go wrong.
3. Add comments