Skip to content

🎨 Streamline conversions#1548

Merged
denialhaag merged 11 commits intomainfrom
streamline-conversions
Mar 10, 2026
Merged

🎨 Streamline conversions#1548
denialhaag merged 11 commits intomainfrom
streamline-conversions

Conversation

@denialhaag
Copy link
Copy Markdown
Member

@denialhaag denialhaag commented Mar 10, 2026

Description

This PR streamlines the conversions in several aspects:

  • Use add_mlir_conversion_library() instead of add_mlir_library()
  • Prefix conversion targets with MLIR
  • Use templated structs instead of macros und remove superfluous helper functions
  • Replace all instances of rewriter.create<Op>(...) with `Op::create(rewriter, ...)

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.

@denialhaag denialhaag self-assigned this Mar 10, 2026
@denialhaag denialhaag added enhancement Improvement of existing feature MLIR Anything related to MLIR labels Mar 10, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 10, 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: 4f0dd490-78ab-4980-a3cf-5496814b52b7

📥 Commits

Reviewing files that changed from the base of the PR and between 7451ee9 and f01e7e2.

📒 Files selected for processing (1)
  • docs/mlir/QCO.md

📝 Walkthrough

Summary by CodeRabbit

  • Documentation

    • Added new documentation sections covering Jeff↔QCO conversions and QCO passes.
  • Refactor

    • Consolidated and modernized conversion logic across multiple conversion paths for more uniform, maintainable behavior.
    • Updated build/test wiring to reference the refreshed conversion components.

Walkthrough

Renames MLIR conversion targets to MLIR-prefixed names, replaces macro-based conversion patterns with template-based converter structs across conversion passes, switches many op constructions to static Op::create(...) factories, and updates CMakeLists, unit-test linkages, and documentation includes.

Changes

Cohort / File(s) Summary
Docs
docs/mlir/Conversions.md, docs/mlir/QCO.md
Added includes for Jeff↔QCO conversion docs and a "Passes" include for QCO (documentation-only additions).
Top-level CMake
mlir/lib/Compiler/CMakeLists.txt
Updated MQTCompilerPipeline PUBLIC link targets to use renamed MLIR conversion targets (QCToQCO→MLIRQCToQCO, QCOToQC→MLIRQCOToQC, QCToQIR→MLIRQCToQIR).
Conversion CMakeLists
mlir/lib/Conversion/.../CMakeLists.txt (JeffToQCO, QCOToJeff, QCOToQC, QCToQCO, QCToQIR)
Replaced add_mlir_library(...) with add_mlir_conversion_library(...), renamed public targets to MLIR-prefixed names, and updated target_use_project_options / conditional checks.
Jeff ↔ QCO conversions
mlir/lib/Conversion/JeffToQCO/JeffToQCO.cpp, mlir/lib/Conversion/QCOToJeff/QCOToJeff.cpp
Removed macro-generated converters and introduced templated converter structs (one-/two-/three-parameter and adjoint variants); centralized result handling and updated pattern registrations.
QCO ↔ QC and QC→QCO conversions
mlir/lib/Conversion/QCOToQC/QCOToQC.cpp, mlir/lib/Conversion/QCToQCO/QCToQCO.cpp
Replaced broad macro-based conversions with comprehensive template-based ConvertQCO...ToQC and ConvertQC...ToQCO families; added QCOToQCTypeConverter; rewrote pattern registrations to use templates.
QC→QIR
mlir/lib/Conversion/QCToQIR/QCToQIR.cpp
Switched from rewriter.create<LLVM::CallOp>(...) to LLVM::CallOp::create(...) for QIR measurement call emission.
QCO dialect factory usage
mlir/lib/Dialect/QCO/IR/Modifiers/CtrlOp.cpp, .../Operations/StandardGates/BarrierOp.cpp, .../Transforms/Mapping/Mapping.cpp
Replaced rewriter.create<Op>(...) with static Op::create(rewriter, loc, ...) factory methods for several QCO ops (POp, BarrierOp, StaticOp, DeallocOp, SWAPOp, etc.).
Unit test CMake updates
mlir/unittests/.../CMakeLists.txt (JeffRoundTrip, QCOToQC, QCToQCO, QCToQIR, Dialect QCO Mapping tests)
Updated target_link_libraries to reference renamed MLIR conversion targets used by unit tests.
CHANGELOG
CHANGELOG.md
Added PR reference #1548 for Jeff↔QCO conversion in Unreleased section.

Sequence Diagram(s)

sequenceDiagram
    participant Source as Source IR (Jeff / QC)
    participant JeffPass as MLIRJeffToQCO
    participant QCOPass as MLIRQCOToQC / MLIRQCOToJeff
    participant QIRPass as MLIRQCToQIR
    participant Pipeline as MQTCompilerPipeline

    Source->>JeffPass: match ops, apply template patterns
    JeffPass->>QCOPass: emit QCO/QC ops (stateful mappings)
    QCOPass->>QIRPass: lower to QIR calls / LLVM::CallOps
    Pipeline->>JeffPass: register patterns (MLIR target)
    Pipeline->>QCOPass: register patterns (MLIR target)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

refactor, c++

Suggested reviewers

  • burgholzer

Poem

🐰 I hop through headers, templates shining bright,
Macros tuck away, factories build with might.
Passes renamed and patterns neat,
Conversions hum with rhythmic beat,
A carrot-coded celebration tonight! 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title '🎨 Streamline conversions' is concise, clear, and accurately reflects the main objective of the PR to refactor and streamline the conversion infrastructure.
Description check ✅ Passed The description provides a clear summary of changes across four dimensions (CMake updates, target renaming, macro-to-template refactoring, API changes) and includes a completed checklist aligned with the changeset.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch streamline-conversions

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
Copy Markdown
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: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
mlir/lib/Conversion/QCOToQC/CMakeLists.txt (1)

25-25: ⚠️ Potential issue | 🟡 Minor

Target name mismatch in mqt_mlir_target_use_project_options.

Same issue as in QCToQCO/CMakeLists.txt: the library target is now MLIRQCOToQC, but this call still references QCOToQC.

Proposed fix
-mqt_mlir_target_use_project_options(QCOToQC)
+mqt_mlir_target_use_project_options(MLIRQCOToQC)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@mlir/lib/Conversion/QCOToQC/CMakeLists.txt` at line 25, The call to
mqt_mlir_target_use_project_options currently references the old target name
QCOToQC; update this to the new library target MLIRQCOToQC (i.e., replace the
argument in mqt_mlir_target_use_project_options to MLIRQCOToQC) so the project
options are applied to the correct target defined for this directory.
mlir/lib/Conversion/QCToQCO/CMakeLists.txt (1)

25-25: ⚠️ Potential issue | 🟡 Minor

Update mqt_mlir_target_use_project_options to match the actual MLIR-prefixed target name.

The library target created by add_mlir_conversion_library on line 12 is MLIRQCToQCO, but the call on line 25 references QCToQCO. This causes the function to silently fail to find the target and skip applying project options.

Proposed fix
-mqt_mlir_target_use_project_options(QCToQCO)
+mqt_mlir_target_use_project_options(MLIRQCToQCO)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@mlir/lib/Conversion/QCToQCO/CMakeLists.txt` at line 25, The call to
mqt_mlir_target_use_project_options uses the wrong target name (QCToQCO) so it
doesn't apply project options; update that call to use the actual MLIR target
name MLIRQCToQCO (the target created by add_mlir_conversion_library) by
replacing the QCToQCO argument with MLIRQCToQCO so
mqt_mlir_target_use_project_options can locate and apply the options to the
correct target.
mlir/lib/Conversion/QCOToQC/QCOToQC.cpp (1)

757-814: ⚠️ Potential issue | 🔴 Critical

Re-add the SCF conversion patterns before applying this pass.

This registration block no longer installs any ConvertQCOScf* patterns or scf::* legality rules. populateBranchOpInterfaceTypeConversionPattern only covers branch-like ops, not scf.if/scf.while/scf.for, so all-qubit SCF regions that this pass previously handled will now be left behind or accepted with !qco.qubit types still embedded in legal scf ops.

Please restore the dedicated ConvertQCOScfYieldOp, ConvertQCOScfConditionOp, ConvertQCOScfIfOp, ConvertQCOScfWhileOp, and ConvertQCOScfForOp registrations together with the corresponding dynamic legality checks. Based on learnings: ensure mlir/lib/Conversion/QCOToQC/QCOToQC.cpp keeps dedicated all-qubit ConvertQCOScf* patterns for SCF conversion.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@mlir/lib/Conversion/QCOToQC/QCOToQC.cpp` around lines 757 - 814, The SCF
conversion patterns were removed and must be re-added: register
ConvertQCOScfYieldOp, ConvertQCOScfConditionOp, ConvertQCOScfIfOp,
ConvertQCOScfWhileOp, and ConvertQCOScfForOp into the same
patterns.add<...>(typeConverter, context) call (or immediately after) so SCF
regions get converted; also add dynamic legality checks for scf.if, scf.for,
scf.while and scf.yield (using target.addDynamicallyLegalOp with lambdas that
call typeConverter.isLegal(...) or isSignatureLegal(...) as appropriate) before
calling applyPartialConversion so those ops are treated as illegal until
converted (do not rely solely on
populateBranchOpInterfaceTypeConversionPattern).
🤖 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/lib/Conversion/QCOToJeff/QCOToJeff.cpp`:
- Line 439: Change the inconsistent use of this->getState() in the
ConvertQCOSXOpToJeff class to match the file's style by calling getState()
without the this-> qualifier; locate the occurrence in ConvertQCOSXOpToJeff
(currently using this->getState()) and replace it with getState(), keeping
behavior unchanged and aligning with other converters like
ConvertQCOSXdgOpToJeff and ConvertQCOiSWAPOpToJeff.

In `@mlir/lib/Conversion/QCToQIR/CMakeLists.txt`:
- Around line 11-12: The target created by add_mlir_conversion_library was
renamed to MLIRQCToQIR, but the call
mqt_mlir_target_use_project_options(QCToQIR) still references the old target
name; update the call to mqt_mlir_target_use_project_options to use MLIRQCToQIR
(i.e., replace QCToQIR with MLIRQCToQIR) so the CMake target names match (check
add_mlir_conversion_library and the mqt_mlir_target_use_project_options
invocation).

---

Outside diff comments:
In `@mlir/lib/Conversion/QCOToQC/CMakeLists.txt`:
- Line 25: The call to mqt_mlir_target_use_project_options currently references
the old target name QCOToQC; update this to the new library target MLIRQCOToQC
(i.e., replace the argument in mqt_mlir_target_use_project_options to
MLIRQCOToQC) so the project options are applied to the correct target defined
for this directory.

In `@mlir/lib/Conversion/QCOToQC/QCOToQC.cpp`:
- Around line 757-814: The SCF conversion patterns were removed and must be
re-added: register ConvertQCOScfYieldOp, ConvertQCOScfConditionOp,
ConvertQCOScfIfOp, ConvertQCOScfWhileOp, and ConvertQCOScfForOp into the same
patterns.add<...>(typeConverter, context) call (or immediately after) so SCF
regions get converted; also add dynamic legality checks for scf.if, scf.for,
scf.while and scf.yield (using target.addDynamicallyLegalOp with lambdas that
call typeConverter.isLegal(...) or isSignatureLegal(...) as appropriate) before
calling applyPartialConversion so those ops are treated as illegal until
converted (do not rely solely on
populateBranchOpInterfaceTypeConversionPattern).

In `@mlir/lib/Conversion/QCToQCO/CMakeLists.txt`:
- Line 25: The call to mqt_mlir_target_use_project_options uses the wrong target
name (QCToQCO) so it doesn't apply project options; update that call to use the
actual MLIR target name MLIRQCToQCO (the target created by
add_mlir_conversion_library) by replacing the QCToQCO argument with MLIRQCToQCO
so mqt_mlir_target_use_project_options can locate and apply the options to the
correct target.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 6f48e9f0-c0ea-4e07-8911-d5d57a9b5655

📥 Commits

Reviewing files that changed from the base of the PR and between 6b208c4 and 52e985d.

📒 Files selected for processing (21)
  • docs/mlir/Conversions.md
  • docs/mlir/QCO.md
  • mlir/lib/Compiler/CMakeLists.txt
  • mlir/lib/Conversion/JeffToQCO/CMakeLists.txt
  • mlir/lib/Conversion/JeffToQCO/JeffToQCO.cpp
  • mlir/lib/Conversion/QCOToJeff/CMakeLists.txt
  • mlir/lib/Conversion/QCOToJeff/QCOToJeff.cpp
  • mlir/lib/Conversion/QCOToQC/CMakeLists.txt
  • mlir/lib/Conversion/QCOToQC/QCOToQC.cpp
  • mlir/lib/Conversion/QCToQCO/CMakeLists.txt
  • mlir/lib/Conversion/QCToQCO/QCToQCO.cpp
  • mlir/lib/Conversion/QCToQIR/CMakeLists.txt
  • mlir/lib/Conversion/QCToQIR/QCToQIR.cpp
  • mlir/lib/Dialect/QCO/IR/Modifiers/CtrlOp.cpp
  • mlir/lib/Dialect/QCO/IR/Operations/StandardGates/BarrierOp.cpp
  • mlir/lib/Dialect/QCO/Transforms/Mapping/Mapping.cpp
  • mlir/unittests/Conversion/JeffRoundTrip/CMakeLists.txt
  • mlir/unittests/Conversion/QCOToQC/CMakeLists.txt
  • mlir/unittests/Conversion/QCToQCO/CMakeLists.txt
  • mlir/unittests/Conversion/QCToQIR/CMakeLists.txt
  • mlir/unittests/Dialect/QCO/Transforms/Mapping/CMakeLists.txt

Comment thread mlir/lib/Conversion/QCOToJeff/QCOToJeff.cpp Outdated
Comment thread mlir/lib/Conversion/QCToQIR/CMakeLists.txt
@denialhaag denialhaag requested a review from burgholzer March 10, 2026 21:10
Copy link
Copy Markdown
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/lib/Conversion/QCOToJeff/QCOToJeff.cpp`:
- Around line 366-418: The four ConvertQCO... template matchAndRewrite
implementations duplicate the same modifier/result bookkeeping (checking
state.inModifier()/selecting target from state.targetsIn, choosing between
rewriter.replaceOp vs rewriter.eraseOp and assigning state.targetsOut, and
setting state.controlsOut from jeffOp.getOutCtrlQubits()); factor that into one
or two small helpers (e.g., handleSingleTargetPostprocess(StateType&, Operation*
originalOp, Value outQubit, ArrayRef<Value> outCtrlQubits) and a two-target
variant) and call them from
ConvertQCOOneTargetZeroParameterToJeff::matchAndRewrite (and the other three
template families referenced). Ensure the helpers use state.inModifier(),
state.targetsIn, rewriter.replaceOp/eraseOp, state.targetsOut, and
state.controlsOut to preserve current behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 209325b7-208f-466b-9d18-e25f4573b5c3

