Skip to content

Conversation

@taminob
Copy link
Collaborator

@taminob taminob commented Jan 8, 2026

Description

Unfortunately, this became a little bit more cumbersome to figure out than expected.
The automatically generated getter for the parameter "body" was hiding one of the trait interface methods. These methods do have a slightly different signature (getBody() returns a Block* and getBodyRegion() accepts an index parameter) which can lead to confusion and an inconsistent API.

An alternative to this proposal could be simply the name "region" because getRegion() of the OneRegion trait has the same signature and thus the override would probably not be noticed. However, there would be two identical implementations for this method and this could make debugging harder.

The downside to the current solution is that there are now three functions to access the region: getRegion() (by OneRegion), getBodyRegion() (by SingleBlock) and getCtrlBodyRegion() (by getter).

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.

@taminob taminob self-assigned this Jan 8, 2026
@taminob taminob added bug Something isn't working c++ Anything related to C++ code MLIR Anything related to MLIR labels Jan 8, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 8, 2026

📝 Walkthrough

Summary by CodeRabbit

  • Refactor

    • Standardized internal region accessor naming conventions across the codebase for improved API consistency.
    • Updated region access patterns to use unified method interfaces throughout the dialect implementations.
  • Chores

    • Updated changelog documentation with additional release references.

✏️ Tip: You can customize this high-level summary in your review settings.

Walkthrough

CtrlOp's region symbol renamed from body to region in TD files; all references in conversion passes and modifier implementations updated to use the generic region accessor (getRegion() / region pointer) and adjusted block/front accesses accordingly.

Changes

Cohort / File(s) Summary
Operation Definitions
mlir/include/mlir/Dialect/QC/IR/QCOps.td, mlir/include/mlir/Dialect/QCO/IR/QCOOps.td
CtrlOp region symbol renamed (let regions = ...:$body:$region) and assemblyFormat updated to use $region.
Conversion Passes
mlir/lib/Conversion/QCOToQC/QCOToQC.cpp, mlir/lib/Conversion/QCToQCO/QCToQCO.cpp
Replaced getBody() with getRegion() and updated cloneRegionBefore source/destination to use the region accessor.
CtrlOp Implementations / Modifiers
mlir/lib/Dialect/QC/IR/Modifiers/CtrlOp.cpp, mlir/lib/Dialect/QCO/IR/Modifiers/CtrlOp.cpp
Adjusted body/block access to use region-level accessors (e.g., *getRegion(), getRegion()->front()); updated getBodyUnitary() and verify() accordingly.
Changelog
CHANGELOG.md
Added PR references entries (cosmetic/documentation).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

code quality

Suggested reviewers

  • burgholzer
  • ystade

Poem

🐰 I hopped through TDs and fields so wide,
Renamed the span where regions hide.
getRegion() now leads the gentle race,
Blocks found with pointers, neat and in place.
A nibble, a hop — clean code, carrot-tied! 🥕

🚥 Pre-merge checks | ✅ 3 | ❌ 2
❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Linked Issues check ❓ Inconclusive The description lacks an explicit issue reference (no 'Fixes #' statement) despite referencing a PR number context. Clarify whether this PR addresses a specific GitHub issue or is a standalone refactoring, and update the description accordingly.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: renaming CtrlOp's region parameter to avoid method hiding.
Description check ✅ Passed The description explains the motivation and technical reasoning but lacks specific implementation details about which methods changed and omits issue references.
Out of Scope Changes check ✅ Passed Changes are focused on renaming CtrlOp region parameter and updating corresponding method calls across the codebase, with minimal scope creep.

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


📜 Recent review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f9f2e94 and 1631e44.

📒 Files selected for processing (1)
  • CHANGELOG.md
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1264
File: mlir/lib/Dialect/Quartz/IR/Modifiers/CtrlOp.cpp:80-100
Timestamp: 2025-12-08T23:58:09.648Z
Learning: In the Quartz dialect (mlir/lib/Dialect/Quartz/IR/Modifiers/CtrlOp.cpp), quartz.ctrl uses reference semantics and does not return values, unlike flux.ctrl which uses value semantics and returns transformed qubits. When inlining a GPhaseOp in the CtrlInlineGPhase pattern, it's correct to create POp operations for positive controls and erase the CtrlOp without collecting or replacing result values.
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1264
File: mlir/lib/Dialect/Quartz/IR/Modifiers/CtrlOp.cpp:60-70
Timestamp: 2025-12-08T12:44:05.883Z
Learning: In the Quartz dialect (mlir/lib/Dialect/Quartz/IR/Modifiers/CtrlOp.cpp), negative controls are not supported at the current stage. The RemoveTrivialCtrl pattern correctly only checks getNumPosControls() when determining if a CtrlOp should be removed.
📚 Learning: 2025-12-05T17:45:37.602Z
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1360
File: .github/workflows/reusable-mlir-tests.yml:40-43
Timestamp: 2025-12-05T17:45:37.602Z
Learning: In the munich-quantum-toolkit/core repository, patch releases of LLVM dependencies don't require documentation updates, changelog entries, or additional tests beyond what's validated by passing CI checks.

Applied to files:

  • CHANGELOG.md
📚 Learning: 2025-10-14T14:37:38.047Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/yaqs PR: 212
File: CHANGELOG.md:12-15
Timestamp: 2025-10-14T14:37:38.047Z
Learning: In the munich-quantum-toolkit/yaqs project, changelog entries follow the template: "- $TITLE ([#$NUMBER]($URL)) ([**AUTHOR**](https://github.com/$AUTHOR))". Issue references should not be included in changelog entries; the PR number is sufficient for traceability.

Applied to files:

  • CHANGELOG.md
📚 Learning: 2025-12-01T11:00:40.342Z
Learnt from: flowerthrower
Repo: munich-quantum-toolkit/core-plugins-catalyst PR: 1
File: CHANGELOG.md:18-18
Timestamp: 2025-12-01T11:00:40.342Z
Learning: In the munich-quantum-toolkit/core-plugins-catalyst repository, the CHANGELOG.md intentionally references the parent MQT Core repository's release notes (https://github.com/munich-quantum-toolkit/core/releases) because the plugin repository is based on work performed in the parent repository.

Applied to files:

  • CHANGELOG.md
📚 Learning: 2025-11-24T10:19:41.147Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1326
File: python/mqt/core/__init__.py:22-22
Timestamp: 2025-11-24T10:19:41.147Z
Learning: In the munich-quantum-toolkit/core repository, Ruff is configured with 'ALL' rules enabled by default, and only specific rules are selectively disabled. When reviewing changes that enable previously-disabled rules (like PLC0415), noqa directives for those rules become necessary and should be retained.

Applied to files:

  • CHANGELOG.md
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: 🇨‌ Test 🐧 (ubuntu-24.04, gcc, Debug) / 🐧 ubuntu-24.04 gcc Debug
  • GitHub Check: 🇨‌ Test 🏁 (windows-11-arm, msvc, Release) / 🏁 windows-11-arm msvc Release
  • GitHub Check: 🇨‌ Test 🐧 (ubuntu-24.04, gcc, Release) / 🐧 ubuntu-24.04 gcc Release
  • GitHub Check: 🇨‌ Test 🏁 (windows-2025, msvc, Release) / 🏁 windows-2025 msvc Release
  • GitHub Check: 🇨‌ Test 🍎 (macos-15, clang, Release) / 🍎 macos-15 clang Release
  • GitHub Check: 🇨‌ Test 🍎 (macos-15-intel, clang, Release) / 🍎 macos-15-intel clang Release
  • GitHub Check: 🇨‌ Lint / 🚨 Lint
  • GitHub Check: 🇨‌ Coverage / 📈 Coverage
  • GitHub Check: Run
