Simon Peyton Jones pushed to branch wip/T23109 at Glasgow Haskell Compiler / GHC

Commits:

3 changed files:

Changes:

  • compiler/GHC/Core/TyCon.hs
    ... ... @@ -1506,6 +1506,10 @@ There are a number of wrinkles
    1506 1506
           guide inlining) treats (MkUC e) as the same size as `e`, and similarly
    
    1507 1507
           (op d).
    
    1508 1508
     
    
    1509
    +    - `GHC.Core.Unfold.inlineBoringOK` where we want to ensure that we
    
    1510
    +      always-inline (MkUC op), even into a boring context. See (IB6)
    
    1511
    +      in Note [inlineBoringOk]
    
    1512
    +
    
    1509 1513
     (UCM5) `GHC.Core.Unfold.Make.mkDFunUnfolding` builds a `DFunUnfolding` for
    
    1510 1514
        non-unary classes, but just an /ordinary/ unfolding for unary classes.
    
    1511 1515
            instance Num a => Num [a] where { .. }       -- (I1)
    

  • compiler/GHC/Core/Unfold.hs
    ... ... @@ -278,6 +278,14 @@ inlining a saturated call is no bigger than `body`. Some wrinkles:
    278 278
       whose body is, in some sense, just as small as (g x y z).
    
    279 279
       But `inlineBoringOk` doesn't attempt anything fancy; it just looks
    
    280 280
       for a function call with trivial arguments, Keep it simple.
    
    281
    +
    
    282
    +(IB6) If we have an unfolding (K op) where K is a unary-class data constructor,
    
    283
    +  we want to inline it!  So that we get calls (f op), which in turn can see (in
    
    284
    +  STG land) that `op` is already evaluated and properly tagged. (If `op` isn't
    
    285
    +  trivial we will have baled out before we get to the Var case.)  This made
    
    286
    +  a big difference in benchmarks for the `effectful` library; details in !10479.
    
    287
    +
    
    288
    +  See Note [Unary class magic] in GHC/Core/TyCon.
    
    281 289
     -}
    
    282 290
     
    
    283 291
     inlineBoringOk :: CoreExpr -> Bool
    
    ... ... @@ -291,6 +299,7 @@ inlineBoringOk e
    291 299
         is_fun = isValFun e
    
    292 300
     
    
    293 301
         go :: Int -> CoreExpr -> Bool
    
    302
    +    -- credit = #(value lambdas) = #(value args)
    
    294 303
         go credit (Lam x e) | isRuntimeVar x  = go (credit+1) e
    
    295 304
                             | otherwise       = go credit e      -- See (IB3)
    
    296 305
     
    
    ... ... @@ -309,13 +318,15 @@ inlineBoringOk e
    309 318
         go credit (Tick _ e) = go credit e      -- dubious
    
    310 319
         go credit (Cast e _) = go credit e      -- See (IB3)
    
    311 320
     
    
    321
    +    -- Lit: we assume credit >= 0; literals aren't functions
    
    312 322
         go _      (Lit l)    = litIsTrivial l && boringCxtOk
    
    313 323
     
    
    314
    -      -- We assume credit >= 0; literals aren't functions
    
    315 324
         go credit (Var v) | isDataConWorkId v, is_fun = boringCxtOk  -- See (IB2)
    
    325
    +                      | isUnaryClassId v          = boringCxtOk  -- See (IB6)
    
    316 326
                           | credit >= 0               = boringCxtOk
    
    317 327
                           | otherwise                 = boringCxtNotOk
    
    318
    -    go _      _                                   = boringCxtNotOk
    
    328
    +
    
    329
    +    go _ _ = boringCxtNotOk
    
    319 330
     
    
    320 331
     isValFun :: CoreExpr -> Bool
    
    321 332
     -- True of functions with at least
    

  • compiler/GHC/CoreToStg.hs
    ... ... @@ -836,19 +836,20 @@ myCollectArgs expr res_ty
    836 836
       where
    
    837 837
         go h@(Var f) as ts
    
    838 838
           | isUnaryClassId f, (the_arg:as') <- dropWhile isTypeArg as
    
    839
    -                              = go the_arg as' ts
    
    839
    +      = go the_arg as' ts
    
    840 840
             -- See (UCM1) in Note [Unary class magic] in GHC.Core.TyCon
    
    841 841
             -- isUnaryClassId includes both the class op and the data-con
    
    842
    -      | otherwise             = (h, as, ts)
    
    843 842
     
    
    844
    -    go (App f a)        as ts = go f (a:as) ts
    
    845
    -    go (Cast e _)       as ts = go e as ts
    
    843
    +      | otherwise
    
    844
    +      = (h, as, ts)
    
    846 845
     
    
    847
    -    go (Tick t e)       as ts = assertPpr (not (tickishIsCode t) || all isTypeArg as)
    
    848
    -                                          (ppr e $$ ppr as $$ ppr ts) $
    
    849
    -                                -- See Note [Ticks in applications]
    
    850
    -                                -- ticks can appear in type apps
    
    851
    -                                go e as (coreToStgTick res_ty t : ts)
    
    846
    +    go (App f a)  as ts = go f (a:as) ts
    
    847
    +    go (Cast e _) as ts = go e as ts
    
    848
    +    go (Tick t e) as ts = assertPpr (not (tickishIsCode t) || all isTypeArg as)
    
    849
    +                                    (ppr e $$ ppr as $$ ppr ts) $
    
    850
    +                          -- See Note [Ticks in applications]
    
    851
    +                          -- ticks can appear in type apps
    
    852
    +                          go e as (coreToStgTick res_ty t : ts)
    
    852 853
     
    
    853 854
         go (Case e b _ alts) as ts  -- Just like in exprIsTrivial!
    
    854 855
                                     -- Otherwise we fall over in case we encounter
    
    ... ... @@ -859,10 +860,11 @@ myCollectArgs expr res_ty
    859 860
            | Just rhs <- isUnsafeEqualityCase e b alts
    
    860 861
            = go rhs as ts         -- Discards unsafeCoerce in App heads
    
    861 862
     
    
    862
    -    go (Lam b e)        as ts
    
    863
    -       | isTyVar b            = go e (drop 1 as) ts -- Note [Collect args]
    
    863
    +    go (Lam b e) as ts
    
    864
    +       | isTyVar b
    
    865
    +       = go e (drop 1 as) ts -- Note [Collect args]
    
    864 866
     
    
    865
    -    go e                as ts = (e, as, ts)
    
    867
    +    go e as ts = (e, as, ts)
    
    866 868
     
    
    867 869
     {- Note [Collect args]
    
    868 870
     ~~~~~~~~~~~~~~~~~~~~~~