From 9089f9ddb49820671a1e65ad2a886aec56b2a928 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Tue, 9 Dec 2025 23:14:24 -0800 Subject: [PATCH] use branch numbers to detect branch subsumption --- src/codegen.rs | 17 +++-- src/debray_allocator.rs | 64 ++++++++---------- src/forms.rs | 95 +++++++++++++++++++++++--- src/iterators.rs | 58 +++++++++++----- src/machine/disjuncts.rs | 140 +++++++++++---------------------------- src/variable_records.rs | 25 +++---- 6 files changed, 218 insertions(+), 181 deletions(-) diff --git a/src/codegen.rs b/src/codegen.rs index 67ba2dbf..19d056d6 100644 --- a/src/codegen.rs +++ b/src/codegen.rs @@ -994,20 +994,27 @@ impl CodeGenerator { self.marker.in_tail_position = false; self.marker.reset_contents(); } - ClauseItem::FirstBranch(num_branches) => { + ClauseItem::FirstBranch { + branch_num, + num_branches, + } => { branch_code_stack.add_new_branch_stack(); branch_code_stack.add_new_branch(); - self.marker.branch_stack.add_branch_stack(num_branches); + self.marker + .branch_stack + .add_branch_stack(branch_num.clone(), num_branches); self.marker.add_branch(); } - ClauseItem::NextBranch => { + ClauseItem::NextBranch { branch_num } => { branch_code_stack.add_new_branch(); self.marker.add_branch(); - self.marker.branch_stack.incr_current_branch(); + self.marker + .branch_stack + .incr_current_branch(branch_num.clone()); } - ClauseItem::BranchEnd(depth) => { + ClauseItem::BranchEnd { depth } => { if !clause_iter.in_tail_position() { let subsumed_hits = branch_code_stack.push_missing_vars(depth, &mut self.marker); diff --git a/src/debray_allocator.rs b/src/debray_allocator.rs index 7fe37259..d214b8c7 100644 --- a/src/debray_allocator.rs +++ b/src/debray_allocator.rs @@ -1,6 +1,6 @@ use crate::allocator::*; use crate::codegen::SubsumedBranchHits; -use crate::forms::{GenContext, Level}; +use crate::forms::{BranchNumber, GenContext, Level}; use crate::instructions::*; use crate::machine::disjuncts::VarData; use crate::parser::ast::*; @@ -24,24 +24,26 @@ pub struct BranchOccurrences { pub shallow_safety: BitSet, // unset means safe, set means unsafe (after the branch merge) pub deep_safety: BitSet, pub num_branches: usize, - pub current_branch: usize, + pub current_branch_idx: usize, + pub current_branch_num: BranchNumber, pub subsumed_hits: SubsumedBranchHits, } impl BranchOccurrences { - fn new(num_branches: usize) -> Self { + fn new(current_branch_num: BranchNumber, num_branches: usize) -> Self { Self { hits: BranchHits::with_hasher(FxBuildHasher::default()), shallow_safety: BitSet::default(), deep_safety: BitSet::default(), num_branches, - current_branch: 0, + current_branch_idx: 0, + current_branch_num, subsumed_hits: SubsumedBranchHits::with_hasher(FxBuildHasher::default()), } } pub(crate) fn add_branch_occurrence(&mut self, var_num: usize) { - debug_assert!(self.current_branch < self.num_branches); + debug_assert!(self.current_branch_idx < self.num_branches); let num_branches = self.num_branches; let entry = self @@ -49,7 +51,7 @@ impl BranchOccurrences { .entry(var_num) .or_insert_with(|| BitVec::repeat(false, num_branches)); - entry.set(self.current_branch, true); + entry.set(self.current_branch_idx, true); self.subsumed_hits.insert(var_num); } } @@ -76,19 +78,6 @@ impl DerefMut for BranchStack { } impl BranchStack { - fn branch_subsumes(&self, branch: &BranchDesignator, sub_branch: &BranchDesignator) -> bool { - if branch.branch_stack_num < sub_branch.branch_stack_num { - if branch.branch_stack_num == 0 { - true - } else { - let idx = branch.branch_stack_num - 1; - self[idx].current_branch == branch.branch_num - } - } else { - branch == sub_branch - } - } - fn safety_unneeded_in_branch( &self, safety: &VarSafetyStatus, @@ -97,7 +86,7 @@ impl BranchStack { match safety { VarSafetyStatus::Needed => false, VarSafetyStatus::LocallyUnneeded(planter_branch) => { - self.branch_subsumes(planter_branch, branch) + planter_branch.branch_num.has_as_subbranch(&branch.branch_num) } VarSafetyStatus::GloballyUnneeded => true, } @@ -109,27 +98,26 @@ impl BranchStack { } } - pub(crate) fn add_branch_stack(&mut self, num_branches: usize) { - self.push(BranchOccurrences::new(num_branches)); + pub(crate) fn add_branch_stack(&mut self, branch_num: BranchNumber, num_branches: usize) { + self.push(BranchOccurrences::new(branch_num, num_branches)); } pub(crate) fn current_branch_designator(&self) -> BranchDesignator { - let branch_stack_num = self.len(); let branch_num = self .last() - .map(|occurrences| occurrences.current_branch) - .unwrap_or(0); + .map(|occurrences| occurrences.current_branch_num.clone()) + .unwrap_or_else(|| BranchNumber::default()); BranchDesignator { - branch_stack_num, branch_num, } } #[inline] - pub(crate) fn incr_current_branch(&mut self) { + pub(crate) fn incr_current_branch(&mut self, branch_num: BranchNumber) { let branch_occurrences = self.last_mut().unwrap(); - branch_occurrences.current_branch += 1; + branch_occurrences.current_branch_idx += 1; + branch_occurrences.current_branch_num = branch_num; } #[inline] @@ -235,12 +223,12 @@ impl DebrayAllocator { VarAlloc::Perm(_, allocation) => { let shallow_safety = VarSafetyStatus::needed_if( shallow_safety.contains(var_num), - branch_designator, + &branch_designator, ); let deep_safety = VarSafetyStatus::needed_if( deep_safety.contains(var_num), - branch_designator, + &branch_designator, ); if running_count < num_occurrences { @@ -531,11 +519,11 @@ impl DebrayAllocator { .. }, ) => { - *deep_safety = VarSafetyStatus::unneeded(branch_designator); - *shallow_safety = VarSafetyStatus::unneeded(branch_designator); + *deep_safety = VarSafetyStatus::unneeded(&branch_designator); + *shallow_safety = VarSafetyStatus::unneeded(&branch_designator); } VarAlloc::Temp { safety, .. } => { - *safety = VarSafetyStatus::unneeded(branch_designator); + *safety = VarSafetyStatus::unneeded(&branch_designator); } _ => { unreachable!() @@ -557,8 +545,8 @@ impl DebrayAllocator { ) => { // GetVariable in head chunk is considered safe. if lvl == Level::Deep { - *deep_safety = VarSafetyStatus::unneeded(branch_designator); - *shallow_safety = VarSafetyStatus::unneeded(branch_designator); + *deep_safety = VarSafetyStatus::unneeded(&branch_designator); + *shallow_safety = VarSafetyStatus::unneeded(&branch_designator); } else if term_loc == GenContext::Head { *shallow_safety = VarSafetyStatus::GloballyUnneeded; } else if let Some(&temp_var_num) = self.shallow_temp_mappings.get(&self.arg_c) { @@ -605,7 +593,7 @@ impl DebrayAllocator { { Target::argument_to_value(r, arg_c) } else { - *shallow_safety = VarSafetyStatus::unneeded(branch_designator); + *shallow_safety = VarSafetyStatus::unneeded(&branch_designator); Target::unsafe_argument_to_value(r, arg_c) } } @@ -640,7 +628,7 @@ impl DebrayAllocator { { Target::subterm_to_value(r) } else { - *deep_safety = VarSafetyStatus::unneeded(branch_designator); + *deep_safety = VarSafetyStatus::unneeded(&branch_designator); Target::unsafe_subterm_to_value(r) } } @@ -651,7 +639,7 @@ impl DebrayAllocator { { Target::subterm_to_value(r) } else { - *safety = VarSafetyStatus::unneeded(branch_designator); + *safety = VarSafetyStatus::unneeded(&branch_designator); Target::unsafe_subterm_to_value(r) } } diff --git a/src/forms.rs b/src/forms.rs index ae9b829d..447328f7 100644 --- a/src/forms.rs +++ b/src/forms.rs @@ -18,9 +18,11 @@ use indexmap::{IndexMap, IndexSet}; use ordered_float::OrderedFloat; use std::cell::Cell; +use std::cmp::Ordering; use std::collections::VecDeque; use std::convert::TryFrom; use std::fmt; +use std::hash::{Hash, Hasher}; use std::ops::{AddAssign, Deref, DerefMut}; use std::path::PathBuf; @@ -128,10 +130,86 @@ impl ChunkType { } } +#[derive(Debug, Clone)] //, PartialOrd, PartialEq, Eq, Hash)] +pub(crate) struct BranchNumber { + pub(crate) branch_num: Rational, + pub(crate) delta: Rational, +} + +impl Default for BranchNumber { + fn default() -> Self { + Self { + branch_num: Rational::from(0), + delta: Rational::from(1u64 << 31), + } + } +} + +impl PartialEq for BranchNumber { + #[inline] + fn eq(&self, rhs: &BranchNumber) -> bool { + self.branch_num == rhs.branch_num + } +} + +impl Eq for BranchNumber {} + +impl Hash for BranchNumber { + #[inline(always)] + fn hash(&self, hasher: &mut H) { + self.branch_num.hash(hasher) + } +} + +impl PartialOrd for BranchNumber { + #[inline] + fn partial_cmp(&self, rhs: &BranchNumber) -> Option { + self.branch_num.partial_cmp(&rhs.branch_num) + } +} + +impl BranchNumber { + pub(crate) fn has_as_subbranch(&self, other: &Self) -> bool { + let delta_ratio = &self.delta / &other.delta; + + if !delta_ratio.denominator().is_one() { + return false; + } + + other.branch_num >= self.branch_num && other.branch_num < &self.branch_num + &self.delta + } + + pub(crate) fn split(&self) -> BranchNumber { + BranchNumber { + branch_num: self.branch_num.clone() + &self.delta / Rational::from(2), + delta: &self.delta / Rational::from(4), + } + } + + pub(crate) fn incr_by_delta(&self) -> BranchNumber { + BranchNumber { + branch_num: self.branch_num.clone() + &self.delta, + delta: self.delta.clone(), + } + } + + pub(crate) fn halve_delta(&self) -> BranchNumber { + BranchNumber { + branch_num: self.branch_num.clone(), + delta: &self.delta / Rational::from(2), + } + } +} + #[derive(Debug)] pub enum ChunkedTerms { - Branch(Vec>), - Chunk { terms: VecDeque }, + Branch { + branch_nums: Vec, + arms: Vec>, + }, + Chunk { + terms: VecDeque, + }, } #[derive(Debug)] @@ -165,21 +243,22 @@ impl ChunkedTermVec { } pub fn reserve_branch(&mut self, capacity: usize) { - self.chunk_vec - .push_back(ChunkedTerms::Branch(Vec::with_capacity(capacity))); + self.chunk_vec.push_back(ChunkedTerms::Branch { + branch_nums: Vec::with_capacity(capacity), + arms: Vec::with_capacity(capacity), + }); } #[inline] pub fn add_chunk(&mut self) { - let chunk = ChunkedTerms::Chunk { + self.chunk_vec.push_back(ChunkedTerms::Chunk { terms: VecDeque::from(vec![]), - }; - self.chunk_vec.push_back(chunk); + }); } pub fn push_chunk_term(&mut self, term: QueryTerm) { match self.chunk_vec.back_mut() { - Some(ChunkedTerms::Branch(_)) => { + Some(ChunkedTerms::Branch { .. }) => { let chunk = ChunkedTerms::Chunk { terms: VecDeque::from(vec![term]), }; diff --git a/src/iterators.rs b/src/iterators.rs index e3a2ccbd..0aa7bd38 100644 --- a/src/iterators.rs +++ b/src/iterators.rs @@ -319,15 +319,28 @@ pub(crate) fn breadth_first_iter( #[derive(Debug, Copy, Clone)] enum ClauseIteratorState<'a> { RemainingChunks(&'a VecDeque, usize), - RemainingBranches(&'a Vec>, usize), + RemainingBranches( + &'a Vec, + &'a Vec>, + usize, + ), } #[derive(Debug, Clone)] pub(crate) enum ClauseItem<'a> { - FirstBranch(usize), - NextBranch, - BranchEnd(usize), - Chunk { terms: &'a VecDeque }, + FirstBranch { + branch_num: &'a BranchNumber, + num_branches: usize, + }, + NextBranch { + branch_num: &'a BranchNumber, + }, + BranchEnd { + depth: usize, + }, + Chunk { + terms: &'a VecDeque, + }, } #[derive(Debug)] @@ -338,8 +351,8 @@ pub(crate) struct ClauseIterator<'a> { fn state_from_chunked_terms(chunk_vec: &VecDeque) -> ClauseIteratorState<'_> { if chunk_vec.len() == 1 { - if let Some(ChunkedTerms::Branch(ref branches)) = chunk_vec.front() { - return ClauseIteratorState::RemainingBranches(branches, 0); + if let Some(ChunkedTerms::Branch { branch_nums, arms }) = chunk_vec.front() { + return ClauseIteratorState::RemainingBranches(branch_nums, arms, 0); } } @@ -370,7 +383,9 @@ impl<'a> ClauseIterator<'a> { while let Some(state) = self.state_stack.pop() { match state { - ClauseIteratorState::RemainingBranches(terms, focus) if terms.len() == focus => { + ClauseIteratorState::RemainingBranches(_branch_nums, terms, focus) + if terms.len() == focus => + { depth += 1; } _ => { @@ -399,9 +414,9 @@ impl<'a> Iterator for ClauseIterator<'a> { } match &chunks[focus] { - ChunkedTerms::Branch(branches) => { + ChunkedTerms::Branch { branch_nums, arms } => { self.state_stack - .push(ClauseIteratorState::RemainingBranches(branches, 0)); + .push(ClauseIteratorState::RemainingBranches(branch_nums, arms, 0)); } ChunkedTerms::Chunk { ref terms } => { return Some(ClauseItem::Chunk { terms }); @@ -411,11 +426,15 @@ impl<'a> Iterator for ClauseIterator<'a> { ClauseIteratorState::RemainingChunks(chunks, focus) => { debug_assert_eq!(chunks.len(), focus); } - ClauseIteratorState::RemainingBranches(branches, focus) + ClauseIteratorState::RemainingBranches(branch_nums, branches, focus) if focus < branches.len() => { self.state_stack - .push(ClauseIteratorState::RemainingBranches(branches, focus + 1)); + .push(ClauseIteratorState::RemainingBranches( + branch_nums, + branches, + focus + 1, + )); let state = state_from_chunked_terms(&branches[focus]); if let ClauseIteratorState::RemainingChunks(..) = &state { @@ -425,14 +444,21 @@ impl<'a> Iterator for ClauseIterator<'a> { self.state_stack.push(state); return if focus == 0 { - Some(ClauseItem::FirstBranch(branches.len())) + Some(ClauseItem::FirstBranch { + branch_num: &branch_nums[0], + num_branches: branches.len(), + }) } else { - Some(ClauseItem::NextBranch) + Some(ClauseItem::NextBranch { + branch_num: &branch_nums[focus], + }) }; } - ClauseIteratorState::RemainingBranches(branches, focus) => { + ClauseIteratorState::RemainingBranches(_branch_nums, branches, focus) => { debug_assert_eq!(branches.len(), focus); - return Some(ClauseItem::BranchEnd(self.branch_end_depth())); + return Some(ClauseItem::BranchEnd { + depth: self.branch_end_depth(), + }); } } } diff --git a/src/machine/disjuncts.rs b/src/machine/disjuncts.rs index 4ecac7bc..95f4ae5f 100644 --- a/src/machine/disjuncts.rs +++ b/src/machine/disjuncts.rs @@ -6,79 +6,16 @@ use crate::machine::loader::*; use crate::machine::machine_errors::CompilationError; use crate::machine::preprocessor::*; use crate::parser::ast::*; -use crate::parser::dashu::Rational; use crate::variable_records::*; use dashu::Integer; use indexmap::{IndexMap, IndexSet}; use std::cell::Cell; -use std::cmp::Ordering; use std::collections::VecDeque; -use std::hash::{Hash, Hasher}; +use std::hash::Hash; use std::ops::{Deref, DerefMut}; -#[derive(Debug, Clone)] //, PartialOrd, PartialEq, Eq, Hash)] -pub struct BranchNumber { - branch_num: Rational, - delta: Rational, -} - -impl Default for BranchNumber { - fn default() -> Self { - Self { - branch_num: Rational::from(1u64 << 63), - delta: Rational::from(1), - } - } -} - -impl PartialEq for BranchNumber { - #[inline] - fn eq(&self, rhs: &BranchNumber) -> bool { - self.branch_num == rhs.branch_num - } -} - -impl Eq for BranchNumber {} - -impl Hash for BranchNumber { - #[inline(always)] - fn hash(&self, hasher: &mut H) { - self.branch_num.hash(hasher) - } -} - -impl PartialOrd for BranchNumber { - #[inline] - fn partial_cmp(&self, rhs: &BranchNumber) -> Option { - self.branch_num.partial_cmp(&rhs.branch_num) - } -} - -impl BranchNumber { - fn split(&self) -> BranchNumber { - BranchNumber { - branch_num: self.branch_num.clone() + &self.delta / Rational::from(2), - delta: &self.delta / Rational::from(4), - } - } - - fn incr_by_delta(&self) -> BranchNumber { - BranchNumber { - branch_num: self.branch_num.clone() + &self.delta, - delta: self.delta.clone(), - } - } - - fn halve_delta(&self) -> BranchNumber { - BranchNumber { - branch_num: self.branch_num.clone(), - delta: &self.delta / Rational::from(2), - } - } -} - #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct VarInfo { var_ptr: VarPtr, @@ -140,12 +77,13 @@ pub struct ClassifyInfo { } enum TraversalState { - // construct a QueryTerm::Branch with number of disjuncts, reset - // the chunk type to that of the chunk preceding the disjunct and the chunk_num. + // pop the latest branch number from the root set and use it to construct a QueryTerm::Branch + // with number of disjuncts, reset the chunk type to that of the chunk preceding the disjunct + // and the chunk_num. BuildDisjunct(usize), + BuildFinalDisjunct(usize), // add the last disjunct to a QueryTerm::Branch, continuing from // where it leaves off. - BuildFinalDisjunct(usize), Fail, GetCutPoint { var_num: usize, prev_b: bool }, Cut { var_num: usize, is_global: bool }, @@ -154,7 +92,6 @@ enum TraversalState { Term(Term), OverrideGlobalCutVar(usize), ResetGlobalCutVarOverride(Option), - RemoveBranchNum, // pop the current_branch_num and from the root set. AddBranchNum(BranchNumber), // set current_branch_num, add it to the root set RepBranchNum(BranchNumber), // replace current_branch_num and the latest in the root set } @@ -199,7 +136,7 @@ impl VarData { VarAlloc::Perm(0, PermVarAllocation::Pending); match build_stack.front_mut() { - Some(ChunkedTerms::Branch(_)) => { + Some(ChunkedTerms::Branch { .. }) => { build_stack.push_front(ChunkedTerms::Chunk { terms: VecDeque::from(vec![term]), }); @@ -232,11 +169,16 @@ fn merge_branch_seq(branches: impl Iterator) -> BranchInfo { branch_info } -fn flatten_into_disjunct(build_stack: &mut ChunkedTermVec, preceding_len: usize) { +fn flatten_into_disjunct( + build_stack: &mut ChunkedTermVec, + branch_num: BranchNumber, + preceding_len: usize, +) { let branch_vec = build_stack.drain(preceding_len + 1..).collect(); - if let ChunkedTerms::Branch(ref mut disjuncts) = &mut build_stack[preceding_len] { - disjuncts.push(branch_vec); + if let ChunkedTerms::Branch { branch_nums, arms } = &mut build_stack[preceding_len] { + branch_nums.push(branch_num); + arms.push(branch_vec); } else { unreachable!(); } @@ -477,9 +419,6 @@ impl VariableClassifier { self.root_set.insert(branch_num.clone()); self.current_branch_num = branch_num; } - TraversalState::RemoveBranchNum => { - self.root_set.pop(); - } TraversalState::RepBranchNum(branch_num) => { self.root_set.pop(); self.root_set.insert(branch_num.clone()); @@ -488,14 +427,9 @@ impl VariableClassifier { TraversalState::ResetCallPolicy(call_policy) => { self.call_policy = call_policy; } - TraversalState::BuildDisjunct(preceding_len) => { - flatten_into_disjunct(&mut build_stack, preceding_len); - - self.current_chunk_type = ChunkType::Mid; - self.current_chunk_num += 1; - } - TraversalState::BuildFinalDisjunct(preceding_len) => { - flatten_into_disjunct(&mut build_stack, preceding_len); + TraversalState::BuildDisjunct(preceding_len) | TraversalState::BuildFinalDisjunct(preceding_len) => { + let branch_num = self.root_set.pop().unwrap(); + flatten_into_disjunct(&mut build_stack, branch_num, preceding_len); self.current_chunk_type = ChunkType::Mid; self.current_chunk_num += 1; @@ -632,11 +566,10 @@ impl VariableClassifier { )); let iter = branches.into_iter().zip(branch_numbers.into_iter()); - let final_disjunct_loc = state_stack.len(); + let final_disjunct_loc = state_stack.len(); for (term, branch_num) in iter.rev() { state_stack.push(TraversalState::BuildDisjunct(build_stack_len)); - state_stack.push(TraversalState::RemoveBranchNum); state_stack.push(TraversalState::Term(term)); state_stack.push(TraversalState::AddBranchNum(branch_num)); } @@ -655,23 +588,18 @@ impl VariableClassifier { let then_term = terms.pop().unwrap(); let if_term = terms.pop().unwrap(); - let prev_b = if matches!( - state_stack.last(), - Some(TraversalState::RemoveBranchNum) - ) { - // check if the second-to-last element - // is a regular BuildDisjunct, as we - // don't want to add GetPrevLevel in - // case of a TrustMe. - match state_stack.iter().rev().nth(1) { - Some(&TraversalState::BuildDisjunct(preceding_len)) => { - preceding_len + 1 == build_stack.len() - } - _ => false, - } - } else { - false - }; + let prev_b = + if let Some(&TraversalState::BuildDisjunct(preceding_len)) = + state_stack.last() + { + // check if the second-to-last element + // is a regular BuildDisjunct, as we + // don't want to add GetPrevLevel in + // case of a TrustMe. + preceding_len + 1 == build_stack.len() + } else { + false + }; state_stack.push(TraversalState::Term(then_term)); state_stack.push(TraversalState::Cut { @@ -690,14 +618,21 @@ impl VariableClassifier { let not_term = terms.pop().unwrap(); let build_stack_len = build_stack.len(); + let first_branch_num = self.current_branch_num.split(); + let second_branch_num = first_branch_num.incr_by_delta(); + build_stack.reserve_branch(2); + state_stack.push(TraversalState::RepBranchNum( + self.current_branch_num.halve_delta(), + )); state_stack.push(TraversalState::BuildFinalDisjunct(build_stack_len)); state_stack.push(TraversalState::Term(Term::Clause( Cell::default(), atom!("$succeed"), vec![], ))); + state_stack.push(TraversalState::AddBranchNum(second_branch_num)); state_stack.push(TraversalState::BuildDisjunct(build_stack_len)); state_stack.push(TraversalState::Fail); state_stack.push(TraversalState::CutPrev(self.var_num)); @@ -710,6 +645,7 @@ impl VariableClassifier { var_num: self.var_num, prev_b: false, }); + state_stack.push(TraversalState::AddBranchNum(first_branch_num)); self.current_chunk_type = ChunkType::Mid; self.current_chunk_num += 1; diff --git a/src/variable_records.rs b/src/variable_records.rs index c918067e..e8a867df 100644 --- a/src/variable_records.rs +++ b/src/variable_records.rs @@ -1,9 +1,11 @@ -use crate::forms::GenContext; +use crate::forms::{BranchNumber, GenContext}; use crate::parser::ast::*; use bit_set::*; use fxhash::FxBuildHasher; use indexmap::{IndexMap, IndexSet}; +use num_order::NumOrd; + use std::ops::{Deref, DerefMut}; #[derive(Debug, Clone)] @@ -13,20 +15,19 @@ pub struct TempVarData { pub(crate) conflict_set: BitSet, } -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct BranchDesignator { - pub branch_stack_num: usize, - pub branch_num: usize, + pub branch_num: BranchNumber, } impl BranchDesignator { #[inline] pub fn is_sub_branch(&self) -> bool { - self.branch_stack_num > 0 + self.branch_num.branch_num.num_gt(&0) } } -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone)] pub enum VarSafetyStatus { Needed, // which branch planted the last unsafe guarded instruction? It may still be needed. @@ -35,27 +36,27 @@ pub enum VarSafetyStatus { } impl VarSafetyStatus { - pub(crate) fn unneeded(current_branch: BranchDesignator) -> Self { + pub(crate) fn unneeded(current_branch: &BranchDesignator) -> Self { if current_branch.is_sub_branch() { - VarSafetyStatus::LocallyUnneeded(current_branch) + VarSafetyStatus::LocallyUnneeded(current_branch.clone()) } else { VarSafetyStatus::GloballyUnneeded } } #[inline] - pub(crate) fn needed_if(needed: bool, branch_designator: BranchDesignator) -> Self { + pub(crate) fn needed_if(needed: bool, branch_designator: &BranchDesignator) -> Self { if needed { VarSafetyStatus::Needed - } else if branch_designator.branch_stack_num == 0 { + } else if branch_designator.branch_num.branch_num.num_eq(&0) { VarSafetyStatus::GloballyUnneeded } else { - VarSafetyStatus::LocallyUnneeded(branch_designator) + VarSafetyStatus::LocallyUnneeded(branch_designator.clone()) } } } -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone)] pub enum PermVarAllocation { Done { shallow_safety: VarSafetyStatus, -- 2.54.0