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",