
#14688: Note [Lone variables] leads to missing a case-of-case opportunity -------------------------------------+------------------------------------- Reporter: mpickering | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.2.2 Keywords: | Operating System: Unknown/Multiple Architecture: | Type of failure: None/Unknown Unknown/Multiple | Test Case: | Blocked By: Blocking: | Related Tickets: Differential Rev(s): | Wiki Page: -------------------------------------+------------------------------------- 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. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14688 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler