[][src]Trait peepmatic_runtime::instruction_set::InstructionSet

pub unsafe trait InstructionSet<'a> {
    type Context;
    type Instruction: Copy + Debug + Eq;
    fn replace_instruction(
        &self,
        context: &mut Self::Context,
        old: Self::Instruction,
        new: Part<Self::Instruction>
    ) -> Self::Instruction;
fn get_part_at_path(
        &self,
        context: &mut Self::Context,
        root: Self::Instruction,
        path: Path
    ) -> Option<Part<Self::Instruction>>;
fn operator(
        &self,
        context: &mut Self::Context,
        instr: Self::Instruction
    ) -> Option<Operator>;
fn make_inst_1(
        &self,
        context: &mut Self::Context,
        root: Self::Instruction,
        operator: Operator,
        r#type: Type,
        a: Part<Self::Instruction>
    ) -> Self::Instruction;
fn make_inst_2(
        &self,
        context: &mut Self::Context,
        root: Self::Instruction,
        operator: Operator,
        r#type: Type,
        a: Part<Self::Instruction>,
        b: Part<Self::Instruction>
    ) -> Self::Instruction;
fn make_inst_3(
        &self,
        context: &mut Self::Context,
        root: Self::Instruction,
        operator: Operator,
        r#type: Type,
        a: Part<Self::Instruction>,
        b: Part<Self::Instruction>,
        c: Part<Self::Instruction>
    ) -> Self::Instruction;
fn instruction_to_constant(
        &self,
        context: &mut Self::Context,
        inst: Self::Instruction
    ) -> Option<Constant>;
fn instruction_result_bit_width(
        &self,
        context: &mut Self::Context,
        inst: Self::Instruction
    ) -> u8;
fn native_word_size_in_bits(&self, context: &mut Self::Context) -> u8; }

A trait for interfacing with actual instruction sequences.

This trait enables both:

  • peepmatic-runtime to be used by cranelift-codegen without a circular dependency from peepmatic-runtime to cranelift-codegen to get access to Cranelift's IR types, and

  • enables us to write local tests that exercise peephole optimizers on a simple, testing-only instruction set without pulling in all of Cranelift.

Finally, this should also make the task of adding support for Cranelift's new MachInst and vcode backend easier, since all that needs to be done is "just" implementing this trait. (And probably add/modify some peepmatic_runtime::operation::Operations as well).

Safety

See doc comment for instruction_result_bit_width.

Associated Types

type Context

Mutable context passed into all trait methods. Can be whatever you want!

In practice, this is a FuncCursor for cranelift-codegen's trait implementation.

type Instruction: Copy + Debug + Eq

An instruction (or identifier for an instruction).

Loading content...

Required methods

fn replace_instruction(
    &self,
    context: &mut Self::Context,
    old: Self::Instruction,
    new: Part<Self::Instruction>
) -> Self::Instruction

Replace the old instruction with new.

new is either a Part::Instruction or a constant Part::Boolean or Part::Integer. In the former case, it can directly replace old. In the latter case, implementations of this trait should transparently create an iconst or bconst instruction to wrap the given constant.

new will never be Part::ConditionCode.

fn get_part_at_path(
    &self,
    context: &mut Self::Context,
    root: Self::Instruction,
    path: Path
) -> Option<Part<Self::Instruction>>

Get the instruction, constant, or condition code at the given path.

If there is no such entity at the given path (e.g. we run into a function parameter and can't traverse the path any further) then None should be returned.

fn operator(
    &self,
    context: &mut Self::Context,
    instr: Self::Instruction
) -> Option<Operator>

Get the given instruction's operator.

If the instruction's opcode does not have an associated peepmatic_runtime::operator::Operator variant (i.e. that instruction isn't supported by peepmatic yet) then None should be returned.

fn make_inst_1(
    &self,
    context: &mut Self::Context,
    root: Self::Instruction,
    operator: Operator,
    r#type: Type,
    a: Part<Self::Instruction>
) -> Self::Instruction

Make a unary instruction.

If the type is not given, then it should be inferred.

fn make_inst_2(
    &self,
    context: &mut Self::Context,
    root: Self::Instruction,
    operator: Operator,
    r#type: Type,
    a: Part<Self::Instruction>,
    b: Part<Self::Instruction>
) -> Self::Instruction

Make a binary instruction.

Operands are given as immediates first and arguments following them. Condition codes are treated as immediates. So if we are creating an iadd_imm instruction, then a will be the constant integer immediate and b will be the instruction whose result is the dynamic argument.

fn make_inst_3(
    &self,
    context: &mut Self::Context,
    root: Self::Instruction,
    operator: Operator,
    r#type: Type,
    a: Part<Self::Instruction>,
    b: Part<Self::Instruction>,
    c: Part<Self::Instruction>
) -> Self::Instruction

Make a ternary instruction.

Operands are given as immediates first and arguments following them. Condition codes are treated as immediates. So if we are creating an icmp instruction, then a will be the condition code, and b and c will be instructions whose results are the dynamic arguments.

fn instruction_to_constant(
    &self,
    context: &mut Self::Context,
    inst: Self::Instruction
) -> Option<Constant>

Try to resolve the given instruction into a constant value.

If we can tell that the instruction returns a constant value, then return that constant value as either a Part::Boolean or Part::Integer. Otherwise, return None.

fn instruction_result_bit_width(
    &self,
    context: &mut Self::Context,
    inst: Self::Instruction
) -> u8

Get the bit width of the given instruction's result.

Safety

There is code that makes memory-safety assumptions that the result is always one of 1, 8, 16, 32, 64, or 128. Implementors must uphold this.

fn native_word_size_in_bits(&self, context: &mut Self::Context) -> u8

Get the size of a native word in bits.

Loading content...

Implementors

Loading content...