🔇 Additional comments (1)
CHANGELOG.md (1)

14-14: Changelog entry correctly groups follow-up PRs with dialect infrastructure work.

The changelog entry appropriately groups PR #1430 with related dialect infrastructure PRs (#1264, #1402, #1428) rather than creating a separate fragment, which aligns with project guidance for small follow-ups to larger initiatives. The PR link references are properly formatted and sorted in descending order.

Also applies to: 297-298


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.

@codecov
Copy link

codecov bot commented Jan 8, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@burgholzer burgholzer added this to the MLIR Support milestone Jan 8, 2026
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.

This LGTM and I wouldn't worry too much about the different ways to get the region.
However, the proposal of simply calling it $region seems enticing.
This would simply be an override of the respective method, right?
Could we try this here in the PR?

@taminob
Copy link
Collaborator Author

taminob commented Jan 8, 2026

This would simply be an override of the respective method, right?

It is not an override since the original method is not virtual. So the original one can still be called via up-casting (and is internally used, e.g. for getOps()).
I'd rather call it "hiding" the other method - but the implementation is the same anyway, so I'll do that. Probably better than polluting the API with one more (unnecessary) way to get the region.

This prevents the automatically generated getter to hide one of the
trait interface methods. These methods do have a slightly different
signature (getBody() returns a Block and getBodyRegion() accepts a index
parameter) which could lead to confusion and is an inconsistent API.

An alternative could be simply the name "region" because getRegion() of
the OneRegion trait has the same signature and thus the override would
probably not be noticed. However, there would be two identical
implementations for this method and this could make debugging harder.

The downside to this solution is that there are now three functions to
access the region: getRegion() (by OneRegion), getBodyRegion() (by
SingleBlock) and getCtrlBodyRegion() (by getter).
This will intentionally hide OneRegion::getRegion() which is exactly the
same anyway.
It avoids adding an additional method to the API that does exactly the
same as getBodyRegion() and getRegion().
@taminob taminob force-pushed the taminob/mlir-qco-rework-ctrl-op-methods branch from 804dc3d to f9f2e94 Compare January 8, 2026 14:41
@taminob
Copy link
Collaborator Author

taminob commented Jan 8, 2026

Does this change require an addition to the changelog? I'm not sure how you want to handle these small follow-ups for the dialect rewrite.

@burgholzer
Copy link
Member

Does this change require an addition to the changelog? I'm not sure how you want to handle these small follow-ups for the dialect rewrite.

While the dialect rewrite is not part of an official release, I would typically not include changelog fragments for changes like these.
However, feel free to add this PR number (and the other one) as well as your name to the changelog entry for the dialect redesign.
That would be appropriate in my opinion.

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

🤖 Fix all issues with AI agents
In @mlir/lib/Dialect/QC/IR/Modifiers/CtrlOp.cpp:
- Line 112: The PR text is inconsistent: the TableGen def uses
SizedRegion<1>:$region (see QCOps.td entries) so the generated getter is
getRegion(), not getCtrlBodyRegion(); update the PR title and description to
state the region was renamed to "region" and mention the generated accessor
getRegion() (and any references to ctrlBodyRegion in comments or docs) so they
match the actual TableGen symbol and generated API.
📜 Review details

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9ae9af9 and f9f2e94.

📒 Files selected for processing (6)
  • mlir/include/mlir/Dialect/QC/IR/QCOps.td
  • mlir/include/mlir/Dialect/QCO/IR/QCOOps.td
  • mlir/lib/Conversion/QCOToQC/QCOToQC.cpp
  • mlir/lib/Conversion/QCToQCO/QCToQCO.cpp
  • mlir/lib/Dialect/QC/IR/Modifiers/CtrlOp.cpp
  • mlir/lib/Dialect/QCO/IR/Modifiers/CtrlOp.cpp
