|
37 | 37 | #include <mlir/IR/Value.h> |
38 | 38 | #include <mlir/Support/LLVM.h> |
39 | 39 |
|
40 | | -#include <algorithm> |
41 | 40 | #include <cassert> |
42 | 41 | #include <cstddef> |
43 | 42 | #include <cstdint> |
@@ -185,7 +184,6 @@ namespace { |
185 | 184 | /// Static gate dispatch table, built once at startup. |
186 | 185 | const llvm::StringMap<GateFn> GATE_DISPATCH = buildGateDispatch(); |
187 | 186 |
|
188 | | -/// Local qubit scope used during compound gate body expansion. |
189 | 187 | /// Maps argument name → vector of MLIR qubit Values. |
190 | 188 | using QubitScope = llvm::StringMap<SmallVector<Value>>; |
191 | 189 |
|
@@ -235,7 +233,7 @@ class MLIRQasmImporter final : public qasm3::InstVisitor { |
235 | 233 | /// Updated each time a measure is emitted. Used for if/else conditions. |
236 | 234 | llvm::StringMap<SmallVector<Value>> bitValues; |
237 | 235 |
|
238 | | - /// Gate library: standard gates + user-defined compound gates |
| 236 | + /// Gate library |
239 | 237 | std::map<std::string, std::shared_ptr<qasm3::Gate>> gates; |
240 | 238 |
|
241 | 239 | bool openQASM2CompatMode{false}; |
@@ -384,28 +382,6 @@ class MLIRQasmImporter final : public qasm3::InstVisitor { |
384 | 382 | throw qasm3::CompilerError("Gate '" + id + "' already declared.", |
385 | 383 | stmt->debugInfo); |
386 | 384 | } |
387 | | - std::vector<std::string> paramNames; |
388 | | - for (const auto& p : stmt->parameters->identifiers) { |
389 | | - if (std::ranges::find(paramNames, p->identifier) != paramNames.end()) { |
390 | | - throw qasm3::CompilerError("Parameter '" + p->identifier + |
391 | | - "' already declared in gate '" + id + |
392 | | - "'.", |
393 | | - stmt->debugInfo); |
394 | | - } |
395 | | - paramNames.push_back(p->identifier); |
396 | | - } |
397 | | - std::vector<std::string> qubitNames; |
398 | | - for (const auto& q : stmt->qubits->identifiers) { |
399 | | - if (std::ranges::find(qubitNames, q->identifier) != qubitNames.end()) { |
400 | | - throw qasm3::CompilerError("Qubit '" + q->identifier + |
401 | | - "' already declared in gate '" + id + |
402 | | - "'.", |
403 | | - stmt->debugInfo); |
404 | | - } |
405 | | - qubitNames.push_back(q->identifier); |
406 | | - } |
407 | | - gates[id] = std::make_shared<qasm3::CompoundGate>( |
408 | | - std::move(paramNames), std::move(qubitNames), stmt->statements); |
409 | 385 | } |
410 | 386 |
|
411 | 387 | void visitGateCallStatement( |
@@ -511,8 +487,6 @@ class MLIRQasmImporter final : public qasm3::InstVisitor { |
511 | 487 | //===--- Core gate application ----------------------------------------===// |
512 | 488 |
|
513 | 489 | /// Apply a gate call statement, resolving qubits from \p scope. |
514 | | - /// For top-level calls pass \p qubitRegisters; for compound gate bodies |
515 | | - /// pass the local argument scope. |
516 | 490 | void |
517 | 491 | applyGateCallStatement(const std::shared_ptr<qasm3::GateCallStatement>& stmt, |
518 | 492 | const QubitScope& scope) { |
@@ -617,12 +591,12 @@ class MLIRQasmImporter final : public qasm3::InstVisitor { |
617 | 591 | expandedOperands.begin() + static_cast<std::ptrdiff_t>(totalCtrlCount), |
618 | 592 | expandedOperands.end()); |
619 | 593 |
|
620 | | - // Compound gate: inline expand |
| 594 | + // Compound gate |
621 | 595 | if (const auto* compound = |
622 | 596 | dynamic_cast<qasm3::CompoundGate*>(it->second.get())) { |
623 | | - applyCompoundGate(*compound, gateOperands, posControls, negControls, |
624 | | - params, invert, stmt->debugInfo); |
625 | | - return; |
| 597 | + throw qasm3::CompilerError( |
| 598 | + "Compound gates cannot be translated to QC at the moment.", |
| 599 | + stmt->debugInfo); |
626 | 600 | } |
627 | 601 |
|
628 | 602 | // Standard gate: validate param count then determine broadcast width |
@@ -711,87 +685,6 @@ class MLIRQasmImporter final : public qasm3::InstVisitor { |
711 | 685 | } |
712 | 686 | } |
713 | 687 |
|
714 | | - /// Inline-expand a compound (user-defined) gate. |
715 | | - void applyCompoundGate(const qasm3::CompoundGate& gate, |
716 | | - const std::vector<SmallVector<Value>>& gateOperands, |
717 | | - ArrayRef<Value> posControls, |
718 | | - ArrayRef<Value> negControls, ArrayRef<double> params, |
719 | | - bool invert, |
720 | | - const std::shared_ptr<qasm3::DebugInfo>& debugInfo) { |
721 | | - if (gate.targetNames.size() != gateOperands.size()) { |
722 | | - throw qasm3::CompilerError("Compound gate operand count mismatch.", |
723 | | - debugInfo); |
724 | | - } |
725 | | - if (gate.parameterNames.size() != params.size()) { |
726 | | - throw qasm3::CompilerError("Compound gate parameter count mismatch.", |
727 | | - debugInfo); |
728 | | - } |
729 | | - |
730 | | - // Build local scope: argument name → Values |
731 | | - QubitScope localScope; |
732 | | - for (size_t i = 0; i < gate.targetNames.size(); ++i) { |
733 | | - localScope[gate.targetNames[i]] = |
734 | | - SmallVector<Value>(gateOperands[i].begin(), gateOperands[i].end()); |
735 | | - } |
736 | | - |
737 | | - // Bind parameters as constants |
738 | | - constEvalPass.pushEnv(); |
739 | | - for (size_t i = 0; i < gate.parameterNames.size(); ++i) { |
740 | | - constEvalPass.addConst(gate.parameterNames[i], |
741 | | - qasm3::const_eval::ConstEvalValue(params[i])); |
742 | | - } |
743 | | - |
744 | | - auto bodyFn = [&] { |
745 | | - for (const auto& bodyStmt : gate.body) { |
746 | | - if (const auto gateCall = |
747 | | - std::dynamic_pointer_cast<qasm3::GateCallStatement>(bodyStmt)) { |
748 | | - applyGateCallStatement(gateCall, localScope); |
749 | | - } else if (const auto barrier = |
750 | | - std::dynamic_pointer_cast<qasm3::BarrierStatement>( |
751 | | - bodyStmt)) { |
752 | | - SmallVector<Value> qubits; |
753 | | - for (const auto& g : barrier->gates) { |
754 | | - auto resolved = |
755 | | - resolveGateOperandInScope(g, localScope, barrier->debugInfo); |
756 | | - qubits.append(resolved.begin(), resolved.end()); |
757 | | - } |
758 | | - builder.barrier(qubits); |
759 | | - } else if (const auto reset = |
760 | | - std::dynamic_pointer_cast<qasm3::ResetStatement>( |
761 | | - bodyStmt)) { |
762 | | - for (auto q : resolveGateOperandInScope(reset->gate, localScope, |
763 | | - reset->debugInfo)) { |
764 | | - builder.reset(q); |
765 | | - } |
766 | | - } |
767 | | - } |
768 | | - }; |
769 | | - |
770 | | - auto withInv = [&] { |
771 | | - if (invert) { |
772 | | - builder.inv(function_ref<void()>(bodyFn)); |
773 | | - } else { |
774 | | - bodyFn(); |
775 | | - } |
776 | | - }; |
777 | | - |
778 | | - if (posControls.empty() && negControls.empty()) { |
779 | | - withInv(); |
780 | | - } else { |
781 | | - for (auto q : negControls) { |
782 | | - builder.x(q); |
783 | | - } |
784 | | - SmallVector<Value> allControls(posControls.begin(), posControls.end()); |
785 | | - allControls.append(negControls.begin(), negControls.end()); |
786 | | - builder.ctrl(allControls, function_ref<void()>(withInv)); |
787 | | - for (auto q : negControls) { |
788 | | - builder.x(q); |
789 | | - } |
790 | | - } |
791 | | - |
792 | | - constEvalPass.popEnv(); |
793 | | - } |
794 | | - |
795 | 688 | //===--- If/else helpers ------------------------------------------------===// |
796 | 689 |
|
797 | 690 | /// Emit quantum statements inside an if/else block. |
@@ -905,9 +798,9 @@ class MLIRQasmImporter final : public qasm3::InstVisitor { |
905 | 798 | return resolveGateOperandInScope(operand, qubitRegisters, debugInfo); |
906 | 799 | } |
907 | 800 |
|
908 | | - /** Resolve a gate operand against \p scope (top-level registers or a |
909 | | - * compound-gate local argument scope). Returns the MLIR Values for the |
910 | | - * qubit(s) named by \p operand — a full register or a single indexed qubit. |
| 801 | + /** |
| 802 | + * Resolve a gate operand against \p scope. Returns the qubit Values named by |
| 803 | + * \p operand. |
911 | 804 | */ |
912 | 805 | SmallVector<Value> resolveGateOperandInScope( |
913 | 806 | const std::shared_ptr<qasm3::GateOperand>& operand, |
|
0 commit comments