Do two-phase inlining in simpleOptPgm
As of #12988 (closed), having
simpleOptPgm leave β-redexes lying around is painful because it requires a special loophole in Core Lint to allow a jump inside a β-redex. We'd rather use a two-phase approach, mirroring the simplifier's
postInlineUnconditionally, so we can aggressively eliminate β-redexes without fear of exponential blowup.
joinrec j1 x = e1 in join j2 x y = jump j1 e2 in jump j2 e3 e4
j2 is only used once, it gets inlined. But
simpleOptPgm only performs inlining //after// a binding is simplified, so we end up here:
joinrec j1 x = e1' in (\x y -> jump j1 e2') e3' e4'
e2' was already simplified, performing the β-reduction here risks exponential blowup for the same reason it can happen in the simplifier (see the Secrets paper;
perf/compiler/T783 is a live example, increasing in allocs by over 80% if we re-simplify here). We //could// just
e4' (carefully avoiding capturing free occurrences of
e4'), but not if one them is actually a type argument. Well, okay, we //could// introduce a type
let, but doing that here means the desugarer can now return a type
let and we're not prepared for that. (Specifically, under certain circumstances, the simplifier never runs in between the desugarer and Float Out, and the latter breaks in the presence of type
So for the moment, we leave the β-redex there, but this needs a special rule just for β-redexes because normally you can't have a jump under a lambda (or an application, for that matter). In the long term, we'd prefer to take the simplifier's approach instead: If we want to inline something because it only occurs once (even though it may be big), we add it to the substitution //before// simplifying it so that we only simplify it once. This means the substitution has to carry lexical closures around, though, just like the simplifier does (see
ContEx disjunct), so it's not trivial.
simpleOptPgm β-redexes are the only reason for the special rule in Core Lint (see Note [Beta redexes] in
CoreLint.hs), so once this is done we can be rid of that.