Note [Lone variables] leads to missing a case-of-case opportunity
After the simplifier, my program ends up in the following state.
foo = \f s -> let x = case s of { T1 a b -> a :> b :> Nil }
in fmap (\v -> case x of
{ _v1 :> vs -> T1 v (case vs of {v2 :> _ -> v2}) })
(f (case x of {v1 :> _ -> v1}))
Now if I understand Note [Lone variables] correctly, x is NOT inlined into
the call sites, no matter what I do as x is work-free. However,
this is bad as if we were to inline x we get a case-of-case opportunity.
=> Inline
foo = \f s -> let x = case s of { T1 a b -> a :> b :> Nil }
in fmap (\v -> case (case s of { T1 a b -> a :> b :> Nil }) of
{ _v1 :> vs -> T1 v (case vs of {v2 :> _ -> v2}) })
(f (case x of {v1 :> _ -> v1}))
=> case of case
foo = \f s -> let x = case s of { T1 a b -> a :> b :> Nil }
in fmap (\v -> case s of { T1 a b -> case (a :> b :> Nil) of
{ _v1 :> vs -> T1 v (case vs of {v2 :> _ -> v2}) })
(f (case x of {v1 :> _ -> v1}))
=> case of known constructor
foo = \f s -> let x = case s of { T1 a b -> a :> b :> Nil }
in fmap (\v -> case s of { T1 a b -> T1 v b})
(f (case x of {v1 :> _ -> v1}))
=> Same for the other branch
foo = \f s -> fmap (\v -> case s of { T1 a b -> T1 v b})
(case s of T1 a b -> a)
Which no longer mentions the intermediate representation.
Trac metadata
| Trac field | Value |
|---|---|
| Version | 8.2.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture |