| ... |
... |
@@ -111,12 +111,13 @@ import GHC.Types.Demand ( DmdSig, prependArgsDmdSig ) |
|
111
|
111
|
import GHC.Types.Cpr ( CprSig, prependArgsCprSig )
|
|
112
|
112
|
import GHC.Types.Name ( getOccName, mkSystemVarName )
|
|
113
|
113
|
import GHC.Types.Name.Occurrence ( occNameFS )
|
|
114
|
|
-import GHC.Types.Unique ( hasKey )
|
|
|
114
|
+import GHC.Types.Unique ( Unique, hasKey )
|
|
115
|
115
|
import GHC.Types.Tickish ( tickishIsCode )
|
|
116
|
116
|
import GHC.Types.Unique.Supply
|
|
117
|
117
|
import GHC.Types.Unique.DFM
|
|
118
|
118
|
import GHC.Types.Basic ( Arity, RecFlag(..), isRec )
|
|
119
|
119
|
|
|
|
120
|
+import GHC.Data.Maybe ( orElse )
|
|
120
|
121
|
import GHC.Builtin.Types
|
|
121
|
122
|
import GHC.Builtin.Names ( runRWKey )
|
|
122
|
123
|
|
| ... |
... |
@@ -290,7 +291,7 @@ lvl_top env is_rec bndr rhs |
|
290
|
291
|
= do { rhs' <- lvlRhs env is_rec (isDeadEndId bndr)
|
|
291
|
292
|
NotJoinPoint
|
|
292
|
293
|
(freeVars rhs)
|
|
293
|
|
- ; return (stayPut tOP_LEVEL bndr, rhs') }
|
|
|
294
|
+ ; return (TB bndr (StayPut tOP_LEVEL), rhs') }
|
|
294
|
295
|
|
|
295
|
296
|
{-
|
|
296
|
297
|
************************************************************************
|
| ... |
... |
@@ -363,8 +364,8 @@ lvlExpr env expr@(_, AnnLam {}) |
|
363
|
364
|
; return (mkLams new_bndrs new_body) }
|
|
364
|
365
|
where
|
|
365
|
366
|
(bndrs, body) = collectAnnBndrs expr
|
|
366
|
|
- (env1, bndrs1) = substBndrsSL NonRecursive env bndrs
|
|
367
|
|
- (new_env, new_bndrs) = lvlLamBndrs env1 (le_ctxt_lvl env) bndrs1
|
|
|
367
|
+ bndr_lvl = lamBndrLevel (le_ctxt_lvl env) bndrs
|
|
|
368
|
+ (new_env, new_bndrs) = substAndLvlBndrs env NonRecursive bndr_lvl bndrs
|
|
368
|
369
|
-- At one time we called a special version of collectBinders,
|
|
369
|
370
|
-- which ignored coercions, because we don't want to split
|
|
370
|
371
|
-- a lambda like this (\x -> coerce t (\s -> ...))
|
| ... |
... |
@@ -455,11 +456,11 @@ lvlCase env scrut_fvs scrut' case_bndr ty alts |
|
455
|
456
|
do { (env1, (case_bndr' : bs')) <- cloneCaseBndrs env dest_lvl (case_bndr : bs)
|
|
456
|
457
|
; let rhs_env = extendCaseBndrEnv env1 case_bndr scrut'
|
|
457
|
458
|
; body' <- lvlMFE rhs_env True body
|
|
458
|
|
- ; let alt' = Alt con (map (stayPut dest_lvl) bs') body'
|
|
459
|
|
- ; return (Case scrut' (TB case_bndr' (FloatMe dest_lvl)) ty' [alt']) }
|
|
|
459
|
+ ; let alt' = Alt con bs' body'
|
|
|
460
|
+ ; return (Case scrut' case_bndr' ty' [alt']) }
|
|
460
|
461
|
|
|
461
|
462
|
| otherwise -- Stays put
|
|
462
|
|
- = do { let (alts_env1, [case_bndr']) = substAndLvlBndrs NonRecursive env incd_lvl [case_bndr]
|
|
|
463
|
+ = do { let (alts_env1, [case_bndr']) = substAndLvlBndrs env NonRecursive incd_lvl [case_bndr]
|
|
463
|
464
|
alts_env = extendCaseBndrEnv alts_env1 case_bndr scrut'
|
|
464
|
465
|
; alts' <- mapM (lvl_alt alts_env) alts
|
|
465
|
466
|
; return (Case scrut' case_bndr' ty' alts') }
|
| ... |
... |
@@ -474,7 +475,7 @@ lvlCase env scrut_fvs scrut' case_bndr ty alts |
|
474
|
475
|
= do { rhs' <- lvlMFE new_env True rhs
|
|
475
|
476
|
; return (Alt con bs' rhs') }
|
|
476
|
477
|
where
|
|
477
|
|
- (new_env, bs') = substAndLvlBndrs NonRecursive alts_env incd_lvl bs
|
|
|
478
|
+ (new_env, bs') = substAndLvlBndrs alts_env NonRecursive incd_lvl bs
|
|
478
|
479
|
|
|
479
|
480
|
{- Note [Floating single-alternative cases]
|
|
480
|
481
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| ... |
... |
@@ -631,13 +632,14 @@ lvlMFE env strict_ctxt ann_expr |
|
631
|
632
|
| float_is_new_lam || exprIsTopLevelBindable expr expr_ty
|
|
632
|
633
|
-- No wrapping needed if the type is lifted, or is a literal string
|
|
633
|
634
|
-- or if we are wrapping it in one or more value lambdas
|
|
634
|
|
- = do { expr1 <- lvlFloatRhs abs_vars dest_lvl rhs_env NonRecursive
|
|
635
|
|
- is_bot_lam NotJoinPoint ann_expr
|
|
|
635
|
+ = do { rhs' <- lvlFloatRhs env dest_lvl abs_vars NonRecursive
|
|
|
636
|
+ is_bot_lam NotJoinPoint ann_expr
|
|
636
|
637
|
-- Treat the expr just like a right-hand side
|
|
637
|
|
- ; var <- newLvlVar expr1 NotJoinPoint is_mk_static
|
|
638
|
|
- ; let var2 = annotateBotStr var float_n_lams mb_bot_str
|
|
639
|
|
- ; return (Let (NonRec (TB var2 (FloatMe dest_lvl)) expr1)
|
|
640
|
|
- (mkVarApps (Var var2) abs_vars)) }
|
|
|
638
|
+ ; var <- newLvlVar rhs' NotJoinPoint is_mk_static
|
|
|
639
|
+ ; let lb = TB (FloatMe dest_lvl) var
|
|
|
640
|
+ lb' = annotateBotStr lb float_n_lams mb_bot_str
|
|
|
641
|
+ ; return (Let (NonRec lb' rhs')
|
|
|
642
|
+ (mkVarApps (Var var abs_vars))) }
|
|
641
|
643
|
|
|
642
|
644
|
-- OK, so the float has an unlifted type (not top-level bindable)
|
|
643
|
645
|
-- and no new value lambdas (float_is_new_lam is False)
|
| ... |
... |
@@ -649,14 +651,15 @@ lvlMFE env strict_ctxt ann_expr |
|
649
|
651
|
, BI_Box { bi_data_con = box_dc, bi_inst_con = boxing_expr
|
|
650
|
652
|
, bi_boxed_type = box_ty } <- boxingDataCon expr_ty
|
|
651
|
653
|
, let [bx_bndr, ubx_bndr] = mkTemplateLocals [box_ty, expr_ty]
|
|
652
|
|
- = do { expr1 <- lvlExpr rhs_env ann_expr
|
|
653
|
|
- ; let l1r = incMinorLvlFrom rhs_env
|
|
654
|
|
- float_rhs = mkLams abs_vars_w_lvls $
|
|
|
654
|
+ = do { let bndr_lvl = lamBndrLevel dest_lvl abs_vars
|
|
|
655
|
+ ; expr1 <- lvlExpr (env `setCtxtLevel` bndr_lvl) ann_expr
|
|
|
656
|
+ ; let l1r = incMinorLvl bndr_lvl
|
|
|
657
|
+ float_rhs = mkLams (stayPut bndr_lvl abs_vars) $
|
|
655
|
658
|
Case expr1 (stayPut l1r ubx_bndr) box_ty
|
|
656
|
659
|
[Alt DEFAULT [] (App boxing_expr (Var ubx_bndr))]
|
|
657
|
660
|
|
|
658
|
661
|
; var <- newLvlVar float_rhs NotJoinPoint is_mk_static
|
|
659
|
|
- ; let l1u = incMinorLvlFrom env
|
|
|
662
|
+ ; let l1u = incMinorLvl (ctxtLevel env)
|
|
660
|
663
|
use_expr = Case (mkVarApps (Var var) abs_vars)
|
|
661
|
664
|
(stayPut l1u bx_bndr) expr_ty
|
|
662
|
665
|
[Alt (DataAlt box_dc) [stayPut l1u ubx_bndr] (Var ubx_bndr)]
|
| ... |
... |
@@ -690,8 +693,6 @@ lvlMFE env strict_ctxt ann_expr |
|
690
|
693
|
float_is_new_lam = float_n_lams > 0
|
|
691
|
694
|
float_n_lams = count isId abs_vars
|
|
692
|
695
|
|
|
693
|
|
- (rhs_env, abs_vars_w_lvls) = lvlLamBndrs env dest_lvl abs_vars
|
|
694
|
|
-
|
|
695
|
696
|
is_mk_static = isJust (collectMakeStaticArgs expr)
|
|
696
|
697
|
-- Yuk: See Note [Grand plan for static forms] in GHC.Iface.Tidy.StaticPtrTable
|
|
697
|
698
|
|
| ... |
... |
@@ -706,7 +707,7 @@ lvlMFE env strict_ctxt ann_expr |
|
706
|
707
|
saves_work = escapes_value_lam -- (a)
|
|
707
|
708
|
&& not is_hnf -- (b)
|
|
708
|
709
|
&& not float_is_new_lam -- (c)
|
|
709
|
|
- escapes_value_lam = dest_lvl `ltMajLvl` (le_ctxt_lvl env)
|
|
|
710
|
+ escapes_value_lam = dest_lvl `ltMajLvl` (ctxtLevel env)
|
|
710
|
711
|
|
|
711
|
712
|
-- See Note [Saving allocation] and Note [Floating to the top]
|
|
712
|
713
|
saves_alloc = isTopLvl dest_lvl
|
| ... |
... |
@@ -720,8 +721,9 @@ hasFreeJoin :: LevelEnv -> DVarSet -> Bool |
|
720
|
721
|
-- (In the latter case it won't be a join point any more.)
|
|
721
|
722
|
-- Not treating top-level ones specially had a massive effect
|
|
722
|
723
|
-- on nofib/minimax/Prog.prog
|
|
723
|
|
-hasFreeJoin env fvs
|
|
724
|
|
- = not (maxFvLevel isJoinId env fvs == tOP_LEVEL)
|
|
|
724
|
+hasFreeJoin env fvs = anyDVarSet bad_join fvs
|
|
|
725
|
+ where
|
|
|
726
|
+ bad_join v = isJoinId v && lookupLevel env v == tOP_LEVEL
|
|
725
|
727
|
|
|
726
|
728
|
{- Note [Saving work]
|
|
727
|
729
|
~~~~~~~~~~~~~~~~~~~~~
|
| ... |
... |
@@ -1117,18 +1119,20 @@ artificial benchmarks (e.g. integer, queens), but there is no perfect |
|
1117
|
1119
|
answer.
|
|
1118
|
1120
|
-}
|
|
1119
|
1121
|
|
|
1120
|
|
-annotateBotStr :: Id -> Arity -> Maybe (Arity, DmdSig, CprSig) -> Id
|
|
|
1122
|
+annotateBotStr :: LevelledBndr -> Arity -> Maybe (Arity, DmdSig, CprSig) -> LevelledBndr
|
|
1121
|
1123
|
-- See Note [Bottoming floats] for why we want to add
|
|
1122
|
1124
|
-- bottoming information right now
|
|
1123
|
1125
|
--
|
|
1124
|
1126
|
-- n_extra are the number of extra value arguments added during floating
|
|
1125
|
|
-annotateBotStr id n_extra mb_bot_str
|
|
1126
|
|
- | Just (arity, str_sig, cpr_sig) <- mb_bot_str
|
|
1127
|
|
- = id `setIdArity` (arity + n_extra)
|
|
1128
|
|
- `setIdDmdSig` prependArgsDmdSig n_extra str_sig
|
|
1129
|
|
- `setIdCprSig` prependArgsCprSig n_extra cpr_sig
|
|
1130
|
|
- | otherwise
|
|
1131
|
|
- = id
|
|
|
1127
|
+annotateBotStr lb@(TB lvl id) n_extra mb_bot_str
|
|
|
1128
|
+ = case mb_bot_str of
|
|
|
1129
|
+ Nothing -> lb
|
|
|
1130
|
+ Just (arity, str_sig, cpr_sig)
|
|
|
1131
|
+ -> TB lvl id'
|
|
|
1132
|
+ where
|
|
|
1133
|
+ id' = id `setIdArity` (arity + n_extra)
|
|
|
1134
|
+ `setIdDmdSig` prependArgsDmdSig n_extra str_sig
|
|
|
1135
|
+ `setIdCprSig` prependArgsCprSig n_extra cpr_sig
|
|
1132
|
1136
|
|
|
1133
|
1137
|
notWorthFloating :: CoreExpr -> [Var] -> Bool
|
|
1134
|
1138
|
-- See Note [notWorthFloating]
|
| ... |
... |
@@ -1269,26 +1273,26 @@ lvlBind env (AnnNonRec bndr rhs) |
|
1269
|
1273
|
|| not (wantToFloat env NonRecursive dest_lvl is_join is_top_bindable)
|
|
1270
|
1274
|
= -- No float
|
|
1271
|
1275
|
do { rhs' <- lvlRhs env NonRecursive is_bot_lam mb_join_arity rhs
|
|
1272
|
|
- ; let bind_lvl = incMinorLvl (le_ctxt_lvl env)
|
|
1273
|
|
- (env', [bndr']) = substAndLvlBndrs NonRecursive env bind_lvl [bndr]
|
|
|
1276
|
+ ; let bind_lvl = incMinorLvl (ctxtLevel env)
|
|
|
1277
|
+ (env', [bndr']) = substAndLvlBndrs env NonRecursive bind_lvl [bndr]
|
|
1274
|
1278
|
; return (NonRec bndr' rhs', env') }
|
|
1275
|
1279
|
|
|
1276
|
1280
|
-- Otherwise we are going to float
|
|
1277
|
1281
|
| null abs_vars
|
|
1278
|
1282
|
= do { -- No type abstraction; clone existing binder
|
|
1279
|
|
- rhs' <- lvlFloatRhs [] dest_lvl env NonRecursive
|
|
|
1283
|
+ rhs' <- lvlFloatRhs env dest_lvl [] NonRecursive
|
|
1280
|
1284
|
is_bot_lam NotJoinPoint rhs
|
|
1281
|
|
- ; (env', [bndr']) <- cloneLetVars NonRecursive env dest_lvl [bndr]
|
|
1282
|
|
- ; let bndr2 = annotateBotStr bndr' 0 mb_bot_str
|
|
1283
|
|
- ; return (NonRec (TB bndr2 (FloatMe dest_lvl)) rhs', env') }
|
|
|
1285
|
+ ; (env', [lbndr]) <- cloneLetVars NonRecursive env dest_lvl [bndr]
|
|
|
1286
|
+ ; let lbndr' = annotateBotStr lbndr 0 mb_bot_str
|
|
|
1287
|
+ ; return (NonRec lbndr' rhs', env') }
|
|
1284
|
1288
|
|
|
1285
|
1289
|
| otherwise
|
|
1286
|
1290
|
= do { -- Yes, type abstraction; create a new binder, extend substitution, etc
|
|
1287
|
|
- rhs' <- lvlFloatRhs abs_vars dest_lvl env NonRecursive
|
|
|
1291
|
+ rhs' <- lvlFloatRhs env dest_lvl abs_vars NonRecursive
|
|
1288
|
1292
|
is_bot_lam NotJoinPoint rhs
|
|
1289
|
|
- ; (env', [bndr']) <- newPolyBndrs dest_lvl env abs_vars [bndr]
|
|
1290
|
|
- ; let bndr2 = annotateBotStr bndr' n_extra mb_bot_str
|
|
1291
|
|
- ; return (NonRec (TB bndr2 (FloatMe dest_lvl)) rhs', env') }
|
|
|
1293
|
+ ; (env', [lbndr]) <- newPolyBndrs env dest_lvl abs_vars [bndr]
|
|
|
1294
|
+ ; let lbndr' = annotateBotStr lbndr n_extra mb_bot_str
|
|
|
1295
|
+ ; return (NonRec lbndr' rhs', env') }
|
|
1292
|
1296
|
|
|
1293
|
1297
|
where
|
|
1294
|
1298
|
bndr_ty = idType bndr
|
| ... |
... |
@@ -1314,8 +1318,8 @@ lvlBind env (AnnNonRec bndr rhs) |
|
1314
|
1318
|
lvlBind env (AnnRec pairs)
|
|
1315
|
1319
|
| not (wantToFloat env Recursive dest_lvl is_join is_top_bindable)
|
|
1316
|
1320
|
= -- No float
|
|
1317
|
|
- do { let bind_lvl = incMinorLvl (le_ctxt_lvl env)
|
|
1318
|
|
- (env', bndrs') = substAndLvlBndrs Recursive env bind_lvl bndrs
|
|
|
1321
|
+ do { let bind_lvl = incMinorLvl (ctxtLevel env)
|
|
|
1322
|
+ (env', bndrs') = substAndLvlBndrs env Recursive bind_lvl bndrs
|
|
1319
|
1323
|
lvl_rhs (b,r) = lvlRhs env' Recursive is_bot (idJoinPointHood b) r
|
|
1320
|
1324
|
; rhss' <- mapM lvl_rhs pairs
|
|
1321
|
1325
|
; return (Rec (bndrs' `zip` rhss'), env') }
|
| ... |
... |
@@ -1331,7 +1335,7 @@ lvlBind env (AnnRec pairs) |
|
1331
|
1335
|
-- I think we want to stop doing this
|
|
1332
|
1336
|
| [(bndr,rhs)] <- pairs
|
|
1333
|
1337
|
, count isId abs_vars > 1
|
|
1334
|
|
- = do -- Special case for self recursion where there are
|
|
|
1338
|
+ = -- Special case for self recursion where there are
|
|
1335
|
1339
|
-- several variables carried around: build a local loop:
|
|
1336
|
1340
|
-- poly_f = \abs_vars. \lam_vars . letrec f = \lam_vars. rhs in f lam_vars
|
|
1337
|
1341
|
-- This just makes the closures a bit smaller. If we don't do
|
| ... |
... |
@@ -1341,26 +1345,25 @@ lvlBind env (AnnRec pairs) |
|
1341
|
1345
|
-- mutually recursive functions, but it's quite a bit more complicated
|
|
1342
|
1346
|
--
|
|
1343
|
1347
|
-- This all seems a bit ad hoc -- sigh
|
|
1344
|
|
- let (rhs_env, abs_vars_w_lvls) = lvlLamBndrs env dest_lvl abs_vars
|
|
1345
|
|
- rhs_lvl = le_ctxt_lvl rhs_env
|
|
1346
|
|
-
|
|
1347
|
|
- (rhs_env', [new_bndr]) <- cloneLetVars Recursive rhs_env rhs_lvl [bndr]
|
|
1348
|
|
- let
|
|
1349
|
|
- (lam_bndrs, rhs_body) = collectAnnBndrs rhs
|
|
1350
|
|
- (body_env1, lam_bndrs1) = substBndrsSL NonRecursive rhs_env' lam_bndrs
|
|
1351
|
|
- (body_env2, lam_bndrs2) = lvlLamBndrs body_env1 rhs_lvl lam_bndrs1
|
|
1352
|
|
- new_rhs_body <- lvlRhs body_env2 Recursive is_bot NotJoinPoint rhs_body
|
|
1353
|
|
- (poly_env, [poly_bndr]) <- newPolyBndrs dest_lvl env abs_vars [bndr]
|
|
1354
|
|
- return (Rec [(TB poly_bndr (FloatMe dest_lvl)
|
|
1355
|
|
- , mkLams abs_vars_w_lvls $
|
|
1356
|
|
- mkLams lam_bndrs2 $
|
|
1357
|
|
- Let (Rec [( TB new_bndr (StayPut rhs_lvl)
|
|
1358
|
|
- , mkLams lam_bndrs2 new_rhs_body)])
|
|
1359
|
|
- (mkVarApps (Var new_bndr) lam_bndrs1))]
|
|
1360
|
|
- , poly_env)
|
|
|
1348
|
+ do { let (lam_bndrs, body) = collectAnnBndrs rhs
|
|
|
1349
|
+ bndr_lvl = lamBndrLevel dest_lvl (abs_vars ++ lam_bndrs)
|
|
|
1350
|
+ abs_lbs = stayPut bndr_lvl abs_vars
|
|
|
1351
|
+ (body_env1, lam_lbs) = substAndLvlBndrs env NonRecursive bndr_lvl lam_bndrs
|
|
|
1352
|
+
|
|
|
1353
|
+ ; (body_env2, [new_bndr]) <- cloneLetVars Recursive body_env1 (ctxtLevel body_env1) [bndr]
|
|
|
1354
|
+ ; new_body <- lvlRhs body_env2 Recursive is_bot NotJoinPoint body
|
|
|
1355
|
+ ; (poly_env, [poly_bndr]) <- newPolyBndrs dest_lvl env abs_vars [bndr]
|
|
|
1356
|
+
|
|
|
1357
|
+ ; let rec_rhs = mkLams lam_lbs new_body
|
|
|
1358
|
+ new_rhs = mkLams abs_lbs $
|
|
|
1359
|
+ mkLams lam_lbs $
|
|
|
1360
|
+ Let (Rec [( new_bndr, rec_rhs )]) $
|
|
|
1361
|
+ mkVarApps (Var new_bndr) (map taggedBndrBndr lam_lbs)
|
|
|
1362
|
+ ; return ( Rec [(poly_bndr, new_rhs)]
|
|
|
1363
|
+ , poly_env) }
|
|
1361
|
1364
|
|
|
1362
|
1365
|
| otherwise -- Non-null abs_vars
|
|
1363
|
|
- = do { (new_env, new_bndrs) <- newPolyBndrs dest_lvl env abs_vars bndrs
|
|
|
1366
|
+ = do { (new_env, new_bndrs) <- newPolyBndrs env dest_lvl abs_vars bndrs
|
|
1364
|
1367
|
; new_rhss <- mapM (do_rhs new_env) pairs
|
|
1365
|
1368
|
; return ( Rec ([TB b (FloatMe dest_lvl) | b <- new_bndrs] `zip` new_rhss)
|
|
1366
|
1369
|
, new_env) }
|
| ... |
... |
@@ -1375,7 +1378,7 @@ lvlBind env (AnnRec pairs) |
|
1375
|
1378
|
-- function in a Rec, and we don't much care what
|
|
1376
|
1379
|
-- happens to it. False is simple!
|
|
1377
|
1380
|
|
|
1378
|
|
- do_rhs env (_,rhs) = lvlFloatRhs abs_vars dest_lvl env Recursive
|
|
|
1381
|
+ do_rhs env (_,rhs) = lvlFloatRhs env dest_lvl abs_vars Recursive
|
|
1379
|
1382
|
is_bot NotJoinPoint
|
|
1380
|
1383
|
rhs
|
|
1381
|
1384
|
|
| ... |
... |
@@ -1425,7 +1428,7 @@ wantToFloat env is_rec dest_lvl is_join is_top_bindable |
|
1425
|
1428
|
|
|
1426
|
1429
|
profitableFloat :: LevelEnv -> Level -> Bool
|
|
1427
|
1430
|
profitableFloat env dest_lvl
|
|
1428
|
|
- = (dest_lvl `ltMajLvl` le_ctxt_lvl env) -- Escapes a value lambda
|
|
|
1431
|
+ = (dest_lvl `ltMajLvl` ctxtLevel env) -- Escapes a value lambda
|
|
1429
|
1432
|
|| (isTopLvl dest_lvl && floatConsts env) -- Going all the way to top level
|
|
1430
|
1433
|
|
|
1431
|
1434
|
|
| ... |
... |
@@ -1439,33 +1442,31 @@ lvlRhs :: LevelEnv |
|
1439
|
1442
|
-> CoreExprWithFVs
|
|
1440
|
1443
|
-> LvlM LevelledExpr
|
|
1441
|
1444
|
lvlRhs env rec_flag is_bot mb_join_arity expr
|
|
1442
|
|
- = lvlFloatRhs [] (le_ctxt_lvl env) env
|
|
|
1445
|
+ = lvlFloatRhs env (ctxtLevel env) []
|
|
1443
|
1446
|
rec_flag is_bot mb_join_arity expr
|
|
1444
|
1447
|
|
|
1445
|
|
-lvlFloatRhs :: [OutVar] -> Level -> LevelEnv -> RecFlag
|
|
|
1448
|
+lvlFloatRhs :: LevelEnv -> Level -> [OutVar] -> RecFlag
|
|
1446
|
1449
|
-> Bool -- Binding is for a bottoming function
|
|
1447
|
1450
|
-> JoinPointHood
|
|
1448
|
1451
|
-> CoreExprWithFVs
|
|
1449
|
1452
|
-> LvlM (Expr LevelledBndr)
|
|
1450
|
1453
|
-- Ignores the le_ctxt_lvl in env; treats dest_lvl as the baseline
|
|
1451
|
|
-lvlFloatRhs abs_vars dest_lvl env rec is_bot mb_join_arity rhs
|
|
|
1454
|
+lvlFloatRhs env dest_lvl abs_vars rec_flag is_bot mb_join_arity rhs
|
|
1452
|
1455
|
= do { body' <- if not is_bot -- See Note [Floating from a RHS]
|
|
1453
|
1456
|
&& any isId bndrs
|
|
1454
|
1457
|
then lvlMFE body_env True body
|
|
1455
|
1458
|
else lvlExpr body_env body
|
|
1456
|
|
- ; return (mkLams bndrs' body') }
|
|
|
1459
|
+ ; return (mkLams (abs_bndrs ++ bndrs') body') }
|
|
1457
|
1460
|
where
|
|
1458
|
|
- (bndrs, body) | JoinPoint join_arity <- mb_join_arity
|
|
1459
|
|
- = collectNAnnBndrs join_arity rhs
|
|
1460
|
|
- | otherwise
|
|
1461
|
|
- = collectAnnBndrs rhs
|
|
1462
|
|
- (env1, bndrs1) = substBndrsSL NonRecursive env bndrs
|
|
1463
|
|
- all_bndrs = abs_vars ++ bndrs1
|
|
1464
|
|
- (body_env, bndrs') | JoinPoint {} <- mb_join_arity
|
|
1465
|
|
- = lvlJoinBndrs env1 dest_lvl rec all_bndrs
|
|
1466
|
|
- | otherwise
|
|
1467
|
|
- = lvlLamBndrs env1 dest_lvl all_bndrs
|
|
1468
|
|
- -- The important thing here is that we call lvlLamBndrs on
|
|
|
1461
|
+ (bndrs, body) = collectAnnBndrs rhs
|
|
|
1462
|
+ bndr_lvl = case mb_join_arity of
|
|
|
1463
|
+ JoinPoint ja -> assertPpr (null abs_vars) (ppr abs_vars) $
|
|
|
1464
|
+ joinLamBndrLevel dest_lvl rec_flag ja bndrs
|
|
|
1465
|
+ NotJoinPoint -> lamBndrLevel dest_lvl (abs_bndrs ++ bndrs)
|
|
|
1466
|
+
|
|
|
1467
|
+ abs_bndrs = stayPut bndr_lvl abs_vars
|
|
|
1468
|
+ (body_env, bndrs') = substAndLvlBndrs env NonRecursive bndr_lvl bndrs
|
|
|
1469
|
+ -- The important thing here is that we call `lamBndrLevel` on
|
|
1469
|
1470
|
-- all these binders at once (abs_vars and bndrs), so they
|
|
1470
|
1471
|
-- all get the same major level. Otherwise we create stupid
|
|
1471
|
1472
|
-- let-bindings inside, joyfully thinking they can float; but
|
| ... |
... |
@@ -1522,31 +1523,32 @@ Use lvlExpr otherwise. A little subtle, and I got it wrong at least twice |
|
1522
|
1523
|
************************************************************************
|
|
1523
|
1524
|
-}
|
|
1524
|
1525
|
|
|
1525
|
|
-substAndLvlBndrs :: RecFlag -> LevelEnv -> Level -> [InVar] -> (LevelEnv, [LevelledBndr])
|
|
1526
|
|
-substAndLvlBndrs is_rec env lvl bndrs
|
|
1527
|
|
- = lvlBndrs subst_env lvl subst_bndrs
|
|
|
1526
|
+setCtxtLevel :: LevelEnv -> Level -> LevelEnv
|
|
|
1527
|
+setCtxtLevel env lvl = env { le_ctxt_lvl = lvl }
|
|
|
1528
|
+
|
|
|
1529
|
+substAndLvlBndrs :: LevelEnv -> RecFlag -> Level -> [InVar] -> (LevelEnv, [LevelledBndr])
|
|
|
1530
|
+-- New env has
|
|
|
1531
|
+-- * Updated context level
|
|
|
1532
|
+-- * Updated le_lvl_env for the InVars
|
|
|
1533
|
+-- * Updated le_subst and le_env for cloning
|
|
|
1534
|
+substAndLvlBndrs env@(LE { le_subst = subst, le_env = id_env, le_lvl_env = lvl_env })
|
|
|
1535
|
+ is_rec bndr_lvl in_bndrs
|
|
|
1536
|
+ = ( env { le_ctxt_lvl = bndr_lvl
|
|
|
1537
|
+ , le_lvl_env = addLvls bndr_lvl lvl_env in_bndrs
|
|
|
1538
|
+ , le_subst = subst'
|
|
|
1539
|
+ , le_env = foldl' add_id id_env (in_bndrs `zip` lvld_bndrs) }
|
|
|
1540
|
+ , lvld_bndrs)
|
|
1528
|
1541
|
where
|
|
1529
|
|
- (subst_env, subst_bndrs) = substBndrsSL is_rec env bndrs
|
|
1530
|
|
-
|
|
1531
|
|
-substBndrsSL :: RecFlag -> LevelEnv -> [InVar] -> (LevelEnv, [OutVar])
|
|
1532
|
|
--- So named only to avoid the name clash with GHC.Core.Subst.substBndrs
|
|
1533
|
|
-substBndrsSL is_rec env@(LE { le_subst = subst, le_env = id_env }) bndrs
|
|
1534
|
|
- = ( env { le_subst = subst'
|
|
1535
|
|
- , le_env = foldl' add_id id_env (bndrs `zip` bndrs') }
|
|
1536
|
|
- , bndrs')
|
|
|
1542
|
+ lvld_bndrs = stayPut bndr_lvl out_bndrs
|
|
|
1543
|
+ (subst', out_bndrs) = case is_rec of
|
|
|
1544
|
+ NonRecursive -> substBndrs subst in_bndrs
|
|
|
1545
|
+ Recursive -> substRecBndrs subst in_bndrs
|
|
|
1546
|
+
|
|
|
1547
|
+lamBndrLevel :: Level -> [InVar] -> Level
|
|
|
1548
|
+lamBndrLevel ctxt_lvl bndrs
|
|
|
1549
|
+ | any is_major bndrs = incMajorLvl ctxt_lvl
|
|
|
1550
|
+ | otherwise = incMinorLvl ctxt_lvl
|
|
1537
|
1551
|
where
|
|
1538
|
|
- (subst', bndrs') = case is_rec of
|
|
1539
|
|
- NonRecursive -> substBndrs subst bndrs
|
|
1540
|
|
- Recursive -> substRecBndrs subst bndrs
|
|
1541
|
|
-
|
|
1542
|
|
-lvlLamBndrs :: LevelEnv -> Level -> [OutVar] -> (LevelEnv, [LevelledBndr])
|
|
1543
|
|
--- Compute the levels for the binders of a lambda group
|
|
1544
|
|
-lvlLamBndrs env lvl bndrs
|
|
1545
|
|
- = lvlBndrs env new_lvl bndrs
|
|
1546
|
|
- where
|
|
1547
|
|
- new_lvl | any is_major bndrs = incMajorLvl lvl
|
|
1548
|
|
- | otherwise = incMinorLvl lvl
|
|
1549
|
|
-
|
|
1550
|
1552
|
is_major bndr = not (isOneShotBndr bndr)
|
|
1551
|
1553
|
-- Only non-one-shot lambdas bump a major level, which in
|
|
1552
|
1554
|
-- turn triggers floating. NB: isOneShotBndr is always
|
| ... |
... |
@@ -1554,14 +1556,10 @@ lvlLamBndrs env lvl bndrs |
|
1554
|
1556
|
-- out of a big lambda.
|
|
1555
|
1557
|
-- See Note [Computing one-shot info] in GHC.Types.Demand
|
|
1556
|
1558
|
|
|
1557
|
|
-lvlJoinBndrs :: LevelEnv -> Level -> RecFlag -> [OutVar]
|
|
1558
|
|
- -> (LevelEnv, [LevelledBndr])
|
|
1559
|
|
-lvlJoinBndrs env lvl rec bndrs
|
|
1560
|
|
- = lvlBndrs env new_lvl bndrs
|
|
1561
|
|
- where
|
|
1562
|
|
- new_lvl | isRec rec = incMajorLvl lvl
|
|
1563
|
|
- | otherwise = incMinorLvl lvl
|
|
1564
|
|
- -- Non-recursive join points are one-shot; recursive ones are not
|
|
|
1559
|
+joinLamBndrLevel :: Level -> RecFlag -> JoinArity -> [InVar] -> Level
|
|
|
1560
|
+joinLamBndrLevel ctxt_lvl rec_flag join_arity bndrs
|
|
|
1561
|
+ | isRec rec_flag = lamBndrLevel ctxt_lvl bndrs
|
|
|
1562
|
+ | otherwise = lamBndrLevel ctxt_lvl (drop join_arity bndrs)
|
|
1565
|
1563
|
|
|
1566
|
1564
|
lvlBndrs :: LevelEnv -> Level -> [CoreBndr] -> (LevelEnv, [LevelledBndr])
|
|
1567
|
1565
|
-- The binders returned are exactly the same as the ones passed,
|
| ... |
... |
@@ -1576,10 +1574,10 @@ lvlBndrs :: LevelEnv -> Level -> [CoreBndr] -> (LevelEnv, [LevelledBndr]) |
|
1576
|
1574
|
lvlBndrs env@(LE { le_lvl_env = lvl_env }) new_lvl bndrs
|
|
1577
|
1575
|
= ( env { le_ctxt_lvl = new_lvl
|
|
1578
|
1576
|
, le_lvl_env = addLvls new_lvl lvl_env bndrs }
|
|
1579
|
|
- , map (stayPut new_lvl) bndrs)
|
|
|
1577
|
+ , stayPut new_lvl bndrs)
|
|
1580
|
1578
|
|
|
1581
|
|
-stayPut :: Level -> OutVar -> LevelledBndr
|
|
1582
|
|
-stayPut new_lvl bndr = TB bndr (StayPut new_lvl)
|
|
|
1579
|
+stayPut :: Level -> [OutVar] -> [LevelledBndr]
|
|
|
1580
|
+stayPut new_lvl bndrs = [ TB bndr (StayPut new_lvl) | bndr <- bndrs ]
|
|
1583
|
1581
|
|
|
1584
|
1582
|
-- Destination level is the max Id level of the expression
|
|
1585
|
1583
|
-- (We'll abstract the type variables, if any.)
|
| ... |
... |
@@ -1677,14 +1675,15 @@ countFreeIds = nonDetStrictFoldUDFM add 0 . getUniqDSet |
|
1677
|
1675
|
data LevelEnv
|
|
1678
|
1676
|
= LE { le_switches :: FloatOutSwitches
|
|
1679
|
1677
|
, le_ctxt_lvl :: Level -- The current level
|
|
1680
|
|
- , le_lvl_env :: VarEnv Level -- Domain is *post-cloned* TyVars and Ids
|
|
|
1678
|
+ , le_lvl_env :: VarEnv Level -- Domain is *pre-cloned* InVars
|
|
1681
|
1679
|
|
|
1682
|
1680
|
-- See Note [le_subst and le_env]
|
|
1683
|
|
- , le_subst :: Subst -- Domain is pre-cloned TyVars and Ids
|
|
1684
|
|
- -- The Id -> CoreExpr in the Subst is ignored
|
|
1685
|
|
- -- (since we want to substitute a LevelledExpr for
|
|
1686
|
|
- -- an Id via le_env) but we do use the Co/TyVar substs
|
|
1687
|
|
- , le_env :: IdEnv ([OutVar], LevelledExpr) -- Domain is pre-cloned Ids
|
|
|
1681
|
+ , le_subst :: Subst -- Domain is pre-cloned TyVars and Ids
|
|
|
1682
|
+ -- The Id -> CoreExpr in the Subst is ignored
|
|
|
1683
|
+ -- (since we want to substitute a LevelledExpr for
|
|
|
1684
|
+ -- an Id via le_env) but we do use the Co/TyVar substs
|
|
|
1685
|
+ , le_env :: IdEnv ([LevelledBndr], LevelledExpr) -- Domain is pre-cloned Ids
|
|
|
1686
|
+ -- The LevelledBndrs are the free vars of LevelledExpr
|
|
1688
|
1687
|
}
|
|
1689
|
1688
|
|
|
1690
|
1689
|
{- Note [le_subst and le_env]
|
| ... |
... |
@@ -1733,10 +1732,13 @@ initialEnv float_lams binds |
|
1733
|
1732
|
-- to a later one. So here we put all the top-level binders in scope before
|
|
1734
|
1733
|
-- we start, to satisfy the lookupIdSubst invariants (#20200 and #20294)
|
|
1735
|
1734
|
|
|
1736
|
|
-addLvl :: Level -> VarEnv Level -> OutVar -> VarEnv Level
|
|
|
1735
|
+ctxtLevel :: LevelEnv -> Level
|
|
|
1736
|
+ctxtLevel = le_ctxt_lvl
|
|
|
1737
|
+
|
|
|
1738
|
+addLvl :: Level -> VarEnv Level -> InVar -> VarEnv Level
|
|
1737
|
1739
|
addLvl dest_lvl env v' = extendVarEnv env v' dest_lvl
|
|
1738
|
1740
|
|
|
1739
|
|
-addLvls :: Level -> VarEnv Level -> [OutVar] -> VarEnv Level
|
|
|
1741
|
+addLvls :: Level -> VarEnv Level -> [InVar] -> VarEnv Level
|
|
1740
|
1742
|
addLvls dest_lvl env vs = foldl' (addLvl dest_lvl) env vs
|
|
1741
|
1743
|
|
|
1742
|
1744
|
floatLams :: LevelEnv -> Maybe Int
|
| ... |
... |
@@ -1751,9 +1753,6 @@ floatOverSat le = floatOutOverSatApps (le_switches le) |
|
1751
|
1753
|
floatTopLvlOnly :: LevelEnv -> Bool
|
|
1752
|
1754
|
floatTopLvlOnly le = floatToTopLevelOnly (le_switches le)
|
|
1753
|
1755
|
|
|
1754
|
|
-incMinorLvlFrom :: LevelEnv -> Level
|
|
1755
|
|
-incMinorLvlFrom env = incMinorLvl (le_ctxt_lvl env)
|
|
1756
|
|
-
|
|
1757
|
1756
|
-- extendCaseBndrEnv adds the mapping case-bndr->scrut-var if it can
|
|
1758
|
1757
|
-- See Note [Binder-swap during float-out]
|
|
1759
|
1758
|
extendCaseBndrEnv :: LevelEnv
|
| ... |
... |
@@ -1769,34 +1768,25 @@ extendCaseBndrEnv le@(LE { le_subst = subst, le_env = id_env }) |
|
1769
|
1768
|
, le_env = add_id id_env (case_bndr, scrut_var) }
|
|
1770
|
1769
|
extendCaseBndrEnv env _ _ = env
|
|
1771
|
1770
|
|
|
1772
|
|
-maxFvLevel :: (OutVar -> Bool) -> LevelEnv -> DVarSet -> Level
|
|
1773
|
|
-maxFvLevel max_me env var_set
|
|
1774
|
|
- = nonDetStrictFoldDVarSet (maxIn max_me env) tOP_LEVEL var_set
|
|
|
1771
|
+maxFvLevel :: Bool -> LevelEnv -> DVarSet -> Level
|
|
|
1772
|
+-- True <=> include type variables
|
|
|
1773
|
+maxFvLevel include_tyvars (LE { le_lvl_env = env }) var_set
|
|
|
1774
|
+ = nonDetStrictFoldDVarSet (maxIn include_tyvars env) tOP_LEVEL var_set
|
|
1775
|
1775
|
-- It's OK to use a non-deterministic fold here because maxIn commutes.
|
|
1776
|
1776
|
|
|
1777
|
|
-maxFvLevel' :: (OutVar -> Bool) -> LevelEnv -> TyCoVarSet -> Level
|
|
|
1777
|
+maxFvLevel' :: Bool -> LevelEnv -> TyCoVarSet -> Level
|
|
1778
|
1778
|
-- Same but for TyCoVarSet
|
|
1779
|
|
-maxFvLevel' max_me env var_set
|
|
1780
|
|
- = nonDetStrictFoldUniqSet (maxIn max_me env) tOP_LEVEL var_set
|
|
|
1779
|
+maxFvLevel' include_tyvars (LE { le_lvl_env = env }) var_set
|
|
|
1780
|
+ = nonDetStrictFoldUniqSet (maxIn include_tyvars env) tOP_LEVEL var_set
|
|
1781
|
1781
|
-- It's OK to use a non-deterministic fold here because maxIn commutes.
|
|
1782
|
1782
|
|
|
1783
|
|
-maxIn :: (OutVar -> Bool) -> LevelEnv -> InVar -> Level -> Level
|
|
1784
|
|
-maxIn max_me (LE { le_lvl_env = lvl_env, le_env = id_env, le_subst = subst }) in_var lvl
|
|
1785
|
|
- | isId in_var
|
|
1786
|
|
- = case lookupVarEnv id_env in_var of
|
|
1787
|
|
- Just (abs_vars, _) -> foldr max_out lvl abs_vars
|
|
1788
|
|
- Nothing -> max_out in_var lvl
|
|
1789
|
|
- | otherwise -- TyVars
|
|
1790
|
|
- = case lookupTyVar subst in_var of
|
|
1791
|
|
- Just ty -> nonDetStrictFoldVarSet max_out lvl (tyCoVarsOfType ty)
|
|
1792
|
|
- Nothing -> max_out in_var lvl
|
|
1793
|
|
- where
|
|
1794
|
|
- max_out :: OutVar -> Level -> Level
|
|
1795
|
|
- max_out out_var lvl
|
|
1796
|
|
- | max_me out_var = case lookupVarEnv lvl_env out_var of
|
|
1797
|
|
- Just lvl' -> maxLvl lvl' lvl
|
|
1798
|
|
- Nothing -> lvl
|
|
1799
|
|
- | otherwise = lvl -- Ignore some vars depending on max_me
|
|
|
1783
|
+maxIn :: Bool -> VarEnv Level -> InVar -> Level -> Level
|
|
|
1784
|
+maxIn include_tyvars lvl_env var lvl
|
|
|
1785
|
+ | not include_tyvars, isTyVar var = lvl
|
|
|
1786
|
+ | otherwise = maxLvl lvl (lookupLevel lvl_env var)
|
|
|
1787
|
+
|
|
|
1788
|
+lookupLevel :: VarEnv Level -> InVar -> Level
|
|
|
1789
|
+lookupLevel env v = lookupVarEnv env v `orElse` tOP_LEVEL
|
|
1800
|
1790
|
|
|
1801
|
1791
|
lookupVar :: LevelEnv -> Id -> LevelledExpr
|
|
1802
|
1792
|
lookupVar le v = case lookupVarEnv (le_env le) v of
|
| ... |
... |
@@ -1841,18 +1831,17 @@ type LvlM result = UniqSM result |
|
1841
|
1831
|
initLvl :: UniqSupply -> UniqSM a -> a
|
|
1842
|
1832
|
initLvl = initUs_
|
|
1843
|
1833
|
|
|
1844
|
|
-newPolyBndrs :: Level -> LevelEnv -> [OutVar] -> [InId]
|
|
1845
|
|
- -> LvlM (LevelEnv, [OutId])
|
|
|
1834
|
+newPolyBndrs :: LevelEnv -> Level -> [OutVar] -> [InId]
|
|
|
1835
|
+ -> LvlM (LevelEnv, [LevelledBndr])
|
|
1846
|
1836
|
-- The envt is extended to bind the new bndrs to dest_lvl, but
|
|
1847
|
1837
|
-- the le_ctxt_lvl is unaffected
|
|
1848
|
|
-newPolyBndrs dest_lvl
|
|
1849
|
|
- env@(LE { le_lvl_env = lvl_env, le_subst = subst, le_env = id_env })
|
|
1850
|
|
- abs_vars bndrs
|
|
|
1838
|
+newPolyBndrs env@(LE { le_lvl_env = lvl_env, le_subst = subst, le_env = id_env })
|
|
|
1839
|
+ dest_lvl abs_vars in_bndrs
|
|
1851
|
1840
|
= assert (all (not . isCoVar) bndrs) $ -- What would we add to the CoSubst in this case. No easy answer.
|
|
1852
|
1841
|
do { uniqs <- getUniquesM
|
|
1853
|
1842
|
; let new_bndrs = zipWith mk_poly_bndr bndrs uniqs
|
|
1854
|
1843
|
bndr_prs = bndrs `zip` new_bndrs
|
|
1855
|
|
- env' = env { le_lvl_env = addLvls dest_lvl lvl_env new_bndrs
|
|
|
1844
|
+ env' = env { le_lvl_env = addLvls dest_lvl lvl_env in_bndrs
|
|
1856
|
1845
|
, le_subst = foldl' add_subst subst bndr_prs
|
|
1857
|
1846
|
, le_env = foldl' add_id id_env bndr_prs }
|
|
1858
|
1847
|
; return (env', new_bndrs) }
|
| ... |
... |
@@ -1860,12 +1849,15 @@ newPolyBndrs dest_lvl |
|
1860
|
1849
|
add_subst env (v, v') = extendIdSubst env v (mkVarApps (Var v') abs_vars)
|
|
1861
|
1850
|
add_id env (v, v') = extendVarEnv env v ((v':abs_vars), mkVarApps (Var v') abs_vars)
|
|
1862
|
1851
|
|
|
1863
|
|
- mk_poly_bndr bndr uniq = transferPolyIdInfo bndr abs_vars $ -- Note [transferPolyIdInfo] in GHC.Types.Id
|
|
1864
|
|
- transfer_join_info bndr $
|
|
1865
|
|
- mkSysLocal str uniq (idMult bndr) poly_ty
|
|
1866
|
|
- where
|
|
1867
|
|
- str = fsLit "poly_" `appendFS` occNameFS (getOccName bndr)
|
|
1868
|
|
- poly_ty = mkLamTypes abs_vars (substTyUnchecked subst (idType bndr))
|
|
|
1852
|
+ mk_poly_bndr :: InId -> Unique -> LevelledBndr
|
|
|
1853
|
+ mk_poly_bndr bndr uniq
|
|
|
1854
|
+ = TB new_bndr (FloatMe dest_lvl)
|
|
|
1855
|
+ where
|
|
|
1856
|
+ new_bndr = transferPolyIdInfo bndr abs_vars $ -- Note [transferPolyIdInfo] in GHC.Types.Id
|
|
|
1857
|
+ transfer_join_info bndr $
|
|
|
1858
|
+ mkSysLocal str uniq (idMult bndr) poly_ty
|
|
|
1859
|
+ str = fsLit "poly_" `appendFS` occNameFS (getOccName bndr)
|
|
|
1860
|
+ poly_ty = mkLamTypes abs_vars (substTyUnchecked subst (idType bndr))
|
|
1869
|
1861
|
|
|
1870
|
1862
|
-- If we are floating a join point to top level, it stops being
|
|
1871
|
1863
|
-- a join point. Otherwise it continues to be a join point,
|
| ... |
... |
@@ -1900,21 +1892,22 @@ newLvlVar lvld_rhs join_arity_maybe is_mk_static |
|
1900
|
1892
|
= mkSysLocal (mkFastString "lvl") uniq ManyTy rhs_ty
|
|
1901
|
1893
|
|
|
1902
|
1894
|
-- | Clone the binders bound by a single-alternative case.
|
|
1903
|
|
-cloneCaseBndrs :: LevelEnv -> Level -> [Var] -> LvlM (LevelEnv, [Var])
|
|
|
1895
|
+cloneCaseBndrs :: LevelEnv -> Level -> [Var] -> LvlM (LevelEnv, [LevelledBndr])
|
|
1904
|
1896
|
cloneCaseBndrs env@(LE { le_subst = subst, le_lvl_env = lvl_env, le_env = id_env })
|
|
1905
|
|
- new_lvl vs
|
|
|
1897
|
+ dest_lvl vs
|
|
1906
|
1898
|
= do { (subst', vs') <- cloneBndrsM subst vs
|
|
1907
|
1899
|
-- N.B. We are not moving the body of the case, merely its case
|
|
1908
|
1900
|
-- binders. Consequently we should *not* set le_ctxt_lvl.
|
|
1909
|
1901
|
-- See Note [Setting levels when floating single-alternative cases].
|
|
1910
|
|
- ; let env' = env { le_lvl_env = addLvls new_lvl lvl_env vs'
|
|
|
1902
|
+ ; let lvld_bndrs = stayPut dest_lvl vs'
|
|
|
1903
|
+ env' = env { le_lvl_env = addLvls dest_lvl lvl_env vs'
|
|
1911
|
1904
|
, le_subst = subst'
|
|
1912
|
|
- , le_env = foldl' add_id id_env (vs `zip` vs') }
|
|
|
1905
|
+ , le_env = foldl' add_id id_env (vs `zip` lvld_bndrs) }
|
|
1913
|
1906
|
|
|
1914
|
|
- ; return (env', vs') }
|
|
|
1907
|
+ ; return (env', lvld_bndrs) }
|
|
1915
|
1908
|
|
|
1916
|
1909
|
cloneLetVars :: RecFlag -> LevelEnv -> Level -> [InVar]
|
|
1917
|
|
- -> LvlM (LevelEnv, [OutVar])
|
|
|
1910
|
+ -> LvlM (LevelEnv, [LevelledBndr])
|
|
1918
|
1911
|
-- See Note [Need for cloning during float-out]
|
|
1919
|
1912
|
-- Works for Ids bound by let(rec)
|
|
1920
|
1913
|
-- The dest_lvl is attributed to the binders in the new env,
|
| ... |
... |
@@ -1927,12 +1920,13 @@ cloneLetVars is_rec |
|
1927
|
1920
|
NonRecursive -> cloneBndrsM subst vs1
|
|
1928
|
1921
|
Recursive -> cloneRecIdBndrsM subst vs1
|
|
1929
|
1922
|
|
|
1930
|
|
- ; let prs = vs `zip` vs2
|
|
1931
|
|
- env' = env { le_lvl_env = addLvls dest_lvl lvl_env vs2
|
|
|
1923
|
+ ; let lvld_bndrs = [ TB v2 (FloatMe dest_lvl) | v2 <- vs2 ]
|
|
|
1924
|
+ prs = vs `zip` lvld_bndrs
|
|
|
1925
|
+ env' = env { le_lvl_env = addLvls dest_lvl lvl_env vs
|
|
1932
|
1926
|
, le_subst = subst'
|
|
1933
|
1927
|
, le_env = foldl' add_id id_env prs }
|
|
1934
|
1928
|
|
|
1935
|
|
- ; return (env', vs2) }
|
|
|
1929
|
+ ; return (env', lvld_bndrs) }
|
|
1936
|
1930
|
where
|
|
1937
|
1931
|
zap :: Var -> Var
|
|
1938
|
1932
|
-- See Note [Floatifying demand info when floating]
|
| ... |
... |
@@ -1944,10 +1938,11 @@ cloneLetVars is_rec |
|
1944
|
1938
|
zap_join | isTopLvl dest_lvl = zapJoinId
|
|
1945
|
1939
|
| otherwise = id
|
|
1946
|
1940
|
|
|
1947
|
|
-add_id :: IdEnv ([Var], LevelledExpr) -> (Var, Var) -> IdEnv ([Var], LevelledExpr)
|
|
1948
|
|
-add_id id_env (v, v1)
|
|
|
1941
|
+add_id :: IdEnv ([LevelledBndr], LevelledExpr) -> (Var, LevelledBndr)
|
|
|
1942
|
+ -> IdEnv ([LevelledBndr], LevelledExpr)
|
|
|
1943
|
+add_id id_env (v, lb@(TB v1 _))
|
|
1949
|
1944
|
| isTyVar v = delVarEnv id_env v
|
|
1950
|
|
- | otherwise = extendVarEnv id_env v ([v1], assert (not (isCoVar v1)) $ Var v1)
|
|
|
1945
|
+ | otherwise = extendVarEnv id_env v ([lb], assert (not (isCoVar v1)) $ Var v1)
|
|
1951
|
1946
|
|
|
1952
|
1947
|
{- Note [Zapping JoinId when floating]
|
|
1953
|
1948
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|