Skip to content

HPC tick floating seems wrong

Consider this:

import GHC.Exts

bar :: () -> Proxy# Int
bar _ = proxy# @Int

foo xs f = map f xs

And compile with -O0 -fhpc. We get this

foo :: forall a b. [a] -> (a -> b) -> [b]
foo
  = \ (@a_aC5) (@b_aC6) ->
      letrec {
        foo_aC9 :: [a_aC5] -> (a_aC5 -> b_aC6) -> [b_aC6]
        [LclId]
        foo_aC9
          = \ (xs_avz :: [a_aC5]) (f_avA :: a_aC5 -> b_aC6) ->
              hpc<Foo,3>
              hpc<Foo,2>
              map @a_aC5 @b_aC6 (hpc<Foo,0> f_avA) (hpc<Foo,1> xs_avz); } in
      foo_aC9

bar :: () -> Proxy# Int
bar = \ (ds_dCz :: ()) -> hpc<Foo,5> hpc<Foo,4> proxy# @(*) @Int


==================== Desugar (after optimization) ====================
bar :: () -> Proxy# Int
bar = \ _ [Occ=Dead] ->
         (hpc<Foo,5> hpc<Foo,4> proxy#) @(*) @Int

foo :: forall a b. [a] -> (a -> b) -> [b]
foo
  = \ (@a_aC5) (@b_aC6) (xs_avz :: [a_aC5]) (f_avA :: a_aC5 -> b_aC6) ->
      hpc<Foo,3> hpc<Foo,2> map @a_aC5 @b_aC6
                                (hpc<Foo,0> f_avA)
                                (hpc<Foo,1> xs_avz)

Notice that for bar the HPC ticks wrap the entire expression. But for foo, the HPC ticks are pushed inwards so we get

         (hpc<Foo,5> hpc<Foo,4> proxy#)
            @(*)
            @Int

The treatment of HPC ticks seeme weirdly inconsistent: they stay outside value application but get pushed into the head of a type application. Why?

This inconsistent treatment is maintained by the simplifier, so we end up with the rather silly code for bar after CorePrep

bar = \_ -> case (hpc<Foo,5> hpc<Foo,4> proxy#) of
               f -> f @(*) @Int

This mysterious behaviour happens because of the elaborate and poorly-documented function CoreUtils.mkTick, which does this "push ticks inside type application stuff":

    App f arg
      -- Always float through type applications.
      | not (isRuntimeArg arg)
      -> mkTick' (top . flip App arg) rest f

Maybe none of this is a bug, and it probably doesn't affect many programs, but looks wrong to me. And I wish mkTick was properly documented.

All this arose from looking at this commennt in !1869 (closed)

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