| ... |
... |
@@ -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.
|