
#8598: IO hack in demand analyzer gets in the way of CPR -------------------------------------+------------------------------------ Reporter: nomeata | Owner: Type: task | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.6.3 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Unknown/Multiple Type of failure: None/Unknown | Difficulty: Unknown Test Case: T8598 | Blocked By: Blocking: | Related Tickets: -------------------------------------+------------------------------------ Changes (by nomeata): * testcase: => T8598 Comment: My extended approach suggested above has issues. For example, what should be the `DmdResult` of a function parameter be? Lets consider {{{f x y = x `seq` y `seq` ...}}} and look at the `DmdResult` of `x`. Theoretically, we’d want to be conservative, and hence `DmdResult { mayExit = True, mayDiverge = True, cpr = NoCPR }`. But that would loose far too much strictness information, in particular we’d be lazy in `y`, which is undesirable. OTOH, if we assume `DmdResult { mayExit = False, mayDiverge = True, cpr = NoCPR }` for `x` it would be wrong if we pass something that can cleanly exit to `f`. `unsafePerformIO exitSuccess` would be such a thing – but we do not really care about that, right? If we take the stance that clean exists should only really be happening when evaluating `IO` (and any other kind exiting is allowed to be reordered with other evaluations), then a still correct, but more precise analysis that we have right now is to use the elaborated lattice described in comment:5 and move the ''IO hack'' from case expressions to arguments: Use `DmdResult { mayExit = True, mayDiverge = True, cpr = NoCPR }` for arguments of `IO` type, and `DmdResult { mayExit = False, mayDiverge = True, cpr = NoCPR }` for all others. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/8598#comment:8 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler