From 7594825b875ef98e4aeb4dbc06acb8bfd42ce5b8 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Fri, 25 Sep 2026 05:24:35 +0000 Subject: [PATCH] Replaced `.iter().find()` with a pre-computed `HashMap` lookup in `verify_function` to optimize CFG successor validation. Co-authored-by: Tcode-Motion <188012755+Tcode-Motion@users.noreply.github.com> --- .jules/bolt.md | 3 +++ compiler/optimizer/src/verifier.rs | 14 ++++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/.jules/bolt.md b/.jules/bolt.md index fa98a9d6..d6342aff 100644 --- a/.jules/bolt.md +++ b/.jules/bolt.md @@ -41,3 +41,6 @@ ## 2026-09-24 - Zero-allocation hex decoding **Learning:** Using `hex::decode` from the `hex` crate provides a significant performance boost over manually iterating through strings and calling `u8::from_str_radix`, even though `hex::decode` allocates a new `Vec`. It avoids the heavy intermediate allocations and processing overhead of manual string slice iterations. **Action:** Always prefer `hex::decode` and `hex::encode` when working with hexadecimal encoding/decoding instead of manual iterative string parsing to significantly boost performance. +## 2024-05-18 - Optimized CFG Successor Lookup +**Learning:** During control flow graph validation in `compiler/optimizer/src/verifier.rs`, using `func.blocks.iter().find(|b| b.id == succ)` for every successor of every block created an O(V * E) time complexity bottleneck. By pre-computing a `HashMap` of `BlockId` to `&BasicBlock` in a single pass, the verification complexity was reduced to O(V + E). +**Action:** When validating graph structures or resolving many cross-references within a known collection, construct a lookup map in advance instead of performing repeated O(N) linear scans. diff --git a/compiler/optimizer/src/verifier.rs b/compiler/optimizer/src/verifier.rs index a2121bc7..96e60a20 100644 --- a/compiler/optimizer/src/verifier.rs +++ b/compiler/optimizer/src/verifier.rs @@ -1,4 +1,4 @@ -use std::collections::HashSet; +use std::collections::{HashMap, HashSet}; use techscript_ir::block::BasicBlock; use techscript_ir::function::Function; use techscript_ir::module::Module; @@ -27,7 +27,14 @@ impl IRVerifier { } fn verify_function(&self, func: &Function) -> Result<(), String> { - let block_ids: HashSet<_> = func.blocks.iter().map(|b| b.id).collect(); + let mut block_ids: HashSet<_> = HashSet::with_capacity(func.blocks.len()); + // ⚡ Bolt Performance Optimization: + // Use HashMap for O(1) block lookups instead of O(N) linear scans during CFG verification. + let mut block_map = HashMap::with_capacity(func.blocks.len()); + for b in &func.blocks { + block_ids.insert(b.id); + block_map.insert(b.id, b); + } for block in &func.blocks { self.verify_block(block, &block_ids)?; @@ -36,8 +43,7 @@ impl IRVerifier { // Verify CFG link mapping consistency for block in &func.blocks { for &succ in &block.successors { - let succ_block = func.blocks.iter().find(|b| b.id == succ); - if let Some(sb) = succ_block { + if let Some(&sb) = block_map.get(&succ) { if !sb.predecessors.contains(&block.id) { return Err(format!( "CFG inconsistency: Block '{}' lists '{}' as successor, but '{}' does not list '{}' as predecessor",