[meta] Map global TransformGroup to local TransformGroup indices;
This commit is contained in:
@@ -35,37 +35,6 @@ impl CpuMode {
|
|||||||
.is_none());
|
.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<TransformGroupIndex> {
|
|
||||||
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
|
/// Returns a deterministically ordered, deduplicated list of TransformGroupIndex for the directly
|
||||||
/// reachable set of TransformGroup this TargetIsa uses.
|
/// reachable set of TransformGroup this TargetIsa uses.
|
||||||
pub fn direct_transform_groups(&self) -> Vec<TransformGroupIndex> {
|
pub fn direct_transform_groups(&self) -> Vec<TransformGroupIndex> {
|
||||||
|
|||||||
@@ -13,6 +13,11 @@ pub struct TargetIsa {
|
|||||||
pub settings: SettingGroup,
|
pub settings: SettingGroup,
|
||||||
pub regs: IsaRegs,
|
pub regs: IsaRegs,
|
||||||
pub cpu_modes: Vec<CpuMode>,
|
pub cpu_modes: Vec<CpuMode>,
|
||||||
|
|
||||||
|
/// 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<TransformGroupIndex>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TargetIsa {
|
impl TargetIsa {
|
||||||
@@ -23,12 +28,29 @@ impl TargetIsa {
|
|||||||
regs: IsaRegs,
|
regs: IsaRegs,
|
||||||
cpu_modes: Vec<CpuMode>,
|
cpu_modes: Vec<CpuMode>,
|
||||||
) -> Self {
|
) -> 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 {
|
Self {
|
||||||
name,
|
name,
|
||||||
instructions,
|
instructions,
|
||||||
settings,
|
settings,
|
||||||
regs,
|
regs,
|
||||||
cpu_modes,
|
cpu_modes,
|
||||||
|
local_transform_groups,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,9 +61,17 @@ impl TargetIsa {
|
|||||||
all_groups: &TransformGroups,
|
all_groups: &TransformGroups,
|
||||||
) -> Vec<TransformGroupIndex> {
|
) -> Vec<TransformGroupIndex> {
|
||||||
let mut set = HashSet::new();
|
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);
|
let mut vec = Vec::from_iter(set);
|
||||||
vec.sort();
|
vec.sort();
|
||||||
vec
|
vec
|
||||||
@@ -49,13 +79,14 @@ impl TargetIsa {
|
|||||||
|
|
||||||
/// Returns a deterministically ordered, deduplicated list of TransformGroupIndex for the directly
|
/// Returns a deterministically ordered, deduplicated list of TransformGroupIndex for the directly
|
||||||
/// reachable set of TransformGroup this TargetIsa uses.
|
/// reachable set of TransformGroup this TargetIsa uses.
|
||||||
pub fn direct_transform_groups(&self) -> Vec<TransformGroupIndex> {
|
pub fn direct_transform_groups(&self) -> &Vec<TransformGroupIndex> {
|
||||||
let mut set = HashSet::new();
|
&self.local_transform_groups
|
||||||
for cpu_mode in &self.cpu_modes {
|
|
||||||
set.extend(cpu_mode.direct_transform_groups());
|
|
||||||
}
|
}
|
||||||
let mut vec = Vec::from_iter(set);
|
|
||||||
vec.sort();
|
pub fn translate_group_index(&self, group_index: TransformGroupIndex) -> usize {
|
||||||
vec
|
self.local_transform_groups
|
||||||
|
.iter()
|
||||||
|
.position(|&val| val == group_index)
|
||||||
|
.expect("TransformGroup unused by this TargetIsa!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -148,6 +148,14 @@ impl SettingGroup {
|
|||||||
}
|
}
|
||||||
panic!("Should have found bool setting by name.");
|
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
|
/// This is the basic information needed to track the specific parts of a setting when building
|
||||||
@@ -209,10 +217,12 @@ struct ProtoPredicate {
|
|||||||
node: PredicateNode,
|
node: PredicateNode,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub type SettingPredicateNumber = u8;
|
||||||
|
|
||||||
pub struct Predicate {
|
pub struct Predicate {
|
||||||
pub name: &'static str,
|
pub name: &'static str,
|
||||||
node: PredicateNode,
|
node: PredicateNode,
|
||||||
pub number: u8,
|
pub number: SettingPredicateNumber,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Predicate {
|
impl Predicate {
|
||||||
|
|||||||
@@ -527,7 +527,7 @@ fn gen_isa(
|
|||||||
direct_groups.len()
|
direct_groups.len()
|
||||||
);
|
);
|
||||||
fmt.indent(|fmt| {
|
fmt.indent(|fmt| {
|
||||||
for group_index in direct_groups {
|
for &group_index in direct_groups {
|
||||||
fmtln!(fmt, "{},", transform_groups.get(group_index).rust_name());
|
fmtln!(fmt, "{},", transform_groups.get(group_index).rust_name());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user