diff --git a/crates/ir/src/inst.rs b/crates/ir/src/inst/basic.rs similarity index 70% rename from crates/ir/src/inst.rs rename to crates/ir/src/inst/basic.rs index 9a52fc19..35dd530a 100644 --- a/crates/ir/src/inst.rs +++ b/crates/ir/src/inst/basic.rs @@ -1,24 +1,7 @@ -use sonatina_macros::Inst; -use std::any::{Any, TypeId}; - -use smallvec::SmallVec; - use crate::{module::FuncRef, Block, Type, Value}; +use smallvec::SmallVec; -pub trait Inst: Any { - fn visit_values(&self, f: &mut dyn FnMut(Value)); - fn visit_values_mut(&mut self, f: &mut dyn FnMut(&mut Value)); - fn has_side_effect(&self) -> bool; - fn as_text(&self) -> &'static str; -} - -/// This trait works as a "proof" that a specific ISA contains `I`, -/// and then allows a construction and reflection of type `I` in that specific ISA context. -pub trait HasInst { - fn is(&self, inst: &dyn Inst) -> bool { - inst.type_id() == TypeId::of::() - } -} +use sonatina_macros::Inst; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Inst)] #[inst(side_effect = false)] @@ -308,87 +291,6 @@ pub struct Phi { ty: Type, } -pub(crate) trait ValueVisitable { - fn visit_with(&self, f: &mut dyn FnMut(Value)); - fn visit_mut_with(&mut self, f: &mut dyn FnMut(&mut Value)); -} - -impl ValueVisitable for Value { - fn visit_with(&self, f: &mut dyn FnMut(Value)) { - f(*self) - } - - fn visit_mut_with(&mut self, f: &mut dyn FnMut(&mut Value)) { - f(self) - } -} - -impl ValueVisitable for Option -where - V: ValueVisitable, -{ - fn visit_with(&self, f: &mut dyn FnMut(Value)) { - if let Some(value) = self { - value.visit_with(f) - } - } - - fn visit_mut_with(&mut self, f: &mut dyn FnMut(&mut Value)) { - if let Some(value) = self.as_mut() { - value.visit_mut_with(f) - } - } -} - -impl ValueVisitable for (V, T) -where - V: ValueVisitable, -{ - fn visit_with(&self, f: &mut dyn FnMut(Value)) { - self.0.visit_with(f) - } - - fn visit_mut_with(&mut self, f: &mut dyn FnMut(&mut Value)) { - self.0.visit_mut_with(f) - } -} - -impl ValueVisitable for Vec -where - V: ValueVisitable, -{ - fn visit_with(&self, f: &mut dyn FnMut(Value)) { - self.iter().for_each(|v| v.visit_with(f)) - } - - fn visit_mut_with(&mut self, f: &mut dyn FnMut(&mut Value)) { - self.iter_mut().for_each(|v| v.visit_mut_with(f)) - } -} - -impl ValueVisitable for [V] -where - V: ValueVisitable, -{ - fn visit_with(&self, f: &mut dyn FnMut(Value)) { - self.iter().for_each(|v| v.visit_with(f)) - } - - fn visit_mut_with(&mut self, f: &mut dyn FnMut(&mut Value)) { - self.iter_mut().for_each(|v| v.visit_mut_with(f)) - } -} - -impl ValueVisitable for SmallVec<[V; N]> -where - V: ValueVisitable, - [V; N]: smallvec::Array, -{ - fn visit_with(&self, f: &mut dyn FnMut(Value)) { - self.iter().for_each(|v| v.visit_with(f)) - } - - fn visit_mut_with(&mut self, f: &mut dyn FnMut(&mut Value)) { - self.iter_mut().for_each(|v| v.visit_mut_with(f)) - } -} +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Inst)] +#[inst(side_effect = false)] +pub struct Nop {} diff --git a/crates/ir/src/inst/mod.rs b/crates/ir/src/inst/mod.rs new file mode 100644 index 00000000..2d11dee9 --- /dev/null +++ b/crates/ir/src/inst/mod.rs @@ -0,0 +1,107 @@ +pub mod basic; + +use std::any::{Any, TypeId}; + +use smallvec::SmallVec; + +use crate::Value; + +pub trait Inst: Any { + fn visit_values(&self, f: &mut dyn FnMut(Value)); + fn visit_values_mut(&mut self, f: &mut dyn FnMut(&mut Value)); + fn has_side_effect(&self) -> bool; + fn as_text(&self) -> &'static str; +} + +/// This trait works as a "proof" that a specific ISA contains `I`, +/// and then allows a construction and reflection of type `I` in that specific ISA context. +pub trait HasInst { + fn is(&self, inst: &dyn Inst) -> bool { + inst.type_id() == TypeId::of::() + } +} + +pub(crate) trait ValueVisitable { + fn visit_with(&self, f: &mut dyn FnMut(Value)); + fn visit_mut_with(&mut self, f: &mut dyn FnMut(&mut Value)); +} + +impl ValueVisitable for Value { + fn visit_with(&self, f: &mut dyn FnMut(Value)) { + f(*self) + } + + fn visit_mut_with(&mut self, f: &mut dyn FnMut(&mut Value)) { + f(self) + } +} + +impl ValueVisitable for Option +where + V: ValueVisitable, +{ + fn visit_with(&self, f: &mut dyn FnMut(Value)) { + if let Some(value) = self { + value.visit_with(f) + } + } + + fn visit_mut_with(&mut self, f: &mut dyn FnMut(&mut Value)) { + if let Some(value) = self.as_mut() { + value.visit_mut_with(f) + } + } +} + +impl ValueVisitable for (V, T) +where + V: ValueVisitable, +{ + fn visit_with(&self, f: &mut dyn FnMut(Value)) { + self.0.visit_with(f) + } + + fn visit_mut_with(&mut self, f: &mut dyn FnMut(&mut Value)) { + self.0.visit_mut_with(f) + } +} + +impl ValueVisitable for Vec +where + V: ValueVisitable, +{ + fn visit_with(&self, f: &mut dyn FnMut(Value)) { + self.iter().for_each(|v| v.visit_with(f)) + } + + fn visit_mut_with(&mut self, f: &mut dyn FnMut(&mut Value)) { + self.iter_mut().for_each(|v| v.visit_mut_with(f)) + } +} + +impl ValueVisitable for [V] +where + V: ValueVisitable, +{ + fn visit_with(&self, f: &mut dyn FnMut(Value)) { + self.iter().for_each(|v| v.visit_with(f)) + } + + fn visit_mut_with(&mut self, f: &mut dyn FnMut(&mut Value)) { + self.iter_mut().for_each(|v| v.visit_mut_with(f)) + } +} + +impl ValueVisitable for SmallVec<[V; N]> +where + V: ValueVisitable, + [V; N]: smallvec::Array, +{ + fn visit_with(&self, f: &mut dyn FnMut(Value)) { + self.iter().for_each(|v| v.visit_with(f)) + } + + fn visit_mut_with(&mut self, f: &mut dyn FnMut(&mut Value)) { + self.iter_mut().for_each(|v| v.visit_mut_with(f)) + } +} diff --git a/crates/macros/src/lib.rs b/crates/macros/src/lib.rs index 3c421bfe..940b71fc 100644 --- a/crates/macros/src/lib.rs +++ b/crates/macros/src/lib.rs @@ -186,20 +186,20 @@ impl InstStruct { fn make_cast_fn(&self) -> proc_macro2::TokenStream { quote! { - pub fn cast<'i>(hi: &dyn crate::HasInst, inst: &'i dyn Inst) -> Option<&'i Self> { + pub fn cast<'i>(hi: &dyn crate::HasInst, inst: &'i dyn crate::Inst) -> Option<&'i Self> { if hi.is(inst) { - unsafe { Some(&*(inst as *const dyn Inst as *const Self)) } + unsafe { Some(&*(inst as *const dyn crate::Inst as *const Self)) } } else { None } } pub fn cast_mut<'i>( - hi: &dyn HasInst, - inst: &'i mut dyn Inst, + hi: &dyn crate::HasInst, + inst: &'i mut dyn crate::Inst, ) -> Option<&'i mut Self> { if hi.is(inst) { - unsafe { Some(&mut *(inst as *mut dyn Inst as *mut Self)) } + unsafe { Some(&mut *(inst as *mut dyn crate::Inst as *mut Self)) } } else { None }