Share constants between codegen and the meta crate;
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
30
cranelift/codegen/shared/src/constants.rs
Normal file
30
cranelift/codegen/shared/src/constants.rs
Normal file
@@ -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;
|
||||
@@ -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");
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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::<RegClassMask>() * 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::<RegClassIndex>() * 8)),
|
||||
"need to change RegClassIndex's type to a wider type"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user