From 92853a6a1276d746b27baa249f08c1a35cb2089e Mon Sep 17 00:00:00 2001 From: Mark Date: Fri, 23 Jun 2023 12:24:34 -0600 Subject: [PATCH] free local cut variables after cut --- src/codegen.rs | 8 ++++---- src/debray_allocator.rs | 43 ++++++++++++++++++++++++++++++----------- 2 files changed, 36 insertions(+), 15 deletions(-) diff --git a/src/codegen.rs b/src/codegen.rs index dca532ce..87345494 100644 --- a/src/codegen.rs +++ b/src/codegen.rs @@ -332,7 +332,7 @@ trait AddToFreeList<'a, Target: CompilationTarget<'a>> { impl<'a, 'b> AddToFreeList<'a, FactInstruction> for CodeGenerator<'b> { fn add_term_to_free_list(&mut self, r: RegType) { - self.marker.add_to_free_list(r); + self.marker.add_reg_to_free_list(r); } fn add_subterm_to_free_list(&mut self, _term: &Term) {} @@ -345,7 +345,7 @@ impl<'a, 'b> AddToFreeList<'a, QueryInstruction> for CodeGenerator<'b> { #[inline(always)] fn add_subterm_to_free_list(&mut self, term: &Term) { if let Some(cell) = structure_cell(term) { - self.marker.add_to_free_list(cell.get()); + self.marker.add_reg_to_free_list(cell.get()); } } } @@ -881,7 +881,6 @@ impl<'b> CodeGenerator<'b> { code.push_back(instr!("neck_cut")); } else { let r = self.marker.get_binding(var_num); - // let r = self.marker.mark_cut_var(var_num, chunk_num); code.push_back(instr!("cut", r)); } @@ -896,7 +895,6 @@ impl<'b> CodeGenerator<'b> { &QueryTerm::LocalCut(var_num) => { let code = branch_code_stack.code(code); let r = self.marker.get_binding(var_num); - // let r = self.marker.mark_cut_var(var_num, chunk_num); code.push_back(instr!("cut", r)); if self.marker.in_tail_position { @@ -905,6 +903,8 @@ impl<'b> CodeGenerator<'b> { } code.push_back(instr!("proceed")); + } else { + self.marker.free_cut_var(chunk_num, var_num); } } &QueryTerm::Clause( diff --git a/src/debray_allocator.rs b/src/debray_allocator.rs index 6ad47cfc..6bfbfb5e 100644 --- a/src/debray_allocator.rs +++ b/src/debray_allocator.rs @@ -382,7 +382,7 @@ impl DebrayAllocator { p } - pub fn add_to_free_list(&mut self, r: RegType) { + pub(crate) fn add_reg_to_free_list(&mut self, r: RegType) { if let RegType::Temp(r) = r { self.in_use.remove(r); self.temp_free_list.push(r); @@ -406,22 +406,43 @@ impl DebrayAllocator { self.var_data.records[var_num].running_count += 1; } + fn add_perm_to_free_list(&mut self, chunk_num: usize, var_num: usize) { + match &self.var_data.records[var_num].allocation { + VarAlloc::Perm(..) => { + self.perm_free_list.push_back((chunk_num, var_num)); + } + _ => {} + } + } + fn pop_free_perm(&mut self, chunk_num: usize) -> Option { - if let Some((perm_chunk_num, var_num)) = self.perm_free_list.front().cloned() { - if chunk_num == perm_chunk_num { - None - } else { + while let Some((perm_chunk_num, var_num)) = self.perm_free_list.front().cloned() { + if chunk_num > perm_chunk_num { self.perm_free_list.pop_front(); match &mut self.var_data.records[var_num].allocation { - &mut VarAlloc::Perm(p, _) => { - Some(p) + VarAlloc::Perm(p, PermVarAllocation::Pending) if *p > 0 => { + return Some(std::mem::replace(p, 0)); + } + _ => { } - _ => unreachable!() } + } else { + return None; + } + } + + None + } + + pub(crate) fn free_cut_var(&mut self, chunk_num: usize, var_num: usize) { + match &mut self.var_data.records[var_num].allocation { + VarAlloc::Perm(_, allocation) => { + *allocation = PermVarAllocation::Pending; + self.add_perm_to_free_list(chunk_num, var_num); + } + _ => { } - } else { - None } } @@ -704,7 +725,7 @@ impl Allocator for DebrayAllocator { if record.running_count < record.num_occurrences { record.running_count += 1; } else if r.is_perm() { - self.perm_free_list.push_back((term_loc.chunk_num(), var_num)); + self.add_perm_to_free_list(term_loc.chunk_num(), var_num); } self.in_use.insert(o); -- 2.54.0