Skip to content

Draft: Try to do CPR on loop-variant constructor applications of recursive types.

Andreas Klebinger requested to merge wip/andreask/cpr-dependent into master

Implements the idea from #22983 (comment 482449)

The basic idea is that we want to avoid doing CPR when we have:

  c = C# 'a'
  replicateC :: Int -> [Int]
  replicateC 1 = [c]
  replicateC n = c : replicateC (n-1)

But if we have:

  replicateC :: Int -> [Int]
  replicateC 1 = [f 1]
  replicateC n = f n : replicateC (n-1)

Then there is nothing to share across iterations so CPR is safe to do. For one benchmark I looked at in #22983 no longer doing so made the benchmark take about twice as long.


The solution in this MR is that we keep a set of variables which are arguments to the recursive binder we are under. If any of these appear in an argument of a constructor application the constructor application can't be shared so we will happily CPR this constructor.

Merge request reports