Skip to content

Graduated @inline directives: arity=N, accessor forms, and a directives file #232

Description

@Unisay

Problem

pslua honours only binary @inline always / @inline never on a binding. The abstraction-elimination story (lenses, variants, generics) wants a richer directive DSL bound to a fully-qualified name plus an optional accessor:

[export] qualified-ident accessor? mode
accessor ::= ""         -- the value itself
           | ".label"   -- a field of a dictionary record
           | "...label" -- a field after application: f(x).member
mode ::= default | never | always | arity=N   (N > 0)

arity=N inlines only when applied to at least N arguments, so a tiny curried combinator inlines at saturated sites but stays a reference otherwise; the accessor forms target one dictionary method rather than the whole record; and a --directives file.txt supplies these globally, above the built-in heuristics. Without graduated directives pslua cannot start the inlining cascade that eliminates a user-defined abstraction: a fusion pragma like @inline export overArray arity=1 never gets off the ground.

Worth stating up front: #180 already auto-specializes the non-Effect/ST monads with no directives needed, so the marginal value here is lens/variant/generics elimination and user tuning, not monad collapse.

Approach

Extend the pragma parser in IR/Inliner.hs to accept arity=N and the .label / ...label accessor forms, and add a --directives <file> input layering the sources by specificity: a local module-header directive beats the project directives file, which beats export-transitive directives, which beat the built-in defaults. At the call site an arity=N directive gates inlining on the saturation count already computed for the uncurry pass; the accessor forms attach the policy to a projection out of a known dictionary rather than to the binding as a whole.

Prerequisites / Relations

Independent to land; sharper together with the Complexity/Capture lattice, since default mode falls back to those heuristics. Enables two follow-ups tracked separately: #241 (auto-inferred directives on synthetic specializations) and #242 (a shipped default-directive pack for the prelude/core forks).

Verification / Measurement

A curried combinator marked arity=2 inlines at a saturated two-argument site and stays a reference at a partial one. A focused test covers both. A directives file overrides an exported directive for the same name, and a local module-header directive beats the file (precedence tests). An end-to-end golden where a user abstraction marked arity=1 collapses through the existing beta / case-of-known-constructor cascade.

Metadata

Metadata

Assignees

Labels

OptimisationA Compiler Optimisationarea: irIR / optimizer / DCE / inlinerarea: toolchainnix / spago / purs / buildenhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions