From b1ae09d7aa6157db8dc22486c8e8ebce05454155 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Sun, 12 Nov 2017 23:43:42 -0700 Subject: [PATCH] add register marking for non-callable/inlined predicates. --- src/prolog/allocator.rs | 4 +- src/prolog/arithmetic.rs | 14 +-- src/prolog/codegen.rs | 110 +++++++++++------------ src/prolog/debray_allocator.rs | 2 +- src/prolog/naive_allocator.rs | 157 --------------------------------- 5 files changed, 65 insertions(+), 222 deletions(-) delete mode 100644 src/prolog/naive_allocator.rs diff --git a/src/prolog/allocator.rs b/src/prolog/allocator.rs index c3a3e79b..cd9f523b 100644 --- a/src/prolog/allocator.rs +++ b/src/prolog/allocator.rs @@ -17,8 +17,8 @@ pub trait Allocator<'a> fn reset(&mut self); fn reset_contents(&mut self) {} - - fn advance(&mut self, GenContext, usize); + fn reset_arg(&mut self, usize); + fn advance_arg(&mut self); fn bindings(&self) -> &AllocVarDict<'a>; diff --git a/src/prolog/arithmetic.rs b/src/prolog/arithmetic.rs index 52a2a89a..51341230 100644 --- a/src/prolog/arithmetic.rs +++ b/src/prolog/arithmetic.rs @@ -84,8 +84,8 @@ impl<'a> ArithmeticEvaluator<'a> { ArithmeticEvaluator { bindings, interm: Vec::new(), interm_c: 1 } } - fn get_un_instr(name: &Atom, a1: ArithmeticTerm, t: usize) - -> Result + fn get_unary_instr(name: &Atom, a1: ArithmeticTerm, t: usize) + -> Result { match name.as_str() { "-" => Ok(ArithmeticInstruction::Neg(a1, t)), @@ -93,8 +93,8 @@ impl<'a> ArithmeticEvaluator<'a> { } } - fn gen_bin_instr(name: &Atom, a1: ArithmeticTerm, a2: ArithmeticTerm, t: usize) - -> Result + fn gen_binary_instr(name: &Atom, a1: ArithmeticTerm, a2: ArithmeticTerm, t: usize) + -> Result { match name.as_str() { "+" => Ok(ArithmeticInstruction::Add(a1, a2, t)), @@ -129,7 +129,7 @@ impl<'a> ArithmeticEvaluator<'a> { a1.interm_or(0) }; - Self::get_un_instr(name, a1, ninterm) + Self::get_unary_instr(name, a1, ninterm) }, 2 => { let a2 = self.interm.pop().unwrap(); @@ -153,7 +153,7 @@ impl<'a> ArithmeticEvaluator<'a> { min_interm }; - Self::gen_bin_instr(name, a1, a2, ninterm) + Self::gen_binary_instr(name, a1, a2, ninterm) }, _ => Err(ArithmeticError::InvalidOp) } @@ -221,7 +221,7 @@ impl<'a> ArithmeticEvaluator<'a> { _ => {} }; } - + Ok(code) } } diff --git a/src/prolog/codegen.rs b/src/prolog/codegen.rs index 0fb1a53e..bafcea3e 100644 --- a/src/prolog/codegen.rs +++ b/src/prolog/codegen.rs @@ -6,6 +6,7 @@ use prolog::indexing::*; use prolog::iterators::*; use prolog::targets::*; +use std::cell::Cell; use std::collections::HashMap; use std::mem::swap; use std::vec::Vec; @@ -79,6 +80,29 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker> *self.var_count.get(var).unwrap() } + fn mark_non_callable(&mut self, + name: &'a Atom, + arity: usize, + term_loc: GenContext, + vr: &'a Cell, + code: &mut Code) + -> RegType + { + match self.marker.bindings().get(name) { + Some(&VarData::Temp(_, t, _)) if t != 0 => RegType::Temp(t), + Some(&VarData::Perm(p)) if p != 0 => RegType::Perm(p), + _ => { + let mut target = Vec::new(); + + self.marker.reset_arg(arity); + self.marker.mark_var(name, Level::Shallow, vr, term_loc, &mut target); + + code.push(Line::Query(target)); + vr.get().norm() + } + } + } + fn add_or_increment_void_instr(target: &mut Vec) where Target: CompilationTarget<'a> { @@ -297,23 +321,15 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker> code.append(&mut arith_code); match terms[0].as_ref() { - &Term::Var(ref vr, ref name) => - match self.marker.bindings().get(name) { - Some(&VarData::Temp(_, t, _)) if t != 0 => - code.push(is_call!(temp_v!(t))), - Some(&VarData::Perm(p)) if p != 0 => - code.push(is_call!(perm_v!(p))), - _ => { - let mut target = Vec::new(); - - // reset self.marker.arg_c to 1. - self.marker.advance(term_loc, term.arity()); - self.marker.mark_var(name, Level::Shallow, vr, term_loc, &mut target); - - code.push(Line::Query(target)); - code.push(is_call!(vr.get().norm())); - } - }, + &Term::Var(ref vr, ref name) => { + let r = self.mark_non_callable(name, + term.arity(), + term_loc, + vr, + code); + + code.push(is_call!(r)); + }, &Term::Constant(_, Constant::Float(fl)) => { code.push(query![put_constant!(Level::Shallow, Constant::Float(fl), @@ -340,23 +356,15 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker> &Term::Constant(_, _) => { code.push(succeed!()); }, - &Term::Var(ref vr, ref name) => - match self.marker.bindings().get(name) { - Some(&VarData::Temp(_, t, _)) if t != 0 => - code.push(is_atomic!(RegType::Temp(t))), - Some(&VarData::Perm(p)) if p != 0 => - code.push(is_atomic!(RegType::Perm(p))), - _ => { - let mut target = Vec::new(); - - // reset self.marker.arg_c to 1. - self.marker.advance(term_loc, term.arity()); - self.marker.mark_var(name, Level::Shallow, vr, term_loc, &mut target); - - code.push(Line::Query(target)); - code.push(is_atomic!(vr.get().norm())); - } - }, + &Term::Var(ref vr, ref name) => { + let r = self.mark_non_callable(name, + term.arity(), + term_loc, + vr, + code); + + code.push(is_atomic!(r)); + } }, &QueryTerm::IsVar(ref inner_term) => match inner_term[0].as_ref() { @@ -366,26 +374,18 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker> &Term::AnonVar => { code.push(succeed!()); }, - &Term::Var(ref vr, ref name) => - match self.marker.bindings().get(name) { - Some(&VarData::Temp(_, t, _)) if t != 0 => - code.push(is_var!(RegType::Temp(t))), - Some(&VarData::Perm(p)) if p != 0 => - code.push(is_var!(RegType::Perm(p))), - _ => { - let mut target = Vec::new(); - - // reset self.marker.arg_c to 1. - self.marker.advance(term_loc, term.arity()); - self.marker.mark_var(name, Level::Shallow, vr, term_loc, &mut target); - - code.push(Line::Query(target)); - code.push(is_var!(vr.get().norm())); - } - } + &Term::Var(ref vr, ref name) => { + let r = self.mark_non_callable(name, + term.arity(), + term_loc, + vr, + code); + + code.push(is_var!(r)); + } }, _ if chunk_num == 0 => { - self.marker.advance(GenContext::Head, term.arity()); + self.marker.reset_arg(term.arity()); let iter = term.post_order_iter(); code.push(Line::Query(self.compile_target(iter, term_loc, is_exposed))); @@ -441,7 +441,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker> let &Rule { head: (ref p0, ref p1), ref clauses } = rule; let mut code = Vec::new(); - self.marker.advance(GenContext::Head, p0.arity()); + self.marker.reset_arg(p0.arity()); self.compile_seq_prelude(&conjunct_info, &mut code); if let &QueryTerm::Term(ref term) = p0 { @@ -509,7 +509,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker> vs.populate_restricting_sets(); self.marker.drain_var_data(vs); - self.marker.advance(GenContext::Head, term.arity()); + self.marker.reset_arg(term.arity()); let mut code = Vec::new(); @@ -532,7 +532,7 @@ impl<'a, TermMarker: Allocator<'a>> CodeGenerator<'a, TermMarker> index: usize, is_exposed: bool) { - self.marker.advance(term_loc, term.arity()); + self.marker.reset_arg(term.arity()); let iter = term.post_order_iter(); let compiled_query = Line::Query(self.compile_target(iter, term_loc, is_exposed)); diff --git a/src/prolog/debray_allocator.rs b/src/prolog/debray_allocator.rs index 44e3800f..a7f4a0f2 100644 --- a/src/prolog/debray_allocator.rs +++ b/src/prolog/debray_allocator.rs @@ -348,7 +348,7 @@ impl<'a> Allocator<'a> for DebrayAllocator<'a> self.bindings } - fn advance(&mut self, _: GenContext, arity: usize) { + fn reset_arg(&mut self, arity: usize) { self.arg_c = 1; self.temp_lb = arity + 1; } diff --git a/src/prolog/naive_allocator.rs b/src/prolog/naive_allocator.rs deleted file mode 100644 index 4b1f13c7..00000000 --- a/src/prolog/naive_allocator.rs +++ /dev/null @@ -1,157 +0,0 @@ -use prolog::allocator::*; -use prolog::ast::*; -use prolog::fixtures::*; -use prolog::targets::*; - -use std::cell::Cell; -use std::cmp::max; -use std::collections::HashMap; - -pub struct NaiveAllocator<'a> { - bindings: AllocVarDict<'a>, - arg_c: usize, - temp_c: usize, -} - -impl<'a> Allocator<'a> for NaiveAllocator<'a> -{ - fn new() -> Self { - NaiveAllocator { - arg_c: 1, - temp_c: 1, - bindings: HashMap::new(), - } - } - - fn mark_anon_var(&mut self, lvl: Level, target: &mut Vec) - where Target: CompilationTarget<'a> - { - let r = { - let temp = self.temp_c; - self.temp_c += 1; - RegType::Temp(temp) - }; - - match lvl { - Level::Deep => target.push(Target::subterm_to_variable(r)), - Level::Shallow => { - let k = self.arg_c; - self.arg_c += 1; - - target.push(Target::argument_to_variable(r, k)); - } - } - } - - fn mark_non_var(&mut self, - lvl: Level, - _: GenContext, - cell: &Cell, - _: &mut Vec) - where Target: CompilationTarget<'a> - { - let r = cell.get(); - - if r.reg_num() == 0 { - let r = match lvl { - Level::Shallow => { - let k = self.arg_c; - self.arg_c += 1; - - RegType::Temp(k) - }, - _ => { - let temp = self.temp_c; - self.temp_c += 1; - - RegType::Temp(temp) - } - }; - - cell.set(r); - } - } - - fn mark_var(&mut self, - var: &'a Var, - lvl: Level, - cell: &'a Cell, - _: GenContext, - target: &mut Vec) - where Target: CompilationTarget<'a> - { - let (r, is_new_var) = match self.get(var) { - RegType::Temp(0) => { - let o = self.temp_c; - self.temp_c += 1; - - (RegType::Temp(o), true) - }, - RegType::Perm(0) => { - let pr = cell.get().norm(); - self.record_register(var, pr); - - (pr, true) - }, - r => (r, false) - }; - - match lvl { - Level::Shallow => { - let k = self.arg_c; - self.arg_c += 1; - - cell.set(VarReg::ArgAndNorm(r, k)); - - if is_new_var { - target.push(Target::argument_to_variable(r, k)); - } else { - target.push(Target::argument_to_value(r, k)); - } - }, - Level::Deep => { - cell.set(VarReg::Norm(r)); - - if is_new_var { - target.push(Target::subterm_to_variable(r)); - } else { - target.push(Target::subterm_to_value(r)); - } - } - }; - - if !r.is_perm() { - self.record_register(var, r); - } - } - - fn reset(&mut self) { - self.bindings.clear(); - } - - fn advance(&mut self, term_loc: GenContext, arity: usize) { - if let GenContext::Head = term_loc { - self.arg_c = 1; - self.temp_c = max(arity + 1, self.temp_c); - } else { - self.arg_c = 1; - self.temp_c = arity + 1; - } - } - - fn advance_arg(&mut self) { - self.arg_c += 1; - } - - fn bindings(&self) -> &AllocVarDict<'a> { - &self.bindings - } - - fn bindings_mut(&mut self) -> &mut AllocVarDict<'a> { - &mut self.bindings - } - - fn take_bindings(self) -> AllocVarDict<'a> { - self.bindings - } -} -- 2.54.0