From 75998bed37d88a02a09cfd54ce5b5a50f939234e Mon Sep 17 00:00:00 2001 From: Bilal Mahmoud Date: Mon, 22 Dec 2025 12:31:48 +0100 Subject: [PATCH 1/3] feat: changed integration --- libs/@local/hashql/mir/benches/transform.rs | 4 +- .../src/pass/analysis/data_dependency/mod.rs | 2 +- libs/@local/hashql/mir/src/pass/mod.rs | 50 ++++++++++++++++++- .../src/pass/transform/cfg_simplify/mod.rs | 14 +++++- .../hashql/mir/src/pass/transform/cp/mod.rs | 9 +++- .../hashql/mir/src/pass/transform/dbe/mod.rs | 7 +-- .../hashql/mir/src/pass/transform/dle/mod.rs | 11 +++- .../hashql/mir/src/pass/transform/dse/mod.rs | 20 ++++++-- .../src/pass/transform/inst_simplify/mod.rs | 11 +++- .../hashql/mir/src/pass/transform/sroa.rs | 19 ++++--- .../mir/src/pass/transform/ssa_repair/mod.rs | 10 +++- 11 files changed, 132 insertions(+), 25 deletions(-) diff --git a/libs/@local/hashql/mir/benches/transform.rs b/libs/@local/hashql/mir/benches/transform.rs index ff96f7da621..7d47d5076eb 100644 --- a/libs/@local/hashql/mir/benches/transform.rs +++ b/libs/@local/hashql/mir/benches/transform.rs @@ -365,7 +365,9 @@ fn run( bencher, body, #[inline] - |context, body| pass.run(context, body), + |context, body| { + pass.run(context, body); + }, ); } diff --git a/libs/@local/hashql/mir/src/pass/analysis/data_dependency/mod.rs b/libs/@local/hashql/mir/src/pass/analysis/data_dependency/mod.rs index c1746c3f5fe..99c9d311537 100644 --- a/libs/@local/hashql/mir/src/pass/analysis/data_dependency/mod.rs +++ b/libs/@local/hashql/mir/src/pass/analysis/data_dependency/mod.rs @@ -119,7 +119,7 @@ impl<'env, 'heap, A: Allocator + Clone> AnalysisPass<'env, 'heap> graph.derive(&body.local_decls, |id, _| id); - let Ok(()) = DataDependencyAnalysisVisitor { + Ok(()) = DataDependencyAnalysisVisitor { graph: &mut graph, constant_bindings: &mut constant_bindings, context, diff --git a/libs/@local/hashql/mir/src/pass/mod.rs b/libs/@local/hashql/mir/src/pass/mod.rs index 575eee3ec13..db73632b05d 100644 --- a/libs/@local/hashql/mir/src/pass/mod.rs +++ b/libs/@local/hashql/mir/src/pass/mod.rs @@ -58,6 +58,54 @@ const fn simplify_type_name(name: &'static str) -> &'static str { } } +/// Indicates whether a pass modified the MIR. +/// +/// Passes return this to signal whether they made changes, enabling the pass manager to skip +/// dependent re-analyses when nothing changed. +#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub enum Changed { + /// The pass definitely made modifications. + Yes, + /// The pass may have made modifications, but precise tracking was not possible. + Unknown, + /// The pass made no modifications. + No, +} + +impl Changed { + /// Returns `true` if the MIR may have changed. + /// + /// This is the conservative choice: returns `true` for both [`Changed::Yes`] and + /// [`Changed::Unknown`], ensuring dependent analyses are invalidated when in doubt, but may + /// result in unnecessary passes to be run. + #[must_use] + pub const fn conservative(self) -> bool { + match self { + Self::Yes | Self::Unknown => true, + Self::No => false, + } + } + + /// Returns `true` only if the MIR definitely changed. + /// + /// This is the optimistic choice: returns `true` only for [`Changed::Yes`], assuming + /// [`Changed::Unknown`] did not actually modify anything. Use with caution, as this may + /// skip necessary re-runs of passes. + #[must_use] + pub const fn optimistic(self) -> bool { + match self { + Self::Yes => true, + Self::Unknown | Self::No => false, + } + } +} + +impl From for Changed { + fn from(value: bool) -> Self { + if value { Self::Yes } else { Self::No } + } +} + /// A transformation or analysis pass over MIR. /// /// Passes operate on a [`Body`] within a [`MirContext`], allowing them to read and modify the @@ -86,7 +134,7 @@ pub trait TransformPass<'env, 'heap> { /// /// The `context` provides access to the heap allocator, type environment, interner, and /// diagnostic collection. The `body` can be read and modified in place. - fn run(&mut self, context: &mut MirContext<'env, 'heap>, body: &mut Body<'heap>); + fn run(&mut self, context: &mut MirContext<'env, 'heap>, body: &mut Body<'heap>) -> Changed; /// Returns a human-readable name for this pass. /// diff --git a/libs/@local/hashql/mir/src/pass/transform/cfg_simplify/mod.rs b/libs/@local/hashql/mir/src/pass/transform/cfg_simplify/mod.rs index 0f7018764f4..9754cd17e01 100644 --- a/libs/@local/hashql/mir/src/pass/transform/cfg_simplify/mod.rs +++ b/libs/@local/hashql/mir/src/pass/transform/cfg_simplify/mod.rs @@ -64,7 +64,7 @@ use crate::{ terminator::{Goto, Terminator, TerminatorKind}, }, context::MirContext, - pass::TransformPass, + pass::{Changed, TransformPass}, }; /// Control-flow graph simplification pass. @@ -479,8 +479,9 @@ impl<'env, 'heap, A: BumpAllocator> TransformPass<'env, 'heap> for CfgSimplify, body: &mut Body<'heap>) { + fn run(&mut self, context: &mut MirContext<'env, 'heap>, body: &mut Body<'heap>) -> Changed { let mut queue = WorkQueue::new(body.basic_blocks.len()); + let mut changed = false; // Process in reverse of reverse-postorder (i.e., roughly postorder) to handle // successors before predecessors, maximizing optimization opportunities. @@ -500,6 +501,7 @@ impl<'env, 'heap, A: BumpAllocator> TransformPass<'env, 'heap> for CfgSimplify TransformPass<'env, 'heap> for CfgSimplify CopyPropagation { } impl<'env, 'heap, A: BumpAllocator> TransformPass<'env, 'heap> for CopyPropagation { - fn run(&mut self, context: &mut MirContext<'env, 'heap>, body: &mut Body<'heap>) { + fn run(&mut self, context: &mut MirContext<'env, 'heap>, body: &mut Body<'heap>) -> Changed { self.alloc.reset(); let mut visitor = CopyPropagationVisitor { interner: context.interner, constants: IdVec::with_capacity_in(body.local_decls.len(), &self.alloc), + changed: false, }; let reverse_postorder = body @@ -187,12 +188,15 @@ impl<'env, 'heap, A: BumpAllocator> TransformPass<'env, 'heap> for CopyPropagati Ok(()) = visitor.visit_basic_block(id, &mut body.basic_blocks.as_mut_preserving_cfg()[id]); } + + visitor.changed.into() } } struct CopyPropagationVisitor<'env, 'heap, A: Allocator> { interner: &'env Interner<'heap>, constants: LocalVec>, A>, + changed: bool, } impl<'heap, A: Allocator> CopyPropagationVisitor<'_, 'heap, A> { @@ -234,6 +238,7 @@ impl<'heap, A: Allocator> VisitorMut<'heap> for CopyPropagationVisitor<'_, 'heap && let Some(&constant) = self.constants.lookup(place.local) { *operand = Operand::Constant(constant); + self.changed = true; } Ok(()) diff --git a/libs/@local/hashql/mir/src/pass/transform/dbe/mod.rs b/libs/@local/hashql/mir/src/pass/transform/dbe/mod.rs index 2a87da7f3c3..7a30d888bde 100644 --- a/libs/@local/hashql/mir/src/pass/transform/dbe/mod.rs +++ b/libs/@local/hashql/mir/src/pass/transform/dbe/mod.rs @@ -36,7 +36,7 @@ use crate::{ }, context::MirContext, intern::Interner, - pass::TransformPass, + pass::{Changed, TransformPass}, visit::{VisitorMut, r#mut::filter}, }; @@ -56,7 +56,7 @@ impl DeadBlockElimination { } impl<'env, 'heap, A: BumpAllocator> TransformPass<'env, 'heap> for DeadBlockElimination { - fn run(&mut self, context: &mut MirContext<'env, 'heap>, body: &mut Body<'heap>) { + fn run(&mut self, context: &mut MirContext<'env, 'heap>, body: &mut Body<'heap>) -> Changed { self.alloc.reset(); let mut reachable = fast_hash_set_with_capacity_in( @@ -75,7 +75,7 @@ impl<'env, 'heap, A: BumpAllocator> TransformPass<'env, 'heap> for DeadBlockElim // Early exit if all blocks are reachable if reachable.len() == body.basic_blocks.len() { - return; + return Changed::No; } // Step 2: Build the remapping table @@ -141,6 +141,7 @@ impl<'env, 'heap, A: BumpAllocator> TransformPass<'env, 'heap> for DeadBlockElim // We **remove** the blocks, so cfg must be invalidated. body.basic_blocks.as_mut().truncate(write_index); + Changed::Yes } } diff --git a/libs/@local/hashql/mir/src/pass/transform/dle/mod.rs b/libs/@local/hashql/mir/src/pass/transform/dle/mod.rs index 30ced2a7db5..2b58e281d40 100644 --- a/libs/@local/hashql/mir/src/pass/transform/dle/mod.rs +++ b/libs/@local/hashql/mir/src/pass/transform/dle/mod.rs @@ -66,7 +66,7 @@ use crate::{ }, context::MirContext, intern::Interner, - pass::TransformPass, + pass::{Changed, TransformPass}, visit::{Visitor, VisitorMut, r#mut::filter}, }; @@ -104,7 +104,7 @@ impl DeadLocalElimination { } impl<'env, 'heap, A: BumpAllocator> TransformPass<'env, 'heap> for DeadLocalElimination { - fn run(&mut self, context: &mut MirContext<'env, 'heap>, body: &mut Body<'heap>) { + fn run(&mut self, context: &mut MirContext<'env, 'heap>, body: &mut Body<'heap>) -> Changed { self.alloc.reset(); let mut dead = if let Some(dead) = self.dead.take() { @@ -121,6 +121,12 @@ impl<'env, 'heap, A: BumpAllocator> TransformPass<'env, 'heap> for DeadLocalElim dead.remove(Local::new(index)); } + if dead.is_empty() { + // If there are no dead locals, we can skip further analysis, as no locals will be + // removed. + return Changed::No; + } + let mut remap = LocalVec::new_in(&self.alloc); let mut new_id = Local::new(0); for old_id in body.local_decls.ids() { @@ -159,6 +165,7 @@ impl<'env, 'heap, A: BumpAllocator> TransformPass<'env, 'heap> for DeadLocalElim // Remove unused locals body.local_decls.truncate(write_index); + Changed::Yes } } diff --git a/libs/@local/hashql/mir/src/pass/transform/dse/mod.rs b/libs/@local/hashql/mir/src/pass/transform/dse/mod.rs index 6eea0a7610c..3ae27741fa5 100644 --- a/libs/@local/hashql/mir/src/pass/transform/dse/mod.rs +++ b/libs/@local/hashql/mir/src/pass/transform/dse/mod.rs @@ -72,7 +72,7 @@ use crate::{ }, context::MirContext, intern::Interner, - pass::TransformPass, + pass::{Changed, TransformPass}, visit::{self, Visitor, VisitorMut, r#mut::filter}, }; @@ -138,9 +138,14 @@ impl Default for DeadStoreElimination { } impl<'env, 'heap, A: BumpAllocator> TransformPass<'env, 'heap> for DeadStoreElimination { - fn run(&mut self, context: &mut MirContext<'env, 'heap>, body: &mut Body<'heap>) { + fn run(&mut self, context: &mut MirContext<'env, 'heap>, body: &mut Body<'heap>) -> Changed { self.alloc.reset(); let dead = self.dead_locals(body); + + if dead.is_empty() { + return Changed::No; + } + let mut visitor = EliminationVisitor { dead: &dead, params: BasicBlockVec::from_fn_in( @@ -149,16 +154,20 @@ impl<'env, 'heap, A: BumpAllocator> TransformPass<'env, 'heap> for DeadStoreElim &self.alloc, ), interner: context.interner, + changed: false, scratch_locals: Vec::new_in(&self.alloc), scratch_operands: Vec::new_in(&self.alloc), }; Ok(()) = visitor.visit_body_preserving_cfg(body); + let mut changed = Changed::from(visitor.changed); drop(visitor); let mut dle = DeadLocalElimination::new_in(&mut self.alloc).with_dead(dead); - dle.run(context, body); + changed = changed.max(dle.run(context, body)); + + changed } } @@ -312,6 +321,7 @@ struct EliminationVisitor<'dead, 'env, 'heap, A: Allocator> { params: BasicBlockVec, A>, interner: &'env Interner<'heap>, + changed: bool, /// Scratch buffer for building new block parameter lists. scratch_locals: Vec, @@ -352,6 +362,8 @@ impl<'heap, A: Allocator> VisitorMut<'heap> for EliminationVisitor<'_, '_, 'heap .retain(|¶m| !self.dead.contains(param)); block.params = self.interner.locals.intern_slice(&self.scratch_locals); + + self.changed = true; } Ok(()) @@ -370,6 +382,7 @@ impl<'heap, A: Allocator> VisitorMut<'heap> for EliminationVisitor<'_, '_, 'heap if self.dead.contains(local) { statement.kind = StatementKind::Nop; + self.changed = true; } Ok(()) @@ -397,6 +410,7 @@ impl<'heap, A: Allocator> VisitorMut<'heap> for EliminationVisitor<'_, '_, 'heap let operands = self.interner.operands.intern_slice(&self.scratch_operands); target.args = operands; + self.changed = true; Ok(()) } diff --git a/libs/@local/hashql/mir/src/pass/transform/inst_simplify/mod.rs b/libs/@local/hashql/mir/src/pass/transform/inst_simplify/mod.rs index 2329ac1f50d..4475bd2858b 100644 --- a/libs/@local/hashql/mir/src/pass/transform/inst_simplify/mod.rs +++ b/libs/@local/hashql/mir/src/pass/transform/inst_simplify/mod.rs @@ -111,7 +111,7 @@ use crate::{ }, context::MirContext, intern::Interner, - pass::TransformPass, + pass::{Changed, TransformPass}, visit::{self, VisitorMut, r#mut::filter}, }; @@ -171,7 +171,7 @@ impl InstSimplify { } impl<'env, 'heap, A: BumpAllocator> TransformPass<'env, 'heap> for InstSimplify { - fn run(&mut self, context: &mut MirContext<'env, 'heap>, body: &mut Body<'heap>) { + fn run(&mut self, context: &mut MirContext<'env, 'heap>, body: &mut Body<'heap>) -> Changed { self.alloc.reset(); let mut visitor = InstSimplifyVisitor { @@ -180,6 +180,7 @@ impl<'env, 'heap, A: BumpAllocator> TransformPass<'env, 'heap> for InstSimplify< trampoline: None, decl: &body.local_decls, evaluated: IdVec::with_capacity_in(body.local_decls.len(), &self.alloc), + changed: false, }; let reverse_postorder = body @@ -199,6 +200,8 @@ impl<'env, 'heap, A: BumpAllocator> TransformPass<'env, 'heap> for InstSimplify< Ok(()) = visitor.visit_basic_block(id, &mut body.basic_blocks.as_mut_preserving_cfg()[id]); } + + visitor.changed.into() } } @@ -219,6 +222,8 @@ struct InstSimplifyVisitor<'env, 'heap, A: Allocator> { /// Map from locals to their known constant values. /// Populated when a local is assigned a constant (directly or via folding). evaluated: LocalVec, A>, + + changed: bool, } impl<'heap, A: Allocator> InstSimplifyVisitor<'_, 'heap, A> { @@ -519,6 +524,8 @@ impl<'heap, A: Allocator> VisitorMut<'heap> for InstSimplifyVisitor<'_, 'heap, A return Ok(()); }; + self.changed = true; + // If the simplified RHS is a constant, record it for future simplifications. if let RValue::Load(Operand::Constant(Constant::Int(int))) = trampoline && assign.lhs.projections.is_empty() diff --git a/libs/@local/hashql/mir/src/pass/transform/sroa.rs b/libs/@local/hashql/mir/src/pass/transform/sroa.rs index 07622d0265c..073d35eec5d 100644 --- a/libs/@local/hashql/mir/src/pass/transform/sroa.rs +++ b/libs/@local/hashql/mir/src/pass/transform/sroa.rs @@ -66,7 +66,7 @@ use crate::{ context::MirContext, intern::Interner, pass::{ - AnalysisPass as _, TransformPass, + AnalysisPass as _, Changed, TransformPass, analysis::{DataDependencyAnalysis, TransientDataDependencyGraph}, }, visit::{VisitorMut, r#mut::filter}, @@ -76,6 +76,7 @@ use crate::{ struct PlaceVisitor<'env, 'heap, A: Allocator> { interner: &'env Interner<'heap>, graph: TransientDataDependencyGraph<'heap, A>, + changed: bool, } impl<'heap, A: Allocator + Clone> VisitorMut<'heap> for PlaceVisitor<'_, 'heap, A> { @@ -94,7 +95,10 @@ impl<'heap, A: Allocator + Clone> VisitorMut<'heap> for PlaceVisitor<'_, 'heap, // We do not walk the operand, as we're only interested in operands themselves, with cannot // be nested. if let Operand::Place(place) = operand { - *operand = self.graph.resolve(self.interner, place.as_ref()); + let next = self.graph.resolve(self.interner, place.as_ref()); + self.changed |= next != *operand; + + *operand = next; } Ok(()) @@ -127,7 +131,7 @@ impl Sroa { } impl<'env, 'heap, A: BumpAllocator> TransformPass<'env, 'heap> for Sroa { - fn run(&mut self, context: &mut MirContext<'env, 'heap>, body: &mut Body<'heap>) { + fn run(&mut self, context: &mut MirContext<'env, 'heap>, body: &mut Body<'heap>) -> Changed { self.alloc.reset(); let mut analysis = DataDependencyAnalysis::new_in(&self.alloc); @@ -135,12 +139,15 @@ impl<'env, 'heap, A: BumpAllocator> TransformPass<'env, 'heap> for Sroa { let analysis = analysis.finish(); let transient = analysis.transient(context.interner); - Ok(()) = PlaceVisitor { + let mut visitor = PlaceVisitor { interner: context.interner, graph: transient, - } - .visit_body_preserving_cfg(body); + changed: false, + }; + Ok(()) = visitor.visit_body_preserving_cfg(body); drop(analysis); + + visitor.changed.into() } } diff --git a/libs/@local/hashql/mir/src/pass/transform/ssa_repair/mod.rs b/libs/@local/hashql/mir/src/pass/transform/ssa_repair/mod.rs index de920c0a24b..102b60d3615 100644 --- a/libs/@local/hashql/mir/src/pass/transform/ssa_repair/mod.rs +++ b/libs/@local/hashql/mir/src/pass/transform/ssa_repair/mod.rs @@ -58,7 +58,7 @@ use crate::{ }, context::MirContext, intern::Interner, - pass::TransformPass, + pass::{Changed, TransformPass}, visit::{self, Visitor, VisitorMut, r#mut::filter}, }; @@ -162,7 +162,7 @@ impl Default for SsaRepair { } impl<'env, 'heap, A: BumpAllocator> TransformPass<'env, 'heap> for SsaRepair { - fn run(&mut self, context: &mut MirContext<'env, 'heap>, body: &mut Body<'heap>) { + fn run(&mut self, context: &mut MirContext<'env, 'heap>, body: &mut Body<'heap>) -> Changed { self.alloc.reset(); let mut sites = DefSites::new_in(body, &self.alloc); sites.visit_body(body); @@ -174,7 +174,11 @@ impl<'env, 'heap, A: BumpAllocator> TransformPass<'env, 'heap> for SsaRepair ); let mut prev_repair: Option> = None; + let mut changed = false; + for (violation, locations) in sites.iter_violations() { + changed = true; + let iterated = iterated_dominance_frontier( &body.basic_blocks, &frontiers, @@ -200,6 +204,8 @@ impl<'env, 'heap, A: BumpAllocator> TransformPass<'env, 'heap> for SsaRepair prev_repair = Some(repair); } + + changed.into() } } From 56e97740a53cb94d097e3023ec42b930ca5bbbc6 Mon Sep 17 00:00:00 2001 From: Bilal Mahmoud Date: Mon, 22 Dec 2025 12:59:05 +0100 Subject: [PATCH 2/3] chore: update snapshots --- .../suite/mir_pass_transform_cfg_simplify.rs | 4 +- .../src/suite/mir_pass_transform_dse.rs | 4 +- .../suite/mir_pass_transform_inst_simplify.rs | 4 +- .../src/suite/mir_pass_transform_sroa.rs | 4 +- libs/@local/hashql/mir/benches/transform.rs | 53 ++++++++++++------- libs/@local/hashql/mir/src/pass/mod.rs | 7 +-- .../src/pass/transform/cfg_simplify/mod.rs | 7 ++- .../src/pass/transform/cfg_simplify/tests.rs | 14 ++--- .../hashql/mir/src/pass/transform/cp/tests.rs | 14 ++--- .../mir/src/pass/transform/dbe/tests.rs | 14 ++--- .../mir/src/pass/transform/dle/tests.rs | 14 ++--- .../mir/src/pass/transform/dse/tests.rs | 14 ++--- .../src/pass/transform/inst_simplify/tests.rs | 14 ++--- .../src/pass/transform/ssa_repair/tests.rs | 14 ++--- .../identical_switch_targets.snap | 2 +- .../no_inline_non_noop_multiple_preds.snap | 2 +- .../noop_block_multiple_predecessors.snap | 2 +- .../cfg_simplify/only_otherwise_switch.snap | 2 +- .../cfg_simplify/redundant_cases_removal.snap | 2 +- .../cfg_simplify/self_loop_preservation.snap | 2 +- .../self_loop_preservation_with_params.snap | 2 +- .../switch_promotion_with_goto_params.snap | 2 +- .../switch_self_loop_preservation.snap | 2 +- .../cfg_simplify/switch_target_promotion.snap | 2 +- .../unreachable_switch_arm_ice.snap | 2 +- .../ui/pass/cp/block_param_disagreement.snap | 2 +- .../ui/pass/cp/block_param_effectful.snap | 2 +- .../ui/pass/cp/block_param_unanimous.snap | 2 +- .../ui/pass/cp/block_param_via_local.snap | 2 +- .../mir/tests/ui/pass/cp/constant_chain.snap | 2 +- .../mir/tests/ui/pass/cp/loop_back_edge.snap | 2 +- .../ui/pass/cp/projection_unchanged.snap | 2 +- .../mir/tests/ui/pass/cp/single_constant.snap | 2 +- .../mir/tests/ui/pass/dbe/all_reachable.snap | 2 +- .../ui/pass/dbe/block_params_preserved.snap | 2 +- .../pass/dbe/multiple_unreachable_at_end.snap | 2 +- .../ui/pass/dbe/scattered_unreachable.snap | 2 +- .../pass/dbe/single_unreachable_at_end.snap | 2 +- .../ui/pass/dbe/switch_target_remapping.snap | 2 +- .../tests/ui/pass/dbe/unreachable_chain.snap | 2 +- .../ui/pass/dbe/unreachable_in_middle.snap | 2 +- .../mir/tests/ui/pass/dle/all_live.snap | 2 +- .../mir/tests/ui/pass/dle/dead_in_middle.snap | 2 +- .../pass/dle/projection_locals_preserved.snap | 2 +- .../mir/tests/ui/pass/dle/scattered_dead.snap | 2 +- .../tests/ui/pass/dle/single_dead_at_end.snap | 2 +- .../ui/pass/dle/unused_args_preserved.snap | 2 +- .../mir/tests/ui/pass/dse/all_live.snap | 2 +- .../pass/dse/branch_condition_preserved.snap | 2 +- .../mir/tests/ui/pass/dse/dead_chain.snap | 2 +- .../mir/tests/ui/pass/dse/dead_cycle.snap | 2 +- .../dse/dead_param_multiple_predecessors.snap | 2 +- .../dse/dead_param_with_live_sibling.snap | 2 +- .../ui/pass/dse/dead_storage_statements.snap | 2 +- .../pass/dse/graph_read_token_preserved.snap | 2 +- .../ui/pass/dse/single_dead_assignment.snap | 2 +- .../block_param_predecessors_agree.snap | 2 +- .../block_param_predecessors_disagree.snap | 2 +- .../block_param_single_predecessor.snap | 2 +- .../inst_simplify/const_fold_bit_and.snap | 2 +- .../pass/inst_simplify/const_fold_bit_or.snap | 2 +- .../inst_simplify/const_fold_unary_neg.snap | 2 +- .../inst_simplify/const_fold_unary_not.snap | 2 +- .../idempotent_to_const_forwarding.snap | 2 +- .../identical_operand_bit_and.snap | 2 +- .../identical_operand_bit_or.snap | 2 +- .../inst_simplify/identity_bit_or_zero.snap | 2 +- .../diamond_both_branches_define.snap | 2 +- .../diamond_one_branch_redefines.snap | 2 +- .../tests/ui/pass/ssa_repair/irreducible.snap | 2 +- .../mir/tests/ui/pass/ssa_repair/linear.snap | 2 +- .../ssa_repair/loop_with_conditional_def.snap | 2 +- .../ssa_repair/multiple_defs_same_block.snap | 2 +- .../multiple_variables_violated.snap | 2 +- .../tests/ui/pass/ssa_repair/nested_loop.snap | 2 +- .../ui/pass/ssa_repair/passthrough_chain.snap | 2 +- .../ui/pass/ssa_repair/reassign_rodeo.snap | 2 +- .../tests/ui/pass/ssa_repair/simple_loop.snap | 2 +- .../ui/pass/ssa_repair/single_def_use.snap | 2 +- .../ui/pass/ssa_repair/three_way_merge.snap | 2 +- .../ssa_repair/use_before_def_in_block.snap | 2 +- 81 files changed, 173 insertions(+), 142 deletions(-) diff --git a/libs/@local/hashql/compiletest/src/suite/mir_pass_transform_cfg_simplify.rs b/libs/@local/hashql/compiletest/src/suite/mir_pass_transform_cfg_simplify.rs index 3ebf744b04a..cdcaec8fdd2 100644 --- a/libs/@local/hashql/compiletest/src/suite/mir_pass_transform_cfg_simplify.rs +++ b/libs/@local/hashql/compiletest/src/suite/mir_pass_transform_cfg_simplify.rs @@ -14,7 +14,7 @@ use hashql_mir::{ context::MirContext, def::{DefId, DefIdSlice, DefIdVec}, intern::Interner, - pass::{TransformPass as _, transform::CfgSimplify}, + pass::{Changed, TransformPass as _, transform::CfgSimplify}, }; use super::{RunContext, Suite, SuiteDiagnostic, common::process_issues, mir_reify::mir_reify}; @@ -63,7 +63,7 @@ pub(crate) fn mir_pass_transform_cfg_simplify<'heap>( let mut pass = CfgSimplify::new_in(&mut scratch); for body in bodies.as_mut_slice() { - pass.run(&mut context, body); + let _: Changed = pass.run(&mut context, body); } process_issues(diagnostics, context.diagnostics)?; diff --git a/libs/@local/hashql/compiletest/src/suite/mir_pass_transform_dse.rs b/libs/@local/hashql/compiletest/src/suite/mir_pass_transform_dse.rs index 88087d9c208..55ded73061e 100644 --- a/libs/@local/hashql/compiletest/src/suite/mir_pass_transform_dse.rs +++ b/libs/@local/hashql/compiletest/src/suite/mir_pass_transform_dse.rs @@ -11,7 +11,7 @@ use hashql_mir::{ context::MirContext, def::{DefId, DefIdSlice, DefIdVec}, intern::Interner, - pass::{TransformPass as _, transform::DeadStoreElimination}, + pass::{Changed, TransformPass as _, transform::DeadStoreElimination}, }; use super::{ @@ -45,7 +45,7 @@ pub(crate) fn mir_pass_transform_dse<'heap>( // CFG -> SROA -> Inst -> DSE let mut pass = DeadStoreElimination::new_in(&mut scratch); for body in bodies.as_mut_slice() { - pass.run(&mut context, body); + let _: Changed = pass.run(&mut context, body); } process_issues(diagnostics, context.diagnostics)?; diff --git a/libs/@local/hashql/compiletest/src/suite/mir_pass_transform_inst_simplify.rs b/libs/@local/hashql/compiletest/src/suite/mir_pass_transform_inst_simplify.rs index d05bc9d5aca..ee0be713bf4 100644 --- a/libs/@local/hashql/compiletest/src/suite/mir_pass_transform_inst_simplify.rs +++ b/libs/@local/hashql/compiletest/src/suite/mir_pass_transform_inst_simplify.rs @@ -11,7 +11,7 @@ use hashql_mir::{ context::MirContext, def::{DefId, DefIdSlice, DefIdVec}, intern::Interner, - pass::{TransformPass as _, transform::InstSimplify}, + pass::{Changed, TransformPass as _, transform::InstSimplify}, }; use super::{ @@ -44,7 +44,7 @@ pub(crate) fn mir_pass_transform_inst_simplify<'heap>( let mut pass = InstSimplify::new_in(&mut scratch); for body in bodies.as_mut_slice() { - pass.run(&mut context, body); + let _: Changed = pass.run(&mut context, body); } process_issues(diagnostics, context.diagnostics)?; diff --git a/libs/@local/hashql/compiletest/src/suite/mir_pass_transform_sroa.rs b/libs/@local/hashql/compiletest/src/suite/mir_pass_transform_sroa.rs index e2dab0653fe..7f84177a25e 100644 --- a/libs/@local/hashql/compiletest/src/suite/mir_pass_transform_sroa.rs +++ b/libs/@local/hashql/compiletest/src/suite/mir_pass_transform_sroa.rs @@ -11,7 +11,7 @@ use hashql_mir::{ context::MirContext, def::{DefId, DefIdSlice, DefIdVec}, intern::Interner, - pass::{TransformPass as _, transform::Sroa}, + pass::{Changed, TransformPass as _, transform::Sroa}, }; use super::{ @@ -44,7 +44,7 @@ pub(crate) fn mir_pass_transform_sroa<'heap>( let mut pass = Sroa::new_in(&mut scratch); for body in bodies.as_mut_slice() { - pass.run(&mut context, body); + let _: Changed = pass.run(&mut context, body); } process_issues(diagnostics, context.diagnostics)?; diff --git a/libs/@local/hashql/mir/benches/transform.rs b/libs/@local/hashql/mir/benches/transform.rs index 7d47d5076eb..5ca449cb9fc 100644 --- a/libs/@local/hashql/mir/benches/transform.rs +++ b/libs/@local/hashql/mir/benches/transform.rs @@ -5,7 +5,7 @@ clippy::similar_names )] -use core::hint::black_box; +use core::{cmp, hint::black_box}; use codspeed_criterion_compat::{BatchSize, Bencher, Criterion, criterion_group, criterion_main}; use hashql_core::{ @@ -301,10 +301,10 @@ fn create_complex_cfg<'heap>(env: &Environment<'heap>, interner: &Interner<'heap #[expect(unsafe_code)] #[inline] -fn run_bencher( +fn run_bencher( bencher: &mut Bencher, body: for<'heap> fn(&Environment<'heap>, &Interner<'heap>) -> Body<'heap>, - mut func: impl for<'env, 'heap> FnMut(&mut MirContext<'env, 'heap>, &mut Body<'heap>), + mut func: impl for<'env, 'heap> FnMut(&mut MirContext<'env, 'heap>, &mut Body<'heap>) -> T, ) { // NOTE: `heap` must not be moved or reassigned; `heap_ptr` assumes its address is stable // for the entire duration of this function. @@ -348,8 +348,8 @@ fn run_bencher( diagnostics: DiagnosticIssues::new(), }; - func(black_box(&mut context), black_box(body)); - context.diagnostics + let value = func(black_box(&mut context), black_box(body)); + (context.diagnostics, value) }, BatchSize::PerIteration, ); @@ -365,9 +365,7 @@ fn run( bencher, body, #[inline] - |context, body| { - pass.run(context, body); - }, + |context, body| pass.run(context, body), ); } @@ -442,30 +440,45 @@ fn pipeline(criterion: &mut Criterion) { let mut scratch = Scratch::new(); run_bencher(bencher, create_linear_cfg, |context, body| { - CfgSimplify::new_in(&mut scratch).run(context, body); - Sroa::new_in(&mut scratch).run(context, body); - InstSimplify::new().run(context, body); - DeadStoreElimination::new_in(&mut scratch).run(context, body); + let mut changed = CfgSimplify::new_in(&mut scratch).run(context, body); + changed = cmp::max(changed, Sroa::new_in(&mut scratch).run(context, body)); + changed = cmp::max(changed, InstSimplify::new().run(context, body)); + changed = cmp::max( + changed, + DeadStoreElimination::new_in(&mut scratch).run(context, body), + ); + + changed }); }); group.bench_function("diamond", |bencher| { let mut scratch = Scratch::new(); run_bencher(bencher, create_diamond_cfg, |context, body| { - CfgSimplify::new_in(&mut scratch).run(context, body); - Sroa::new_in(&mut scratch).run(context, body); - InstSimplify::new().run(context, body); - DeadStoreElimination::new_in(&mut scratch).run(context, body); + let mut changed = CfgSimplify::new_in(&mut scratch).run(context, body); + changed = cmp::max(changed, Sroa::new_in(&mut scratch).run(context, body)); + changed = cmp::max(changed, InstSimplify::new().run(context, body)); + changed = cmp::max( + changed, + DeadStoreElimination::new_in(&mut scratch).run(context, body), + ); + + changed }); }); group.bench_function("complex", |bencher| { let mut scratch = Scratch::new(); run_bencher(bencher, create_complex_cfg, |context, body| { - CfgSimplify::new_in(&mut scratch).run(context, body); - Sroa::new_in(&mut scratch).run(context, body); - InstSimplify::new().run(context, body); - DeadStoreElimination::new_in(&mut scratch).run(context, body); + let mut changed = CfgSimplify::new_in(&mut scratch).run(context, body); + changed = cmp::max(changed, Sroa::new_in(&mut scratch).run(context, body)); + changed = cmp::max(changed, InstSimplify::new().run(context, body)); + changed = cmp::max( + changed, + DeadStoreElimination::new_in(&mut scratch).run(context, body), + ); + + changed }); }); } diff --git a/libs/@local/hashql/mir/src/pass/mod.rs b/libs/@local/hashql/mir/src/pass/mod.rs index db73632b05d..70bb9480c9c 100644 --- a/libs/@local/hashql/mir/src/pass/mod.rs +++ b/libs/@local/hashql/mir/src/pass/mod.rs @@ -62,14 +62,15 @@ const fn simplify_type_name(name: &'static str) -> &'static str { /// /// Passes return this to signal whether they made changes, enabling the pass manager to skip /// dependent re-analyses when nothing changed. +#[must_use] #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum Changed { /// The pass definitely made modifications. - Yes, + Yes = 2, /// The pass may have made modifications, but precise tracking was not possible. - Unknown, + Unknown = 1, /// The pass made no modifications. - No, + No = 0, } impl Changed { diff --git a/libs/@local/hashql/mir/src/pass/transform/cfg_simplify/mod.rs b/libs/@local/hashql/mir/src/pass/transform/cfg_simplify/mod.rs index 9754cd17e01..a38753e3201 100644 --- a/libs/@local/hashql/mir/src/pass/transform/cfg_simplify/mod.rs +++ b/libs/@local/hashql/mir/src/pass/transform/cfg_simplify/mod.rs @@ -520,10 +520,13 @@ impl<'env, 'heap, A: BumpAllocator> TransformPass<'env, 'heap> for CfgSimplify( .format(DefIdSlice::from_raw(&bodies), &[]) .expect("should be able to write bodies"); - text_format - .writer - .extend(b"\n\n------------------------------------\n\n"); - - CfgSimplify::new().run(context, &mut bodies[0]); + let changed = CfgSimplify::new().run(context, &mut bodies[0]); + write!( + text_format.writer, + "\n\n{:=^50}\n\n", + format!(" Changed: {changed:?} ") + ) + .expect("infallible"); text_format .format(DefIdSlice::from_raw(&bodies), &[]) diff --git a/libs/@local/hashql/mir/src/pass/transform/cp/tests.rs b/libs/@local/hashql/mir/src/pass/transform/cp/tests.rs index 57575fa75f6..edeb495f9e7 100644 --- a/libs/@local/hashql/mir/src/pass/transform/cp/tests.rs +++ b/libs/@local/hashql/mir/src/pass/transform/cp/tests.rs @@ -1,6 +1,6 @@ #![expect(clippy::min_ident_chars, reason = "tests")] -use std::path::PathBuf; +use std::{io::Write as _, path::PathBuf}; use bstr::ByteVec as _; use hashql_core::{ @@ -49,11 +49,13 @@ fn assert_cp_pass<'heap>( .format(DefIdSlice::from_raw(&bodies), &[]) .expect("should be able to write bodies"); - text_format - .writer - .extend(b"\n\n------------------------------------\n\n"); - - CopyPropagation::new().run(context, &mut bodies[0]); + let changed = CopyPropagation::new().run(context, &mut bodies[0]); + write!( + text_format.writer, + "\n\n{:=^50}\n\n", + format!(" Changed: {changed:?} ") + ) + .expect("infallible"); text_format .format(DefIdSlice::from_raw(&bodies), &[]) diff --git a/libs/@local/hashql/mir/src/pass/transform/dbe/tests.rs b/libs/@local/hashql/mir/src/pass/transform/dbe/tests.rs index fe126d89089..e874d77352c 100644 --- a/libs/@local/hashql/mir/src/pass/transform/dbe/tests.rs +++ b/libs/@local/hashql/mir/src/pass/transform/dbe/tests.rs @@ -1,4 +1,4 @@ -use std::path::PathBuf; +use std::{io::Write as _, path::PathBuf}; use bstr::ByteVec as _; use hashql_core::{ @@ -40,11 +40,13 @@ fn assert_dbe_pass<'heap>( .format(DefIdSlice::from_raw(&bodies), &[]) .expect("should be able to write bodies"); - text_format - .writer - .extend(b"\n\n------------------------------------\n\n"); - - DeadBlockElimination::new_in(Scratch::new()).run(context, &mut bodies[0]); + let changed = DeadBlockElimination::new_in(Scratch::new()).run(context, &mut bodies[0]); + write!( + text_format.writer, + "\n\n{:=^50}\n\n", + format!(" Changed: {changed:?} ") + ) + .expect("infallible"); text_format .format(DefIdSlice::from_raw(&bodies), &[]) diff --git a/libs/@local/hashql/mir/src/pass/transform/dle/tests.rs b/libs/@local/hashql/mir/src/pass/transform/dle/tests.rs index d02e8476988..e4d79222aeb 100644 --- a/libs/@local/hashql/mir/src/pass/transform/dle/tests.rs +++ b/libs/@local/hashql/mir/src/pass/transform/dle/tests.rs @@ -1,6 +1,6 @@ #![expect(clippy::min_ident_chars, reason = "tests")] -use std::path::PathBuf; +use std::{io::Write as _, path::PathBuf}; use bstr::ByteVec as _; use hashql_core::{ @@ -42,11 +42,13 @@ fn assert_dle_pass<'heap>( .format(DefIdSlice::from_raw(&bodies), &[]) .expect("should be able to write bodies"); - text_format - .writer - .extend(b"\n\n------------------------------------\n\n"); - - DeadLocalElimination::new_in(Scratch::new()).run(context, &mut bodies[0]); + let changed = DeadLocalElimination::new_in(Scratch::new()).run(context, &mut bodies[0]); + write!( + text_format.writer, + "\n\n{:=^50}\n\n", + format!(" Changed: {changed:?} ") + ) + .expect("infallible"); text_format .format(DefIdSlice::from_raw(&bodies), &[]) diff --git a/libs/@local/hashql/mir/src/pass/transform/dse/tests.rs b/libs/@local/hashql/mir/src/pass/transform/dse/tests.rs index 0d7a22ad462..267c68f789b 100644 --- a/libs/@local/hashql/mir/src/pass/transform/dse/tests.rs +++ b/libs/@local/hashql/mir/src/pass/transform/dse/tests.rs @@ -1,5 +1,5 @@ #![expect(clippy::min_ident_chars, reason = "tests")] -use std::path::PathBuf; +use std::{io::Write as _, path::PathBuf}; use bstr::ByteVec as _; use hashql_core::{ @@ -49,11 +49,13 @@ fn assert_dse_pass<'heap>( .format(DefIdSlice::from_raw(&bodies), &[]) .expect("should be able to write bodies"); - text_format - .writer - .extend(b"\n\n------------------------------------\n\n"); - - DeadStoreElimination::new().run(context, &mut bodies[0]); + let changed = DeadStoreElimination::new().run(context, &mut bodies[0]); + write!( + text_format.writer, + "\n\n{:=^50}\n\n", + format!(" Changed: {changed:?} ") + ) + .expect("infallible"); text_format .format(DefIdSlice::from_raw(&bodies), &[]) diff --git a/libs/@local/hashql/mir/src/pass/transform/inst_simplify/tests.rs b/libs/@local/hashql/mir/src/pass/transform/inst_simplify/tests.rs index c7ee100a8b1..156fce63871 100644 --- a/libs/@local/hashql/mir/src/pass/transform/inst_simplify/tests.rs +++ b/libs/@local/hashql/mir/src/pass/transform/inst_simplify/tests.rs @@ -1,4 +1,4 @@ -use std::path::PathBuf; +use std::{io::Write as _, path::PathBuf}; use bstr::ByteVec as _; use hashql_core::{ @@ -43,11 +43,13 @@ fn assert_inst_simplify_pass<'heap>( .format(DefIdSlice::from_raw(&bodies), &[]) .expect("should be able to write bodies"); - text_format - .writer - .extend(b"\n\n------------------------------------\n\n"); - - InstSimplify::new().run(context, &mut bodies[0]); + let changed = InstSimplify::new().run(context, &mut bodies[0]); + write!( + text_format.writer, + "\n\n{:=^50}\n\n", + format!(" Changed: {changed:?} ") + ) + .expect("infallible"); text_format .format(DefIdSlice::from_raw(&bodies), &[]) diff --git a/libs/@local/hashql/mir/src/pass/transform/ssa_repair/tests.rs b/libs/@local/hashql/mir/src/pass/transform/ssa_repair/tests.rs index 99764e558df..d9a995f7577 100644 --- a/libs/@local/hashql/mir/src/pass/transform/ssa_repair/tests.rs +++ b/libs/@local/hashql/mir/src/pass/transform/ssa_repair/tests.rs @@ -1,4 +1,4 @@ -use std::path::PathBuf; +use std::{io::Write as _, path::PathBuf}; use bstr::ByteVec as _; use hashql_core::{ @@ -42,11 +42,13 @@ fn assert_ssa_pass<'heap>( .format(DefIdSlice::from_raw(&bodies), &[]) .expect("should be able to write bodies"); - text_format - .writer - .extend(b"\n\n------------------------------------\n\n"); - - SsaRepair::new().run(&mut context, &mut bodies[0]); + let changed = SsaRepair::new().run(&mut context, &mut bodies[0]); + write!( + text_format.writer, + "\n\n{:=^50}\n\n", + format!(" Changed: {changed:?} ") + ) + .expect("infallible"); text_format .format(DefIdSlice::from_raw(&bodies), &[]) diff --git a/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/identical_switch_targets.snap b/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/identical_switch_targets.snap index 979fa6036c8..42ad94aaeb4 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/identical_switch_targets.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/identical_switch_targets.snap @@ -16,7 +16,7 @@ fn {intrinsic#4294967040}() -> Null { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}() -> Null { let %0: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/no_inline_non_noop_multiple_preds.snap b/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/no_inline_non_noop_multiple_preds.snap index f173e96c3ee..5d18a794352 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/no_inline_non_noop_multiple_preds.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/no_inline_non_noop_multiple_preds.snap @@ -30,7 +30,7 @@ fn {intrinsic#4294967040}(%0: Integer) -> Null { } } ------------------------------------- +================== Changed: No =================== fn {intrinsic#4294967040}(%0: Integer) -> Null { let %1: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/noop_block_multiple_predecessors.snap b/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/noop_block_multiple_predecessors.snap index 7812715c59d..050e8f4c682 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/noop_block_multiple_predecessors.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/noop_block_multiple_predecessors.snap @@ -28,7 +28,7 @@ fn {intrinsic#4294967040}() -> Null { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}() -> Null { let %0: Boolean diff --git a/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/only_otherwise_switch.snap b/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/only_otherwise_switch.snap index a0c35c72955..e21edd4050c 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/only_otherwise_switch.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/only_otherwise_switch.snap @@ -16,7 +16,7 @@ fn {intrinsic#4294967040}() -> Null { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}() -> Null { let %0: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/redundant_cases_removal.snap b/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/redundant_cases_removal.snap index 68498896d98..8ba4eb727ad 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/redundant_cases_removal.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/redundant_cases_removal.snap @@ -20,7 +20,7 @@ fn {intrinsic#4294967040}() -> Null { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}() -> Null { let %0: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/self_loop_preservation.snap b/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/self_loop_preservation.snap index 0bf820ab564..f1b12eff07d 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/self_loop_preservation.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/self_loop_preservation.snap @@ -12,7 +12,7 @@ fn {intrinsic#4294967040}() -> Null { } } ------------------------------------- +================== Changed: No =================== fn {intrinsic#4294967040}() -> Null { bb0(): { diff --git a/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/self_loop_preservation_with_params.snap b/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/self_loop_preservation_with_params.snap index bb0d70c8503..36f18325db0 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/self_loop_preservation_with_params.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/self_loop_preservation_with_params.snap @@ -14,7 +14,7 @@ fn {intrinsic#4294967040}() -> Null { } } ------------------------------------- +================== Changed: No =================== fn {intrinsic#4294967040}() -> Null { let %0: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/switch_promotion_with_goto_params.snap b/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/switch_promotion_with_goto_params.snap index 39b541b406b..e4e62195a6c 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/switch_promotion_with_goto_params.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/switch_promotion_with_goto_params.snap @@ -32,7 +32,7 @@ fn {intrinsic#4294967040}() -> Null { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}() -> Null { let %0: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/switch_self_loop_preservation.snap b/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/switch_self_loop_preservation.snap index d5735d12444..7f8c372be0f 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/switch_self_loop_preservation.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/switch_self_loop_preservation.snap @@ -20,7 +20,7 @@ fn {intrinsic#4294967040}() -> Null { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}() -> Null { let %0: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/switch_target_promotion.snap b/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/switch_target_promotion.snap index a7ad770c58f..e62bf1a835c 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/switch_target_promotion.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/switch_target_promotion.snap @@ -28,7 +28,7 @@ fn {intrinsic#4294967040}() -> Null { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}() -> Null { let %0: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/unreachable_switch_arm_ice.snap b/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/unreachable_switch_arm_ice.snap index 13edab21fe9..972f50469b1 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/unreachable_switch_arm_ice.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/unreachable_switch_arm_ice.snap @@ -16,7 +16,7 @@ fn {intrinsic#4294967040}() -> Null { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}() -> Null { bb0(): { diff --git a/libs/@local/hashql/mir/tests/ui/pass/cp/block_param_disagreement.snap b/libs/@local/hashql/mir/tests/ui/pass/cp/block_param_disagreement.snap index 8774f3e0959..65ec81588f6 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/cp/block_param_disagreement.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/cp/block_param_disagreement.snap @@ -28,7 +28,7 @@ fn {intrinsic#4294967040}() -> Boolean { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}() -> Boolean { let %0: Boolean diff --git a/libs/@local/hashql/mir/tests/ui/pass/cp/block_param_effectful.snap b/libs/@local/hashql/mir/tests/ui/pass/cp/block_param_effectful.snap index d82a34c135d..ebf5bcba0fa 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/cp/block_param_effectful.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/cp/block_param_effectful.snap @@ -22,7 +22,7 @@ fn {intrinsic#4294967040}(%0: ?) -> Boolean { } } ------------------------------------- +================== Changed: No =================== fn {intrinsic#4294967040}(%0: ?) -> Boolean { let %1: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/cp/block_param_unanimous.snap b/libs/@local/hashql/mir/tests/ui/pass/cp/block_param_unanimous.snap index 553b7e7985a..ebb75ae5982 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/cp/block_param_unanimous.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/cp/block_param_unanimous.snap @@ -28,7 +28,7 @@ fn {intrinsic#4294967040}() -> Boolean { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}() -> Boolean { let %0: Boolean diff --git a/libs/@local/hashql/mir/tests/ui/pass/cp/block_param_via_local.snap b/libs/@local/hashql/mir/tests/ui/pass/cp/block_param_via_local.snap index a9cc1677e5f..183c2a51636 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/cp/block_param_via_local.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/cp/block_param_via_local.snap @@ -20,7 +20,7 @@ fn {intrinsic#4294967040}() -> Boolean { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}() -> Boolean { let %0: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/cp/constant_chain.snap b/libs/@local/hashql/mir/tests/ui/pass/cp/constant_chain.snap index 869bd6aa199..17e48d263a4 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/cp/constant_chain.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/cp/constant_chain.snap @@ -18,7 +18,7 @@ fn {intrinsic#4294967040}() -> Boolean { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}() -> Boolean { let %0: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/cp/loop_back_edge.snap b/libs/@local/hashql/mir/tests/ui/pass/cp/loop_back_edge.snap index dbb947c404d..8943f06c704 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/cp/loop_back_edge.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/cp/loop_back_edge.snap @@ -24,7 +24,7 @@ fn {intrinsic#4294967040}() -> Boolean { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}() -> Boolean { let %0: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/cp/projection_unchanged.snap b/libs/@local/hashql/mir/tests/ui/pass/cp/projection_unchanged.snap index 9a6fdabf992..9de90f74399 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/cp/projection_unchanged.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/cp/projection_unchanged.snap @@ -16,7 +16,7 @@ fn {intrinsic#4294967040}() -> Boolean { } } ------------------------------------- +================== Changed: No =================== fn {intrinsic#4294967040}() -> Boolean { let %0: (Integer, Integer) diff --git a/libs/@local/hashql/mir/tests/ui/pass/cp/single_constant.snap b/libs/@local/hashql/mir/tests/ui/pass/cp/single_constant.snap index dc817a19b82..118a83bac84 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/cp/single_constant.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/cp/single_constant.snap @@ -14,7 +14,7 @@ fn {intrinsic#4294967040}() -> Boolean { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}() -> Boolean { let %0: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/dbe/all_reachable.snap b/libs/@local/hashql/mir/tests/ui/pass/dbe/all_reachable.snap index 97e81eda368..6444c386aaf 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/dbe/all_reachable.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/dbe/all_reachable.snap @@ -12,7 +12,7 @@ fn {intrinsic#4294967040}() -> Null { } } ------------------------------------- +================== Changed: No =================== fn {intrinsic#4294967040}() -> Null { bb0(): { diff --git a/libs/@local/hashql/mir/tests/ui/pass/dbe/block_params_preserved.snap b/libs/@local/hashql/mir/tests/ui/pass/dbe/block_params_preserved.snap index 569364cac48..ddb23616958 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/dbe/block_params_preserved.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/dbe/block_params_preserved.snap @@ -21,7 +21,7 @@ fn {intrinsic#4294967040}() -> Null { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}() -> Null { let %0: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/dbe/multiple_unreachable_at_end.snap b/libs/@local/hashql/mir/tests/ui/pass/dbe/multiple_unreachable_at_end.snap index 56c700d4b17..33b6287aa7c 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/dbe/multiple_unreachable_at_end.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/dbe/multiple_unreachable_at_end.snap @@ -20,7 +20,7 @@ fn {intrinsic#4294967040}() -> Null { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}() -> Null { bb0(): { diff --git a/libs/@local/hashql/mir/tests/ui/pass/dbe/scattered_unreachable.snap b/libs/@local/hashql/mir/tests/ui/pass/dbe/scattered_unreachable.snap index 91374151313..a4e61f79960 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/dbe/scattered_unreachable.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/dbe/scattered_unreachable.snap @@ -24,7 +24,7 @@ fn {intrinsic#4294967040}() -> Null { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}() -> Null { bb0(): { diff --git a/libs/@local/hashql/mir/tests/ui/pass/dbe/single_unreachable_at_end.snap b/libs/@local/hashql/mir/tests/ui/pass/dbe/single_unreachable_at_end.snap index 9b21ac6a069..33cc4ea5f45 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/dbe/single_unreachable_at_end.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/dbe/single_unreachable_at_end.snap @@ -12,7 +12,7 @@ fn {intrinsic#4294967040}() -> Null { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}() -> Null { bb0(): { diff --git a/libs/@local/hashql/mir/tests/ui/pass/dbe/switch_target_remapping.snap b/libs/@local/hashql/mir/tests/ui/pass/dbe/switch_target_remapping.snap index 0b87db5da07..04eff79ecd6 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/dbe/switch_target_remapping.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/dbe/switch_target_remapping.snap @@ -20,7 +20,7 @@ fn {intrinsic#4294967040}(%0: Integer) -> Null { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}(%0: Integer) -> Null { bb0(): { diff --git a/libs/@local/hashql/mir/tests/ui/pass/dbe/unreachable_chain.snap b/libs/@local/hashql/mir/tests/ui/pass/dbe/unreachable_chain.snap index 47efb8ab310..4b91dbe2e70 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/dbe/unreachable_chain.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/dbe/unreachable_chain.snap @@ -20,7 +20,7 @@ fn {intrinsic#4294967040}() -> Null { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}() -> Null { bb0(): { diff --git a/libs/@local/hashql/mir/tests/ui/pass/dbe/unreachable_in_middle.snap b/libs/@local/hashql/mir/tests/ui/pass/dbe/unreachable_in_middle.snap index 323d681d02a..734bd0ef550 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/dbe/unreachable_in_middle.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/dbe/unreachable_in_middle.snap @@ -16,7 +16,7 @@ fn {intrinsic#4294967040}() -> Null { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}() -> Null { bb0(): { diff --git a/libs/@local/hashql/mir/tests/ui/pass/dle/all_live.snap b/libs/@local/hashql/mir/tests/ui/pass/dle/all_live.snap index 63ecfacf71b..68406a3d2bc 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/dle/all_live.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/dle/all_live.snap @@ -14,7 +14,7 @@ fn {intrinsic#4294967040}() -> Integer { } } ------------------------------------- +================== Changed: No =================== fn {intrinsic#4294967040}() -> Integer { let %0: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/dle/dead_in_middle.snap b/libs/@local/hashql/mir/tests/ui/pass/dle/dead_in_middle.snap index 299a3b9b3c2..3c2afe72164 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/dle/dead_in_middle.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/dle/dead_in_middle.snap @@ -15,7 +15,7 @@ fn {intrinsic#4294967040}() -> Integer { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}() -> Integer { let %0: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/dle/projection_locals_preserved.snap b/libs/@local/hashql/mir/tests/ui/pass/dle/projection_locals_preserved.snap index 230cf6d6112..504ff9fbe1a 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/dle/projection_locals_preserved.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/dle/projection_locals_preserved.snap @@ -14,7 +14,7 @@ fn {intrinsic#4294967040}(%0: List) -> Integer { } } ------------------------------------- +================== Changed: No =================== fn {intrinsic#4294967040}(%0: List) -> Integer { let %1: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/dle/scattered_dead.snap b/libs/@local/hashql/mir/tests/ui/pass/dle/scattered_dead.snap index 51d4c8559ce..699b7e3d0f4 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/dle/scattered_dead.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/dle/scattered_dead.snap @@ -18,7 +18,7 @@ fn {intrinsic#4294967040}() -> Integer { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}() -> Integer { let %0: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/dle/single_dead_at_end.snap b/libs/@local/hashql/mir/tests/ui/pass/dle/single_dead_at_end.snap index 2bfc6107673..c32d6e27aab 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/dle/single_dead_at_end.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/dle/single_dead_at_end.snap @@ -13,7 +13,7 @@ fn {intrinsic#4294967040}() -> Integer { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}() -> Integer { let %0: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/dle/unused_args_preserved.snap b/libs/@local/hashql/mir/tests/ui/pass/dle/unused_args_preserved.snap index 76037d96979..fd344141d78 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/dle/unused_args_preserved.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/dle/unused_args_preserved.snap @@ -12,7 +12,7 @@ fn {intrinsic#4294967040}(%0: Integer, %1: Integer) -> Integer { } } ------------------------------------- +================== Changed: No =================== fn {intrinsic#4294967040}(%0: Integer, %1: Integer) -> Integer { let %2: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/dse/all_live.snap b/libs/@local/hashql/mir/tests/ui/pass/dse/all_live.snap index 124d41dc29b..d858ab7cca2 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/dse/all_live.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/dse/all_live.snap @@ -14,7 +14,7 @@ fn {intrinsic#4294967040}() -> Integer { } } ------------------------------------- +================== Changed: No =================== fn {intrinsic#4294967040}() -> Integer { let %0: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/dse/branch_condition_preserved.snap b/libs/@local/hashql/mir/tests/ui/pass/dse/branch_condition_preserved.snap index 84f4551c9a7..46745141412 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/dse/branch_condition_preserved.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/dse/branch_condition_preserved.snap @@ -22,7 +22,7 @@ fn {intrinsic#4294967040}() -> Integer { } } ------------------------------------- +================== Changed: No =================== fn {intrinsic#4294967040}() -> Integer { let %0: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/dse/dead_chain.snap b/libs/@local/hashql/mir/tests/ui/pass/dse/dead_chain.snap index 84de733a130..b32fc3dd061 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/dse/dead_chain.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/dse/dead_chain.snap @@ -18,7 +18,7 @@ fn {intrinsic#4294967040}() -> Integer { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}() -> Integer { let %0: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/dse/dead_cycle.snap b/libs/@local/hashql/mir/tests/ui/pass/dse/dead_cycle.snap index b77a9690295..7fa750b4d89 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/dse/dead_cycle.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/dse/dead_cycle.snap @@ -17,7 +17,7 @@ fn {intrinsic#4294967040}(%0: Integer) -> Integer { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}(%0: Integer) -> Integer { bb0(): { diff --git a/libs/@local/hashql/mir/tests/ui/pass/dse/dead_param_multiple_predecessors.snap b/libs/@local/hashql/mir/tests/ui/pass/dse/dead_param_multiple_predecessors.snap index 1f2e4f71fb4..0ba842ffffe 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/dse/dead_param_multiple_predecessors.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/dse/dead_param_multiple_predecessors.snap @@ -26,7 +26,7 @@ fn {intrinsic#4294967040}() -> Integer { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}() -> Integer { let %0: Boolean diff --git a/libs/@local/hashql/mir/tests/ui/pass/dse/dead_param_with_live_sibling.snap b/libs/@local/hashql/mir/tests/ui/pass/dse/dead_param_with_live_sibling.snap index ab7e9dc213e..639c94d1614 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/dse/dead_param_with_live_sibling.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/dse/dead_param_with_live_sibling.snap @@ -15,7 +15,7 @@ fn {intrinsic#4294967040}() -> Integer { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}() -> Integer { let %0: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/dse/dead_storage_statements.snap b/libs/@local/hashql/mir/tests/ui/pass/dse/dead_storage_statements.snap index 24d75f5effd..dc6a368b4cc 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/dse/dead_storage_statements.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/dse/dead_storage_statements.snap @@ -16,7 +16,7 @@ fn {intrinsic#4294967040}() -> Integer { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}() -> Integer { let %0: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/dse/graph_read_token_preserved.snap b/libs/@local/hashql/mir/tests/ui/pass/dse/graph_read_token_preserved.snap index 497ba3c1ffe..860badd3f0a 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/dse/graph_read_token_preserved.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/dse/graph_read_token_preserved.snap @@ -18,7 +18,7 @@ fn {intrinsic#4294967040}(%0: ?) -> Integer { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}(%0: ?) -> Integer { let %1: GraphToken diff --git a/libs/@local/hashql/mir/tests/ui/pass/dse/single_dead_assignment.snap b/libs/@local/hashql/mir/tests/ui/pass/dse/single_dead_assignment.snap index b0130a746a1..cfe22d04d27 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/dse/single_dead_assignment.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/dse/single_dead_assignment.snap @@ -14,7 +14,7 @@ fn {intrinsic#4294967040}() -> Integer { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}() -> Integer { let %0: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/block_param_predecessors_agree.snap b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/block_param_predecessors_agree.snap index 20b9a6549b4..304eeaf09b3 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/block_param_predecessors_agree.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/block_param_predecessors_agree.snap @@ -25,7 +25,7 @@ fn {intrinsic#4294967040}(%0: Integer) -> Boolean { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}(%0: Integer) -> Boolean { let %1: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/block_param_predecessors_disagree.snap b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/block_param_predecessors_disagree.snap index 12918418674..9ac1ea2ac51 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/block_param_predecessors_disagree.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/block_param_predecessors_disagree.snap @@ -25,7 +25,7 @@ fn {intrinsic#4294967040}(%0: Integer) -> Boolean { } } ------------------------------------- +================== Changed: No =================== fn {intrinsic#4294967040}(%0: Integer) -> Boolean { let %1: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/block_param_single_predecessor.snap b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/block_param_single_predecessor.snap index a7f60fc8baf..888b40a78ce 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/block_param_single_predecessor.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/block_param_single_predecessor.snap @@ -17,7 +17,7 @@ fn {intrinsic#4294967040}() -> Boolean { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}() -> Boolean { let %0: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const_fold_bit_and.snap b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const_fold_bit_and.snap index bbc9335b167..8fcaa838f04 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const_fold_bit_and.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const_fold_bit_and.snap @@ -12,7 +12,7 @@ fn {intrinsic#4294967040}() -> Integer { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}() -> Integer { let %0: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const_fold_bit_or.snap b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const_fold_bit_or.snap index 40e2c225d4e..50adf11e525 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const_fold_bit_or.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const_fold_bit_or.snap @@ -12,7 +12,7 @@ fn {intrinsic#4294967040}() -> Integer { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}() -> Integer { let %0: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const_fold_unary_neg.snap b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const_fold_unary_neg.snap index 71f0e8c78ab..9cfb22e68aa 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const_fold_unary_neg.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const_fold_unary_neg.snap @@ -12,7 +12,7 @@ fn {intrinsic#4294967040}() -> Integer { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}() -> Integer { let %0: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const_fold_unary_not.snap b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const_fold_unary_not.snap index a6f3582d2c9..479bf1209ed 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const_fold_unary_not.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const_fold_unary_not.snap @@ -12,7 +12,7 @@ fn {intrinsic#4294967040}() -> Boolean { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}() -> Boolean { let %0: Boolean diff --git a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/idempotent_to_const_forwarding.snap b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/idempotent_to_const_forwarding.snap index 85acef647b9..9b9f2809ace 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/idempotent_to_const_forwarding.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/idempotent_to_const_forwarding.snap @@ -16,7 +16,7 @@ fn {intrinsic#4294967040}() -> Boolean { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}() -> Boolean { let %0: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/identical_operand_bit_and.snap b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/identical_operand_bit_and.snap index 19728b0aa72..5a782fc863f 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/identical_operand_bit_and.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/identical_operand_bit_and.snap @@ -12,7 +12,7 @@ fn {intrinsic#4294967040}(%0: Integer) -> Integer { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}(%0: Integer) -> Integer { let %1: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/identical_operand_bit_or.snap b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/identical_operand_bit_or.snap index a94d4c7eb87..6094667212a 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/identical_operand_bit_or.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/identical_operand_bit_or.snap @@ -12,7 +12,7 @@ fn {intrinsic#4294967040}(%0: Integer) -> Integer { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}(%0: Integer) -> Integer { let %1: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/identity_bit_or_zero.snap b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/identity_bit_or_zero.snap index fb533c0d2eb..eae86da8708 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/identity_bit_or_zero.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/identity_bit_or_zero.snap @@ -12,7 +12,7 @@ fn {intrinsic#4294967040}(%0: Integer) -> Integer { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}(%0: Integer) -> Integer { let %1: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/diamond_both_branches_define.snap b/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/diamond_both_branches_define.snap index 808a8e10cce..47d60940f38 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/diamond_both_branches_define.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/diamond_both_branches_define.snap @@ -31,7 +31,7 @@ fn {intrinsic#4294967040}() -> Null { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}() -> Null { let %0: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/diamond_one_branch_redefines.snap b/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/diamond_one_branch_redefines.snap index a1e055fe7a1..56b1091bfa8 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/diamond_one_branch_redefines.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/diamond_one_branch_redefines.snap @@ -30,7 +30,7 @@ fn {intrinsic#4294967040}() -> Null { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}() -> Null { let %0: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/irreducible.snap b/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/irreducible.snap index 022e9d34a00..149718767d7 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/irreducible.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/irreducible.snap @@ -37,7 +37,7 @@ fn {intrinsic#4294967040}() -> Null { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}() -> Null { let %0: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/linear.snap b/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/linear.snap index ae8568c5873..29f97e19f8f 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/linear.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/linear.snap @@ -20,7 +20,7 @@ fn {intrinsic#4294967040}() -> Null { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}() -> Null { let %0: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/loop_with_conditional_def.snap b/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/loop_with_conditional_def.snap index bfc43bf81cd..85d6a66f44d 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/loop_with_conditional_def.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/loop_with_conditional_def.snap @@ -41,7 +41,7 @@ fn {intrinsic#4294967040}() -> Null { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}() -> Null { let %0: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/multiple_defs_same_block.snap b/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/multiple_defs_same_block.snap index accc88432ce..26013a3630e 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/multiple_defs_same_block.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/multiple_defs_same_block.snap @@ -16,7 +16,7 @@ fn {intrinsic#4294967040}() -> Null { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}() -> Null { let %0: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/multiple_variables_violated.snap b/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/multiple_variables_violated.snap index b87bf381b9a..d34813f581c 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/multiple_variables_violated.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/multiple_variables_violated.snap @@ -35,7 +35,7 @@ fn {intrinsic#4294967040}() -> Null { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}() -> Null { let %0: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/nested_loop.snap b/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/nested_loop.snap index 6369b772f2d..c6bfde15f82 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/nested_loop.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/nested_loop.snap @@ -35,7 +35,7 @@ fn {intrinsic#4294967040}() -> Null { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}() -> Null { let %0: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/passthrough_chain.snap b/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/passthrough_chain.snap index 0fff8f9e00f..4194c510b3e 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/passthrough_chain.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/passthrough_chain.snap @@ -28,7 +28,7 @@ fn {intrinsic#4294967040}() -> Null { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}() -> Null { let %0: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/reassign_rodeo.snap b/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/reassign_rodeo.snap index bdf05bb031e..172a8c6f3d0 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/reassign_rodeo.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/reassign_rodeo.snap @@ -17,7 +17,7 @@ fn {intrinsic#4294967040}() -> Null { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}() -> Null { let %0: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/simple_loop.snap b/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/simple_loop.snap index 76a77de3118..c74daee92da 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/simple_loop.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/simple_loop.snap @@ -25,7 +25,7 @@ fn {intrinsic#4294967040}() -> Null { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}() -> Null { let %0: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/single_def_use.snap b/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/single_def_use.snap index 9b963d859ef..c2a891bc4a7 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/single_def_use.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/single_def_use.snap @@ -14,7 +14,7 @@ fn {intrinsic#4294967040}() -> Null { } } ------------------------------------- +================== Changed: No =================== fn {intrinsic#4294967040}() -> Null { let %0: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/three_way_merge.snap b/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/three_way_merge.snap index a8c89060527..057ea028e38 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/three_way_merge.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/three_way_merge.snap @@ -38,7 +38,7 @@ fn {intrinsic#4294967040}() -> Null { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}() -> Null { let %0: Integer diff --git a/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/use_before_def_in_block.snap b/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/use_before_def_in_block.snap index b2549d4e6ca..54172a3850b 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/use_before_def_in_block.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/ssa_repair/use_before_def_in_block.snap @@ -20,7 +20,7 @@ fn {intrinsic#4294967040}() -> Null { } } ------------------------------------- +================== Changed: Yes ================== fn {intrinsic#4294967040}() -> Null { let %0: Integer From 65c338167af4e0a2081c94ebecca68a578f269df Mon Sep 17 00:00:00 2001 From: Bilal Mahmoud Date: Mon, 22 Dec 2025 13:03:01 +0100 Subject: [PATCH 3/3] feat: update skill --- .claude/skills/testing-hashql/SKILL.md | 14 +++++++++---- .../references/mir-builder-guide.md | 21 ++++++++++++------- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/.claude/skills/testing-hashql/SKILL.md b/.claude/skills/testing-hashql/SKILL.md index 7bdfd1ce9af..af639962bc4 100644 --- a/.claude/skills/testing-hashql/SKILL.md +++ b/.claude/skills/testing-hashql/SKILL.md @@ -180,6 +180,12 @@ For testing MIR transformation and analysis passes directly with programmaticall - Edge cases requiring specific MIR structures hard to produce from source - Benchmarking pass performance +**Key features:** + +- Transform passes return `Changed` enum (`Yes`, `No`, `Unknown`) to indicate modifications +- Test harness captures and includes `Changed` value in snapshots for verification +- Snapshot format: before MIR → `Changed: Yes/No/Unknown` separator → after MIR + **Quick Example:** ```rust @@ -201,10 +207,10 @@ builder let body = builder.finish(0, TypeBuilder::synthetic(&env).integer()); ``` -📖 **Full Guide:** [resources/mir-builder-guide.md](resources/mir-builder-guide.md) +📖 **Full Guide:** [references/mir-builder-guide.md](references/mir-builder-guide.md) ## References -- [compiletest Guide](resources/compiletest-guide.md) - Detailed UI test documentation -- [Testing Strategies](resources/testing-strategies.md) - Choosing the right approach -- [MIR Builder Guide](resources/mir-builder-guide.md) - Programmatic MIR construction for tests +- [compiletest Guide](references/compiletest-guide.md) - Detailed UI test documentation +- [Testing Strategies](references/testing-strategies.md) - Choosing the right approach +- [MIR Builder Guide](references/mir-builder-guide.md) - Programmatic MIR construction for tests diff --git a/.claude/skills/testing-hashql/references/mir-builder-guide.md b/.claude/skills/testing-hashql/references/mir-builder-guide.md index 7b6190c4541..a71e78d5376 100644 --- a/.claude/skills/testing-hashql/references/mir-builder-guide.md +++ b/.claude/skills/testing-hashql/references/mir-builder-guide.md @@ -228,10 +228,11 @@ builder.build_block(bb_merge).ret(x); // x receives value from param ## Test Harness Pattern -Standard pattern used across transform pass tests: +Standard pattern used across transform pass tests. The harness captures and displays +the `Changed` return value to verify pass behavior: ```rust -use std::path::PathBuf; +use std::{io::Write as _, path::PathBuf}; use bstr::ByteVec as _; use hashql_core::{ pretty::Formatter, @@ -274,12 +275,16 @@ fn assert_pass<'heap>( .format(DefIdSlice::from_raw(&bodies), &[]) .expect("should be able to write bodies"); - text_format - .writer - .extend(b"\n\n------------------------------------\n\n"); - - // Run the pass - YourPass::new().run(context, &mut bodies[0]); + // Run the pass and capture change status + let changed = YourPass::new().run(context, &mut bodies[0]); + + // Include Changed value in snapshot for verification + write!( + text_format.writer, + "\n\n{:=^50}\n\n", + format!(" Changed: {changed:?} ") + ) + .expect("infallible"); // Format after text_format