From f668869508b61ef190a6c9ecf2f798c57132c6a5 Mon Sep 17 00:00:00 2001 From: Benjamin Bouvier Date: Wed, 9 Oct 2019 17:38:29 +0200 Subject: [PATCH] Share constants between codegen and the meta crate; --- cranelift/codegen/meta/src/cdsl/regs.rs | 17 ++++++---- cranelift/codegen/meta/src/cdsl/types.rs | 21 ++---------- cranelift/codegen/shared/src/constants.rs | 30 +++++++++++++++++ cranelift/codegen/shared/src/lib.rs | 1 + cranelift/codegen/src/ir/types.rs | 19 ++++------- cranelift/codegen/src/isa/registers.rs | 39 +++++++++++++--------- cranelift/codegen/src/regalloc/pressure.rs | 7 ++-- 7 files changed, 79 insertions(+), 55 deletions(-) create mode 100644 cranelift/codegen/shared/src/constants.rs diff --git a/cranelift/codegen/meta/src/cdsl/regs.rs b/cranelift/codegen/meta/src/cdsl/regs.rs index 920b1f5426..d60835ab3f 100644 --- a/cranelift/codegen/meta/src/cdsl/regs.rs +++ b/cranelift/codegen/meta/src/cdsl/regs.rs @@ -1,3 +1,4 @@ +use cranelift_codegen_shared::constants; use cranelift_entity::{entity_impl, EntityRef, PrimaryMap}; #[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] @@ -364,19 +365,21 @@ impl IsaRegsBuilder { } } - // This limit should be coordinated with the `RegClassMask` and `RegClassIndex` types in - // isa/registers.rs of the non-meta code. - assert!(self.classes.len() <= 32, "Too many register classes"); + assert!( + self.classes.len() <= constants::MAX_NUM_REG_CLASSES, + "Too many register classes" + ); - // The maximum number of top-level register classes which have pressure tracking should be - // kept in sync with the MAX_TRACKED_TOPRCS constant in isa/registers.rs of the non-meta - // code. let num_toplevel = self .classes .values() .filter(|x| x.toprc == x.index && self.banks.get(x.bank).unwrap().pressure_tracking) .count(); - assert!(num_toplevel <= 4, "Too many top-level register classes"); + + assert!( + num_toplevel <= constants::MAX_TRACKED_TOP_RCS, + "Too many top-level register classes" + ); IsaRegs::new(self.banks, self.classes) } diff --git a/cranelift/codegen/meta/src/cdsl/types.rs b/cranelift/codegen/meta/src/cdsl/types.rs index 92b9ab3a2f..33ce0acfc1 100644 --- a/cranelift/codegen/meta/src/cdsl/types.rs +++ b/cranelift/codegen/meta/src/cdsl/types.rs @@ -1,24 +1,9 @@ //! Cranelift ValueType hierarchy -// Temporary disabled: Unused at the moment. -// use std::collections::HashMap; - use std::fmt; use crate::shared::types as shared_types; - -// Numbering scheme for value types: -// -// 0: Void -// 0x01-0x6f: Special types -// 0x70-0x7d: Lane types -// 0x7e-0x7f: Reference types -// 0x80-0xff: Vector types -// -// Vector types are encoded with the lane type in the low 4 bits and log2(lanes) -// in the high 4 bits, giving a range of 2-256 lanes. -static LANE_BASE: u8 = 0x70; -static REFERENCE_BASE: u8 = 0x7E; +use cranelift_codegen_shared::constants; // Rust name prefix used for the `rust_name` method. static _RUST_NAME_PREFIX: &'static str = "ir::types::"; @@ -208,7 +193,7 @@ impl LaneType { /// Find the unique number associated with this lane type. pub fn number(self) -> u8 { - LANE_BASE + constants::LANE_BASE + match self { LaneType::BoolType(shared_types::Bool::B1) => 0, LaneType::BoolType(shared_types::Bool::B8) => 1, @@ -579,7 +564,7 @@ impl ReferenceType { /// Find the unique number associated with this reference type. pub fn number(self) -> u8 { - REFERENCE_BASE + constants::REFERENCE_BASE + match self { ReferenceType(shared_types::Reference::R32) => 0, ReferenceType(shared_types::Reference::R64) => 1, diff --git a/cranelift/codegen/shared/src/constants.rs b/cranelift/codegen/shared/src/constants.rs new file mode 100644 index 0000000000..b3f1377856 --- /dev/null +++ b/cranelift/codegen/shared/src/constants.rs @@ -0,0 +1,30 @@ +//! This module contains constants that are shared between the codegen and the meta crate, so they +//! are kept in sync. + +// Numbering scheme for value types: +// +// 0: Void +// 0x01-0x6f: Special types +// 0x70-0x7d: Lane types +// 0x7e-0x7f: Reference types +// 0x80-0xff: Vector types +// +// Vector types are encoded with the lane type in the low 4 bits and log2(lanes) +// in the high 4 bits, giving a range of 2-256 lanes. + +/// Start of the lane types. +pub const LANE_BASE: u8 = 0x70; + +/// Base for reference types. +pub const REFERENCE_BASE: u8 = 0x7E; + +/// Start of the 2-lane vector types. +pub const VECTOR_BASE: u8 = 0x80; + +// Some constants about register classes and types. + +/// Guaranteed maximum number of top-level register classes with pressure tracking in any ISA. +pub const MAX_TRACKED_TOP_RCS: usize = 4; + +/// Guaranteed maximum number of register classes in any ISA. +pub const MAX_NUM_REG_CLASSES: usize = 32; diff --git a/cranelift/codegen/shared/src/lib.rs b/cranelift/codegen/shared/src/lib.rs index 478fb0526f..a2c5f3df33 100644 --- a/cranelift/codegen/shared/src/lib.rs +++ b/cranelift/codegen/shared/src/lib.rs @@ -22,6 +22,7 @@ pub mod condcodes; pub mod constant_hash; +pub mod constants; /// Version number of this crate. pub const VERSION: &str = env!("CARGO_PKG_VERSION"); diff --git a/cranelift/codegen/src/ir/types.rs b/cranelift/codegen/src/ir/types.rs index 4ada74b070..4bdec45268 100644 --- a/cranelift/codegen/src/ir/types.rs +++ b/cranelift/codegen/src/ir/types.rs @@ -2,6 +2,7 @@ use core::default::Default; use core::fmt::{self, Debug, Display, Formatter}; +use cranelift_codegen_shared::constants; use target_lexicon::{PointerWidth, Triple}; /// The type of an SSA value. @@ -25,12 +26,6 @@ pub struct Type(u8); /// Not a valid type. Can't be loaded or stored. Can't be part of a SIMD vector. pub const INVALID: Type = Type(0); -/// Start of the lane types. See also `meta/src/cdsl/types.rs`. -const LANE_BASE: u8 = 0x70; - -/// Start of the 2-lane vector types. -const VECTOR_BASE: u8 = LANE_BASE + 16; - // Include code generated by `cranelift-codegen/meta/gen_types.rs`. This file contains constant // definitions for all the scalar types as well as common vector types for 64, 128, 256, and // 512-bit SIMD vectors. @@ -41,10 +36,10 @@ impl Type { /// /// A lane type is the same as a SIMD vector type with one lane, so it returns itself. pub fn lane_type(self) -> Self { - if self.0 < VECTOR_BASE { + if self.0 < constants::VECTOR_BASE { self } else { - Self(LANE_BASE | (self.0 & 0x0f)) + Self(constants::LANE_BASE | (self.0 & 0x0f)) } } @@ -170,21 +165,21 @@ impl Type { /// Is this a special type? pub fn is_special(self) -> bool { - self.0 < LANE_BASE + self.0 < constants::LANE_BASE } /// Is this a lane type? /// /// This is a scalar type that can also appear as the lane type of a SIMD vector. pub fn is_lane(self) -> bool { - LANE_BASE <= self.0 && self.0 < VECTOR_BASE + constants::LANE_BASE <= self.0 && self.0 < constants::VECTOR_BASE } /// Is this a SIMD vector type? /// /// A vector type has 2 or more lanes. pub fn is_vector(self) -> bool { - self.0 >= VECTOR_BASE + self.0 >= constants::VECTOR_BASE } /// Is this a scalar boolean type? @@ -234,7 +229,7 @@ impl Type { /// /// A scalar type is the same as a SIMD vector type with one lane, so it returns 0. pub fn log2_lane_count(self) -> u8 { - self.0.saturating_sub(LANE_BASE) >> 4 + self.0.saturating_sub(constants::LANE_BASE) >> 4 } /// Get the number of lanes in this SIMD vector type. diff --git a/cranelift/codegen/src/isa/registers.rs b/cranelift/codegen/src/isa/registers.rs index f7fcdcac2e..d3544904e0 100644 --- a/cranelift/codegen/src/isa/registers.rs +++ b/cranelift/codegen/src/isa/registers.rs @@ -12,25 +12,16 @@ use core::fmt; /// The register allocator will enforce that each register unit only gets used for one thing. pub type RegUnit = u16; +/// A bit mask indexed by register classes. +/// +/// The size of this type is determined by the ISA with the most register classes. +pub type RegClassMask = u32; + /// A bit mask indexed by register units. /// /// The size of this type is determined by the target ISA that has the most register units defined. /// Currently that is arm32 which has 64+16 units. -/// -/// This type should be coordinated with meta/src/cdsl/regs.rs. -pub type RegUnitMask = [u32; 3]; - -/// A bit mask indexed by register classes. -/// -/// The size of this type is determined by the ISA with the most register classes. -/// -/// This type should be coordinated with meta/src/cdsl/regs.rs. -pub type RegClassMask = u32; - -/// Guaranteed maximum number of top-level register classes with pressure tracking in any ISA. -/// -/// This can be increased, but should be coordinated with meta/src/cdsl/regs.rs. -pub const MAX_TRACKED_TOPRCS: usize = 4; +pub type RegUnitMask = [RegClassMask; 3]; /// The register units in a target ISA are divided into disjoint register banks. Each bank covers a /// contiguous range of register units. @@ -338,3 +329,21 @@ impl<'a> fmt::Display for DisplayRegUnit<'a> { } } } + +#[test] +fn assert_sizes() { + use cranelift_codegen_shared::constants; + use std::mem::size_of; + + // In these tests, size_of returns number of bytes: we actually want the number of bits, so + // multiply these by 8. + assert!( + (size_of::() * 8) <= constants::MAX_NUM_REG_CLASSES, + "need to bump MAX_NUM_REG_CLASSES or change RegClassMask type" + ); + + assert!( + constants::MAX_NUM_REG_CLASSES < (1 << (size_of::() * 8)), + "need to change RegClassIndex's type to a wider type" + ); +} diff --git a/cranelift/codegen/src/regalloc/pressure.rs b/cranelift/codegen/src/regalloc/pressure.rs index c7fc1fff9a..73c7fbc1a3 100644 --- a/cranelift/codegen/src/regalloc/pressure.rs +++ b/cranelift/codegen/src/regalloc/pressure.rs @@ -36,11 +36,12 @@ // Remove once we're using the pressure tracker. #![allow(dead_code)] -use crate::isa::registers::{RegClass, RegClassMask, RegInfo, MAX_TRACKED_TOPRCS}; +use crate::isa::registers::{RegClass, RegClassMask, RegInfo}; use crate::regalloc::RegisterSet; use core::cmp::min; use core::fmt; use core::iter::ExactSizeIterator; +use cranelift_codegen_shared::constants::MAX_TRACKED_TOP_RCS; /// Information per top-level register class. /// @@ -76,7 +77,7 @@ pub struct Pressure { aliased: RegClassMask, // Current register counts per top-level register class. - toprc: [TopRC; MAX_TRACKED_TOPRCS], + toprc: [TopRC; MAX_TRACKED_TOP_RCS], } impl Pressure { @@ -105,7 +106,7 @@ impl Pressure { } else { // This bank has no pressure tracking, so its top-level register classes may exceed // `MAX_TRACKED_TOPRCS`. Fill in dummy entries. - for rc in &mut p.toprc[first..min(first + num, MAX_TRACKED_TOPRCS)] { + for rc in &mut p.toprc[first..min(first + num, MAX_TRACKED_TOP_RCS)] { // These aren't used if we don't set the `aliased` bit. rc.first_toprc = !0; rc.limit = !0;