Draft: Try to do CPR on loop-variant constructor applications of recursive types.
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.