Files
wasmtime/cranelift/codegen/meta/src/shared/entities.rs
Trevor Elliott b58a197d33 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.
2023-01-24 14:37:16 -08:00

117 lines
4.0 KiB
Rust

use crate::cdsl::operands::{OperandKind, OperandKindFields};
/// Small helper to initialize an OperandBuilder with the right kind, for a given name and doc.
fn new(format_field_name: &'static str, rust_type: &'static str, doc: &'static str) -> OperandKind {
OperandKind::new(
format_field_name,
rust_type,
OperandKindFields::EntityRef,
doc,
)
}
pub(crate) struct EntityRefs {
/// A reference to a basic block in the same function, with its arguments provided.
/// This is primarily used in control flow instructions.
pub(crate) block_call: OperandKind,
/// A reference to a basic block in the same function.
/// This is primarily used in control flow instructions.
pub(crate) label: OperandKind,
/// A reference to a basic block in the same function, with its arguments provided.
/// This is primarily used in control flow instructions.
pub(crate) block_then: OperandKind,
/// A reference to a basic block in the same function, with its arguments provided.
/// This is primarily used in control flow instructions.
pub(crate) block_else: OperandKind,
/// A reference to a stack slot declared in the function preamble.
pub(crate) stack_slot: OperandKind,
/// A reference to a dynamic_stack slot declared in the function preamble.
pub(crate) dynamic_stack_slot: OperandKind,
/// A reference to a global value.
pub(crate) global_value: OperandKind,
/// A reference to a function signature declared in the function preamble.
/// This is used to provide the call signature in a call_indirect instruction.
pub(crate) sig_ref: OperandKind,
/// A reference to an external function declared in the function preamble.
/// This is used to provide the callee and signature in a call instruction.
pub(crate) func_ref: OperandKind,
/// A reference to a jump table declared in the function preamble.
pub(crate) jump_table: OperandKind,
/// A reference to a table declared in the function preamble.
pub(crate) table: OperandKind,
/// A variable-sized list of value operands. Use for Block and function call arguments.
pub(crate) varargs: OperandKind,
}
impl EntityRefs {
pub fn new() -> Self {
Self {
block_call: new(
"destination",
"ir::BlockCall",
"a basic block in the same function, with its arguments provided.",
),
label: new(
"destination",
"ir::Block",
"a basic block in the same function.",
),
block_then: new(
"block_then",
"ir::BlockCall",
"a basic block in the same function, with its arguments provided.",
),
block_else: new(
"block_else",
"ir::BlockCall",
"a basic block in the same function, with its arguments provided.",
),
stack_slot: new("stack_slot", "ir::StackSlot", "A stack slot"),
dynamic_stack_slot: new(
"dynamic_stack_slot",
"ir::DynamicStackSlot",
"A dynamic stack slot",
),
global_value: new("global_value", "ir::GlobalValue", "A global value."),
sig_ref: new("sig_ref", "ir::SigRef", "A function signature."),
func_ref: new("func_ref", "ir::FuncRef", "An external function."),
jump_table: new("table", "ir::JumpTable", "A jump table."),
table: new("table", "ir::Table", "A table."),
varargs: OperandKind::new(
"",
"&[Value]",
OperandKindFields::VariableArgs,
r#"
A variable size list of `value` operands.
Use this to represent arguments passed to a function call, arguments
passed to a basic block, or a variable number of results
returned from an instruction.
"#,
),
}
}
}