🧰 Additional context used
🧠 Learnings (15)
📓 Common learnings
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1264
File: mlir/lib/Dialect/Quartz/IR/Modifiers/CtrlOp.cpp:80-100
Timestamp: 2025-12-08T23:58:09.648Z
Learning: In the Quartz dialect (mlir/lib/Dialect/Quartz/IR/Modifiers/CtrlOp.cpp), quartz.ctrl uses reference semantics and does not return values, unlike flux.ctrl which uses value semantics and returns transformed qubits. When inlining a GPhaseOp in the CtrlInlineGPhase pattern, it's correct to create POp operations for positive controls and erase the CtrlOp without collecting or replacing result values.
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1264
File: mlir/lib/Dialect/Quartz/IR/Modifiers/CtrlOp.cpp:60-70
Timestamp: 2025-12-08T12:44:05.883Z
Learning: In the Quartz dialect (mlir/lib/Dialect/Quartz/IR/Modifiers/CtrlOp.cpp), negative controls are not supported at the current stage. The RemoveTrivialCtrl pattern correctly only checks getNumPosControls() when determining if a CtrlOp should be removed.
📚 Learning: 2025-12-08T23:58:09.648Z
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1264
File: mlir/lib/Dialect/Quartz/IR/Modifiers/CtrlOp.cpp:80-100
Timestamp: 2025-12-08T23:58:09.648Z
Learning: In the Quartz dialect (mlir/lib/Dialect/Quartz/IR/Modifiers/CtrlOp.cpp), quartz.ctrl uses reference semantics and does not return values, unlike flux.ctrl which uses value semantics and returns transformed qubits. When inlining a GPhaseOp in the CtrlInlineGPhase pattern, it's correct to create POp operations for positive controls and erase the CtrlOp without collecting or replacing result values.

Applied to files:

  • mlir/include/mlir/Dialect/QCO/IR/QCOOps.td
  • mlir/lib/Dialect/QCO/IR/Modifiers/CtrlOp.cpp
  • mlir/include/mlir/Dialect/QC/IR/QCOps.td
  • mlir/lib/Conversion/QCOToQC/QCOToQC.cpp
  • mlir/lib/Dialect/QC/IR/Modifiers/CtrlOp.cpp
  • mlir/lib/Conversion/QCToQCO/QCToQCO.cpp
📚 Learning: 2025-12-08T12:44:05.883Z
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1264
File: mlir/lib/Dialect/Quartz/IR/Modifiers/CtrlOp.cpp:60-70
Timestamp: 2025-12-08T12:44:05.883Z
Learning: In the Quartz dialect (mlir/lib/Dialect/Quartz/IR/Modifiers/CtrlOp.cpp), negative controls are not supported at the current stage. The RemoveTrivialCtrl pattern correctly only checks getNumPosControls() when determining if a CtrlOp should be removed.

Applied to files:

  • mlir/include/mlir/Dialect/QCO/IR/QCOOps.td
  • mlir/lib/Dialect/QCO/IR/Modifiers/CtrlOp.cpp
  • mlir/include/mlir/Dialect/QC/IR/QCOps.td
  • mlir/lib/Conversion/QCOToQC/QCOToQC.cpp
  • mlir/lib/Dialect/QC/IR/Modifiers/CtrlOp.cpp
  • mlir/lib/Conversion/QCToQCO/QCToQCO.cpp
📚 Learning: 2025-12-08T14:55:43.899Z
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1264
File: mlir/lib/Dialect/Flux/IR/Modifiers/CtrlOp.cpp:78-100
Timestamp: 2025-12-08T14:55:43.899Z
Learning: In the Flux dialect (mlir/lib/Dialect/Flux/IR/Modifiers/CtrlOp.cpp), GPhaseOp is a zero-target operation (global phase). When a CtrlOp wraps a GPhaseOp, it only has control qubits and no targets. The CtrlInlineGPhase canonicalization pattern correctly produces outputs only for the positive controls, not targets.

