
#13221: OccurAnal fails to rediscover join points -------------------------------------+------------------------------------- Reporter: lukemaurer | Owner: lukemaurer Type: bug | Status: patch Priority: high | Milestone: 8.2.1 Component: Compiler | Version: 8.1 Resolution: | Keywords: JoinPoints Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): D3080 Wiki Page: | -------------------------------------+------------------------------------- Changes (by lukemaurer): * status: new => patch * differential: => D3080 Comment: Found two causes: * In several files, the problem was a mistake with occurrence-analyzing rules: {{{ let $sj = \y ys -> ... {-# RULES "SC:j" forall y ys. j (y:ys) = $sj y ys #-} j = \xs -> ... in ... }}} Here `j` can be a join point of join arity 1. Since its rule matches exactly one argument (same as the join arity), the body of its RHS can contain tail calls (see Note [Rules and join points] in OccurAnal). Thus `$sj` can also be a join point, since its only occurrence is a tail call with two arguments. But by mistake, OccurAnal is counting the binders of the rule, not the arguments on its RHS; since there are two binders and `j`'s join arity is 1, `$sj` gets rejected as a potential join point. The warning appears because in the case that `j` is a join point to begin with and SpecConstr specializes it, `$sj` will be created as a join point, so if OccurAnal doesn't think it can be a join point it issues the warning. * In T7796, the problem is that we're zapping too much when looking at stable unfoldings; we should be allowing unfoldings for join points to have tail calls. {{{ let j1 = \x -> ... j2 [Unf=\y -> j1 y] j2 = \y -> j1 y in ... j2 a {- tail call -} ... }}} Here both `j1` and `j2` should be made join points, but to know that we have to see that the call to `j1` from the unfolding of `j2` is a tail call. Again, the warning arises from a join point getting specialized; if `j1` is a specialization of `j2`, failing to discover `j1` as a join point produces the warning. Submitted a patch to Phab. This doesn't fix //all// the instances of the warning, but it fixes the noisy ones that show up in test cases. (The remaining source of noise is beta redexes arising from the simple optimizer; that's an ongoing issue. Fortunately, when that causes a warning, it'll only show up once before the simplifier gets rid of the beta redex.) -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13221#comment:3 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler