1 use serde::{de::DeserializeOwned, Deserialize, Serialize};
6 ops::{Index, IndexMut, Range},
11 BlockIdxOutOfRange, BlockParamIdxOutOfRange, InstIdxOutOfRange, OperandIdxOutOfRange,
14 function::{Block, Inst, Operand, SSAVal},
15 live_range::LiveRange,
18 pub trait DisplayOptionIdx {
19 type Type: fmt::Display;
20 fn display_option_idx(self) -> Self::Type;
23 pub trait IndexTy: Copy + fmt::Debug + Ord + Hash + Serialize + DeserializeOwned {
24 fn new(value: usize) -> Self;
25 fn get(self) -> usize;
26 fn next(self) -> Self {
27 Self::new(self.get() + 1)
29 fn prev(self) -> Self {
30 Self::new(self.get() - 1)
34 #[derive(Debug, Clone)]
35 pub struct RangeIter<T: IndexTy>(pub Range<T>);
37 impl<T: IndexTy> RangeIter<T> {
38 pub fn as_usize_range(&self) -> Range<usize> {
39 self.0.start.get()..self.0.end.get()
41 pub fn from_usize_range(range: Range<usize>) -> Self {
42 Self(T::new(range.start)..T::new(range.end))
44 pub fn with_self_as_usize_range<R, F: FnOnce(&mut Range<usize>) -> R>(&mut self, f: F) -> R {
45 let mut range = self.as_usize_range();
46 let retval = f(&mut range);
47 *self = Self::from_usize_range(range);
52 impl<T: IndexTy> Iterator for RangeIter<T> {
55 fn next(&mut self) -> Option<Self::Item> {
56 self.with_self_as_usize_range(|r| r.next().map(T::new))
59 fn size_hint(&self) -> (usize, Option<usize>) {
60 self.as_usize_range().size_hint()
63 fn nth(&mut self, n: usize) -> Option<Self::Item> {
64 self.with_self_as_usize_range(|r| r.nth(n).map(T::new))
67 fn fold<B, F>(self, init: B, mut f: F) -> B
69 F: FnMut(B, Self::Item) -> B,
72 .fold(init, move |a, v| f(a, T::new(v)))
76 impl<T: IndexTy> FusedIterator for RangeIter<T> {}
78 impl<T: IndexTy> ExactSizeIterator for RangeIter<T> {
79 fn len(&self) -> usize {
80 self.as_usize_range().len()
84 impl<T: IndexTy> DoubleEndedIterator for RangeIter<T> {
85 fn next_back(&mut self) -> Option<Self::Item> {
86 self.with_self_as_usize_range(|r| r.next_back().map(T::new))
89 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
90 self.with_self_as_usize_range(|r| r.nth_back(n).map(T::new))
93 fn rfold<B, F>(self, init: B, mut f: F) -> B
95 F: FnMut(B, Self::Item) -> B,
98 .rfold(init, move |a, v| f(a, T::new(v)))
102 macro_rules! define_index {
105 Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize,
107 #[serde(transparent)]
112 impl IndexTy for $name {
113 fn new(value: usize) -> Self {
116 fn get(self) -> usize {
122 pub const fn new(value: usize) -> Self {
125 pub const fn get(self) -> usize {
128 pub const fn next(self) -> Self {
130 value: self.value + 1,
133 pub const fn prev(self) -> Self {
135 value: self.value - 1,
141 #[derive(Copy, Clone)]
142 pub struct DisplayOptionIdxImpl(Option<$name>);
144 impl fmt::Debug for DisplayOptionIdxImpl {
145 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
146 fmt::Display::fmt(self, f)
150 impl fmt::Display for DisplayOptionIdxImpl {
151 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
153 Some(v) => fmt::Display::fmt(v, f),
154 None => write!(f, "none"),
159 impl DisplayOptionIdx for Option<$name> {
160 type Type = DisplayOptionIdxImpl;
162 fn display_option_idx(self) -> Self::Type {
163 DisplayOptionIdxImpl(self)
170 define_index!(SSAValIdx);
171 define_index!(InstIdx);
172 define_index!(BlockIdx);
173 define_index!(BlockParamIdx);
174 define_index!(OperandIdx);
175 define_index!(LiveRangeIdx);
177 pub trait Entries<'a, I>: Index<I>
182 type Iter: Iterator<Item = (I, &'a Self::Output)>
183 + DoubleEndedIterator
186 fn entries(&'a self) -> Self::Iter;
187 fn keys(&'a self) -> RangeIter<I>;
190 pub trait EntriesMut<'a, I>: Entries<'a, I> + IndexMut<I>
195 type IterMut: Iterator<Item = (I, &'a mut Self::Output)>
196 + DoubleEndedIterator
199 fn entries_mut(&'a mut self) -> Self::IterMut;
202 pub trait TryIndex<I>: for<'a> Entries<'a, I>
207 fn try_index(&self, idx: I) -> Result<&Self::Output, Self::Error>;
210 pub trait TryIndexMut<I>: TryIndex<I> + for<'a> EntriesMut<'a, I>
214 fn try_index_mut(&mut self, idx: I) -> Result<&mut Self::Output, Self::Error>;
217 macro_rules! impl_index {
219 #[$(error = $Error:ident, )?iter = $Iter:ident, iter_mut = $IterMut:ident]
220 impl Index<$I:ty> for Vec<$T:ty> {}
222 #[derive(Clone, Debug)]
223 pub struct $Iter<'a> {
224 iter: std::iter::Enumerate<std::slice::Iter<'a, $T>>,
227 impl<'a> Iterator for $Iter<'a> {
228 type Item = ($I, &'a $T);
230 fn next(&mut self) -> Option<Self::Item> {
231 self.iter.next().map(|(i, v)| (<$I>::new(i), v))
234 fn size_hint(&self) -> (usize, Option<usize>) {
235 self.iter.size_hint()
238 fn fold<B, F>(self, init: B, mut f: F) -> B
240 F: FnMut(B, Self::Item) -> B,
243 .fold(init, move |a, (i, v)| f(a, (<$I>::new(i), v)))
247 impl DoubleEndedIterator for $Iter<'_> {
248 fn next_back(&mut self) -> Option<Self::Item> {
249 self.iter.next_back().map(|(i, v)| (<$I>::new(i), v))
252 fn rfold<B, F>(self, init: B, mut f: F) -> B
254 F: FnMut(B, Self::Item) -> B,
257 .rfold(init, move |a, (i, v)| f(a, (<$I>::new(i), v)))
261 impl ExactSizeIterator for $Iter<'_> {
262 fn len(&self) -> usize {
267 impl FusedIterator for $Iter<'_> {}
270 pub struct $IterMut<'a> {
271 iter: std::iter::Enumerate<std::slice::IterMut<'a, $T>>,
274 impl<'a> Iterator for $IterMut<'a> {
275 type Item = ($I, &'a mut $T);
277 fn next(&mut self) -> Option<Self::Item> {
278 self.iter.next().map(|(i, v)| (<$I>::new(i), v))
281 fn size_hint(&self) -> (usize, Option<usize>) {
282 self.iter.size_hint()
285 fn fold<B, F>(self, init: B, mut f: F) -> B
287 F: FnMut(B, Self::Item) -> B,
290 .fold(init, move |a, (i, v)| f(a, (<$I>::new(i), v)))
294 impl DoubleEndedIterator for $IterMut<'_> {
295 fn next_back(&mut self) -> Option<Self::Item> {
296 self.iter.next_back().map(|(i, v)| (<$I>::new(i), v))
299 fn rfold<B, F>(self, init: B, mut f: F) -> B
301 F: FnMut(B, Self::Item) -> B,
304 .rfold(init, move |a, (i, v)| f(a, (<$I>::new(i), v)))
308 impl ExactSizeIterator for $IterMut<'_> {
309 fn len(&self) -> usize {
314 impl FusedIterator for $IterMut<'_> {}
316 impl Index<$I> for Vec<$T> {
319 fn index(&self, index: $I) -> &Self::Output {
324 impl IndexMut<$I> for Vec<$T> {
325 fn index_mut(&mut self, index: $I) -> &mut Self::Output {
326 &mut self[index.get()]
330 impl<'a> Entries<'a, $I> for Vec<$T> {
331 type Iter = $Iter<'a>;
332 fn entries(&'a self) -> Self::Iter {
334 iter: (**self).iter().enumerate(),
337 fn keys(&'a self) -> RangeIter<$I> {
338 RangeIter::from_usize_range(0..self.len())
342 impl<'a> EntriesMut<'a, $I> for Vec<$T> {
343 type IterMut = $IterMut<'a>;
344 fn entries_mut(&'a mut self) -> Self::IterMut {
346 iter: (**self).iter_mut().enumerate(),
352 impl TryIndex<$I> for Vec<$T> {
355 fn try_index(&self, idx: $I) -> Result<&Self::Output, Self::Error> {
356 self.get(idx.get()).ok_or($Error { idx })
360 impl TryIndexMut<$I> for Vec<$T> {
361 fn try_index_mut(&mut self, idx: $I) -> Result<&mut Self::Output, Self::Error> {
362 self.get_mut(idx.get()).ok_or($Error { idx })
367 impl Index<$I> for [$T] {
370 fn index(&self, index: $I) -> &Self::Output {
375 impl IndexMut<$I> for [$T] {
376 fn index_mut(&mut self, index: $I) -> &mut Self::Output {
377 &mut self[index.get()]
381 impl<'a> Entries<'a, $I> for [$T] {
382 type Iter = $Iter<'a>;
383 fn entries(&'a self) -> Self::Iter {
385 iter: self.iter().enumerate(),
388 fn keys(&'a self) -> RangeIter<$I> {
389 RangeIter::from_usize_range(0..self.len())
393 impl<'a> EntriesMut<'a, $I> for [$T] {
394 type IterMut = $IterMut<'a>;
395 fn entries_mut(&'a mut self) -> Self::IterMut {
397 iter: self.iter_mut().enumerate(),
403 impl TryIndex<$I> for [$T] {
406 fn try_index(&self, idx: $I) -> Result<&Self::Output, Self::Error> {
407 self.get(idx.get()).ok_or($Error { idx })
411 impl TryIndexMut<$I> for [$T] {
412 fn try_index_mut(&mut self, idx: $I) -> Result<&mut Self::Output, Self::Error> {
413 self.get_mut(idx.get()).ok_or($Error { idx })
421 #[error = SSAValIdxOutOfRange, iter = SSAValEntriesIter, iter_mut = SSAValEntriesIterMut]
422 impl Index<SSAValIdx> for Vec<SSAVal> {}
426 #[error = BlockParamIdxOutOfRange, iter = BlockParamEntriesIter, iter_mut = BlockParamEntriesIterMut]
427 impl Index<BlockParamIdx> for Vec<SSAValIdx> {}
431 #[error = OperandIdxOutOfRange, iter = OperandEntriesIter, iter_mut = OperandEntriesIterMut]
432 impl Index<OperandIdx> for Vec<Operand> {}
436 #[error = InstIdxOutOfRange, iter = InstEntriesIter, iter_mut = InstEntriesIterMut]
437 impl Index<InstIdx> for Vec<Inst> {}
441 #[error = BlockIdxOutOfRange, iter = BlockEntriesIter, iter_mut = BlockEntriesIterMut]
442 impl Index<BlockIdx> for Vec<Block> {}
446 #[iter = LiveRangeEntriesIter, iter_mut = LiveRangeEntriesIterMut]
447 impl Index<LiveRangeIdx> for Vec<LiveRange> {}
450 impl fmt::Display for SSAValIdx {
451 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
452 write!(f, "v{}", self.get())
456 impl fmt::Display for InstIdx {
457 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
458 write!(f, "inst{}", self.get())
462 impl fmt::Display for BlockIdx {
463 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
464 write!(f, "blk{}", self.get())
468 impl fmt::Display for BlockParamIdx {
469 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
470 write!(f, "bparam{}", self.get())
474 impl fmt::Display for OperandIdx {
475 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
476 write!(f, "operand{}", self.get())
480 impl fmt::Display for LiveRangeIdx {
481 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
482 write!(f, "live_range{}", self.get())
487 pub const ENTRY_BLOCK: BlockIdx = BlockIdx::new(0);
490 /// range of instruction indexes from `start` inclusive to `end` exclusive.
491 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
492 pub struct InstRange {
497 impl fmt::Display for InstRange {
498 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
499 write!(f, "inst{}..{}", self.start.get(), self.end.get())
503 impl IntoIterator for InstRange {
505 type IntoIter = InstRangeIter;
506 fn into_iter(self) -> Self::IntoIter {
512 pub const fn iter(self) -> InstRangeIter {
513 InstRangeIter(self.start.get()..self.end.get())
515 pub const fn is_empty(self) -> bool {
516 self.start.get() >= self.end.get()
518 pub const fn first(self) -> Option<InstIdx> {
519 Some(const_try_opt!(self.split_first()).0)
521 pub const fn last(self) -> Option<InstIdx> {
522 Some(const_try_opt!(self.split_last()).0)
524 pub const fn split_first(self) -> Option<(InstIdx, InstRange)> {
531 start: self.start.next(),
537 pub const fn split_last(self) -> Option<(InstIdx, InstRange)> {
545 end: self.end.prev(),
550 pub const fn len(self) -> usize {
554 self.end.get() - self.start.get()
559 #[derive(Clone, Debug)]
560 pub struct InstRangeIter(Range<usize>);
563 pub const fn range(self) -> InstRange {
565 start: InstIdx::new(self.0.start),
566 end: InstIdx::new(self.0.end),
571 impl Iterator for InstRangeIter {
574 fn next(&mut self) -> Option<Self::Item> {
575 self.0.next().map(InstIdx::new)
578 fn size_hint(&self) -> (usize, Option<usize>) {
579 let v = self.0.len();
583 fn count(self) -> usize
590 fn last(self) -> Option<Self::Item>
594 self.0.last().map(InstIdx::new)
597 fn nth(&mut self, n: usize) -> Option<Self::Item> {
598 self.0.nth(n).map(InstIdx::new)
602 impl FusedIterator for InstRangeIter {}
604 impl DoubleEndedIterator for InstRangeIter {
605 fn next_back(&mut self) -> Option<Self::Item> {
606 self.0.next_back().map(InstIdx::new)
609 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
610 self.0.nth_back(n).map(InstIdx::new)
614 impl ExactSizeIterator for InstRangeIter {
615 fn len(&self) -> usize {