Sort type bits at compile time for Display
This commit is contained in:
parent
8b2a4625cb
commit
d9a51eb865
Notes:
git
2025-04-18 13:48:25 +00:00
@ -14,7 +14,7 @@ class Type
|
|||||||
end
|
end
|
||||||
|
|
||||||
def all_subtypes
|
def all_subtypes
|
||||||
subtypes + subtypes.flat_map { |subtype| subtype.all_subtypes }
|
subtypes.flat_map { |subtype| subtype.all_subtypes } + subtypes
|
||||||
end
|
end
|
||||||
|
|
||||||
def subtype name
|
def subtype name
|
||||||
@ -102,17 +102,25 @@ unsigned = primitive_int.subtype "CUnsigned"
|
|||||||
# Assign individual bits to type leaves and union bit patterns to nodes with subtypes
|
# Assign individual bits to type leaves and union bit patterns to nodes with subtypes
|
||||||
num_bits = 0
|
num_bits = 0
|
||||||
bits = {"Bottom" => ["0u64"]}
|
bits = {"Bottom" => ["0u64"]}
|
||||||
|
numeric_bits = {"Bottom" => 0}
|
||||||
Set[top, *top.all_subtypes].sort_by(&:name).each {|type|
|
Set[top, *top.all_subtypes].sort_by(&:name).each {|type|
|
||||||
subtypes = type.subtypes
|
subtypes = type.subtypes
|
||||||
if subtypes.empty?
|
if subtypes.empty?
|
||||||
# Assign bits for leaves
|
# Assign bits for leaves
|
||||||
bits[type.name] = ["1u64 << #{num_bits}"]
|
bits[type.name] = ["1u64 << #{num_bits}"]
|
||||||
|
numeric_bits[type.name] = 1 << num_bits
|
||||||
num_bits += 1
|
num_bits += 1
|
||||||
else
|
else
|
||||||
# Assign bits for unions
|
# Assign bits for unions
|
||||||
bits[type.name] = subtypes.map(&:name).sort
|
bits[type.name] = subtypes.map(&:name).sort
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
[*top.all_subtypes, top].each {|type|
|
||||||
|
subtypes = type.subtypes
|
||||||
|
unless subtypes.empty?
|
||||||
|
numeric_bits[type.name] = subtypes.map {|ty| numeric_bits[ty.name]}.reduce(&:|)
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
# ===== Finished generating the DAG; write Rust code =====
|
# ===== Finished generating the DAG; write Rust code =====
|
||||||
|
|
||||||
@ -123,7 +131,10 @@ bits.keys.sort.map {|type_name|
|
|||||||
puts " pub const #{type_name}: u64 = #{subtypes};"
|
puts " pub const #{type_name}: u64 = #{subtypes};"
|
||||||
}
|
}
|
||||||
puts " pub const AllBitPatterns: [(&'static str, u64); #{bits.size}] = ["
|
puts " pub const AllBitPatterns: [(&'static str, u64); #{bits.size}] = ["
|
||||||
bits.keys.sort.map {|type_name|
|
# Sort the bit patterns by decreasing value so that we can print the densest
|
||||||
|
# possible to-string representation of a Type. For example, CSigned instead of
|
||||||
|
# CInt8|CInt16|...
|
||||||
|
numeric_bits.sort_by {|key, val| -val}.each {|type_name, _|
|
||||||
puts " (\"#{type_name}\", #{type_name}),"
|
puts " (\"#{type_name}\", #{type_name}),"
|
||||||
}
|
}
|
||||||
puts " ];"
|
puts " ];"
|
||||||
|
100
zjit/src/hir_type.inc.rs
generated
100
zjit/src/hir_type.inc.rs
generated
@ -57,62 +57,62 @@ mod bits {
|
|||||||
pub const TrueClassUser: u64 = 1u64 << 33;
|
pub const TrueClassUser: u64 = 1u64 << 33;
|
||||||
pub const User: u64 = ArrayUser | FalseClassUser | FloatUser | HashUser | IntegerUser | NilClassUser | StringUser | SymbolUser | TrueClassUser;
|
pub const User: u64 = ArrayUser | FalseClassUser | FloatUser | HashUser | IntegerUser | NilClassUser | StringUser | SymbolUser | TrueClassUser;
|
||||||
pub const AllBitPatterns: [(&'static str, u64); 56] = [
|
pub const AllBitPatterns: [(&'static str, u64); 56] = [
|
||||||
("Array", Array),
|
("Top", Top),
|
||||||
("ArrayExact", ArrayExact),
|
("Object", Object),
|
||||||
("ArrayUser", ArrayUser),
|
("ObjectUser", ObjectUser),
|
||||||
("Bignum", Bignum),
|
("TrueClass", TrueClass),
|
||||||
("Bottom", Bottom),
|
("User", User),
|
||||||
|
("TrueClassUser", TrueClassUser),
|
||||||
("BuiltinExact", BuiltinExact),
|
("BuiltinExact", BuiltinExact),
|
||||||
("CBool", CBool),
|
("TrueClassExact", TrueClassExact),
|
||||||
("CDouble", CDouble),
|
("Symbol", Symbol),
|
||||||
("CInt", CInt),
|
("SymbolUser", SymbolUser),
|
||||||
("CInt16", CInt16),
|
("String", String),
|
||||||
("CInt32", CInt32),
|
("StringUser", StringUser),
|
||||||
("CInt64", CInt64),
|
("StringExact", StringExact),
|
||||||
("CInt8", CInt8),
|
("SymbolExact", SymbolExact),
|
||||||
("CNull", CNull),
|
("StaticSymbol", StaticSymbol),
|
||||||
("CPtr", CPtr),
|
("ObjectExact", ObjectExact),
|
||||||
("CSigned", CSigned),
|
("NilClass", NilClass),
|
||||||
("CUInt16", CUInt16),
|
("NilClassUser", NilClassUser),
|
||||||
("CUInt32", CUInt32),
|
("NilClassExact", NilClassExact),
|
||||||
("CUInt64", CUInt64),
|
("Integer", Integer),
|
||||||
("CUInt8", CUInt8),
|
("IntegerUser", IntegerUser),
|
||||||
("CUnsigned", CUnsigned),
|
|
||||||
("DynamicSymbol", DynamicSymbol),
|
|
||||||
("FalseClass", FalseClass),
|
|
||||||
("FalseClassExact", FalseClassExact),
|
|
||||||
("FalseClassUser", FalseClassUser),
|
|
||||||
("Fixnum", Fixnum),
|
|
||||||
("Float", Float),
|
("Float", Float),
|
||||||
("FloatExact", FloatExact),
|
("FloatExact", FloatExact),
|
||||||
("FloatUser", FloatUser),
|
|
||||||
("Flonum", Flonum),
|
|
||||||
("Hash", Hash),
|
|
||||||
("HashExact", HashExact),
|
|
||||||
("HashUser", HashUser),
|
|
||||||
("HeapFloat", HeapFloat),
|
("HeapFloat", HeapFloat),
|
||||||
("Integer", Integer),
|
("Hash", Hash),
|
||||||
|
("HashUser", HashUser),
|
||||||
|
("HashExact", HashExact),
|
||||||
|
("Flonum", Flonum),
|
||||||
|
("FloatUser", FloatUser),
|
||||||
("IntegerExact", IntegerExact),
|
("IntegerExact", IntegerExact),
|
||||||
("IntegerUser", IntegerUser),
|
("Fixnum", Fixnum),
|
||||||
("NilClass", NilClass),
|
("FalseClass", FalseClass),
|
||||||
("NilClassExact", NilClassExact),
|
("FalseClassUser", FalseClassUser),
|
||||||
("NilClassUser", NilClassUser),
|
("FalseClassExact", FalseClassExact),
|
||||||
("Object", Object),
|
("DynamicSymbol", DynamicSymbol),
|
||||||
("ObjectExact", ObjectExact),
|
|
||||||
("ObjectUser", ObjectUser),
|
|
||||||
("Primitive", Primitive),
|
("Primitive", Primitive),
|
||||||
("StaticSymbol", StaticSymbol),
|
("CInt", CInt),
|
||||||
("String", String),
|
("CUnsigned", CUnsigned),
|
||||||
("StringExact", StringExact),
|
("CUInt8", CUInt8),
|
||||||
("StringUser", StringUser),
|
("CUInt64", CUInt64),
|
||||||
("Symbol", Symbol),
|
("CUInt32", CUInt32),
|
||||||
("SymbolExact", SymbolExact),
|
("CUInt16", CUInt16),
|
||||||
("SymbolUser", SymbolUser),
|
("CPtr", CPtr),
|
||||||
("Top", Top),
|
("CNull", CNull),
|
||||||
("TrueClass", TrueClass),
|
("CSigned", CSigned),
|
||||||
("TrueClassExact", TrueClassExact),
|
("CInt8", CInt8),
|
||||||
("TrueClassUser", TrueClassUser),
|
("CInt64", CInt64),
|
||||||
("User", User),
|
("CInt32", CInt32),
|
||||||
|
("CInt16", CInt16),
|
||||||
|
("CDouble", CDouble),
|
||||||
|
("CBool", CBool),
|
||||||
|
("Bignum", Bignum),
|
||||||
|
("Array", Array),
|
||||||
|
("ArrayUser", ArrayUser),
|
||||||
|
("ArrayExact", ArrayExact),
|
||||||
|
("Bottom", Bottom),
|
||||||
];
|
];
|
||||||
pub const NumTypeBits: u64 = 34;
|
pub const NumTypeBits: u64 = 34;
|
||||||
}
|
}
|
||||||
|
@ -102,13 +102,12 @@ impl std::fmt::Display for Type {
|
|||||||
return write_spec(f, *self);
|
return write_spec(f, *self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let mut bit_patterns = Vec::from_iter(bits::AllBitPatterns);
|
assert!(bits::AllBitPatterns.is_sorted_by(|(_, left), (_, right)| left > right));
|
||||||
bit_patterns.sort_by(|(_, left), (_, right)| left.partial_cmp(right).unwrap());
|
|
||||||
let mut bits = self.bits;
|
let mut bits = self.bits;
|
||||||
let mut sep = "";
|
let mut sep = "";
|
||||||
for (name, pattern) in bit_patterns {
|
for (name, pattern) in bits::AllBitPatterns {
|
||||||
if bits == 0 { break; }
|
if bits == 0 { break; }
|
||||||
if (bits & pattern) != 0 {
|
if (bits & pattern) == pattern {
|
||||||
write!(f, "{sep}{name}")?;
|
write!(f, "{sep}{name}")?;
|
||||||
sep = "|";
|
sep = "|";
|
||||||
bits &= !pattern;
|
bits &= !pattern;
|
||||||
@ -475,7 +474,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn display_multiple_bits() {
|
fn display_multiple_bits() {
|
||||||
assert_eq!(format!("{}", types::CSigned), "CSigned");
|
assert_eq!(format!("{}", types::CSigned), "CSigned");
|
||||||
assert_eq!(format!("{}", types::CUInt8.union(types::CInt32)), "CInt32|CUInt8");
|
assert_eq!(format!("{}", types::CUInt8.union(types::CInt32)), "CUInt8|CInt32");
|
||||||
assert_eq!(format!("{}", types::HashExact.union(types::HashUser)), "Hash");
|
assert_eq!(format!("{}", types::HashExact.union(types::HashUser)), "Hash");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user