
Maybe it is enough to relax the rule “The return type must not depend on any arguments” to “The return type must be representatoinally equal for all arguments” and that might allow us to e `cast` co to be a tail-call
#14610: newtype wrapping of a monadic stack kills performance -------------------------------------+------------------------------------- Reporter: mrkkrp | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: 8.6.1 Component: Compiler | Version: 8.2.2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: Runtime | Unknown/Multiple performance bug | Test Case: Blocked By: | Blocking: Related Tickets: #14620 | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by simonpj): position Actually I think we may just be able to say that if `(f x)` is a tail call, then `(f x |> co)` is a tail call. So in this code: {{{ occAnal env (Cast expr co) = case occAnal env expr of { (usage, expr') -> let usage1 = zapDetailsIf (isRhsEnv env) usage -- usage1: if we see let x = y `cast` co -- then mark y as 'Many' so that we don't -- immediately inline y again. usage2 = addManyOccsSet usage1 (coVarsOfCo co) -- usage2: see Note [Gather occurrences of coercion variables] in (markAllNonTailCalled usage2, Cast expr' co) } }}} just remove the `markAllNonTailCalled`. That call was in Luke's original join-point patch, but it seems over-conservative to me. That said, I'm intrigued about how this happens in practice, if it really does. In the example given in comment:5, a single run of the simplifer removes the redundant casts, and for recursive join points the tail calls really must return the same type as the function itself, so the cast seems unlikely. While the change above (removing `markAllNonTailCalled`) is ok (I think), I'm surprised if it has any effect. An example would be great. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14610#comment:11 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler