Skip to content

Uncurry the shapes that only appear after magicDo and flattening #200

Description

@Unisay

Problem

The worker/wrapper uncurrying pass from #24 runs once, in the middle of the IR pipeline: after the post-merge optimize/dce fixpoint has settled the manifest arities, and before floatIn, magicDo and flattenDeepBinds. Two families of saturated n-ary call sites do not exist yet at that point, so the pass never splits the functions behind them.

Effect functions forced after magicDo

A curried effect action like f :: A -> B -> Effect C is, on the Lua target, a function that returns a thunk: applying it to its two real arguments yields \_ -> body, and running the effect forces that thunk with a final unit application. The saturated site is therefore f(a)(b)(), a three-argument spine. That third application only appears once magicDo has rewritten the do-block into explicit thunk-forcing. When the uncurry pass runs, magicDo has not run, so the site is still the partial f(a)(b) and f is left curried. The functions that would benefit most, the ones threaded through effectful loops, are exactly the ones the pass cannot see.

The $kont helpers minted by flattening

flattenDeepBinds lambda-lifts long continuation chains into named $kont helpers. Each helper takes the captured live set plus the bound value, so its arity is at least two and every call it introduces is saturated by construction. These helpers are created downstream of the uncurry pass, so their saturated sites are never offered to it either.

Approach

Run the same pass a second time, late, after flattenDeepBinds, followed by a short optimize/dce fixpoint to drop the wrappers and beta-reduce the use-once workers. The pass is idempotent and cheap, so a second run over already-uncurried code costs one traversal and changes nothing where there is nothing new to do. Moving the single early run later instead is not an option: it has to observe the arities that only settle after the early inlining fixpoints, so the early run must stay where it is.

Prerequisites / Relations

Builds on #24. Synergy with #181: a late run gives effectful loops their n-ary workers, which is the shape loopification needs to turn a tail-recursive effect loop into a Lua while.

Open questions

Metadata

Metadata

Assignees

No one assigned

    Labels

    OptimisationA Compiler Optimisationarea: irIR / optimizer / DCE / inlinerenhancementNew feature or request

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions