use std::collections::{hash_map, HashMap, HashSet}; use std::iter::FromIterator; use crate::cdsl::encodings::Encoding; use crate::cdsl::types::{LaneType, ValueType}; use crate::cdsl::xform::{TransformGroup, TransformGroupIndex}; pub(crate) struct CpuMode { pub name: &'static str, default_legalize: Option, monomorphic_legalize: Option, typed_legalize: HashMap, pub encodings: Vec, } impl CpuMode { pub fn new(name: &'static str) -> Self { Self { name, default_legalize: None, monomorphic_legalize: None, typed_legalize: HashMap::new(), encodings: Vec::new(), } } pub fn set_encodings(&mut self, encodings: Vec) { assert!(self.encodings.is_empty(), "clobbering encodings"); self.encodings = encodings; } pub fn legalize_monomorphic(&mut self, group: &TransformGroup) { assert!(self.monomorphic_legalize.is_none()); self.monomorphic_legalize = Some(group.id); } pub fn legalize_default(&mut self, group: &TransformGroup) { assert!(self.default_legalize.is_none()); self.default_legalize = Some(group.id); } pub fn legalize_value_type(&mut self, lane_type: impl Into, group: &TransformGroup) { assert!(self .typed_legalize .insert(lane_type.into(), group.id) .is_none()); } pub fn legalize_type(&mut self, lane_type: impl Into, group: &TransformGroup) { assert!(self .typed_legalize .insert(lane_type.into().into(), group.id) .is_none()); } pub fn get_default_legalize_code(&self) -> TransformGroupIndex { self.default_legalize .expect("a finished CpuMode must have a default legalize code") } pub fn get_legalize_code_for(&self, typ: &Option) -> TransformGroupIndex { match typ { Some(typ) => self .typed_legalize .get(typ) .copied() .unwrap_or_else(|| self.get_default_legalize_code()), None => self .monomorphic_legalize .unwrap_or_else(|| self.get_default_legalize_code()), } } pub fn get_legalized_types(&self) -> hash_map::Keys { self.typed_legalize.keys() } /// Returns a deterministically ordered, deduplicated list of TransformGroupIndex for the directly /// reachable set of TransformGroup this TargetIsa uses. pub fn direct_transform_groups(&self) -> Vec { let mut set = HashSet::new(); if let Some(i) = &self.default_legalize { set.insert(*i); } if let Some(i) = &self.monomorphic_legalize { set.insert(*i); } set.extend(self.typed_legalize.values().cloned()); let mut ret = Vec::from_iter(set); ret.sort(); ret } }