cranelift: Add a conditional branch instruction with two targets (#5446)

Add a conditional branch instruction with two targets: brif. This instruction will eventually replace brz and brnz, as it encompasses the behavior of both.

This PR also changes the InstructionData layout for instruction formats that hold BlockCall values, taking the same approach we use for Value arguments. This allows branch_destination to return a slice to the BlockCall values held in the instruction, rather than requiring that we pattern match on InstructionData to fetch the then/else blocks.

Function generation for fuzzing has been updated to generate uses of brif, and I've run the cranelift-fuzzgen target locally for hours without triggering any new failures.
This commit is contained in:
Trevor Elliott
2023-01-24 14:37:16 -08:00
committed by GitHub
parent ec6922ff24
commit b58a197d33
35 changed files with 943 additions and 159 deletions

View File

@@ -38,6 +38,8 @@ pub(crate) struct InstructionFormat {
pub imm_fields: Vec<FormatField>,
pub num_block_operands: usize,
/// Index of the value input operand that is used to infer the controlling type variable. By
/// default, this is `0`, the first `value` operand. The index is relative to the values only,
/// ignoring immediate operands.
@@ -49,6 +51,7 @@ pub(crate) struct InstructionFormat {
pub(crate) struct FormatStructure {
pub num_value_operands: usize,
pub has_value_list: bool,
pub num_block_operands: usize,
/// Tuples of (Rust field name / Rust type) for each immediate field.
pub imm_field_names: Vec<(&'static str, &'static str)>,
}
@@ -62,8 +65,8 @@ impl fmt::Display for InstructionFormat {
.collect::<Vec<_>>()
.join(", ");
fmt.write_fmt(format_args!(
"{}(imms=({}), vals={})",
self.name, imm_args, self.num_value_operands
"{}(imms=({}), vals={}, blocks={})",
self.name, imm_args, self.num_value_operands, self.num_block_operands,
))?;
Ok(())
}
@@ -75,6 +78,7 @@ impl InstructionFormat {
FormatStructure {
num_value_operands: self.num_value_operands,
has_value_list: self.has_value_list,
num_block_operands: self.num_block_operands,
imm_field_names: self
.imm_fields
.iter()
@@ -92,6 +96,7 @@ impl InstructionFormatBuilder {
name,
num_value_operands: 0,
has_value_list: false,
num_block_operands: 0,
imm_fields: Vec::new(),
typevar_operand: None,
})
@@ -107,6 +112,11 @@ impl InstructionFormatBuilder {
self
}
pub fn block(mut self) -> Self {
self.0.num_block_operands += 1;
self
}
pub fn imm(mut self, operand_kind: &OperandKind) -> Self {
let field = FormatField {
kind: operand_kind.clone(),