Sort type bits at compile time for Display

This commit is contained in:
Max Bernstein 2025-03-05 12:40:47 -05:00 committed by Takashi Kokubun
parent 8b2a4625cb
commit d9a51eb865
Notes: git 2025-04-18 13:48:25 +00:00
3 changed files with 67 additions and 57 deletions

View File

@ -14,7 +14,7 @@ class Type
end
def all_subtypes
subtypes + subtypes.flat_map { |subtype| subtype.all_subtypes }
subtypes.flat_map { |subtype| subtype.all_subtypes } + subtypes
end
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
num_bits = 0
bits = {"Bottom" => ["0u64"]}
numeric_bits = {"Bottom" => 0}
Set[top, *top.all_subtypes].sort_by(&:name).each {|type|
subtypes = type.subtypes
if subtypes.empty?
# Assign bits for leaves
bits[type.name] = ["1u64 << #{num_bits}"]
numeric_bits[type.name] = 1 << num_bits
num_bits += 1
else
# Assign bits for unions
bits[type.name] = subtypes.map(&:name).sort
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 =====
@ -123,7 +131,10 @@ bits.keys.sort.map {|type_name|
puts " pub const #{type_name}: u64 = #{subtypes};"
}
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 " ];"

100
zjit/src/hir_type.inc.rs generated
View File

@ -57,62 +57,62 @@ mod bits {
pub const TrueClassUser: u64 = 1u64 << 33;
pub const User: u64 = ArrayUser | FalseClassUser | FloatUser | HashUser | IntegerUser | NilClassUser | StringUser | SymbolUser | TrueClassUser;
pub const AllBitPatterns: [(&'static str, u64); 56] = [
("Array", Array),
("ArrayExact", ArrayExact),
("ArrayUser", ArrayUser),
("Bignum", Bignum),
("Bottom", Bottom),
("Top", Top),
("Object", Object),
("ObjectUser", ObjectUser),
("TrueClass", TrueClass),
("User", User),
("TrueClassUser", TrueClassUser),
("BuiltinExact", BuiltinExact),
("CBool", CBool),
("CDouble", CDouble),
("CInt", CInt),
("CInt16", CInt16),
("CInt32", CInt32),
("CInt64", CInt64),
("CInt8", CInt8),
("CNull", CNull),
("CPtr", CPtr),
("CSigned", CSigned),
("CUInt16", CUInt16),
("CUInt32", CUInt32),
("CUInt64", CUInt64),
("CUInt8", CUInt8),
("CUnsigned", CUnsigned),
("DynamicSymbol", DynamicSymbol),
("FalseClass", FalseClass),
("FalseClassExact", FalseClassExact),
("FalseClassUser", FalseClassUser),
("Fixnum", Fixnum),
("TrueClassExact", TrueClassExact),
("Symbol", Symbol),
("SymbolUser", SymbolUser),
("String", String),
("StringUser", StringUser),
("StringExact", StringExact),
("SymbolExact", SymbolExact),
("StaticSymbol", StaticSymbol),
("ObjectExact", ObjectExact),
("NilClass", NilClass),
("NilClassUser", NilClassUser),
("NilClassExact", NilClassExact),
("Integer", Integer),
("IntegerUser", IntegerUser),
("Float", Float),
("FloatExact", FloatExact),
("FloatUser", FloatUser),
("Flonum", Flonum),
("Hash", Hash),
("HashExact", HashExact),
("HashUser", HashUser),
("HeapFloat", HeapFloat),
("Integer", Integer),
("Hash", Hash),
("HashUser", HashUser),
("HashExact", HashExact),
("Flonum", Flonum),
("FloatUser", FloatUser),
("IntegerExact", IntegerExact),
("IntegerUser", IntegerUser),
("NilClass", NilClass),
("NilClassExact", NilClassExact),
("NilClassUser", NilClassUser),
("Object", Object),
("ObjectExact", ObjectExact),
("ObjectUser", ObjectUser),
("Fixnum", Fixnum),
("FalseClass", FalseClass),
("FalseClassUser", FalseClassUser),
("FalseClassExact", FalseClassExact),
("DynamicSymbol", DynamicSymbol),
("Primitive", Primitive),
("StaticSymbol", StaticSymbol),
("String", String),
("StringExact", StringExact),
("StringUser", StringUser),
("Symbol", Symbol),
("SymbolExact", SymbolExact),
("SymbolUser", SymbolUser),
("Top", Top),
("TrueClass", TrueClass),
("TrueClassExact", TrueClassExact),
("TrueClassUser", TrueClassUser),
("User", User),
("CInt", CInt),
("CUnsigned", CUnsigned),
("CUInt8", CUInt8),
("CUInt64", CUInt64),
("CUInt32", CUInt32),
("CUInt16", CUInt16),
("CPtr", CPtr),
("CNull", CNull),
("CSigned", CSigned),
("CInt8", CInt8),
("CInt64", CInt64),
("CInt32", CInt32),
("CInt16", CInt16),
("CDouble", CDouble),
("CBool", CBool),
("Bignum", Bignum),
("Array", Array),
("ArrayUser", ArrayUser),
("ArrayExact", ArrayExact),
("Bottom", Bottom),
];
pub const NumTypeBits: u64 = 34;
}

View File

@ -102,13 +102,12 @@ impl std::fmt::Display for Type {
return write_spec(f, *self);
}
}
let mut bit_patterns = Vec::from_iter(bits::AllBitPatterns);
bit_patterns.sort_by(|(_, left), (_, right)| left.partial_cmp(right).unwrap());
assert!(bits::AllBitPatterns.is_sorted_by(|(_, left), (_, right)| left > right));
let mut bits = self.bits;
let mut sep = "";
for (name, pattern) in bit_patterns {
for (name, pattern) in bits::AllBitPatterns {
if bits == 0 { break; }
if (bits & pattern) != 0 {
if (bits & pattern) == pattern {
write!(f, "{sep}{name}")?;
sep = "|";
bits &= !pattern;
@ -475,7 +474,7 @@ mod tests {
#[test]
fn display_multiple_bits() {
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");
}