Skip to content

✨ Canonicalize equivalent qc.static operations#1567

Open
simon1hofmann wants to merge 5 commits intomainfrom
canonicalize_static_operations
Open

✨ Canonicalize equivalent qc.static operations#1567
simon1hofmann wants to merge 5 commits intomainfrom
canonicalize_static_operations

Conversation

@simon1hofmann
Copy link
Contributor

@simon1hofmann simon1hofmann commented Mar 16, 2026

Description

In the QC dialect two qc.static operations using the same static index represent the equivalent reference to a hardware qubit. Likewise, two (static) registers in the QC dialect consisting of the same static indices are also equivalent.

Remove all but the first sc.static operation and replace the uses accordingly using MLIR's CSE pass (https://mlir.llvm.org/docs/Passes/#-cse)

Fixes #1514

Checklist

  • The pull request only contains commits that are focused and relevant to this change.
  • I have added appropriate tests that cover the new/changed functionality.
  • I have updated the documentation to reflect these changes.
  • I have added entries to the changelog for any noteworthy additions, changes, fixes, or removals.
  • I have added migration instructions to the upgrade guide (if needed).
  • The changes follow the project's style guidelines and introduce no new warnings.
  • The changes are fully tested and pass the CI checks.
  • I have reviewed my own code changes.

If PR contains AI-assisted content:

  • I have disclosed the use of AI tools in the PR description as per our AI Usage Guidelines.
  • AI-assisted commits include an Assisted-by: [Model Name] via [Tool Name] footer.
  • I confirm that I have personally reviewed and understood all AI-generated content, and accept full responsibility for it.

@codecov
Copy link

codecov bot commented Mar 16, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@simon1hofmann simon1hofmann marked this pull request as ready for review March 16, 2026 12:39
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 16, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: b395af0c-04b0-4c03-a91f-340f264b5ab1

📥 Commits

Reviewing files that changed from the base of the PR and between 80e45d7 and 92399c8.

📒 Files selected for processing (1)
  • mlir/unittests/programs/qco_programs.cpp

📝 Walkthrough

Summary by CodeRabbit

  • Compiler Enhancements

    • Added Common Subexpression Elimination (CSE) into the cleanup/canonicalization sequence to improve optimization.
  • Testing & Validation

    • Expanded test coverage with new cases covering static qubit duplication across QC, QIR, QCO dialects.
    • Updated test mappings and references to align expected program equivalence.
  • Documentation

    • Clarified descriptions for static qubit behaviors and related test utilities.

Walkthrough

Adds Common Subexpression Elimination (CSE) into the compiler cleanup/canonicalization pass sequence and extends unit tests and program helpers to cover duplicate static-qubit allocations across QC/QIR/QCO test suites; updates documentation and CHANGELOG accordingly.

Changes

Cohort / File(s) Summary
Compiler pipeline & passes
mlir/include/mlir/Compiler/CompilerPipeline.h, mlir/lib/Compiler/CompilerPipeline.cpp, mlir/lib/Support/Passes.cpp
Insert createCSEPass() into the canonicalization/cleanup sequence (after canonicalizer, before RemoveDeadValues). Update doc comment to reflect inclusion of CSE.
QC / QIR / QCO test programs & headers
mlir/unittests/programs/qc_programs.h, mlir/unittests/programs/qc_programs.cpp, mlir/unittests/programs/qir_programs.h, mlir/unittests/programs/qir_programs.cpp, mlir/unittests/programs/qco_programs.h, mlir/unittests/programs/qco_programs.cpp
Add staticQubitsWithDuplicates program helpers (duplicate static index allocation). Update staticQubits implementations/docs to use explicit qubit handles and apply H on both plus a controlled-X.
Unit tests instantiations
mlir/unittests/Compiler/test_compiler_pipeline.cpp, mlir/unittests/Dialect/QC/IR/test_qc_ir.cpp, mlir/unittests/Dialect/QCO/IR/test_qco_ir.cpp, mlir/unittests/Dialect/QIR/IR/test_qir_ir.cpp, mlir/unittests/Conversion/QCToQIR/test_qc_to_qir.cpp
Add new parameterized test cases StaticQubitsWithDuplicates; adjust several existing test references to use the non-empty staticQubits reference builders.
Changelog
CHANGELOG.md
Add PR reference entry for this change.

Sequence Diagram(s)

sequenceDiagram
    participant CompilerPipeline as CompilerPipeline
    participant PassManager as PassManager
    participant Canonicalizer as Canonicalizer
    participant CSE as CSE
    participant RemoveDeadValues as RemoveDeadValues

    CompilerPipeline->>PassManager: addCleanupPasses()
    PassManager->>Canonicalizer: addPass(createCanonicalizer())
    PassManager->>CSE: addPass(createCSEPass())
    PassManager->>RemoveDeadValues: addPass(createRemoveDeadValuesPass())
    CompilerPipeline->>PassManager: run(module)
    PassManager->>Canonicalizer: run(module)
    Canonicalizer-->>PassManager: canonicalized IR
    PassManager->>CSE: run(module)
    CSE-->>PassManager: eliminated common subexpressions
    PassManager->>RemoveDeadValues: run(module)
    RemoveDeadValues-->>PassManager: removed dead values
    PassManager-->>CompilerPipeline: finished
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

