| ... |
... |
@@ -2375,28 +2375,26 @@ simplOutId env fun cont |
|
2375
|
2375
|
simplOutId env noinline_fun cont
|
|
2376
|
2376
|
| isNoinlineId noinline_fun
|
|
2377
|
2377
|
, ApplyToTy { sc_cont = cont1 } <- cont
|
|
2378
|
|
- , ApplyToTy { sc_cont = cont2 } <- cont1
|
|
2379
|
|
- , ApplyToVal { sc_cont = cont3, sc_arg = the_call, sc_cast = arg_mco
|
|
|
2378
|
+ , ApplyToTy { sc_cont = cont2, sc_arg_ty = call_ty } <- cont1
|
|
|
2379
|
+ , ApplyToVal { sc_cont = cont3, sc_arg = the_call, sc_cast = call_mco
|
|
2380
|
2380
|
, sc_env = UnSimplified arg_se } <- cont2
|
|
2381
|
2381
|
, let -- encl_app_cont collects any /arguments/ from `cont3`
|
|
2382
|
2382
|
(encl_app_cont, rest_cont) = splitContArgs cont3
|
|
2383
|
2383
|
new_call_ty = contHoleType rest_cont
|
|
2384
|
|
- , typeHasFixedRuntimeRep new_call_ty -- See (NOI6) in Note [noinlineId magic]
|
|
2385
|
|
- = do { -- Push any arguments in `the_call` onto `encl_app_cont`
|
|
2386
|
|
- let push_args :: InExpr -> SimplCont -> SimplM (InExpr, SimplCont)
|
|
2387
|
|
- -- push_args just pushes multiple arguments onto the continuation
|
|
2388
|
|
- push_args (Cast f co) cont = do { cont' <- pushInCast arg_se co cont
|
|
2389
|
|
- ; push_args f cont' }
|
|
2390
|
|
- push_args (App f a) cont = do { cont' <- pushAppCont arg_se f a cont
|
|
2391
|
|
- ; push_args f cont' }
|
|
2392
|
|
- push_args fun cont = return (fun, cont)
|
|
2393
|
|
- ; (inner_fun, call_cont) <- push_args the_call $
|
|
2394
|
|
- addCastMCo arg_mco $
|
|
2395
|
|
- encl_app_cont
|
|
2396
|
|
-
|
|
2397
|
|
- -- Now simplify the function itself, crucially setting sm_inline = False
|
|
2398
|
|
- -- The /arguments/, in `call_cont` will be simplified with their own
|
|
2399
|
|
- -- flags, captured in `arg_se`
|
|
|
2384
|
+ = do { (inner_fun, call_cont, outer_cont)
|
|
|
2385
|
+ <- -- See Note [noinlineId magic]...
|
|
|
2386
|
+ if var_at_head the_call && -- (NOI7)
|
|
|
2387
|
+ typeHasFixedRuntimeRep new_call_ty -- (NOI6)
|
|
|
2388
|
+ then do { (inner_fun, call_cont) <- push_args arg_se the_call $
|
|
|
2389
|
+ addCastMCo call_mco $
|
|
|
2390
|
+ encl_app_cont
|
|
|
2391
|
+ ; return (inner_fun, call_cont, rest_cont) }
|
|
|
2392
|
+ else do { let call_stop = addCastMCo call_mco (mkBoringStop call_ty)
|
|
|
2393
|
+ ; return (the_call, call_stop, cont3) }
|
|
|
2394
|
+
|
|
|
2395
|
+ -- Now simplify the function itself, in call_cont, crucially setting
|
|
|
2396
|
+ -- sm_inline = False. The /arguments/ in `call_cont` will be simplified
|
|
|
2397
|
+ -- with their own flags, captured in `arg_se`
|
|
2400
|
2398
|
; let call_env = updMode updModeForNoInline $
|
|
2401
|
2399
|
arg_se `setInScopeFromE` env
|
|
2402
|
2400
|
; (floats1, call1) <- wrapJoinFloatsX $
|
| ... |
... |
@@ -2404,16 +2402,29 @@ simplOutId env noinline_fun cont |
|
2404
|
2402
|
-- wrapJoinFloatsX: any floating join bindings must stay
|
|
2405
|
2403
|
-- around the call, not be floated out
|
|
2406
|
2404
|
|
|
2407
|
|
- -- Now `rebuild` does the rest
|
|
|
2405
|
+ -- Now `rebuild` does the rest, wrapping in outer_cont
|
|
2408
|
2406
|
; let (new_noinline_fun, rep) = getNoinlineId new_call_ty
|
|
2409
|
2407
|
noinline_expr = Var new_noinline_fun
|
|
2410
|
2408
|
`App` Type rep
|
|
2411
|
2409
|
`App` Type new_call_ty
|
|
2412
|
2410
|
`App` call1
|
|
2413
|
2411
|
; (floats2, res) <- rebuild (env `setInScopeFromF` floats1)
|
|
2414
|
|
- noinline_expr rest_cont
|
|
|
2412
|
+ noinline_expr outer_cont
|
|
2415
|
2413
|
; return (floats1 `addFloats` floats2 , res) }
|
|
2416
|
2414
|
where
|
|
|
2415
|
+ var_at_head :: CoreExpr -> Bool
|
|
|
2416
|
+ var_at_head (Var {}) = True
|
|
|
2417
|
+ var_at_head (App f _) = var_at_head f
|
|
|
2418
|
+ var_at_head (Cast f _) = var_at_head f
|
|
|
2419
|
+ var_at_head _ = False
|
|
|
2420
|
+
|
|
|
2421
|
+ push_args :: SimplEnv -> InExpr -> SimplCont -> SimplM (InExpr, SimplCont)
|
|
|
2422
|
+ -- push_args just pushes multiple arguments onto the continuation
|
|
|
2423
|
+ push_args arg_se (Cast f co) cont = do { cont' <- pushInCast arg_se co cont
|
|
|
2424
|
+ ; push_args arg_se f cont' }
|
|
|
2425
|
+ push_args arg_se (App f a) cont = do { cont' <- pushAppCont arg_se f a cont
|
|
|
2426
|
+ ; push_args arg_se f cont' }
|
|
|
2427
|
+ push_args _ fun cont = return (fun, cont)
|
|
2417
|
2428
|
|
|
2418
|
2429
|
-----------------------
|
|
2419
|
2430
|
-- General fall-through case for (f e1 .. en)
|