Better occurrence analysis for join points
Consider this
let x = ... in
join j y = x+y in
case v of
A -> x
B -> j 1
C -> j 2
D -> 3
What does OccAnal say about x's usage? It says ManyOccs!
But it's plain as a pikestaff that x is used at most once:
- Either in the
Abranch, - or in the
BorCbranches viaj.
If instead we had inlined j we'd have
let x = ... in
join j y = x+y in
case v of
A -> x
B -> x + 1
C -> x + 2
D -> 3
and now it's all more obvious: x's occurrence info should be OneOcc { occ_one_br = False }, not ManyOccs.
Does this matter? Not a great deal, but there is a reason for having OneOcc with occ_one_br = False, and it seems a shame not to take advantage.
One case in point is the definition of `SimplUtils.isExitJoinId
isExitJoinId :: Var -> Bool
isExitJoinId id = isJoinId id && isOneOcc (idOccInfo id) && occ_in_lam (idOccInfo id)
Something does not cease to be an exit-join-point if it is mentioned in multiple places as above.
Another use for this info is postInlineUnconditionally.
Could we improve this situation? I think it'd be quite easy. For non-recursive join points j = rhs
- Gather occurrence info from the RHS
- Bind
jto its occurrence info - Unleash that occurrence info at each jump-site for
j\, just as if it had been inlined.
See Trac #14152 (closed), #15091.
Trac metadata
| Trac field | Value |
|---|---|
| Version | 8.2.2 |
| Type | Task |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture |