diff --git a/Cargo.lock b/Cargo.lock index 1b9b7d25..21a07046 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -453,6 +453,12 @@ dependencies = [ "syn", ] +[[package]] +name = "dissimilar" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8975ffdaa0ef3661bfe02dbdcc06c9f829dfafe6a3c474de366a8d5e44276921" + [[package]] name = "either" version = "1.15.0" @@ -496,6 +502,16 @@ dependencies = [ "windows-sys 0.61.1", ] +[[package]] +name = "expect-test" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63af43ff4431e848fb47472a920f14fa71c24de13255a5692e93d4e90302acb0" +dependencies = [ + "dissimilar", + "once_cell", +] + [[package]] name = "fallible-iterator" version = "0.3.0" @@ -1137,6 +1153,7 @@ dependencies = [ name = "mchprs" version = "0.4.1" dependencies = [ + "expect-test", "mchprs_blocks", "mchprs_core", "mchprs_redpiler", diff --git a/Cargo.toml b/Cargo.toml index 01649bf9..25a46951 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,6 +46,7 @@ mchprs_blocks = { path = "./crates/blocks" } mchprs_redpiler = { path = "./crates/redpiler" } mchprs_redstone = { path = "./crates/redstone" } paste = { workspace = true } +expect-test = { workspace = true } [workspace.dependencies] toml = "0.8" @@ -86,3 +87,4 @@ tracing-appender = "0.2" paste = "1.0" chrono = "0.4" clap = { version = "4.5", features = ["derive"] } +expect-test = "1.5" diff --git a/crates/redpiler/src/lib.rs b/crates/redpiler/src/lib.rs index 36d3c162..0f5162db 100644 --- a/crates/redpiler/src/lib.rs +++ b/crates/redpiler/src/lib.rs @@ -5,16 +5,21 @@ mod ril; mod task_monitor; use backend::{BackendDispatcher, JITBackend}; + use mchprs_blocks::blocks::Block; use mchprs_blocks::BlockPos; use mchprs_world::{for_each_block_mut_optimized, TickEntry, World}; -use passes::make_default_pass_manager; + use std::sync::Arc; use std::time::Instant; use tracing::{debug, error, trace, warn}; pub use task_monitor::TaskMonitor; +pub use compile_graph::*; +pub use passes::PassManager; +pub use ril::DumpGraph; + fn block_powered_mut(block: &mut Block) -> Option<&mut bool> { Some(match block { Block::RedstoneComparator { comparator } => &mut comparator.powered, @@ -136,7 +141,7 @@ impl Compiler { let start = Instant::now(); let input = CompilerInput { world, bounds }; - let pass_manager = make_default_pass_manager::(); + let pass_manager = PassManager::default(); let graph = pass_manager.run_passes(&options, &input, monitor.clone()); if monitor.cancelled() { diff --git a/crates/redpiler/src/passes/mod.rs b/crates/redpiler/src/passes/mod.rs index 07dbb4d1..922780df 100644 --- a/crates/redpiler/src/passes/mod.rs +++ b/crates/redpiler/src/passes/mod.rs @@ -23,22 +23,6 @@ use std::sync::Arc; use std::time::Instant; use tracing::{debug, trace}; -pub const fn make_default_pass_manager<'w, W: World>() -> PassManager<'w, W> { - PassManager::new(&[ - &identify_nodes::IdentifyNodes, - &input_search::InputSearch, - &clamp_weights::ClampWeights, - &dedup_links::DedupLinks, - &constant_fold::ConstantFold, - &analysis::ss_range_analysis::SSRangeAnalysis, - &unreachable_output::UnreachableOutput, - &constant_coalesce::ConstantCoalesce, - &coalesce::Coalesce, - &prune_orphans::PruneOrphans, - &export_graph::ExportGraph, - ]) -} - pub trait AnalysisInfo: Any {} #[derive(Default)] @@ -64,6 +48,24 @@ pub struct PassManager<'p, W: World> { passes: &'p [&'p dyn Pass], } +impl<'p, W: World> Default for PassManager<'p, W> { + fn default() -> Self { + Self::new(&[ + &identify_nodes::IdentifyNodes, + &input_search::InputSearch, + &clamp_weights::ClampWeights, + &dedup_links::DedupLinks, + &constant_fold::ConstantFold, + &analysis::ss_range_analysis::SSRangeAnalysis, + &unreachable_output::UnreachableOutput, + &constant_coalesce::ConstantCoalesce, + &coalesce::Coalesce, + &prune_orphans::PruneOrphans, + &export_graph::ExportGraph, + ]) + } +} + impl<'p, W: World> PassManager<'p, W> { pub const fn new(passes: &'p [&dyn Pass]) -> Self { Self { passes } @@ -106,13 +108,13 @@ impl<'p, W: World> PassManager<'p, W> { if options.print_after_all { debug!("Printing circuit after pass: {}", pass.name()); - graph.dump(); + graph.dump_to_stderr(); } } if options.print_before_backend { debug!("Printing circuit before backend compile:"); - graph.dump(); + graph.dump_to_stderr(); } graph diff --git a/crates/redpiler/src/ril.rs b/crates/redpiler/src/ril.rs index f989326f..ae1b35aa 100644 --- a/crates/redpiler/src/ril.rs +++ b/crates/redpiler/src/ril.rs @@ -227,13 +227,18 @@ impl<'a> fmt::Display for GraphDumper<'a> { } pub trait DumpGraph { - fn dump(&self); + fn dump_to_stderr(&self); + fn dump_to_string(&self) -> String; } impl DumpGraph for CompileGraph { - fn dump(&self) { + fn dump_to_stderr(&self) { eprintln!("{}", GraphDumper { graph: self }); } + + fn dump_to_string(&self) -> String { + format!("{}", GraphDumper { graph: self }) + } } #[derive(Clone, Copy, PartialEq, Eq, Debug)] diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 3e711fe1..5064cd65 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -31,6 +31,11 @@ impl TestWorld { } } + pub fn bounds(&self) -> (BlockPos, BlockPos) { + let max_coord = self.size * 16 - 1; + (pos(0, 0, 0), pos(max_coord, max_coord, max_coord)) + } + fn get_chunk_index_for_chunk(&self, chunk_x: i32, chunk_z: i32) -> usize { (chunk_x * self.size + chunk_z).unsigned_abs() as usize } diff --git a/tests/frontend.rs b/tests/frontend.rs new file mode 100644 index 00000000..60ec245b --- /dev/null +++ b/tests/frontend.rs @@ -0,0 +1,296 @@ +mod common; +use common::*; + +use expect_test::expect_file; + +use mchprs_blocks::{ + blocks::{Block, ComparatorMode, Lever, LeverFace}, + BlockDirection, +}; +use mchprs_redpiler::{CompilerInput, CompilerOptions, DumpGraph, PassManager}; +use mchprs_world::{TickPriority, World}; + +enum OptLevel { + Unoptimized, + Optimized, +} + +fn test_frontend(world: &TestWorld, expected_ril: expect_test::ExpectFile, opt_level: OptLevel) { + let compile_options = match opt_level { + OptLevel::Unoptimized => CompilerOptions { + optimize: false, + ..Default::default() + }, + OptLevel::Optimized => CompilerOptions { + optimize: true, + io_only: true, + ..Default::default() + }, + }; + let pass_manager = PassManager::default(); + let graph = pass_manager.run_passes( + &compile_options, + &CompilerInput { + world, + bounds: world.bounds(), + }, + Default::default(), + ); + let ril = graph.dump_to_string(); + expected_ril.assert_eq(&ril); +} + +const SANDSTONE: Block = Block::Sandstone {}; +const REDSTONE_BLOCK: Block = Block::RedstoneBlock {}; + +const REDSTONE_LAMP_UNLIT: Block = Block::RedstoneLamp { lit: false }; +const REDSTONE_LAMP_LIT: Block = Block::RedstoneLamp { lit: true }; + +const LEVER_GROUND_DEACTIVATED: Block = Block::Lever { + lever: Lever { + face: LeverFace::Floor, + facing: BlockDirection::North, + powered: false, + }, +}; + +const TORCH_GROUND_UNLIT: Block = Block::RedstoneTorch { lit: false }; +const TORCH_GROUND_LIT: Block = Block::RedstoneTorch { lit: true }; + +#[test] +fn lever_on_constantly_powered_lamp() { + let mut world = TestWorld::new(1); + world.set_block(pos(0, 0, 0), REDSTONE_BLOCK); + world.set_block(pos(0, 1, 0), REDSTONE_LAMP_LIT); + world.set_block(pos(0, 2, 0), LEVER_GROUND_DEACTIVATED); + + // Unoptimized + let expected = expect_file!["test_expects/lever_on_constantly_powered_lamp_UNOPTIMIZED"]; + test_frontend(&world, expected, OptLevel::Unoptimized); + + // Optimized + // TODO: Missed optimization: + // The lever has no effect on the lamp. + let expected = expect_file!["test_expects/lever_on_constantly_powered_lamp_OPTIMIZED"]; + test_frontend(&world, expected, OptLevel::Optimized); +} + +#[test] +fn lit_torch_with_no_inputs() { + let mut world = TestWorld::new(1); + world.set_block(pos(0, 0, 0), SANDSTONE); + world.set_block(pos(0, 1, 0), TORCH_GROUND_LIT); + world.set_block(pos(0, 2, 0), REDSTONE_LAMP_LIT); + + // Unoptimized + let expected = expect_file!["test_expects/lit_torch_with_no_inputs_UNOPTIMIZED"]; + test_frontend(&world, expected, OptLevel::Unoptimized); + + // Optimized + let expected = expect_file!["test_expects/lit_torch_with_no_inputs_OPTIMIZED"]; + test_frontend(&world, expected, OptLevel::Optimized); +} + +#[test] +fn unlit_torch_on_redstone_block() { + let mut world = TestWorld::new(1); + world.set_block(pos(0, 0, 0), REDSTONE_BLOCK); + world.set_block(pos(0, 1, 0), TORCH_GROUND_UNLIT); + world.set_block(pos(0, 2, 0), REDSTONE_LAMP_UNLIT); + + // Unoptimized + let expected = expect_file!["test_expects/unlit_torch_on_redstone_block_UNOPTIMIZED"]; + test_frontend(&world, expected, OptLevel::Unoptimized); + + // Optimized + let expected = expect_file!["test_expects/unlit_torch_on_redstone_block_OPTIMIZED"]; + test_frontend(&world, expected, OptLevel::Optimized); +} + +#[test] +fn lever_with_many_edges_to_same_lamp() { + let mut world = TestWorld::new(1); + world.set_block(pos(1, 1, 1), REDSTONE_LAMP_UNLIT); + world.set_block(pos(1, 2, 1), LEVER_GROUND_DEACTIVATED); + make_wire(&mut world, pos(0, 1, 1)); + make_wire(&mut world, pos(1, 1, 0)); + make_wire(&mut world, pos(2, 1, 1)); + make_wire(&mut world, pos(1, 1, 2)); + + // Unoptimized + let expected = expect_file!["test_expects/lever_with_many_edges_to_same_lamp_UNOPTIMIZED"]; + test_frontend(&world, expected, OptLevel::Unoptimized); + + // Optimized + let expected = expect_file!["test_expects/lever_with_many_edges_to_same_lamp_OPTIMIZED"]; + test_frontend(&world, expected, OptLevel::Optimized); +} + +#[test] +fn long_redstone_wire() { + let mut world = TestWorld::new(2); + make_lever(&mut world, pos(0, 1, 0)); + world.set_block(pos(0, 1, 20), REDSTONE_LAMP_UNLIT); + for z in 1..20 { + make_wire(&mut world, pos(0, 1, z)); + } + + // Unoptimized + let expected = expect_file!["test_expects/long_redstone_wire_UNOPTIMIZED"]; + test_frontend(&world, expected, OptLevel::Unoptimized); + + // Optimized + let expected = expect_file!["test_expects/long_redstone_wire_OPTIMIZED"]; + test_frontend(&world, expected, OptLevel::Optimized); +} + +#[test] +fn long_redstone_wire_with_comparator() { + let mut world = TestWorld::new(1); + make_lever(&mut world, pos(0, 1, 0)); + for z in 1..10 { + make_wire(&mut world, pos(0, 1, z)); + } + make_comparator( + &mut world, + pos(0, 1, 10), + ComparatorMode::Compare, + BlockDirection::North, + ); + for z in 11..20 { + make_wire(&mut world, pos(0, 1, z)); + } + world.set_block(pos(0, 1, 20), REDSTONE_LAMP_UNLIT); + + // Unoptimized + // FIXME: Unoptimized mode should not be removing edges. + let expected = expect_file!["test_expects/long_redstone_wire_with_comparator_UNOPTIMIZED"]; + test_frontend(&world, expected, OptLevel::Unoptimized); + + // Optimized + let expected = expect_file!["test_expects/long_redstone_wire_with_comparator_OPTIMIZED"]; + test_frontend(&world, expected, OptLevel::Optimized); +} + +#[test] +fn unpowered_repeater_clock() { + let mut world = TestWorld::new(1); + make_wire(&mut world, pos(0, 1, 0)); + make_repeater(&mut world, pos(0, 1, 1), 1, BlockDirection::East); + world.set_block(pos(0, 1, 2), REDSTONE_LAMP_UNLIT); + make_wire(&mut world, pos(1, 1, 2)); + make_repeater(&mut world, pos(1, 1, 1), 1, BlockDirection::West); + world.set_block(pos(1, 1, 0), REDSTONE_LAMP_UNLIT); + + // Unoptimized + let expected = expect_file!["test_expects/unpowered_repeater_clock_UNOPTIMIZED"]; + test_frontend(&world, expected, OptLevel::Unoptimized); + + // Optimized + let expected = expect_file!["test_expects/unpowered_repeater_clock_OPTIMIZED"]; + test_frontend(&world, expected, OptLevel::Optimized); +} + +#[test] +fn repeater_clock_duplicated_repeaters() { + // L W W W W W W + // RN RN RN RS RS RS + // L W W W W W W + let mut world = TestWorld::new(1); + make_lever(&mut world, pos(0, 1, 0)); + world.set_block(pos(0, 0, 2), REDSTONE_LAMP_UNLIT); + for x in 1..7 { + let repeater_direction = match x { + ..4 => BlockDirection::North, + _ => BlockDirection::South, + }; + make_wire(&mut world, pos(x, 1, 0)); + make_repeater(&mut world, pos(x, 1, 1), 1, repeater_direction); + make_wire(&mut world, pos(x, 1, 2)); + } + + // Unoptimized + let expected = expect_file!["test_expects/repeater_clock_duplicated_repeaters_UNOPTIMIZED"]; + test_frontend(&world, expected, OptLevel::Unoptimized); + + // Optimized + // TODO: Missed optimization: + // A lot of redundant edges. + let expected = expect_file!["test_expects/repeater_clock_duplicated_repeaters_OPTIMIZED"]; + test_frontend(&world, expected, OptLevel::Optimized); +} + +#[test] +fn compare_mode_full_ss_rear_input() { + let mut world = TestWorld::new(1); + world.set_block(pos(0, 1, 0), REDSTONE_LAMP_UNLIT); + make_comparator( + &mut world, + pos(0, 1, 1), + ComparatorMode::Compare, + BlockDirection::South, + ); + make_wire(&mut world, pos(0, 1, 2)); + make_lever(&mut world, pos(0, 1, 3)); // rear input + make_repeater(&mut world, pos(1, 1, 1), 1, BlockDirection::East); + make_lever(&mut world, pos(2, 1, 1)); // side input + + // Unoptimized + let expected = expect_file!["test_expects/compare_mode_full_ss_rear_input_UNOPTIMIZED"]; + test_frontend(&world, expected, OptLevel::Unoptimized); + + // Optimized + // TODO: Missed optimization: + // The side input of the comparator has no effect on the comparator. + let expected = expect_file!["test_expects/compare_mode_full_ss_rear_input_OPTIMIZED"]; + test_frontend(&world, expected, OptLevel::Optimized); +} + +#[test] +fn repeater_chain_with_pending_update() { + let mut world = TestWorld::new(1); + world.set_block(pos(0, 1, 0), REDSTONE_BLOCK); + make_repeater(&mut world, pos(1, 1, 0), 1, BlockDirection::West); + make_repeater(&mut world, pos(2, 1, 0), 1, BlockDirection::West); + world.set_block(pos(3, 1, 0), REDSTONE_LAMP_UNLIT); + // schedule an update for the first repeater + world.schedule_tick(pos(1, 1, 0), 1, TickPriority::Normal); + + // Unoptimized + let expected = expect_file!["test_expects/repeater_chain_with_pending_update_UNOPTIMIZED"]; + test_frontend(&world, expected, OptLevel::Unoptimized); + + // Optimized + // FIXME: Illegal optimization: + // The repeaters must not be optimized away because they become powered in the next ticks. + let expected = expect_file!["test_expects/repeater_chain_with_pending_update_OPTIMIZED"]; + test_frontend(&world, expected, OptLevel::Optimized); +} + +#[test] +fn multiple_different_constants() { + let mut world = TestWorld::new(1); + for x in 0..4 { + make_wire(&mut world, pos(x, 1, 1)); + } + world.set_block(pos(0, 1, 0), REDSTONE_BLOCK); + world.set_block(pos(2, 1, 0), REDSTONE_BLOCK); + world.set_block(pos(4, 1, 0), REDSTONE_LAMP_UNLIT); + make_comparator( + &mut world, + pos(4, 1, 1), + ComparatorMode::Subtract, + BlockDirection::South, + ); + make_lever(&mut world, pos(4, 1, 2)); + + // Unoptimized + let expected = expect_file!["test_expects/multiple_different_constants_UNOPTIMIZED"]; + test_frontend(&world, expected, OptLevel::Unoptimized); + + // Optimized + // TODO: Missed optimization: + // Redundant edge from constant to comparator. + let expected = expect_file!["test_expects/multiple_different_constants_OPTIMIZED"]; + test_frontend(&world, expected, OptLevel::Optimized); +} diff --git a/tests/test_expects/compare_mode_full_ss_rear_input_OPTIMIZED b/tests/test_expects/compare_mode_full_ss_rear_input_OPTIMIZED new file mode 100644 index 00000000..6d7b4e5e --- /dev/null +++ b/tests/test_expects/compare_mode_full_ss_rear_input_OPTIMIZED @@ -0,0 +1,7 @@ +circuit { + %0 = lamp false, [%1:0] # Loc: (0, 1, 0) + %1 = comparator compare, none, false, 0, [%2:0], [%3:0] # Loc: (0, 1, 1) + %2 = lever false # Loc: (0, 1, 3) + %3 = repeater 1, true, false, false, [%4:0], [] # Loc: (1, 1, 1) + %4 = lever false # Loc: (2, 1, 1) +} \ No newline at end of file diff --git a/tests/test_expects/compare_mode_full_ss_rear_input_UNOPTIMIZED b/tests/test_expects/compare_mode_full_ss_rear_input_UNOPTIMIZED new file mode 100644 index 00000000..a7dc6202 --- /dev/null +++ b/tests/test_expects/compare_mode_full_ss_rear_input_UNOPTIMIZED @@ -0,0 +1,8 @@ +circuit { + %0 = lamp false, [%1:0] # Loc: (0, 1, 0) + %1 = comparator compare, none, false, 0, [%3:0], [%4:0] # Loc: (0, 1, 1) + %2 = wire 0, [%3:0] # Loc: (0, 1, 2) + %3 = lever false # Loc: (0, 1, 3) + %4 = repeater 1, true, false, false, [%5:0], [] # Loc: (1, 1, 1) + %5 = lever false # Loc: (2, 1, 1) +} \ No newline at end of file diff --git a/tests/test_expects/lever_on_constantly_powered_lamp_OPTIMIZED b/tests/test_expects/lever_on_constantly_powered_lamp_OPTIMIZED new file mode 100644 index 00000000..1ca7a29d --- /dev/null +++ b/tests/test_expects/lever_on_constantly_powered_lamp_OPTIMIZED @@ -0,0 +1,5 @@ +circuit { + %1 = lamp true, [%3:0, %2:0] # Loc: (0, 1, 0) + %2 = lever false # Loc: (0, 2, 0) + %3 = constant 15 +} \ No newline at end of file diff --git a/tests/test_expects/lever_on_constantly_powered_lamp_UNOPTIMIZED b/tests/test_expects/lever_on_constantly_powered_lamp_UNOPTIMIZED new file mode 100644 index 00000000..aa4f2fd7 --- /dev/null +++ b/tests/test_expects/lever_on_constantly_powered_lamp_UNOPTIMIZED @@ -0,0 +1,5 @@ +circuit { + %0 = constant 15 # Loc: (0, 0, 0) + %1 = lamp true, [%0:0, %2:0] # Loc: (0, 1, 0) + %2 = lever false # Loc: (0, 2, 0) +} \ No newline at end of file diff --git a/tests/test_expects/lever_with_many_edges_to_same_lamp_OPTIMIZED b/tests/test_expects/lever_with_many_edges_to_same_lamp_OPTIMIZED new file mode 100644 index 00000000..a0601fd3 --- /dev/null +++ b/tests/test_expects/lever_with_many_edges_to_same_lamp_OPTIMIZED @@ -0,0 +1,4 @@ +circuit { + %0 = lamp false, [%1:0] # Loc: (1, 1, 1) + %1 = lever false # Loc: (1, 2, 1) +} \ No newline at end of file diff --git a/tests/test_expects/lever_with_many_edges_to_same_lamp_UNOPTIMIZED b/tests/test_expects/lever_with_many_edges_to_same_lamp_UNOPTIMIZED new file mode 100644 index 00000000..66e6a0c3 --- /dev/null +++ b/tests/test_expects/lever_with_many_edges_to_same_lamp_UNOPTIMIZED @@ -0,0 +1,8 @@ +circuit { + %0 = wire 0, [%4:0] # Loc: (0, 1, 1) + %1 = wire 0, [%4:0] # Loc: (1, 1, 0) + %2 = lamp false, [%4:0, %4:0, %4:0, %4:0, %4:0] # Loc: (1, 1, 1) + %3 = wire 0, [%4:0] # Loc: (1, 1, 2) + %4 = lever false # Loc: (1, 2, 1) + %5 = wire 0, [%4:0] # Loc: (2, 1, 1) +} \ No newline at end of file diff --git a/tests/test_expects/lit_torch_with_no_inputs_OPTIMIZED b/tests/test_expects/lit_torch_with_no_inputs_OPTIMIZED new file mode 100644 index 00000000..c725ccf4 --- /dev/null +++ b/tests/test_expects/lit_torch_with_no_inputs_OPTIMIZED @@ -0,0 +1,4 @@ +circuit { + %1 = lamp true, [%2:0] # Loc: (0, 2, 0) + %2 = constant 15 +} \ No newline at end of file diff --git a/tests/test_expects/lit_torch_with_no_inputs_UNOPTIMIZED b/tests/test_expects/lit_torch_with_no_inputs_UNOPTIMIZED new file mode 100644 index 00000000..0c563faa --- /dev/null +++ b/tests/test_expects/lit_torch_with_no_inputs_UNOPTIMIZED @@ -0,0 +1,4 @@ +circuit { + %0 = torch true, [] # Loc: (0, 1, 0) + %1 = lamp true, [%0:0] # Loc: (0, 2, 0) +} \ No newline at end of file diff --git a/tests/test_expects/long_redstone_wire_OPTIMIZED b/tests/test_expects/long_redstone_wire_OPTIMIZED new file mode 100644 index 00000000..c9cf3ece --- /dev/null +++ b/tests/test_expects/long_redstone_wire_OPTIMIZED @@ -0,0 +1,4 @@ +circuit { + %0 = lever false # Loc: (0, 1, 0) + %1 = lamp false, [] # Loc: (0, 1, 20) +} \ No newline at end of file diff --git a/tests/test_expects/long_redstone_wire_UNOPTIMIZED b/tests/test_expects/long_redstone_wire_UNOPTIMIZED new file mode 100644 index 00000000..0acf3f77 --- /dev/null +++ b/tests/test_expects/long_redstone_wire_UNOPTIMIZED @@ -0,0 +1,23 @@ +circuit { + %0 = lever false # Loc: (0, 1, 0) + %1 = wire 0, [%0:0] # Loc: (0, 1, 1) + %2 = wire 0, [%0:1] # Loc: (0, 1, 2) + %3 = wire 0, [%0:2] # Loc: (0, 1, 3) + %4 = wire 0, [%0:3] # Loc: (0, 1, 4) + %5 = wire 0, [%0:4] # Loc: (0, 1, 5) + %6 = wire 0, [%0:5] # Loc: (0, 1, 6) + %7 = wire 0, [%0:6] # Loc: (0, 1, 7) + %8 = wire 0, [%0:7] # Loc: (0, 1, 8) + %9 = wire 0, [%0:8] # Loc: (0, 1, 9) + %10 = wire 0, [%0:9] # Loc: (0, 1, 10) + %11 = wire 0, [%0:10] # Loc: (0, 1, 11) + %12 = wire 0, [%0:11] # Loc: (0, 1, 12) + %13 = wire 0, [%0:12] # Loc: (0, 1, 13) + %14 = wire 0, [%0:13] # Loc: (0, 1, 14) + %15 = wire 0, [%0:14] # Loc: (0, 1, 15) + %16 = wire 0, [] # Loc: (0, 1, 16) + %17 = wire 0, [] # Loc: (0, 1, 17) + %18 = wire 0, [] # Loc: (0, 1, 18) + %19 = wire 0, [] # Loc: (0, 1, 19) + %20 = lamp false, [] # Loc: (0, 1, 20) +} \ No newline at end of file diff --git a/tests/test_expects/long_redstone_wire_with_comparator_OPTIMIZED b/tests/test_expects/long_redstone_wire_with_comparator_OPTIMIZED new file mode 100644 index 00000000..0cdbfed0 --- /dev/null +++ b/tests/test_expects/long_redstone_wire_with_comparator_OPTIMIZED @@ -0,0 +1,3 @@ +circuit { + %0 = lever false # Loc: (0, 1, 0) +} \ No newline at end of file diff --git a/tests/test_expects/long_redstone_wire_with_comparator_UNOPTIMIZED b/tests/test_expects/long_redstone_wire_with_comparator_UNOPTIMIZED new file mode 100644 index 00000000..6c5de5d3 --- /dev/null +++ b/tests/test_expects/long_redstone_wire_with_comparator_UNOPTIMIZED @@ -0,0 +1,18 @@ +circuit { + %0 = lever false # Loc: (0, 1, 0) + %1 = wire 0, [%0:0] # Loc: (0, 1, 1) + %2 = wire 0, [%0:1] # Loc: (0, 1, 2) + %3 = wire 0, [%0:2] # Loc: (0, 1, 3) + %4 = wire 0, [%0:3] # Loc: (0, 1, 4) + %5 = wire 0, [%0:4] # Loc: (0, 1, 5) + %6 = wire 0, [%0:5] # Loc: (0, 1, 6) + %7 = wire 0, [%0:6] # Loc: (0, 1, 7) + %8 = wire 0, [%0:7] # Loc: (0, 1, 8) + %9 = wire 0, [%0:8] # Loc: (0, 1, 9) + %10 = comparator compare, none, false, 0, [%0:8], [] # Loc: (0, 1, 10) + %11 = wire 0, [%10:0] # Loc: (0, 1, 11) + %12 = wire 0, [%10:1] # Loc: (0, 1, 12) + %13 = wire 0, [%10:2] # Loc: (0, 1, 13) + %14 = wire 0, [%10:3] # Loc: (0, 1, 14) + %15 = wire 0, [%10:4] # Loc: (0, 1, 15) +} \ No newline at end of file diff --git a/tests/test_expects/multiple_different_constants_OPTIMIZED b/tests/test_expects/multiple_different_constants_OPTIMIZED new file mode 100644 index 00000000..d56ff8df --- /dev/null +++ b/tests/test_expects/multiple_different_constants_OPTIMIZED @@ -0,0 +1,6 @@ +circuit { + %2 = lamp false, [%3:0] # Loc: (4, 1, 0) + %3 = comparator subtract, none, false, 0, [%4:0], [%5:1, %5:3] # Loc: (4, 1, 1) + %4 = lever false # Loc: (4, 1, 2) + %5 = constant 15 +} \ No newline at end of file diff --git a/tests/test_expects/multiple_different_constants_UNOPTIMIZED b/tests/test_expects/multiple_different_constants_UNOPTIMIZED new file mode 100644 index 00000000..e7419434 --- /dev/null +++ b/tests/test_expects/multiple_different_constants_UNOPTIMIZED @@ -0,0 +1,11 @@ +circuit { + %0 = constant 15 # Loc: (0, 1, 0) + %1 = wire 0, [%3:2, %0:0] # Loc: (0, 1, 1) + %2 = wire 0, [%0:1, %3:1] # Loc: (1, 1, 1) + %3 = constant 15 # Loc: (2, 1, 0) + %4 = wire 0, [%0:2, %3:0] # Loc: (2, 1, 1) + %5 = wire 0, [%0:3, %3:1] # Loc: (3, 1, 1) + %6 = lamp false, [%7:0] # Loc: (4, 1, 0) + %7 = comparator subtract, none, false, 0, [%8:0], [%0:3, %3:1] # Loc: (4, 1, 1) + %8 = lever false # Loc: (4, 1, 2) +} \ No newline at end of file diff --git a/tests/test_expects/repeater_chain_with_pending_update_OPTIMIZED b/tests/test_expects/repeater_chain_with_pending_update_OPTIMIZED new file mode 100644 index 00000000..40d6f5ce --- /dev/null +++ b/tests/test_expects/repeater_chain_with_pending_update_OPTIMIZED @@ -0,0 +1,4 @@ +circuit { + %1 = constant 15 + %3 = lamp false, [%1:0] # Loc: (3, 1, 0) +} \ No newline at end of file diff --git a/tests/test_expects/repeater_chain_with_pending_update_UNOPTIMIZED b/tests/test_expects/repeater_chain_with_pending_update_UNOPTIMIZED new file mode 100644 index 00000000..c17f8d87 --- /dev/null +++ b/tests/test_expects/repeater_chain_with_pending_update_UNOPTIMIZED @@ -0,0 +1,6 @@ +circuit { + %0 = constant 15 # Loc: (0, 1, 0) + %1 = repeater 1, true, false, false, [%0:0], [] # Loc: (1, 1, 0) + %2 = repeater 1, false, false, false, [%1:0], [] # Loc: (2, 1, 0) + %3 = lamp false, [%2:0] # Loc: (3, 1, 0) +} \ No newline at end of file diff --git a/tests/test_expects/repeater_clock_duplicated_repeaters_OPTIMIZED b/tests/test_expects/repeater_clock_duplicated_repeaters_OPTIMIZED new file mode 100644 index 00000000..011bcdef --- /dev/null +++ b/tests/test_expects/repeater_clock_duplicated_repeaters_OPTIMIZED @@ -0,0 +1,10 @@ +circuit { + %0 = lamp false, [%4:2, %3:1, %2:0] # Loc: (0, 0, 2) + %1 = lever false # Loc: (0, 1, 0) + %2 = repeater 1, false, false, false, [%7:5, %6:4, %5:3, %1:0], [] # Loc: (1, 1, 1) + %3 = repeater 1, false, false, false, [%7:4, %6:3, %5:2, %1:1], [] # Loc: (2, 1, 1) + %4 = repeater 1, false, false, false, [%7:3, %1:2, %6:2, %5:1], [] # Loc: (3, 1, 1) + %5 = repeater 1, false, false, false, [%2:3, %3:2, %4:1], [] # Loc: (4, 1, 1) + %6 = repeater 1, false, false, false, [%2:4, %3:3, %4:2], [] # Loc: (5, 1, 1) + %7 = repeater 1, false, false, false, [%2:5, %3:4, %4:3], [] # Loc: (6, 1, 1) +} \ No newline at end of file diff --git a/tests/test_expects/repeater_clock_duplicated_repeaters_UNOPTIMIZED b/tests/test_expects/repeater_clock_duplicated_repeaters_UNOPTIMIZED new file mode 100644 index 00000000..1b308cba --- /dev/null +++ b/tests/test_expects/repeater_clock_duplicated_repeaters_UNOPTIMIZED @@ -0,0 +1,22 @@ +circuit { + %0 = lamp false, [%9:2, %6:1, %3:0] # Loc: (0, 0, 2) + %1 = lever false # Loc: (0, 1, 0) + %2 = wire 0, [%18:5, %15:4, %12:3, %1:0] # Loc: (1, 1, 0) + %3 = repeater 1, false, false, false, [%18:5, %15:4, %12:3, %1:0], [] # Loc: (1, 1, 1) + %4 = wire 0, [%9:2, %6:1, %3:0] # Loc: (1, 1, 2) + %5 = wire 0, [%18:4, %15:3, %12:2, %1:1] # Loc: (2, 1, 0) + %6 = repeater 1, false, false, false, [%18:4, %15:3, %12:2, %1:1], [] # Loc: (2, 1, 1) + %7 = wire 0, [%3:1, %9:1, %6:0] # Loc: (2, 1, 2) + %8 = wire 0, [%18:3, %1:2, %15:2, %12:1] # Loc: (3, 1, 0) + %9 = repeater 1, false, false, false, [%18:3, %1:2, %15:2, %12:1], [] # Loc: (3, 1, 1) + %10 = wire 0, [%3:2, %6:1, %9:0] # Loc: (3, 1, 2) + %11 = wire 0, [%1:3, %18:2, %15:1, %12:0] # Loc: (4, 1, 0) + %12 = repeater 1, false, false, false, [%3:3, %6:2, %9:1], [] # Loc: (4, 1, 1) + %13 = wire 0, [%3:3, %6:2, %9:1] # Loc: (4, 1, 2) + %14 = wire 0, [%1:4, %12:1, %18:1, %15:0] # Loc: (5, 1, 0) + %15 = repeater 1, false, false, false, [%3:4, %6:3, %9:2], [] # Loc: (5, 1, 1) + %16 = wire 0, [%3:4, %6:3, %9:2] # Loc: (5, 1, 2) + %17 = wire 0, [%1:5, %12:2, %15:1, %18:0] # Loc: (6, 1, 0) + %18 = repeater 1, false, false, false, [%3:5, %6:4, %9:3], [] # Loc: (6, 1, 1) + %19 = wire 0, [%3:5, %6:4, %9:3] # Loc: (6, 1, 2) +} \ No newline at end of file diff --git a/tests/test_expects/unlit_torch_on_redstone_block_OPTIMIZED b/tests/test_expects/unlit_torch_on_redstone_block_OPTIMIZED new file mode 100644 index 00000000..ac3be816 --- /dev/null +++ b/tests/test_expects/unlit_torch_on_redstone_block_OPTIMIZED @@ -0,0 +1,3 @@ +circuit { + %2 = lamp false, [] # Loc: (0, 2, 0) +} \ No newline at end of file diff --git a/tests/test_expects/unlit_torch_on_redstone_block_UNOPTIMIZED b/tests/test_expects/unlit_torch_on_redstone_block_UNOPTIMIZED new file mode 100644 index 00000000..a496404e --- /dev/null +++ b/tests/test_expects/unlit_torch_on_redstone_block_UNOPTIMIZED @@ -0,0 +1,5 @@ +circuit { + %0 = constant 15 # Loc: (0, 0, 0) + %1 = torch false, [%0:0] # Loc: (0, 1, 0) + %2 = lamp false, [%1:0] # Loc: (0, 2, 0) +} \ No newline at end of file diff --git a/tests/test_expects/unpowered_repeater_clock_OPTIMIZED b/tests/test_expects/unpowered_repeater_clock_OPTIMIZED new file mode 100644 index 00000000..c2d3ecb4 --- /dev/null +++ b/tests/test_expects/unpowered_repeater_clock_OPTIMIZED @@ -0,0 +1,4 @@ +circuit { + %1 = lamp false, [] # Loc: (0, 1, 2) + %2 = lamp false, [] # Loc: (1, 1, 0) +} \ No newline at end of file diff --git a/tests/test_expects/unpowered_repeater_clock_UNOPTIMIZED b/tests/test_expects/unpowered_repeater_clock_UNOPTIMIZED new file mode 100644 index 00000000..ef4482f4 --- /dev/null +++ b/tests/test_expects/unpowered_repeater_clock_UNOPTIMIZED @@ -0,0 +1,8 @@ +circuit { + %0 = wire 0, [] # Loc: (0, 1, 0) + %1 = repeater 1, false, false, false, [], [] # Loc: (0, 1, 1) + %2 = lamp false, [] # Loc: (0, 1, 2) + %3 = lamp false, [] # Loc: (1, 1, 0) + %4 = repeater 1, false, false, false, [], [] # Loc: (1, 1, 1) + %5 = wire 0, [] # Loc: (1, 1, 2) +} \ No newline at end of file