Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
530f3b8
:poop: Generated first draft of Constant Propagation, assisted by GPT…
LiRem101 Aug 24, 2026
c3398b6
:construction: Improved generated code
LiRem101 Aug 24, 2026
339feb6
:construction: Improved QuantumState
LiRem101 Aug 25, 2026
38ea72f
:construction: Improved Generated Code
LiRem101 Aug 25, 2026
4d1dc93
:construction: Improved Generated Code
LiRem101 Aug 25, 2026
c949b49
:construction: Added merge of two HybridStates
LiRem101 Aug 25, 2026
53f98c6
:construction: Propagate classical operations
LiRem101 Aug 26, 2026
e353b7e
:construction: Propagate unitary operations
LiRem101 Aug 26, 2026
e254321
:boom: Removed some code for now
LiRem101 Aug 26, 2026
2f42fea
:construction: Added Constant Propagation Base pass
LiRem101 Aug 26, 2026
b87ed74
:construction: Adapted structure for new approach, assisted-by Sonnet…
LiRem101 Aug 28, 2026
21c9bd4
:construction: Created QuantumState, assisted-by Sonnet 5 via Claude …
LiRem101 Aug 28, 2026
3ea51c8
:construction: QuantumState only applies relative phases, assisted-by…
LiRem101 Aug 28, 2026
64454eb
:construction: QuantumState fails if controls are not in state, assis…
LiRem101 Aug 28, 2026
3d8ea29
:construction: QuantumState renames input, assisted-by Sonnet 5 via C…
LiRem101 Aug 28, 2026
04e9600
:construction: Added HybridState, assisted-by Sonnet 5 via Claude Code
LiRem101 Aug 28, 2026
2f42ce1
:construction: Added functions for HybridState, assisted-by Sonnet 5 …
LiRem101 Aug 29, 2026
7302626
:construction: Added UnionTable.hpp, assisted-by Sonnet 5 via Claude …
LiRem101 Aug 29, 2026
947dc5f
:construction: Added UnionTable, assisted-by Sonnet 5 via Claude Code
LiRem101 Aug 29, 2026
2ac8801
:construction: Added handling of values instead of classical constant…
LiRem101 Aug 29, 2026
6f58de7
:construction: Added handling of values instead of classical constant…
LiRem101 Aug 29, 2026
09e695b
:construction: Added ConstantPropagationAnalysis, assisted-by Sonnet …
LiRem101 Aug 29, 2026
8919e4e
:construction: Added ConstantPropagationPass, assisted-by Sonnet 5 vi…
LiRem101 Aug 29, 2026
a489f17
:construction: Added removal of all ctrl qubits, assisted-by Sonnet 5…
LiRem101 Aug 29, 2026
beaf11b
:white_check_mark: Added tests for constant propagation, assisted-by …
LiRem101 Aug 30, 2026
07294f3
:twisted_rightwards_arrows: Merged with main
LiRem101 Aug 30, 2026
958af96
:construction: Added registering of constant propagation
LiRem101 Aug 30, 2026
fa9bd22
:memo: Corrected docstring
LiRem101 Aug 30, 2026
7ecb300
🎨 pre-commit fixes
pre-commit-ci[bot] Aug 30, 2026
7f60545
:memo: Updated CHANGELOG.md
LiRem101 Aug 30, 2026
91f032d
:twisted_rightwards_arrows: Merge branch 'mlir/constant-propagation-v…
LiRem101 Aug 30, 2026
368ade5
🎨 pre-commit fixes
pre-commit-ci[bot] Aug 30, 2026
851c9fb
:rotating_light: Made mlir values non-const, assisted-by Sonnet 5 via…
LiRem101 Aug 30, 2026
6df5ef9
:rotating_light: Solved linter issues, assisted-by Sonnet 5 via Claud…
LiRem101 Aug 30, 2026
6259330
:twisted_rightwards_arrows: Merge branch 'mlir/constant-propagation-v…
LiRem101 Aug 30, 2026
ec1b97e
:rotating_light: Made implicit cast explicit
LiRem101 Aug 30, 2026
ed8a25b
:rotating_light: Made implicit cast explicit
LiRem101 Aug 30, 2026
4604bc2
:white_check_mark: Added tests, assisted by Sonnet 5 via Claude Code
LiRem101 Aug 30, 2026
e74d760
🎨 pre-commit fixes
pre-commit-ci[bot] Aug 30, 2026
1a64251
:rotating_light: Removed const modifier of mlir value
LiRem101 Aug 30, 2026
5a55a1b
:twisted_rightwards_arrows: Merge branch 'mlir/constant-propagation-v…
LiRem101 Aug 30, 2026
d838bb9
:memo: Updated CHANGELOG.md
LiRem101 Aug 30, 2026
26ac211
:pencil2: Fixed typos
LiRem101 Aug 30, 2026
c4654a5
:construction: Handling unknown op's by putting to top, assisted by S…
LiRem101 Aug 30, 2026
f4fda70
:construction: Fixed coderabbit comments on HybridState, assisted by …
LiRem101 Aug 30, 2026
d44c29b
:memo: Fixed comments
LiRem101 Aug 30, 2026
9153099
:memo: Fixed comments
LiRem101 Aug 30, 2026
f394eca
:white_check_mark: Assert cast before checking value
LiRem101 Aug 30, 2026
5ca396c
:white_check_mark: Add ctrl output qubit
LiRem101 Aug 30, 2026
0584479
:white_check_mark: Removed const from value parameters, assisted by S…
LiRem101 Aug 30, 2026
b404cc5
:white_check_mark: Made tests more specific, assisted by Sonnet 5 via…
LiRem101 Aug 30, 2026
d7cd003
:white_check_mark: Re-structured test code
LiRem101 Aug 30, 2026
f62289f
:construction: Fixed formatting issues
LiRem101 Aug 30, 2026
1e7e0c2
:construction: Fixed handling of no out ctrl and added tests, assiste…
LiRem101 Aug 30, 2026
93b2702
🎨 pre-commit fixes
pre-commit-ci[bot] Aug 30, 2026
5853369
:construction: QuantumState rejects uncontrolled global Phase
LiRem101 Aug 30, 2026
d65e292
:construction: Check if all ctrls are present in state, assisted by S…
LiRem101 Aug 30, 2026
add0e90
:construction: Skip controls nested anywhere below a modifier
LiRem101 Aug 30, 2026
77cf074
:twisted_rightwards_arrows: Merge branch 'mlir/constant-propagation-v…
LiRem101 Aug 30, 2026
5faed8a
:white_check_mark: Fixed test title
LiRem101 Aug 30, 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
464 changes: 460 additions & 4 deletions CHANGELOG.md

Large diffs are not rendered by default.

36 changes: 36 additions & 0 deletions mlir/include/mlir/Dialect/QCO/Transforms/Passes.td
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,42 @@ def MappingPass : Pass<"place-and-route", "mlir::ModuleOp"> {
// Optimization Passes
//===----------------------------------------------------------------------===//

def ConstantPropagation : Pass<"constant-propagation", "mlir::ModuleOp"> {
let dependentDialects = ["mlir::qco::QCODialect",
"::mlir::arith::ArithDialect"];
let summary = "This pass applies constant propagation to a circuit. It "
"assumes that all input qubits are |0>. It propagates the "
"state of the qubits up to a given complexity threshold and "
"removes gates which are superfluous considering the current "
"state.";
let description = [{
This pass applies quantum constant propagation. This optimization routine assumes that the input qubits of the
circuits are |0>. It propagates the qubit states and the state of additional classical values through the circuit.
All quantum instructions are removed which are superfluous considering the current state.

The qubit states and classical values are stored in hybrid states. Hybrid states are stored in a union table to
reduce the amount of complex amplitudes and classical values to track. There is a maximum number of non zero
amplitudes that is saved per union table entry. Additionally, there is also a maximum of hybrid states that can be
propagated. If the maximum number of amplitudes or the maximum number of hybrid states is exceeded, the propagated
state reaches top and no optimization routines are further applied.

The applied optimization routines are:

**General Control Reduction**
If a controlling qubit is always one, the control is removed.
If a controlling qubit is always zero, the complete gate is removed.

}];
let options = [Option<"maximumNonzeroAmplitudes",
"maximum-nonzero-amplitudes", "std::size_t", "4",
"The maximum number of non-zero amplitudes in the "
"tracked quantum states before reaching top.">,
Option<"maximumHybridStates", "maximum-hybrid-states",
"std::size_t", "4",
"The maximum number of hybrid states which have a "
"non-zero probability.">];
}

def PauliTwirl2QGates : Pass<"pauli-twirl-2q-gates", "mlir::ModuleOp"> {
let dependentDialects = ["mlir::qco::QCODialect",
"::mlir::arith::ArithDialect"];
Expand Down
5 changes: 5 additions & 0 deletions mlir/lib/Dialect/QCO/Transforms/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,15 @@ add_mlir_library(
PUBLIC
MQTCompilerTarget
PRIVATE
MLIRAnalysis
MLIRControlFlowInterfaces
MLIRFunctionInterfaces
MLIRQCODialect
MLIRQCOUtils
MLIRQTensorDialect
MLIRQTensorUtils
MLIRArithDialect
MLIRFuncDialect
MLIRMathDialect
MLIRMQTDialect
MLIRMQTTransforms
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*
* 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
*/

#include "ConstantPropagation/ConstantPropagationAnalysis.hpp"
#include "ConstantPropagation/Decisions.hpp"
#include "ConstantPropagation/Rewriter.hpp"
#include "mlir/Dialect/MQT/IR/MQTDialect.h"
#include "mlir/Dialect/QCO/Transforms/Passes.h"

#include <llvm/ADT/SmallVector.h>
#include <mlir/Analysis/DataFlow/ConstantPropagationAnalysis.h>
#include <mlir/Analysis/DataFlow/DeadCodeAnalysis.h>
#include <mlir/Analysis/DataFlowFramework.h>
#include <mlir/Dialect/Arith/IR/Arith.h>
#include <mlir/Dialect/Func/IR/FuncOps.h>
#include <mlir/IR/BuiltinOps.h>
#include <mlir/IR/PatternMatch.h>

namespace mlir::qco {

#define GEN_PASS_DEF_CONSTANTPROPAGATION
#include "mlir/Dialect/QCO/Transforms/Passes.h.inc"

namespace {

/**
* @brief Quantum constant propagation.
*
* Assumes every input qubit of the entry-point function starts in |0>,
* propagates the quantum/classical state through the circuit up to a complexity
* threshold (an MLIR `DenseForwardDataFlowAnalysis` over a `UnionTable`
* lattice), then removes operations that are superfluous given that state.
*
* Rewrites: delete a `qco.ctrl` whose controls can never all hold, and remove
* the always-satisfied controls from a `qco.ctrl` - rebuilding it with the
* rest, or inlining its body when every control was redundant. Analyze and
* rewrite alternate until a fixpoint because a removed gate can change a later
* gate's control facts. Classical controls are not reasoned about yet.
*/
struct ConstantPropagation final
: impl::ConstantPropagationBase<ConstantPropagation> {
using ConstantPropagationBase::ConstantPropagationBase;

protected:
void runOnOperation() override {
ModuleOp module = getOperation();

func::FuncOp entry;
for (auto func : module.getOps<func::FuncOp>()) {
if (!mqt::isEntryPoint(func)) {
continue;
}
if (entry) {
module.emitError(
"constant propagation supports a single entry-point function");
return signalPassFailure();
}
entry = func;
}
if (!entry) {
return;
}

IRRewriter rewriter(&getContext());
constexpr unsigned maxRounds = 64;
for (unsigned round = 0; round < maxRounds; ++round) {
DataFlowSolver solver;
solver.load<dataflow::DeadCodeAnalysis>();
solver.load<dataflow::SparseConstantPropagation>();
solver.load<ConstantPropagationAnalysis>(maximumNonzeroAmplitudes,
maximumHybridStates);
if (failed(solver.initializeAndRun(module))) {
return signalPassFailure(); // the analysis emitted the diagnostic
}

const SmallVector<Decision> decisions = collectDecisions(entry, solver);
if (decisions.empty()) {
return; // fixpoint reached
}
applyDecisions(decisions, rewriter);
}

entry.emitError("constant propagation did not converge within ")
<< maxRounds << " rounds";
signalPassFailure();
}
};

} // namespace

} // namespace mlir::qco
Loading
Loading