Skip to content

Commit

Permalink
RIR SSA check pass (#1358)
Browse files Browse the repository at this point in the history
This pass checks that the RIR is in Single Static Assignment (SSA) form.
The check verifies that each variable is assigned exactly once before it
is used, and that phi nodes are used correctly.

The change also updates how successors are calculated for branch
instructions that have constant conditions, and updates the tests that
used constant conditions to use dynamic bool values instead.
  • Loading branch information
swernli authored Apr 4, 2024
1 parent 597c39b commit f5b4cb5
Show file tree
Hide file tree
Showing 9 changed files with 1,338 additions and 76 deletions.
20 changes: 20 additions & 0 deletions compiler/qsc_rir/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,24 @@ pub fn array_record_decl() -> Callable {
}
}

/// Creates a new program with a single, entry callable that has block 0 as its body.
#[must_use]
pub fn new_program() -> Program {
let mut program = Program::new();
program.entry = CallableId(0);
program.callables.insert(
CallableId(0),
Callable {
name: "main".to_string(),
input_type: Vec::new(),
output_type: None,
body: Some(BlockId(0)),
call_type: CallableType::Regular,
},
);
program
}

#[must_use]
pub fn bell_program() -> Program {
let mut program = Program::default();
Expand All @@ -147,6 +165,7 @@ pub fn bell_program() -> Program {
call_type: CallableType::Regular,
},
);
program.entry = CallableId(5);
program.blocks.insert(
BlockId(0),
Block(vec![
Expand Down Expand Up @@ -236,6 +255,7 @@ pub fn teleport_program() -> Program {
call_type: CallableType::Regular,
},
);
program.entry = CallableId(7);
program.blocks.insert(
BlockId(0),
Block(vec![
Expand Down
2 changes: 2 additions & 0 deletions compiler/qsc_rir/src/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ mod build_dominator_graph;
mod defer_meas;
mod reindex_qubits;
mod remap_block_ids;
mod ssa_check;
mod unreachable_code_check;

pub use build_dominator_graph::build_dominator_graph;
pub use defer_meas::defer_measurements;
pub use reindex_qubits::reindex_qubits;
pub use remap_block_ids::remap_block_ids;
pub use ssa_check::check_ssa_form;
pub use unreachable_code_check::check_unreachable_code;
13 changes: 5 additions & 8 deletions compiler/qsc_rir/src/passes/build_dominator_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@

use qsc_data_structures::index_map::IndexMap;

use crate::{
rir::{BlockId, Program},
utils::build_predecessors_map,
};
use crate::rir::{BlockId, Program};

#[cfg(test)]
mod tests;
Expand All @@ -19,16 +16,16 @@ mod tests;
/// - Blocks are assumed to be sequentially numbered starting from 0 in reverse postorder rather than depth first order.
/// - Given that reversal, intersection between nodes uses the lesser of the two nodes rather than the greater.
#[must_use]
pub fn build_dominator_graph(program: &Program) -> IndexMap<BlockId, BlockId> {
pub fn build_dominator_graph(
program: &Program,
preds: &IndexMap<BlockId, Vec<BlockId>>,
) -> IndexMap<BlockId, BlockId> {
let mut doms = IndexMap::default();
let entry_block_id = program
.get_callable(program.entry)
.body
.expect("entry point should have a body");

// Predecessors are needed to compute the dominator tree.
let preds = build_predecessors_map(program);

// The entry block dominates itself.
doms.insert(entry_block_id, entry_block_id);

Expand Down
Loading

0 comments on commit f5b4cb5

Please sign in to comment.