Skip to content

CPR analysis too optimistic when returning a component of a product

Sorry the ticket summary is not great, but here is an example.

module PM where

-- Some nonsense so that the simplifier can't see through
-- to the I# constructor
pm :: Int -> Int -> (Int, Int)
pm x y = (l !! 0, l !! 1)
  where l = [x+y, x-y]
{-# NOINLINE pm #-}

m :: Int -> Int -> Int
m x y = case pm x y of
  (pr, mr) -> mr

The generated Core is

pm [InlPrag=NOINLINE] :: Int -> Int -> (Int, Int)
[GblId, Arity=2, Str=DmdType <L,U(U)><L,U(U)>m]   -- ok, pm does construct a pair
pm = [...]

m :: Int -> Int -> Int
[GblId,
 Arity=2,
 Str=DmdType <L,U(U)><L,U(U)>m,                   -- but where did this come from?
 Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True,
         WorkFree=True, Expandable=True,
         Guidance=ALWAYS_IF(arity=2,unsat_ok=True,boring_ok=False)
         Tmpl= \ (x_as5 [Occ=Once] :: Int) (y_as6 [Occ=Once] :: Int) ->
                 case pm x_as5 y_as6
                 of _ [Occ=Dead] { (_ [Occ=Dead], mr_as8 [Occ=Once]) ->
                 mr_as8
                 }}]
m =
  \ (x_as5 :: Int) (y_as6 :: Int) ->
    case pm x_as5 y_as6 of _ [Occ=Dead] { (pr_as7, mr_as8) -> mr_as8 }

I think what's happening is that the body of the function is strict in mr_as8 (it's the entire body) and so mr_as8 is given the CPR property as described in Notes [CPR in a product case alternative] and [Initial CPR for strict binders]. But the reason it is strict is that we are going to need to evaluate it later, not that we have evaluated it already, so the logic in those notes does not apply here.

Reverting 0696fc6d makes m's CPR property go away.

This arises in #10678 (closed) since a function which is an application of, say, runST now has this form (runST (ST st_rep) = case runRW# st_rep of (# _, a #) -> a). It causes wasted unboxing and reboxing of the value returned from runST.

Trac metadata
Trac field Value
Version 7.11
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component Compiler
Test case
Differential revisions
BlockedBy
Related
Blocking #10678 (closed)
CC
Operating system
Architecture
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information