Better combining for identical case alternatives
Sometimes (e.g. here) the user wants to write
f (IfLFCon n) = unitNameSet n
f (IfLFReEntrant _) = emptyNameSet
f (IfLFThunk _ _) = emptyNameSet
f (IfLFUnknown _) = emptyNameSet
f IfLFUnlifted = emptyNameSet
enumerating all the constructors for the sake of explicitness. But we don't want to do all those tests at runtime! We'd prefer to execute
f (IfLFCon n) = unitNameSet n
f _ = emptyNameSet
Some bits of GHC already combine identical alternatives:
- The Simplifier uses
combineIdenticalAlts
- CSE uses
combineAlts
, which tries a bit harder
But neither does the full job:
- CSE doesn't use occurrence analysis to look for dead binders, so it only looks for nullary constructors
- The Simplifier uses only
cheapEqExpr
, and only combines the first alternative.
What we want is to
- Look at alternatives whose binders are all dead
- Among them pick the most popular RHS
- Combine them
Not really hard. Probably appropriate to do this in CSE.
Then we could guarantee that we wouldn't make redundant runtime tests.
See also #14684 for an earlier version of the same issue.