Applied to files:

  • mlir/include/mlir/Dialect/QCO/IR/QCOOps.td
  • mlir/lib/Dialect/QCO/IR/Modifiers/CtrlOp.cpp
  • mlir/include/mlir/Dialect/QC/IR/QCOps.td
  • mlir/lib/Dialect/QC/IR/Modifiers/CtrlOp.cpp
  • mlir/lib/Conversion/QCToQCO/QCToQCO.cpp
📚 Learning: 2025-12-08T23:16:20.680Z
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1264
File: mlir/lib/Dialect/Flux/IR/Modifiers/CtrlOp.cpp:78-101
Timestamp: 2025-12-08T23:16:20.680Z
Learning: In the Flux dialect (mlir/lib/Dialect/Flux/IR/Modifiers/CtrlOp.cpp), negative controls are not supported at the current stage. The CtrlInlineGPhase canonicalization pattern correctly only checks getNumPosControls() and processes only positive controls when inlining a GPhaseOp.

Applied to files:

  • mlir/include/mlir/Dialect/QCO/IR/QCOOps.td
  • mlir/lib/Dialect/QCO/IR/Modifiers/CtrlOp.cpp
  • mlir/include/mlir/Dialect/QC/IR/QCOps.td
  • mlir/lib/Dialect/QC/IR/Modifiers/CtrlOp.cpp
📚 Learning: 2025-12-14T17:02:02.997Z
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1264
File: mlir/lib/Dialect/Flux/Builder/FluxProgramBuilder.cpp:187-210
Timestamp: 2025-12-14T17:02:02.997Z
Learning: In the Flux dialect builder (mlir/lib/Dialect/Flux/Builder/FluxProgramBuilder.cpp), the coding style relies on implicit conversion from Value to ValueRange in ctrl() calls (e.g., `ctrl(control, {}, ...)` instead of `ctrl(ValueRange{control}, ValueRange{}, ...)`). This pattern is used consistently throughout all macro-generated methods and should be maintained for consistency.

Applied to files:

  • mlir/include/mlir/Dialect/QCO/IR/QCOOps.td
  • mlir/include/mlir/Dialect/QC/IR/QCOps.td
  • mlir/lib/Conversion/QCOToQC/QCOToQC.cpp
📚 Learning: 2025-12-17T17:44:21.624Z
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1264
File: mlir/include/mlir/Dialect/QCO/IR/QCOOps.td:259-259
Timestamp: 2025-12-17T17:44:21.624Z
Learning: In mlir/include/mlir/Dialect/QCO/IR/QCOOps.td (QCO dialect), ensure GPhaseOp declares MemoryEffects<[MemWrite]> rather than Pure. This op has no results and is a zero-target operation, so using Pure would lead to its removal by dead-code elimination. By marking it with MemWrite, review ensures DCE preserves the operation because it has a meaningful effect on the global quantum state. This guidance applies when reviewing or updating QCO ops in this file (and broadly to similar zero-target ops with side effects in QCO).

Applied to files:

  • mlir/include/mlir/Dialect/QCO/IR/QCOOps.td
📚 Learning: 2025-10-09T13:13:51.224Z
Learnt from: DRovara
Repo: munich-quantum-toolkit/core PR: 1108
File: mlir/lib/Dialect/MQTOpt/Transforms/ReplaceBasisStateControlsWithIfPattern.cpp:171-180
Timestamp: 2025-10-09T13:13:51.224Z
Learning: In MQT Core MLIR, UnitaryInterface operations guarantee 1-1 correspondence between input and output qubits in the same order. When cloning or modifying unitary operations (e.g., removing controls), this correspondence is maintained by construction, so yielding getAllInQubits() in else-branches matches the result types from the operation's outputs.

Applied to files:

  • mlir/lib/Dialect/QCO/IR/Modifiers/CtrlOp.cpp
  • mlir/include/mlir/Dialect/QC/IR/QCOps.td
  • mlir/lib/Conversion/QCOToQC/QCOToQC.cpp
  • mlir/lib/Dialect/QC/IR/Modifiers/CtrlOp.cpp
  • mlir/lib/Conversion/QCToQCO/QCToQCO.cpp
📚 Learning: 2026-01-07T12:29:02.062Z
Learnt from: li-mingbao
Repo: munich-quantum-toolkit/core PR: 1396
File: mlir/lib/Conversion/QCOToQC/QCOToQC.cpp:1040-1050
Timestamp: 2026-01-07T12:29:02.062Z
Learning: In the QCOToQC conversion pass (mlir/lib/Conversion/QCOToQC/QCOToQC.cpp), ConvertQCOFuncCallOp assumes that if a func::CallOp has qubit results, then all arguments and results are qubits (no mixed classical/quantum types). The conversion is scoped to handle all-qubit function calls only.

Applied to files:

  • mlir/lib/Dialect/QCO/IR/Modifiers/CtrlOp.cpp
  • mlir/include/mlir/Dialect/QC/IR/QCOps.td
  • mlir/lib/Conversion/QCOToQC/QCOToQC.cpp
  • mlir/lib/Conversion/QCToQCO/QCToQCO.cpp
📚 Learning: 2026-01-07T12:29:16.380Z
Learnt from: li-mingbao
Repo: munich-quantum-toolkit/core PR: 1396
File: mlir/lib/Conversion/QCOToQC/QCOToQC.cpp:1070-1085
Timestamp: 2026-01-07T12:29:16.380Z
Learning: In the QCOToQC conversion pass (mlir/lib/Conversion/QCOToQC/QCOToQC.cpp), the ConvertQCOFuncFuncOp pattern assumes that when a func.func operation is matched for conversion, all of its arguments are qco.qubit types (never mixed qubit/classical). The pattern unconditionally converts all arguments to qc::QubitType based on this assumption.

Applied to files:

  • mlir/lib/Dialect/QCO/IR/Modifiers/CtrlOp.cpp
  • mlir/include/mlir/Dialect/QC/IR/QCOps.td
  • mlir/lib/Conversion/QCOToQC/QCOToQC.cpp
  • mlir/lib/Conversion/QCToQCO/QCToQCO.cpp
📚 Learning: 2025-10-09T13:25:36.887Z
Learnt from: DRovara
Repo: munich-quantum-toolkit/core PR: 1108
File: mlir/lib/Dialect/MQTOpt/Transforms/ReuseQubitsPattern.cpp:98-100
Timestamp: 2025-10-09T13:25:36.887Z
Learning: In MLIR code, when traversing parent operations to find a common block between two operations where one uses the result of another, explicit bounds checking is not necessary. MLIR's SSA properties and scope locality guarantees ensure that operations using results must be in compatible scopes and will always share a common ancestor in the operation hierarchy.

Applied to files:

  • mlir/lib/Dialect/QCO/IR/Modifiers/CtrlOp.cpp
  • mlir/lib/Dialect/QC/IR/Modifiers/CtrlOp.cpp
📚 Learning: 2025-12-08T23:44:39.930Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1264
File: mlir/lib/Dialect/Quartz/IR/Operations/StandardGates/PhaseOp.cpp:0-0
Timestamp: 2025-12-08T23:44:39.930Z
Learning: In MLIR code under any mlir/ directory, avoid using const qualifiers on core MLIR types in function parameters/signatures (e.g., Value, Type, Attribute, Operation*, Block*, Region*, etc.). This aligns with MLIR's design rationale and should be applied to C++ source files (e.g., .cpp) within mlir/; see https://mlir.llvm.org/docs/Rationale/UsageOfConst/ for details.

Applied to files:

  • mlir/lib/Dialect/QCO/IR/Modifiers/CtrlOp.cpp
  • mlir/lib/Conversion/QCOToQC/QCOToQC.cpp
  • mlir/lib/Dialect/QC/IR/Modifiers/CtrlOp.cpp
  • mlir/lib/Conversion/QCToQCO/QCToQCO.cpp
📚 Learning: 2025-12-17T11:32:45.843Z
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1264
File: mlir/lib/Dialect/MQTOpt/Transforms/Transpilation/LayeredUnit.cpp:83-86
Timestamp: 2025-12-17T11:32:45.843Z
Learning: In the mlir portion of munich-quantum-toolkit/core, prefer marking free functions as static (static linkage) over placing them in anonymous namespaces, per the clang-tidy rule llvm-prefer-static-over-anonymous-namespace. Do not apply this to type/class definitions; they may continue to use anonymous namespaces. This guideline should be checked across C++ source files under mlir/ (e.g., any free function in LayeredUnit.cpp) to ensure free functions have static linkage, while types/classes can remain in anonymous namespaces.

Applied to files:

  • mlir/lib/Dialect/QCO/IR/Modifiers/CtrlOp.cpp
  • mlir/lib/Conversion/QCOToQC/QCOToQC.cpp
  • mlir/lib/Dialect/QC/IR/Modifiers/CtrlOp.cpp
  • mlir/lib/Conversion/QCToQCO/QCToQCO.cpp
📚 Learning: 2025-12-17T17:44:31.349Z
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1264
File: mlir/include/mlir/Dialect/QCO/IR/QCOOps.td:259-259
Timestamp: 2025-12-17T17:44:31.349Z
Learning: In the QCO dialect (mlir/include/mlir/Dialect/QCO/IR/QCOOps.td), GPhaseOp intentionally uses `MemoryEffects<[MemWrite]>` instead of `Pure` to prevent the remove-dead-values pass from eliminating it. Since GPhaseOp is a zero-target operation with no result values, it would otherwise be removed by DCE, even though it has a meaningful effect on the global quantum state.

Applied to files:

  • mlir/include/mlir/Dialect/QC/IR/QCOps.td
  • mlir/lib/Conversion/QCOToQC/QCOToQC.cpp
  • mlir/lib/Conversion/QCToQCO/QCToQCO.cpp
📚 Learning: 2025-12-02T07:37:46.860Z
Learnt from: MatthiasReumann
Repo: munich-quantum-toolkit/core PR: 1301
File: mlir/lib/Dialect/MQTOpt/Transforms/Transpilation/sc/NaiveRoutingPass.cpp:144-151
Timestamp: 2025-12-02T07:37:46.860Z
Learning: In MLIR transformation code (mlir/lib/Dialect/MQTOpt/Transforms/Transpilation/sc/NaiveRoutingPass.cpp and similar), when inserting operations before a target operation, prefer `rewriter.setInsertionPoint(op)` over `rewriter.setInsertionPointAfter(op->getPrevNode())`. The former is cleaner, avoids null pointer edge cases (when op is first in block), and is semantically clearer.

Applied to files:

  • mlir/lib/Conversion/QCOToQC/QCOToQC.cpp
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
  • GitHub Check: 🇨‌ Test 🍎 (macos-15, clang, Debug) / 🍎 macos-15 clang Debug
  • GitHub Check: 🇨‌ Test 🏁 (windows-2025, msvc, Release) / 🏁 windows-2025 msvc Release
  • GitHub Check: 🇨‌ Test 🐧 (ubuntu-24.04-arm, gcc, Release) / 🐧 ubuntu-24.04-arm gcc Release
  • GitHub Check: 🇨‌ Test 🍎 (macos-15-intel, clang, Release) / 🍎 macos-15-intel clang Release
  • GitHub Check: 🇨‌ Test 🏁 (windows-2025, msvc, Debug) / 🏁 windows-2025 msvc Debug
  • GitHub Check: 🇨‌ Test 🍎 (macos-15, clang, Release) / 🍎 macos-15 clang Release
  • GitHub Check: 🇨‌ Test 🐧 (ubuntu-24.04, gcc, Debug) / 🐧 ubuntu-24.04 gcc Debug
  • GitHub Check: 🇨‌ Test 🏁 (windows-11-arm, msvc, Release) / 🏁 windows-11-arm msvc Release
  • GitHub Check: 🇨‌ Test 🐧 (ubuntu-24.04, gcc, Release) / 🐧 ubuntu-24.04 gcc Release
  • GitHub Check: 🇨‌ Lint / 🚨 Lint
  • GitHub Check: 🇨‌ Coverage / 📈 Coverage
