Skip to content

refactor(ir): Mark pure DaphneIR base classes as Pure [#512] - #1013

Open
grapentt wants to merge 25 commits into
daphne-project:mainfrom
grapentt:512-baseline-wrapper
Open

grapentt wants to merge 25 commits into
daphne-project:mainfrom
grapentt:512-baseline-wrapper

Conversation

@grapentt

@grapentt grapentt commented Jul 7, 2026 •

Copy link
Copy Markdown

Foundation for #512. This PR doesn't add any algebraic rewrites, it makes MLIR's purity traits and CSE apply to DaphneIR, so those rewrites can compose correctly later.

The four PRs:

  1. refactor(ir): Mark pure DaphneIR base classes as Pure [#512] #1013 (this PR); purity traits, plus retiring the CSE workaround.
  2. feat(ir): Algebraic trait vocabulary + shared scalar-fold interface [#512] #1014; the ScalarConstantFoldable interface and the algebraic-trait vocabulary; moving existing rewrites onto it and adding new trait-based rewrites.
  3. feat(ir): Fail-closed property accessors, and make symmetric a real inferred property [#512] #1015; fail-closed property accessors, symmetric inference for matrix products, and the transpose elision it unlocks.
  4. feat(ir): linear-algebra simplification rewrites [#512] #1016; the linear-algebra rewrites: the trace idiom, diagonal scaling, pulling a scalar out of a sum, dropping length-1 aggregates, repeated-add-to-multiply, and combining shifted matrices.

What changed

Attach Pure to ~150 ops

Pure expands to TraitList<[AlwaysSpeculatable, NoMemoryEffect]>. Without NoMemoryEffect, CSE's simplifyOperation bails out and the op is never a candidate for elimination. Annotated seven base classes in DaphneOps.td (aggregations, group-aggregations, outer-binary, bind, activation-forward, pool-forward, the five columnar bases) plus thirteen individual ops: SyrkOp, GemvOp, SolveOp, DiagMatrixOp, EigenOp, ReshapeOp, ReverseOp, OrderOp, SoftmaxOp, Conv2DForwardOp, TypeOfOp, SparsityOp, IsSymmetricOp.

Retire the 5×CSE loop in DaphneIrExecutor.cpp

The columnar branch ran CSE five times behind a TODO that said "CSE seems to eliminate only one row of dead code at a time... how to apply CSE until a fixpoint?" The observation was real: CSE defers dead-op erasure to the end of its walk and never revisits an op, so a dead chain of length N needs N passes to fully collapse. It's now a single createCSEPass(), because the canonicalizer that runs right before CSE already drives DCE to a fixpoint (its greedy driver erases dead ops immediately and re-queues their operands), so the dead chains are gone before CSE runs. Confirmed empirically: full suite byte-identical at i < 5 vs i < 1, and numDCE == 0 on every CSE run.

Seed CSE in buildCodegenPipeline

Two nested-FuncOp CSE passes:

  • one after LinalgElementwiseOpFusionPass (fusion often exposes duplicate memref/tensor ops)
  • one after the post-sparsification canonicalize.
    Both sit behind use_mlir_codegen / use_mlir_hybrid_codegen, so non-MLIR-codegen pipelines are untouched.

Verification

daphne-opt --cse on IR with two identical daphne.sumAll calls on the same operand deduplicates them (num-cse'd 0 → 2). End-to-end, sum(X) + sum(X) with X = fill(1.0, 4, 3) shows two daphne.sumAll under --explain parsing and one under --explain parsing_simplified.

test/codegen/purity_cse_syrk.mlir runs daphne-opt --cse on two identical syrk ops and checks that only one survives. A case that depends on the new tag, since on the pre-Pure build both survive and the test fails.

Full suite via a small wrapper that filters two pre-existing aarch64-only crashes (#1011, #1012, neither of which reproduces on x86_64 CI): 2431 matched, 2318 passed, 113 failed. Byte-identical before and after this PR.

Out of scope

Kept impure by design: IncRefOp / DecRefOp (ref counting; CSE must not delete them; see DaphneIrExecutor.cpp:225-231), RandMatrixOp / SampleOp / NowOp (non-deterministic), VectorizedPipelineOp (regional effects, TODO at DaphneOps.td:1907). Also skipped: QrOp / SvdOp (no kernel or lowering yet) and EwAddOp Commutative restoration (#449 / #351).

On the commit range

This PR is stacked on #1010 (the kernel-compile OOM fix). #1010's branch lives on my fork and can't be a PR base upstream, so the first six commits here duplicate #1010's contents. Once #1010 merges I'll rebase and force-push; the duplicated commits drop out, leaving only the purity + CSE commits.

Refs #512.

@grapentt grapentt changed the title 🔧 add issue-512 baseline test wrapper ♻️ Pillar 1 purity sweep — aggregation, outer-binary, bind, NN, columnar (issue #512) Jul 7, 2026
@grapentt grapentt changed the title ♻️ Pillar 1 purity sweep — aggregation, outer-binary, bind, NN, columnar (issue #512) Pillar 1: purity sweep across DaphneIR base classes (issue #512) Jul 7, 2026
@grapentt grapentt changed the title Pillar 1: purity sweep across DaphneIR base classes (issue #512) refactor(ir): mark pure DaphneIR base classes as Pure Jul 7, 2026
@grapentt
grapentt force-pushed the 512-baseline-wrapper branch 3 times, most recently from 23fee41 to 8073761 Compare July 8, 2026 12:15
@grapentt
grapentt marked this pull request as ready for review July 8, 2026 12:21
@grapentt
grapentt marked this pull request as draft July 8, 2026 12:24
@grapentt
grapentt force-pushed the 512-baseline-wrapper branch from 0c9c3c4 to 8073761 Compare July 8, 2026 13:05
@grapentt grapentt changed the title refactor(ir): mark pure DaphneIR base classes as Pure refactor(ir): Mark pure DaphneIR base classes as Pure Jul 8, 2026
@grapentt
grapentt force-pushed the 512-baseline-wrapper branch from 2b247b0 to 85d0968 Compare July 12, 2026 21:41
@grapentt grapentt changed the title refactor(ir): Mark pure DaphneIR base classes as Pure refactor(ir): Mark pure DaphneIR base classes as Pure [#512] Jul 15, 2026
@grapentt
grapentt force-pushed the 512-baseline-wrapper branch from 85d0968 to ce3556e Compare July 18, 2026 20:31
@grapentt
grapentt force-pushed the 512-baseline-wrapper branch from 9415eae to 8d8d5aa Compare July 18, 2026 22:46
@grapentt
grapentt marked this pull request as ready for review July 19, 2026 16:17

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants