Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC

Commits:

20 changed files:

Changes:

  • compiler/GHC/Builtin/PrimOps.hs
    ... ... @@ -807,16 +807,23 @@ the former has an additional type binder. Hmmm....
    807 807
     
    
    808 808
     Note [Eta expanding primops]
    
    809 809
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    810
    -
    
    811 810
     STG requires that primop applications be saturated. This makes code generation
    
    812 811
     significantly simpler since otherwise we would need to define a calling
    
    813 812
     convention for curried applications that can accommodate representation
    
    814 813
     polymorphism.
    
    815 814
     
    
    816
    -To ensure saturation, CorePrep eta expands all primop applications as
    
    817
    -described in Note [Eta expansion of hasNoBinding things in CorePrep] in
    
    815
    +To ensure saturation, CorePrep eta expands all primop applications
    
    816
    +as described in Note [Eta expansion of unsaturated calls] in
    
    818 817
     GHC.Core.Prep.
    
    819 818
     
    
    819
    +Side note: this decision is somewhat in flux: see comments with `hasNoBinding`.
    
    820
    +The question is: do we generate a trivial wrapper for each primop
    
    821
    +   (+#) x y = (+#) x y
    
    822
    +and now we can call that wrapper unsaturated.  But in practice we
    
    823
    +might never call it because in practice Prep eta-expands all partial
    
    824
    +applications!
    
    825
    +
    
    826
    +
    
    820 827
     Historical Note:
    
    821 828
     
    
    822 829
     For a short period around GHC 8.8 we rewrote unsaturated primop applications to
    

  • compiler/GHC/Core/Opt/Arity.hs
    ... ... @@ -2551,9 +2551,6 @@ This reduces clutter, sometimes a lot. See Note [Do not eta-expand PAPs]
    2551 2551
     in GHC.Core.Opt.Simplify.Utils, where we are careful not to eta-expand
    
    2552 2552
     a PAP.  If eta-expanding is bad, then eta-reducing is good!
    
    2553 2553
     
    
    2554
    -Also the code generator likes eta-reduced PAPs; see GHC.CoreToStg.Prep
    
    2555
    -Note [No eta reduction needed in rhsToBody].
    
    2556
    -
    
    2557 2554
     But note that we don't want to eta-reduce
    
    2558 2555
          \x y.  f <expensive> x y
    
    2559 2556
     to
    

  • compiler/GHC/Core/Opt/Specialise.hs
    ... ... @@ -3247,9 +3247,14 @@ case we can clearly specialise. But there are wrinkles:
    3247 3247
     
    
    3248 3248
     (ID6) The Main Plan says that it's worth specialising if the argument is an application
    
    3249 3249
        of a dictionary contructor.  But what if the dictionary has no methods?  Then we
    
    3250
    -   gain nothing by specialising, unless the /superclasses/ are interesting.   A case
    
    3251
    -   in point is constraint tuples (% d1, .., dn %); a constraint N-tuple is a class
    
    3252
    -   with N superclasses and no methods.
    
    3250
    +   gain nothing by specialising, unless the /superclasses/ are interesting.
    
    3251
    +
    
    3252
    +   So if there are no methods, we recursively call `interestingDict` on the
    
    3253
    +   superclasses.  Why recurse? If we have
    
    3254
    +         \d1 d2.  f (CTuple d1 d2)
    
    3255
    +   If `d1 and `d2` are uninteresting dictionaries, then so is (CTuple d1 d2).
    
    3256
    +   (Remember: a constraint tuple is just a class with N superclasses and no methods.)
    
    3257
    +   See discussion on #26831.
    
    3253 3258
     
    
    3254 3259
     (ID7) A unary (single-method) class is currently represented by (meth |> co).  We
    
    3255 3260
        will unwrap the cast (see (ID5)) and then want to reply "yes" if the method
    

  • compiler/GHC/Core/Tidy.hs
    ... ... @@ -165,6 +165,7 @@ computeCbvInfo fun_id rhs
    165 165
                     map mkMark val_args
    
    166 166
     
    
    167 167
         cbv_bndr | any isMarkedCbv cbv_marks
    
    168
    +               -- isMarkedCbv: see (CBV2) in Note [CBV Function Ids: overview]
    
    168 169
                  = cbv_marks `seqList` setIdCbvMarks fun_id cbv_marks
    
    169 170
                    -- seqList: avoid retaining the original rhs
    
    170 171
     
    
    ... ... @@ -176,6 +177,7 @@ computeCbvInfo fun_id rhs
    176 177
         -- We don't set CBV marks on functions which take unboxed tuples or sums as
    
    177 178
         -- arguments.  Doing so would require us to compute the result of unarise
    
    178 179
         -- here in order to properly determine argument positions at runtime.
    
    180
    +    -- See (CBV1) in Note [CBV Function Ids: overview]
    
    179 181
         --
    
    180 182
         -- In practice this doesn't matter much. Most "interesting" functions will
    
    181 183
         -- get a W/W split which will eliminate unboxed tuple arguments, and unboxed
    

  • compiler/GHC/Core/Unfold.hs
    ... ... @@ -779,22 +779,28 @@ litSize _other = 0 -- Must match size of nullary constructors
    779 779
     
    
    780 780
     classOpSize :: UnfoldingOpts -> Class -> [Id] -> [CoreExpr] -> ExprSize
    
    781 781
     -- See (IA1) in Note [Interesting arguments] in GHC.Core.Opt.Simplify.Utils
    
    782
    -classOpSize opts cls top_args args
    
    783
    -  | isUnaryClass cls
    
    784
    -  = sizeZero   -- See (UCM4) in Note [Unary class magic] in GHC.Core.TyCon
    
    785
    -  | otherwise
    
    786
    -  = case args of
    
    787
    -       []                -> sizeZero
    
    788
    -       (arg1:other_args) -> SizeIs (size other_args) (arg_discount arg1) 0
    
    782
    +classOpSize _opts _cls _top_args []
    
    783
    +  = sizeZero   -- A non-applied classop
    
    784
    +classOpSize opts cls top_args (dict_arg:other_val_args)
    
    785
    +  = SizeIs size (arg_discount dict_arg) 0
    
    789 786
       where
    
    790
    -    size other_args = 20 + (10 * length other_args)
    
    787
    +    size | isUnaryClass cls = 0    -- See (UCM4) in Note [Unary class magic] in GHC.Core.TyCon
    
    788
    +         | otherwise        = 20 + (10 * length other_val_args)
    
    791 789
     
    
    792 790
         -- If the class op is scrutinising a lambda bound dictionary then
    
    793 791
         -- give it a discount, to encourage the inlining of this function
    
    794
    -    -- The actual discount is rather arbitrarily chosen
    
    795
    -    arg_discount (Var dict) | dict `elem` top_args
    
    796
    -                   = unitBag (dict, unfoldingDictDiscount opts)
    
    797
    -    arg_discount _ = emptyBag
    
    792
    +    arg_discount (Cast arg _co)                    = arg_discount arg
    
    793
    +    arg_discount (Var dict) | dict `elem` top_args = unitBag (dict, dict_discount)
    
    794
    +    arg_discount _                                 = emptyBag
    
    795
    +
    
    796
    +    -- If we have (class-op d arg1 .. argn) then it's super-good to inline
    
    797
    +    -- to expose `d`; not only can we do the dictionary selection
    
    798
    +    -- (class-op d), but that will likely expose a lambda which we can then
    
    799
    +    -- apply.  In that case (n > 0), we add `unfoldingFunAppDiscount`.
    
    800
    +    -- See the discussion on #26831, esp "Delicate inlining".
    
    801
    +    dict_discount
    
    802
    +      | null other_val_args = unfoldingDictDiscount opts
    
    803
    +      | otherwise           = unfoldingDictDiscount opts + unfoldingFunAppDiscount opts
    
    798 804
     
    
    799 805
     -- | The size of a function call
    
    800 806
     callSize
    

  • compiler/GHC/CoreToStg.hs
    ... ... @@ -39,6 +39,8 @@ import GHC.Types.Basic ( Arity, TypeOrConstraint(..) )
    39 39
     import GHC.Types.Literal
    
    40 40
     import GHC.Types.ForeignCall
    
    41 41
     import GHC.Types.IPE
    
    42
    +import GHC.Types.Unique.Supply
    
    43
    +import GHC.Types.Unique
    
    42 44
     
    
    43 45
     import GHC.Unit.Module
    
    44 46
     import GHC.Platform        ( Platform )
    
    ... ... @@ -49,297 +51,309 @@ import GHC.Utils.Outputable
    49 51
     import GHC.Utils.Monad
    
    50 52
     import GHC.Utils.Misc (HasDebugCallStack)
    
    51 53
     import GHC.Utils.Panic
    
    54
    +import GHC.Data.FastString
    
    52 55
     
    
    53 56
     import Control.Monad (ap)
    
    54 57
     
    
    55
    --- Note [Live vs free]
    
    56
    --- ~~~~~~~~~~~~~~~~~~~
    
    57
    ---
    
    58
    --- The two are not the same. Liveness is an operational property rather
    
    59
    --- than a semantic one. A variable is live at a particular execution
    
    60
    --- point if it can be referred to directly again. In particular, a dead
    
    61
    --- variable's stack slot (if it has one):
    
    62
    ---
    
    63
    ---           - should be stubbed to avoid space leaks, and
    
    64
    ---           - may be reused for something else.
    
    65
    ---
    
    66
    --- There ought to be a better way to say this. Here are some examples:
    
    67
    ---
    
    68
    ---         let v = [q] \[x] -> e
    
    69
    ---         in
    
    70
    ---         ...v...  (but no q's)
    
    71
    ---
    
    72
    --- Just after the `in', v is live, but q is dead. If the whole of that
    
    73
    --- let expression was enclosed in a case expression, thus:
    
    74
    ---
    
    75
    ---         case (let v = [q] \[x] -> e in ...v...) of
    
    76
    ---                 alts[...q...]
    
    77
    ---
    
    78
    --- (ie `alts' mention `q'), then `q' is live even after the `in'; because
    
    79
    --- we'll return later to the `alts' and need it.
    
    80
    ---
    
    81
    --- Let-no-escapes make this a bit more interesting:
    
    82
    ---
    
    83
    ---         let-no-escape v = [q] \ [x] -> e
    
    84
    ---         in
    
    85
    ---         ...v...
    
    86
    ---
    
    87
    --- Here, `q' is still live at the `in', because `v' is represented not by
    
    88
    --- a closure but by the current stack state.  In other words, if `v' is
    
    89
    --- live then so is `q'. Furthermore, if `e' mentions an enclosing
    
    90
    --- let-no-escaped variable, then its free variables are also live if `v' is.
    
    58
    +{- Note [Live vs free]
    
    59
    +~~~~~~~~~~~~~~~~~~~~~~
    
    60
    +The two are not the same. Liveness is an operational property rather
    
    61
    +than a semantic one. A variable is live at a particular execution
    
    62
    +point if it can be referred to directly again. In particular, a dead
    
    63
    +variable's stack slot (if it has one):
    
    91 64
     
    
    92
    --- Note [What are these SRTs all about?]
    
    93
    --- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    94
    ---
    
    95
    --- Consider the Core program,
    
    96
    ---
    
    97
    ---     fibs = go 1 1
    
    98
    ---       where go a b = let c = a + c
    
    99
    ---                      in c : go b c
    
    100
    ---     add x = map (\y -> x*y) fibs
    
    101
    ---
    
    102
    --- In this case we have a CAF, 'fibs', which is quite large after evaluation and
    
    103
    --- has only one possible user, 'add'. Consequently, we want to ensure that when
    
    104
    --- all references to 'add' die we can garbage collect any bit of 'fibs' that we
    
    105
    --- have evaluated.
    
    106
    ---
    
    107
    --- However, how do we know whether there are any references to 'fibs' still
    
    108
    --- around? Afterall, the only reference to it is buried in the code generated
    
    109
    --- for 'add'. The answer is that we record the CAFs referred to by a definition
    
    110
    --- in its info table, namely a part of it known as the Static Reference Table
    
    111
    --- (SRT).
    
    112
    ---
    
    113
    --- Since SRTs are so common, we use a special compact encoding for them in: we
    
    114
    --- produce one table containing a list of CAFs in a module and then include a
    
    115
    --- bitmap in each info table describing which entries of this table the closure
    
    116
    --- references.
    
    117
    ---
    
    118
    --- See also: commentary/rts/storage/gc/CAFs on the GHC Wiki.
    
    65
    +          - should be stubbed to avoid space leaks, and
    
    66
    +          - may be reused for something else.
    
    119 67
     
    
    120
    --- Note [What is a non-escaping let]
    
    121
    --- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    122
    ---
    
    123
    --- NB: Nowadays this is recognized by the occurrence analyser by turning a
    
    124
    --- "non-escaping let" into a join point. The following is then an operational
    
    125
    --- account of join points.
    
    126
    ---
    
    127
    --- Consider:
    
    128
    ---
    
    129
    ---     let x = fvs \ args -> e
    
    130
    ---     in
    
    131
    ---         if ... then x else
    
    132
    ---            if ... then x else ...
    
    133
    ---
    
    134
    --- `x' is used twice (so we probably can't unfold it), but when it is
    
    135
    --- entered, the stack is deeper than it was when the definition of `x'
    
    136
    --- happened.  Specifically, if instead of allocating a closure for `x',
    
    137
    --- we saved all `x's fvs on the stack, and remembered the stack depth at
    
    138
    --- that moment, then whenever we enter `x' we can simply set the stack
    
    139
    --- pointer(s) to these remembered (compile-time-fixed) values, and jump
    
    140
    --- to the code for `x'.
    
    141
    ---
    
    142
    --- All of this is provided x is:
    
    143
    ---   1. non-updatable;
    
    144
    ---   2. guaranteed to be entered before the stack retreats -- ie x is not
    
    145
    ---      buried in a heap-allocated closure, or passed as an argument to
    
    146
    ---      something;
    
    147
    ---   3. all the enters have exactly the right number of arguments,
    
    148
    ---      no more no less;
    
    149
    ---   4. all the enters are tail calls; that is, they return to the
    
    150
    ---      caller enclosing the definition of `x'.
    
    151
    ---
    
    152
    --- Under these circumstances we say that `x' is non-escaping.
    
    153
    ---
    
    154
    --- An example of when (4) does not hold:
    
    155
    ---
    
    156
    ---     let x = ...
    
    157
    ---     in case x of ...alts...
    
    158
    ---
    
    159
    --- Here, `x' is certainly entered only when the stack is deeper than when
    
    160
    --- `x' is defined, but here it must return to ...alts... So we can't just
    
    161
    --- adjust the stack down to `x''s recalled points, because that would lost
    
    162
    --- alts' context.
    
    163
    ---
    
    164
    --- Things can get a little more complicated.  Consider:
    
    165
    ---
    
    166
    ---     let y = ...
    
    167
    ---     in let x = fvs \ args -> ...y...
    
    168
    ---     in ...x...
    
    169
    ---
    
    170
    --- Now, if `x' is used in a non-escaping way in ...x..., and `y' is used in a
    
    171
    --- non-escaping way in ...y..., then `y' is non-escaping.
    
    172
    ---
    
    173
    --- `x' can even be recursive!  Eg:
    
    174
    ---
    
    175
    ---     letrec x = [y] \ [v] -> if v then x True else ...
    
    176
    ---     in
    
    177
    ---         ...(x b)...
    
    68
    +There ought to be a better way to say this. Here are some examples:
    
    178 69
     
    
    179
    --- Note [Cost-centre initialization plan]
    
    180
    --- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    181
    ---
    
    182
    --- Previously `coreToStg` was initializing cost-centre stack fields as `noCCS`,
    
    183
    --- and the fields were then fixed by a separate pass `stgMassageForProfiling`.
    
    184
    --- We now initialize these correctly. The initialization works like this:
    
    185
    ---
    
    186
    ---   - For non-top level bindings always use `currentCCS`.
    
    187
    ---
    
    188
    ---   - For top-level bindings, check if the binding is a CAF
    
    189
    ---
    
    190
    ---     - CAF:      If -fcaf-all is enabled, create a new CAF just for this CAF
    
    191
    ---                 and use it. Note that these new cost centres need to be
    
    192
    ---                 collected to be able to generate cost centre initialization
    
    193
    ---                 code, so `coreToTopStgRhs` now returns `CollectedCCs`.
    
    194
    ---
    
    195
    ---                 If -fcaf-all is not enabled, use "all CAFs" cost centre.
    
    196
    ---
    
    197
    ---     - Non-CAF:  Top-level (static) data is not counted in heap profiles; nor
    
    198
    ---                 do we set CCCS from it; so we just slam in
    
    199
    ---                 dontCareCostCentre.
    
    200
    -
    
    201
    --- Note [Coercion tokens]
    
    202
    --- ~~~~~~~~~~~~~~~~~~~~~~
    
    203
    --- In coreToStgArgs, we drop type arguments completely, but we replace
    
    204
    --- coercions with a special coercionToken# placeholder. Why? Consider:
    
    205
    ---
    
    206
    ---   f :: forall a. Int ~# Bool -> a
    
    207
    ---   f = /\a. \(co :: Int ~# Bool) -> error "impossible"
    
    208
    ---
    
    209
    --- If we erased the coercion argument completely, we’d end up with just
    
    210
    --- f = error "impossible", but then f `seq` () would be ⊥!
    
    211
    ---
    
    212
    --- This is an artificial example, but back in the day we *did* treat
    
    213
    --- coercion lambdas like type lambdas, and we had bug reports as a
    
    214
    --- result. So now we treat coercion lambdas like value lambdas, but we
    
    215
    --- treat coercions themselves as zero-width arguments — coercionToken#
    
    216
    --- has representation VoidRep — which gets the best of both worlds.
    
    217
    ---
    
    218
    --- (For the gory details, see also the (unpublished) paper, “Practical
    
    219
    --- aspects of evidence-based compilation in System FC.”)
    
    70
    +        let v = [q] \[x] -> e
    
    71
    +        in
    
    72
    +        ...v...  (but no q's)
    
    220 73
     
    
    221
    --- Note [Saturation of data constructors in STG]
    
    222
    --- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    223
    --- We guarantee that `StgConApp` is an exactly-saturated application of a data
    
    224
    --- constructor worker.
    
    225
    ---
    
    226
    --- * If the data constructor is /under/-saturated we just fall through to build
    
    227
    ---   a `StgApp`.  Remember, data constructor workers have a regular top-level definition
    
    228
    ---   (injected by GHC.CoreToStg.Prep.mkDataConWorkers) so we can partially apply
    
    229
    ---   that function.
    
    230
    ---
    
    231
    --- * If the data constructor is /over/-saturated, which can happen (see #23865) we again
    
    232
    ---   fall through to `StgApp`.  That will fail horribly at runtime (by applying data
    
    233
    ---   constructor to an argument) but it should be in dead code, and at least the compiler
    
    234
    ---   itself won't crash.  (We could inject an error-thunk instead.)
    
    74
    +Just after the `in', v is live, but q is dead. If the whole of that
    
    75
    +let expression was enclosed in a case expression, thus:
    
    76
    +
    
    77
    +        case (let v = [q] \[x] -> e in ...v...) of
    
    78
    +                alts[...q...]
    
    79
    +
    
    80
    +(ie `alts' mention `q'), then `q' is live even after the `in'; because
    
    81
    +we'll return later to the `alts' and need it.
    
    82
    +
    
    83
    +Let-no-escapes make this a bit more interesting:
    
    84
    +
    
    85
    +        let-no-escape v = [q] \ [x] -> e
    
    86
    +        in
    
    87
    +        ...v...
    
    88
    +
    
    89
    +Here, `q' is still live at the `in', because `v' is represented not by
    
    90
    +a closure but by the current stack state.  In other words, if `v' is
    
    91
    +live then so is `q'. Furthermore, if `e' mentions an enclosing
    
    92
    +let-no-escaped variable, then its free variables are also live if `v' is.
    
    93
    +
    
    94
    +Note [What are these SRTs all about?]
    
    95
    +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    96
    +
    
    97
    +Consider the Core program,
    
    98
    +
    
    99
    +    fibs = go 1 1
    
    100
    +      where go a b = let c = a + c
    
    101
    +                     in c : go b c
    
    102
    +    add x = map (\y -> x*y) fibs
    
    103
    +
    
    104
    +In this case we have a CAF, 'fibs', which is quite large after evaluation and
    
    105
    +has only one possible user, 'add'. Consequently, we want to ensure that when
    
    106
    +all references to 'add' die we can garbage collect any bit of 'fibs' that we
    
    107
    +have evaluated.
    
    108
    +
    
    109
    +However, how do we know whether there are any references to 'fibs' still
    
    110
    +around? Afterall, the only reference to it is buried in the code generated
    
    111
    +for 'add'. The answer is that we record the CAFs referred to by a definition
    
    112
    +in its info table, namely a part of it known as the Static Reference Table
    
    113
    +(SRT).
    
    235 114
     
    
    115
    +Since SRTs are so common, we use a special compact encoding for them in: we
    
    116
    +produce one table containing a list of CAFs in a module and then include a
    
    117
    +bitmap in each info table describing which entries of this table the closure
    
    118
    +references.
    
    119
    +
    
    120
    +See also: commentary/rts/storage/gc/CAFs on the GHC Wiki.
    
    121
    +
    
    122
    +Note [What is a non-escaping let]
    
    123
    +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    124
    +
    
    125
    +NB: Nowadays this is recognized by the occurrence analyser by turning a
    
    126
    +"non-escaping let" into a join point. The following is then an operational
    
    127
    +account of join points.
    
    128
    +
    
    129
    +Consider:
    
    130
    +
    
    131
    +    let x = fvs \ args -> e
    
    132
    +    in
    
    133
    +        if ... then x else
    
    134
    +           if ... then x else ...
    
    135
    +
    
    136
    +`x' is used twice (so we probably can't unfold it), but when it is
    
    137
    +entered, the stack is deeper than it was when the definition of `x'
    
    138
    +happened.  Specifically, if instead of allocating a closure for `x',
    
    139
    +we saved all `x's fvs on the stack, and remembered the stack depth at
    
    140
    +that moment, then whenever we enter `x' we can simply set the stack
    
    141
    +pointer(s) to these remembered (compile-time-fixed) values, and jump
    
    142
    +to the code for `x'.
    
    143
    +
    
    144
    +All of this is provided x is:
    
    145
    +  1. non-updatable;
    
    146
    +  2. guaranteed to be entered before the stack retreats -- ie x is not
    
    147
    +     buried in a heap-allocated closure, or passed as an argument to
    
    148
    +     something;
    
    149
    +  3. all the enters have exactly the right number of arguments,
    
    150
    +     no more no less;
    
    151
    +  4. all the enters are tail calls; that is, they return to the
    
    152
    +     caller enclosing the definition of `x'.
    
    153
    +
    
    154
    +Under these circumstances we say that `x' is non-escaping.
    
    155
    +
    
    156
    +An example of when (4) does not hold:
    
    157
    +
    
    158
    +    let x = ...
    
    159
    +    in case x of ...alts...
    
    160
    +
    
    161
    +Here, `x' is certainly entered only when the stack is deeper than when
    
    162
    +`x' is defined, but here it must return to ...alts... So we can't just
    
    163
    +adjust the stack down to `x''s recalled points, because that would lost
    
    164
    +alts' context.
    
    165
    +
    
    166
    +Things can get a little more complicated.  Consider:
    
    167
    +
    
    168
    +    let y = ...
    
    169
    +    in let x = fvs \ args -> ...y...
    
    170
    +    in ...x...
    
    171
    +
    
    172
    +Now, if `x' is used in a non-escaping way in ...x..., and `y' is used in a
    
    173
    +non-escaping way in ...y..., then `y' is non-escaping.
    
    174
    +
    
    175
    +`x' can even be recursive!  Eg:
    
    176
    +
    
    177
    +    letrec x = [y] \ [v] -> if v then x True else ...
    
    178
    +    in
    
    179
    +        ...(x b)...
    
    180
    +
    
    181
    +Note [Cost-centre initialization plan]
    
    182
    +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    183
    +
    
    184
    +Previously `coreToStg` was initializing cost-centre stack fields as `noCCS`,
    
    185
    +and the fields were then fixed by a separate pass `stgMassageForProfiling`.
    
    186
    +We now initialize these correctly. The initialization works like this:
    
    187
    +
    
    188
    +  - For non-top level bindings always use `currentCCS`.
    
    189
    +
    
    190
    +  - For top-level bindings, check if the binding is a CAF
    
    191
    +
    
    192
    +    - CAF:      If -fcaf-all is enabled, create a new CAF just for this CAF
    
    193
    +                and use it. Note that these new cost centres need to be
    
    194
    +                collected to be able to generate cost centre initialization
    
    195
    +                code, so `coreToTopStgRhs` now returns `CollectedCCs`.
    
    196
    +
    
    197
    +                If -fcaf-all is not enabled, use "all CAFs" cost centre.
    
    198
    +
    
    199
    +    - Non-CAF:  Top-level (static) data is not counted in heap profiles; nor
    
    200
    +                do we set CCCS from it; so we just slam in
    
    201
    +                dontCareCostCentre.
    
    202
    +
    
    203
    +Note [Coercion tokens]
    
    204
    +~~~~~~~~~~~~~~~~~~~~~~
    
    205
    +In coreToStgArgs, we drop type arguments completely, but we replace
    
    206
    +coercions with a special coercionToken# placeholder. Why? Consider:
    
    207
    +
    
    208
    +  f :: forall a. Int ~# Bool -> a
    
    209
    +  f = /\a. \(co :: Int ~# Bool) -> error "impossible"
    
    210
    +
    
    211
    +If we erased the coercion argument completely, we’d end up with just
    
    212
    +f = error "impossible", but then f `seq` () would be ⊥!
    
    213
    +
    
    214
    +This is an artificial example, but back in the day we *did* treat
    
    215
    +coercion lambdas like type lambdas, and we had bug reports as a
    
    216
    +result. So now we treat coercion lambdas like value lambdas, but we
    
    217
    +treat coercions themselves as zero-width arguments — coercionToken#
    
    218
    +has representation VoidRep — which gets the best of both worlds.
    
    219
    +
    
    220
    +(For the gory details, see also the (unpublished) paper, “Practical
    
    221
    +aspects of evidence-based compilation in System FC.”)
    
    222
    +
    
    223
    +Note [Saturation of data constructors in STG]
    
    224
    +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    225
    +We guarantee that `StgConApp` is an exactly-saturated application of a data
    
    226
    +constructor worker.
    
    227
    +
    
    228
    +* If the data constructor is /under/-saturated we just fall through to build
    
    229
    +  a `StgApp`.  Remember, data constructor workers have a regular top-level definition
    
    230
    +  (injected by GHC.CoreToStg.Prep.mkDataConWorkers) so we can partially apply
    
    231
    +  that function.
    
    232
    +
    
    233
    +* If the data constructor is /over/-saturated, which can happen (see #23865) we again
    
    234
    +  fall through to `StgApp`.  That will fail horribly at runtime (by applying data
    
    235
    +  constructor to an argument) but it should be in dead code, and at least the compiler
    
    236
    +  itself won't crash.  (We could inject an error-thunk instead.)
    
    237
    +
    
    238
    +Note [Naked lambdas in coreToStgExpr]
    
    239
    +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    240
    +Consider
    
    241
    +  f x = case x of
    
    242
    +           True  -> \y. y+x
    
    243
    +           False -> blah
    
    244
    +If `f` is not eta expanded (which would have happened in Prep if it was
    
    245
    +going to happen at all, the code for f must allocate a closure for the
    
    246
    +(\y. y+x).  So the STG code we want has
    
    247
    +
    
    248
    +     True -> let pap = \y. y+x
    
    249
    +             in pap
    
    250
    +
    
    251
    +The Lam case of `coreToStgExpr` deals with adding this `StgLet`. It's the
    
    252
    +main reason we need a unique supply in the monad.
    
    253
    +
    
    254
    +Historical note: in the past, Prep guaranteed there would be no such naked
    
    255
    +lambdas, so we didn't need a unique supply at all. But that proved too hard
    
    256
    +in the end (see Note [Eta expansion and the CorePrep invariants]) so we
    
    257
    +just deal with it here; it's very easy.
    
    258
    +-}
    
    236 259
     
    
    237 260
     -- --------------------------------------------------------------
    
    238 261
     -- Setting variable info: top-level, binds, RHSs
    
    239 262
     -- --------------------------------------------------------------
    
    240 263
     
    
    241 264
     
    
    242
    -coreToStg :: CoreToStgOpts -> Module -> ModLocation -> CoreProgram
    
    243
    -          -> ([StgTopBinding], InfoTableProvMap, CollectedCCs)
    
    244
    -coreToStg opts@CoreToStgOpts
    
    245
    -  { coreToStg_ways = ways
    
    246
    -  , coreToStg_AutoSccsOnIndividualCafs = opt_AutoSccsOnIndividualCafs
    
    247
    -  , coreToStg_InfoTableMap = opt_InfoTableMap
    
    248
    -  , coreToStg_stgDebugOpts = stgDebugOpts
    
    249
    -  } this_mod ml pgm
    
    250
    -  = (pgm'', denv, final_ccs)
    
    265
    +coreToStg :: CoreToStgOpts -> Module -> ModLocation
    
    266
    +          -> CoreProgram
    
    267
    +          -> IO ([StgTopBinding], InfoTableProvMap, CollectedCCs)
    
    268
    +coreToStg opts this_mod ml pgm
    
    269
    +  = do { us <- mkSplitUniqSupply StgTag
    
    270
    +       ; let (_, (local_ccs, local_cc_stacks), pgm')
    
    271
    +                = initCts opts us $
    
    272
    +                  coreTopBindsToStg opts this_mod emptyCollectedCCs pgm
    
    273
    +
    
    274
    +             -- See Note [Mapping Info Tables to Source Positions]
    
    275
    +             (!pgm'', !denv)
    
    276
    +               | opt_InfoTableMap
    
    277
    +               = collectDebugInformation stgDebugOpts ml pgm'
    
    278
    +               | otherwise = (pgm', emptyInfoTableProvMap)
    
    279
    +
    
    280
    +             final_ccs
    
    281
    +               | prof && opt_AutoSccsOnIndividualCafs
    
    282
    +               = (local_ccs,local_cc_stacks)  -- don't need "all CAFs" CC
    
    283
    +               | prof
    
    284
    +               = (all_cafs_cc:local_ccs, all_cafs_ccs:local_cc_stacks)
    
    285
    +               | otherwise
    
    286
    +               = emptyCollectedCCs
    
    287
    +
    
    288
    +      ; return (pgm'', denv, final_ccs) }
    
    251 289
       where
    
    252
    -    (_, (local_ccs, local_cc_stacks), pgm')
    
    253
    -      = coreTopBindsToStg opts this_mod emptyVarEnv emptyCollectedCCs pgm
    
    254
    -
    
    255
    -    -- See Note [Mapping Info Tables to Source Positions]
    
    256
    -    (!pgm'', !denv)
    
    257
    -      | opt_InfoTableMap
    
    258
    -      = collectDebugInformation stgDebugOpts ml pgm'
    
    259
    -      | otherwise = (pgm', emptyInfoTableProvMap)
    
    290
    +    CoreToStgOpts { coreToStg_ways = ways
    
    291
    +                  , coreToStg_AutoSccsOnIndividualCafs = opt_AutoSccsOnIndividualCafs
    
    292
    +                  , coreToStg_InfoTableMap = opt_InfoTableMap
    
    293
    +                  , coreToStg_stgDebugOpts = stgDebugOpts }
    
    294
    +       = opts
    
    260 295
     
    
    261 296
         prof = hasWay ways WayProf
    
    262
    -
    
    263
    -    final_ccs
    
    264
    -      | prof && opt_AutoSccsOnIndividualCafs
    
    265
    -      = (local_ccs,local_cc_stacks)  -- don't need "all CAFs" CC
    
    266
    -      | prof
    
    267
    -      = (all_cafs_cc:local_ccs, all_cafs_ccs:local_cc_stacks)
    
    268
    -      | otherwise
    
    269
    -      = emptyCollectedCCs
    
    270
    -
    
    271 297
         (all_cafs_cc, all_cafs_ccs) = getAllCAFsCC this_mod
    
    272 298
     
    
    273 299
     coreTopBindsToStg
    
    274 300
         :: CoreToStgOpts
    
    275 301
         -> Module
    
    276
    -    -> IdEnv HowBound           -- environment for the bindings
    
    277 302
         -> CollectedCCs
    
    278 303
         -> CoreProgram
    
    279
    -    -> (IdEnv HowBound, CollectedCCs, [StgTopBinding])
    
    304
    +    -> CtsM (IdEnv HowBound, CollectedCCs, [StgTopBinding])
    
    305
    +
    
    306
    +coreTopBindsToStg _ _ ccs []
    
    307
    +  = do { env <- getCtsEnv
    
    308
    +       ; return (env, ccs, []) }
    
    280 309
     
    
    281
    -coreTopBindsToStg _      _        env ccs []
    
    282
    -  = (env, ccs, [])
    
    283
    -coreTopBindsToStg opts this_mod env ccs (b:bs)
    
    310
    +coreTopBindsToStg opts this_mod ccs (b:bs)
    
    284 311
       | NonRec _ rhs <- b, isTyCoArg rhs
    
    285
    -  = coreTopBindsToStg opts this_mod env1 ccs1 bs
    
    312
    +  = coreTopBindsToStg opts this_mod ccs bs
    
    286 313
       | otherwise
    
    287
    -  = (env2, ccs2, b':bs')
    
    288
    -  where
    
    289
    -    (env1, ccs1, b' ) = coreTopBindToStg opts this_mod env ccs b
    
    290
    -    (env2, ccs2, bs') = coreTopBindsToStg opts this_mod env1 ccs1 bs
    
    314
    +  = do { (env1, ccs1, b' ) <- coreTopBindToStg opts this_mod ccs b
    
    315
    +       ; (env2, ccs2, bs') <- setCtsEnv env1 $
    
    316
    +                              coreTopBindsToStg opts this_mod ccs1 bs
    
    317
    +      ; return (env2, ccs2, b':bs') }
    
    291 318
     
    
    292 319
     coreTopBindToStg
    
    293 320
             :: CoreToStgOpts
    
    294 321
             -> Module
    
    295
    -        -> IdEnv HowBound
    
    296 322
             -> CollectedCCs
    
    297 323
             -> CoreBind
    
    298
    -        -> (IdEnv HowBound, CollectedCCs, StgTopBinding)
    
    324
    +        -> CtsM (IdEnv HowBound, CollectedCCs, StgTopBinding)
    
    299 325
     
    
    300
    -coreTopBindToStg _ _ env ccs (NonRec id e)
    
    326
    +coreTopBindToStg _ _ ccs (NonRec id e)
    
    301 327
       | Just str <- exprIsTickedString_maybe e
    
    302 328
       -- top-level string literal
    
    303 329
       -- See Note [Core top-level string literals] in GHC.Core
    
    304
    -  = let
    
    305
    -        env' = extendVarEnv env id how_bound
    
    306
    -        how_bound = LetBound TopLet 0
    
    307
    -    in (env', ccs, StgTopStringLit id str)
    
    308
    -
    
    309
    -coreTopBindToStg opts@CoreToStgOpts
    
    310
    -  { coreToStg_platform = platform
    
    311
    -  } this_mod env ccs (NonRec id rhs)
    
    312
    -  = let
    
    313
    -        env'      = extendVarEnv env id how_bound
    
    314
    -        how_bound = LetBound TopLet $! manifestArity rhs
    
    315
    -
    
    316
    -        (ccs', (id', stg_rhs)) =
    
    317
    -            initCts platform env $
    
    318
    -              coreToTopStgRhs opts this_mod ccs (id,rhs)
    
    319
    -
    
    320
    -        bind = StgTopLifted $ StgNonRec id' stg_rhs
    
    321
    -    in
    
    322
    -      -- NB: previously the assertion printed 'rhs' and 'bind'
    
    323
    -      --     as well as 'id', but that led to a black hole
    
    324
    -      --     where printing the assertion error tripped the
    
    325
    -      --     assertion again!
    
    326
    -    (env', ccs', bind)
    
    327
    -
    
    328
    -coreTopBindToStg opts@CoreToStgOpts
    
    329
    -  { coreToStg_platform = platform
    
    330
    -  } this_mod env ccs (Rec pairs)
    
    330
    +  = do { env <- getCtsEnv
    
    331
    +       ; let env' = extendVarEnv env id how_bound
    
    332
    +             how_bound = LetBound TopLet 0
    
    333
    +       ; return (env', ccs, StgTopStringLit id str) }
    
    334
    +
    
    335
    +coreTopBindToStg opts this_mod ccs (NonRec id rhs)
    
    336
    +  = do { (ccs', (id', stg_rhs)) <- coreToTopStgRhs opts this_mod ccs (id,rhs)
    
    337
    +
    
    338
    +       ; env <- getCtsEnv
    
    339
    +       ; let env'      = extendVarEnv env id how_bound
    
    340
    +             how_bound = LetBound TopLet $! manifestArity rhs
    
    341
    +             bind      = StgTopLifted $ StgNonRec id' stg_rhs
    
    342
    +       ; return (env', ccs', bind) }
    
    343
    +
    
    344
    +coreTopBindToStg opts this_mod ccs (Rec pairs)
    
    331 345
       = assert (not (null pairs)) $
    
    332
    -    let
    
    333
    -        extra_env' = [ (b, LetBound TopLet $! manifestArity rhs)
    
    334
    -                     | (b, rhs) <- pairs ]
    
    335
    -        env' = extendVarEnvList env extra_env'
    
    336
    -
    
    337
    -        -- generate StgTopBindings and CAF cost centres created for CAFs
    
    338
    -        (ccs', stg_rhss)
    
    339
    -          = initCts platform env' $ mapAccumLM (coreToTopStgRhs opts this_mod) ccs pairs
    
    340
    -        bind = StgTopLifted $ StgRec stg_rhss
    
    341
    -    in
    
    342
    -    (env', ccs', bind)
    
    346
    +    do { env <- getCtsEnv
    
    347
    +       ; let extra_env' = [ (b, LetBound TopLet $! manifestArity rhs)
    
    348
    +                          | (b, rhs) <- pairs ]
    
    349
    +             env' = extendVarEnvList env extra_env'
    
    350
    +
    
    351
    +       -- Generate StgTopBindings and CAF cost centres created for CAFs
    
    352
    +       ; (ccs', stg_rhss) <- setCtsEnv env' $
    
    353
    +                             mapAccumLM (coreToTopStgRhs opts this_mod) ccs pairs
    
    354
    +       ; let bind = StgTopLifted $ StgRec stg_rhss
    
    355
    +
    
    356
    +       ; return (env', ccs', bind) }
    
    343 357
     
    
    344 358
     coreToTopStgRhs
    
    345 359
             :: CoreToStgOpts
    
    ... ... @@ -420,16 +434,24 @@ coreToStgExpr expr@(App _ _)
    420 434
           res_ty                  = exprType expr
    
    421 435
           (app_head, args, ticks) = myCollectArgs expr res_ty
    
    422 436
     
    
    423
    -coreToStgExpr expr@(Lam _ _)
    
    424
    -  = let
    
    425
    -        (args, body) = myCollectBinders expr
    
    426
    -    in
    
    427
    -    case filterStgBinders args of
    
    428
    -
    
    429
    -      [] -> coreToStgExpr body
    
    430
    -
    
    431
    -      _ -> pprPanic "coretoStgExpr" $
    
    432
    -        text "Unexpected value lambda:" $$ ppr expr
    
    437
    +coreToStgExpr expr@(Lam {})
    
    438
    +  | null val_bndrs
    
    439
    +  = coreToStgExpr body
    
    440
    +  | otherwise
    
    441
    +  = -- See Note [Naked lambdas in coreToStgExpr]
    
    442
    +    do { body' <- extendVarEnvCts [ (a, LambdaBound) | a <- val_bndrs ] $
    
    443
    +                  coreToStgExpr body
    
    444
    +       ; uniq <- getCtsUnique
    
    445
    +       ; let body_ty = exprType body
    
    446
    +             fun_ty  = mkLamTypes val_bndrs body_ty
    
    447
    +                       -- This type is a bit ill-formed but it doesn't matter
    
    448
    +             rhs = StgRhsClosure noExtFieldSilent currentCCS
    
    449
    +                                 ReEntrant val_bndrs body' body_ty
    
    450
    +             tmp_fun = mkSysLocal (fsLit "pap") uniq ManyTy fun_ty
    
    451
    +       ; return (StgLet noExtFieldSilent (StgNonRec tmp_fun rhs) $
    
    452
    +                 StgApp tmp_fun []) }
    
    453
    +  where
    
    454
    +    (val_bndrs, body) = myCollectBinders NotJoinPoint expr
    
    433 455
     
    
    434 456
     coreToStgExpr (Tick tick expr)
    
    435 457
       = do
    
    ... ... @@ -634,8 +656,13 @@ coreToStgArgs (arg : args) = do -- Non-type argument
    634 656
             stg_arg_rep = stgArgRep arg'
    
    635 657
             bad_args = not (primRepsCompatible platform arg_rep stg_arg_rep)
    
    636 658
     
    
    637
    -    massertPpr (length ticks' <= 1) (text "More than one Tick in trivial arg:" <+> ppr arg)
    
    638
    -    warnPprTraceM bad_args "Dangerous-looking argument. Probable cause: bad unsafeCoerce#" (ppr arg)
    
    659
    +    -- Yikes!  This assert FAILS in tests T13658, T14779b
    
    660
    +    -- It has been so for ages, but without the "() <-" it was lazily dropped
    
    661
    +    -- Hence commenting it out: see #27132
    
    662
    +    --    massertPpr (length ticks' <= 1) (text "More than one Tick in trivial arg:" <+> ppr arg)
    
    663
    +
    
    664
    +    () <- warnPprTraceM bad_args
    
    665
    +            "Dangerous-looking argument. Probable cause: bad unsafeCoerce#" (ppr arg)
    
    639 666
     
    
    640 667
         return (arg' : stg_args, ticks' ++ ticks)
    
    641 668
     
    
    ... ... @@ -710,12 +737,11 @@ coreToStgRhs (bndr, rhs) = do
    710 737
     -- coreToStgExpr that can handle value lambdas.
    
    711 738
     coreToMkStgRhs :: HasDebugCallStack => Id -> CoreExpr -> CtsM MkStgRhs
    
    712 739
     coreToMkStgRhs bndr expr = do
    
    713
    -  let (args, body) = myCollectBinders expr
    
    714
    -  let args'        = filterStgBinders args
    
    715
    -  extendVarEnvCts [ (a, LambdaBound) | a <- args' ] $ do
    
    740
    +  let (bndrs, body) = myCollectBinders (idJoinPointHood bndr) expr
    
    741
    +  extendVarEnvCts [ (a, LambdaBound) | a <- bndrs ] $ do
    
    716 742
         body' <- coreToStgExpr body
    
    717 743
         let mk_rhs = MkStgRhs
    
    718
    -          { rhs_args = args'
    
    744
    +          { rhs_args = bndrs
    
    719 745
               , rhs_expr = body'
    
    720 746
               , rhs_type = exprType body
    
    721 747
               , rhs_is_join = isJoinId bndr
    
    ... ... @@ -733,7 +759,7 @@ coreToMkStgRhs bndr expr = do
    733 759
     newtype CtsM a = CtsM
    
    734 760
         { unCtsM :: Platform -- Needed for checking for bad coercions in coreToStgArgs
    
    735 761
                  -> IdEnv HowBound
    
    736
    -             -> a
    
    762
    +             -> UniqSM a
    
    737 763
         }
    
    738 764
         deriving (Functor)
    
    739 765
     
    
    ... ... @@ -769,20 +795,22 @@ data LetInfo
    769 795
     
    
    770 796
     -- The std monad functions:
    
    771 797
     
    
    772
    -initCts :: Platform -> IdEnv HowBound -> CtsM a -> a
    
    773
    -initCts platform env m = unCtsM m platform env
    
    774
    -
    
    798
    +initCts :: CoreToStgOpts -> UniqSupply -> CtsM a -> a
    
    799
    +initCts opts us cts_m
    
    800
    +  = initUs_ us $
    
    801
    +    unCtsM cts_m (coreToStg_platform opts) emptyVarEnv
    
    775 802
     
    
    776 803
     
    
    777 804
     {-# INLINE thenCts #-}
    
    778 805
     {-# INLINE returnCts #-}
    
    779 806
     
    
    780 807
     returnCts :: a -> CtsM a
    
    781
    -returnCts e = CtsM $ \_ _ -> e
    
    808
    +returnCts e = CtsM $ \_ _ -> return e
    
    782 809
     
    
    783 810
     thenCts :: CtsM a -> (a -> CtsM b) -> CtsM b
    
    784
    -thenCts m k = CtsM $ \platform env
    
    785
    -  -> unCtsM (k (unCtsM m platform env)) platform env
    
    811
    +thenCts m k = CtsM $ \platform env ->
    
    812
    +              do { v <- unCtsM m platform env
    
    813
    +                 ; unCtsM (k v) platform env }
    
    786 814
     
    
    787 815
     instance Applicative CtsM where
    
    788 816
         pure = returnCts
    
    ... ... @@ -792,17 +820,26 @@ instance Monad CtsM where
    792 820
         (>>=)  = thenCts
    
    793 821
     
    
    794 822
     getPlatform :: CtsM Platform
    
    795
    -getPlatform = CtsM const
    
    823
    +getPlatform = CtsM $ \platform _ -> return platform
    
    796 824
     
    
    797 825
     -- Functions specific to this monad:
    
    798 826
     
    
    827
    +setCtsEnv :: IdEnv HowBound -> CtsM a -> CtsM a
    
    828
    +setCtsEnv env thing = CtsM $ \platform _ -> unCtsM thing platform env
    
    829
    +
    
    830
    +getCtsEnv :: CtsM (IdEnv HowBound)
    
    831
    +getCtsEnv = CtsM $ \_ env -> return env
    
    832
    +
    
    833
    +getCtsUnique :: CtsM Unique
    
    834
    +getCtsUnique = CtsM $ \_ _ -> getUniqueM
    
    835
    +
    
    799 836
     extendVarEnvCts :: [(Id, HowBound)] -> CtsM a -> CtsM a
    
    800 837
     extendVarEnvCts ids_w_howbound expr
    
    801 838
        =    CtsM $   \platform env
    
    802 839
        -> unCtsM expr platform (extendVarEnvList env ids_w_howbound)
    
    803 840
     
    
    804 841
     lookupVarCts :: Id -> CtsM HowBound
    
    805
    -lookupVarCts v = CtsM $ \_ env -> lookupBinding env v
    
    842
    +lookupVarCts v = CtsM $ \_ env -> return (lookupBinding env v)
    
    806 843
     
    
    807 844
     lookupBinding :: IdEnv HowBound -> Id -> HowBound
    
    808 845
     lookupBinding env v = case lookupVarEnv env v of
    
    ... ... @@ -814,13 +851,26 @@ lookupBinding env v = case lookupVarEnv env v of
    814 851
     filterStgBinders :: [Var] -> [Var]
    
    815 852
     filterStgBinders bndrs = filter isId bndrs
    
    816 853
     
    
    817
    -myCollectBinders :: Expr Var -> ([Var], Expr Var)
    
    818
    -myCollectBinders expr
    
    854
    +myCollectBinders :: JoinPointHood -> Expr Var -> ([Var], Expr Var)
    
    855
    +-- Collect the binders from a lambda:
    
    856
    +--   * Dropping type lambdas
    
    857
    +--   * Stopping at join-point arity
    
    858
    +myCollectBinders NotJoinPoint expr
    
    819 859
       = go [] expr
    
    820 860
       where
    
    821
    -    go bs (Lam b e)          = go (b:bs) e
    
    822
    -    go bs (Cast e _)         = go bs e
    
    823
    -    go bs e                  = (reverse bs, e)
    
    861
    +    go bs (Lam b e) | isRuntimeVar b = go (b:bs) e
    
    862
    +                    | otherwise      = go bs     e
    
    863
    +    go bs (Cast e _)                 = go bs e
    
    864
    +    go bs e                          = (reverse bs, e)
    
    865
    +
    
    866
    +myCollectBinders (JoinPoint n) expr
    
    867
    +  = go n [] expr
    
    868
    +  where
    
    869
    +    go n bs e | n==0                   = (reverse bs, e)
    
    870
    +    go n bs (Lam b e) | isRuntimeVar b = go (n-1) (b:bs) e
    
    871
    +                      | otherwise      = go (n-1) bs     e
    
    872
    +    go n bs (Cast e _)                 = go n bs e
    
    873
    +    go _ bs e                          = (reverse bs, e)
    
    824 874
     
    
    825 875
     -- | If the argument expression is (potential chain of) 'App', return the head
    
    826 876
     -- of the app chain, and collect ticks/args along the chain.
    

  • compiler/GHC/CoreToStg/Prep.hs
    ... ... @@ -144,16 +144,13 @@ Here is the syntax of the Core produced by CorePrep:
    144 144
     
    
    145 145
         Expressions
    
    146 146
            body ::= app
    
    147
    -             |  let(rec) x = rhs in body     -- Boxed only
    
    147
    +             |  let(rec) x = body in body     -- Boxed only
    
    148 148
                  |  case body of pat -> body
    
    149
    -             |  /\a. body | /\c. body
    
    149
    +             |  /\a. body | /\c. body | \x. body
    
    150 150
                  |  body |> co
    
    151 151
     
    
    152
    -    Right hand sides (only place where value lambdas can occur)
    
    153
    -       rhs ::= /\a.rhs  |  \x.rhs  |  body
    
    154
    -
    
    155
    -We define a synonym for each of these non-terminals.  Functions
    
    156
    -with the corresponding name produce a result in that syntax.
    
    152
    +We define a synonym for each of these non-terminals, CpeArg, CpeApp, and
    
    153
    +CpeBody.  Functions with the corresponding name produce a result in that syntax.
    
    157 154
     
    
    158 155
     Note [Cloning in CorePrep]
    
    159 156
     ~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    ... ... @@ -218,7 +215,6 @@ So our plan is:
    218 215
     type CpeArg  = CoreExpr    -- Non-terminal 'arg'
    
    219 216
     type CpeApp  = CoreExpr    -- Non-terminal 'app'
    
    220 217
     type CpeBody = CoreExpr    -- Non-terminal 'body'
    
    221
    -type CpeRhs  = CoreExpr    -- Non-terminal 'rhs'
    
    222 218
     
    
    223 219
     {-
    
    224 220
     ************************************************************************
    
    ... ... @@ -261,7 +257,7 @@ corePrepExpr logger config expr = do
    261 257
         withTiming logger (text "CorePrep [expr]") (\e -> e `seq` ()) $ do
    
    262 258
           us <- mkSplitUniqSupply StgTag
    
    263 259
           let initialCorePrepEnv = mkInitialCorePrepEnv config
    
    264
    -      let new_expr = initUs_ us (cpeBodyNF initialCorePrepEnv expr)
    
    260
    +      let new_expr = initUs_ us (cpeBody initialCorePrepEnv expr)
    
    265 261
           putDumpFileMaybe logger Opt_D_dump_prep "CorePrep" FormatCore (ppr new_expr)
    
    266 262
           return new_expr
    
    267 263
     
    
    ... ... @@ -665,16 +661,16 @@ cpeBind top_lvl env (Rec pairs)
    665 661
     ---------------
    
    666 662
     cpePair :: TopLevelFlag -> RecFlag -> Demand -> Levity
    
    667 663
             -> CorePrepEnv -> OutId -> CoreExpr
    
    668
    -        -> UniqSM (Floats, CpeRhs)
    
    664
    +        -> UniqSM (Floats, CpeBody)
    
    669 665
     -- Used for all bindings
    
    670 666
     -- The binder is already cloned, hence an OutId
    
    671 667
     cpePair top_lvl is_rec dmd lev env0 bndr rhs
    
    672 668
       = assert (isNothing $ joinPointBinding_maybe bndr rhs) $ -- those should use cpeJoinPair
    
    673
    -    do { (floats1, rhs1) <- cpeRhsE env rhs
    
    669
    +    do { (floats1, rhs1) <- cpeBodyF env rhs
    
    674 670
     
    
    675 671
            -- See if we are allowed to float this stuff out of the RHS
    
    676 672
            ; let dec = want_float_from_rhs floats1 rhs1
    
    677
    -       ; (floats2, rhs2) <- executeFloatDecision env dec floats1 rhs1
    
    673
    +             (floats2, rhs2) = executeFloatDecision dec floats1 rhs1
    
    678 674
     
    
    679 675
            -- Make the arity match up
    
    680 676
            ; (floats3, rhs3)
    
    ... ... @@ -717,7 +713,7 @@ it seems good for CorePrep to be robust.
    717 713
     
    
    718 714
     ---------------
    
    719 715
     cpeJoinPair :: CorePrepEnv -> JoinId -> CoreExpr
    
    720
    -            -> UniqSM (JoinId, CpeRhs)
    
    716
    +            -> UniqSM (JoinId, CpeBody)
    
    721 717
     -- Used for all join bindings
    
    722 718
     -- No eta-expansion: see Note [Do not eta-expand join points] in GHC.Core.Opt.Simplify.Utils
    
    723 719
     cpeJoinPair env bndr rhs
    
    ... ... @@ -729,7 +725,7 @@ cpeJoinPair env bndr rhs
    729 725
     
    
    730 726
            ; (env', bndrs') <- cpCloneBndrs env bndrs
    
    731 727
     
    
    732
    -       ; body' <- cpeBodyNF env' body -- Will let-bind the body if it starts
    
    728
    +       ; body' <- cpeBody env' body -- Will let-bind the body if it starts
    
    733 729
                                           -- with a lambda
    
    734 730
     
    
    735 731
            ; let rhs'  = mkCoreLams bndrs' body'
    
    ... ... @@ -757,10 +753,20 @@ for us to mess with the arity because a join point is never exported.
    757 753
     -}
    
    758 754
     
    
    759 755
     -- ---------------------------------------------------------------------------
    
    760
    ---              CpeRhs: produces a result satisfying CpeRhs
    
    756
    +--              cpeBodyF: produces a result satisfying CpeBody
    
    761 757
     -- ---------------------------------------------------------------------------
    
    762 758
     
    
    763
    -cpeRhsE :: CorePrepEnv -> CoreExpr -> UniqSM (Floats, CpeRhs)
    
    759
    +cpeBodyF :: CorePrepEnv -> CoreExpr -> UniqSM (Floats, CpeBody)
    
    760
    +-- | Convert a 'CoreExpr' so it satisfies 'CpeBody'; also produce
    
    761
    +-- a list of 'Floats' which are being propagated upwards.  In
    
    762
    +-- fact, this function is used in only two cases: to
    
    763
    +-- implement 'cpeBody' (which is what you usually want),
    
    764
    +-- and in the case when a let-binding is in a case scrutinee--here,
    
    765
    +-- we can always float out:
    
    766
    +--
    
    767
    +--      case (let x = y in z) of ...
    
    768
    +--      ==> let x = y in case z of ...
    
    769
    +--
    
    764 770
     -- If
    
    765 771
     --      e  ===>  (bs, e')
    
    766 772
     -- then
    
    ... ... @@ -769,32 +775,32 @@ cpeRhsE :: CorePrepEnv -> CoreExpr -> UniqSM (Floats, CpeRhs)
    769 775
     -- For example
    
    770 776
     --      f (g x)   ===>   ([v = g x], f v)
    
    771 777
     
    
    772
    -cpeRhsE env (Type ty)
    
    778
    +cpeBodyF env (Type ty)
    
    773 779
       = return (emptyFloats, Type (cpSubstTy env ty))
    
    774
    -cpeRhsE env (Coercion co)
    
    780
    +cpeBodyF env (Coercion co)
    
    775 781
       = return (emptyFloats, Coercion (cpSubstCo env co))
    
    776
    -cpeRhsE env expr@(Lit lit)
    
    782
    +cpeBodyF env expr@(Lit lit)
    
    777 783
       | LitNumber LitNumBigNat i <- lit
    
    778 784
         = cpeBigNatLit env i
    
    779 785
       | otherwise = return (emptyFloats, expr)
    
    780
    -cpeRhsE env expr@(Var {})  = cpeApp env expr
    
    781
    -cpeRhsE env expr@(App {})  = cpeApp env expr
    
    786
    +cpeBodyF env expr@(Var {})  = cpeApp env expr
    
    787
    +cpeBodyF env expr@(App {})  = cpeApp env expr
    
    782 788
     
    
    783
    -cpeRhsE env (Let bind body)
    
    789
    +cpeBodyF env (Let bind body)
    
    784 790
       = do { (env', bind_floats, maybe_bind') <- cpeBind NotTopLevel env bind
    
    785
    -       ; (body_floats, body') <- cpeRhsE env' body
    
    791
    +       ; (body_floats, body') <- cpeBodyF env' body
    
    786 792
            ; let expr' = case maybe_bind' of Just bind' -> Let bind' body'
    
    787 793
                                              Nothing    -> body'
    
    788 794
            ; return (bind_floats `appFloats` body_floats, expr') }
    
    789 795
     
    
    790
    -cpeRhsE env (Tick tickish expr)
    
    796
    +cpeBodyF env (Tick tickish expr)
    
    791 797
       -- Pull out ticks if they are allowed to be floated.
    
    792 798
       | tickishFloatable tickish
    
    793
    -  = do { (floats, body) <- cpeRhsE env expr
    
    799
    +  = do { (floats, body) <- cpeBodyF env expr
    
    794 800
              -- See [Floating Ticks in CorePrep]
    
    795 801
            ; return (FloatTick tickish `consFloat` floats, body) }
    
    796 802
       | otherwise
    
    797
    -  = do { body <- cpeBodyNF env expr
    
    803
    +  = do { body <- cpeBody env expr
    
    798 804
            ; return (emptyFloats, mkTick tickish' body) }
    
    799 805
       where
    
    800 806
         tickish' | Breakpoint ext bid fvs <- tickish
    
    ... ... @@ -803,17 +809,17 @@ cpeRhsE env (Tick tickish expr)
    803 809
                  | otherwise
    
    804 810
                  = tickish
    
    805 811
     
    
    806
    -cpeRhsE env (Cast expr co)
    
    807
    -   = do { (floats, expr') <- cpeRhsE env expr
    
    812
    +cpeBodyF env (Cast expr co)
    
    813
    +   = do { (floats, expr') <- cpeBodyF env expr
    
    808 814
             ; return (floats, Cast expr' (cpSubstCo env co)) }
    
    809 815
     
    
    810
    -cpeRhsE env expr@(Lam {})
    
    816
    +cpeBodyF env expr@(Lam {})
    
    811 817
        = do { let (bndrs,body) = collectBinders expr
    
    812 818
             ; (env', bndrs') <- cpCloneBndrs env bndrs
    
    813
    -        ; body' <- cpeBodyNF env' body
    
    819
    +        ; body' <- cpeBody env' body
    
    814 820
             ; return (emptyFloats, mkLams bndrs' body') }
    
    815 821
     
    
    816
    -cpeRhsE env (Case scrut bndr _ alts@[Alt con [covar] _])
    
    822
    +cpeBodyF env (Case scrut bndr _ alts@[Alt con [covar] _])
    
    817 823
       -- See (U3) in Note [Implementing unsafeCoerce]
    
    818 824
       -- We need make the Case float, otherwise we get
    
    819 825
       --   let x = case ... of UnsafeRefl co ->
    
    ... ... @@ -828,7 +834,7 @@ cpeRhsE env (Case scrut bndr _ alts@[Alt con [covar] _])
    828 834
       -- Note that `x` is a value here. This is visible in the GHCi debugger tests
    
    829 835
       -- (such as `print003`).
    
    830 836
       | Just rhs <- isUnsafeEqualityCase scrut bndr alts
    
    831
    -  = do { (floats_scrut, scrut) <- cpeBody env scrut
    
    837
    +  = do { (floats_scrut, scrut) <- cpeBodyF env scrut
    
    832 838
     
    
    833 839
            ; (env, bndr')  <- cpCloneBndr env bndr
    
    834 840
            ; (env, covar') <- cpCloneCoVarBndr env covar
    
    ... ... @@ -836,19 +842,19 @@ cpeRhsE env (Case scrut bndr _ alts@[Alt con [covar] _])
    836 842
                               -- See Note [Cloning CoVars and TyVars]
    
    837 843
     
    
    838 844
              -- Up until here this should do exactly the same as the regular code
    
    839
    -         -- path of `cpeRhsE Case{}`.
    
    840
    -       ; (floats_rhs, rhs) <- cpeBody env rhs
    
    845
    +         -- path of `cpeBodyF Case{}`.
    
    846
    +       ; (floats_rhs, rhs) <- cpeBodyF env rhs
    
    841 847
              -- ... but we want to float `floats_rhs` as in (U3) so that rhs' might
    
    842 848
              -- become a value
    
    843 849
            ; let case_float = UnsafeEqualityCase scrut bndr' con [covar']
    
    844 850
              -- NB: It is OK to "evaluate" the proof eagerly.
    
    845 851
              --     Usually there's the danger that we float the unsafeCoerce out of
    
    846 852
              --     a branching Case alt. Not so here, because the regular code path
    
    847
    -         --     for `cpeRhsE Case{}` will not float out of alts.
    
    853
    +         --     for `cpeBodyF Case{}` will not float out of alts.
    
    848 854
                  floats = snocFloat floats_scrut case_float `appFloats` floats_rhs
    
    849 855
            ; return (floats, rhs) }
    
    850 856
     
    
    851
    -cpeRhsE env (Case scrut bndr _ [Alt (DataAlt dc) [token_out, res] rhs])
    
    857
    +cpeBodyF env (Case scrut bndr _ [Alt (DataAlt dc) [token_out, res] rhs])
    
    852 858
       -- See item (SEQ4) of Note [seq# magic]. We want to match
    
    853 859
       --   case seq# @a @RealWorld <ok-to-discard> s of (# s', _ #) -> rhs[s']
    
    854 860
       -- and simplify to rhs[s]. Triggers in T15226.
    
    ... ... @@ -869,10 +875,10 @@ cpeRhsE env (Case scrut bndr _ [Alt (DataAlt dc) [token_out, res] rhs])
    869 875
           -- often zaps the OccInfo on case-alternative binders (see Note [DataAlt occ info]
    
    870 876
           -- in GHC.Core.Opt.Simplify.Iteration) because the scrutinee is not a
    
    871 877
           -- variable, and in that case the zapping doesn't happen; see that Note.
    
    872
    -  = cpeRhsE (extendCorePrepEnv env token_out token_in') rhs
    
    878
    +  = cpeBodyF (extendCorePrepEnv env token_out token_in') rhs
    
    873 879
     
    
    874
    -cpeRhsE env (Case scrut bndr ty alts)
    
    875
    -  = do { (floats, scrut') <- cpeBody env scrut
    
    880
    +cpeBodyF env (Case scrut bndr ty alts)
    
    881
    +  = do { (floats, scrut') <- cpeBodyF env scrut
    
    876 882
            ; (env', bndr2) <- cpCloneBndr env bndr
    
    877 883
            ; let bndr3 = bndr2 `setIdUnfolding` evaldUnfolding
    
    878 884
            ; let alts'
    
    ... ... @@ -885,7 +891,7 @@ cpeRhsE env (Case scrut bndr ty alts)
    885 891
                    , not (altsAreExhaustive alts)
    
    886 892
                    = addDefault alts (Just err)
    
    887 893
                    | otherwise = alts
    
    888
    -               where err = mkImpossibleExpr ty "cpeRhsE: missing case alternative"
    
    894
    +               where err = mkImpossibleExpr ty "cpeBodyF: missing case alternative"
    
    889 895
            ; alts'' <- mapM (sat_alt env') alts'
    
    890 896
     
    
    891 897
            ; case alts'' of
    
    ... ... @@ -896,7 +902,7 @@ cpeRhsE env (Case scrut bndr ty alts)
    896 902
       where
    
    897 903
         sat_alt env (Alt con bs rhs)
    
    898 904
            = do { (env2, bs') <- cpCloneBndrs env bs
    
    899
    -            ; rhs' <- cpeBodyNF env2 rhs
    
    905
    +            ; rhs' <- cpeBody env2 rhs
    
    900 906
                 ; return (Alt con bs' rhs') }
    
    901 907
     
    
    902 908
     -- ---------------------------------------------------------------------------
    
    ... ... @@ -908,74 +914,10 @@ cpeRhsE env (Case scrut bndr ty alts)
    908 914
     -- let-bound using 'wrapBinds').  Generally you want this, esp.
    
    909 915
     -- when you've reached a binding form (e.g., a lambda) and
    
    910 916
     -- floating any further would be incorrect.
    
    911
    -cpeBodyNF :: CorePrepEnv -> CoreExpr -> UniqSM CpeBody
    
    912
    -cpeBodyNF env expr
    
    913
    -  = do { (floats, body) <- cpeBody env expr
    
    914
    -       ; return (wrapBinds floats body) }
    
    915
    -
    
    916
    --- | Convert a 'CoreExpr' so it satisfies 'CpeBody'; also produce
    
    917
    --- a list of 'Floats' which are being propagated upwards.  In
    
    918
    --- fact, this function is used in only two cases: to
    
    919
    --- implement 'cpeBodyNF' (which is what you usually want),
    
    920
    --- and in the case when a let-binding is in a case scrutinee--here,
    
    921
    --- we can always float out:
    
    922
    ---
    
    923
    ---      case (let x = y in z) of ...
    
    924
    ---      ==> let x = y in case z of ...
    
    925
    ---
    
    926
    -cpeBody :: CorePrepEnv -> CoreExpr -> UniqSM (Floats, CpeBody)
    
    917
    +cpeBody :: CorePrepEnv -> CoreExpr -> UniqSM CpeBody
    
    927 918
     cpeBody env expr
    
    928
    -  = do { (floats1, rhs) <- cpeRhsE env expr
    
    929
    -       ; (floats2, body) <- rhsToBody env rhs
    
    930
    -       ; return (floats1 `appFloats` floats2, body) }
    
    931
    -
    
    932
    ---------
    
    933
    -rhsToBody :: CorePrepEnv -> CpeRhs -> UniqSM (Floats, CpeBody)
    
    934
    --- Remove top level lambdas by let-binding
    
    935
    -
    
    936
    -rhsToBody env (Tick t expr)
    
    937
    -  | tickishHasNoScope t -- only float out of non-scoped annotations
    
    938
    -  = do { (floats, expr') <- rhsToBody env expr
    
    939
    -       ; return (floats, mkTick t expr') }
    
    940
    -
    
    941
    -rhsToBody env (Cast e co)
    
    942
    -        -- You can get things like
    
    943
    -        --      case e of { p -> coerce t (\s -> ...) }
    
    944
    -  = do { (floats, e') <- rhsToBody env e
    
    945
    -       ; return (floats, Cast e' co) }
    
    946
    -
    
    947
    -rhsToBody env expr@(Lam {})   -- See Note [No eta reduction needed in rhsToBody]
    
    948
    -  | all isTyVar bndrs           -- Type lambdas are ok
    
    949
    -  = return (emptyFloats, expr)
    
    950
    -  | otherwise                   -- Some value lambdas
    
    951
    -  = do { let rhs = cpeEtaExpand (exprArity expr) expr
    
    952
    -       ; fn <- newVar env (exprType rhs)
    
    953
    -       ; let float = Float (NonRec fn rhs) LetBound TopLvlFloatable
    
    954
    -       ; return (unitFloat float, Var fn) }
    
    955
    -  where
    
    956
    -    (bndrs,_) = collectBinders expr
    
    957
    -
    
    958
    -rhsToBody _env expr = return (emptyFloats, expr)
    
    959
    -
    
    960
    -
    
    961
    -{- Note [No eta reduction needed in rhsToBody]
    
    962
    -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    963
    -Historical note.  In the olden days we used to have a Prep-specific
    
    964
    -eta-reduction step in rhsToBody:
    
    965
    -  rhsToBody expr@(Lam {})
    
    966
    -    | Just no_lam_result <- tryEtaReducePrep bndrs body
    
    967
    -    = return (emptyFloats, no_lam_result)
    
    968
    -
    
    969
    -The goal was to reduce
    
    970
    -        case x of { p -> \xs. map f xs }
    
    971
    -    ==> case x of { p -> map f }
    
    972
    -
    
    973
    -to avoid allocating a lambda.  Of course, we'd allocate a PAP
    
    974
    -instead, which is hardly better, but that's the way it was.
    
    975
    -
    
    976
    -Now we simply don't bother with this. It doesn't seem to be a win,
    
    977
    -and it's extra work.
    
    978
    --}
    
    919
    +  = do { (floats, body) <- cpeBodyF env expr
    
    920
    +       ; return (wrapBinds floats body) }
    
    979 921
     
    
    980 922
     -- ---------------------------------------------------------------------------
    
    981 923
     --              CpeApp: produces a result satisfying CpeApp
    
    ... ... @@ -1060,8 +1002,8 @@ body of the eta-expansion lambda, resulting in
    1060 1002
     which is unproblematic.
    
    1061 1003
     -}
    
    1062 1004
     
    
    1063
    -cpeApp :: CorePrepEnv -> CoreExpr -> UniqSM (Floats, CpeRhs)
    
    1064
    --- May return a CpeRhs (instead of CpeApp) because of saturating primops
    
    1005
    +cpeApp :: CorePrepEnv -> CoreExpr -> UniqSM (Floats, CpeBody)
    
    1006
    +-- May return a CpeBody (instead of CpeApp) because of saturating primops
    
    1065 1007
     cpeApp top_env expr
    
    1066 1008
       = do { let (terminal, args) = collect_args expr
    
    1067 1009
           --  ; pprTraceM "cpeApp" $ (ppr expr)
    
    ... ... @@ -1103,7 +1045,7 @@ cpeApp top_env expr
    1103 1045
         cpe_app :: CorePrepEnv
    
    1104 1046
                 -> CoreExpr -- The thing we are calling
    
    1105 1047
                 -> [ArgInfo]
    
    1106
    -            -> UniqSM (Floats, CpeRhs)
    
    1048
    +            -> UniqSM (Floats, CpeBody)
    
    1107 1049
         cpe_app env (Var f) (AIApp Type{} : AIApp arg : args)
    
    1108 1050
             | f `hasKey` lazyIdKey          -- Replace (lazy a) with a, and
    
    1109 1051
                 -- See Note [lazyId magic] in GHC.Types.Id.Make
    
    ... ... @@ -1156,7 +1098,7 @@ cpeApp top_env expr
    1156 1098
             --          case thing of res { __DEFAULT -> (# token, res#) } },
    
    1157 1099
             -- allocating CaseBound Floats for token and thing as needed
    
    1158 1100
             = do { (floats1, token) <- cpeArg env topDmd token
    
    1159
    -             ; (floats2, thing) <- cpeBody env thing
    
    1101
    +             ; (floats2, thing) <- cpeBodyF env thing
    
    1160 1102
                  ; case_bndr <- (`setIdUnfolding` evaldUnfolding) <$> newVar env ty
    
    1161 1103
                  ; let tup = mkCoreUnboxedTuple [token, Var case_bndr]
    
    1162 1104
                  ; let float = mkCaseFloat case_bndr thing
    
    ... ... @@ -1173,9 +1115,10 @@ cpeApp top_env expr
    1173 1115
                          then Just $! idArity v_hd
    
    1174 1116
                          else Nothing
    
    1175 1117
                        Nothing -> Nothing
    
    1176
    -          --  ; pprTraceM "cpe_app:stricts:" (ppr v <+> ppr args $$ ppr stricts $$ ppr (idCbvMarks_maybe v))
    
    1177 1118
                ; (app, floats, unsat_ticks) <- rebuild_app env args e2 emptyFloats stricts min_arity
    
    1178
    -           ; mb_saturate hd app floats unsat_ticks depth }
    
    1119
    +           ; case hd of
    
    1120
    +               Nothing    -> do { massert (null unsat_ticks); return (floats, app) }
    
    1121
    +               Just fn_id -> return (floats, maybeSaturate fn_id app depth unsat_ticks) }
    
    1179 1122
             where
    
    1180 1123
               depth = val_args args
    
    1181 1124
               stricts = case idDmdSig v of
    
    ... ... @@ -1190,8 +1133,8 @@ cpeApp top_env expr
    1190 1133
                     -- partial application might be seq'd
    
    1191 1134
     
    
    1192 1135
             -- We inlined into something that's not a var and has no args.
    
    1193
    -        -- Bounce it back up to cpeRhsE.
    
    1194
    -    cpe_app env fun [] = cpeRhsE env fun
    
    1136
    +        -- Bounce it back up to cpeBodyF.
    
    1137
    +    cpe_app env fun [] = cpeBodyF env fun
    
    1195 1138
     
    
    1196 1139
         -- Here we get:
    
    1197 1140
         -- N-variable fun, better let-bind it
    
    ... ... @@ -1202,7 +1145,8 @@ cpeApp top_env expr
    1202 1145
                               -- If evalDmd says that it's sure to be evaluated,
    
    1203 1146
                               -- we'll end up case-binding it
    
    1204 1147
                ; (app, floats,unsat_ticks) <- rebuild_app env args fun' fun_floats [] Nothing
    
    1205
    -           ; mb_saturate Nothing app floats unsat_ticks (val_args args) }
    
    1148
    +           ; massert (null unsat_ticks)
    
    1149
    +           ; return (floats, app) }
    
    1206 1150
     
    
    1207 1151
         -- Count the number of value arguments *and* coercions (since we don't eliminate the later in STG)
    
    1208 1152
         val_args :: [ArgInfo] -> Int
    
    ... ... @@ -1223,13 +1167,6 @@ cpeApp top_env expr
    1223 1167
                       | isTypeArg e = n
    
    1224 1168
                       | otherwise   = n+1
    
    1225 1169
     
    
    1226
    -    -- Saturate if necessary
    
    1227
    -    mb_saturate head app floats unsat_ticks depth =
    
    1228
    -       case head of
    
    1229
    -         Just fn_id -> do { sat_app <- maybeSaturate fn_id app depth unsat_ticks
    
    1230
    -                          ; return (floats, sat_app) }
    
    1231
    -         _other     -> do { massert (null unsat_ticks)
    
    1232
    -                          ; return (floats, app) }
    
    1233 1170
     
    
    1234 1171
         -- Deconstruct and rebuild the application, floating any non-atomic
    
    1235 1172
         -- arguments to the outside.  We collect the type of the expression,
    
    ... ... @@ -1561,11 +1498,11 @@ Wrinkles:
    1561 1498
     cpeArg :: CorePrepEnv -> Demand
    
    1562 1499
            -> CoreArg -> UniqSM (Floats, CpeArg)
    
    1563 1500
     cpeArg env dmd arg
    
    1564
    -  = do { (floats1, arg1) <- cpeRhsE env arg     -- arg1 can be a lambda
    
    1501
    +  = do { (floats1, arg1) <- cpeBodyF env arg     -- arg1 can be a lambda
    
    1565 1502
            ; let arg_ty = exprType arg1
    
    1566 1503
                  lev    = typeLevity arg_ty
    
    1567 1504
                  dec    = wantFloatLocal NonRecursive dmd lev floats1 arg1
    
    1568
    -       ; (floats2, arg2) <- executeFloatDecision env dec floats1 arg1
    
    1505
    +             (floats2, arg2) = executeFloatDecision dec floats1 arg1
    
    1569 1506
                     -- Else case: arg1 might have lambdas, and we can't
    
    1570 1507
                     --            put them inside a wrapBinds
    
    1571 1508
     
    
    ... ... @@ -1580,7 +1517,12 @@ cpeArg env dmd arg
    1580 1517
                            arg3  = cpeEtaExpand arity arg2
    
    1581 1518
                            -- See Note [Eta expansion of arguments in CorePrep]
    
    1582 1519
                      ; let (arg_float, v') = mkNonRecFloat env lev v arg3
    
    1583
    -                 ---; pprTraceM "cpeArg" (ppr arg1 $$ ppr dec $$ ppr arg2)
    
    1520
    +--                 ; pprTraceM "cpeArg" (vcat [ text "arg1" <+> ppr arg1
    
    1521
    +--                                            , text "decision" <+>  ppr dec
    
    1522
    +--                                            , text "arg2" <+> ppr arg2
    
    1523
    +--                                            , text "arity" <+> ppr arity
    
    1524
    +--                                            , text "arg3" <+> ppr arg3
    
    1525
    +--                                            ])
    
    1584 1526
                      ; return (snocFloat floats2 arg_float, varToCoreExpr v') }
    
    1585 1527
            }
    
    1586 1528
     
    
    ... ... @@ -1617,59 +1559,56 @@ eta_would_wreck_join (Tick _ e) = eta_would_wreck_join e
    1617 1559
     eta_would_wreck_join (Case _ _ _ alts) = any eta_would_wreck_join (rhssOfAlts alts)
    
    1618 1560
     eta_would_wreck_join _                 = False
    
    1619 1561
     
    
    1620
    -maybeSaturate :: Id -> CpeApp -> Int -> [CoreTickish] -> UniqSM CpeRhs
    
    1562
    +maybeSaturate :: Id -> CpeApp
    
    1563
    +              -> Int  -- Number of value arguments in the application
    
    1564
    +              -> [CoreTickish]
    
    1565
    +              -> CpeBody
    
    1621 1566
     maybeSaturate fn expr n_args unsat_ticks
    
    1622
    -  | hasNoBinding fn        -- There's no binding
    
    1623
    -    -- See Note [Eta expansion of hasNoBinding things in CorePrep]
    
    1624
    -  = return $ wrapLamBody (\body -> foldr mkTick body unsat_ticks) sat_expr
    
    1625
    -
    
    1626
    -  | mark_arity > 0 -- A call-by-value function.
    
    1627
    -                   -- See Note [CBV Function Ids: overview]
    
    1628
    -  , not applied_marks
    
    1629
    -  = assertPpr
    
    1630
    -      ( not (isJoinId fn)) -- See Note [Do not eta-expand join points]
    
    1631
    -      ( ppr fn $$ text "expr:" <+> ppr expr $$ text "n_args:" <+> ppr n_args $$
    
    1632
    -          text "marks:" <+> ppr (idCbvMarks_maybe fn) $$
    
    1633
    -          text "join_arity" <+> ppr (idJoinPointHood fn) $$
    
    1634
    -          text "fn_arity" <+> ppr fn_arity
    
    1635
    -       ) $
    
    1636
    -    -- pprTrace "maybeSat"
    
    1637
    -    --   ( ppr fn $$ text "expr:" <+> ppr expr $$ text "n_args:" <+> ppr n_args $$
    
    1638
    -    --       text "marks:" <+> ppr (idCbvMarks_maybe fn) $$
    
    1639
    -    --       text "join_arity" <+> ppr (isJoinId_maybe fn) $$
    
    1640
    -    --       text "fn_arity" <+> ppr fn_arity $$
    
    1641
    -    --       text "excess_arity" <+> ppr excess_arity $$
    
    1642
    -    --       text "mark_arity" <+> ppr mark_arity
    
    1643
    -    --    ) $
    
    1644
    -    return sat_expr
    
    1567
    +  | isJoinId fn  -- Never eta-expand a call to a join point
    
    1568
    +                 -- See Note [Do not eta-expand join points]
    
    1569
    +  = assertPpr (not must_eta_expand) (ppr expr) $
    
    1570
    +    -- assertPpr: check that all arguments that need to be passed cbv
    
    1571
    +    -- are visible, so the backend can evalaute them if required
    
    1572
    +    expr
    
    1573
    +
    
    1574
    +  | must_eta_expand || desirable_to_eta_expand
    
    1575
    +    -- n_args > 0: do not eta-expand a naked variable!
    
    1576
    +  = wrapLamBody (mkTicks unsat_ticks) $
    
    1577
    +    cpeEtaExpand excess_arity expr
    
    1645 1578
     
    
    1646 1579
       | otherwise
    
    1647
    -  = assert (null unsat_ticks) $
    
    1648
    -    return expr
    
    1580
    +  = expr
    
    1581
    +
    
    1649 1582
       where
    
    1650
    -    mark_arity    = idCbvMarkArity fn
    
    1651
    -    fn_arity      = idArity fn
    
    1652
    -    excess_arity  = (max fn_arity mark_arity) - n_args
    
    1653
    -    sat_expr      = cpeEtaExpand excess_arity expr
    
    1654
    -    applied_marks = n_args >= (length . dropWhile (not . isMarkedCbv) .
    
    1655
    -                               reverse . expectJust $ (idCbvMarks_maybe fn))
    
    1656
    -    -- For join points we never eta-expand (See Note [Do not eta-expand join points])
    
    1657
    -    -- so we assert all arguments that need to be passed cbv are visible so that the
    
    1658
    -    -- backend can evalaute them if required..
    
    1583
    +    must_eta_expand
    
    1584
    +      =  (hasNoBinding fn && fn_arity > n_args)
    
    1585
    +            -- hasNoBinding functions must be saturated
    
    1586
    +      || (mark_arity > n_args)
    
    1587
    +            -- CBV functions must be CBV-saturated
    
    1588
    +
    
    1589
    +    desirable_to_eta_expand = fn_arity > n_args && n_args > 0
    
    1590
    +       -- n_args > 0: do not eta-expand a naked variable unless we have to
    
    1591
    +
    
    1592
    +    mark_arity   = idCbvMarkArity fn
    
    1593
    +    fn_arity     = idArity fn
    
    1594
    +    excess_arity = (max fn_arity mark_arity) - n_args
    
    1659 1595
     
    
    1660 1596
     {- Note [Eta expansion]
    
    1661 1597
     ~~~~~~~~~~~~~~~~~~~~~~~
    
    1662
    -Eta expand to match the arity claimed by the binder Remember,
    
    1663
    -CorePrep must not change arity
    
    1598
    +Eta expand to match the arity claimed by the binder.
    
    1599
    +Remember, CorePrep must not change arity
    
    1664 1600
     
    
    1665 1601
     Eta expansion might not have happened already, because it is done by
    
    1666 1602
     the simplifier only when there at least one lambda already.
    
    1667 1603
     
    
    1668
    -NB1:we could refrain when the RHS is trivial (which can happen
    
    1669
    -    for exported things).  This would reduce the amount of code
    
    1670
    -    generated (a little) and make things a little worse for
    
    1671
    -    code compiled without -O.  The case in point is data constructor
    
    1672
    -    wrappers.
    
    1604
    +We do eta-expansion (via `cpeEtaExpand`) in three places:
    
    1605
    +
    
    1606
    +* At let-bindings; in `cpePair`
    
    1607
    +
    
    1608
    +* On function arguments: in `cpeArg`
    
    1609
    +  See Note [Eta expansion of arguments in CorePrep]
    
    1610
    +
    
    1611
    +* At un-saturated function calls: in `maybeSaturate`
    
    1673 1612
     
    
    1674 1613
     NB2: we have to be careful that the result of etaExpand doesn't
    
    1675 1614
        invalidate any of the assumptions that CorePrep is attempting
    
    ... ... @@ -1677,12 +1616,37 @@ NB2: we have to be careful that the result of etaExpand doesn't
    1677 1616
        an SCC note - we're now careful in etaExpand to make sure the
    
    1678 1617
        SCC is pushed inside any new lambdas that are generated.
    
    1679 1618
     
    
    1680
    -Note [Eta expansion of hasNoBinding things in CorePrep]
    
    1681
    -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    1682
    -maybeSaturate deals with eta expanding to saturate things that can't deal
    
    1683
    -with unsaturated applications (identified by 'hasNoBinding', currently
    
    1684
    -foreign calls, unboxed tuple/sum constructors, and representation-polymorphic
    
    1685
    -primitives such as 'coerce' and 'unsafeCoerce#').
    
    1619
    +Note [Eta expansion for let-bindings]
    
    1620
    +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    1621
    +Given f = rhs, we eta-expand `rhs` to match f's arity.
    
    1622
    +
    
    1623
    +We could refrain when the RHS is trivial (which can happen for exported things).
    
    1624
    +This would reduce the amount of code generated (a little) and make things a
    
    1625
    +little worse for code compiled without -O.  The case in point is data
    
    1626
    +constructor wrappers.
    
    1627
    +
    
    1628
    +Note [Eta expansion of unsaturated calls]
    
    1629
    +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    1630
    +Give a call (f a1..an), where `f` is a known function with arity greater than `n`,
    
    1631
    +there are three reasons we might want to eta-expand:
    
    1632
    +
    
    1633
    +* Must eta-expand: if `f` is a `hasNoBinding` function, we must saturate
    
    1634
    +  it, because the function has no (curried) binding to call. Currently
    
    1635
    +  this includes:
    
    1636
    +     - foreign calls,
    
    1637
    +     - unboxed tuple/sum constructors
    
    1638
    +     - representation-polymorphic primitives such as 'coerce' and 'unsafeCoerce#'
    
    1639
    +     - primops (for now anyway; see comments in `hasNoBinding`)
    
    1640
    +
    
    1641
    +* Must eta-expand: if `f` has a call-by-value calling convention, we /must/
    
    1642
    +  call it with evaluated arguments.  The back end deals with adding the
    
    1643
    +  necessary evaluation at the call site, but we must first ensure that it is
    
    1644
    +  saturated.
    
    1645
    +
    
    1646
    +* May eta-expand: consider
    
    1647
    +     \x -> f x True
    
    1648
    +  where `f` has arity 3.   Then it's much better to eta-expand f so we have
    
    1649
    +     \xy -> f x True y
    
    1686 1650
     
    
    1687 1651
     Historical Note: Note that eta expansion in CorePrep used to be very fragile
    
    1688 1652
     due to the "prediction" of CAFfyness that we used to make during tidying.  We
    
    ... ... @@ -1694,7 +1658,7 @@ Note [Eta expansion and the CorePrep invariants]
    1694 1658
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    1695 1659
     It turns out to be much much easier to do eta expansion
    
    1696 1660
     *after* the main CorePrep stuff.  But that places constraints
    
    1697
    -on the eta expander: given a CpeRhs, it must return a CpeRhs.
    
    1661
    +on the eta expander: given a CpeBody, it must return a CpeBody.
    
    1698 1662
     
    
    1699 1663
     For example here is what we do not want:
    
    1700 1664
                     f = /\a -> g (h 3)      -- h has arity 2
    
    ... ... @@ -1706,6 +1670,26 @@ and now we do NOT want eta expansion to give
    1706 1670
     Instead GHC.Core.Opt.Arity.etaExpand gives
    
    1707 1671
                     f = /\a -> \y -> let s = h 3 in g s y
    
    1708 1672
     
    
    1673
    +Another example:
    
    1674
    +  f x = case x of
    
    1675
    +           A -> \y. e
    
    1676
    +           B -> hnb 3  -- where `hnb` has no binding
    
    1677
    +           C -> z
    
    1678
    +Then we may eta-expand `hnb` to get
    
    1679
    +  f x = case x of
    
    1680
    +           A -> \y. e
    
    1681
    +           B -> \y. hnb 3 y
    
    1682
    +           C -> z
    
    1683
    +Now we come to the binding of `f` itself, and eta-expand that, to give
    
    1684
    +  f x y = case x of
    
    1685
    +            A -> e
    
    1686
    +            B -> hnb 3 y
    
    1687
    +            C -> z y
    
    1688
    +Notice how important it is that the eta-expansion for `f` doesn't
    
    1689
    +generate any crap like
    
    1690
    +            B -> (\y. hnb 3 y) y
    
    1691
    +Fortunately, the eta-expander is careful not to do so.
    
    1692
    +
    
    1709 1693
     Note [Eta expansion of arguments in CorePrep]
    
    1710 1694
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    1711 1695
     Suppose `g = \x y. blah` and consider the expression `f (g x)`; we ANFise to
    
    ... ... @@ -1798,7 +1782,7 @@ There is a nasty Wrinkle:
    1798 1782
           #24471 is a good example, where Prep took 25% of compile time!
    
    1799 1783
     -}
    
    1800 1784
     
    
    1801
    -cpeEtaExpand :: Arity -> CpeRhs -> CpeRhs
    
    1785
    +cpeEtaExpand :: Arity -> CpeBody -> CpeBody
    
    1802 1786
     cpeEtaExpand arity expr
    
    1803 1787
       | arity == 0 = expr
    
    1804 1788
       | otherwise  = etaExpand arity expr
    
    ... ... @@ -2165,9 +2149,6 @@ isEmptyFloats (Floats _ b) = isNilOL b
    2165 2149
     getFloats :: Floats -> OrdList FloatingBind
    
    2166 2150
     getFloats = fs_binds
    
    2167 2151
     
    
    2168
    -unitFloat :: FloatingBind -> Floats
    
    2169
    -unitFloat = snocFloat emptyFloats
    
    2170
    -
    
    2171 2152
     floatInfo :: FloatingBind -> FloatInfo
    
    2172 2153
     floatInfo (Float _ _ info)     = info
    
    2173 2154
     floatInfo UnsafeEqualityCase{} = LazyContextFloatable -- See Note [Floating in CorePrep]
    
    ... ... @@ -2255,7 +2236,7 @@ decideFloatInfo FIA{fia_levity=lev, fia_demand=dmd, fia_is_hnf=is_hnf,
    2255 2236
       | Lifted   <- lev       = (LetBound, TopLvlFloatable)
    
    2256 2237
           -- And these float freely but can't be speculated, hence LetBound
    
    2257 2238
     
    
    2258
    -mkCaseFloat :: Id -> CpeRhs -> FloatingBind
    
    2239
    +mkCaseFloat :: Id -> CpeBody -> FloatingBind
    
    2259 2240
     mkCaseFloat bndr scrut
    
    2260 2241
       = -- pprTrace "mkCaseFloat" (ppr bndr <+> ppr (bound,info)
    
    2261 2242
         --                             -- <+> ppr is_lifted <+> ppr is_strict
    
    ... ... @@ -2273,7 +2254,7 @@ mkCaseFloat bndr scrut
    2273 2254
               -- (ok-for-spec case bindings are unlikely anyway.)
    
    2274 2255
           }
    
    2275 2256
     
    
    2276
    -mkNonRecFloat :: CorePrepEnv -> Levity -> Id -> CpeRhs -> (FloatingBind, Id)
    
    2257
    +mkNonRecFloat :: CorePrepEnv -> Levity -> Id -> CpeBody -> (FloatingBind, Id)
    
    2277 2258
     mkNonRecFloat env lev bndr rhs
    
    2278 2259
       = -- pprTrace "mkNonRecFloat" (ppr bndr <+> ppr (bound,info)
    
    2279 2260
         --                             <+> if is_strict then text "strict" else if is_lifted then text "lazy" else text "unlifted"
    
    ... ... @@ -2413,24 +2394,18 @@ instance Outputable FloatDecision where
    2413 2394
       ppr FloatNone = text "none"
    
    2414 2395
       ppr FloatAll  = text "all"
    
    2415 2396
     
    
    2416
    -executeFloatDecision :: CorePrepEnv -> FloatDecision -> Floats -> CpeRhs -> UniqSM (Floats, CpeRhs)
    
    2417
    -executeFloatDecision env dec floats rhs
    
    2397
    +executeFloatDecision :: FloatDecision -> Floats -> CpeBody -> (Floats, CpeBody)
    
    2398
    +executeFloatDecision dec floats rhs
    
    2418 2399
       = case dec of
    
    2419
    -      FloatAll                 -> return (floats, rhs)
    
    2420
    -      FloatNone
    
    2421
    -        | isEmptyFloats floats -> return (emptyFloats, rhs)
    
    2422
    -        | otherwise            -> do { (floats', body) <- rhsToBody env rhs
    
    2423
    -                                     ; return (emptyFloats, wrapBinds floats $
    
    2424
    -                                                            wrapBinds floats' body) }
    
    2425
    -            -- FloatNone case: `rhs` might have lambdas, and we can't
    
    2426
    -            -- put them inside a wrapBinds, which expects a `CpeBody`.
    
    2400
    +      FloatAll  -> (floats,      rhs)
    
    2401
    +      FloatNone -> (emptyFloats, wrapBinds floats rhs)
    
    2427 2402
     
    
    2428 2403
     wantFloatTop :: Floats -> FloatDecision
    
    2429 2404
     wantFloatTop fs
    
    2430 2405
       | fs_info fs `floatsAtLeastAsFarAs` TopLvlFloatable = FloatAll
    
    2431 2406
       | otherwise                                         = FloatNone
    
    2432 2407
     
    
    2433
    -wantFloatLocal :: RecFlag -> Demand -> Levity -> Floats -> CpeRhs -> FloatDecision
    
    2408
    +wantFloatLocal :: RecFlag -> Demand -> Levity -> Floats -> CpeBody -> FloatDecision
    
    2434 2409
     -- See Note [wantFloatLocal]
    
    2435 2410
     wantFloatLocal is_rec rhs_dmd rhs_lev floats rhs
    
    2436 2411
       |  isEmptyFloats floats -- Well yeah...
    
    ... ... @@ -2479,7 +2454,7 @@ zero free variables.)
    2479 2454
     In general, the inliner is good at eliminating these let-bindings.  However,
    
    2480 2455
     there is one case where these trivial updatable thunks can arise: when
    
    2481 2456
     we are optimizing away 'lazy' (see Note [lazyId magic], and also
    
    2482
    -'cpeRhsE'.)  Then, we could have started with:
    
    2457
    +'cpeBodyF'.)  Then, we could have started with:
    
    2483 2458
     
    
    2484 2459
          let x :: ()
    
    2485 2460
              x = lazy @() y
    
    ... ... @@ -2783,8 +2758,7 @@ wrapTicks floats expr
    2783 2758
     -- ---------------------------------------------------------------------------
    
    2784 2759
     
    
    2785 2760
     -- | Converts Bignum literals into their final CoreExpr
    
    2786
    -cpeBigNatLit
    
    2787
    -   :: CorePrepEnv -> Integer -> UniqSM (Floats, CpeRhs)
    
    2761
    +cpeBigNatLit :: CorePrepEnv -> Integer -> UniqSM (Floats, CpeBody)
    
    2788 2762
     cpeBigNatLit env i = assert (i >= 0) $ do
    
    2789 2763
       let
    
    2790 2764
         platform = cp_platform (cpe_config env)
    

  • compiler/GHC/Driver/Main.hs
    ... ... @@ -2434,8 +2434,8 @@ myCoreToStg :: Logger -> DynFlags -> [Var]
    2434 2434
                       , CollectedCCs -- CAF cost centre info (declared and used)
    
    2435 2435
                       , StgCgInfos )
    
    2436 2436
     myCoreToStg logger dflags ic_inscope for_bytecode this_mod ml prepd_binds = do
    
    2437
    -    let (stg_binds, denv, cost_centre_info)
    
    2438
    -         = {-# SCC "Core2Stg" #-}
    
    2437
    +    (stg_binds, denv, cost_centre_info)
    
    2438
    +       <- {-# SCC "Core2Stg" #-}
    
    2439 2439
                coreToStg (initCoreToStgOpts dflags) this_mod ml prepd_binds
    
    2440 2440
     
    
    2441 2441
         (stg_binds_with_fvs,stg_cg_info)
    

  • compiler/GHC/Stg/Lint.hs
    ... ... @@ -105,7 +105,7 @@ import GHC.Core ( AltCon(..) )
    105 105
     import GHC.Core.Type
    
    106 106
     import GHC.Core.Lint        ( lintMessage )
    
    107 107
     
    
    108
    -import GHC.Types.Basic      ( TopLevelFlag(..), isTopLevel, isMarkedCbv )
    
    108
    +import GHC.Types.Basic      ( TopLevelFlag(..), isTopLevel )
    
    109 109
     import GHC.Types.CostCentre ( isCurrentCCS )
    
    110 110
     import GHC.Types.Id
    
    111 111
     import GHC.Types.Var.Set
    
    ... ... @@ -123,12 +123,9 @@ import GHC.Unit.Module ( Module )
    123 123
     import GHC.Data.Bag         ( Bag, emptyBag, isEmptyBag, snocBag, bagToList )
    
    124 124
     
    
    125 125
     import Control.Monad
    
    126
    -import Data.Maybe
    
    127
    -import GHC.Utils.Misc
    
    128 126
     import GHC.Core.Multiplicity (scaledThing)
    
    129 127
     import GHC.Settings (Platform)
    
    130 128
     import GHC.Core.TyCon (primRepCompatible, primRepsCompatible)
    
    131
    -import GHC.Utils.Panic.Plain (panic)
    
    132 129
     
    
    133 130
     lintStgTopBindings :: forall a . (OutputablePass a, BinderP a ~ Id)
    
    134 131
                        => Platform
    
    ... ... @@ -174,36 +171,37 @@ lintStgTopBindings platform logger diag_opts opts extra_vars this_mod unarised w
    174 171
         lint_bind (StgTopStringLit v _) = return [v]
    
    175 172
     
    
    176 173
     lintStgConArg :: StgArg -> LintM ()
    
    177
    -lintStgConArg arg = do
    
    178
    -  unarised <- lf_unarised <$> getLintFlags
    
    179
    -  when unarised $ case stgArgRep_maybe arg of
    
    180
    -    -- Note [Post-unarisation invariants], invariant 4
    
    181
    -    Just [_] -> pure ()
    
    182
    -    badRep   -> addErrL $
    
    183
    -      text "Non-unary constructor arg: " <> ppr arg $$
    
    184
    -      text "Its PrimReps are: " <> ppr badRep
    
    185
    -
    
    186
    -  case arg of
    
    187
    -    StgLitArg _ -> pure ()
    
    188
    -    StgVarArg v -> lintStgVar v
    
    174
    +lintStgConArg arg
    
    175
    +  = do { lintStgArg arg
    
    176
    +
    
    177
    +       ; unarised <- lf_unarised <$> getLintFlags
    
    178
    +       ; when unarised $ case stgArgRep_maybe arg of
    
    179
    +           -- Note [Post-unarisation invariants], invariant 4
    
    180
    +           Just [_] -> pure ()
    
    181
    +           badRep   -> addErrL $
    
    182
    +             text "Non-unary constructor arg: " <> ppr arg $$
    
    183
    +             text "Its PrimReps are: " <> ppr badRep }
    
    189 184
     
    
    190 185
     lintStgFunArg :: StgArg -> LintM ()
    
    191
    -lintStgFunArg arg = do
    
    192
    -  unarised <- lf_unarised <$> getLintFlags
    
    193
    -  when unarised $ case stgArgRep_maybe arg of
    
    194
    -    -- Note [Post-unarisation invariants], invariant 3
    
    195
    -    Just []  -> pure ()
    
    196
    -    Just [_] -> pure ()
    
    197
    -    badRep   -> addErrL $
    
    198
    -      text "Function arg is not unary or void: " <> ppr arg $$
    
    199
    -      text "Its PrimReps are: " <> ppr badRep
    
    200
    -
    
    201
    -  case arg of
    
    202
    -    StgLitArg _ -> pure ()
    
    203
    -    StgVarArg v -> lintStgVar v
    
    204
    -
    
    205
    -lintStgVar :: Id -> LintM ()
    
    206
    -lintStgVar id = checkInScope id
    
    186
    +lintStgFunArg arg
    
    187
    +  = do { lintStgArg arg
    
    188
    +
    
    189
    +       ; unarised <- lf_unarised <$> getLintFlags
    
    190
    +       ; when unarised $ case stgArgRep_maybe arg of
    
    191
    +           -- Note [Post-unarisation invariants], invariant 3
    
    192
    +           Just []  -> pure ()
    
    193
    +           Just [_] -> pure ()
    
    194
    +           badRep   -> addErrL $
    
    195
    +             text "Function arg is not unary or void: " <> ppr arg $$
    
    196
    +             text "Its PrimReps are: " <> ppr badRep }
    
    197
    +
    
    198
    +lintStgArg :: StgArg -> LintM ()
    
    199
    +lintStgArg (StgLitArg _) = pure ()
    
    200
    +lintStgArg (StgVarArg v) = do { lintStgVarOcc v
    
    201
    +                              ; lintAppCbvMarks v [] }
    
    202
    +
    
    203
    +lintStgVarOcc :: Id -> LintM ()
    
    204
    +lintStgVarOcc id = checkInScope id
    
    207 205
     
    
    208 206
     lintStgBinds
    
    209 207
         :: (OutputablePass a, BinderP a ~ Id)
    
    ... ... @@ -275,13 +273,11 @@ lintStgExpr :: (OutputablePass a, BinderP a ~ Id) => GenStgExpr a -> LintM ()
    275 273
     
    
    276 274
     lintStgExpr (StgLit _) = return ()
    
    277 275
     
    
    278
    -lintStgExpr e@(StgApp fun args) = do
    
    279
    -  lintStgVar fun
    
    280
    -  mapM_ lintStgFunArg args
    
    281
    -  lintAppCbvMarks e
    
    282
    -  lintStgAppReps fun args
    
    283
    -
    
    284
    -
    
    276
    +lintStgExpr (StgApp fun args)
    
    277
    +  = do { lintStgVarOcc fun
    
    278
    +       ; mapM_ lintStgFunArg args
    
    279
    +       ; lintAppCbvMarks fun args
    
    280
    +       ; lintStgAppReps fun args }
    
    285 281
     
    
    286 282
     lintStgExpr app@(StgConApp con _n args _arg_tys) = do
    
    287 283
         -- unboxed sums should vanish during unarise
    
    ... ... @@ -413,22 +409,20 @@ lintStgAppReps fun args = do
    413 409
     
    
    414 410
       match_args actual_arg_reps fun_arg_tys_reps
    
    415 411
     
    
    416
    -lintAppCbvMarks :: OutputablePass pass
    
    417
    -                => GenStgExpr pass -> LintM ()
    
    418
    -lintAppCbvMarks e@(StgApp fun args) = do
    
    419
    -  lf <- getLintFlags
    
    420
    -  when (lf_unarised lf) $ do
    
    412
    +lintAppCbvMarks :: Id -> [StgArg] -> LintM ()
    
    413
    +lintAppCbvMarks fun args
    
    414
    +  | idCbvMarkArity fun > length args
    
    421 415
         -- A function which expects a unlifted argument as n'th argument
    
    422 416
         -- always needs to be applied to n arguments.
    
    423 417
         -- See Note [CBV Function Ids: overview].
    
    424
    -    let marks = fromMaybe [] $ idCbvMarks_maybe fun
    
    425
    -    when (length (dropWhileEndLE (not . isMarkedCbv) marks) > length args) $ do
    
    426
    -      addErrL $ hang (text "Undersatured cbv marked ID in App" <+> ppr e ) 2 $
    
    427
    -        (text "marks" <> ppr marks $$
    
    428
    -        text "args" <> ppr args $$
    
    429
    -        text "arity" <> ppr (idArity fun) $$
    
    430
    -        text "join_arity" <> ppr (idJoinPointHood fun))
    
    431
    -lintAppCbvMarks _ = panic "impossible - lintAppCbvMarks"
    
    418
    +  = addErrL $ hang (text "Undersatured cbv marked ID in App" <+> ppr fun)
    
    419
    +                 2 (vcat [ text "marks" <> ppr (idCbvMarks_maybe fun)
    
    420
    +                         , text "args" <> ppr args
    
    421
    +                         , text "arity" <> ppr (idArity fun)
    
    422
    +                         , text "join_arity" <> ppr (idJoinPointHood fun) ])
    
    423
    +
    
    424
    +  | otherwise
    
    425
    +  = return ()
    
    432 426
     
    
    433 427
     {-
    
    434 428
     ************************************************************************
    

  • compiler/GHC/Types/Id.hs
    ... ... @@ -852,7 +852,7 @@ idCbvMarks_maybe id = case idDetails id of
    852 852
       _                    -> Nothing
    
    853 853
     
    
    854 854
     -- Id must be called with at least this arity in order to allow arguments to
    
    855
    --- be passed unlifted.
    
    855
    +-- be passed unlifted.  Return 0 if there are no CBV marks.
    
    856 856
     idCbvMarkArity :: Id -> Arity
    
    857 857
     idCbvMarkArity fn = maybe 0 length (idCbvMarks_maybe fn)
    
    858 858
     
    

  • compiler/GHC/Types/Id/Info.hs
    ... ... @@ -210,6 +210,7 @@ data IdDetails
    210 210
             -- Can also work as a WorkerLikeId if given `CbvMark`s.
    
    211 211
             -- See Note [CBV Function Ids: overview]
    
    212 212
             -- The [CbvMark] is always empty (and ignored) until after Tidy.
    
    213
    +
    
    213 214
       | WorkerLikeId [CbvMark]
    
    214 215
             -- ^ An 'Id' for a worker like function, which might expect some arguments to be
    
    215 216
             -- passed both evaluated and tagged.
    
    ... ... @@ -217,8 +218,10 @@ data IdDetails
    217 218
             -- aren't used unapplied.
    
    218 219
             -- See Note [CBV Function Ids: overview]
    
    219 220
             -- See Note [EPT enforcement]
    
    220
    -        -- The [CbvMark] is always empty (and ignored) until after Tidy for ids from the current
    
    221
    -        -- module.
    
    221
    +        -- Invariants:
    
    222
    +        --   - the [CbvMark] is always empty (and ignored) until after Tidy
    
    223
    +        --     for ids from the current module
    
    224
    +        --   - If non-empty, at least is isMarkedCbbv; see (CBV2)
    
    222 225
     
    
    223 226
     data RecSelInfo
    
    224 227
       = RSI { rsi_def   :: [ConLike]   -- Record selector defined for these
    
    ... ... @@ -297,9 +300,7 @@ Here's how it all works:
    297 300
       to identify strict arguments.  See Note [Call-by-value for worker args] for
    
    298 301
       how a worker guarantees to be strict in strict datacon fields.
    
    299 302
     
    
    300
    -  TODO: We currently don't do this for arguments that are unboxed sums or tuples,
    
    301
    -  because then we'd have to predict the result of unarisation. But it would be nice to
    
    302
    -  do so. See `computeCbvInfo`.
    
    303
    +  See (CBV1) and (CBV2).
    
    303 304
     
    
    304 305
     * During CorePrep calls to CBV Ids are eta expanded.
    
    305 306
       See `GHC.CoreToStg.Prep.maybeSaturate`.
    
    ... ... @@ -319,6 +320,16 @@ Here's how it all works:
    319 320
     * Imported functions may be CBV, and then there is no point in eta-reducing
    
    320 321
       them; we'll just have to eta-expand later; see GHC.Core.Opt.Arity.cantEtaReduceFun.
    
    321 322
     
    
    323
    +Wrinkles
    
    324
    +
    
    325
    +(CBV1) We do not set the CBV-marks for a function that takes an unboxed sum or tuple,
    
    326
    +  as an argument, because then we'd have to predict the result of unarisation.
    
    327
    +  It would be nice to do so in future. See `computeCbvInfo`.
    
    328
    +
    
    329
    +(CBV2) We do not set CBV-marks if none of them are `isMarkedCbv`.  Why not?
    
    330
    +  Because if none are CBV then there is nothing special to do for this function;
    
    331
    +  in particular, we don't need to saturate its calls.  See `computeCbvInfo`.
    
    332
    +
    
    322 333
     *** SPJ really? Andreas? ****
    
    323 334
     We only use this for workers and specialized versions of SpecConstr
    
    324 335
     But we also check other functions during tidy and potentially turn some of them into
    

  • testsuite/tests/arityanal/should_compile/Arity01.stderr
    ... ... @@ -5,19 +5,19 @@ Result size of Tidy Core = {terms: 71, types: 43, coercions: 0, joins: 0/0}
    5 5
     -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
    
    6 6
     F1.f2 :: Integer
    
    7 7
     [GblId, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}]
    
    8
    -F1.f2 = GHC.Num.Integer.IS 1#
    
    8
    +F1.f2 = GHC.Internal.Bignum.Integer.IS 1#
    
    9 9
     
    
    10 10
     Rec {
    
    11 11
     -- RHS size: {terms: 24, types: 6, coercions: 0, joins: 0/0}
    
    12 12
     F1.f1_h1 [Occ=LoopBreaker] :: Integer -> Integer -> Integer -> Integer
    
    13 13
     [GblId, Arity=3, Str=<1L><1L><SL>, Unf=OtherCon []]
    
    14 14
     F1.f1_h1
    
    15
    -  = \ (n :: Integer) (x :: Integer) (eta [OS=OneShot] :: Integer) ->
    
    15
    +  = \ (n :: Integer) (x [OS=OneShot] :: Integer) (eta [OS=OneShot] :: Integer) ->
    
    16 16
           case x of x1 { __DEFAULT ->
    
    17 17
           case n of y1 { __DEFAULT ->
    
    18
    -      case GHC.Num.Integer.integerLt# x1 y1 of {
    
    18
    +      case GHC.Internal.Bignum.Integer.integerLt# x1 y1 of {
    
    19 19
             __DEFAULT -> eta;
    
    20
    -        1# -> F1.f1_h1 y1 (GHC.Num.Integer.integerAdd x1 F1.f2) (GHC.Num.Integer.integerAdd x1 eta)
    
    20
    +        1# -> F1.f1_h1 y1 (GHC.Internal.Bignum.Integer.integerAdd x1 F1.f2) (GHC.Internal.Bignum.Integer.integerAdd x1 eta)
    
    21 21
           }
    
    22 22
           }
    
    23 23
           }
    
    ... ... @@ -26,7 +26,7 @@ end Rec }
    26 26
     -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
    
    27 27
     F1.f3 :: Integer
    
    28 28
     [GblId, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}]
    
    29
    -F1.f3 = GHC.Num.Integer.IS 5#
    
    29
    +F1.f3 = GHC.Internal.Bignum.Integer.IS 5#
    
    30 30
     
    
    31 31
     -- RHS size: {terms: 4, types: 0, coercions: 0, joins: 0/0}
    
    32 32
     f1 :: Integer
    
    ... ... @@ -36,27 +36,27 @@ f1 = F1.f1_h1 F1.f3 F1.f2 F1.f3
    36 36
     -- RHS size: {terms: 14, types: 5, coercions: 0, joins: 0/0}
    
    37 37
     g :: Integer -> Integer -> Integer -> Integer -> Integer -> Integer
    
    38 38
     [GblId, Arity=5, Str=<1L><SL><SL><SL><SL>, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [0 0 0 0 0] 120 0}]
    
    39
    -g = \ (x1 :: Integer) (x2 :: Integer) (x3 :: Integer) (x4 :: Integer) (x5 :: Integer) -> GHC.Num.Integer.integerAdd (GHC.Num.Integer.integerAdd (GHC.Num.Integer.integerAdd (GHC.Num.Integer.integerAdd x1 x2) x3) x4) x5
    
    39
    +g = \ (x1 :: Integer) (x2 :: Integer) (x3 :: Integer) (x4 :: Integer) (x5 :: Integer) -> GHC.Internal.Bignum.Integer.integerAdd (GHC.Internal.Bignum.Integer.integerAdd (GHC.Internal.Bignum.Integer.integerAdd (GHC.Internal.Bignum.Integer.integerAdd x1 x2) x3) x4) x5
    
    40 40
     
    
    41 41
     -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
    
    42 42
     F1.s1 :: Integer
    
    43 43
     [GblId, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}]
    
    44
    -F1.s1 = GHC.Num.Integer.IS 3#
    
    44
    +F1.s1 = GHC.Internal.Bignum.Integer.IS 3#
    
    45 45
     
    
    46 46
     -- RHS size: {terms: 8, types: 7, coercions: 0, joins: 0/0}
    
    47 47
     s :: forall {t1} {t2}. Num t1 => (t1 -> t2) -> t2
    
    48
    -[GblId, Arity=2, Str=<MP(A,A,A,A,A,A,1C(1,L))><1C(1,L)>, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [30 60] 50 0}]
    
    48
    +[GblId, Arity=2, Str=<MP(A,A,A,A,A,A,1C(1,L))><1C(1,L)>, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [90 60] 50 0}]
    
    49 49
     s = \ (@t) (@t1) ($dNum :: Num t) (f :: t -> t1) -> f (fromInteger @t $dNum F1.s1)
    
    50 50
     
    
    51 51
     -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
    
    52 52
     F1.h1 :: Integer
    
    53 53
     [GblId, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}]
    
    54
    -F1.h1 = GHC.Num.Integer.IS 24#
    
    54
    +F1.h1 = GHC.Internal.Bignum.Integer.IS 24#
    
    55 55
     
    
    56 56
     -- RHS size: {terms: 4, types: 1, coercions: 0, joins: 0/0}
    
    57 57
     h :: Integer -> Integer
    
    58 58
     [GblId, Arity=1, Str=<SL>, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [0] 30 0}]
    
    59
    -h = \ (x5 :: Integer) -> GHC.Num.Integer.integerAdd F1.h1 x5
    
    59
    +h = \ (x5 :: Integer) -> GHC.Internal.Bignum.Integer.integerAdd F1.h1 x5
    
    60 60
     
    
    61 61
     
    
    62 62
     

  • testsuite/tests/arityanal/should_compile/Arity05.stderr
    ... ... @@ -5,27 +5,27 @@ Result size of Tidy Core = {terms: 42, types: 44, coercions: 0, joins: 0/0}
    5 5
     -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
    
    6 6
     F5.f5g1 :: Integer
    
    7 7
     [GblId, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}]
    
    8
    -F5.f5g1 = GHC.Num.Integer.IS 1#
    
    8
    +F5.f5g1 = GHC.Internal.Bignum.Integer.IS 1#
    
    9 9
     
    
    10 10
     -- RHS size: {terms: 12, types: 9, coercions: 0, joins: 0/0}
    
    11 11
     f5g :: forall {a} {t}. Num a => (t -> a) -> t -> a
    
    12
    -[GblId, Arity=3, Str=<SP(1C(1,C(1,L)),A,A,A,A,A,MC(1,L))><MC(1,L)><L>, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [60 60 0] 90 0}]
    
    12
    +[GblId, Arity=3, Str=<SP(1C(1,C(1,L)),A,A,A,A,A,MC(1,L))><MC(1,L)><L>, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [180 60 0] 90 0}]
    
    13 13
     f5g = \ (@a) (@t) ($dNum :: Num a) (h :: t -> a) (z :: t) -> + @a $dNum (h z) (fromInteger @a $dNum F5.f5g1)
    
    14 14
     
    
    15 15
     -- RHS size: {terms: 17, types: 12, coercions: 0, joins: 0/0}
    
    16 16
     f5h :: forall {a} {t}. Num a => (t -> a) -> t -> (t -> a) -> a
    
    17
    -[GblId, Arity=4, Str=<SP(SC(S,C(1,L)),A,A,A,A,A,MC(1,L))><MC(1,L)><L><MC(1,L)>, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [90 60 0 60] 150 0}]
    
    17
    +[GblId, Arity=4, Str=<SP(SC(S,C(1,L)),A,A,A,A,A,MC(1,L))><MC(1,L)><L><MC(1,L)>, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [270 60 0 60] 150 0}]
    
    18 18
     f5h = \ (@a) (@t) ($dNum :: Num a) (f :: t -> a) (x :: t) (g :: t -> a) -> + @a $dNum (f x) (+ @a $dNum (g x) (fromInteger @a $dNum F5.f5g1))
    
    19 19
     
    
    20 20
     -- RHS size: {terms: 4, types: 1, coercions: 0, joins: 0/0}
    
    21 21
     f5y :: Integer -> Integer
    
    22 22
     [GblId, Arity=1, Str=<1L>, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [0] 30 0}]
    
    23
    -f5y = \ (y :: Integer) -> GHC.Num.Integer.integerAdd y F5.f5g1
    
    23
    +f5y = \ (y :: Integer) -> GHC.Internal.Bignum.Integer.integerAdd y F5.f5g1
    
    24 24
     
    
    25 25
     -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
    
    26 26
     f5 :: Integer
    
    27 27
     [GblId, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}]
    
    28
    -f5 = GHC.Num.Integer.IS 3#
    
    28
    +f5 = GHC.Internal.Bignum.Integer.IS 3#
    
    29 29
     
    
    30 30
     
    
    31 31
     

  • testsuite/tests/arityanal/should_compile/Arity08.stderr
    ... ... @@ -4,7 +4,7 @@ Result size of Tidy Core = {terms: 24, types: 18, coercions: 0, joins: 0/0}
    4 4
     
    
    5 5
     -- RHS size: {terms: 20, types: 10, coercions: 0, joins: 0/0}
    
    6 6
     f8f :: forall {p}. Num p => Bool -> p -> p -> p
    
    7
    -[GblId, Arity=4, Str=<LP(SC(S,C(1,L)),A,MC(1,C(1,L)),A,A,A,A)><1L><L><L>, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [90 30 0 0] 140 0}]
    
    7
    +[GblId, Arity=4, Str=<LP(SC(S,C(1,L)),A,MC(1,C(1,L)),A,A,A,A)><1L><L><L>, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [270 30 0 0] 140 0}]
    
    8 8
     f8f
    
    9 9
       = \ (@p) ($dNum :: Num p) (b :: Bool) (x :: p) (y :: p) ->
    
    10 10
           case b of {
    
    ... ... @@ -15,7 +15,7 @@ f8f
    15 15
     -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
    
    16 16
     f8 :: Integer
    
    17 17
     [GblId, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}]
    
    18
    -f8 = GHC.Num.Integer.IS 2#
    
    18
    +f8 = GHC.Internal.Bignum.Integer.IS 2#
    
    19 19
     
    
    20 20
     
    
    21 21
     

  • testsuite/tests/arityanal/should_compile/Arity11.stderr
    ... ... @@ -5,57 +5,23 @@ Result size of Tidy Core = {terms: 136, types: 75, coercions: 0, joins: 2/7}
    5 5
     -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
    
    6 6
     F11.fib3 :: Integer
    
    7 7
     [GblId, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}]
    
    8
    -F11.fib3 = GHC.Num.Integer.IS 1#
    
    8
    +F11.fib3 = GHC.Internal.Bignum.Integer.IS 1#
    
    9 9
     
    
    10 10
     -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
    
    11 11
     F11.fib2 :: Integer
    
    12 12
     [GblId, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}]
    
    13
    -F11.fib2 = GHC.Num.Integer.IS 2#
    
    14
    -
    
    15
    -Rec {
    
    16
    --- RHS size: {terms: 38, types: 13, coercions: 0, joins: 2/2}
    
    17
    -F11.f11_fib [Occ=LoopBreaker] :: Integer -> Integer
    
    18
    -[GblId, Arity=1, Str=<SL>, Unf=OtherCon []]
    
    19
    -F11.f11_fib
    
    20
    -  = \ (ds :: Integer) ->
    
    21
    -      join {
    
    22
    -        $j [Dmd=ML] :: Integer
    
    23
    -        [LclId[JoinId(0)(Nothing)]]
    
    24
    -        $j
    
    25
    -          = join {
    
    26
    -              $j1 [Dmd=ML] :: Integer
    
    27
    -              [LclId[JoinId(0)(Nothing)]]
    
    28
    -              $j1 = GHC.Num.Integer.integerAdd (F11.f11_fib (GHC.Num.Integer.integerSub ds F11.fib3)) (F11.f11_fib (GHC.Num.Integer.integerSub ds F11.fib2)) } in
    
    29
    -            case ds of {
    
    30
    -              GHC.Num.Integer.IS x1 ->
    
    31
    -                case x1 of {
    
    32
    -                  __DEFAULT -> jump $j1;
    
    33
    -                  1# -> F11.fib3
    
    34
    -                };
    
    35
    -              GHC.Num.Integer.IP x1 -> jump $j1;
    
    36
    -              GHC.Num.Integer.IN x1 -> jump $j1
    
    37
    -            } } in
    
    38
    -      case ds of {
    
    39
    -        GHC.Num.Integer.IS x1 ->
    
    40
    -          case x1 of {
    
    41
    -            __DEFAULT -> jump $j;
    
    42
    -            0# -> F11.fib3
    
    43
    -          };
    
    44
    -        GHC.Num.Integer.IP x1 -> jump $j;
    
    45
    -        GHC.Num.Integer.IN x1 -> jump $j
    
    46
    -      }
    
    47
    -end Rec }
    
    13
    +F11.fib2 = GHC.Internal.Bignum.Integer.IS 2#
    
    48 14
     
    
    49 15
     -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
    
    50 16
     F11.fib1 :: Integer
    
    51 17
     [GblId, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}]
    
    52
    -F11.fib1 = GHC.Num.Integer.IS 0#
    
    18
    +F11.fib1 = GHC.Internal.Bignum.Integer.IS 0#
    
    53 19
     
    
    54 20
     -- RHS size: {terms: 54, types: 27, coercions: 0, joins: 0/5}
    
    55
    -fib :: forall {t} {a}. (Eq t, Num t, Num a) => t -> a
    
    56
    -[GblId, Arity=4, Str=<SP(SC(S,C(1,L)),A)><LP(A,LC(L,C(1,L)),A,A,A,A,L)><LP(LC(S,C(1,L)),A,A,A,A,A,MC(1,L))><L>, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [60 150 60 0] 480 0}]
    
    21
    +fib :: forall {t1} {t2}. (Eq t1, Num t1, Num t2) => t1 -> t2
    
    22
    +[GblId, Arity=4, Str=<SP(SC(S,C(1,L)),A)><LP(A,LC(L,C(1,L)),A,A,A,A,L)><LP(LC(S,C(1,L)),A,A,A,A,A,MC(1,L))><L>, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [180 450 180 0] 480 0}]
    
    57 23
     fib
    
    58
    -  = \ (@t) (@a) ($dEq :: Eq t) ($dNum :: Num t) ($dNum1 :: Num a) (eta :: t) ->
    
    24
    +  = \ (@t) (@t1) ($dEq :: Eq t) ($dNum :: Num t) ($dNum1 :: Num t1) (eta :: t) ->
    
    59 25
           let {
    
    60 26
             lvl :: t
    
    61 27
             [LclId]
    
    ... ... @@ -65,32 +31,66 @@ fib
    65 31
             [LclId]
    
    66 32
             lvl1 = fromInteger @t $dNum F11.fib2 } in
    
    67 33
           let {
    
    68
    -        lvl2 :: a
    
    34
    +        lvl2 :: t1
    
    69 35
             [LclId]
    
    70
    -        lvl2 = fromInteger @a $dNum1 F11.fib3 } in
    
    36
    +        lvl2 = fromInteger @t1 $dNum1 F11.fib3 } in
    
    71 37
           let {
    
    72 38
             lvl3 :: t
    
    73 39
             [LclId]
    
    74 40
             lvl3 = fromInteger @t $dNum F11.fib1 } in
    
    75 41
           letrec {
    
    76
    -        fib4 [Occ=LoopBreaker, Dmd=SC(S,L)] :: t -> a
    
    42
    +        fib4 [Occ=LoopBreaker, Dmd=SC(S,L)] :: t -> t1
    
    77 43
             [LclId, Arity=1, Str=<L>, Unf=OtherCon []]
    
    78 44
             fib4
    
    79 45
               = \ (ds :: t) ->
    
    80 46
                   case == @t $dEq ds lvl3 of {
    
    81 47
                     False ->
    
    82 48
                       case == @t $dEq ds lvl of {
    
    83
    -                    False -> + @a $dNum1 (fib4 (- @t $dNum ds lvl)) (fib4 (- @t $dNum ds lvl1));
    
    49
    +                    False -> + @t1 $dNum1 (fib4 (- @t $dNum ds lvl)) (fib4 (- @t $dNum ds lvl1));
    
    84 50
                         True -> lvl2
    
    85 51
                       };
    
    86 52
                     True -> lvl2
    
    87 53
                   }; } in
    
    88 54
           fib4 eta
    
    89 55
     
    
    56
    +Rec {
    
    57
    +-- RHS size: {terms: 38, types: 13, coercions: 0, joins: 2/2}
    
    58
    +F11.f11_fib [Occ=LoopBreaker] :: Integer -> Integer
    
    59
    +[GblId, Arity=1, Str=<SL>, Unf=OtherCon []]
    
    60
    +F11.f11_fib
    
    61
    +  = \ (ds :: Integer) ->
    
    62
    +      join {
    
    63
    +        $j [Dmd=ML] :: Integer
    
    64
    +        [LclId[JoinId(0)(Nothing)]]
    
    65
    +        $j
    
    66
    +          = join {
    
    67
    +              $j1 [Dmd=ML] :: Integer
    
    68
    +              [LclId[JoinId(0)(Nothing)]]
    
    69
    +              $j1 = GHC.Internal.Bignum.Integer.integerAdd (F11.f11_fib (GHC.Internal.Bignum.Integer.integerSub ds F11.fib3)) (F11.f11_fib (GHC.Internal.Bignum.Integer.integerSub ds F11.fib2)) } in
    
    70
    +            case ds of {
    
    71
    +              GHC.Internal.Bignum.Integer.IS x ->
    
    72
    +                case x of {
    
    73
    +                  __DEFAULT -> jump $j1;
    
    74
    +                  1# -> F11.fib3
    
    75
    +                };
    
    76
    +              GHC.Internal.Bignum.Integer.IP x -> jump $j1;
    
    77
    +              GHC.Internal.Bignum.Integer.IN x -> jump $j1
    
    78
    +            } } in
    
    79
    +      case ds of {
    
    80
    +        GHC.Internal.Bignum.Integer.IS x ->
    
    81
    +          case x of {
    
    82
    +            __DEFAULT -> jump $j;
    
    83
    +            0# -> F11.fib3
    
    84
    +          };
    
    85
    +        GHC.Internal.Bignum.Integer.IP x -> jump $j;
    
    86
    +        GHC.Internal.Bignum.Integer.IN x -> jump $j
    
    87
    +      }
    
    88
    +end Rec }
    
    89
    +
    
    90 90
     -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
    
    91 91
     F11.f3 :: Integer
    
    92 92
     [GblId, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}]
    
    93
    -F11.f3 = GHC.Num.Integer.IS 1000#
    
    93
    +F11.f3 = GHC.Internal.Bignum.Integer.IS 1000#
    
    94 94
     
    
    95 95
     -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
    
    96 96
     F11.f11_x :: Integer
    
    ... ... @@ -100,7 +100,7 @@ F11.f11_x = F11.f11_fib F11.f3
    100 100
     -- RHS size: {terms: 4, types: 1, coercions: 0, joins: 0/0}
    
    101 101
     F11.f11f1 :: Integer -> Integer
    
    102 102
     [GblId, Arity=1, Str=<SL>, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [0] 30 0}]
    
    103
    -F11.f11f1 = \ (y :: Integer) -> GHC.Num.Integer.integerAdd F11.f11_x y
    
    103
    +F11.f11f1 = \ (y :: Integer) -> GHC.Internal.Bignum.Integer.integerAdd F11.f11_x y
    
    104 104
     
    
    105 105
     -- RHS size: {terms: 3, types: 2, coercions: 0, joins: 0/0}
    
    106 106
     f11f :: forall {p}. p -> Integer -> Integer
    
    ... ... @@ -110,22 +110,22 @@ f11f = \ (@p) _ [Occ=Dead] -> F11.f11f1
    110 110
     -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
    
    111 111
     F11.f5 :: Integer
    
    112 112
     [GblId, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}]
    
    113
    -F11.f5 = GHC.Num.Integer.IS 6#
    
    113
    +F11.f5 = GHC.Internal.Bignum.Integer.IS 6#
    
    114 114
     
    
    115 115
     -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0}
    
    116 116
     F11.f4 :: Integer
    
    117 117
     [GblId, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=False, ConLike=False, WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 30 0}]
    
    118
    -F11.f4 = GHC.Num.Integer.integerAdd F11.f11_x F11.f5
    
    118
    +F11.f4 = GHC.Internal.Bignum.Integer.integerAdd F11.f11_x F11.f5
    
    119 119
     
    
    120 120
     -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
    
    121 121
     F11.f2 :: Integer
    
    122 122
     [GblId, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}]
    
    123
    -F11.f2 = GHC.Num.Integer.IS 8#
    
    123
    +F11.f2 = GHC.Internal.Bignum.Integer.IS 8#
    
    124 124
     
    
    125 125
     -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0}
    
    126 126
     F11.f1 :: Integer
    
    127 127
     [GblId, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=False, ConLike=False, WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 30 0}]
    
    128
    -F11.f1 = GHC.Num.Integer.integerAdd F11.f11_x F11.f2
    
    128
    +F11.f1 = GHC.Internal.Bignum.Integer.integerAdd F11.f11_x F11.f2
    
    129 129
     
    
    130 130
     -- RHS size: {terms: 3, types: 2, coercions: 0, joins: 0/0}
    
    131 131
     f11 :: (Integer, Integer)
    
    ... ... @@ -133,7 +133,4 @@ f11 :: (Integer, Integer)
    133 133
     f11 = (F11.f4, F11.f1)
    
    134 134
     
    
    135 135
     
    
    136
    ------- Local rules for imported ids --------
    
    137
    -"SPEC fib @Integer @Integer" forall ($dEq :: Eq Integer) ($dNum :: Num Integer) ($dNum1 :: Num Integer). fib @Integer @Integer $dEq $dNum $dNum1 = F11.f11_fib
    
    138
    -
    
    139 136
     

  • testsuite/tests/arityanal/should_compile/Arity14.stderr
    ... ... @@ -3,18 +3,18 @@
    3 3
     Result size of Tidy Core = {terms: 44, types: 38, coercions: 0, joins: 0/3}
    
    4 4
     
    
    5 5
     -- RHS size: {terms: 3, types: 2, coercions: 0, joins: 0/0}
    
    6
    -F14.f1 :: forall {t}. t -> t
    
    6
    +F14.f1 :: forall t. t -> t
    
    7 7
     [GblId, Arity=1, Str=<1L>, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=1,unsat_ok=True,boring_ok=True)}]
    
    8 8
     F14.f1 = \ (@t) (y :: t) -> y
    
    9 9
     
    
    10 10
     -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0}
    
    11 11
     F14.f2 :: Integer
    
    12 12
     [GblId, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 10}]
    
    13
    -F14.f2 = GHC.Num.Integer.IS 1#
    
    13
    +F14.f2 = GHC.Internal.Bignum.Integer.IS 1#
    
    14 14
     
    
    15 15
     -- RHS size: {terms: 36, types: 23, coercions: 0, joins: 0/3}
    
    16 16
     f14 :: forall {t}. (Ord t, Num t) => t -> t -> t -> t
    
    17
    -[GblId, Arity=4, Str=<SP(A,A,SC(S,C(1,L)),A,A,A,A,A)><LP(LC(L,C(1,L)),A,A,A,A,A,MC(1,L))><L><L>, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [30 90 0 0] 310 0}]
    
    17
    +[GblId, Arity=4, Str=<SP(A,A,SC(S,C(1,L)),A,A,A,A,A)><LP(LC(L,C(1,L)),A,A,A,A,A,MC(1,L))><L><L>, Unf=Unf{Src=<vanilla>, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [90 270 0 0] 310 0}]
    
    18 18
     f14
    
    19 19
       = \ (@t) ($dOrd :: Ord t) ($dNum :: Num t) (eta :: t) (eta1 :: t) ->
    
    20 20
           let {
    
    ... ... @@ -25,7 +25,7 @@ f14
    25 25
             f3 [Occ=LoopBreaker, Dmd=SC(S,C(1,L))] :: t -> t -> t -> t
    
    26 26
             [LclId, Arity=2, Str=<L><L>, Unf=OtherCon []]
    
    27 27
             f3
    
    28
    -          = \ (n :: t) (x :: t) ->
    
    28
    +          = \ (n :: t) (x [OS=OneShot] :: t) ->
    
    29 29
                   case < @t $dOrd x n of {
    
    30 30
                     False -> F14.f1 @t;
    
    31 31
                     True ->
    

  • testsuite/tests/perf/compiler/T13960.hs
    1
    +{-# LANGUAGE OverloadedStrings #-}
    
    2
    +
    
    3
    +-- GHC used to run out of simplifier ticks due to inlining the internals of
    
    4
    +-- `toStrict . toLazyByteString`.
    
    5
    +module T13960 (breaks) where
    
    6
    +
    
    7
    +import Data.ByteString (ByteString)
    
    8
    +import Data.ByteString.Builder (Builder, stringUtf8, toLazyByteString)
    
    9
    +import Data.ByteString.Lazy (toStrict)
    
    10
    +import Data.String (IsString(..))
    
    11
    +
    
    12
    +newtype Query = Query ByteString
    
    13
    +
    
    14
    +toByteString :: Builder -> ByteString
    
    15
    +toByteString x = toStrict (toLazyByteString x)
    
    16
    +
    
    17
    +instance IsString Query where
    
    18
    +  fromString = Query . toByteString . stringUtf8
    
    19
    +
    
    20
    +breaks :: [(Query, Query)]
    
    21
    +breaks =
    
    22
    +  [ ("query001a", "query001b")
    
    23
    +  , ("query002a", "query002b")
    
    24
    +  , ("query003a", "query003b")
    
    25
    +  , ("query004a", "query004b")
    
    26
    +  , ("query005a", "query005b")
    
    27
    +  , ("query006a", "query006b")
    
    28
    +  , ("query007a", "query007b")
    
    29
    +  , ("query008a", "query008b")
    
    30
    +  , ("query009a", "query009b")
    
    31
    +  , ("query010a", "query010b")
    
    32
    +  , ("query011a", "query011b")
    
    33
    +  , ("query012a", "query012b")
    
    34
    +  , ("query013a", "query013b")
    
    35
    +  , ("query014a", "query014b")
    
    36
    +  , ("query015a", "query015b")
    
    37
    +  , ("query016a", "query016b")
    
    38
    +  , ("query017a", "query017b")
    
    39
    +  , ("query018a", "query018b")
    
    40
    +  , ("query019a", "query019b")
    
    41
    +  , ("query020a", "query020b")
    
    42
    +  , ("query021a", "query021b")
    
    43
    +  , ("query022a", "query022b")
    
    44
    +  , ("query023a", "query023b")
    
    45
    +  , ("query024a", "query024b")
    
    46
    +  , ("query025a", "query025b")
    
    47
    +  , ("query026a", "query026b")
    
    48
    +  , ("query027a", "query027b")
    
    49
    +  , ("query028a", "query028b")
    
    50
    +  , ("query029a", "query029b")
    
    51
    +  , ("query030a", "query030b")
    
    52
    +  , ("query031a", "query031b")
    
    53
    +  , ("query032a", "query032b")
    
    54
    +  , ("query033a", "query033b")
    
    55
    +  , ("query034a", "query034b")
    
    56
    +  , ("query035a", "query035b")
    
    57
    +  , ("query036a", "query036b")
    
    58
    +  , ("query037a", "query037b")
    
    59
    +  , ("query038a", "query038b")
    
    60
    +  , ("query039a", "query039b")
    
    61
    +  , ("query040a", "query040b")
    
    62
    +  , ("query041a", "query041b")
    
    63
    +  , ("query042a", "query042b")
    
    64
    +  , ("query043a", "query043b")
    
    65
    +  , ("query044a", "query044b")
    
    66
    +  , ("query045a", "query045b")
    
    67
    +  , ("query046a", "query046b")
    
    68
    +  , ("query047a", "query047b")
    
    69
    +  , ("query048a", "query048b")
    
    70
    +  , ("query049a", "query049b")
    
    71
    +  , ("query050a", "query050b")
    
    72
    +  ]

  • testsuite/tests/perf/compiler/all.T
    ... ... @@ -686,6 +686,12 @@ test ('T13820',
    686 686
           ],
    
    687 687
           compile,
    
    688 688
           ['-v0'])
    
    689
    +test ('T13960',
    
    690
    +      [ collect_compiler_stats('peak_megabytes_allocated', 20),
    
    691
    +        collect_compiler_stats('bytes allocated', 2),
    
    692
    +      ],
    
    693
    +      compile,
    
    694
    +      ['-O'])
    
    689 695
     test ('T14766',
    
    690 696
           [ collect_compiler_stats('bytes allocated',2),
    
    691 697
             pre_cmd('python3 genT14766.py > T14766.hs'),
    

  • testsuite/tests/simplCore/should_compile/T15205.stderr
    ... ... @@ -10,7 +10,7 @@ f :: forall a b. C a b => a -> b
    10 10
      Str=<1P(A,1C(1,C(1,L)))><L>,
    
    11 11
      Unf=Unf{Src=<vanilla>, TopLvl=True,
    
    12 12
              Value=True, ConLike=True, WorkFree=True, Expandable=True,
    
    13
    -         Guidance=IF_ARGS [30 0] 40 0}]
    
    13
    +         Guidance=IF_ARGS [90 0] 40 0}]
    
    14 14
     f = \ (@a) (@b) ($dC :: C a b) (x :: a) -> op @a @b $dC x x
    
    15 15
     
    
    16 16
     
    

  • testsuite/tests/wasm/should_run/control-flow/LoadCmmGroup.hs
    ... ... @@ -91,12 +91,17 @@ stgify :: ModSummary -> ModGuts -> Ghc [StgTopBinding]
    91 91
     stgify summary guts = do
    
    92 92
         hsc_env <- getSession
    
    93 93
         let dflags = hsc_dflags hsc_env
    
    94
    -    prepd_binds <- liftIO $ do
    
    94
    +    liftIO $ do
    
    95 95
           cp_cfg <- initCorePrepConfig hsc_env
    
    96
    -      corePrepPgm (hsc_logger hsc_env) cp_cfg (initCorePrepPgmConfig dflags (interactiveInScope $ hsc_IC hsc_env)) this_mod core_binds
    
    97
    -    return $ fstOf3 $ coreToStg (initCoreToStgOpts dflags) (ms_mod summary) (ms_location summary) prepd_binds
    
    98
    -  where this_mod = mg_module guts
    
    99
    -        core_binds = mg_binds guts
    
    96
    +      prepd_binds <- corePrepPgm (hsc_logger hsc_env) cp_cfg
    
    97
    +                       (initCorePrepPgmConfig dflags (interactiveInScope $ hsc_IC hsc_env))
    
    98
    +                       this_mod core_binds
    
    99
    +      (binds, _, _) <- coreToStg (initCoreToStgOpts dflags) (ms_mod summary)
    
    100
    +                                 (ms_location summary) prepd_binds
    
    101
    +      return binds
    
    102
    +  where
    
    103
    +    this_mod = mg_module guts
    
    104
    +    core_binds = mg_binds guts
    
    100 105
     
    
    101 106
     slurpCmm :: HscEnv -> FilePath -> IO (CmmGroup)
    
    102 107
     slurpCmm hsc_env filename = runHsc hsc_env $ do