Skip to content

Fold ReflectCtor and DataArgumentByIndex over known constructor applications (case-of-known-constructor) #177

Description

@Unisay

Problem

The IR has no case-of-known-constructor: ReflectCtor (tag read) and DataArgumentByIndex (field read) never reduce, even when applied to a syntactically known saturated Ctor application — both are handled only at lowering in Lua.hs. While dictionaries stay opaque these shapes rarely occur, but they are exactly what dictionary specialization and method inlining produce en masse: bind maybeBind (Just x) f unfolds into a match on a literal Just x, and without these folds the cascade stops at "construct a table, immediately read its tag". This is the payoff step of the whole inlining series (GHC calls it KnownBranch); the upcoming specialization issues will list this one as a prerequisite.

Approach

Two rewrite rules in the optimizedExpressionM fixpoint:

  1. ReflectCtor (Ctor … a₁ … aₙ) over a saturated constructor spine reduces to the tag string literal. The existing string constant folding plus removeUnreachableThenBranch/removeUnreachableElseBranch then collapse the surrounding if-chain to the live branch.
  2. DataArgumentByIndex i (Ctor … a₁ … aₙ) reduces to aᵢ, with the same effect discipline as reduceObjectProp: discarded arguments must be trivial (Ref/literal), otherwise they are Let-bound rather than dropped or duplicated (the betaReduce substitutes a non-trivial argument into every occurrence of the parameter, multiplying work #167 class of care).

This is the algebraic-type twin of #153, which added the same fold for record literals.

Prerequisites / Relations

Nothing must land first — this is the enabler. Its landing unblocks the dictionary-specialization work in #178 and #180, whose inlining cascades bottom out at exactly these folds. It reuses the discard discipline established for #167 and mirrors #153 for algebraic types.

Verification / Measurement

Standalone benchmark impact is near zero — the shapes barely exist before specialization lands — so the value materializes through the inlining cascade and is measured end-to-end by #172, not in isolation. Because the rules touch discard semantics, stress the randomized optimizer specs across seeds.

Metadata

Metadata

Assignees

No one assigned

    Labels

    OptimisationA Compiler Optimisationarea: irIR / optimizer / DCE / inliner

    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