c++

Suggested reviewers

  • denialhaag
  • burgholzer

Poem

🐰 I hopped through passes, one by one,

Found repeated echoes, two by two,
CSE nudged duplicates away,
Qubits primped and tests anew,
A rabbit cheers — pipeline review 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 10.53% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: canonicalizing equivalent qc.static operations to eliminate duplicates.
Description check ✅ Passed The description follows the template with all major sections completed, including issue reference, clear explanation of the change, and a comprehensive checklist with most items marked done.
Linked Issues check ✅ Passed The PR directly addresses issue #1514 by implementing canonicalization for qc.static operations. Code changes add CSE pass to the pipeline and include test cases for duplicate static operations as required.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing canonicalization of qc.static operations: CSE pass additions, test coverage for duplicates, and documentation updates are all in scope.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch canonicalize_static_operations
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@mlir/unittests/Compiler/test_compiler_pipeline.cpp`:
- Around line 188-192: The test case uses mlir::qc::staticQubits as the
canonical reference while the input builder
MQT_NAMED_BUILDER(mlir::qc::staticQubitsWithDuplicates) emits extra h/x gates;
update the canonical comparator to the actual canonical builder by replacing
mlir::qc::staticQubits with mlir::qc::staticQubitsCanonical in the
CompilerPipelineTestCase entry so the test compares against the correct
canonical QC implementation.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: a3faf48d-3418-4128-9d82-ad8df55b2646

📥 Commits

Reviewing files that changed from the base of the PR and between a5cf121 and 50878a3.

📒 Files selected for processing (7)
  • mlir/include/mlir/Compiler/CompilerPipeline.h
  • mlir/lib/Compiler/CompilerPipeline.cpp
  • mlir/lib/Support/Passes.cpp
  • mlir/unittests/Compiler/test_compiler_pipeline.cpp
  • mlir/unittests/Dialect/QC/IR/test_qc_ir.cpp
  • mlir/unittests/programs/qc_programs.cpp
  • mlir/unittests/programs/qc_programs.h

@simon1hofmann simon1hofmann requested a review from DRovara March 16, 2026 12:49
@simon1hofmann simon1hofmann added enhancement Improvement of existing feature MLIR Anything related to MLIR labels Mar 16, 2026
@simon1hofmann simon1hofmann added this to the MLIR Support milestone Mar 16, 2026
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@CHANGELOG.md`:
- Line 18: Add an UPGRADING.md entry documenting the canonicalization behavior
change introduced by PR `#1567`: describe that qc.static equivalence and
deduplication semantics have changed, explain the effect on downstream IR
expectations and tests (what may break or need updating), and provide brief
migration guidance or examples for updating tests and IR consumers to the new
canonicalization rules; place the note in UPGRADING.md and reference PR `#1567`
and the qc.static/deduplication behavior so maintainers can find the relevant
changelog entry.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 79c65211-6f7a-4b87-939f-f31419c06f0a

📥 Commits

Reviewing files that changed from the base of the PR and between 50878a3 and 284ce48.

📒 Files selected for processing (1)
  • CHANGELOG.md

@denialhaag denialhaag self-requested a review March 16, 2026 15:24
@denialhaag
Copy link
Member

denialhaag commented Mar 16, 2026

@simon1hofmann, thanks a lot for updating the pipeline and the tests! 🙂

I left a couple of comments. After they are addressed, this should be ready to go in!

Copy link
Member

@denialhaag denialhaag left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the somewhat confused initial review... The improved examples look good to me now!

Below, I'm proposing a simplification that feels closer to how we do things in the QCO tests. Feel free to resolve the comments if you disagree.

I'd propose we leave this PR open for a bit longer so @burgholzer can give a final approval.

…R, and QCO programs to remove canonical versions and enhance functionality with controlled operations.
Copy link
Member

@burgholzer burgholzer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As per the comment on Discord, this will first need another fix before it can go in.
And with that fix, the tests here can be made significantly simpler (hopefully).
Specifically, the QCO programs being generated for static qubits are currently not valid as there is no "sink" for the qubit values corresponding to static qubits. Similarly to dynamic qubits, the static allocations need to be deallocated at the end of the program.
This is also related, and the fix probably closes, the issue that @MatthiasReumann raised regarding static qubits.

I'd prefer that to be fixed in a separate PR and have this PR be rebased afterwards, if that is fine with you.

@simon1hofmann
Copy link
Contributor Author

As per the comment on Discord, this will first need another fix before it can go in. And with that fix, the tests here can be made significantly simpler (hopefully). Specifically, the QCO programs being generated for static qubits are currently not valid as there is no "sink" for the qubit values corresponding to static qubits. Similarly to dynamic qubits, the static allocations need to be deallocated at the end of the program. This is also related, and the fix probably closes, the issue that @MatthiasReumann raised regarding static qubits.

I'd prefer that to be fixed in a separate PR and have this PR be rebased afterwards, if that is fine with you.

I opened another PR (#1569) to try and fix that behavior.

@mergify mergify bot added the conflict label Mar 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

conflict enhancement Improvement of existing feature MLIR Anything related to MLIR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

✨ Canonicalize equivalent qc.static operations

3 participants