Note [Combining arity type with demand info]
Consider
let f = \x. let y = <expensive> in \p \q{os}. blah
in ...(f a b)...(f c d)...
* From the RHS we get an ArityType like
AT [ (IsCheap,?), (IsExpensive,?), (IsCheap,OneShotLam) ] Dunno
where "?" means NoOneShotInfo
* From the body, the demand analyser (or Call Arity) will tell us
that the function is always applied to at least two arguments.
Combining these two pieces of info, we can get the final ArityType
AT [ (IsCheap,?), (IsExpensive,OneShotLam), (IsCheap,OneShotLam) ] Dunno
result: arity=3, which is better than we could do from either
source alone.
The "combining" part is done by combineWithCallCards. It
uses info from both Call Arity and demand analysis.
We may have /more/ call demands from the calls than we have lambdas
in the binding. E.g.
let f1 = \x. g x x in ...(f1 p q r)...
Demand on f1 is C(x,C(1,C(1,L)))
let f2 = \y. error y in ...(f2 p q r)...
Demand on f2 is C(x,C(1,C(1,L)))
In both these cases we can eta expand f1 and f2 to arity 3.
But /only/ for called-once demands. Suppose we had
let f1 = \y. g x x in ...let h = f1 p q in ...(h r1)...(h r2)...
Now we don't want to eta-expand f1 to have 3 args; only two.
Nor, in the case of f2, do we want to push that error call under
a lambda. Hence the takeWhile in combineWithDemandDoneShots.
Wrinkles:
(CAD1) #24296 exposed a subtle interaction with -fpedantic-bottoms
(See Note [Dealing with bottom]). Consider
let f = \x y. error "blah" in
f 2 1 `seq` Just (f 3 2 1)
Demand on f is C(x,C(1,C(M,L)))
Usually, it is OK to consider a lambda that is called *at most* once (so call
cardinality C_01, abbreviated M) a one-shot lambda and eta-expand over it.
But with -fpedantic-bottoms that is no longer true: If we were to eta-expand
f to arity 3, we'd discard the error raised when evaluating `f 2 1`.
Hence in the presence of -fpedantic-bottoms, we must have C_11 for
eta-expansion. References 1
- Dealing with bottom GHC.Core.Opt.Arity
Referenced by 5
- GHC.Core.Opt.Arity call site ×3
- Dealing with bottom GHC.Core.Opt.Arity
- SafeArityType GHC.Core.Opt.Arity