Skip to content

Cmm output should exploit Unf=OtherCon []

It appears to me that generated Cmm does not take into account Unf= OtherCon [], which as far as I know indicates that something is known to be already forced. For example:

data S a = S {unS :: !a}

data Tree = Node !Tree !Tree | Leaf !Int

inc :: S Tree -> Tree
inc (S t) = case t of
  Leaf n   -> Leaf (n + 1)
  Node l r -> Node (inc (S l)) (inc (S r))

With GHC 8.8.4 and 8.10.2, I get the following worker function:

$winc :: Tree -> Tree
$winc
  = \ (ww_s1iY
         :: Tree
         Unf=OtherCon []) ->
      case ww_s1iY of {
        Node l_a137 r_a138 ->
          case $winc l_a137 of dt_X13T { __DEFAULT ->
          case $winc r_a138 of dt1_X13V { __DEFAULT ->
          Node dt_X13T dt1_X13V
          }
          };
        Leaf dt_d1hC -> Leaf (+# dt_d1hC 1#)
      }

I expected that $winc$ does not check for thunks, but it does:

[$winc_entry() //  [R2]
       ...
       c1kC:
           I64[Sp - 8] = c1kt;
           R1 = R2;
           Sp = Sp - 8;
           if (R1 & 7 != 0) goto c1kt; else goto c1ku;
       c1ku:
           call (I64[R1])(R1) returns to c1kt, args: 8, res: 8, upd: 8;
       c1kt:

It's quite common to use records with strict fields, and in all such cases we get worker functions with superfluous forcing like above.

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