From 3e4167ba956f15f70b3075e2536c0954d36cc383 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Mon, 21 Jun 2021 12:57:37 +0200 Subject: [PATCH] Remove registers from cranelift-codegen-meta --- cranelift/codegen/meta/src/cdsl/isa.rs | 10 +- cranelift/codegen/meta/src/cdsl/mod.rs | 1 - cranelift/codegen/meta/src/cdsl/regs.rs | 332 -------------------- cranelift/codegen/meta/src/gen_registers.rs | 148 --------- cranelift/codegen/meta/src/isa/arm32/mod.rs | 41 +-- cranelift/codegen/meta/src/isa/arm64/mod.rs | 37 +-- cranelift/codegen/meta/src/isa/s390x/mod.rs | 4 +- cranelift/codegen/meta/src/isa/x86/mod.rs | 3 +- cranelift/codegen/meta/src/lib.rs | 3 - 9 files changed, 6 insertions(+), 573 deletions(-) delete mode 100644 cranelift/codegen/meta/src/cdsl/regs.rs delete mode 100644 cranelift/codegen/meta/src/gen_registers.rs diff --git a/cranelift/codegen/meta/src/cdsl/isa.rs b/cranelift/codegen/meta/src/cdsl/isa.rs index 7eb7c30517..b595ffa99f 100644 --- a/cranelift/codegen/meta/src/cdsl/isa.rs +++ b/cranelift/codegen/meta/src/cdsl/isa.rs @@ -1,18 +1,12 @@ -use crate::cdsl::regs::IsaRegs; use crate::cdsl::settings::SettingGroup; pub(crate) struct TargetIsa { pub name: &'static str, pub settings: SettingGroup, - pub regs: IsaRegs, } impl TargetIsa { - pub fn new(name: &'static str, settings: SettingGroup, regs: IsaRegs) -> Self { - Self { - name, - settings, - regs, - } + pub fn new(name: &'static str, settings: SettingGroup) -> Self { + Self { name, settings } } } diff --git a/cranelift/codegen/meta/src/cdsl/mod.rs b/cranelift/codegen/meta/src/cdsl/mod.rs index a1fb8d4ea3..bf7acbbeb4 100644 --- a/cranelift/codegen/meta/src/cdsl/mod.rs +++ b/cranelift/codegen/meta/src/cdsl/mod.rs @@ -7,7 +7,6 @@ pub mod formats; pub mod instructions; pub mod isa; pub mod operands; -pub mod regs; pub mod settings; pub mod type_inference; pub mod types; diff --git a/cranelift/codegen/meta/src/cdsl/regs.rs b/cranelift/codegen/meta/src/cdsl/regs.rs deleted file mode 100644 index 11e1d83dd6..0000000000 --- a/cranelift/codegen/meta/src/cdsl/regs.rs +++ /dev/null @@ -1,332 +0,0 @@ -use cranelift_codegen_shared::constants; -use cranelift_entity::{entity_impl, EntityRef, PrimaryMap}; - -#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] -pub(crate) struct RegBankIndex(u32); -entity_impl!(RegBankIndex); - -pub(crate) struct RegBank { - pub name: &'static str, - pub first_unit: u8, - pub units: u8, - pub names: Vec<&'static str>, - pub prefix: &'static str, - pub pressure_tracking: bool, - pub pinned_reg: Option, - pub toprcs: Vec, - pub classes: Vec, -} - -impl RegBank { - pub fn new( - name: &'static str, - first_unit: u8, - units: u8, - names: Vec<&'static str>, - prefix: &'static str, - pressure_tracking: bool, - pinned_reg: Option, - ) -> Self { - RegBank { - name, - first_unit, - units, - names, - prefix, - pressure_tracking, - pinned_reg, - toprcs: Vec::new(), - classes: Vec::new(), - } - } -} - -#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)] -pub(crate) struct RegClassIndex(u32); -entity_impl!(RegClassIndex); - -pub(crate) struct RegClass { - pub name: &'static str, - pub index: RegClassIndex, - pub width: u8, - pub bank: RegBankIndex, - pub toprc: RegClassIndex, - pub count: u8, - pub start: u8, - pub subclasses: Vec, -} - -impl RegClass { - pub fn new( - name: &'static str, - index: RegClassIndex, - width: u8, - bank: RegBankIndex, - toprc: RegClassIndex, - count: u8, - start: u8, - ) -> Self { - Self { - name, - index, - width, - bank, - toprc, - count, - start, - subclasses: Vec::new(), - } - } - - /// Compute a bit-mask of subclasses, including self. - pub fn subclass_mask(&self) -> u64 { - let mut m = 1 << self.index.index(); - for rc in self.subclasses.iter() { - m |= 1 << rc.index(); - } - m - } - - /// Compute a bit-mask of the register units allocated by this register class. - pub fn mask(&self, bank_first_unit: u8) -> Vec { - let mut u = (self.start + bank_first_unit) as usize; - let mut out_mask = vec![0, 0, 0]; - for _ in 0..self.count { - out_mask[u / 32] |= 1 << (u % 32); - u += self.width as usize; - } - out_mask - } -} - -pub(crate) enum RegClassProto { - TopLevel(RegBankIndex), -} - -pub(crate) struct RegClassBuilder { - pub name: &'static str, - pub width: u8, - pub count: u8, - pub start: u8, - pub proto: RegClassProto, -} - -impl RegClassBuilder { - pub fn new_toplevel(name: &'static str, bank: RegBankIndex) -> Self { - Self { - name, - width: 1, - count: 0, - start: 0, - proto: RegClassProto::TopLevel(bank), - } - } - pub fn count(mut self, count: u8) -> Self { - self.count = count; - self - } - pub fn width(mut self, width: u8) -> Self { - match self.proto { - RegClassProto::TopLevel(_) => self.width = width, - } - self - } -} - -pub(crate) struct RegBankBuilder { - pub name: &'static str, - pub units: u8, - pub names: Vec<&'static str>, - pub prefix: &'static str, - pub pressure_tracking: Option, - pub pinned_reg: Option, -} - -impl RegBankBuilder { - pub fn new(name: &'static str, prefix: &'static str) -> Self { - Self { - name, - units: 0, - names: vec![], - prefix, - pressure_tracking: None, - pinned_reg: None, - } - } - pub fn units(mut self, units: u8) -> Self { - self.units = units; - self - } - pub fn names(mut self, names: Vec<&'static str>) -> Self { - self.names = names; - self - } - pub fn track_pressure(mut self, track: bool) -> Self { - self.pressure_tracking = Some(track); - self - } -} - -pub(crate) struct IsaRegsBuilder { - pub banks: PrimaryMap, - pub classes: PrimaryMap, -} - -impl IsaRegsBuilder { - pub fn new() -> Self { - Self { - banks: PrimaryMap::new(), - classes: PrimaryMap::new(), - } - } - - pub fn add_bank(&mut self, builder: RegBankBuilder) -> RegBankIndex { - let first_unit = if self.banks.is_empty() { - 0 - } else { - let last = &self.banks.last().unwrap(); - let first_available_unit = (last.first_unit + last.units) as i8; - let units = builder.units; - let align = if units.is_power_of_two() { - units - } else { - units.next_power_of_two() - } as i8; - (first_available_unit + align - 1) & -align - } as u8; - - self.banks.push(RegBank::new( - builder.name, - first_unit, - builder.units, - builder.names, - builder.prefix, - builder - .pressure_tracking - .expect("Pressure tracking must be explicitly set"), - builder.pinned_reg, - )) - } - - pub fn add_class(&mut self, builder: RegClassBuilder) -> RegClassIndex { - let class_index = self.classes.next_key(); - - // Finish delayed construction of RegClass. - let (bank, toprc, start, width) = match builder.proto { - RegClassProto::TopLevel(bank_index) => { - self.banks - .get_mut(bank_index) - .unwrap() - .toprcs - .push(class_index); - (bank_index, class_index, builder.start, builder.width) - } - }; - - let reg_bank_units = self.banks.get(bank).unwrap().units; - assert!(start < reg_bank_units); - - let count = if builder.count != 0 { - builder.count - } else { - reg_bank_units / width - }; - - let reg_class = RegClass::new(builder.name, class_index, width, bank, toprc, count, start); - self.classes.push(reg_class); - - let reg_bank = self.banks.get_mut(bank).unwrap(); - reg_bank.classes.push(class_index); - - class_index - } - - /// Checks that the set of register classes satisfies: - /// - /// 1. Closed under intersection: The intersection of any two register - /// classes in the set is either empty or identical to a member of the - /// set. - /// 2. There are no identical classes under different names. - /// 3. Classes are sorted topologically such that all subclasses have a - /// higher index that the superclass. - pub fn build(self) -> IsaRegs { - for reg_bank in self.banks.values() { - for i1 in reg_bank.classes.iter() { - for i2 in reg_bank.classes.iter() { - if i1 >= i2 { - continue; - } - - let rc1 = self.classes.get(*i1).unwrap(); - let rc2 = self.classes.get(*i2).unwrap(); - - let rc1_mask = rc1.mask(0); - let rc2_mask = rc2.mask(0); - - assert!( - rc1.width != rc2.width || rc1_mask != rc2_mask, - "no duplicates" - ); - if rc1.width != rc2.width { - continue; - } - - let mut intersect = Vec::new(); - for (a, b) in rc1_mask.iter().zip(rc2_mask.iter()) { - intersect.push(a & b); - } - if intersect == vec![0; intersect.len()] { - continue; - } - - // Classes must be topologically ordered, so the intersection can't be the - // superclass. - assert!(intersect != rc1_mask); - - // If the intersection is the second one, then it must be a subclass. - if intersect == rc2_mask { - assert!(self - .classes - .get(*i1) - .unwrap() - .subclasses - .iter() - .any(|x| *x == *i2)); - } - } - } - } - - assert!( - self.classes.len() <= constants::MAX_NUM_REG_CLASSES, - "Too many register classes" - ); - - let num_toplevel = self - .classes - .values() - .filter(|x| x.toprc == x.index && self.banks.get(x.bank).unwrap().pressure_tracking) - .count(); - - assert!( - num_toplevel <= constants::MAX_TRACKED_TOP_RCS, - "Too many top-level register classes" - ); - - IsaRegs::new(self.banks, self.classes) - } -} - -pub(crate) struct IsaRegs { - pub banks: PrimaryMap, - pub classes: PrimaryMap, -} - -impl IsaRegs { - fn new( - banks: PrimaryMap, - classes: PrimaryMap, - ) -> Self { - Self { banks, classes } - } -} diff --git a/cranelift/codegen/meta/src/gen_registers.rs b/cranelift/codegen/meta/src/gen_registers.rs deleted file mode 100644 index bd5ac95ae0..0000000000 --- a/cranelift/codegen/meta/src/gen_registers.rs +++ /dev/null @@ -1,148 +0,0 @@ -//! Generate the ISA-specific registers. -use crate::cdsl::isa::TargetIsa; -use crate::cdsl::regs::{RegBank, RegClass}; -use crate::error; -use crate::srcgen::Formatter; -use cranelift_entity::EntityRef; - -fn gen_regbank(fmt: &mut Formatter, reg_bank: &RegBank) { - let names = if !reg_bank.names.is_empty() { - format!(r#""{}""#, reg_bank.names.join(r#"", ""#)) - } else { - "".to_string() - }; - fmtln!(fmt, "RegBank {"); - fmt.indent(|fmt| { - fmtln!(fmt, r#"name: "{}","#, reg_bank.name); - fmtln!(fmt, "first_unit: {},", reg_bank.first_unit); - fmtln!(fmt, "units: {},", reg_bank.units); - fmtln!(fmt, "names: &[{}],", names); - fmtln!(fmt, r#"prefix: "{}","#, reg_bank.prefix); - fmtln!(fmt, "first_toprc: {},", reg_bank.toprcs[0].index()); - fmtln!(fmt, "num_toprcs: {},", reg_bank.toprcs.len()); - fmtln!( - fmt, - "pressure_tracking: {},", - if reg_bank.pressure_tracking { - "true" - } else { - "false" - } - ); - }); - fmtln!(fmt, "},"); -} - -fn gen_regclass(isa: &TargetIsa, reg_class: &RegClass, fmt: &mut Formatter) { - let reg_bank = isa.regs.banks.get(reg_class.bank).unwrap(); - - let mask: Vec = reg_class - .mask(reg_bank.first_unit) - .iter() - .map(|x| format!("0x{:08x}", x)) - .collect(); - let mask = mask.join(", "); - - fmtln!( - fmt, - "pub static {}_DATA: RegClassData = RegClassData {{", - reg_class.name - ); - fmt.indent(|fmt| { - fmtln!(fmt, r#"name: "{}","#, reg_class.name); - fmtln!(fmt, "index: {},", reg_class.index.index()); - fmtln!(fmt, "width: {},", reg_class.width); - fmtln!(fmt, "bank: {},", reg_class.bank.index()); - fmtln!(fmt, "toprc: {},", reg_class.toprc.index()); - fmtln!(fmt, "first: {},", reg_bank.first_unit + reg_class.start); - fmtln!(fmt, "subclasses: {:#x},", reg_class.subclass_mask()); - fmtln!(fmt, "mask: [{}],", mask); - fmtln!( - fmt, - "pinned_reg: {:?},", - reg_bank - .pinned_reg - .map(|index| index + reg_bank.first_unit as u16 + reg_class.start as u16) - ); - fmtln!(fmt, "info: &INFO,"); - }); - fmtln!(fmt, "};"); - - fmtln!(fmt, "#[allow(dead_code)]"); - fmtln!( - fmt, - "pub static {}: RegClass = &{}_DATA;", - reg_class.name, - reg_class.name - ); -} - -fn gen_regbank_units(reg_bank: &RegBank, fmt: &mut Formatter) { - for unit in 0..reg_bank.units { - let v = unit + reg_bank.first_unit; - if (unit as usize) < reg_bank.names.len() { - fmtln!(fmt, "{} = {},", reg_bank.names[unit as usize], v); - continue; - } - fmtln!(fmt, "{}{} = {},", reg_bank.prefix, unit, v); - } -} - -fn gen_isa(isa: &TargetIsa, fmt: &mut Formatter) { - // Emit RegInfo. - fmtln!(fmt, "pub static INFO: RegInfo = RegInfo {"); - - fmt.indent(|fmt| { - fmtln!(fmt, "banks: &["); - // Bank descriptors. - fmt.indent(|fmt| { - for reg_bank in isa.regs.banks.values() { - gen_regbank(fmt, ®_bank); - } - }); - fmtln!(fmt, "],"); - // References to register classes. - fmtln!(fmt, "classes: &["); - fmt.indent(|fmt| { - for reg_class in isa.regs.classes.values() { - fmtln!(fmt, "&{}_DATA,", reg_class.name); - } - }); - fmtln!(fmt, "],"); - }); - fmtln!(fmt, "};"); - - // Register class descriptors. - for rc in isa.regs.classes.values() { - gen_regclass(&isa, rc, fmt); - } - - // Emit constants for all the register units. - fmtln!(fmt, "#[allow(dead_code, non_camel_case_types)]"); - fmtln!(fmt, "#[derive(Clone, Copy)]"); - fmtln!(fmt, "pub enum RU {"); - fmt.indent(|fmt| { - for reg_bank in isa.regs.banks.values() { - gen_regbank_units(reg_bank, fmt); - } - }); - fmtln!(fmt, "}"); - - // Emit Into conversion for the RU class. - fmtln!(fmt, "impl Into for RU {"); - fmt.indent(|fmt| { - fmtln!(fmt, "fn into(self) -> RegUnit {"); - fmt.indent(|fmt| { - fmtln!(fmt, "self as RegUnit"); - }); - fmtln!(fmt, "}"); - }); - fmtln!(fmt, "}"); -} - -pub(crate) fn generate(isa: &TargetIsa, filename: &str, out_dir: &str) -> Result<(), error::Error> { - let mut fmt = Formatter::new(); - gen_isa(&isa, &mut fmt); - fmt.update_file(filename, out_dir)?; - Ok(()) -} diff --git a/cranelift/codegen/meta/src/isa/arm32/mod.rs b/cranelift/codegen/meta/src/isa/arm32/mod.rs index f524a87ea7..1c3b4d1fe0 100644 --- a/cranelift/codegen/meta/src/isa/arm32/mod.rs +++ b/cranelift/codegen/meta/src/isa/arm32/mod.rs @@ -1,5 +1,4 @@ use crate::cdsl::isa::TargetIsa; -use crate::cdsl::regs::{IsaRegs, IsaRegsBuilder, RegBankBuilder, RegClassBuilder}; use crate::cdsl::settings::{SettingGroup, SettingGroupBuilder}; use crate::shared::Definitions as SharedDefinitions; @@ -9,46 +8,8 @@ fn define_settings(_shared: &SettingGroup) -> SettingGroup { setting.build() } -fn define_regs() -> IsaRegs { - let mut regs = IsaRegsBuilder::new(); - - let builder = RegBankBuilder::new("FloatRegs", "s") - .units(64) - .track_pressure(true); - let float_regs = regs.add_bank(builder); - - let builder = RegBankBuilder::new("IntRegs", "r") - .units(16) - .track_pressure(true); - let int_regs = regs.add_bank(builder); - - let builder = RegBankBuilder::new("FlagRegs", "") - .units(1) - .names(vec!["nzcv"]) - .track_pressure(false); - let flag_reg = regs.add_bank(builder); - - let builder = RegClassBuilder::new_toplevel("S", float_regs).count(32); - regs.add_class(builder); - - let builder = RegClassBuilder::new_toplevel("D", float_regs).width(2); - regs.add_class(builder); - - let builder = RegClassBuilder::new_toplevel("Q", float_regs).width(4); - regs.add_class(builder); - - let builder = RegClassBuilder::new_toplevel("GPR", int_regs); - regs.add_class(builder); - - let builder = RegClassBuilder::new_toplevel("FLAG", flag_reg); - regs.add_class(builder); - - regs.build() -} - pub(crate) fn define(shared_defs: &mut SharedDefinitions) -> TargetIsa { let settings = define_settings(&shared_defs.settings); - let regs = define_regs(); - TargetIsa::new("arm32", settings, regs) + TargetIsa::new("arm32", settings) } diff --git a/cranelift/codegen/meta/src/isa/arm64/mod.rs b/cranelift/codegen/meta/src/isa/arm64/mod.rs index a8920f703d..5fd7b69309 100644 --- a/cranelift/codegen/meta/src/isa/arm64/mod.rs +++ b/cranelift/codegen/meta/src/isa/arm64/mod.rs @@ -1,5 +1,4 @@ use crate::cdsl::isa::TargetIsa; -use crate::cdsl::regs::{IsaRegs, IsaRegsBuilder, RegBankBuilder, RegClassBuilder}; use crate::cdsl::settings::{SettingGroup, SettingGroupBuilder}; use crate::shared::Definitions as SharedDefinitions; @@ -12,42 +11,8 @@ fn define_settings(_shared: &SettingGroup) -> SettingGroup { setting.build() } -fn define_registers() -> IsaRegs { - let mut regs = IsaRegsBuilder::new(); - - // The `x31` regunit serves as the stack pointer / zero register depending on context. We - // reserve it and don't model the difference. - let builder = RegBankBuilder::new("IntRegs", "x") - .units(32) - .track_pressure(true); - let int_regs = regs.add_bank(builder); - - let builder = RegBankBuilder::new("FloatRegs", "v") - .units(32) - .track_pressure(true); - let float_regs = regs.add_bank(builder); - - let builder = RegBankBuilder::new("FlagRegs", "") - .units(1) - .names(vec!["nzcv"]) - .track_pressure(false); - let flag_reg = regs.add_bank(builder); - - let builder = RegClassBuilder::new_toplevel("GPR", int_regs); - regs.add_class(builder); - - let builder = RegClassBuilder::new_toplevel("FPR", float_regs); - regs.add_class(builder); - - let builder = RegClassBuilder::new_toplevel("FLAG", flag_reg); - regs.add_class(builder); - - regs.build() -} - pub(crate) fn define(shared_defs: &mut SharedDefinitions) -> TargetIsa { let settings = define_settings(&shared_defs.settings); - let regs = define_registers(); - TargetIsa::new("arm64", settings, regs) + TargetIsa::new("arm64", settings) } diff --git a/cranelift/codegen/meta/src/isa/s390x/mod.rs b/cranelift/codegen/meta/src/isa/s390x/mod.rs index a4fb05a9f5..1e36e462c6 100644 --- a/cranelift/codegen/meta/src/isa/s390x/mod.rs +++ b/cranelift/codegen/meta/src/isa/s390x/mod.rs @@ -1,5 +1,4 @@ use crate::cdsl::isa::TargetIsa; -use crate::cdsl::regs::IsaRegsBuilder; use crate::cdsl::settings::{SettingGroup, SettingGroupBuilder}; use crate::shared::Definitions as SharedDefinitions; @@ -43,7 +42,6 @@ fn define_settings(_shared: &SettingGroup) -> SettingGroup { pub(crate) fn define(shared_defs: &mut SharedDefinitions) -> TargetIsa { let settings = define_settings(&shared_defs.settings); - let regs = IsaRegsBuilder::new().build(); - TargetIsa::new("s390x", settings, regs) + TargetIsa::new("s390x", settings) } diff --git a/cranelift/codegen/meta/src/isa/x86/mod.rs b/cranelift/codegen/meta/src/isa/x86/mod.rs index e21bfe1485..b4c670fce7 100644 --- a/cranelift/codegen/meta/src/isa/x86/mod.rs +++ b/cranelift/codegen/meta/src/isa/x86/mod.rs @@ -1,5 +1,4 @@ use crate::cdsl::isa::TargetIsa; -use crate::cdsl::regs::IsaRegsBuilder; use crate::shared::Definitions as SharedDefinitions; @@ -8,5 +7,5 @@ pub(crate) mod settings; pub(crate) fn define(shared_defs: &mut SharedDefinitions) -> TargetIsa { let settings = settings::define(&shared_defs.settings); - TargetIsa::new("x86", settings, IsaRegsBuilder::new().build()) + TargetIsa::new("x86", settings) } diff --git a/cranelift/codegen/meta/src/lib.rs b/cranelift/codegen/meta/src/lib.rs index d8972702a3..77fcbc7bf9 100644 --- a/cranelift/codegen/meta/src/lib.rs +++ b/cranelift/codegen/meta/src/lib.rs @@ -8,7 +8,6 @@ pub mod error; pub mod isa; mod gen_inst; -mod gen_registers; mod gen_settings; mod gen_types; @@ -55,8 +54,6 @@ pub fn generate( )?; for isa in target_isas { - gen_registers::generate(&isa, &format!("registers-{}.rs", isa.name), &out_dir)?; - gen_settings::generate( &isa.settings, gen_settings::ParentGroup::Shared,