diff --git a/cranelift/codegen/meta/src/cdsl/cpu_modes.rs b/cranelift/codegen/meta/src/cdsl/cpu_modes.rs index 5e0e5b4762..30a7028cf9 100644 --- a/cranelift/codegen/meta/src/cdsl/cpu_modes.rs +++ b/cranelift/codegen/meta/src/cdsl/cpu_modes.rs @@ -35,37 +35,6 @@ impl CpuMode { .is_none()); } - /// Returns a deterministically ordered, deduplicated list of TransformGroupIndex for the - /// transitive set of TransformGroup this TargetIsa uses. - pub fn transitive_transform_groups( - &self, - all_groups: &TransformGroups, - ) -> Vec { - let mut roots = Vec::new(); - if let Some(i) = &self.default_legalize { - roots.push(*i); - } - if let Some(i) = &self.monomorphic_legalize { - roots.push(*i); - } - roots.extend(self.typed_legalize.values().cloned()); - - let mut set = HashSet::new(); - for root in roots { - set.insert(root); - let mut base = root; - // Follow the chain of chain_with. - while let Some(chain_with) = &all_groups.get(base).chain_with { - set.insert(*chain_with); - base = *chain_with; - } - } - - let mut ret = Vec::from_iter(set); - ret.sort(); - ret - } - /// 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 { diff --git a/cranelift/codegen/meta/src/cdsl/isa.rs b/cranelift/codegen/meta/src/cdsl/isa.rs index dcac2605c1..07467229c7 100644 --- a/cranelift/codegen/meta/src/cdsl/isa.rs +++ b/cranelift/codegen/meta/src/cdsl/isa.rs @@ -13,6 +13,11 @@ pub struct TargetIsa { pub settings: SettingGroup, pub regs: IsaRegs, pub cpu_modes: Vec, + + /// TransformGroupIndex are global to all the ISAs, while we want to have indices into the + /// local array of transform groups that are directly used. We use this map to get this + /// information. + pub local_transform_groups: Vec, } impl TargetIsa { @@ -23,12 +28,29 @@ impl TargetIsa { regs: IsaRegs, cpu_modes: Vec, ) -> Self { + // Compute the local TransformGroup index. + let mut local_transform_groups = Vec::new(); + for cpu_mode in &cpu_modes { + let transform_groups = cpu_mode.direct_transform_groups(); + for group_index in transform_groups { + // find() is fine here: the number of transform group is < 5 as of June 2019. + if local_transform_groups + .iter() + .find(|&val| group_index == *val) + .is_none() + { + local_transform_groups.push(group_index); + } + } + } + Self { name, instructions, settings, regs, cpu_modes, + local_transform_groups, } } @@ -39,9 +61,17 @@ impl TargetIsa { all_groups: &TransformGroups, ) -> Vec { let mut set = HashSet::new(); - for cpu_mode in &self.cpu_modes { - set.extend(cpu_mode.transitive_transform_groups(all_groups)); + + for &root in self.local_transform_groups.iter() { + set.insert(root); + let mut base = root; + // Follow the chain of chain_with. + while let Some(chain_with) = &all_groups.get(base).chain_with { + set.insert(*chain_with); + base = *chain_with; + } } + let mut vec = Vec::from_iter(set); vec.sort(); vec @@ -49,13 +79,14 @@ impl TargetIsa { /// 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(); - for cpu_mode in &self.cpu_modes { - set.extend(cpu_mode.direct_transform_groups()); - } - let mut vec = Vec::from_iter(set); - vec.sort(); - vec + pub fn direct_transform_groups(&self) -> &Vec { + &self.local_transform_groups + } + + pub fn translate_group_index(&self, group_index: TransformGroupIndex) -> usize { + self.local_transform_groups + .iter() + .position(|&val| val == group_index) + .expect("TransformGroup unused by this TargetIsa!") } } diff --git a/cranelift/codegen/meta/src/cdsl/settings.rs b/cranelift/codegen/meta/src/cdsl/settings.rs index 61677a71f3..5a45d9fb9b 100644 --- a/cranelift/codegen/meta/src/cdsl/settings.rs +++ b/cranelift/codegen/meta/src/cdsl/settings.rs @@ -148,6 +148,14 @@ impl SettingGroup { } panic!("Should have found bool setting by name."); } + + pub fn predicate_by_name(&self, name: &'static str) -> SettingPredicateNumber { + self.predicates + .iter() + .find(|pred| pred.name == name) + .unwrap_or_else(|| panic!("unknown predicate {}", name)) + .number + } } /// This is the basic information needed to track the specific parts of a setting when building @@ -209,10 +217,12 @@ struct ProtoPredicate { node: PredicateNode, } +pub type SettingPredicateNumber = u8; + pub struct Predicate { pub name: &'static str, node: PredicateNode, - pub number: u8, + pub number: SettingPredicateNumber, } impl Predicate { diff --git a/cranelift/codegen/meta/src/gen_legalizer.rs b/cranelift/codegen/meta/src/gen_legalizer.rs index 149e29f926..545928db1e 100644 --- a/cranelift/codegen/meta/src/gen_legalizer.rs +++ b/cranelift/codegen/meta/src/gen_legalizer.rs @@ -527,7 +527,7 @@ fn gen_isa( direct_groups.len() ); fmt.indent(|fmt| { - for group_index in direct_groups { + for &group_index in direct_groups { fmtln!(fmt, "{},", transform_groups.get(group_index).rust_name()); } });