Optimize vconst for x86 when immediate contains all zeroes or ones
Instead of using MOVUPS to expensively load bits from memory, this change uses a predicate to optimize vconst without a memory access: - when the 128-bit immediate is all zeroes in all bits, use PXOR to zero out an XMM register - when the 128-bit immediate is all ones in all bits, use PCMPEQB to set an XMM register to all ones This leaves the constant data in the constant pool, which may increase code size (TODO)
This commit is contained in:
@@ -614,6 +614,12 @@ pub enum FormatPredicateKind {
|
||||
/// Is the immediate format field member equal to zero? (float64 version)
|
||||
IsZero64BitFloat,
|
||||
|
||||
/// Is the immediate format field member equal zero in all lanes?
|
||||
IsAllZeroes128Bit,
|
||||
|
||||
/// Does the immediate format field member have ones in all bits of all lanes?
|
||||
IsAllOnes128Bit,
|
||||
|
||||
/// Has the value list (in member_name) the size specified in parameter?
|
||||
LengthEquals(usize),
|
||||
|
||||
@@ -690,6 +696,14 @@ impl FormatPredicateNode {
|
||||
FormatPredicateKind::IsZero64BitFloat => {
|
||||
format!("predicates::is_zero_64_bit_float({})", self.member_name)
|
||||
}
|
||||
FormatPredicateKind::IsAllZeroes128Bit => format!(
|
||||
"predicates::is_all_zeroes_128_bit(func.dfg.constants.get({}))",
|
||||
self.member_name
|
||||
),
|
||||
FormatPredicateKind::IsAllOnes128Bit => format!(
|
||||
"predicates::is_all_ones_128_bit(func.dfg.constants.get({}))",
|
||||
self.member_name
|
||||
),
|
||||
FormatPredicateKind::LengthEquals(num) => format!(
|
||||
"predicates::has_length_of({}, {}, func)",
|
||||
self.member_name, num
|
||||
@@ -929,6 +943,28 @@ impl InstructionPredicate {
|
||||
))
|
||||
}
|
||||
|
||||
pub fn new_is_all_zeroes_128bit(
|
||||
format: &InstructionFormat,
|
||||
field_name: &'static str,
|
||||
) -> InstructionPredicateNode {
|
||||
InstructionPredicateNode::FormatPredicate(FormatPredicateNode::new(
|
||||
format,
|
||||
field_name,
|
||||
FormatPredicateKind::IsAllZeroes128Bit,
|
||||
))
|
||||
}
|
||||
|
||||
pub fn new_is_all_ones_128bit(
|
||||
format: &InstructionFormat,
|
||||
field_name: &'static str,
|
||||
) -> InstructionPredicateNode {
|
||||
InstructionPredicateNode::FormatPredicate(FormatPredicateNode::new(
|
||||
format,
|
||||
field_name,
|
||||
FormatPredicateKind::IsAllOnes128Bit,
|
||||
))
|
||||
}
|
||||
|
||||
pub fn new_length_equals(format: &InstructionFormat, size: usize) -> InstructionPredicateNode {
|
||||
assert!(
|
||||
format.has_value_list,
|
||||
|
||||
Reference in New Issue
Block a user