diff --git a/Cargo.lock b/Cargo.lock index 70c88018..9077b511 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1047,6 +1047,32 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "criterion" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2b12d017a929603d80db1831cd3a24082f8137ce19c69e6447f54f5fc8d692f" +dependencies = [ + "anes", + "cast", + "ciborium", + "clap", + "criterion-plot 0.5.0", + "is-terminal", + "itertools 0.10.5", + "num-traits", + "once_cell", + "oorandom", + "plotters", + "rayon", + "regex", + "serde", + "serde_derive", + "serde_json", + "tinytemplate", + "walkdir", +] + [[package]] name = "criterion" version = "0.8.2" @@ -1058,7 +1084,7 @@ dependencies = [ "cast", "ciborium", "clap", - "criterion-plot", + "criterion-plot 0.8.2", "itertools 0.13.0", "num-traits", "oorandom", @@ -1072,6 +1098,16 @@ dependencies = [ "walkdir", ] +[[package]] +name = "criterion-plot" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" +dependencies = [ + "cast", + "itertools 0.10.5", +] + [[package]] name = "criterion-plot" version = "0.8.2" @@ -2033,12 +2069,32 @@ dependencies = [ "syn 2.0.119", ] +[[package]] +name = "is-terminal" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" +dependencies = [ + "hermit-abi", + "libc", + "windows-sys 0.61.2", +] + [[package]] name = "is_terminal_polyfill" version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + [[package]] name = "itertools" version = "0.13.0" @@ -3894,6 +3950,7 @@ dependencies = [ name = "techscript_ir" version = "2.0.0" dependencies = [ + "criterion 0.5.1", "serde", "techscript_ast", "techscript_common", @@ -3946,7 +4003,7 @@ dependencies = [ name = "techscript_lsp" version = "2.0.0" dependencies = [ - "criterion", + "criterion 0.8.2", "serde", "serde_json", "techscript_ast", diff --git a/compiler/ir/Cargo.toml b/compiler/ir/Cargo.toml index 862a54bf..8bc0f91d 100644 --- a/compiler/ir/Cargo.toml +++ b/compiler/ir/Cargo.toml @@ -16,3 +16,8 @@ serde = { workspace = true } techscript_lexer = { path = "../lexer" } techscript_parser = { path = "../parser" } techscript_semantic = { path = "../semantic" } +criterion = "0.5" + +[[bench]] +name = "builder_bench" +harness = false diff --git a/compiler/ir/benches/builder_bench.rs b/compiler/ir/benches/builder_bench.rs new file mode 100644 index 00000000..3a1c5864 --- /dev/null +++ b/compiler/ir/benches/builder_bench.rs @@ -0,0 +1,38 @@ +use criterion::{criterion_group, criterion_main, Criterion}; +use techscript_ir::builder::IRBuilder; +use techscript_ir::types::IRType; + +fn criterion_benchmark(c: &mut Criterion) { + c.bench_function("seal_function 10000 blocks", |b| { + b.iter(|| { + let mut builder = IRBuilder::new(); + builder.start_function("bench_func".to_string(), IRType::Void); + + let num_blocks = 10000; + let mut blocks = vec![]; + for i in 0..num_blocks { + let block_id = builder.new_block(format!("block_{}", i)); + blocks.push(block_id); + } + + for i in 0..(num_blocks - 1) { + builder.enter_block(blocks[i], format!("block_{}", i)); + builder.emit_terminator( + techscript_ir::instruction::TerminatorKind::Jump(blocks[i + 1]), + techscript_common::Span { start: 0, end: 0 }, + ); + } + + builder.enter_block(blocks[num_blocks - 1], format!("block_{}", num_blocks - 1)); + builder.emit_terminator( + techscript_ir::instruction::TerminatorKind::Return(None), + techscript_common::Span { start: 0, end: 0 }, + ); + + builder.seal_function(); + }); + }); +} + +criterion_group!(benches, criterion_benchmark); +criterion_main!(benches); diff --git a/compiler/ir/src/builder.rs b/compiler/ir/src/builder.rs index b7ebaf52..8274ee9d 100644 --- a/compiler/ir/src/builder.rs +++ b/compiler/ir/src/builder.rs @@ -263,15 +263,15 @@ impl IRBuilder { } // Map predecessors - for i in 0..num_blocks { - let block_id = func.blocks[i].id; - let mut preds = Vec::new(); - for other in &func.blocks { - if other.successors.contains(&block_id) { - preds.push(other.id); - } + let mut pred_map = HashMap::new(); + for block in &func.blocks { + for &succ in &block.successors { + pred_map.entry(succ).or_insert_with(Vec::new).push(block.id); } - func.blocks[i].predecessors = preds; + } + + for block in &mut func.blocks { + block.predecessors = pred_map.remove(&block.id).unwrap_or_default(); } self.functions.push(func);