📥 Commits

Reviewing files that changed from the base of the PR and between 52e985d and fc4e382.

📒 Files selected for processing (6)
  • CHANGELOG.md
  • mlir/lib/Conversion/QCOToJeff/QCOToJeff.cpp
  • mlir/lib/Conversion/QCOToQC/CMakeLists.txt
  • mlir/lib/Conversion/QCOToQC/QCOToQC.cpp
  • mlir/lib/Conversion/QCToQCO/CMakeLists.txt
  • mlir/lib/Conversion/QCToQIR/CMakeLists.txt

Comment thread mlir/lib/Conversion/QCOToJeff/QCOToJeff.cpp
Copy link
Copy Markdown
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.

This looks great! I think the one suggestion by the rabbit might make sense. But then this can go in 🙌

@denialhaag denialhaag enabled auto-merge (squash) March 10, 2026 23:18
@denialhaag denialhaag merged commit 81abfca into main Mar 10, 2026
34 checks passed
@denialhaag denialhaag deleted the streamline-conversions branch March 10, 2026 23:47
@codecov
Copy link
Copy Markdown

codecov Bot commented Mar 11, 2026

Codecov Report

❌ Patch coverage is 97.58454% with 5 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
mlir/lib/Conversion/QCToQCO/QCToQCO.cpp 96.8% 5 Missing ⚠️

📢 Thoughts on this report? Let us know!

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

Labels

enhancement Improvement of existing feature MLIR Anything related to MLIR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants