| ... |
... |
@@ -303,59 +303,72 @@ mkCast expr co |
|
303
|
303
|
* *
|
|
304
|
304
|
********************************************************************* -}
|
|
305
|
305
|
|
|
306
|
|
--- | Wraps the given expression in the source annotation, dropping the
|
|
307
|
|
--- annotation if possible.
|
|
|
306
|
+-- | Wraps the given expression in a Tick while respecting Tick invariants,
|
|
|
307
|
+-- and performing small on-the-fly optimisations.
|
|
|
308
|
+--
|
|
|
309
|
+-- Prefer using 'mkTick' over explicit use of the 'Tick' constructor.
|
|
|
310
|
+--
|
|
|
311
|
+-- Small optimisations performed:
|
|
|
312
|
+--
|
|
|
313
|
+-- * Minimise the AST covered by the tick, by pushing the tick deeper into
|
|
|
314
|
+-- the expression if this doesn't change the semantics of the tick.
|
|
|
315
|
+-- For example, push runtime relevant ticks through type applications
|
|
|
316
|
+-- and type lambdas.
|
|
|
317
|
+-- * Eliminate unnecessary ticks by either absorbing them into existing ones
|
|
|
318
|
+-- or dropping them if that is valid (e.g. dropping profiling ticks around
|
|
|
319
|
+-- types, coercions and literals).
|
|
|
320
|
+-- * Split profiling ticks into counting/scoping parts so that the two parts
|
|
|
321
|
+-- can be placed independently into the AST.
|
|
308
|
322
|
mkTick :: CoreTickish -> CoreExpr -> CoreExpr
|
|
309
|
|
-mkTick t orig_expr = mkTick' id orig_expr
|
|
|
323
|
+mkTick t orig_expr = mkTick' orig_expr
|
|
310
|
324
|
where
|
|
311
|
325
|
-- Some ticks (cost-centres) can be split in two, with the
|
|
312
|
326
|
-- non-counting part having laxer placement properties.
|
|
313
|
|
- canSplit = tickishCanSplit t && tickishPlace (mkNoCount t) /= tickishPlace t
|
|
|
327
|
+ -- See Note [Scoping ticks and counting ticks] in GHC.Types.Tickish.
|
|
|
328
|
+ can_split = tickishCanSplit t
|
|
314
|
329
|
|
|
315
|
|
- -- mkTick' handles floating of ticks *into* the expression.
|
|
316
|
|
- mkTick' :: (CoreExpr -> CoreExpr) -- Apply before adding tick (float with)
|
|
317
|
|
- -- Always a composition of (Tick t) wrappers
|
|
318
|
|
- -> CoreExpr -- Current expression
|
|
319
|
|
- -> CoreExpr
|
|
320
|
|
- -- So in the call (mkTick' rest e), the expression
|
|
321
|
|
- -- (rest e)
|
|
322
|
|
- -- has the same type as e
|
|
323
|
|
- -- Returns an expression equivalent to (Tick t (rest e))
|
|
324
|
|
- mkTick' rest expr = case expr of
|
|
325
|
|
- -- Float ticks into unsafe coerce the same way we would do with a cast.
|
|
326
|
|
- Case scrut bndr ty alts@[Alt ac abs _rhs]
|
|
327
|
|
- | Just rhs <- isUnsafeEqualityCase scrut bndr alts
|
|
328
|
|
- -> Case scrut bndr ty [Alt ac abs (mkTick' rest rhs)]
|
|
|
330
|
+ stop_here e = Tick t e -- Just wrap `t` around the current expression
|
|
|
331
|
+ -- That's the default option!
|
|
329
|
332
|
|
|
330
|
|
- -- Cost centre ticks should never be reordered relative to each
|
|
331
|
|
- -- other. Therefore we can stop whenever two collide.
|
|
|
333
|
+ -- mkTick' handles floating of tick `t` *into* the expression.
|
|
|
334
|
+ mkTick' :: CoreExpr -> CoreExpr
|
|
|
335
|
+ mkTick' expr = case expr of
|
|
332
|
336
|
Tick t2 e
|
|
333
|
|
- | ProfNote{} <- t2, ProfNote{} <- t -> Tick t $ rest expr
|
|
334
|
|
-
|
|
335
|
|
- -- Otherwise we assume that ticks of different placements float
|
|
336
|
|
- -- through each other.
|
|
337
|
|
- | tickishPlace t2 /= tickishPlace t -> Tick t2 $ mkTick' rest e
|
|
|
337
|
+ | ProfNote { profNoteCC = cc1, profNoteCount = cnt1, profNoteScope = scope1 } <- t
|
|
|
338
|
+ , ProfNote { profNoteCC = cc2, profNoteCount = cnt2, profNoteScope = scope2 } <- t2
|
|
|
339
|
+ ->
|
|
|
340
|
+ -- Common up ticks with a shared cost centre.
|
|
|
341
|
+ -- Alas, if both ticks count, we are forced to retain both.
|
|
|
342
|
+ if cc1 == cc2 && (not cnt1 || not cnt2)
|
|
|
343
|
+ then
|
|
|
344
|
+ let t' = ProfNote { profNoteCC = cc1
|
|
|
345
|
+ , profNoteCount = cnt1 || cnt2
|
|
|
346
|
+ , profNoteScope = scope1 || scope2
|
|
|
347
|
+ }
|
|
|
348
|
+ in mkTick t' e
|
|
|
349
|
+ else
|
|
|
350
|
+ -- Cost centre ticks for different cost centres should never be reordered
|
|
|
351
|
+ -- relative to each other. Therefore we can stop whenever two collide.
|
|
|
352
|
+ stop_here expr
|
|
|
353
|
+
|
|
|
354
|
+ | tickishPlace t2 /= tickishPlace t
|
|
|
355
|
+ -> -- Otherwise, we assume that ticks of different
|
|
|
356
|
+ -- placements float through each other.
|
|
|
357
|
+ Tick t2 $ mkTick' e
|
|
|
358
|
+
|
|
|
359
|
+ -- For source note ticks, this is where we make sure to
|
|
|
360
|
+ -- not introduce redundant ticks.
|
|
|
361
|
+ | tickishContains t t2 -> mkTick' e -- Drop t2
|
|
|
362
|
+ | tickishContains t2 t -> expr -- Drop t
|
|
338
|
363
|
|
|
339
|
|
- -- For annotations this is where we make sure to not introduce
|
|
340
|
|
- -- redundant ticks.
|
|
341
|
|
- | tickishContains t t2 -> mkTick' rest e -- Drop t2
|
|
342
|
|
- | tickishContains t2 t -> rest e -- Drop t
|
|
343
|
|
- | otherwise -> mkTick' (rest . Tick t2) e
|
|
344
|
|
-
|
|
345
|
|
- -- Ticks don't care about types, so we just float all ticks
|
|
346
|
|
- -- through them. Note that it's not enough to check for these
|
|
347
|
|
- -- cases top-level. While mkTick will never produce Core with type
|
|
348
|
|
- -- expressions below ticks, such constructs can be the result of
|
|
349
|
|
- -- unfoldings. We therefore make an effort to put everything into
|
|
350
|
|
- -- the right place no matter what we start with.
|
|
351
|
|
- Cast e co -> mkCast (mkTick' rest e) co
|
|
352
|
|
- Coercion co -> Tick t $ rest (Coercion co)
|
|
|
364
|
+ | otherwise
|
|
|
365
|
+ -> stop_here expr -- Always safe
|
|
353
|
366
|
|
|
354
|
367
|
Lam x e
|
|
355
|
368
|
-- Always float through type lambdas. Even for non-type lambdas,
|
|
356
|
369
|
-- floating is allowed for all but the most strict placement rule.
|
|
357
|
370
|
| not (isRuntimeVar x) || tickishPlace t /= PlaceRuntime
|
|
358
|
|
- -> Lam x $ mkTick' rest e
|
|
|
371
|
+ -> Lam x $ mkTick' e
|
|
359
|
372
|
|
|
360
|
373
|
-- If it is both counting and scoped, we split the tick into its
|
|
361
|
374
|
-- two components, often allowing us to keep the counting tick on
|
| ... |
... |
@@ -363,26 +376,41 @@ mkTick t orig_expr = mkTick' id orig_expr |
|
363
|
376
|
-- The point of this is that the counting tick can probably be
|
|
364
|
377
|
-- floated, and the lambda may then be in a position to be
|
|
365
|
378
|
-- beta-reduced.
|
|
366
|
|
- | canSplit
|
|
367
|
|
- -> Tick (mkNoScope t) $ rest $ Lam x $ mkTick (mkNoCount t) e
|
|
|
379
|
+ | can_split
|
|
|
380
|
+ -> Tick (mkNoScope t) $ Lam x $ mkTick (mkNoCount t) e
|
|
368
|
381
|
|
|
369
|
382
|
App f arg
|
|
370
|
383
|
-- Always float through type applications.
|
|
371
|
384
|
| not (isRuntimeArg arg)
|
|
372
|
|
- -> App (mkTick' rest f) arg
|
|
|
385
|
+ -> App (mkTick' f) arg
|
|
373
|
386
|
|
|
374
|
387
|
-- We can also float through constructor applications, placement
|
|
375
|
|
- -- permitting. Again we can split.
|
|
376
|
|
- | isSaturatedConApp expr && (tickishPlace t==PlaceCostCentre || canSplit)
|
|
|
388
|
+ -- permitting. Again we can try splitting.
|
|
|
389
|
+ | isSaturatedConApp expr
|
|
|
390
|
+ , tickishPlace t == PlaceCostCentre || can_split
|
|
377
|
391
|
-> if tickishPlace t == PlaceCostCentre
|
|
378
|
|
- then rest $ tickHNFArgs t expr
|
|
379
|
|
- else Tick (mkNoScope t) $ rest $ tickHNFArgs (mkNoCount t) expr
|
|
|
392
|
+ then tickHNFArgs t expr
|
|
|
393
|
+ else Tick (mkNoScope t) $ tickHNFArgs (mkNoCount t) expr
|
|
|
394
|
+
|
|
|
395
|
+ -- Ticks don't care about types, so we just float all ticks
|
|
|
396
|
+ -- through them. Note that it's not enough to check for these
|
|
|
397
|
+ -- cases at the top-level. While mkTick will never produce Core with type
|
|
|
398
|
+ -- expressions below ticks, such constructs can be the result of
|
|
|
399
|
+ -- unfoldings. We therefore make an effort to put everything into
|
|
|
400
|
+ -- the right place no matter what we start with.
|
|
|
401
|
+ Cast e co -> mkCast (mkTick' e) co
|
|
|
402
|
+
|
|
|
403
|
+ -- Float ticks into 'unsafeCoerce' the same way we would do with a cast.
|
|
|
404
|
+ Case scrut bndr ty alts@[Alt ac abs _rhs]
|
|
|
405
|
+ | Just rhs <- isUnsafeEqualityCase scrut bndr alts
|
|
|
406
|
+ -> Case scrut bndr ty [Alt ac abs (mkTick' rhs)]
|
|
380
|
407
|
|
|
381
|
408
|
Var x
|
|
382
|
|
- | notFunction && tickishPlace t == PlaceCostCentre
|
|
383
|
|
- -> rest expr -- Drop t
|
|
384
|
|
- | notFunction && canSplit
|
|
385
|
|
- -> Tick (mkNoScope t) $ rest expr
|
|
|
409
|
+ | notFunction
|
|
|
410
|
+ , tickishPlace t == PlaceCostCentre || can_split
|
|
|
411
|
+ -> if tickishPlace t == PlaceCostCentre
|
|
|
412
|
+ then expr -- Drop tick t entirely
|
|
|
413
|
+ else Tick (mkNoScope t) expr
|
|
386
|
414
|
where
|
|
387
|
415
|
-- SCCs can be eliminated on variables provided the variable
|
|
388
|
416
|
-- is not a function. In these cases the SCC makes no difference:
|
| ... |
... |
@@ -392,12 +420,26 @@ mkTick t orig_expr = mkTick' id orig_expr |
|
392
|
420
|
-- when the function is called, so we must retain those.
|
|
393
|
421
|
notFunction = not (isFunTy (idType x))
|
|
394
|
422
|
|
|
395
|
|
- Lit{}
|
|
396
|
|
- | tickishPlace t == PlaceCostCentre
|
|
397
|
|
- -> rest expr -- Drop t
|
|
398
|
|
-
|
|
399
|
|
- -- Catch-all: Annotate where we stand
|
|
400
|
|
- _any -> Tick t $ rest expr
|
|
|
423
|
+ -- It doesn't make sense to wrap static data (such as coercions, types and literals)
|
|
|
424
|
+ -- in a tick which compiles to code, as the code will never be run.
|
|
|
425
|
+ --
|
|
|
426
|
+ -- It is in fact actively harmful, because Core Lint will fail on a
|
|
|
427
|
+ -- coercion binding such as let co = <scc> (...), see #26941.
|
|
|
428
|
+ -- It makes more sense to discard the cost centre tick rather than weakening
|
|
|
429
|
+ -- Core Lint.
|
|
|
430
|
+ e@(Coercion {})
|
|
|
431
|
+ | tickishIsCode t
|
|
|
432
|
+ -> e
|
|
|
433
|
+ e@(Type {})
|
|
|
434
|
+ | tickishIsCode t
|
|
|
435
|
+ -> e
|
|
|
436
|
+ e@(Lit {})
|
|
|
437
|
+ | tickishIsCode t
|
|
|
438
|
+ -> e
|
|
|
439
|
+
|
|
|
440
|
+ -- Catch-all: annotate where we stand.
|
|
|
441
|
+ -- In particular (but not only): Let, most Cases.
|
|
|
442
|
+ _any -> Tick t expr
|
|
401
|
443
|
|
|
402
|
444
|
mkTicks :: [CoreTickish] -> CoreExpr -> CoreExpr
|
|
403
|
445
|
mkTicks ticks expr = foldr mkTick expr ticks
|