Duplicated allocation in case-of-known-constructor
Consider this
x = reverse "hello"
y = x `seq` Just True
f p = y `seq` (p, y)
You'd expect that we'd end up iwth
f = \p -> case y of DEFAULT -> (p, y)
or just possibly
f = \p -> case x of DEFAULT -> (p, y)
But we don't. We get
Foo3.f
= \ (@ a_a13D) (p_a13b [Occ=Once] :: a_a13D) ->
case Foo3.x of { __DEFAULT ->
(p_a13b, Just @ Bool True)
}
Yikes. Look at that completely-wasted Just True allocation, which will happen in every call to f.
There's nothing special about the top level here; this could happen for nested bindings too.
The culprit is this code in Simplify:
rebuildCase env scrut case_bndr alts cont
| Just (wfloats, con, ty_args, other_args) <- exprIsConApp_maybe (getUnfoldingInRuleMatch env) scrut
= do { case findAlt (DataAlt con) alts of
Nothing -> missingAlt env case_bndr alts cont
Just (DEFAULT, bs, rhs) -> let con_app = Var (dataConWorkId con)
`mkTyApps` ty_args
`mkApps` other_args
in simple_rhs wfloats con_app bs rhs
Just (_, bs, rhs) -> knownCon env scrut wfloats con ty_args other_args
case_bndr bs rhs cont
}
If we try to simplify
case y of y' { DEFAULT -> (p, y') }
then exprIsConApp_maybe succeeds (with a floated case on x), effectively inlining y bodily,
and we transform to
case x of DEFAULT -> let y' = Just True in blah
Sigh. If making exprIsConApp_maybe to fire requires duplicating an allocation
(here by inlining y), then perhaps we only want this rebuildCase transformation to fire
if the case-binder y' is dead.
What happens in the knownCon case?
f = \p -> case y of y'
Just t -> (y',p)
Nothing -> (p,p)
Here we correctly inline y, cancel the Just and end up with
f = \p -> case x of DEFAUT ->
let y' = y in Just p
Where did that y' = y binding come from? Ah... the clever bind_case_bndr in knownCon. We should do something like this in the default case too.
Trac metadata
| Trac field | Value |
|---|---|
| Version | 8.6.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture |