Skip to content

Lua optimizer: fold a field projection through a branching scope-call tail #335

Description

@Unisay

Problem

The Lua-level optimizer has two sibling rewrites that fold an operation applied to an immediately-invoked scope call ((function() … end)(), the shape codegen emits for an if in expression position) into the callee's return sites. They cover their tail chains asymmetrically. foldCallThroughScopeCall — the rule folding (function() … return e end)()(args) into return e(args) — recurses through branching tails: its pushIntoStatement handles Return, IfThenElse (both blocks, gated on atomic arguments), and Do. Its projection sibling foldFieldProjectionThroughScopeCall — folding ((function() … return e end)()).f into return e.f — only matches a body whose last statement is a single Return (matchScopeCallProjection), so a field read over a branching scope call keeps its IIFE:

return ((function() if b then return l else return r end end)()).name

stays as is, while the call-shaped analogue of the same body folds. Since #243 the IR optimizer distributes accessors into IfThenElse arms before codegen, so IR-originated shapes no longer reach this backstop — but the Lua optimizer also runs over shapes the IR never sees (FFI-adjacent rewriting, fixtures), and the asymmetry makes the backstop's coverage surprising.

Approach

Extend foldFieldProjectionThroughScopeCall to traverse the same tail chain as foldCallThroughScopeCall: recurse the projection through IfThenElse/Do tails, declining on the same conditions (an early Return among the leading statements, a fall-off path, a multi-value tail Return). A field name has no evaluation cost, so no atomic-arguments analogue is needed. Alternatively, extract the shared tail-chain walker from foldCallThroughScopeCall and instantiate it for both consumers, so the two rules cannot drift again.

Prerequisites / Relations

None blocking. Relates to #243 (the IR-level distribution that now handles these shapes before codegen for IR-originated code) and to the scope-call fold family shipped for #172.

Verification / Measurement

A unit test over the Lua optimizer: a projection over a branching scope call folds into both return sites, and a body with an early return or fall-off path is declined. Existing goldens should not move (the IR rule already strips these shapes from IR-originated output); if any do, the diff is the review artifact.

Metadata

Metadata

Assignees

No one assigned

    Labels

    OptimisationA Compiler Optimisationarea: codegenLua code generation / printingenhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions