Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
9682f41
♻️ Relax condition on modifiers
denialhaag May 26, 2026
fcdfc1a
Fix equivalence checking
denialhaag May 28, 2026
a69cc62
Fix linter errors
denialhaag May 29, 2026
3422343
Add patterns for removing empty modifiers
denialhaag May 29, 2026
c4e2882
Add test cases
denialhaag May 29, 2026
6024961
Add support for translating CompoundOperations
denialhaag Jun 1, 2026
ccec22f
Fix QC-to-QIR conversion
denialhaag Jun 1, 2026
e5eb892
Resolve TODO comments
denialhaag Jun 1, 2026
fed9ed8
Remove remaining TODO comments in preparation for the Rabbit
denialhaag Jun 1, 2026
d4c45e9
Fix linter errors
denialhaag Jun 1, 2026
925aaa5
Address the Rabbit's comments
denialhaag Jun 1, 2026
db79dac
Fix inverse cancellation
denialhaag Jun 1, 2026
e146563
Improve translation of nested control modifiers
denialhaag Jun 1, 2026
d84b58b
Improve verifiers
denialhaag Jun 2, 2026
570878f
Improve implementation of getNumBodyUnitaries()
denialhaag Jun 2, 2026
c199cc9
Improve implementation of getBodyUnitary()
denialhaag Jun 2, 2026
4c4b31c
Fix linter errors
denialhaag Jun 2, 2026
9c18fae
Merge remote-tracking branch 'origin/main' into more-control
denialhaag Jun 3, 2026
aa76e32
Merge remote-tracking branch 'origin/main' into more-control
denialhaag Jun 5, 2026
e67219c
Update documentation
denialhaag Jun 5, 2026
60f99ef
Merge remote-tracking branch 'origin/main' into more-control
denialhaag Jun 9, 2026
0082619
Update changelog
denialhaag Jun 9, 2026
eea4c2d
:recycle: Introduce a `getQubits` method for the QC UnitaryOpInterfac…
burgholzer Jun 10, 2026
8bbe722
:recycle: Use `OperandRange` for the return type of `getParameters` i…
burgholzer Jun 10, 2026
026ac04
:art: Avoid repeatedly calling `checkFinalized()` in builder
burgholzer Jun 10, 2026
95585c7
:art: Tidy up `Utils.h` helper linkage
burgholzer Jun 10, 2026
805793b
:recycle: Share body-unitary helpers across modifier canonicalizations
burgholzer Jun 10, 2026
13ee270
:recycle: Share region-inlining helper across dialect conversions
burgholzer Jun 10, 2026
822055f
:recycle: Pull out an `inlineModifierBody` helper for simplifying can…
burgholzer Jun 10, 2026
ff1e4f5
:recycle: Simplify CtrlOp and InvOp canonicalizations by relying more…
burgholzer Jun 10, 2026
55b78ae
:recycle: Further simplify CtrlOp and InvOp canonicalizations by rely…
burgholzer Jun 10, 2026
2db1271
:recycle: Simplify verifiers of modifier operations
burgholzer Jun 10, 2026
0b3d8af
:art: Small simplification in QIR conversion
burgholzer Jun 10, 2026
da147e0
:art: Simplify implementation of `getQubit` and `getControl` for QC C…
burgholzer Jun 10, 2026
15ce87b
:art: Simplify implementation of UnitaryOpInterface methods for QCO B…
burgholzer Jun 10, 2026
51c5641
:art: Use `getSoleBodyUnitary` helper in HadamardLifting pass
burgholzer Jun 10, 2026
936aa14
:art: Simplify QC program construction slightly
burgholzer Jun 10, 2026
e028c35
🔥 Remove tests that do not exercise the conversion
burgholzer Jun 10, 2026
45a5928
🚨 Address clang-tidy warnings
burgholzer Jun 10, 2026
c160d6c
🚨 Address clang-tidy warnings
burgholzer Jun 10, 2026
e7711c0
:ok_hand: Address review comment
burgholzer Jun 10, 2026
9d2217a
:ok_hand: Conservatively address second review comment
burgholzer Jun 10, 2026
bcea1f8
Address the Rabbit's out-of-diff comments
denialhaag Jun 10, 2026
db03b3c
Add defensive check
denialhaag Jun 10, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ This project adheres to [Semantic Versioning], with the exception that minor rel
- ✨ Add conversions between `jeff` and QCO ([#1479], [#1548], [#1565], [#1637], [#1676], [#1706]) ([**@denialhaag**], [**@burgholzer**])
- ✨ Add a `place-and-route` pass for mapping circuits to architectures with restricted topologies ([#1537], [#1547], [#1568], [#1581], [#1583], [#1588], [#1600], [#1664], [#1709], [#1716], [#1748]) ([**@MatthiasReumann**], [**@burgholzer**])
- ✨ Add initial infrastructure for new QC and QCO MLIR dialects
([#1264], [#1330], [#1402], [#1428], [#1430], [#1436], [#1443], [#1446], [#1464], [#1465], [#1470], [#1471], [#1472], [#1474], [#1475], [#1506], [#1510], [#1513], [#1521], [#1542], [#1548], [#1550], [#1554], [#1567], [#1569], [#1570], [#1572], [#1573], [#1580], [#1602], [#1620], [#1623], [#1624], [#1626], [#1627], [#1635], [#1638], [#1673], [#1675], [#1700], [#1717], [#1728], [#1730], [#1749], [#1762], [#1765], [#1774])
([#1264], [#1330], [#1402], [#1428], [#1430], [#1436], [#1443], [#1446], [#1464], [#1465], [#1470], [#1471], [#1472], [#1474], [#1475], [#1506], [#1510], [#1513], [#1521], [#1542], [#1548], [#1550], [#1554], [#1567], [#1569], [#1570], [#1572], [#1573], [#1580], [#1602], [#1620], [#1623], [#1624], [#1626], [#1627], [#1635], [#1638], [#1673], [#1675], [#1700], [#1717], [#1728], [#1730], [#1749], [#1751], [#1762], [#1765], [#1774])
([**@burgholzer**], [**@denialhaag**], [**@taminob**], [**@DRovara**], [**@li-mingbao**], [**@Ectras**], [**@MatthiasReumann**], [**@simon1hofmann**])

### Changed
Expand Down Expand Up @@ -405,6 +405,7 @@ _📚 Refer to the [GitHub Release Notes](https://github.com/munich-quantum-tool
[#1774]: https://github.com/munich-quantum-toolkit/core/pull/1774
[#1765]: https://github.com/munich-quantum-toolkit/core/pull/1765
[#1762]: https://github.com/munich-quantum-toolkit/core/pull/1762
[#1751]: https://github.com/munich-quantum-toolkit/core/pull/1751
[#1749]: https://github.com/munich-quantum-toolkit/core/pull/1749
[#1748]: https://github.com/munich-quantum-toolkit/core/pull/1748
[#1737]: https://github.com/munich-quantum-toolkit/core/pull/1737
Expand Down
49 changes: 49 additions & 0 deletions mlir/include/mlir/Conversion/ConversionUtils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright (c) 2023 - 2026 Chair for Design Automation, TUM
* Copyright (c) 2025 - 2026 Munich Quantum Software Company GmbH
* All rights reserved.
*
* SPDX-License-Identifier: MIT
*
* Licensed under the MIT License
*/

#pragma once

#include <mlir/IR/Region.h>
#include <mlir/Support/LLVM.h>
#include <mlir/Support/LogicalResult.h>
#include <mlir/Transforms/DialectConversion.h>

namespace mlir {

/**
* @brief Inlines @p source into @p dest and converts the entry block signature.
*
* @details Moves all blocks of @p source to the end of @p dest and converts the
* argument types of the resulting entry block using @p typeConverter. This is
* the canonical way to migrate a region from one dialect to another during a
* dialect conversion when the block arguments change type.
*
* @param source The region whose blocks are moved out.
* @param dest The region the blocks are moved into.
* @param rewriter The conversion rewriter driving the current pass.
* @param typeConverter The type converter used to convert the entry block
* signature.
* @return Whether converting the entry block signature succeeded.
*/
inline LogicalResult moveRegion(Region& source, Region& dest,
ConversionPatternRewriter& rewriter,
const TypeConverter* typeConverter) {
rewriter.inlineRegionBefore(source, dest, dest.end());
auto* block = &dest.front();
TypeConverter::SignatureConversion sc(block->getNumArguments());
if (failed(
typeConverter->convertSignatureArgs(block->getArgumentTypes(), sc))) {
return failure();
}
rewriter.applySignatureConversion(block, sc);
return success();
}

} // namespace mlir
74 changes: 40 additions & 34 deletions mlir/include/mlir/Dialect/QC/Builder/QCProgramBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -406,8 +406,8 @@ class QCProgramBuilder final : public ImplicitLocOpBuilder {
* builder.c##OP_NAME(q0, q1); \
* ``` \
* ```mlir \
* qc.ctrl(%q0) { \
* qc.OP_NAME %q1 : !qc.qubit \
* qc.ctrl(%q0) targets(%a0 = %q1) { \
* qc.OP_NAME %a0 : !qc.qubit \
* } : !qc.qubit \
* ``` \
*/ \
Expand All @@ -424,8 +424,8 @@ class QCProgramBuilder final : public ImplicitLocOpBuilder {
* builder.mc##OP_NAME({q0, q1}, q2); \
* ``` \
* ```mlir \
* qc.ctrl(%q0, %q1) { \
* qc.OP_NAME %q2 : !qc.qubit \
* qc.ctrl(%q0, %q1) targets(%a0 = %q2) { \
* qc.OP_NAME %a0 : !qc.qubit \
* } : !qc.qubit, !qc.qubit \
* ``` \
*/ \
Expand Down Expand Up @@ -478,8 +478,8 @@ class QCProgramBuilder final : public ImplicitLocOpBuilder {
* builder.c##OP_NAME(PARAM, q0, q1); \
* ``` \
* ```mlir \
* qc.ctrl(%q0) { \
* qc.OP_NAME(%PARAM) %q1 : !qc.qubit \
* qc.ctrl(%q0) targets(%a0 = %q1) { \
* qc.OP_NAME(%PARAM) %a0 : !qc.qubit \
* } : !qc.qubit \
* ``` \
*/ \
Expand All @@ -498,8 +498,8 @@ class QCProgramBuilder final : public ImplicitLocOpBuilder {
* builder.mc##OP_NAME(PARAM, {q0, q1}, q2); \
* ``` \
* ```mlir \
* qc.ctrl(%q0, %q1) { \
* qc.OP_NAME(%PARAM) %q2 : !qc.qubit \
* qc.ctrl(%q0, %q1) targets(%a0 = %q2) { \
* qc.OP_NAME(%PARAM) %a0 : !qc.qubit \
* } : !qc.qubit, !qc.qubit \
* ``` \
*/ \
Expand Down Expand Up @@ -549,8 +549,8 @@ class QCProgramBuilder final : public ImplicitLocOpBuilder {
* builder.c##OP_NAME(PARAM1, PARAM2, q0, q1); \
* ``` \
* ```mlir \
* qc.ctrl(%q0) { \
* qc.OP_NAME(%PARAM1, %PARAM2) %q1 : !qc.qubit \
* qc.ctrl(%q0) (%a0 = %q1) { \
* qc.OP_NAME(%PARAM1, %PARAM2) %a0 : !qc.qubit \
* } : !qc.qubit \
* ``` \
*/ \
Expand All @@ -571,8 +571,8 @@ class QCProgramBuilder final : public ImplicitLocOpBuilder {
* builder.mc##OP_NAME(PARAM1, PARAM2, {q0, q1}, q2); \
* ``` \
* ```mlir \
* qc.ctrl(%q0, %q1) { \
* qc.OP_NAME(%PARAM1, %PARAM2) %q2 : !qc.qubit \
* qc.ctrl(%q0, %q1) targets(%a0 = %q2) { \
* qc.OP_NAME(%PARAM1, %PARAM2) %a0 : !qc.qubit \
* } : !qc.qubit, !qc.qubit \
* ``` \
*/ \
Expand Down Expand Up @@ -625,8 +625,8 @@ class QCProgramBuilder final : public ImplicitLocOpBuilder {
* builder.c##OP_NAME(PARAM1, PARAM2, PARAM3, q0, q1); \
* ``` \
* ```mlir \
* qc.ctrl(%q0) { \
* qc.OP_NAME(%PARAM1, %PARAM2, %PARAM3) %q1 : !qc.qubit \
* qc.ctrl(%q0) targets(%a0 = %q1) { \
* qc.OP_NAME(%PARAM1, %PARAM2, %PARAM3) %a0 : !qc.qubit \
* } : !qc.qubit \
* ``` \
*/ \
Expand All @@ -649,8 +649,8 @@ class QCProgramBuilder final : public ImplicitLocOpBuilder {
* builder.mc##OP_NAME(PARAM1, PARAM2, PARAM3, {q0, q1}, q2); \
* ``` \
* ```mlir \
* qc.ctrl(%q0, %q1) { \
* qc.OP_NAME(%PARAM1, %PARAM2, %PARAM3) %q2 : !qc.qubit \
* qc.ctrl(%q0, %q1) targets(%a0 = %q2) { \
* qc.OP_NAME(%PARAM1, %PARAM2, %PARAM3) %a0 : !qc.qubit \
* } : !qc.qubit, !qc.qubit \
* ``` \
*/ \
Expand Down Expand Up @@ -695,8 +695,8 @@ class QCProgramBuilder final : public ImplicitLocOpBuilder {
* builder.c##OP_NAME(q0, q1, q2); \
* ``` \
* ```mlir \
* qc.ctrl(%q0) { \
* qc.OP_NAME %q1, %q2 : !qc.qubit, !qc.qubit \
* qc.ctrl(%q0) targets(%a0 = %q1, %a1 = %q2) { \
* qc.OP_NAME %a0, %a1 : !qc.qubit, !qc.qubit \
* } : !qc.qubit \
* ``` \
*/ \
Expand All @@ -714,8 +714,8 @@ class QCProgramBuilder final : public ImplicitLocOpBuilder {
* builder.mc##OP_NAME({q0, q1}, q2, q3); \
* ``` \
* ```mlir \
* qc.ctrl(%q0, %q1) { \
* qc.OP_NAME %q2, %q3 : !qc.qubit, !qc.qubit \
* qc.ctrl(%q0, %q1) targets(%a0 = %q2, %a1 = %q3) { \
* qc.OP_NAME %a0, %a1 : !qc.qubit, !qc.qubit \
* } : !qc.qubit, !qc.qubit \
* ``` \
*/ \
Expand Down Expand Up @@ -764,8 +764,8 @@ class QCProgramBuilder final : public ImplicitLocOpBuilder {
* builder.c##OP_NAME(PARAM, q0, q1, q2); \
* ``` \
* ```mlir \
* qc.ctrl(%q0) { \
* qc.OP_NAME(%PARAM) %q1, %q2 : !qc.qubit, !qc.qubit \
* qc.ctrl(%q0) targets(%a0 = %q1, %a1 = %q2) { \
* qc.OP_NAME(%PARAM) %a0, %a1 : !qc.qubit, !qc.qubit \
* } : !qc.qubit \
* ``` \
*/ \
Expand All @@ -785,8 +785,8 @@ class QCProgramBuilder final : public ImplicitLocOpBuilder {
* builder.mc##OP_NAME(PARAM, {q0, q1}, q2, q3); \
* ``` \
* ```mlir \
* qc.ctrl(%q0, %q1) { \
* qc.OP_NAME(%PARAM) %q2, %q3 : !qc.qubit, !qc.qubit \
* qc.ctrl(%q0, %q1) targets(%a0 = %q2, %a1 = %q3) { \
* qc.OP_NAME(%PARAM) %a0, %a1 : !qc.qubit, !qc.qubit \
* } : !qc.qubit, !qc.qubit \
* ``` \
*/ \
Expand Down Expand Up @@ -839,8 +839,8 @@ class QCProgramBuilder final : public ImplicitLocOpBuilder {
* builder.c##OP_NAME(PARAM1, PARAM2, q0, q1, q2); \
* ``` \
* ```mlir \
* qc.ctrl(%q0) { \
* qc.OP_NAME(%PARAM1, %PARAM2) %q1, %q2 : !qc.qubit, \
* qc.ctrl(%q0) targets(%a0 = %q1, %a1 = %q2) { \
* qc.OP_NAME(%PARAM1, %PARAM2) %a0, %a1 : !qc.qubit, \
* !qc.qubit \
* } : !qc.qubit \
* ``` \
Expand All @@ -863,8 +863,8 @@ class QCProgramBuilder final : public ImplicitLocOpBuilder {
* builder.mc##OP_NAME(PARAM1, PARAM2, {q0, q1}, q2, q3); \
* ``` \
* ```mlir \
* qc.ctrl(%q0, %q1) { \
* qc.OP_NAME(%PARAM1, %PARAM2) %q2, %q3 : !qc.qubit, !qc.qubit \
* qc.ctrl(%q0, %q1) targets(%a0 = %q2, %a1 = %q3) { \
* qc.OP_NAME(%PARAM1, %PARAM2) %a0, %a1 : !qc.qubit, !qc.qubit \
* } : !qc.qubit, !qc.qubit \
* ``` \
*/ \
Expand Down Expand Up @@ -909,15 +909,18 @@ class QCProgramBuilder final : public ImplicitLocOpBuilder {
*
* @par Example:
* ```c++
* builder.ctrl(q0, [&] { builder.x(q1); });
* builder.ctrl(q0, q1, [&](ValueRange targets) {
* builder.x(targets[0]);
* });
* ```
* ```mlir
* qc.ctrl(%q0) {
* qc.x %q1 : !qc.qubit
* qc.ctrl(%q0) targets(%a0 = %q1) {
* qc.x %a0 : !qc.qubit
* } : !qc.qubit
* ```
*/
QCProgramBuilder& ctrl(ValueRange controls, const function_ref<void()>& body);
QCProgramBuilder& ctrl(ValueRange controls, ValueRange targets,
const function_ref<void(ValueRange)>& body);

/**
* @brief Apply an inverse (i.e., adjoint) operation.
Expand All @@ -928,15 +931,18 @@ class QCProgramBuilder final : public ImplicitLocOpBuilder {
*
* @par Example:
* ```c++
* builder.inv([&] { builder.s(q0); });
* builder.inv(q0, [&](ValueRange qubits) {
* builder.h(qubits[0]);
* });
* ```
* ```mlir
* qc.inv {
* qc.s %q0 : !qc.qubit
* }
* ```
*/
QCProgramBuilder& inv(const function_ref<void()>& body);
QCProgramBuilder& inv(ValueRange qubits,
const function_ref<void(ValueRange)>& body);

//===--------------------------------------------------------------------===//
// Deallocation
Expand Down
7 changes: 4 additions & 3 deletions mlir/include/mlir/Dialect/QC/IR/QCDialect.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ template <size_t T, size_t P> class TargetAndParameterArityTrait {
static size_t getNumQubits() { return T; }
static size_t getNumTargets() { return T; }
static size_t getNumControls() { return 0; }
static ValueRange getControls() { return {}; }
static OperandRange getControls() { return {nullptr, 0}; }

Value getQubit(size_t i) {
if constexpr (T == 0) {
Expand All @@ -71,7 +71,8 @@ template <size_t T, size_t P> class TargetAndParameterArityTrait {
}
return this->getOperation()->getOperand(i);
}
ValueRange getTargets() {
OperandRange getQubits() { return getTargets(); }
OperandRange getTargets() {
return this->getOperation()->getOperands().slice(0, T);
}

Expand All @@ -88,7 +89,7 @@ template <size_t T, size_t P> class TargetAndParameterArityTrait {
return this->getOperation()->getOperand(T + i);
}

ValueRange getParameters() {
OperandRange getParameters() {
return this->getOperation()->getOperands().slice(T, P);
}
};
Expand Down
9 changes: 6 additions & 3 deletions mlir/include/mlir/Dialect/QC/IR/QCInterfaces.td
Original file line number Diff line number Diff line change
Expand Up @@ -44,17 +44,20 @@ def UnitaryOpInterface : OpInterface<"UnitaryOpInterface"> {
(ins "size_t":$i)>,
InterfaceMethod<"Returns the i-th control qubit.", "Value", "getControl",
(ins "size_t":$i)>,
InterfaceMethod<"Returns a range of all target qubits.", "ValueRange",
InterfaceMethod<
"Returns a range of all qubits (targets + controls combined).",
"OperandRange", "getQubits", (ins)>,
InterfaceMethod<"Returns a range of all target qubits.", "OperandRange",
"getTargets", (ins)>,
InterfaceMethod<"Returns a range of all control qubits.", "ValueRange",
InterfaceMethod<"Returns a range of all control qubits.", "OperandRange",
"getControls", (ins)>,

// Parameter handling
InterfaceMethod<"Returns the number of parameters.", "size_t",
"getNumParams", (ins)>,
InterfaceMethod<"Returns the i-th parameter.", "Value", "getParameter",
(ins "size_t":$i)>,
InterfaceMethod<"Returns a range of all parameters.", "ValueRange",
InterfaceMethod<"Returns a range of all parameters.", "OperandRange",
"getParameters", (ins)>,

// Convenience methods
Expand Down
Loading
Loading