You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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:
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.
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.
Problem
The IR has no case-of-known-constructor:
ReflectCtor(tag read) andDataArgumentByIndex(field read) never reduce, even when applied to a syntactically known saturatedCtorapplication — both are handled only at lowering inLua.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) funfolds into a match on a literalJust 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
optimizedExpressionMfixpoint:ReflectCtor (Ctor … a₁ … aₙ)over a saturated constructor spine reduces to the tag string literal. The existing string constant folding plusremoveUnreachableThenBranch/removeUnreachableElseBranchthen collapse the surrounding if-chain to the live branch.DataArgumentByIndex i (Ctor … a₁ … aₙ)reduces toaᵢ, with the same effect discipline asreduceObjectProp: 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.