use VecDeque for generating indices during code generation (#1053)

This commit is contained in:
Mark Thom
2022-02-11 19:23:43 -07:00
parent 60dd47c696
commit db20cda27a
2 changed files with 55 additions and 52 deletions

View File

@@ -805,6 +805,8 @@ fn generate_instruction_preface() -> TokenStream {
use indexmap::IndexMap; use indexmap::IndexMap;
use slice_deque::SliceDeque; use slice_deque::SliceDeque;
use std::collections::VecDeque;
fn reg_type_into_functor(r: RegType) -> MachineStub { fn reg_type_into_functor(r: RegType) -> MachineStub {
match r { match r {
RegType::Temp(r) => functor!(atom!("x"), [fixnum(r)]), RegType::Temp(r) => functor!(atom!("x"), [fixnum(r)]),
@@ -1035,10 +1037,10 @@ fn generate_instruction_preface() -> TokenStream {
} }
} }
impl From<SliceDeque<IndexedChoiceInstruction>> for IndexingLine { impl From<VecDeque<IndexedChoiceInstruction>> for IndexingLine {
#[inline] #[inline]
fn from(instrs: SliceDeque<IndexedChoiceInstruction>) -> Self { fn from(instrs: VecDeque<IndexedChoiceInstruction>) -> Self {
IndexingLine::IndexedChoice(instrs) IndexingLine::IndexedChoice(instrs.into_iter().collect())
} }
} }

View File

@@ -7,6 +7,7 @@ use crate::instructions::*;
use indexmap::IndexMap; use indexmap::IndexMap;
use slice_deque::{sdeq, SliceDeque}; use slice_deque::{sdeq, SliceDeque};
use std::collections::VecDeque;
use std::hash::Hash; use std::hash::Hash;
use std::iter::once; use std::iter::once;
use std::mem; use std::mem;
@@ -1138,16 +1139,16 @@ pub(crate) fn constant_key_alternatives(
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct StaticCodeIndices { pub(crate) struct StaticCodeIndices {
constants: IndexMap<Literal, SliceDeque<IndexedChoiceInstruction>>, constants: IndexMap<Literal, VecDeque<IndexedChoiceInstruction>>,
lists: SliceDeque<IndexedChoiceInstruction>, lists: VecDeque<IndexedChoiceInstruction>,
structures: IndexMap<(Atom, usize), SliceDeque<IndexedChoiceInstruction>>, structures: IndexMap<(Atom, usize), VecDeque<IndexedChoiceInstruction>>,
} }
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct DynamicCodeIndices { pub(crate) struct DynamicCodeIndices {
constants: IndexMap<Literal, SliceDeque<usize>>, constants: IndexMap<Literal, VecDeque<usize>>,
lists: SliceDeque<usize>, lists: VecDeque<usize>,
structures: IndexMap<(Atom, usize), SliceDeque<usize>>, structures: IndexMap<(Atom, usize), VecDeque<usize>>,
} }
pub(crate) trait Indexer { pub(crate) trait Indexer {
@@ -1155,26 +1156,26 @@ pub(crate) trait Indexer {
fn new() -> Self; fn new() -> Self;
fn constants(&mut self) -> &mut IndexMap<Literal, SliceDeque<Self::ThirdLevelIndex>>; fn constants(&mut self) -> &mut IndexMap<Literal, VecDeque<Self::ThirdLevelIndex>>;
fn lists(&mut self) -> &mut SliceDeque<Self::ThirdLevelIndex>; fn lists(&mut self) -> &mut VecDeque<Self::ThirdLevelIndex>;
fn structures(&mut self) -> &mut IndexMap<(Atom, usize), SliceDeque<Self::ThirdLevelIndex>>; fn structures(&mut self) -> &mut IndexMap<(Atom, usize), VecDeque<Self::ThirdLevelIndex>>;
fn compute_index(is_initial_index: bool, index: usize) -> Self::ThirdLevelIndex; fn compute_index(is_initial_index: bool, index: usize) -> Self::ThirdLevelIndex;
fn second_level_index<IndexKey: Eq + Hash>( fn second_level_index<IndexKey: Eq + Hash>(
indices: IndexMap<IndexKey, SliceDeque<Self::ThirdLevelIndex>>, indices: IndexMap<IndexKey, VecDeque<Self::ThirdLevelIndex>>,
prelude: &mut SliceDeque<IndexingLine>, prelude: &mut VecDeque<IndexingLine>,
) -> IndexMap<IndexKey, IndexingCodePtr>; ) -> IndexMap<IndexKey, IndexingCodePtr>;
fn switch_on<IndexKey: Eq + Hash>( fn switch_on<IndexKey: Eq + Hash>(
instr_fn: impl FnMut(IndexMap<IndexKey, IndexingCodePtr>) -> IndexingInstruction, instr_fn: impl FnMut(IndexMap<IndexKey, IndexingCodePtr>) -> IndexingInstruction,
index: &mut IndexMap<IndexKey, SliceDeque<Self::ThirdLevelIndex>>, index: &mut IndexMap<IndexKey, VecDeque<Self::ThirdLevelIndex>>,
prelude: &mut SliceDeque<IndexingLine>, prelude: &mut VecDeque<IndexingLine>,
) -> IndexingCodePtr; ) -> IndexingCodePtr;
fn switch_on_list( fn switch_on_list(
lists: &mut SliceDeque<Self::ThirdLevelIndex>, lists: &mut VecDeque<Self::ThirdLevelIndex>,
prelude: &mut SliceDeque<IndexingLine>, prelude: &mut VecDeque<IndexingLine>,
) -> IndexingCodePtr; ) -> IndexingCodePtr;
fn remove_instruction_with_offset(code: &mut SliceDeque<Self::ThirdLevelIndex>, offset: usize); fn remove_instruction_with_offset(code: &mut SliceDeque<Self::ThirdLevelIndex>, offset: usize);
@@ -1189,23 +1190,23 @@ impl Indexer for StaticCodeIndices {
fn new() -> Self { fn new() -> Self {
Self { Self {
constants: IndexMap::new(), constants: IndexMap::new(),
lists: sdeq![], lists: VecDeque::new(),
structures: IndexMap::new(), structures: IndexMap::new(),
} }
} }
#[inline] #[inline]
fn constants(&mut self) -> &mut IndexMap<Literal, SliceDeque<IndexedChoiceInstruction>> { fn constants(&mut self) -> &mut IndexMap<Literal, VecDeque<IndexedChoiceInstruction>> {
&mut self.constants &mut self.constants
} }
#[inline] #[inline]
fn lists(&mut self) -> &mut SliceDeque<IndexedChoiceInstruction> { fn lists(&mut self) -> &mut VecDeque<IndexedChoiceInstruction> {
&mut self.lists &mut self.lists
} }
#[inline] #[inline]
fn structures(&mut self) -> &mut IndexMap<(Atom, usize), SliceDeque<IndexedChoiceInstruction>> { fn structures(&mut self) -> &mut IndexMap<(Atom, usize), VecDeque<IndexedChoiceInstruction>> {
&mut self.structures &mut self.structures
} }
@@ -1218,18 +1219,18 @@ impl Indexer for StaticCodeIndices {
} }
fn second_level_index<IndexKey: Eq + Hash>( fn second_level_index<IndexKey: Eq + Hash>(
indices: IndexMap<IndexKey, SliceDeque<IndexedChoiceInstruction>>, indices: IndexMap<IndexKey, VecDeque<IndexedChoiceInstruction>>,
prelude: &mut SliceDeque<IndexingLine>, prelude: &mut VecDeque<IndexingLine>,
) -> IndexMap<IndexKey, IndexingCodePtr> { ) -> IndexMap<IndexKey, IndexingCodePtr> {
let mut index_locs = IndexMap::new(); let mut index_locs = IndexMap::new();
for (key, mut code) in indices.into_iter() { for (key, mut code) in indices.into_iter() {
if code.len() > 1 { if code.len() > 1 {
index_locs.insert(key, IndexingCodePtr::Internal(prelude.len() + 1)); index_locs.insert(key, IndexingCodePtr::Internal(prelude.len() + 1));
cap_choice_seq_with_trust(&mut code); cap_choice_seq_with_trust(code.make_contiguous());
prelude.push_back(IndexingLine::from(code)); prelude.push_back(IndexingLine::from(code));
} else { } else {
code.first().map(|i| { code.front().map(|i| {
index_locs.insert(key, IndexingCodePtr::External(i.offset())); index_locs.insert(key, IndexingCodePtr::External(i.offset()));
}); });
} }
@@ -1240,8 +1241,8 @@ impl Indexer for StaticCodeIndices {
fn switch_on<IndexKey: Eq + Hash>( fn switch_on<IndexKey: Eq + Hash>(
mut instr_fn: impl FnMut(IndexMap<IndexKey, IndexingCodePtr>) -> IndexingInstruction, mut instr_fn: impl FnMut(IndexMap<IndexKey, IndexingCodePtr>) -> IndexingInstruction,
index: &mut IndexMap<IndexKey, SliceDeque<IndexedChoiceInstruction>>, index: &mut IndexMap<IndexKey, VecDeque<IndexedChoiceInstruction>>,
prelude: &mut SliceDeque<IndexingLine>, prelude: &mut VecDeque<IndexingLine>,
) -> IndexingCodePtr { ) -> IndexingCodePtr {
let index = mem::replace(index, IndexMap::new()); let index = mem::replace(index, IndexMap::new());
let index = Self::second_level_index(index, prelude); let index = Self::second_level_index(index, prelude);
@@ -1261,18 +1262,18 @@ impl Indexer for StaticCodeIndices {
} }
fn switch_on_list( fn switch_on_list(
lists: &mut SliceDeque<IndexedChoiceInstruction>, lists: &mut VecDeque<IndexedChoiceInstruction>,
prelude: &mut SliceDeque<IndexingLine>, prelude: &mut VecDeque<IndexingLine>,
) -> IndexingCodePtr { ) -> IndexingCodePtr {
if lists.len() > 1 { if lists.len() > 1 {
cap_choice_seq_with_trust(lists); cap_choice_seq_with_trust(lists.make_contiguous());
let lists = mem::replace(lists, sdeq![]); let lists = mem::replace(lists, VecDeque::new());
prelude.push_back(IndexingLine::from(lists)); prelude.push_back(IndexingLine::from(lists));
IndexingCodePtr::Internal(1) IndexingCodePtr::Internal(1)
} else { } else {
lists lists
.first() .front()
.map(|i| IndexingCodePtr::External(i.offset())) .map(|i| IndexingCodePtr::External(i.offset()))
.unwrap_or(IndexingCodePtr::Fail) .unwrap_or(IndexingCodePtr::Fail)
} }
@@ -1305,23 +1306,23 @@ impl Indexer for DynamicCodeIndices {
fn new() -> Self { fn new() -> Self {
Self { Self {
constants: IndexMap::new(), constants: IndexMap::new(),
lists: sdeq![], lists: VecDeque::new(),
structures: IndexMap::new(), structures: IndexMap::new(),
} }
} }
#[inline] #[inline]
fn constants(&mut self) -> &mut IndexMap<Literal, SliceDeque<usize>> { fn constants(&mut self) -> &mut IndexMap<Literal, VecDeque<usize>> {
&mut self.constants &mut self.constants
} }
#[inline] #[inline]
fn lists(&mut self) -> &mut SliceDeque<usize> { fn lists(&mut self) -> &mut VecDeque<usize> {
&mut self.lists &mut self.lists
} }
#[inline] #[inline]
fn structures(&mut self) -> &mut IndexMap<(Atom, usize), SliceDeque<usize>> { fn structures(&mut self) -> &mut IndexMap<(Atom, usize), VecDeque<usize>> {
&mut self.structures &mut self.structures
} }
@@ -1331,17 +1332,17 @@ impl Indexer for DynamicCodeIndices {
} }
fn second_level_index<IndexKey: Eq + Hash>( fn second_level_index<IndexKey: Eq + Hash>(
indices: IndexMap<IndexKey, SliceDeque<usize>>, indices: IndexMap<IndexKey, VecDeque<usize>>,
prelude: &mut SliceDeque<IndexingLine>, prelude: &mut VecDeque<IndexingLine>,
) -> IndexMap<IndexKey, IndexingCodePtr> { ) -> IndexMap<IndexKey, IndexingCodePtr> {
let mut index_locs = IndexMap::new(); let mut index_locs = IndexMap::new();
for (key, code) in indices.into_iter() { for (key, code) in indices.into_iter() {
if code.len() > 1 { if code.len() > 1 {
index_locs.insert(key, IndexingCodePtr::Internal(prelude.len() + 1)); index_locs.insert(key, IndexingCodePtr::Internal(prelude.len() + 1));
prelude.push_back(IndexingLine::DynamicIndexedChoice(code)); prelude.push_back(IndexingLine::DynamicIndexedChoice(code.into_iter().collect()));
} else { } else {
code.first().map(|i| { code.front().map(|i| {
index_locs.insert(key, IndexingCodePtr::DynamicExternal(*i)); index_locs.insert(key, IndexingCodePtr::DynamicExternal(*i));
}); });
} }
@@ -1352,8 +1353,8 @@ impl Indexer for DynamicCodeIndices {
fn switch_on<IndexKey: Eq + Hash>( fn switch_on<IndexKey: Eq + Hash>(
mut instr_fn: impl FnMut(IndexMap<IndexKey, IndexingCodePtr>) -> IndexingInstruction, mut instr_fn: impl FnMut(IndexMap<IndexKey, IndexingCodePtr>) -> IndexingInstruction,
index: &mut IndexMap<IndexKey, SliceDeque<usize>>, index: &mut IndexMap<IndexKey, VecDeque<usize>>,
prelude: &mut SliceDeque<IndexingLine>, prelude: &mut VecDeque<IndexingLine>,
) -> IndexingCodePtr { ) -> IndexingCodePtr {
let index = mem::replace(index, IndexMap::new()); let index = mem::replace(index, IndexMap::new());
let index = Self::second_level_index(index, prelude); let index = Self::second_level_index(index, prelude);
@@ -1373,16 +1374,16 @@ impl Indexer for DynamicCodeIndices {
} }
fn switch_on_list( fn switch_on_list(
lists: &mut SliceDeque<usize>, lists: &mut VecDeque<usize>,
prelude: &mut SliceDeque<IndexingLine>, prelude: &mut VecDeque<IndexingLine>,
) -> IndexingCodePtr { ) -> IndexingCodePtr {
if lists.len() > 1 { if lists.len() > 1 {
let lists = mem::replace(lists, sdeq![]); let lists = mem::replace(lists, VecDeque::new());
prelude.push_back(IndexingLine::DynamicIndexedChoice(lists)); prelude.push_back(IndexingLine::DynamicIndexedChoice(lists.into_iter().collect()));
IndexingCodePtr::Internal(1) IndexingCodePtr::Internal(1)
} else { } else {
lists lists
.first() .front()
.map(|i| IndexingCodePtr::DynamicExternal(*i)) .map(|i| IndexingCodePtr::DynamicExternal(*i))
.unwrap_or(IndexingCodePtr::Fail) .unwrap_or(IndexingCodePtr::Fail)
} }
@@ -1431,7 +1432,7 @@ impl<I: Indexer> CodeOffsets<I> {
index: usize, index: usize,
) -> Vec<Literal> { ) -> Vec<Literal> {
let overlapping_constants = constant_key_alternatives(constant, atom_tbl); let overlapping_constants = constant_key_alternatives(constant, atom_tbl);
let code = self.indices.constants().entry(constant).or_insert(sdeq![]); let code = self.indices.constants().entry(constant).or_insert(VecDeque::new());
let is_initial_index = code.is_empty(); let is_initial_index = code.is_empty();
code.push_back(I::compute_index(is_initial_index, index)); code.push_back(I::compute_index(is_initial_index, index));
@@ -1441,7 +1442,7 @@ impl<I: Indexer> CodeOffsets<I> {
.indices .indices
.constants() .constants()
.entry(*constant) .entry(*constant)
.or_insert(sdeq![]); .or_insert(VecDeque::new());
let is_initial_index = code.is_empty(); let is_initial_index = code.is_empty();
let index = I::compute_index(is_initial_index, index); let index = I::compute_index(is_initial_index, index);
@@ -1457,7 +1458,7 @@ impl<I: Indexer> CodeOffsets<I> {
.indices .indices
.structures() .structures()
.entry((name.clone(), arity)) .entry((name.clone(), arity))
.or_insert(sdeq![]); .or_insert(VecDeque::new());
let code_len = code.len(); let code_len = code.len();
let is_initial_index = code.is_empty(); let is_initial_index = code.is_empty();
@@ -1508,7 +1509,7 @@ impl<I: Indexer> CodeOffsets<I> {
return vec![]; return vec![];
} }
let mut prelude = sdeq![]; let mut prelude = VecDeque::new();
let mut emitted_switch_on_structure = false; let mut emitted_switch_on_structure = false;
let mut emitted_switch_on_constant = false; let mut emitted_switch_on_constant = false;