Skip to content

📝 Getting Started With MLIR#1555

Open
MatthiasReumann wants to merge 26 commits intomainfrom
docs/getting_started_mlir
Open

📝 Getting Started With MLIR#1555
MatthiasReumann wants to merge 26 commits intomainfrom
docs/getting_started_mlir

Conversation

@MatthiasReumann
Copy link
Collaborator

@MatthiasReumann MatthiasReumann commented Mar 12, 2026

Description

This pull request adds a "Getting Started with MLIR" tutorial to the ReadTheDocs documentation. Thus, resolves #1452.

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.

@MatthiasReumann
Copy link
Collaborator Author

@burgholzer @denialhaag @DRovara
Hello everyone 👋🏻

I am pretty sure everyone of you has an opinion on how this getting started guide should look - and should not look. Hence, I kindly asked for a review from each one of you. I hope this is okay!

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 12, 2026

📝 Walkthrough

Summary by CodeRabbit

  • Documentation
    • Added a comprehensive "Getting Started" guide for the MQT Compiler Collection, including build verification and running the mqt-cc tool.
    • Introduces quantum computing basics (qubits, gates, measurement, Bell states) with practical examples.
    • Provides an MLIR primer (dialects, SSA, types, ops, regions, control-flow, passes) and explains MLIR quantum dialects, the compilation flow, optimization examples, and QIR emission.

Walkthrough

Adds a new MLIR "Getting Started" guide at docs/mlir/GettingStarted.md and registers it in docs/mlir/index.md. The guide documents build/verification steps, MLIR fundamentals, QC vs QCO semantics with examples and diagrams, and end-to-end compilation/optimization workflows. (41 words)

Changes

Cohort / File(s) Summary
New MLIR Documentation
docs/mlir/GettingStarted.md
Adds a comprehensive tutorial covering setup/build verification (CMake, MLIR/LLVM paths, BUILD_MQT_CORE_MLIR), MLIR fundamentals (dialects, SSA, types, ops, blocks, regions), QC vs QCO semantics with example MLIR snippets/diagrams, compilation architecture, and runnable tool examples (mqt-cc, --emit-qir, mlir-translate).
Documentation Index
docs/mlir/index.md
Registers the new GettingStarted page in the MLIR toctree (single-line addition).

Sequence Diagram(s)

(omitted — changes are documentation additions, not new multi-component control flow)

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~15 minutes

Suggested labels

enhancement

Suggested reviewers

  • burgholzer

Poem

🐇 I hopped through pages, circuits in my paw,
Qubits and Hadamards, a Bell that I saw,
QC and QCO danced in neat rows,
Snippets and diagrams where knowledge grows,
Off I skippity-skip with a joyful guffaw.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Getting Started With MLIR' accurately describes the main change: adding a comprehensive getting-started tutorial for MLIR. It is clear, specific, and directly related to the primary objective of the PR.
Description check ✅ Passed The PR description includes a clear summary stating it adds a Getting Started with MLIR tutorial resolving #1452, but the checklist is entirely unchecked, missing details on changelog entries, migration instructions, and AI-assisted content disclosure if applicable.
Linked Issues check ✅ Passed The PR comprehensively addresses issue #1452 objectives: installation setup (linking to existing guide), 'Hello Quantum' walkthrough (Bell state example), detailed QC vs QCO comparison with running examples, advanced constructs with control-flow, accessible content for MLIR beginners, and verified code snippets.
Out of Scope Changes check ✅ Passed All changes are in-scope: the new GettingStarted.md tutorial and index.md update directly support the linked issue #1452 objectives. No unrelated modifications are present.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/getting_started_mlir
📝 Coding Plan
  • Generate coding plan for human review comments

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.

@burgholzer burgholzer added documentation Improvements or additions to documentation MLIR Anything related to MLIR labels Mar 12, 2026
@burgholzer burgholzer added this to the MLIR Support milestone Mar 12, 2026
Copy link
Collaborator

@DRovara DRovara left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot for the work, @MatthiasReumann! All in all, it already looks pretty nice. I still tried to give some (maybe controversial) opinions, just to make sure everything is clear. None of them are really set in stone, just suggestions.

That being said though: I believe there is still some room for discussion when it comes to who the target audience should be for this "Getting Started Guide":

  • Probably it shouldn't be quantum algorithm engineers who just want to compile their code. They don't care what happens in the background.
  • Then, one would assume it's compiler developers. But why would compiler developers care about the qc dialect (which the majority of this tutorial is about).

All in all, this brings me to the big question: Is it really the "correct" approach to give the getting started guide in terms of the QC dialect? People are never supposed to write MLIR code anyways - we will likely have some other front-end or DSL for that. So the only time when the code will use QC is during the translation process (and for the output, if the user does not compile down to QIR). The only advantage that QC has over QCO is that it is simpler, but it is weird to argue, for a tutorial "we won't explain the important thing because that is too complicated, so instead we explain the less important thing".

What are everyone else's thoughts on that?

@@ -0,0 +1,196 @@
# Getting Started

The Multi-Level Intermediate Representation (MLIR) project is an extensive framework to build compilers for heterogeneous hardware. The Munich Quantum Toolkit (MQT) utilizes MLIR for quantum compilation. That is, given an intermediate representation (IR) - a description - of a quantum computation, transform this representation to one that is efficiently executable on a target architecture.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something about

That is, given an intermediate representation (IR) - a description - of a quantum computation, transform this representation to one that is efficiently executable on a target architecture.

Feels unclear to me. I wasn't immediately able to determine what exactly is being defined by this phrase, so it kind of kicked me out of the reading flow. Also, I'm not sure what I think about using "a quantum computation" as a technical term. It may not necessarily be wrong, but it feels like such an abstract concept in this context.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Piggybacking off that comment, I believe the entire guide is still too compact and does not yet provide enough context for the reader to follow the narrative (which is not entirely clear as off now as well).
I'll expand a bit on this in a larger comment.


The short snippets above contain many fundamental concepts of MLIR.

- **Dialects**: A dialect groups operations (`alloc`, `dealloc`) and types (`qubit`) under a common namespace (`qc`). The example above combines built-in dialects with custom dialects. The [`builtin`](https://mlir.llvm.org/docs/Dialects/Builtin/) dialect provides the `module` operation (the `builtin.` is usually omitted) and the [`func`](https://mlir.llvm.org/docs/Dialects/Func/) dialect contains operations to define and call functions. The custom [`qc`](./QC.md) (_"quantum circuit"_) dialect is defined in the MQT and extends the built-in ones with the necessary functionality for quantum computing.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a strong opinion, but I wonder what others think about it:

The custom qc ("quantum circuit") dialect is defined in the MQT

"in the MQT" makes it feel a bit like we have this underlying MQT concept that defines stuff. But the MLIR code is only part of MQT Core and other MQT Repositories don't even use it really.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The entire section in the docs is currently called "MLIR in the MQT", which is where I would assume this is coming from.
I would be in favor of changing that and, potentially, making this more of a "MQT Compiler Collection" section in the docs. And then explicitly refer to that name throughout the guide here.

The short snippets above contain many fundamental concepts of MLIR.

- **Dialects**: A dialect groups operations (`alloc`, `dealloc`) and types (`qubit`) under a common namespace (`qc`). The example above combines built-in dialects with custom dialects. The [`builtin`](https://mlir.llvm.org/docs/Dialects/Builtin/) dialect provides the `module` operation (the `builtin.` is usually omitted) and the [`func`](https://mlir.llvm.org/docs/Dialects/Func/) dialect contains operations to define and call functions. The custom [`qc`](./QC.md) (_"quantum circuit"_) dialect is defined in the MQT and extends the built-in ones with the necessary functionality for quantum computing.
- **SSA Values**: Operations can consume (_"operands"_) and produce (_"results"_) values. For instance, `qc.alloc` produces the value `q0`, while `qc.dealloc` consumes it. Furthermore, values in MLIR adhere to the static single-assignment (SSA) principle, where each variable is assigned exactly once and never reassigned.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels a bit weird that this point is named "SSA Values", but the explanation of what that means is just a secondary sentence "Furthermore, ..."

Conceptually, it is also a tiny bit confusing to start with "SSA Values" and then talk about consuming and producing values first. Maybe this can be fixed with simple reformulating?


- **Dialects**: A dialect groups operations (`alloc`, `dealloc`) and types (`qubit`) under a common namespace (`qc`). The example above combines built-in dialects with custom dialects. The [`builtin`](https://mlir.llvm.org/docs/Dialects/Builtin/) dialect provides the `module` operation (the `builtin.` is usually omitted) and the [`func`](https://mlir.llvm.org/docs/Dialects/Func/) dialect contains operations to define and call functions. The custom [`qc`](./QC.md) (_"quantum circuit"_) dialect is defined in the MQT and extends the built-in ones with the necessary functionality for quantum computing.
- **SSA Values**: Operations can consume (_"operands"_) and produce (_"results"_) values. For instance, `qc.alloc` produces the value `q0`, while `qc.dealloc` consumes it. Furthermore, values in MLIR adhere to the static single-assignment (SSA) principle, where each variable is assigned exactly once and never reassigned.
- **Regions and Blocks**: To represent hierarchical structures, operations may contain _"regions"_. A region consists of one to many _"blocks"_ which again contain operations. For instance, the `module` operation contains one region consisting of one block that contains the `func.func` operation. A block optionally requires a _"terminator"_ that defines the end of the current block. The `func.return` operation is such a terminator. The following figure visualizes the connection between operations, regions, and blocks succinctly.
Copy link
Collaborator

@DRovara DRovara Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the figure on Regions and Blocks, but I also don't think it is self-explanatory enough.

The section on Regions and Blocks does not really provide a distinction on what the two are so that a reader would feel confident in distinguishing the concepts. Also, I think we should take advantage of the intuitive "surrounded by curly braces" explanation, so that a reader would think "ah, so it's just like in [their favourite programming language]".

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with Damian here, this could benefit from an updated picture as well as description that makes this a little more tangible.

:align: center
```

### Gates And Measurements
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels a bit abrupt. Maybe we should add a finishing sentence before going back to quantum concepts.


Internally, the optimizations are performed on the [`qco`](./QCO.md) (_"quantum circuit optimization"_) dialect. While the QC dialect is great for exchanging with other formats (such as OpenQASM), the QCO dialect is specifically designed for optimizations.

The following IR describes the construction of the first Bell state (and subsequent measurement) in the QCO dialect. Each unitary operation consumes and produces SSA values and each SSA value is used at most once (_"linear typing"_). Semantically, a qubit SSA value in the QCO dialect represents the state of the qubit (_"value semantics"_) whereas in the QC dialect a qubit SSA value references a qubit (_"reference semantics"_).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Each unitary operation consumes and produces SSA values

From a story-telling perspective, it feels a bit weird that this concept of consuming and producing SSA values was explained in the MLIR basics and then only came up here, so much later.

I don't know if there's a solution for that, though.


Internally, the optimizations are performed on the [`qco`](./QCO.md) (_"quantum circuit optimization"_) dialect. While the QC dialect is great for exchanging with other formats (such as OpenQASM), the QCO dialect is specifically designed for optimizations.

The following IR describes the construction of the first Bell state (and subsequent measurement) in the QCO dialect. Each unitary operation consumes and produces SSA values and each SSA value is used at most once (_"linear typing"_). Semantically, a qubit SSA value in the QCO dialect represents the state of the qubit (_"value semantics"_) whereas in the QC dialect a qubit SSA value references a qubit (_"reference semantics"_).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whereas in the QC dialect a qubit SSA value references a qubit ("reference semantics").

Feels a bit awkward. Maybe more like "is a pointer to a qubit" or "is a reference to a qubit", or maybe even a nod towards related things they already know ("just like Qubits in OpenQASM").

}
}
```

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To make it more intuitive, it would be cool to have an explanation of what changed.

  • "All qco gates now return the new state after applying the gate (%q0_1 = qco.h %q0_0)"
  • "The result of the operation inside the ctrl modifier needs to be passed on to the outer block, so we use qco.yield"
  • "qco.measure now returns two values: in addition to the classical measurement outcome, we also return the state after measurement`"
  • "qco.dealloc does not have to return a value, as the corresponding qubit is destroyed."


The following figure illustrates the data-flow graph of the IR above. Thanks to the QCO dialect, the dependencies between operations become immediately apparent. For example, the controlled-X gate depends on the Hadamard gate because it consumes the `q0_1` qubit SSA value. Moreover, MLIR provides the necessary functionality to efficiently traverse the data-flow graph and thus the circuit.

```{image} ../_static/qco-dataflow.svg
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No strong opinion, just to bring it up: The MLIR code has no CX, just a CTRL(X). Should that be illustrated somehow in the figure?

Great figure, otherwise!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also love the figure. Could be even cooler when showing the control modifier, its block arguments, and the nested structure in general.


Quantum IR in the QCO dialect can be quite complex. Writing it by hand is certainly an error-prone task. Fortunately, you don't have to. The compiler driver's interface accepts and produces quantum IR in the QC dialect. Under the hood, it transforms it to the QCO dialect, performs the optimizations, and transforms it back to the QC dialect. That's also why we refer to the QC dialect as interface dialect. The following figure depicts the interplay between the two dialects illustratively.

```{image} ../_static/compilation-pipeline.svg
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add optional QIR output information here?

Some people may be specifically interested in compiling down to QIR. There should be some source that tells them how to call mqt-cc for that and that even tells them that we can do that to begin with. Might as well be here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe we should definitely talk about QIR here and also show an example of a QIR program. Then this can also be tied back to the other documentation section on the QIR runner. Best case, whatever is being produced here can be directly fed into the commands being shown there.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Covered in the Emitting Quantum Intermediate Representation (QIR) subsection.

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.

Thanks @MatthiasReumann for getting this started 😄
Great to see someone push this forward!

I now also gave this a thorough read.
I added some comments inline as well, but much more important than that, I would like to pick up on Damians points below.

That being said though: I believe there is still some room for discussion when it comes to who the target audience should be for this "Getting Started Guide":

Probably it shouldn't be quantum algorithm engineers who just want to compile their code. They don't care what happens in the background.
Then, one would assume it's compiler developers. But why would compiler developers care about the qc dialect (which the majority of this tutorial is about).
All in all, this brings me to the big question: Is it really the "correct" approach to give the getting started guide in terms of the QC dialect? People are never supposed to write MLIR code anyways - we will likely have some other front-end or DSL for that. So the only time when the code will use QC is during the translation process (and for the output, if the user does not compile down to QIR). The only advantage that QC has over QCO is that it is simpler, but it is weird to argue, for a tutorial "we won't explain the important thing because that is too complicated, so instead we explain the less important thing".

What are everyone else's thoughts on that?

Currently, the guide feels very compact. It touches on some topics, but mostly briefly, and for the most part probably not exhaustively.
I said in one of the comments that it is "nicht fisch, nicht fleisch", and I think this also is what Damian is highlighting above. At the moment the guide itself isn't sure who it is written for.

I think this could easily be split into three parts:

  • For the people knowing quantum that have never heard of MLIR; those should start with an MLIR section that explains the concepts; potentially referring back to concepts that people might know from SDKs like Qiskit or Pennylane, or from languages like OpenQASM. People knowing MLIR may skip this section.
  • For the people that know classical compilers (and MLIR), but that don't know quantum too well. Those should start at a section that step by step explains quantum concepts, but tries to refer back to classical compiler and MLIR terminology wherever suitable. People knowing quantum may skip this section.
  • For the people familiar with both (or that have read both previous sections). Those people, we should tell what exactly we are doing as part of the project here. This should explain the difference between the two dialects, the compilation flow, etc. This is the meat of the tutorial; the previous sections are kind of the background for the relevant crowd. Within this section, it may again be interesting to provide some anecdotes that people from one of the backgrounds would find helpful ("the program structure in QCO is very similar to DAG structures people may be familiar with from Qiskit" for example)

Overall, this should really have an educational character for people and leave as little up for imagination as possible (Damian already did a great job in the comments highlighting a couple of places where this might not yet be the case).

That's all I got for now. I hope this makes sense and helps to navigate this into the right direction. Despite the flood of comments, this is still a really great start! 🎉

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love the figure (and the style in general).
One could extend this, by also showing the potential inputs and outputs (or formats) somehow. For now this would mean it can translate qc::QuantumComputation objects (which in turn can be constructed from OpenQASM 3 and Qiskit QuantumCircuits) and it can produce QIR.
Probably a figure that we will be extending in the future.

@@ -0,0 +1,196 @@
# Getting Started

The Multi-Level Intermediate Representation (MLIR) project is an extensive framework to build compilers for heterogeneous hardware. The Munich Quantum Toolkit (MQT) utilizes MLIR for quantum compilation. That is, given an intermediate representation (IR) - a description - of a quantum computation, transform this representation to one that is efficiently executable on a target architecture.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Piggybacking off that comment, I believe the entire guide is still too compact and does not yet provide enough context for the reader to follow the narrative (which is not entirely clear as off now as well).
I'll expand a bit on this in a larger comment.

Comment on lines +21 to +28
module {
func.func @main() {
%q0 = qc.alloc : !qc.qubit
qc.dealloc %q0 : !qc.qubit

func.return
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this is not a faithful representation of a QC program that would be generated from the ProgramBuilder. It definitely lacks the entrypoint definition and I am not 100% sure whether the return statement is correct.

}
```

### Interlude: MLIR Concepts
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is related to something that Damian brought up elsewhere: The current guide somewhat feels lacking in certain bits and pieces (in German one would say "nicht Fisch, nicht Fleisch"). It starts off with some quantum concepts, but not really to many for someone that wouldn't know much about quantum; then it switches to MLIR concepts, but directly ties these to quantum concepts, which might be confusing to the reader. I think we need to zoom out here a little bit, and find a good, coherent narrative.


The short snippets above contain many fundamental concepts of MLIR.

- **Dialects**: A dialect groups operations (`alloc`, `dealloc`) and types (`qubit`) under a common namespace (`qc`). The example above combines built-in dialects with custom dialects. The [`builtin`](https://mlir.llvm.org/docs/Dialects/Builtin/) dialect provides the `module` operation (the `builtin.` is usually omitted) and the [`func`](https://mlir.llvm.org/docs/Dialects/Func/) dialect contains operations to define and call functions. The custom [`qc`](./QC.md) (_"quantum circuit"_) dialect is defined in the MQT and extends the built-in ones with the necessary functionality for quantum computing.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The entire section in the docs is currently called "MLIR in the MQT", which is where I would assume this is coming from.
I would be in favor of changing that and, potentially, making this more of a "MQT Compiler Collection" section in the docs. And then explicitly refer to that name throughout the guide here.


- **Dialects**: A dialect groups operations (`alloc`, `dealloc`) and types (`qubit`) under a common namespace (`qc`). The example above combines built-in dialects with custom dialects. The [`builtin`](https://mlir.llvm.org/docs/Dialects/Builtin/) dialect provides the `module` operation (the `builtin.` is usually omitted) and the [`func`](https://mlir.llvm.org/docs/Dialects/Func/) dialect contains operations to define and call functions. The custom [`qc`](./QC.md) (_"quantum circuit"_) dialect is defined in the MQT and extends the built-in ones with the necessary functionality for quantum computing.
- **SSA Values**: Operations can consume (_"operands"_) and produce (_"results"_) values. For instance, `qc.alloc` produces the value `q0`, while `qc.dealloc` consumes it. Furthermore, values in MLIR adhere to the static single-assignment (SSA) principle, where each variable is assigned exactly once and never reassigned.
- **Regions and Blocks**: To represent hierarchical structures, operations may contain _"regions"_. A region consists of one to many _"blocks"_ which again contain operations. For instance, the `module` operation contains one region consisting of one block that contains the `func.func` operation. A block optionally requires a _"terminator"_ that defines the end of the current block. The `func.return` operation is such a terminator. The following figure visualizes the connection between operations, regions, and blocks succinctly.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with Damian here, this could benefit from an updated picture as well as description that makes this a little more tangible.


Internally, the optimizations are performed on the [`qco`](./QCO.md) (_"quantum circuit optimization"_) dialect. While the QC dialect is great for exchanging with other formats (such as OpenQASM), the QCO dialect is specifically designed for optimizations.

The following IR describes the construction of the first Bell state (and subsequent measurement) in the QCO dialect. Each unitary operation consumes and produces SSA values and each SSA value is used at most once (_"linear typing"_). Semantically, a qubit SSA value in the QCO dialect represents the state of the qubit (_"value semantics"_) whereas in the QC dialect a qubit SSA value references a qubit (_"reference semantics"_).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The following IR describes the construction of the first Bell state (and subsequent measurement) in the QCO dialect. Each unitary operation consumes and produces SSA values and each SSA value is used at most once (_"linear typing"_). Semantically, a qubit SSA value in the QCO dialect represents the state of the qubit (_"value semantics"_) whereas in the QC dialect a qubit SSA value references a qubit (_"reference semantics"_).
The following IR describes the construction of the first Bell state (and subsequent measurement) in the QCO dialect. Each unitary operation consumes and produces SSA values and each SSA value is used exactly once (_"linear typing"_). Semantically, a qubit SSA value in the QCO dialect represents the state of the qubit (_"value semantics"_) whereas in the QC dialect a qubit SSA value references a qubit (_"reference semantics"_).

Subtle, but important. Linear typing dictates that values are used exactly once.


The following figure illustrates the data-flow graph of the IR above. Thanks to the QCO dialect, the dependencies between operations become immediately apparent. For example, the controlled-X gate depends on the Hadamard gate because it consumes the `q0_1` qubit SSA value. Moreover, MLIR provides the necessary functionality to efficiently traverse the data-flow graph and thus the circuit.

```{image} ../_static/qco-dataflow.svg
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also love the figure. Could be even cooler when showing the control modifier, its block arguments, and the nested structure in general.


Quantum IR in the QCO dialect can be quite complex. Writing it by hand is certainly an error-prone task. Fortunately, you don't have to. The compiler driver's interface accepts and produces quantum IR in the QC dialect. Under the hood, it transforms it to the QCO dialect, performs the optimizations, and transforms it back to the QC dialect. That's also why we refer to the QC dialect as interface dialect. The following figure depicts the interplay between the two dialects illustratively.

```{image} ../_static/compilation-pipeline.svg
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe we should definitely talk about QIR here and also show an example of a QIR program. Then this can also be tied back to the other documentation section on the QIR runner. Best case, whatever is being produced here can be directly fed into the commands being shown there.

QC
QCO
Conversions
GettingStarted
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like this should be the first section in this chapter of the docs. In the end, it is about getting started, which should happen first I suppose.
Also, we may want to nest the other sections one level deeper under an "API" heading or similar.

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

♻️ Duplicate comments (1)
docs/mlir/GettingStarted.md (1)

83-89: ⚠️ Potential issue | 🟠 Major

Fill in the core tutorial sections before merge.

The two key subsections are empty (The QC and QCO Dialects, Compilation Flow), so the guide currently misses the main learning path (QC vs QCO semantics and QC→QCO flow) promised by this PR and linked issue.

✍️ Minimal structure to add now
 ### The QC and QCO Dialects
+QC uses reference semantics and models qubits as references to allocated resources.
+QCO uses value semantics with linear types, where each qubit SSA value is consumed exactly once.
+Show one small side-by-side snippet (QC and QCO) for the same Bell-state step to make this concrete.

 ### Compilation Flow
+The typical flow is: OpenQASM -> QC -> QCO -> (optional) QIR.
+Add one command sequence with `mqt-cc` and briefly explain where optimizations happen.
+Include one short note about current limitations (e.g., unsupported patterns), if applicable.

Based on learnings from issue #1452 objectives, this guide is expected to explain QC vs QCO in detail and illustrate the QC → QCO transformation with a running example.

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

In `@docs/mlir/GettingStarted.md` around lines 83 - 89, The two subsections "The
QC and QCO Dialects" and "Compilation Flow" in GettingStarted.md are empty; fill
them with content that (1) defines QC and QCO semantics (key differences,
example ops/constructs and when to use each) under the "The QC and QCO Dialects"
header and (2) describes the QC→QCO transformation pipeline with a small running
example showing input QC IR, the transformation steps (pass names or functions)
and resulting QCO IR under "Compilation Flow"; reference the section titles "The
QC and QCO Dialects" and "Compilation Flow" when adding content so the guide
explains QC vs QCO and demonstrates the QC→QCO flow end-to-end as requested by
the linked issue.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/mlir/GettingStarted.md`:
- Line 164: The "## Conclusion" heading in the GettingStarted.md document is
empty; either remove the heading or add a brief concluding paragraph summarizing
the guide. Locate the heading text "## Conclusion" and either delete that line
(and any trailing blank lines) or append 2–4 sentences that wrap up the
document’s key takeaways and next steps so the section is not left blank.
- Around line 30-33: Fix the wording in the MLIR intro: change "The core concept
in MLIR are _dialects_" to "The core concepts in MLIR are _dialects_"; change
"floating point" to "floating-point" (e.g., "integer and floating-point
operations"); and replace "which let's us define and call functions" with "which
lets us define and call functions" (remove the apostrophe). Keep references to
SCF, arith, and Func dialects intact.

---

Duplicate comments:
In `@docs/mlir/GettingStarted.md`:
- Around line 83-89: The two subsections "The QC and QCO Dialects" and
"Compilation Flow" in GettingStarted.md are empty; fill them with content that
(1) defines QC and QCO semantics (key differences, example ops/constructs and
when to use each) under the "The QC and QCO Dialects" header and (2) describes
the QC→QCO transformation pipeline with a small running example showing input QC
IR, the transformation steps (pass names or functions) and resulting QCO IR
under "Compilation Flow"; reference the section titles "The QC and QCO Dialects"
and "Compilation Flow" when adding content so the guide explains QC vs QCO and
demonstrates the QC→QCO flow end-to-end as requested by the linked issue.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 5455081e-a4a9-4d40-a96e-60c3468ccfde

📥 Commits

Reviewing files that changed from the base of the PR and between 7bb1caa and 4853bf9.

⛔ Files ignored due to path filters (1)
  • docs/_static/mlir-regions-blocks-ops.svg is excluded by !**/*.svg
📒 Files selected for processing (2)
  • docs/mlir/GettingStarted.md
  • docs/mlir/index.md

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: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/mlir/GettingStarted.md`:
- Line 26: The headings "Quantum Computing" and "Compilation Flow" in
GettingStarted.md are empty placeholders; either remove these headings or add
brief, complete content under each (e.g., a short overview and links/examples)
to avoid interrupting the tutorial flow; update both occurrences (the heading at
line showing "Quantum Computing" and the other empty "Compilation Flow" heading
referenced at the other location) and ensure the added content matches the
surrounding style and links/refs elsewhere in the document.
- Around line 94-95: Several `{code-block}` directives contain a non-breaking
space between "}" and "mlir" (the sequence `{code-block} mlir`) which breaks
MyST/Sphinx parsing; locate each occurrence of the string `{code-block} mlir` in
GettingStarted.md (the blocks around the QC examples) and replace the
non-breaking space with a normal ASCII space so the directives read
`{code-block} mlir`; ensure you update all occurrences mentioned (the four
directive instances around the QC examples) and preserve the surrounding
backticks/Markdown fencing and code content.
- Around line 199-203: Add a short "Current limitations" subsection before the
"Examples Using the MQT Compiler Collection Tool" examples under the
"Compilation Flow" heading that clearly lists the QC→QCO and
multi-function/control-flow boundaries: mention limited support for multiple
functions in a single conversion, constraints around function-like and scf
regions, and known issues with container-typed qubit flows (e.g., lists/arrays
of qubits not fully supported); keep it concise, use the terms "QC→QCO",
"function-like", and "scf" so readers can correlate with code examples, and
place it immediately above the examples section.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 86caa472-2736-4f43-99b3-c860a750e36d

📥 Commits

Reviewing files that changed from the base of the PR and between 4853bf9 and 4d3ed39.

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

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

♻️ Duplicate comments (5)
docs/mlir/GettingStarted.md (5)

274-274: ⚠️ Potential issue | 🟠 Major

Fill or remove the empty "Compilation Flow" subsection.

This subsection heading at line 274 is empty. It should either explain the compilation workflow (QC→QCO conversion, optimization passes, lowering to QIR) or be removed. Given that the Examples section immediately follows, a brief 2-3 paragraph overview of the compilation pipeline would provide valuable context before showing tool usage.

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

In `@docs/mlir/GettingStarted.md` at line 274, The "Compilation Flow" subsection
heading is empty — either remove the heading or populate it with a brief 2–3
paragraph overview describing the pipeline: explain the QC → QCO conversion
step, enumerate key optimization passes (e.g., simplification, gate fusion,
resource/ancilla allocation), and describe the lowering stage to QIR including
any backend/codegen considerations; update the subsection under the "Compilation
Flow" heading so it sits before the Examples section and uses clear, concise
sentences referencing the QC→QCO conversion, optimization passes, and lowering
to QIR.

26-26: ⚠️ Potential issue | 🟠 Major

Fill or remove the empty "Quantum Computing" subsection.

The Fundamentals section (line 24) promises coverage for readers unfamiliar with quantum computing, but the "Quantum Computing" subsection at line 26 is empty. This leaves beginners without necessary context. Either add a brief (3-4 paragraph) introduction covering qubits, gates, superposition, entanglement, and measurement, or remove the heading and adjust the intro text to clarify that quantum computing background is assumed.

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

In `@docs/mlir/GettingStarted.md` at line 26, The "Quantum Computing" subsection
heading is empty; either populate the "Quantum Computing" subsection with a
brief 3–4 paragraph primer covering qubits, quantum gates, superposition,
entanglement, and measurement (so readers unfamiliar with quantum concepts can
follow the "Fundamentals" section), or remove the "Quantum Computing" heading
and update the "Fundamentals" intro to clearly state that quantum computing
background is assumed. Locate the heading "Quantum Computing" in
GettingStarted.md and implement one of these two fixes, ensuring the added text
is concise and aligns with surrounding tone and structure.

276-278: ⚠️ Potential issue | 🟠 Major

Document known multi-function and control-flow limitations.

The PR description notes that "attempts to implement multiple functions and function calling fail when converting QC → QCO." However, the guide does not document this or other known limitations. Add a "Current Limitations" subsection before the examples that clearly states:

  • Multi-function modules with qubit-typed helper functions are not yet supported in QC→QCO conversion
  • Function operations assume all-qubit or all-classical types (no mixed quantum/classical signatures)
  • scf.for can handle qubit containers (memref/tensor), but scf.if and scf.while are restricted to scalar qubit types only

This will prevent confusion when readers attempt workflows beyond the single-function examples shown.

Based on learnings: QCToQCO conversion passes enforce specific constraints on func and scf operations that limit multi-function and container-typed qubit flows.

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

In `@docs/mlir/GettingStarted.md` around lines 276 - 278, Add a new "Current
Limitations" subsection immediately before the "Examples Using the MQT Compiler
Collection Tool" section that explicitly lists the known QC→QCO conversion
constraints: state that multi-function modules with qubit-typed helper functions
are not supported in QC→QCO conversion, that func operations assume homogeneous
argument/result types (all-qubit or all-classical — no mixed quantum/classical
signatures), and that scf.for supports qubit containers (memref/tensor) while
scf.if and scf.while are limited to scalar qubit types only; reference these
symbols (QC→QCO, func, scf.for, scf.if, scf.while) in the prose so readers can
map limitations to the conversion checks mentioned in the PR.

32-32: ⚠️ Potential issue | 🟡 Minor

Fix grammar and style issues in dialect introduction.

Three issues on this line:

  • Subject-verb disagreement: "core concept...are" should be "core concepts...are"
  • Missing hyphen in compound adjective: "floating point operations" should be "floating-point operations"
  • Incorrect apostrophe: "which let's us" should be "which lets us"
📝 Proposed fix
-The core concept in MLIR are _dialects_. A dialect groups operations, types, and attributes under a common namespace. A single program may combine multiple dialects, which facilitates code reuse. For example, the structured control flow (SCF) dialect provides functionality for control flow constructs, while the arith dialect defines integer and floating point operations. Another essential dialect is the Func dialect, which let's us define and call functions.
+The core concepts in MLIR are _dialects_. A dialect groups operations, types, and attributes under a common namespace. A single program may combine multiple dialects, which facilitates code reuse. For example, the structured control flow (SCF) dialect provides functionality for control-flow constructs, while the arith dialect defines integer and floating-point operations. Another essential dialect is the Func dialect, which lets us define and call functions.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/mlir/GettingStarted.md` at line 32, Fix the sentence describing MLIR
dialects: change "The core concept in MLIR are" to either "The core concepts in
MLIR are" or "A core concept in MLIR is" for correct subject-verb agreement; add
a hyphen to "floating point operations" -> "floating-point operations"; and
replace the incorrect contraction "which let's us" with "which lets us". Update
the line referencing MLIR dialects and examples (SCF, arith, Func) accordingly.

94-95: ⚠️ Potential issue | 🔴 Critical

Fix non-breaking spaces in {code-block} directives.

Lines 94, 118, 142, 170, and 204 contain non-breaking space characters (U+00A0) between } and mlir in the code-block directives, which break MyST/Sphinx parsing. Replace these with regular ASCII spaces.

Affected lines
  • Line 94: {code-block} (before mlir)
  • Line 118: {code-block} (before mlir)
  • Line 142: {code-block} (before mlir)
  • Line 170: {code-block} (before mlir)
  • Line 204: {code-block} (before mlir)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/mlir/GettingStarted.md` around lines 94 - 95, Replace the non-breaking
space (U+00A0) between the `{code-block}` token and the language specifier
`mlir` with a normal ASCII space in the `{code-block}` directives; locate
occurrences of the sequence "{code-block} mlir" (note the NBSP) and change them
to "{code-block} mlir" so MyST/Sphinx parsing is restored.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/mlir/GettingStarted.md`:
- Line 351: The "## Conclusion" heading in GettingStarted.md is empty; either
remove the heading or add a 2–3 sentence summary that wraps up the guide (for
example mention foundation for using the MQT Compiler Collection, differences
between QC and QCO dialects, and emitting QIR for execution) so the document has
a proper closing; edit the "## Conclusion" section accordingly in
docs/mlir/GettingStarted.md.

---

Duplicate comments:
In `@docs/mlir/GettingStarted.md`:
- Line 274: The "Compilation Flow" subsection heading is empty — either remove
the heading or populate it with a brief 2–3 paragraph overview describing the
pipeline: explain the QC → QCO conversion step, enumerate key optimization
passes (e.g., simplification, gate fusion, resource/ancilla allocation), and
describe the lowering stage to QIR including any backend/codegen considerations;
update the subsection under the "Compilation Flow" heading so it sits before the
Examples section and uses clear, concise sentences referencing the QC→QCO
conversion, optimization passes, and lowering to QIR.
- Line 26: The "Quantum Computing" subsection heading is empty; either populate
the "Quantum Computing" subsection with a brief 3–4 paragraph primer covering
qubits, quantum gates, superposition, entanglement, and measurement (so readers
unfamiliar with quantum concepts can follow the "Fundamentals" section), or
remove the "Quantum Computing" heading and update the "Fundamentals" intro to
clearly state that quantum computing background is assumed. Locate the heading
"Quantum Computing" in GettingStarted.md and implement one of these two fixes,
ensuring the added text is concise and aligns with surrounding tone and
structure.
- Around line 276-278: Add a new "Current Limitations" subsection immediately
before the "Examples Using the MQT Compiler Collection Tool" section that
explicitly lists the known QC→QCO conversion constraints: state that
multi-function modules with qubit-typed helper functions are not supported in
QC→QCO conversion, that func operations assume homogeneous argument/result types
(all-qubit or all-classical — no mixed quantum/classical signatures), and that
scf.for supports qubit containers (memref/tensor) while scf.if and scf.while are
limited to scalar qubit types only; reference these symbols (QC→QCO, func,
scf.for, scf.if, scf.while) in the prose so readers can map limitations to the
conversion checks mentioned in the PR.
- Line 32: Fix the sentence describing MLIR dialects: change "The core concept
in MLIR are" to either "The core concepts in MLIR are" or "A core concept in
MLIR is" for correct subject-verb agreement; add a hyphen to "floating point
operations" -> "floating-point operations"; and replace the incorrect
contraction "which let's us" with "which lets us". Update the line referencing
MLIR dialects and examples (SCF, arith, Func) accordingly.
- Around line 94-95: Replace the non-breaking space (U+00A0) between the
`{code-block}` token and the language specifier `mlir` with a normal ASCII space
in the `{code-block}` directives; locate occurrences of the sequence
"{code-block} mlir" (note the NBSP) and change them to "{code-block} mlir" so
MyST/Sphinx parsing is restored.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: ae0ea925-ed00-426f-9add-7e1cd6ded496

📥 Commits

Reviewing files that changed from the base of the PR and between 4d3ed39 and d366181.

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

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

♻️ Duplicate comments (3)
docs/mlir/GettingStarted.md (3)

89-140: 🧹 Nitpick | 🔵 Trivial

Optional: Consider adding brief explanations for type syntax and operands vs. attributes.

The MLIR fundamentals section introduces SSA values, types, operations, blocks, and regions effectively. However, as noted in past reviews, readers encountering quantum MLIR examples later may benefit from:

  • A brief note on the !dialect.typename type syntax convention (e.g., !qc.qubit, !qco.qubit)
  • A short distinction between operands (runtime values) and attributes (compile-time constants)

These could be added as 1-2 sentence clarifications in this section or deferred to the Quantum Dialects section where they first appear.

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

In `@docs/mlir/GettingStarted.md` around lines 89 - 140, Add a concise 1–2
sentence clarification in the MLIR fundamentals section (near the explanations
of types and SSA values) that explains the MLIR custom type syntax using the
form !dialect.typename (give examples like !qc.qubit and !qco.qubit) and briefly
distinguish operands (runtime SSA values like %a, %b) from attributes
(compile-time constants attached to ops); insert this either inline after the
bullet about ": index and : i32" or as a short note before the quantum dialect
examples so readers see the convention before encountering !qc.qubit and the use
of operands vs. attributes.

440-440: ⚠️ Potential issue | 🟡 Minor

Fill or remove the empty Conclusion heading.

The "## Conclusion" heading at line 440 has no content. This was flagged in a previous review and remains unresolved. Either:

  1. Add a brief 2–3 sentence closing summary that wraps up the key takeaways (e.g., "You now have a foundation for using the MQT Compiler Collection to write, optimize, and transpile quantum programs using the QC and QCO dialects. The value semantics and linear typing in QCO enable powerful optimization passes, while the QC dialect provides a familiar interface for quantum circuit representation. For more details on specific dialect operations and advanced features, refer to the QC and QCO dialect documentation pages.")

  2. Remove the heading entirely if the examples section serves as a natural conclusion

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

In `@docs/mlir/GettingStarted.md` at line 440, The "## Conclusion" heading is
empty; either add a brief 2–3 sentence closing summary under the "## Conclusion"
heading that wraps up the key takeaways (suggested text: two sentences about
having a foundation for using the MQT Compiler Collection, value of QCO
semantics and QC dialect, and a pointer to the QC and QCO dialect pages) or
delete the "## Conclusion" heading entirely if the examples already serve as the
natural end; if you add the summary, include links to the QC and QCO docs
(referenced as QC and QCO) to guide readers to more detail.

350-363: 🧹 Nitpick | 🔵 Trivial

Consider documenting current compiler limitations for advanced use cases.

The Compilation Flow section provides a good high-level overview. However, as noted in a previous review comment, users attempting more complex workflows should be aware of current limitations. Consider adding a brief "Current Limitations" note or subsection that mentions:

  • Function signatures: Multi-function programs with qubit-typed parameters have limited support in some conversion passes
  • Control-flow constraints: While scf.for supports qubit containers (memref/tensor), scf.if and scf.while are currently restricted to scalar qubit types only in certain conversion contexts
  • QIR emission: The QIR conversion path currently assumes a single entry-point function with specific signature constraints

These caveats would help users understand the boundaries of the current implementation and avoid frustration when exploring beyond the documented examples. Based on learnings, the MLIR functionality is still under active development, so explicitly noting these as temporary limitations is appropriate.

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

In `@docs/mlir/GettingStarted.md` around lines 350 - 363, Add a brief "Current
Limitations" subsection under the "Compilation Flow" heading that explicitly
lists the known MLIR/compilation constraints so advanced users are aware:
mention limited support for multi-function programs with qubit-typed parameters
(function signature constraints), the control-flow restrictions where scf.for
can handle qubit containers (memref/tensor) but scf.if and scf.while are
currently limited to scalar qubit types in some conversion passes, and the QIR
emission path assumption of a single entry-point with specific signature
constraints; mark these as temporary/under-development and keep the note concise
and linked to the Compilation Flow description.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/mlir/GettingStarted.md`:
- Around line 7-19: Replace the `%` shell prompt tokens with `$` in the console
code blocks in GettingStarted.md so they match project documentation style:
change occurrences in the cmake/build example (the lines showing "cmake -Bbuild
\", "cd build && cmake --build . --target mqt-cc") and the verification command
("./mlir/tools/mqt-cc/mqt-cc --help") from `%` to `$`, and apply the same
`%`→`$` replacement to the other console blocks elsewhere in the file that
follow the same pattern.
- Around line 142-349: Add a new subsection after the Quantum Dialects section
that provides (1) an scf.for example showing loop-carried SSA qubit values with
qco.alloc/qco.yield to demonstrate linear typing across iterations (reference
scf.for, qco.yield, loop-carried entry-arguments), (2) an scf.if example that
conditionally applies gates based on a measurement result showing separate SSA
branches and how to merge results without re-using values (reference scf.if,
qco.measure, qco.yield), and (3) a multi-function example that defines a helper
function taking and returning qubits and shows a call site to illustrate
function parameter/return semantics under linear typing (reference the function
declaration/call symbols used in the doc); briefly annotate each example with
one sentence explaining how linear typing is preserved (use scf.yield and
explicit entry-arguments to avoid variable re-use).

---

Duplicate comments:
In `@docs/mlir/GettingStarted.md`:
- Around line 89-140: Add a concise 1–2 sentence clarification in the MLIR
fundamentals section (near the explanations of types and SSA values) that
explains the MLIR custom type syntax using the form !dialect.typename (give
examples like !qc.qubit and !qco.qubit) and briefly distinguish operands
(runtime SSA values like %a, %b) from attributes (compile-time constants
attached to ops); insert this either inline after the bullet about ": index and
: i32" or as a short note before the quantum dialect examples so readers see the
convention before encountering !qc.qubit and the use of operands vs. attributes.
- Line 440: The "## Conclusion" heading is empty; either add a brief 2–3
sentence closing summary under the "## Conclusion" heading that wraps up the key
takeaways (suggested text: two sentences about having a foundation for using the
MQT Compiler Collection, value of QCO semantics and QC dialect, and a pointer to
the QC and QCO dialect pages) or delete the "## Conclusion" heading entirely if
the examples already serve as the natural end; if you add the summary, include
links to the QC and QCO docs (referenced as QC and QCO) to guide readers to more
detail.
- Around line 350-363: Add a brief "Current Limitations" subsection under the
"Compilation Flow" heading that explicitly lists the known MLIR/compilation
constraints so advanced users are aware: mention limited support for
multi-function programs with qubit-typed parameters (function signature
constraints), the control-flow restrictions where scf.for can handle qubit
containers (memref/tensor) but scf.if and scf.while are currently limited to
scalar qubit types in some conversion passes, and the QIR emission path
assumption of a single entry-point with specific signature constraints; mark
these as temporary/under-development and keep the note concise and linked to the
Compilation Flow description.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: b13701dc-8795-46ac-a613-5b08981fc759

📥 Commits

Reviewing files that changed from the base of the PR and between d366181 and 0b25cef.

⛔ Files ignored due to path filters (2)
  • docs/_static/bell-circuit.svg is excluded by !**/*.svg
  • docs/_static/qco-dataflow.svg is excluded by !**/*.svg
📒 Files selected for processing (1)
  • docs/mlir/GettingStarted.md

Comment on lines +7 to +19
```console
% cmake -Bbuild \
-DMLIR_DIR=<path to MLIR> \
-DLLVM_DIR=<path to LLVM> \
-DCMAKE_BUILD_TYPE:STRING=Release \
-DBUILD_MQT_CORE_MLIR=ON
% cd build && cmake --build . --target mqt-cc
```

You can verify your build by running the following command. If everything worked correctly, it should print an usage message.

```console
% ./mlir/tools/mqt-cc/mqt-cc --help
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Consider using $ prompt for consistency with project documentation style.

The console code blocks use % as the shell prompt. Based on learnings, MQT Core documentation conventionally uses $ prompt symbols in console code blocks (e.g., $ uv pip install ...). Consider updating to $ for consistency, unless % is intentionally used to indicate a different shell context.

📝 Suggested prompt update
 ```console
-% cmake -Bbuild \
+$ cmake -Bbuild \
     -DMLIR_DIR=<path to MLIR> \
     -DLLVM_DIR=<path to LLVM> \
     -DCMAKE_BUILD_TYPE:STRING=Release \
     -DBUILD_MQT_CORE_MLIR=ON
-% cd build && cmake --build . --target mqt-cc
+$ cd build && cmake --build . --target mqt-cc

You can verify your build by running the following command. If everything worked correctly, it should print an usage message.

-% ./mlir/tools/mqt-cc/mqt-cc --help
+$ ./mlir/tools/mqt-cc/mqt-cc --help

Apply the same replacement at lines 391, 429, and 435.
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @docs/mlir/GettingStarted.md around lines 7 - 19, Replace the % shell
prompt tokens with $ in the console code blocks in GettingStarted.md so they
match project documentation style: change occurrences in the cmake/build example
(the lines showing "cmake -Bbuild ", "cd build && cmake --build . --target
mqt-cc") and the verification command ("./mlir/tools/mqt-cc/mqt-cc --help") from
% to $, and apply the same %$ replacement to the other console blocks
elsewhere in the file that follow the same pattern.


</details>

<!-- fingerprinting:phantom:triton:puma -->

<!-- This is an auto-generated comment by CodeRabbit -->

Comment on lines +142 to +349
## The MQT Compiler Collection

The MQT Compiler Collection provides tools to optimize and transpile quantum programs. This section outlines how we utilize the MLIR framework as well as its compilation infrastructure to implement these tasks.

### Quantum Dialects

The MQT Compiler Collection defines two dialects in MLIR, each with a distinctive purpose. While the Quantum Circuit (QC) dialect is great for exchanging with other formats (such as OpenQASM), the Quantum Circuit Optimization (QCO) dialect is - as the name suggests - specifically designed for optimizations. Let's explore their differences.

The following snippet allocates and subsequently deallocates one qubit using the `alloc` and `dealloc` operations, respectively.

::::{grid} 2
:::{grid-item}

```{code-block} mlir
// QC
%q0 = qc.alloc : !qc.qubit
qc.dealloc %q0 : !qc.qubit
```

:::

:::{grid-item}

```mlir
// QCO
%q0_0 = qco.alloc : !qco.qubit
qco.dealloc %q0_0 : !qco.qubit
```

:::
::::

Alternatively, we can target specific hardware qubits by using the `static` operation. In the QC dialect, static qubits don't require a deallocation.

::::{grid} 2
:::{grid-item}

```{code-block} mlir
// QC
%q0 = qc.static 1 : !qc.qubit
```

:::

:::{grid-item}

```mlir
// QCO
%q0_0 = qco.static 1 : !qco.qubit
qco.dealloc %q0_0 : !qco.qubit
```

:::
::::

So far so good. No visible differences. Next, we want to apply the single-qubit Hadamard gate.

::::{grid} 2
:::{grid-item}

```{code-block} mlir
// QC
%q0 = qc.alloc : !qc.qubit
qc.h %q0 : !qc.qubit
qc.dealloc %q0 : !qc.qubit
```

:::

:::{grid-item}

```mlir
// QCO
%q0_0 = qco.alloc : !qco.qubit
%q0_1 = qco.h %q0_0 : !qco.qubit -> !qco.qubit
qco.dealloc %q0_1 : !qco.qubit
```

:::
::::

Notice how the Hadamard operation in the QCO dialect consumes and produces SSA values, while the operation in the QC dialect simply references the targeted qubit. We say that the QC dialect uses _reference semantics_ whereas the QCO dialect uses _value semantics_. Semantically, the unitary operations in the QCO dialect return the new state after modifying it. Furthermore, the QCO dialect imposes _linear typing_: each SSA value is used _exactly_ once.

Instead of using the Hadamard directly, we can also apply the transformation in terms of X and Y rotations with parameterized gates.

::::{grid} 2
:::{grid-item}

```{code-block} mlir
// QC
%theta = arith.constant 1.570796 : f64
%phi = arith.constant 3.141593 : f64

%q0 = qc.alloc : !qc.qubit
qc.ry(%theta) %q0 : !qc.qubit
qc.rx(%phi) %q0 : !qc.qubit
qc.dealloc %q0 : !qc.qubit
```

:::

:::{grid-item}

```mlir
// QCO
%theta = arith.constant 1.570796 : f64
%phi = arith.constant 3.141593 : f64

%q0_0 = qco.alloc : !qco.qubit
%q0_1 = qco.ry(%theta) %q0_0 : !qco.qubit -> !qco.qubit
%q0_2 = qco.rx(%phi) %q0_1 : !qco.qubit -> !qco.qubit
qco.dealloc %q0_2 : !qco.qubit
```

:::
::::

To measure qubits, use the `measure` operation. In the QCO dialect, the measurement operation returns not only the classical measurement outcome but also the state after measurement.

::::{grid} 2
:::{grid-item}

```{code-block} mlir
// QC
%q0 = qc.alloc : !qc.qubit
qc.h %q0 : !qc.qubit
%c0 = qc.measure %q0 : !qc.qubit -> i1
qc.dealloc %q0 : !qc.qubit
```

:::

:::{grid-item}

```mlir
// QCO
%q0_0 = qco.alloc : !qco.qubit
%q0_1 = qco.h %q0_0 : !qco.qubit -> !qco.qubit
%q0_2, %c0 = qco.measure %q0_1 : !qco.qubit
qco.dealloc %q0_2 : !qco.qubit
```

:::
::::

Moving on from one-qubit gates, let us apply a controlled-X operation. Towards that end, we allocate another qubit and subsequently use the `ctrl` _modifier_ operation of the respective dialect to implement the controlled-X. Thanks to modifiers, we can represent arbitrary (multi-)controlled gates without having to explicitly define them.

::::{grid} 2
:::{grid-item}

```{code-block} mlir
// QC
%q0 = qc.alloc : !qc.qubit
%q1 = qc.alloc : !qc.qubit

qc.h %q0 : !qc.qubit
qc.ctrl(%q0) {
qc.x %q1 : !qc.qubit

} : !qc.qubit

%c0 = qc.measure %q0 : !qc.qubit -> i1
%c1 = qc.measure %q1 : !qc.qubit -> i1

qc.dealloc %q0 : !qc.qubit
qc.dealloc %q1 : !qc.qubit
```

:::

:::{grid-item}

```mlir
// QCO
%q0_0 = qco.alloc : !qco.qubit
%q1_0 = qco.alloc : !qco.qubit

%q0_1 = qco.h %q0_0 : !qco.qubit -> !qco.qubit
%q0_2, %q1_1 = qco.ctrl(%q0_1) targets (%arg0 = %q1_0) {
%q0_2 = qco.x %arg0 : !qco.qubit -> !qco.qubit
qco.yield %q0_2
} : ({!qco.qubit}, {!qco.qubit}) -> ({!qco.qubit}, {!qco.qubit})

%q0_3, %c0 = qco.measure %q0_2 : !qco.qubit
%q1_2, %c1 = qco.measure %q1_1 : !qco.qubit

qco.dealloc %q0_3 : !qco.qubit
qco.dealloc %q1_2 : !qco.qubit
```

:::
::::

The `qco.ctrl` operation adds a bit of complexity:

- The input target qubit must be explicitly specified and is aliased to the block argument `%arg0`.
- The result of the `qco.x` operation needs to be passed to the outer block. Thus, similarly to the operations in the SCF dialect, we use `qco.yield`.
- Analogously to the other unitary operations in the QCO dialect, the `qco.ctrl` modifier returns the modified state of the input qubits.

The following figure describes the dataflow graph of the above quantum program in the QCO dialect.

```{image} ../_static/qco-dataflow.svg
:width: 85%
:align: center
```

Because of the QCO dialect's value semantics, the dependencies between operations are naturally expressed in the dataflow graph. For instance, in the figure above, the controlled-X operation depends on the application of the Hadamard operation. This is, for example, very useful for gate cancellation: The dependency of one gate is the inverse of it? Cancel the two! Consequently, the expressive dataflow representation is what makes the QCO dialect so powerful for optimization and algorithms more generally.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Address missing advanced constructs required by PR objectives.

The Quantum Dialects section provides excellent QC vs. QCO comparisons and explains value/reference semantics well. However, the PR objectives explicitly require:

"Cover advanced constructs: demonstrate multiple functions and discuss control-flow interactions (scf.for, scf.if) with quantum blocks, highlighting SSA and linear-type considerations in QCO (use scf.yield and entry-arguments to avoid variable re-use)."

Current gaps:

  1. No examples demonstrating scf.for or scf.if with quantum operations
  2. No multi-function examples (function definitions with qubit parameters, function calls)
  3. No discussion of how linear typing interacts with control-flow constructs

Suggested additions (consider adding a new subsection after line 349):

  • Control Flow with Quantum Operations: Show an scf.for example that iterates over quantum operations (e.g., applying a gate N times), demonstrating how loop-carried variables work with linear types and qco.yield
  • Conditional Quantum Operations: Show an scf.if example that conditionally applies operations based on measurement outcomes or parameters
  • Multi-Function Programs: Show a simple example of a helper function that takes and returns qubits, demonstrating function calls in quantum programs

These examples would complete the tutorial's coverage of the dialect's capabilities and directly address the stated PR objectives.

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

In `@docs/mlir/GettingStarted.md` around lines 142 - 349, Add a new subsection
after the Quantum Dialects section that provides (1) an scf.for example showing
loop-carried SSA qubit values with qco.alloc/qco.yield to demonstrate linear
typing across iterations (reference scf.for, qco.yield, loop-carried
entry-arguments), (2) an scf.if example that conditionally applies gates based
on a measurement result showing separate SSA branches and how to merge results
without re-using values (reference scf.if, qco.measure, qco.yield), and (3) a
multi-function example that defines a helper function taking and returning
qubits and shows a call site to illustrate function parameter/return semantics
under linear typing (reference the function declaration/call symbols used in the
doc); briefly annotate each example with one sentence explaining how linear
typing is preserved (use scf.yield and explicit entry-arguments to avoid
variable re-use).

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.

♻️ Duplicate comments (4)
docs/mlir/GettingStarted.md (4)

442-442: ⚠️ Potential issue | 🟡 Minor

Add closing content or remove the empty "Conclusion" heading.

The "Conclusion" heading has no content, leaving the guide without proper closure. Either add a brief 2-3 sentence summary (e.g., recap the key takeaways: understanding QC vs QCO dialects, using mqt-cc for optimization, emitting QIR for execution) or remove the heading entirely.

✍️ Suggested conclusion text
## Conclusion

You now have a foundation for working with the MQT Compiler Collection. You've learned the differences between the QC and QCO dialects, explored how value semantics and linear typing enable powerful optimizations, and seen how to use `mqt-cc` to optimize quantum programs and emit QIR for execution. For more details on the dialects and available passes, refer to the [QC](./QC.md) and [QCO](./QCO.md) documentation.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/mlir/GettingStarted.md` at line 442, The "## Conclusion" heading is
empty; either remove that heading or add a brief 2–3 sentence closing paragraph
under "## Conclusion" that recaps key takeaways (differences between the QC and
QCO dialects, value semantics/linear typing enabling optimizations, using
`mqt-cc` to optimize and emit QIR) and adds links to the QC and QCO docs (e.g.,
reference ./QC.md and ./QCO.md); update the GettingStarted.md by replacing the
empty heading with this short summary or deleting the heading entirely.

352-365: 🧹 Nitpick | 🔵 Trivial

Consider adding a brief "Current Limitations" note.

The compilation flow description is clear and the diagram is helpful. However, based on learnings, the QC↔QCO conversions currently have specific constraints (e.g., limited multi-function support patterns, container-typed qubit flow restrictions, scf operation constraints). Consider adding a brief "Current Limitations" note or a link to more detailed documentation so readers attempting complex multi-function or control-flow programs understand the current boundaries.

📋 Suggested limitation note

Add a note before or after the diagram:

**Note:** The current QC↔QCO conversion has some limitations. For example, multi-function programs with qubit parameters and complex control-flow patterns (mixing `scf` operations with container-typed qubits) may require specific patterns. Refer to the [QC](./QC.md) and [QCO](./QCO.md) dialect documentation for details on supported constructs.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/mlir/GettingStarted.md` around lines 352 - 365, Add a short "Current
Limitations" note adjacent to the compilation flow diagram in GettingStarted.md
explaining that QC↔QCO conversions have constraints (e.g., limited
multi-function patterns with qubit parameters, container-typed qubit flow
restrictions, and scf operation interop limits) and point readers to the QC and
QCO dialect docs for details (suggested phrasing: a one-paragraph note
referencing ./QC.md and ./QCO.md); place this note immediately before or after
the embedded compilation-pipeline.svg block so readers see the limitation caveat
when viewing the flow.

148-351: ⚠️ Potential issue | 🟠 Major

Add required advanced constructs to complete PR objectives.

The Quantum Dialects section provides excellent QC vs. QCO comparisons and clearly explains value/reference semantics and linear typing. However, the PR objectives explicitly require coverage of advanced constructs that are currently missing:

"Cover advanced constructs beyond simple gates: demonstrate multiple functions and discuss interaction of control-flow (scf.for, scf.if) with quantum blocks, emphasizing SSA and linear-type considerations in QCO (use scf.yield and entry-arguments to avoid variable reuse)."

Missing content:

  1. scf.for with quantum operations: Show loop-carried SSA qubit values demonstrating how linear typing works across iterations
  2. scf.if with quantum operations: Show conditional quantum operations with separate SSA branches and how to merge results without reusing values
  3. Multi-function examples: Show helper functions with qubit parameters/returns to illustrate function call semantics under linear typing

These examples are essential for readers to understand how the QCO dialect handles real-world quantum programs with control flow and modularity.

Suggested additions (consider adding a new subsection "Advanced Constructs" after line 349):

📚 Recommended structure for advanced constructs subsection

Add a new subsection covering:

Control Flow with Quantum Operations (scf.for):

  • Example: applying a gate N times in a loop
  • Show how loop-carried variables work with qco.alloc, qco.yield, and entry-arguments
  • Annotate how linear typing is preserved across iterations

Conditional Quantum Operations (scf.if):

  • Example: conditionally applying gates based on measurement outcomes
  • Show separate SSA branches and merging results with qco.yield
  • Explain how to avoid variable reuse in branches

Multi-Function Programs:

  • Example: helper function that takes and returns qubits
  • Show function declaration with qubit parameters
  • Show call site demonstrating function call/return under linear typing

Each example should include 1-2 sentences explaining how linear typing constraints are satisfied.

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

In `@docs/mlir/GettingStarted.md` around lines 148 - 351, The Advanced Constructs
requirement is missing: add a new "Advanced Constructs" subsection after the
Quantum Dialects examples that demonstrates scf.for, scf.if, and multi-function
examples with QCO to show SSA/linear-typing across control flow and calls.
Concretely, include (1) an scf.for example that uses a loop-carried qubit value
(use qco.alloc at entry, thread the qubit through loop iterations via scf.for
region arguments and qco.yield to show linear typing across iterations), (2) an
scf.if example that measures and conditionally applies gates with separate SSA
branches and merges results via qco.yield/entry-arguments (avoid reusing SSA
values), and (3) a small helper function example (declare a function taking and
returning !qco.qubit, call it and thread the returned SSA qubit) to illustrate
function-call semantics under linear typing; annotate each snippet with one or
two sentences explaining how qco.yield, entry-arguments, and SSA ensure linear
usage.

7-20: 🧹 Nitpick | 🔵 Trivial

Console prompt symbols don't match project documentation style.

The console code blocks use % as the shell prompt. Based on learnings, MQT Core documentation conventionally uses $ prompt symbols in console code blocks (e.g., $ uv pip install ... or $ cmake -Bbuild ...). Consider updating to $ for consistency across the documentation.

📝 Suggested prompt update
 ```console
-% cmake -Bbuild \
+$ cmake -Bbuild \
     -DMLIR_DIR=<path to MLIR> \
     -DLLVM_DIR=<path to LLVM> \
     -DCMAKE_BUILD_TYPE:STRING=Release \
     -DBUILD_MQT_CORE_MLIR=ON
-% cd build && cmake --build . --target mqt-cc
+$ cd build && cmake --build . --target mqt-cc

You can verify your build by running the following command. If everything worked correctly, it should print an usage message.

-% ./mlir/tools/mqt-cc/mqt-cc --help
+$ ./mlir/tools/mqt-cc/mqt-cc --help

Apply the same replacement at lines 393, 431, and 437.
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @docs/mlir/GettingStarted.md around lines 7 - 20, Replace the nonstandard
percent shell prompt (%) with the project's conventional dollar prompt ($)
inside the console code blocks: update the prompt for the cmake invocation
("cmake -Bbuild ... -DBUILD_MQT_CORE_MLIR=ON"), the build command ("cd build &&
cmake --build . --target mqt-cc"), and the verification command
("./mlir/tools/mqt-cc/mqt-cc --help"); then apply the same %→$ replacement to
the other console blocks containing those commands (the additional occurrences
mentioned in the review).


</details>

</blockquote></details>

</blockquote></details>

<details>
<summary>🤖 Prompt for all review comments with AI agents</summary>

Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In @docs/mlir/GettingStarted.md:

  • Line 442: The "## Conclusion" heading is empty; either remove that heading or
    add a brief 2–3 sentence closing paragraph under "## Conclusion" that recaps key
    takeaways (differences between the QC and QCO dialects, value semantics/linear
    typing enabling optimizations, using mqt-cc to optimize and emit QIR) and adds
    links to the QC and QCO docs (e.g., reference ./QC.md and ./QCO.md); update the
    GettingStarted.md by replacing the empty heading with this short summary or
    deleting the heading entirely.
  • Around line 352-365: Add a short "Current Limitations" note adjacent to the
    compilation flow diagram in GettingStarted.md explaining that QC↔QCO conversions
    have constraints (e.g., limited multi-function patterns with qubit parameters,
    container-typed qubit flow restrictions, and scf operation interop limits) and
    point readers to the QC and QCO dialect docs for details (suggested phrasing: a
    one-paragraph note referencing ./QC.md and ./QCO.md); place this note
    immediately before or after the embedded compilation-pipeline.svg block so
    readers see the limitation caveat when viewing the flow.
  • Around line 148-351: The Advanced Constructs requirement is missing: add a new
    "Advanced Constructs" subsection after the Quantum Dialects examples that
    demonstrates scf.for, scf.if, and multi-function examples with QCO to show
    SSA/linear-typing across control flow and calls. Concretely, include (1) an
    scf.for example that uses a loop-carried qubit value (use qco.alloc at entry,
    thread the qubit through loop iterations via scf.for region arguments and
    qco.yield to show linear typing across iterations), (2) an scf.if example that
    measures and conditionally applies gates with separate SSA branches and merges
    results via qco.yield/entry-arguments (avoid reusing SSA values), and (3) a
    small helper function example (declare a function taking and returning
    !qco.qubit, call it and thread the returned SSA qubit) to illustrate
    function-call semantics under linear typing; annotate each snippet with one or
    two sentences explaining how qco.yield, entry-arguments, and SSA ensure linear
    usage.
  • Around line 7-20: Replace the nonstandard percent shell prompt (%) with the
    project's conventional dollar prompt ($) inside the console code blocks: update
    the prompt for the cmake invocation ("cmake -Bbuild ...
    -DBUILD_MQT_CORE_MLIR=ON"), the build command ("cd build && cmake --build .
    --target mqt-cc"), and the verification command ("./mlir/tools/mqt-cc/mqt-cc
    --help"); then apply the same %→$ replacement to the other console blocks
    containing those commands (the additional occurrences mentioned in the review).

</details>

---

<details>
<summary>ℹ️ Review info</summary>

<details>
<summary>⚙️ Run configuration</summary>

**Configuration used**: Organization UI

**Review profile**: ASSERTIVE

**Plan**: Pro

**Run ID**: `a0e03394-5f02-488e-9483-b8722bd852bd`

</details>

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 0b25cef4c2eac8ff8638dcd2d2990af47022c3bf and 6caf32718c0929680980b552d0695a9c7b6fb62d.

</details>

<details>
<summary>⛔ Files ignored due to path filters (1)</summary>

* `docs/_static/compilation-pipeline.svg` is excluded by `!**/*.svg`

</details>

<details>
<summary>📒 Files selected for processing (1)</summary>

* `docs/mlir/GettingStarted.md`

</details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->

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.

♻️ Duplicate comments (4)
docs/mlir/GettingStarted.md (4)

294-294: ⚠️ Potential issue | 🔴 Critical

Fix non-breaking space in the MyST {code-block} directive.

At Line 294, {code-block} mlir contains a non-ASCII NBSP between } and mlir, which can break directive parsing in some doc toolchains. Replace it with a normal ASCII space.

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

In `@docs/mlir/GettingStarted.md` at line 294, The `{code-block}` MyST directive
contains a non-breaking space between the closing brace and the language token
(the snippet appears as "```{code-block} mlir"); locate that directive and
replace the NBSP with a normal ASCII space so it reads "```{code-block} mlir" to
avoid parsing issues in doc toolchains.

470-470: ⚠️ Potential issue | 🟡 Minor

Complete or remove the empty Conclusion section.

At Line 470, ## Conclusion is empty, leaving the guide without a closeout. Add a short summary paragraph or remove the heading.

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

In `@docs/mlir/GettingStarted.md` at line 470, The "## Conclusion" heading in
GettingStarted.md is empty; either remove the "## Conclusion" line entirely or
add a brief closing paragraph under the "## Conclusion" heading that summarizes
the guide and next steps; update the section titled "## Conclusion" accordingly
so the document no longer contains an empty heading.

176-379: ⚠️ Potential issue | 🟠 Major

PR objective gap: advanced quantum control-flow and multi-function examples are still missing.

This section still lacks dedicated examples for quantum scf.for, quantum scf.if, and a multi-function qubit flow with explicit linear-typing handling (scf.yield / entry arguments), which are required by the linked objective.

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

In `@docs/mlir/GettingStarted.md` around lines 176 - 379, The docs section is
missing examples for quantum control-flow and multi-function linear-typed flows;
add compact MLIR snippets demonstrating scf.for, scf.if, and a multi-function
example that uses scf.yield and function entry arguments to show explicit linear
typing and qubit SSA flow (reference the QCO dialect operations like qco.alloc,
qco.dealloc, qco.ctrl, qco.h, qco.measure plus scf.for/scf.if/scf.yield and
function signatures) so readers can see how control flow and inter-function
qubit passing respect value semantics and linear usage; place them near the
existing QCO examples and ensure each snippet highlights the linear-typing rules
(each SSA qubit used exactly once) and use of scf.yield to return updated qubit
values.

395-397: ⚠️ Potential issue | 🟠 Major

Add a short “Current limitations” note before the tool examples.

Before Line 395, add a concise limitations block for current QC→QCO, function-like, and scf boundaries so readers do not overgeneralize support from the examples.

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

In `@docs/mlir/GettingStarted.md` around lines 395 - 397, Add a short "Current
limitations" note immediately before the "## Examples Using the MQT Compiler
Collection Tool" header that briefly calls out the known limitations for QC→QCO
translation, function-like constructs, and scf region boundaries so readers
don't overgeneralize from the examples; keep it concise (1–3 sentences or a
3-line bullet list) and mention: QC→QCO mappings are partial, function-like
entities may not be fully preserved/Lowered, and scf regions/loops have limited
handling/edge-case support.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@docs/mlir/GettingStarted.md`:
- Line 294: The `{code-block}` MyST directive contains a non-breaking space
between the closing brace and the language token (the snippet appears as
"```{code-block} mlir"); locate that directive and replace the NBSP with a
normal ASCII space so it reads "```{code-block} mlir" to avoid parsing issues in
doc toolchains.
- Line 470: The "## Conclusion" heading in GettingStarted.md is empty; either
remove the "## Conclusion" line entirely or add a brief closing paragraph under
the "## Conclusion" heading that summarizes the guide and next steps; update the
section titled "## Conclusion" accordingly so the document no longer contains an
empty heading.
- Around line 176-379: The docs section is missing examples for quantum
control-flow and multi-function linear-typed flows; add compact MLIR snippets
demonstrating scf.for, scf.if, and a multi-function example that uses scf.yield
and function entry arguments to show explicit linear typing and qubit SSA flow
(reference the QCO dialect operations like qco.alloc, qco.dealloc, qco.ctrl,
qco.h, qco.measure plus scf.for/scf.if/scf.yield and function signatures) so
readers can see how control flow and inter-function qubit passing respect value
semantics and linear usage; place them near the existing QCO examples and ensure
each snippet highlights the linear-typing rules (each SSA qubit used exactly
once) and use of scf.yield to return updated qubit values.
- Around line 395-397: Add a short "Current limitations" note immediately before
the "## Examples Using the MQT Compiler Collection Tool" header that briefly
calls out the known limitations for QC→QCO translation, function-like
constructs, and scf region boundaries so readers don't overgeneralize from the
examples; keep it concise (1–3 sentences or a 3-line bullet list) and mention:
QC→QCO mappings are partial, function-like entities may not be fully
preserved/Lowered, and scf regions/loops have limited handling/edge-case
support.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 75a98cd7-106b-4785-a6a4-3d120be55e05

📥 Commits

Reviewing files that changed from the base of the PR and between 6caf327 and de49d82.

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

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

Labels

documentation Improvements or additions to documentation MLIR Anything related to MLIR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

📝 MLIR - Getting Started Guide

3 participants