summaryrefslogtreecommitdiff
path: root/testsuite/tests/simplCore/should_compile/T7865.hs
blob: 3ce5be7e66fc83f11941ccb19f9a2b2be144db26 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
module T7865 where

-- Our very expensive operation that we don't want to perform more than once
-- Don't inline it so we can see exactly where it's called in the core
{-# NOINLINE expensive #-}
expensive :: Int -> Int
expensive x = x * 100000

-- SpecConstr this function:
recursive :: [Int] -> (Int,Int) -> (Int,Int)
recursive list acc
 = case list of
   []     -> acc
   (x:xs) ->
     -- Our expensive tuple:
     -- The case is here mainly so that the expensive let isn't floated out before SpecConstr.
     let a'    = case xs of
                 [] -> acc
                 (_:_) -> (let b = expensive x in (b * 2), x)
         -- Use the expensive value once and recurse.
         -- We recurse with (_:_:_) so that a specialisation is made for that pattern,
         -- which simplifies the case xs above. This exposes the expensive let.
         (p,q) = case a' of (p',q') -> recursive (x:x:xs) (q',p')

         -- Use the expensive value again.
         -- Our problem is that this shows up as a separate let-binding for expensive, instead of reusing
         -- the already computed value from above.
     in  (p + fst a', q + snd a')