Skip to content
  • Simon Peyton Jones's avatar
    [project @ 2001-08-23 07:13:16 by simonpj] · 92fbaba6
    Simon Peyton Jones authored
    ------------------------------
    	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
    92fbaba6