| ... |
... |
@@ -2207,6 +2207,8 @@ fun_always_ok _ = True |
|
2207
|
2207
|
-- | A special version of 'exprOkForSpeculation' used during
|
|
2208
|
2208
|
-- Note [Speculative evaluation]. When the predicate arg `fun_ok` returns False
|
|
2209
|
2209
|
-- for `b`, then `b` is never considered ok-for-spec.
|
|
|
2210
|
+--
|
|
|
2211
|
+-- This is the whole reason for the fun_ok arg to expr_ok.
|
|
2210
|
2212
|
exprOkForSpecEval :: (Id -> Bool) -> CoreExpr -> Bool
|
|
2211
|
2213
|
exprOkForSpecEval fun_ok = expr_ok fun_ok primOpOkForSpeculation
|
|
2212
|
2214
|
|
| ... |
... |
@@ -2258,7 +2260,7 @@ expr_ok fun_ok primop_ok other_expr |
|
2258
|
2260
|
|
|
2259
|
2261
|
-----------------------------
|
|
2260
|
2262
|
app_ok :: (Id -> Bool) -> (PrimOp -> Bool) -> Id -> [CoreArg] -> Bool
|
|
2261
|
|
-app_ok fun_ok primop_ok fun args
|
|
|
2263
|
+app_ok fun_ok primop_ok fun val_args
|
|
2262
|
2264
|
| not (fun_ok fun)
|
|
2263
|
2265
|
= False -- This code path is only taken for exprOkForSpecEval
|
|
2264
|
2266
|
-- See Note [Speculative evaluation]
|
| ... |
... |
@@ -2282,17 +2284,18 @@ app_ok fun_ok primop_ok fun args |
|
2282
|
2284
|
|
|
2283
|
2285
|
ClassOpId _ is_terminating_result
|
|
2284
|
2286
|
| is_terminating_result -- See Note [exprOkForSpeculation and type classes]
|
|
2285
|
|
- -> assertPpr (n_val_args == 1) (ppr fun $$ ppr args) $
|
|
|
2287
|
+ -> assertPpr (n_val_args == 1) (ppr fun $$ ppr val_args) $
|
|
2286
|
2288
|
True
|
|
2287
|
2289
|
-- assert: terminating result type => can't be applied;
|
|
2288
|
2290
|
-- c.f the _other case below
|
|
2289
|
2291
|
|
|
2290
|
2292
|
PrimOpId op _
|
|
2291
|
2293
|
| primOpIsDiv op
|
|
2292
|
|
- , Lit divisor <- last args
|
|
|
2294
|
+ , Lit divisor <- last val_args
|
|
2293
|
2295
|
-- there can be 2 args (most div primops) or 3 args
|
|
2294
|
2296
|
-- (WordQuotRem2Op), hence the use of last/init
|
|
2295
|
|
- -> not (isZeroLit divisor) && all (expr_ok fun_ok primop_ok) (init args)
|
|
|
2297
|
+ -> not (isZeroLit divisor) &&
|
|
|
2298
|
+ all ok_for_spec (init val_args)
|
|
2296
|
2299
|
-- Special case for dividing operations that fail
|
|
2297
|
2300
|
-- In general they are NOT ok-for-speculation
|
|
2298
|
2301
|
-- (which primop_ok will catch), but they ARE OK
|
| ... |
... |
@@ -2301,12 +2304,14 @@ app_ok fun_ok primop_ok fun args |
|
2301
|
2304
|
-- can get rid of a thunk in an inner loop
|
|
2302
|
2305
|
|
|
2303
|
2306
|
| otherwise -> primop_ok op && args_ok
|
|
|
2307
|
+ -- Assumes that the primop does not evaluate its
|
|
|
2308
|
+ -- definitely-lifted arguments
|
|
2304
|
2309
|
|
|
2305
|
2310
|
_other -- Unlifted and terminating types;
|
|
2306
|
2311
|
-- Also c.f. the Var case of exprIsHNF
|
|
2307
|
2312
|
| isTerminatingType fun_ty -- See Note [exprOkForSpeculation and type classes]
|
|
2308
|
2313
|
|| definitelyUnliftedType fun_ty
|
|
2309
|
|
- -> assertPpr (n_val_args == 0) (ppr fun $$ ppr args)
|
|
|
2314
|
+ -> assertPpr (n_val_args == 0) (ppr fun $$ ppr val_args)
|
|
2310
|
2315
|
True -- Both terminating types (e.g. Eq a), and unlifted types (e.g. Int#)
|
|
2311
|
2316
|
-- are non-functions and so will have no value args. The assert is
|
|
2312
|
2317
|
-- just to check this.
|
| ... |
... |
@@ -2322,37 +2327,40 @@ app_ok fun_ok primop_ok fun args |
|
2322
|
2327
|
-- for evaluated-ness of the fun;
|
|
2323
|
2328
|
-- see Note [exprOkForSpeculation and evaluated variables]
|
|
2324
|
2329
|
where
|
|
2325
|
|
- fun_ty = idType fun
|
|
2326
|
|
- n_val_args = valArgCount args
|
|
2327
|
|
- (arg_tys, _) = splitPiTys fun_ty -- arg_tys are /uninstantiated/
|
|
2328
|
|
- -- See (EOKS1)
|
|
|
2330
|
+ ok_for_spec = expr_ok fun_ok primop_ok -- Used for recursive calls
|
|
|
2331
|
+
|
|
|
2332
|
+ fun_ty = idType fun
|
|
|
2333
|
+ n_val_args = length val_args
|
|
|
2334
|
+ val_arg_tys = uninstantiatedValArgTys fun_ty
|
|
|
2335
|
+ -- val_arg_tys are /uninstantiated/; see (EOKS1)
|
|
2329
|
2336
|
|
|
2330
|
2337
|
-- Even if a function call itself is OK, any unlifted
|
|
2331
|
2338
|
-- args are still evaluated eagerly and must be checked
|
|
2332
|
2339
|
-- arg_ok bndr arg = field_ok bndr NotMarkedStrict arg
|
|
2333
|
2340
|
-- See Note [exprOkForSpeculation] (a-c)
|
|
2334
|
|
- args_ok = all2Prefix arg_ok arg_tys args
|
|
2335
|
|
- arg_ok :: PiTyVarBinder -> CoreExpr -> Bool
|
|
2336
|
|
- arg_ok (Named _) _ = True
|
|
2337
|
|
- arg_ok (Anon ty _) arg = exprIsCheap arg || definitelyLiftedType (scaledThing ty)
|
|
|
2341
|
+ args_ok = all2Prefix arg_ok val_arg_tys val_args
|
|
|
2342
|
+ arg_ok :: Type -> CoreExpr -> Bool
|
|
|
2343
|
+ arg_ok arg_ty arg = ok_for_spec arg || definitelyLiftedType arg_ty
|
|
2338
|
2344
|
|
|
2339
|
2345
|
-- Used for strict DataCon worker arguments
|
|
2340
|
2346
|
-- See (SFC1) of Note [Strict fields in Core]
|
|
2341
|
2347
|
-- See Note [exprOkForSpeculation] (a-c)
|
|
2342
|
|
- fields_ok str_marks = all3Prefix field_ok arg_tys str_marks args
|
|
2343
|
|
- field_ok :: PiTyVarBinder -> StrictnessMark -> CoreExpr -> Bool
|
|
2344
|
|
- field_ok (Named _) _ _ = True
|
|
2345
|
|
- field_ok (Anon ty _) str arg
|
|
2346
|
|
- = case typeLevity_maybe (scaledThing ty) of
|
|
|
2348
|
+ fields_ok str_marks = all3Prefix field_ok val_arg_tys str_marks val_args
|
|
|
2349
|
+ field_ok :: Type -> StrictnessMark -> CoreExpr -> Bool
|
|
|
2350
|
+ field_ok arg_ty str arg
|
|
|
2351
|
+ = case typeLevity_maybe arg_ty of
|
|
2347
|
2352
|
Just Lifted -> str == NotMarkedStrict
|
|
2348
|
|
- Just Unlifted -> exprIsCheap arg
|
|
2349
|
|
- Nothing -> exprIsCheap arg && str == NotMarkedStrict
|
|
2350
|
|
- -- The Nothing case happens for
|
|
|
2353
|
+ Just Unlifted -> ok_for_spec arg
|
|
|
2354
|
+ Nothing | str == NotMarkedStrict
|
|
|
2355
|
+ , definitelyLiftedType (exprType arg)
|
|
|
2356
|
+ -> True
|
|
|
2357
|
+ | otherwise
|
|
|
2358
|
+ -> ok_for_spec arg
|
|
|
2359
|
+ -- The Nothing case: consider
|
|
2351
|
2360
|
-- (#,#) @rep1 @rep2 @ty1 @ty2 arg1 arg2
|
|
2352
|
2361
|
-- We don't /instantiate/ the type (though we could) so we don't know
|
|
2353
|
|
- -- if lifted or not, so we conservatively check both conditions. This
|
|
2354
|
|
- -- gives a conservative answer False for (# null xs, null ys #), but
|
|
2355
|
|
- -- these unboxed tuples are usually ANF'd so it doesn't reallly matter.
|
|
|
2362
|
+ -- if the argument type is lifted or not. So we look at the type of
|
|
|
2363
|
+ -- the /actual/ argument (it's usually a variable) instead.
|
|
2356
|
2364
|
|
|
2357
|
2365
|
-----------------------------
|
|
2358
|
2366
|
altsAreExhaustive :: [Alt b] -> Bool
|
| ... |
... |
@@ -2405,8 +2413,8 @@ Is the call (K e1 e2 e3) ok-for-speculation? Lok at the arguments e1..e3, |
|
2405
|
2413
|
and their types. The call is ok-for-speculation if each argument satisfies
|
|
2406
|
2414
|
`field_ok`, namely:
|
|
2407
|
2415
|
(a) Arg type is definitely lifted => arg is not marked strict
|
|
2408
|
|
- (b) Arg type is definitely unlifted => (exprIsCheap arg) is True
|
|
2409
|
|
- (c) Otherwise => not marked strict && exprIsCheap
|
|
|
2416
|
+ (b) Arg type is definitely unlifted => (exprOkForSpeculation arg) is True
|
|
|
2417
|
+ (c) Otherwise => not marked strict && exprOkForSpeculation
|
|
2410
|
2418
|
|
|
2411
|
2419
|
For (a), an arbitrary /lazy/ argument is ok provided we don't have a bang.
|
|
2412
|
2420
|
For a strict argument you might wonder if we could use exprIsHNF, but see
|
| ... |
... |
@@ -2414,7 +2422,7 @@ Note [exprOkForSpeculation and evaluated variables]. So for strict arguments |
|
2414
|
2422
|
we just say "no".
|
|
2415
|
2423
|
|
|
2416
|
2424
|
For (b) a variable, or casted variable is fine. But not a call, say (f x).
|
|
2417
|
|
-Hence `exprisCheap`.
|
|
|
2425
|
+Hence `exprOkForSpeculation`.
|
|
2418
|
2426
|
|
|
2419
|
2427
|
For (c) we don't know if we are in case (a) or (b) so we conservatively 'and'
|
|
2420
|
2428
|
them. See (EOKS1) for how we can get this situation.
|
| ... |
... |
@@ -2426,8 +2434,8 @@ them. See (EOKS1) for how we can get this situation. |
|
2426
|
2434
|
If we have a call
|
|
2427
|
2435
|
(#,#) @LiftedRep @IntRep @Int @Int# 3 4#
|
|
2428
|
2436
|
then we could see accurate liftedness by instantiation, but we don't try.
|
|
2429
|
|
- Typically the argument is a variable, in which case `exprIsCheap` does a good job.
|
|
2430
|
|
-
|
|
|
2437
|
+ Instead we get the actual type from (exprType arg). That could be expensive,
|
|
|
2438
|
+ but it really only happens for unboxed tuples.
|
|
2431
|
2439
|
|
|
2432
|
2440
|
Note [exprOkForSpeculation and type classes]
|
|
2433
|
2441
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| ... |
... |
@@ -2713,8 +2721,7 @@ exprIsHNFlike is_con is_con_unf rubbish_lit_result e |
|
2713
|
2721
|
-- PAP: Check unlifted val_args
|
|
2714
|
2722
|
args_hnf = all2Prefix check_arg val_arg_tys val_args
|
|
2715
|
2723
|
|
|
2716
|
|
- fun_ty = idType id
|
|
2717
|
|
- val_arg_tys = mapMaybe anonPiTyBinderType_maybe (collectPiTyBinders fun_ty)
|
|
|
2724
|
+ val_arg_tys = uninstantiatedValArgTys (idType id)
|
|
2718
|
2725
|
-- val_arg_tys = map exprType val_args, but much less costly.
|
|
2719
|
2726
|
-- The obvious definition regresses T16577 by 30% so we don't do it.
|
|
2720
|
2727
|
|
| ... |
... |
@@ -2739,6 +2746,12 @@ exprIsHNFlike is_con is_con_unf rubbish_lit_result e |
|
2739
|
2746
|
| otherwise
|
|
2740
|
2747
|
= Nothing
|
|
2741
|
2748
|
|
|
|
2749
|
+uninstantiatedValArgTys :: Type -> [Type]
|
|
|
2750
|
+-- Returns the value argument types.
|
|
|
2751
|
+-- E.g. uninstantiatedValArgTys (forall a. a -> Int -> T a)
|
|
|
2752
|
+-- returns [a, Int]
|
|
|
2753
|
+uninstantiatedValArgTys fun_ty
|
|
|
2754
|
+ = [ scaledThing ty | Anon ty _ <- collectPiTyBinders fun_ty ]
|
|
2742
|
2755
|
|
|
2743
|
2756
|
{-
|
|
2744
|
2757
|
Note [exprIsHNF Tick]
|