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

Commits:

2 changed files:

Changes:

  • 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,6 +51,7 @@ 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
     
    
    ... ... @@ -239,107 +242,98 @@ import Control.Monad (ap)
    239 242
     -- --------------------------------------------------------------
    
    240 243
     
    
    241 244
     
    
    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)
    
    245
    +coreToStg :: CoreToStgOpts -> Module -> ModLocation
    
    246
    +          -> CoreProgram
    
    247
    +          -> IO ([StgTopBinding], InfoTableProvMap, CollectedCCs)
    
    248
    +coreToStg opts this_mod ml pgm
    
    249
    +  = do { us <- mkSplitUniqSupply StgTag
    
    250
    +       ; let (_, (local_ccs, local_cc_stacks), pgm')
    
    251
    +                = initCts opts us $
    
    252
    +                  coreTopBindsToStg opts this_mod emptyCollectedCCs pgm
    
    253
    +
    
    254
    +             -- See Note [Mapping Info Tables to Source Positions]
    
    255
    +             (!pgm'', !denv)
    
    256
    +               | opt_InfoTableMap
    
    257
    +               = collectDebugInformation stgDebugOpts ml pgm'
    
    258
    +               | otherwise = (pgm', emptyInfoTableProvMap)
    
    259
    +
    
    260
    +             final_ccs
    
    261
    +               | prof && opt_AutoSccsOnIndividualCafs
    
    262
    +               = (local_ccs,local_cc_stacks)  -- don't need "all CAFs" CC
    
    263
    +               | prof
    
    264
    +               = (all_cafs_cc:local_ccs, all_cafs_ccs:local_cc_stacks)
    
    265
    +               | otherwise
    
    266
    +               = emptyCollectedCCs
    
    267
    +
    
    268
    +      ; return (pgm'', denv, final_ccs) }
    
    251 269
       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)
    
    270
    +    CoreToStgOpts { coreToStg_ways = ways
    
    271
    +                  , coreToStg_AutoSccsOnIndividualCafs = opt_AutoSccsOnIndividualCafs
    
    272
    +                  , coreToStg_InfoTableMap = opt_InfoTableMap
    
    273
    +                  , coreToStg_stgDebugOpts = stgDebugOpts }
    
    274
    +       = opts
    
    260 275
     
    
    261 276
         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 277
         (all_cafs_cc, all_cafs_ccs) = getAllCAFsCC this_mod
    
    272 278
     
    
    273 279
     coreTopBindsToStg
    
    274 280
         :: CoreToStgOpts
    
    275 281
         -> Module
    
    276
    -    -> IdEnv HowBound           -- environment for the bindings
    
    277 282
         -> CollectedCCs
    
    278 283
         -> CoreProgram
    
    279
    -    -> (IdEnv HowBound, CollectedCCs, [StgTopBinding])
    
    284
    +    -> CtsM (IdEnv HowBound, CollectedCCs, [StgTopBinding])
    
    285
    +
    
    286
    +coreTopBindsToStg _ _ ccs []
    
    287
    +  = do { env <- getCtsEnv
    
    288
    +       ; return (env, ccs, []) }
    
    280 289
     
    
    281
    -coreTopBindsToStg _      _        env ccs []
    
    282
    -  = (env, ccs, [])
    
    283
    -coreTopBindsToStg opts this_mod env ccs (b:bs)
    
    290
    +coreTopBindsToStg opts this_mod ccs (b:bs)
    
    284 291
       | NonRec _ rhs <- b, isTyCoArg rhs
    
    285
    -  = coreTopBindsToStg opts this_mod env1 ccs1 bs
    
    292
    +  = coreTopBindsToStg opts this_mod ccs bs
    
    286 293
       | 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
    
    294
    +  = do { (env1, ccs1, b' ) <- coreTopBindToStg opts this_mod ccs b
    
    295
    +       ; (env2, ccs2, bs') <- setCtsEnv env1 $
    
    296
    +                              coreTopBindsToStg opts this_mod ccs1 bs
    
    297
    +      ; return (env2, ccs2, b':bs') }
    
    291 298
     
    
    292 299
     coreTopBindToStg
    
    293 300
             :: CoreToStgOpts
    
    294 301
             -> Module
    
    295
    -        -> IdEnv HowBound
    
    296 302
             -> CollectedCCs
    
    297 303
             -> CoreBind
    
    298
    -        -> (IdEnv HowBound, CollectedCCs, StgTopBinding)
    
    304
    +        -> CtsM (IdEnv HowBound, CollectedCCs, StgTopBinding)
    
    299 305
     
    
    300
    -coreTopBindToStg _ _ env ccs (NonRec id e)
    
    306
    +coreTopBindToStg _ _ ccs (NonRec id e)
    
    301 307
       | Just str <- exprIsTickedString_maybe e
    
    302 308
       -- top-level string literal
    
    303 309
       -- 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)
    
    310
    +  = do { env <- getCtsEnv
    
    311
    +       ; let env' = extendVarEnv env id how_bound
    
    312
    +             how_bound = LetBound TopLet 0
    
    313
    +       ; return (env', ccs, StgTopStringLit id str) }
    
    314
    +
    
    315
    +coreTopBindToStg opts this_mod ccs (NonRec id rhs)
    
    316
    +  = do { (ccs', (id', stg_rhs)) <- coreToTopStgRhs opts this_mod ccs (id,rhs)
    
    317
    +
    
    318
    +       ; env <- getCtsEnv
    
    319
    +       ; let env'      = extendVarEnv env id how_bound
    
    320
    +             how_bound = LetBound TopLet $! manifestArity rhs
    
    321
    +             bind      = StgTopLifted $ StgNonRec id' stg_rhs
    
    322
    +       ; return (env', ccs', bind) }
    
    323
    +
    
    324
    +coreTopBindToStg opts this_mod ccs (Rec pairs)
    
    331 325
       = 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)
    
    326
    +    do { env <- getCtsEnv
    
    327
    +       ; let extra_env' = [ (b, LetBound TopLet $! manifestArity rhs)
    
    328
    +                          | (b, rhs) <- pairs ]
    
    329
    +             env' = extendVarEnvList env extra_env'
    
    330
    +
    
    331
    +       -- Generate StgTopBindings and CAF cost centres created for CAFs
    
    332
    +       ; (ccs', stg_rhss) <- setCtsEnv env' $
    
    333
    +                             mapAccumLM (coreToTopStgRhs opts this_mod) ccs pairs
    
    334
    +       ; let bind = StgTopLifted $ StgRec stg_rhss
    
    335
    +
    
    336
    +       ; return (env', ccs', bind) }
    
    343 337
     
    
    344 338
     coreToTopStgRhs
    
    345 339
             :: CoreToStgOpts
    
    ... ... @@ -426,16 +420,17 @@ coreToStgExpr expr@(Lam {})
    426 420
       | otherwise
    
    427 421
       = do { body' <- extendVarEnvCts [ (a, LambdaBound) | a <- val_bndrs ] $
    
    428 422
                       coreToStgExpr body
    
    423
    +       ; uniq <- getCtsUnique
    
    429 424
            ; let body_ty = exprType body
    
    430
    -             fun_ty  = mkLamTypes bndrs body_ty
    
    425
    +             fun_ty  = mkLamTypes val_bndrs body_ty
    
    426
    +                       -- This type is a bit ill-formed but it doesn't matter
    
    431 427
                  rhs = StgRhsClosure noExtFieldSilent currentCCS
    
    432 428
                                      ReEntrant val_bndrs body' body_ty
    
    433
    -             tmp_fun = mkTemplateLocal 0 fun_ty
    
    429
    +             tmp_fun = mkSysLocal (fsLit "pap") uniq ManyTy fun_ty
    
    434 430
            ; return (StgLet noExtFieldSilent (StgNonRec tmp_fun rhs) $
    
    435 431
                      StgApp tmp_fun []) }
    
    436 432
       where
    
    437
    -    (bndrs, body) = myCollectBinders expr
    
    438
    -    val_bndrs = filterStgBinders bndrs
    
    433
    +    (val_bndrs, body) = myCollectBinders NotJoinPoint expr
    
    439 434
     
    
    440 435
     coreToStgExpr (Tick tick expr)
    
    441 436
       = do
    
    ... ... @@ -715,12 +710,11 @@ coreToStgRhs (bndr, rhs) = do
    715 710
     -- coreToStgExpr that can handle value lambdas.
    
    716 711
     coreToMkStgRhs :: HasDebugCallStack => Id -> CoreExpr -> CtsM MkStgRhs
    
    717 712
     coreToMkStgRhs bndr expr = do
    
    718
    -  let (args, body) = myCollectBinders expr
    
    719
    -  let args'        = filterStgBinders args
    
    720
    -  extendVarEnvCts [ (a, LambdaBound) | a <- args' ] $ do
    
    713
    +  let (bndrs, body) = myCollectBinders (idJoinPointHood bndr) expr
    
    714
    +  extendVarEnvCts [ (a, LambdaBound) | a <- bndrs ] $ do
    
    721 715
         body' <- coreToStgExpr body
    
    722 716
         let mk_rhs = MkStgRhs
    
    723
    -          { rhs_args = args'
    
    717
    +          { rhs_args = bndrs
    
    724 718
               , rhs_expr = body'
    
    725 719
               , rhs_type = exprType body
    
    726 720
               , rhs_is_join = isJoinId bndr
    
    ... ... @@ -738,7 +732,7 @@ coreToMkStgRhs bndr expr = do
    738 732
     newtype CtsM a = CtsM
    
    739 733
         { unCtsM :: Platform -- Needed for checking for bad coercions in coreToStgArgs
    
    740 734
                  -> IdEnv HowBound
    
    741
    -             -> a
    
    735
    +             -> UniqSM a
    
    742 736
         }
    
    743 737
         deriving (Functor)
    
    744 738
     
    
    ... ... @@ -774,20 +768,22 @@ data LetInfo
    774 768
     
    
    775 769
     -- The std monad functions:
    
    776 770
     
    
    777
    -initCts :: Platform -> IdEnv HowBound -> CtsM a -> a
    
    778
    -initCts platform env m = unCtsM m platform env
    
    779
    -
    
    771
    +initCts :: CoreToStgOpts -> UniqSupply -> CtsM a -> a
    
    772
    +initCts opts us cts_m
    
    773
    +  = initUs_ us $
    
    774
    +    unCtsM cts_m (coreToStg_platform opts) emptyVarEnv
    
    780 775
     
    
    781 776
     
    
    782 777
     {-# INLINE thenCts #-}
    
    783 778
     {-# INLINE returnCts #-}
    
    784 779
     
    
    785 780
     returnCts :: a -> CtsM a
    
    786
    -returnCts e = CtsM $ \_ _ -> e
    
    781
    +returnCts e = CtsM $ \_ _ -> return e
    
    787 782
     
    
    788 783
     thenCts :: CtsM a -> (a -> CtsM b) -> CtsM b
    
    789
    -thenCts m k = CtsM $ \platform env
    
    790
    -  -> unCtsM (k (unCtsM m platform env)) platform env
    
    784
    +thenCts m k = CtsM $ \platform env ->
    
    785
    +              do { v <- unCtsM m platform env
    
    786
    +                 ; unCtsM (k v) platform env }
    
    791 787
     
    
    792 788
     instance Applicative CtsM where
    
    793 789
         pure = returnCts
    
    ... ... @@ -797,17 +793,26 @@ instance Monad CtsM where
    797 793
         (>>=)  = thenCts
    
    798 794
     
    
    799 795
     getPlatform :: CtsM Platform
    
    800
    -getPlatform = CtsM const
    
    796
    +getPlatform = CtsM $ \platform _ -> return platform
    
    801 797
     
    
    802 798
     -- Functions specific to this monad:
    
    803 799
     
    
    800
    +setCtsEnv :: IdEnv HowBound -> CtsM a -> CtsM a
    
    801
    +setCtsEnv env thing = CtsM $ \platform _ -> unCtsM thing platform env
    
    802
    +
    
    803
    +getCtsEnv :: CtsM (IdEnv HowBound)
    
    804
    +getCtsEnv = CtsM $ \_ env -> return env
    
    805
    +
    
    806
    +getCtsUnique :: CtsM Unique
    
    807
    +getCtsUnique = CtsM $ \_ _ -> getUniqueM
    
    808
    +
    
    804 809
     extendVarEnvCts :: [(Id, HowBound)] -> CtsM a -> CtsM a
    
    805 810
     extendVarEnvCts ids_w_howbound expr
    
    806 811
        =    CtsM $   \platform env
    
    807 812
        -> unCtsM expr platform (extendVarEnvList env ids_w_howbound)
    
    808 813
     
    
    809 814
     lookupVarCts :: Id -> CtsM HowBound
    
    810
    -lookupVarCts v = CtsM $ \_ env -> lookupBinding env v
    
    815
    +lookupVarCts v = CtsM $ \_ env -> return (lookupBinding env v)
    
    811 816
     
    
    812 817
     lookupBinding :: IdEnv HowBound -> Id -> HowBound
    
    813 818
     lookupBinding env v = case lookupVarEnv env v of
    
    ... ... @@ -819,13 +824,26 @@ lookupBinding env v = case lookupVarEnv env v of
    819 824
     filterStgBinders :: [Var] -> [Var]
    
    820 825
     filterStgBinders bndrs = filter isId bndrs
    
    821 826
     
    
    822
    -myCollectBinders :: Expr Var -> ([Var], Expr Var)
    
    823
    -myCollectBinders expr
    
    827
    +myCollectBinders :: JoinPointHood -> Expr Var -> ([Var], Expr Var)
    
    828
    +-- Collect the binders from a lambda:
    
    829
    +--   * Dropping type lambdas
    
    830
    +--   * Stopping at join-point arity
    
    831
    +myCollectBinders NotJoinPoint expr
    
    824 832
       = go [] expr
    
    825 833
       where
    
    826
    -    go bs (Lam b e)          = go (b:bs) e
    
    827
    -    go bs (Cast e _)         = go bs e
    
    828
    -    go bs e                  = (reverse bs, e)
    
    834
    +    go bs (Lam b e) | isRuntimeVar b = go (b:bs) e
    
    835
    +                    | otherwise      = go bs     e
    
    836
    +    go bs (Cast e _)                 = go bs e
    
    837
    +    go bs e                          = (reverse bs, e)
    
    838
    +
    
    839
    +myCollectBinders (JoinPoint n) expr
    
    840
    +  = go n [] expr
    
    841
    +  where
    
    842
    +    go n bs e | n==0                   = (reverse bs, e)
    
    843
    +    go n bs (Lam b e) | isRuntimeVar b = go (n-1) (b:bs) e
    
    844
    +                      | otherwise      = go (n-1) bs     e
    
    845
    +    go n bs (Cast e _)                 = go n bs e
    
    846
    +    go _ bs e                          = (reverse bs, e)
    
    829 847
     
    
    830 848
     -- | If the argument expression is (potential chain of) 'App', return the head
    
    831 849
     -- of the app chain, and collect ticks/args along the chain.
    

  • compiler/GHC/Driver/Main.hs
    ... ... @@ -2447,8 +2447,8 @@ myCoreToStg :: Logger -> DynFlags -> [Var]
    2447 2447
                       , CollectedCCs -- CAF cost centre info (declared and used)
    
    2448 2448
                       , StgCgInfos )
    
    2449 2449
     myCoreToStg logger dflags ic_inscope for_bytecode this_mod ml prepd_binds = do
    
    2450
    -    let (stg_binds, denv, cost_centre_info)
    
    2451
    -         = {-# SCC "Core2Stg" #-}
    
    2450
    +    (stg_binds, denv, cost_centre_info)
    
    2451
    +       <- {-# SCC "Core2Stg" #-}
    
    2452 2452
                coreToStg (initCoreToStgOpts dflags) this_mod ml prepd_binds
    
    2453 2453
     
    
    2454 2454
         (stg_binds_with_fvs,stg_cg_info)