Skip to content
  • Sebastian Graf's avatar
    CprAnal: Don't attach CPR sigs to expandable bindings (#18154) · 86d8ac22
    Sebastian Graf authored and Marge Bot's avatar Marge Bot committed
    Instead, look through expandable unfoldings in `cprTransform`.
    See the new Note [CPR for expandable unfoldings]:
    
    ```
    Long static data structures (whether top-level or not) like
    
      xs = x1 : xs1
      xs1 = x2 : xs2
      xs2 = x3 : xs3
    
    should not get CPR signatures, because they
    
      * Never get WW'd, so their CPR signature should be irrelevant after analysis
        (in fact the signature might even be harmful for that reason)
      * Would need to be inlined/expanded to see their constructed product
      * Recording CPR on them blows up interface file sizes and is redundant with
        their unfolding. In case of Nested CPR, this blow-up can be quadratic!
    
    But we can't just stop giving DataCon application bindings the CPR property,
    for example
    
      fac 0 = 1
      fac n = n * fac (n-1)
    
    fac certainly has the CPR property and should be WW'd! But FloatOut will
    transform the first clause to
    
      lvl = 1
      fac 0 = lvl
    
    If lvl doesn't have the CPR property, fac won't either. But lvl doesn't have a
    CPR signature to extrapolate into a CPR transformer ('cprTransform'). So
    instead we keep on cprAnal'ing through *expandable* unfoldings for these arity
    0 bindings via 'cprExpandUnfolding_maybe'.
    
    In practice, GHC generates a lot of (nested) TyCon and KindRep bindings, one
    for each data declaration. It's wasteful to attach CPR signatures to each of
    them (and intractable in case of Nested CPR).
    ```
    
    Fixes #18154.
    86d8ac22