... |
... |
@@ -1628,13 +1628,11 @@ specCalls spec_imp env existing_rules calls_for_me fn rhs |
1628
|
1628
|
do { let all_call_args | is_dfun = saturating_call_args -- See Note [Specialising DFuns]
|
1629
|
1629
|
| otherwise = call_args
|
1630
|
1630
|
saturating_call_args = call_args ++ map mk_extra_dfun_arg (dropList call_args rhs_bndrs)
|
1631
|
|
- mk_extra_dfun_arg bndr | isTyVar bndr = UnspecType
|
1632
|
|
- | otherwise = UnspecArg
|
|
1631
|
+ mk_extra_dfun_arg bndr | isTyVar bndr = UnspecType (tyVarKind bndr) -- ToDo: right?
|
|
1632
|
+ | otherwise = UnspecArg (idType bndr)
|
1633
|
1633
|
|
1634
|
1634
|
; (useful, rule_bndrs, rule_lhs_args, spec_bndrs1, spec_args) <- specHeader env all_call_args
|
1635
|
1635
|
|
1636
|
|
-
|
1637
|
|
-
|
1638
|
1636
|
-- ; pprTrace "spec_call" (vcat
|
1639
|
1637
|
-- [ text "fun: " <+> ppr fn
|
1640
|
1638
|
-- , text "call info: " <+> ppr _ci
|
... |
... |
@@ -1642,7 +1640,6 @@ specCalls spec_imp env existing_rules calls_for_me fn rhs |
1642
|
1640
|
-- , text "rule_bndrs:" <+> ppr rule_bndrs
|
1643
|
1641
|
-- , text "lhs_args: " <+> ppr rule_lhs_args
|
1644
|
1642
|
-- , text "spec_bndrs1:" <+> ppr spec_bndrs1
|
1645
|
|
--- , text "leftover_bndrs:" <+> pprIds leftover_bndrs
|
1646
|
1643
|
-- , text "spec_args: " <+> ppr spec_args
|
1647
|
1644
|
-- , text "dx_binds: " <+> ppr dx_binds
|
1648
|
1645
|
-- , text "rhs_bndrs" <+> ppr rhs_bndrs
|
... |
... |
@@ -1664,12 +1661,9 @@ specCalls spec_imp env existing_rules calls_for_me fn rhs |
1664
|
1661
|
; (rhs_body', rhs_uds) <- specRhs env rhs_bndrs rhs_body spec_args
|
1665
|
1662
|
-- Add the { d1' = dx1; d2' = dx2 } usage stuff
|
1666
|
1663
|
-- to the rhs_uds; see Note [Specialising Calls]
|
1667
|
|
- ; let rhs_uds_w_dx = dx_binds `consDictBinds` rhs_uds
|
1668
|
|
- spec_rhs_bndrs = spec_bndrs1 ++ leftover_bndrs
|
1669
|
|
- (spec_uds, dumped_dbs) = dumpUDs spec_rhs_bndrs rhs_uds_w_dx
|
1670
|
|
- spec_rhs1 = mkLams spec_rhs_bndrs $
|
|
1664
|
+ ; let (spec_uds, dumped_dbs) = dumpUDs spec_bndrs1 rhs_uds
|
|
1665
|
+ spec_rhs1 = mkLams spec_bndrs1 $
|
1671
|
1666
|
wrapDictBindsE dumped_dbs rhs_body'
|
1672
|
|
-
|
1673
|
1667
|
spec_fn_ty1 = exprType spec_rhs1
|
1674
|
1668
|
|
1675
|
1669
|
-- Maybe add a void arg to the specialised function,
|
... |
... |
@@ -1690,7 +1684,7 @@ specCalls spec_imp env existing_rules calls_for_me fn rhs |
1690
|
1684
|
-- The wrap_unf_body applies the original unfolding to the specialised
|
1691
|
1685
|
-- arguments, not forgetting to wrap the dx_binds around the outside (#22358)
|
1692
|
1686
|
simpl_opts = initSimpleOpts dflags
|
1693
|
|
- wrap_unf_body body = foldr (Let . db_bind) (body `mkApps` spec_args) dx_binds
|
|
1687
|
+ wrap_unf_body body = body `mkApps` spec_args
|
1694
|
1688
|
spec_unf = specUnfolding simpl_opts spec_bndrs wrap_unf_body
|
1695
|
1689
|
rule_lhs_args fn_unf
|
1696
|
1690
|
|
... |
... |
@@ -1769,6 +1763,33 @@ alreadyCovered env bndrs fn args is_active rules |
1769
|
1763
|
where
|
1770
|
1764
|
in_scope = substInScopeSet (se_subst env)
|
1771
|
1765
|
|
|
1766
|
+specRhs :: SpecEnv -> [Var] -> CoreExpr -> [CoreExpr]
|
|
1767
|
+ -> SpecM (CoreExpr, UsageDetails)
|
|
1768
|
+
|
|
1769
|
+specRhs env bndrs body []
|
|
1770
|
+ = specLam env bndrs body
|
|
1771
|
+
|
|
1772
|
+specRhs env [] body args
|
|
1773
|
+ = -- The caller should have ensured that there are no more
|
|
1774
|
+ -- args than we have binders on the RHS
|
|
1775
|
+ pprPanic "specRhs:too many args" (ppr args $$ ppr body)
|
|
1776
|
+
|
|
1777
|
+specRhs env@(SE { se_subst = subst }) (bndr:bndrs) body (arg:args)
|
|
1778
|
+ | exprIsTrivial arg
|
|
1779
|
+ , let env' = env { se_subst = Core.extendSubst subst bndr arg }
|
|
1780
|
+ = specRhs env' bndrs body args
|
|
1781
|
+
|
|
1782
|
+
|
|
1783
|
+ | otherwise -- Non-trivial argument; it must be a dictionary
|
|
1784
|
+ = do { fresh_dict_id <- newIdBndr "dx" (idType bndr)
|
|
1785
|
+ ; let fresh_dict_id' = fresh_dict_id `addDictUnfolding` arg
|
|
1786
|
+ dict_bind = mkDB (NonRec fresh_dict_id' arg)
|
|
1787
|
+ env2 = env1 { se_subst = Core.extendSubst subst bndr (Var fresh_dict_id')
|
|
1788
|
+ `Core.extendSubstInScope` fresh_dict_id' }
|
|
1789
|
+ -- Ensure the new unfolding is in the in-scope set
|
|
1790
|
+ ; (body', uds) <- specRhs env2 bndrs body args
|
|
1791
|
+ ; return (body', dict_bind `consDictBind` uds) }
|
|
1792
|
+
|
1772
|
1793
|
-- Convenience function for invoking lookupRule from Specialise
|
1773
|
1794
|
-- The SpecEnv's InScopeSet should include all the Vars in the [CoreExpr]
|
1774
|
1795
|
specLookupRule :: SpecEnv -> Id -> [CoreExpr]
|
... |
... |
@@ -2426,7 +2447,7 @@ data SpecArg |
2426
|
2447
|
SpecType Type
|
2427
|
2448
|
|
2428
|
2449
|
-- | Type arguments that should remain polymorphic.
|
2429
|
|
- | UnspecType
|
|
2450
|
+ | UnspecType Kind
|
2430
|
2451
|
|
2431
|
2452
|
-- | Dictionaries that should be specialised. mkCallUDs ensures
|
2432
|
2453
|
-- that only "interesting" dictionary arguments get a SpecDict;
|
... |
... |
@@ -2434,25 +2455,25 @@ data SpecArg |
2434
|
2455
|
| SpecDict DictExpr
|
2435
|
2456
|
|
2436
|
2457
|
-- | Value arguments that should not be specialised.
|
2437
|
|
- | UnspecArg
|
|
2458
|
+ | UnspecArg Type
|
2438
|
2459
|
|
2439
|
2460
|
instance Outputable SpecArg where
|
2440
|
|
- ppr (SpecType t) = text "SpecType" <+> ppr t
|
2441
|
|
- ppr UnspecType = text "UnspecType"
|
2442
|
|
- ppr (SpecDict d) = text "SpecDict" <+> ppr d
|
2443
|
|
- ppr UnspecArg = text "UnspecArg"
|
|
2461
|
+ ppr (SpecType t) = text "SpecType" <+> ppr t
|
|
2462
|
+ ppr (UnspecType k) = text "UnspecType"
|
|
2463
|
+ ppr (SpecDict d) = text "SpecDict" <+> ppr d
|
|
2464
|
+ ppr (UnspecArg t) = text "UnspecArg"
|
2444
|
2465
|
|
2445
|
2466
|
specArgFreeIds :: SpecArg -> IdSet
|
2446
|
|
-specArgFreeIds (SpecType {}) = emptyVarSet
|
2447
|
|
-specArgFreeIds (SpecDict dx) = exprFreeIds dx
|
2448
|
|
-specArgFreeIds UnspecType = emptyVarSet
|
2449
|
|
-specArgFreeIds UnspecArg = emptyVarSet
|
|
2467
|
+specArgFreeIds (SpecType {}) = emptyVarSet
|
|
2468
|
+specArgFreeIds (SpecDict dx) = exprFreeIds dx
|
|
2469
|
+specArgFreeIds (UnspecType {}) = emptyVarSet
|
|
2470
|
+specArgFreeIds (UnspecArg {}) = emptyVarSet
|
2450
|
2471
|
|
2451
|
2472
|
specArgFreeVars :: SpecArg -> VarSet
|
2452
|
|
-specArgFreeVars (SpecType ty) = tyCoVarsOfType ty
|
2453
|
|
-specArgFreeVars (SpecDict dx) = exprFreeVars dx
|
2454
|
|
-specArgFreeVars UnspecType = emptyVarSet
|
2455
|
|
-specArgFreeVars UnspecArg = emptyVarSet
|
|
2473
|
+specArgFreeVars (SpecType ty) = tyCoVarsOfType ty
|
|
2474
|
+specArgFreeVars (UnspecType ki) = tyCoVarsOfType ki
|
|
2475
|
+specArgFreeVars (SpecDict dx) = exprFreeVars dx
|
|
2476
|
+specArgFreeVars (UnspecArg ty) = tyCoVarsOfType ty
|
2456
|
2477
|
|
2457
|
2478
|
isSpecDict :: SpecArg -> Bool
|
2458
|
2479
|
isSpecDict (SpecDict {}) = True
|
... |
... |
@@ -2521,7 +2542,7 @@ specHeader |
2521
|
2542
|
-- We want to specialise on type 'T1', and so we must construct a substitution
|
2522
|
2543
|
-- 'a->T1', as well as a LHS argument for the resulting RULE and unfolding
|
2523
|
2544
|
-- details.
|
2524
|
|
-specHeader env (bndr : bndrs) (SpecType ty : args)
|
|
2545
|
+specHeader env (SpecType ty : args)
|
2525
|
2546
|
= do { -- Find qvars, the type variables to add to the binders for the rule
|
2526
|
2547
|
-- Namely those free in `ty` that aren't in scope
|
2527
|
2548
|
-- See (MP2) in Note [Specialising polymorphic dictionaries]
|
... |
... |
@@ -2529,7 +2550,7 @@ specHeader env (bndr : bndrs) (SpecType ty : args) |
2529
|
2550
|
qvars = scopedSort $
|
2530
|
2551
|
filterOut (`elemInScopeSet` in_scope) $
|
2531
|
2552
|
tyCoVarsOfTypeList ty
|
2532
|
|
- ; (useful, rule_bs, rule_args, spec_bs, spec_args) <- specHeader env2 args
|
|
2553
|
+ ; (useful, rule_bs, rule_args, spec_bs, spec_args) <- specHeader env args
|
2533
|
2554
|
; pure ( useful
|
2534
|
2555
|
, qvars ++ rule_bs
|
2535
|
2556
|
, Type ty : rule_args
|
... |
... |
@@ -2542,17 +2563,13 @@ specHeader env (bndr : bndrs) (SpecType ty : args) |
2542
|
2563
|
-- a substitution on it (in case the type refers to 'a'). Additionally, we need
|
2543
|
2564
|
-- to produce a binder, LHS argument and RHS argument for the resulting rule,
|
2544
|
2565
|
-- /and/ a binder for the specialised body.
|
2545
|
|
-specHeader env (bndr : bndrs) (UnspecType : args)
|
2546
|
|
- = do { let (env', bndr') = substBndr env bndr
|
2547
|
|
- ; (useful, env'', leftover_bndrs, rule_bs, rule_es, bs', dx, spec_args)
|
2548
|
|
- <- specHeader env' bndrs args
|
|
2566
|
+specHeader env (UnspecType kind : args)
|
|
2567
|
+ = do { (useful, rule_bs, rule_es, spec_bs, spec_args) <- specHeader env' bndrs args
|
|
2568
|
+ ; tv <- newTyVarBndr kind
|
2549
|
2569
|
; pure ( useful
|
2550
|
|
- , env''
|
2551
|
|
- , leftover_bndrs
|
2552
|
2570
|
, bndr' : rule_bs
|
2553
|
2571
|
, varToCoreExpr bndr' : rule_es
|
2554
|
|
- , bndr' : bs'
|
2555
|
|
- , dx
|
|
2572
|
+ , bndr' : spec_bs
|
2556
|
2573
|
, varToCoreExpr bndr' : spec_args
|
2557
|
2574
|
)
|
2558
|
2575
|
}
|
... |
... |
@@ -2560,27 +2577,21 @@ specHeader env (bndr : bndrs) (UnspecType : args) |
2560
|
2577
|
-- Next we want to specialise the 'Eq a' dict away. We need to construct
|
2561
|
2578
|
-- a wildcard binder to match the dictionary (See Note [Specialising Calls] for
|
2562
|
2579
|
-- the nitty-gritty), as a LHS rule and unfolding details.
|
2563
|
|
-specHeader env (bndr : bndrs) (SpecDict d : args)
|
|
2580
|
+specHeader env (SpecDict dict_arg : args)
|
2564
|
2581
|
| not (isDeadBinder bndr)
|
2565
|
2582
|
, allVarSet (`elemInScopeSet` in_scope) (exprFreeVars d)
|
2566
|
2583
|
-- See Note [Weird special case for SpecDict]
|
2567
|
|
- = do { (env1, bndr') <- newDictBndr env bndr -- See Note [Zap occ info in rule binders]
|
2568
|
|
- ; let (env2, dx_bind, spec_dict) = bindAuxiliaryDict env1 bndr bndr' d
|
2569
|
|
- ; (_, env3, leftover_bndrs, rule_bs, rule_es, bs', dx, spec_args)
|
2570
|
|
- <- specHeader env2 bndrs args
|
|
2584
|
+ = do { (_, rule_bs, rule_es, spec_bs, spec_args) <- specHeader env bndrs args
|
|
2585
|
+ ; new_dict_id <- newIdBndr "dx" (exprType dict_arg)
|
|
2586
|
+ ; let new_dict_expr = varToCoreExpr new_dict_id
|
|
2587
|
+ -- See Note [Evidence foralls]
|
2571
|
2588
|
; pure ( True -- Ha! A useful specialisation!
|
2572
|
|
- , env3
|
2573
|
|
- , leftover_bndrs
|
2574
|
|
- -- See Note [Evidence foralls]
|
2575
|
|
- , exprFreeIdsList (varToCoreExpr bndr') ++ rule_bs
|
2576
|
|
- , varToCoreExpr bndr' : rule_es
|
2577
|
|
- , bs'
|
2578
|
|
- , maybeToList dx_bind ++ dx
|
2579
|
|
- , spec_dict : spec_args
|
|
2589
|
+ , exprFreeIdsList new_dict_expr ++ rule_bs
|
|
2590
|
+ , new_dict_expr : rule_es
|
|
2591
|
+ , spec_bs
|
|
2592
|
+ , dict_arg : spec_args
|
2580
|
2593
|
)
|
2581
|
2594
|
}
|
2582
|
|
- where
|
2583
|
|
- in_scope = Core.substInScopeSet (se_subst env)
|
2584
|
2595
|
|
2585
|
2596
|
-- Finally, we don't want to specialise on this argument 'i':
|
2586
|
2597
|
-- - It's an UnSpecArg, or
|
... |
... |
@@ -2592,13 +2603,14 @@ specHeader env (bndr : bndrs) (SpecDict d : args) |
2592
|
2603
|
-- why 'i' doesn't appear in our RULE above. But we have no guarantee that
|
2593
|
2604
|
-- there aren't 'UnspecArg's which come /before/ all of the dictionaries, so
|
2594
|
2605
|
-- this case must be here.
|
2595
|
|
-specHeader env (bndr : bndrs) (_ : args)
|
|
2606
|
+specHeader env (arg : args)
|
2596
|
2607
|
-- The "_" can be UnSpecArg, or SpecDict where the bndr is dead
|
2597
|
2608
|
= do { -- see Note [Zap occ info in rule binders]
|
2598
|
|
- let (env', bndr') = substBndr env (zapIdOccInfo bndr)
|
2599
|
|
- ; (useful, env'', leftover_bndrs, rule_bs, rule_es, bs', dx, spec_args)
|
2600
|
|
- <- specHeader env' bndrs args
|
|
2609
|
+ ; (useful, rule_bs, rule_es, spec_bs, spec_args) <- specHeader env bndrs args
|
2601
|
2610
|
|
|
2611
|
+ ; spec_bndr <- case arg of
|
|
2612
|
+ SpecDict d -> newIdBndr "dx" (exprType d)
|
|
2613
|
+ UnspecArg t -> newIdBndr "x" t
|
2602
|
2614
|
; let bndr_ty = idType bndr'
|
2603
|
2615
|
|
2604
|
2616
|
-- See Note [Drop dead args from specialisations]
|
... |
... |
@@ -2611,14 +2623,11 @@ specHeader env (bndr : bndrs) (_ : args) |
2611
|
2623
|
= (Just bndr', varToCoreExpr bndr')
|
2612
|
2624
|
|
2613
|
2625
|
; pure ( useful
|
2614
|
|
- , env''
|
2615
|
|
- , leftover_bndrs
|
2616
|
2626
|
, bndr' : rule_bs
|
2617
|
2627
|
, varToCoreExpr bndr' : rule_es
|
2618
|
2628
|
, case mb_spec_bndr of
|
2619
|
|
- Just b' -> b' : bs'
|
2620
|
|
- Nothing -> bs'
|
2621
|
|
- , dx
|
|
2629
|
+ Just b -> b : spec_bs
|
|
2630
|
+ Nothing -> spec_bs
|
2622
|
2631
|
, spec_arg : spec_args
|
2623
|
2632
|
)
|
2624
|
2633
|
}
|
... |
... |
@@ -2636,6 +2645,7 @@ specHeader env bndrs [] |
2636
|
2645
|
(env', bndrs') = substBndrs env bndrs
|
2637
|
2646
|
|
2638
|
2647
|
|
|
2648
|
+{-
|
2639
|
2649
|
-- | Binds a dictionary argument to a fresh name, to preserve sharing
|
2640
|
2650
|
bindAuxiliaryDict
|
2641
|
2651
|
:: SpecEnv
|
... |
... |
@@ -2662,7 +2672,7 @@ bindAuxiliaryDict env@(SE { se_subst = subst }) |
2662
|
2672
|
-- Ensure the new unfolding is in the in-scope set
|
2663
|
2673
|
in -- pprTrace "bindAuxiliaryDict:non-trivial" (ppr orig_dict_id <+> ppr fresh_dict_id') $
|
2664
|
2674
|
(env', Just dict_bind, Var fresh_dict_id')
|
2665
|
|
-
|
|
2675
|
+-}
|
2666
|
2676
|
addDictUnfolding :: Id -> CoreExpr -> Id
|
2667
|
2677
|
-- Add unfolding for freshly-bound Ids: see Note [Make the new dictionaries interesting]
|
2668
|
2678
|
-- and Note [Specialisation modulo dictionary selectors]
|
... |
... |
@@ -2977,16 +2987,13 @@ singleCall spec_env id args |
2977
|
2987
|
unitBag (CI { ci_key = args
|
2978
|
2988
|
, ci_fvs = call_fvs }) }
|
2979
|
2989
|
where
|
2980
|
|
- call_fvs =
|
2981
|
|
- foldr (unionVarSet . free_var_fn) emptyVarSet args
|
|
2990
|
+ call_fvs = foldr (unionVarSet . free_var_fn) emptyVarSet args
|
2982
|
2991
|
|
2983
|
2992
|
free_var_fn =
|
2984
|
2993
|
if gopt Opt_PolymorphicSpecialisation (se_dflags spec_env)
|
2985
|
2994
|
then specArgFreeIds
|
2986
|
2995
|
else specArgFreeVars
|
2987
|
2996
|
|
2988
|
|
-
|
2989
|
|
-
|
2990
|
2997
|
-- specArgFreeIds: we specifically look for free Ids, not TyVars
|
2991
|
2998
|
-- see (MP1) in Note [Specialising polymorphic dictionaries]
|
2992
|
2999
|
--
|
... |
... |
@@ -3022,12 +3029,13 @@ mkCallUDs' env f args |
3022
|
3029
|
-- Establish (CI-KEY): drop trailing args until we get to a SpecDict
|
3023
|
3030
|
|
3024
|
3031
|
mk_spec_arg :: OutExpr -> PiTyBinder -> SpecArg
|
3025
|
|
- mk_spec_arg arg (Named bndr)
|
|
3032
|
+ mk_spec_arg (Type ty) (Named bndr)
|
3026
|
3033
|
| binderVar bndr `elemVarSet` constrained_tyvars
|
3027
|
|
- = case arg of
|
3028
|
|
- Type ty -> SpecType ty
|
3029
|
|
- _ -> pprPanic "ci_key" $ ppr arg
|
3030
|
|
- | otherwise = UnspecType
|
|
3034
|
+ = SpecType ty
|
|
3035
|
+ | otherwise
|
|
3036
|
+ = UnspecType (typeKind ty)
|
|
3037
|
+ mk_spec_arg non_type_arg (Named bndr)
|
|
3038
|
+ = = pprPanic "ci_key" $ (ppr non_type_arg $$ ppr bndr)
|
3031
|
3039
|
|
3032
|
3040
|
-- For "invisibleFunArg", which are the type-class dictionaries,
|
3033
|
3041
|
-- we decide on a case by case basis if we want to specialise
|
... |
... |
@@ -3038,7 +3046,7 @@ mkCallUDs' env f args |
3038
|
3046
|
-- See Note [Interesting dictionary arguments]
|
3039
|
3047
|
= SpecDict arg
|
3040
|
3048
|
|
3041
|
|
- | otherwise = UnspecArg
|
|
3049
|
+ | otherwise = UnspecArg (exprType arg)
|
3042
|
3050
|
|
3043
|
3051
|
{-
|
3044
|
3052
|
Note [Ticks on applications]
|
... |
... |
@@ -3277,10 +3285,10 @@ snocDictBinds uds@MkUD{ud_binds=FDB{ fdb_binds = binds, fdb_bndrs = bs }} dbs |
3277
|
3285
|
= uds { ud_binds = FDB { fdb_binds = binds `appOL` (toOL dbs)
|
3278
|
3286
|
, fdb_bndrs = bs `extendVarSetList` bindersOfDictBinds dbs } }
|
3279
|
3287
|
|
3280
|
|
-consDictBinds :: [DictBind] -> UsageDetails -> UsageDetails
|
3281
|
|
-consDictBinds dbs uds@MkUD{ud_binds=FDB{fdb_binds = binds, fdb_bndrs = bs}}
|
3282
|
|
- = uds { ud_binds = FDB{ fdb_binds = toOL dbs `appOL` binds
|
3283
|
|
- , fdb_bndrs = bs `extendVarSetList` bindersOfDictBinds dbs } }
|
|
3288
|
+consDictBind :: DictBind -> UsageDetails -> UsageDetails
|
|
3289
|
+consDictBind db uds@MkUD{ud_binds=FDB{fdb_binds = binds, fdb_bndrs = bs}}
|
|
3290
|
+ = uds { ud_binds = FDB{ fdb_binds = db `consOL` binds
|
|
3291
|
+ , fdb_bndrs = bs `extendVarSetList` bindersOfDictBind db } }
|
3284
|
3292
|
|
3285
|
3293
|
wrapDictBinds :: FloatedDictBinds -> [CoreBind] -> [CoreBind]
|
3286
|
3294
|
wrapDictBinds (FDB { fdb_binds = dbs }) binds
|
... |
... |
@@ -3394,10 +3402,10 @@ beats_or_same (CI { ci_key = args1 }) (CI { ci_key = args2 }) |
3394
|
3402
|
go _ _ = False
|
3395
|
3403
|
|
3396
|
3404
|
go_arg (SpecType ty1) (SpecType ty2) = isJust (tcMatchTy ty1 ty2)
|
3397
|
|
- go_arg UnspecType UnspecType = True
|
3398
|
|
- go_arg (SpecDict {}) (SpecDict {}) = True
|
3399
|
|
- go_arg UnspecArg UnspecArg = True
|
3400
|
|
- go_arg _ _ = False
|
|
3405
|
+ go_arg (UnspecType {}) (UnspecType {}) = True
|
|
3406
|
+ go_arg (SpecDict {}) (SpecDict {}) = True
|
|
3407
|
+ go_arg (UnspecArg {}) (UnspecArg {}) = True
|
|
3408
|
+ go_arg _ _ = False
|
3401
|
3409
|
|
3402
|
3410
|
----------------------
|
3403
|
3411
|
splitDictBinds :: FloatedDictBinds -> IdSet -> (FloatedDictBinds, OrdList DictBind, IdSet)
|
... |
... |
@@ -3504,17 +3512,6 @@ cloneRecBndrsSM env@(SE { se_subst = subst }) bndrs |
3504
|
3512
|
; let env' = env { se_subst = subst' }
|
3505
|
3513
|
; return (env', bndrs') }
|
3506
|
3514
|
|
3507
|
|
-newDictBndr :: SpecEnv -> CoreBndr -> SpecM (SpecEnv, CoreBndr)
|
3508
|
|
--- Make up completely fresh binders for the dictionaries
|
3509
|
|
--- Their bindings are going to float outwards
|
3510
|
|
-newDictBndr env@(SE { se_subst = subst }) b
|
3511
|
|
- = do { uniq <- getUniqueM
|
3512
|
|
- ; let n = idName b
|
3513
|
|
- ty' = substTyUnchecked subst (idType b)
|
3514
|
|
- b' = mkUserLocal (nameOccName n) uniq ManyTy ty' (getSrcSpan n)
|
3515
|
|
- env' = env { se_subst = subst `Core.extendSubstInScope` b' }
|
3516
|
|
- ; pure (env', b') }
|
3517
|
|
-
|
3518
|
3515
|
newSpecIdSM :: Name -> Type -> IdDetails -> IdInfo -> SpecM Id
|
3519
|
3516
|
-- Give the new Id a similar occurrence name to the old one
|
3520
|
3517
|
newSpecIdSM old_name new_ty details info
|
... |
... |
@@ -3524,6 +3521,19 @@ newSpecIdSM old_name new_ty details info |
3524
|
3521
|
; return (assert (not (isCoVarType new_ty)) $
|
3525
|
3522
|
mkLocalVar details new_name ManyTy new_ty info) }
|
3526
|
3523
|
|
|
3524
|
+newIdBndr :: String -> Type -> SpecM (SpecEnv, CoreBndr)
|
|
3525
|
+-- Make up completely fresh binders for the dictionaries
|
|
3526
|
+-- Their bindings are going to float outwards
|
|
3527
|
+newIdBndr env@(SE { se_subst = subst }) str ty
|
|
3528
|
+ = do { uniq <- getUniqueM
|
|
3529
|
+ ; return (mkUserLocal (mkVarOcc str) uniq ManyTy ty noSrcSpan) }
|
|
3530
|
+
|
|
3531
|
+newTyVarBndr :: Kind -> SpecM TyVar
|
|
3532
|
+newTyVarBndr kind
|
|
3533
|
+ = do { uniq <- getUniqueM
|
|
3534
|
+ ; let name = mkInternalName uniq (mkTyVarOcc "a") noSrcSpan
|
|
3535
|
+ ; return (mkTyVar name kind }
|
|
3536
|
+
|
3527
|
3537
|
{-
|
3528
|
3538
|
Old (but interesting) stuff about unboxed bindings
|
3529
|
3539
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
... |
... |
@@ -3535,7 +3545,7 @@ What should we do when a value is specialised to a *strict* unboxed value? |
3535
|
3545
|
in h:t
|
3536
|
3546
|
|
3537
|
3547
|
Could convert let to case:
|
3538
|
|
-
|
|
3548
|
+
|
3539
|
3549
|
map_*_Int# f (x:xs) = case f x of h# ->
|
3540
|
3550
|
let t = map f xs
|
3541
|
3551
|
in h#:t
|