Skip to content

Ticks and tail calls

Here's a worry I tripped over today. Consider

   f (Tick t e)

where f is strict. According to GHC.Core.Opt.Simplify.Iteraion.simplTick, if

  t `tickishScopesLike` SoftScope

we will float the tick to the outside, giving

   Tick t (f e)

Fine for counting ticks, not for scoped ticks.

Now suppose f is a join point $j. That should not lose the tail-call-ness. We care just counting t. But in the Tick case of GHC.Core.Opt.OccurAnal.occAnal, we zap tail calls precisely for

   t `tickishScopesLike` SoftScope

Here is the code

occAnal env (Tick tickish body)
  | SourceNote{} <- tickish
  = WUD usage (Tick tickish body')
                  -- SourceNotes are best-effort; so we just proceed as usual.
                  -- If we drop a tick due to the issues described below it's
                  -- not the end of the world.

  | tickish `tickishScopesLike` SoftScope  -- Worry: see Note [Simplifying ticks]
  = WUD (markAllNonTail usage) (Tick tickish body')

To me it looks as if we should zap when the negation of that predicate holds!

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information