🔇 Additional comments (6)
mlir/include/mlir/Dialect/QCO/IR/QCOOps.td (1)

1070-1073: LGTM: Region symbol and assembly format correctly updated.

The region symbol rename from $body to $region and the corresponding assembly format update are correct. This will generate a getRegion() method, allowing the getBody() method from the SingleBlock trait (line 1046) to be used without name collision.

mlir/lib/Dialect/QCO/IR/Modifiers/CtrlOp.cpp (1)

155-155: LGTM: Changes consistent with QC dialect pattern.

The updates mirror those in the QC dialect's CtrlOp.cpp:

  • Line 155: getBody()->front() correctly accesses the first operation in the body block
  • Line 275: *getBody() correctly dereferences the Block pointer to get a Block reference

These changes are consistent with using the trait-provided getBody() that returns Block*.

Also applies to: 275-275

mlir/lib/Conversion/QCToQCO/QCToQCO.cpp (1)

1130-1131: LGTM: Conversion correctly uses the new region accessor.

The conversion now properly uses getRegion() to access the CtrlOp's region for cloning:

  • Line 1130: qcoOp.getRegion() obtains the destination region
  • Line 1131: op.getRegion() provides the source region for cloning

This aligns with the region symbol rename in the TableGen definitions.

mlir/include/mlir/Dialect/QC/IR/QCOps.td (1)

951-952: LGTM: QC dialect CtrlOp updated consistently with QCO.

The region symbol and assembly format updates match the pattern in the QCO dialect. The SingleBlockImplicitTerminator trait (line 929) ensures proper single-block semantics, and the rename to $region avoids method name collision with trait-provided methods.

mlir/lib/Dialect/QC/IR/Modifiers/CtrlOp.cpp (1)

112-112: The region accessor pattern is correct.

The code properly uses getBody()->front() (Line 112) and *getBody() (Line 176), which is the correct pattern for accessing the Block* from the SingleBlockImplicitTerminator<"::mlir::qc::YieldOp"> trait. This trait is properly declared for CtrlOp in QCOps.td and ensures that getBody() returns a Block* rather than a Region&.

All other CtrlOp code paths in the QC dialect correctly use the same accessor pattern; no migration to getRegion() is needed since the SingleBlockImplicitTerminator trait provides the correct getBody() accessor.

mlir/lib/Conversion/QCOToQC/QCOToQC.cpp (1)

780-781: LGTM! Correctly uses the trait method for region access.

The changes properly update the region accessor from getBody() to getRegion(), aligning with the TableGen parameter rename. Using the OneRegion trait method ensures consistency and avoids the method hiding issue described in the PR objectives.

@taminob taminob changed the title 🐛 Rename CtrlOp region to ctrlBodyRegion to avoid hiding trait methods 🐛 Rename CtrlOp region to region to avoid hiding trait method getBody() Jan 8, 2026
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.

Nice. Thanks again for the PR!

@burgholzer burgholzer enabled auto-merge (squash) January 8, 2026 14:55
@burgholzer burgholzer merged commit 0eaccba into main Jan 8, 2026
29 checks passed
@burgholzer burgholzer deleted the taminob/mlir-qco-rework-ctrl-op-methods branch January 8, 2026 15:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working c++ Anything related to C++ code MLIR Anything related to MLIR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants