Files
wasmtime/cranelift/peepmatic/crates/traits/src/typing.rs
Nick Fitzgerald ee5982fd16 peepmatic: Be generic over the operator type
This lets us avoid the cost of `cranelift_codegen::ir::Opcode` to
`peepmatic_runtime::Operator` conversion overhead, and paves the way for
allowing Peepmatic to support non-clif optimizations (e.g. vcode optimizations).

Rather than defining our own `peepmatic::Operator` type like we used to, now the
whole `peepmatic` crate is effectively generic over a `TOperator` type
parameter. For the Cranelift integration, we use `cranelift_codegen::ir::Opcode`
as the concrete type for our `TOperator` type parameter. For testing, we also
define a `TestOperator` type, so that we can test Peepmatic code without
building all of Cranelift, and we can keep them somewhat isolated from each
other.

The methods that `peepmatic::Operator` had are now translated into trait bounds
on the `TOperator` type. These traits need to be shared between all of
`peepmatic`, `peepmatic-runtime`, and `cranelift-codegen`'s Peepmatic
integration. Therefore, these new traits live in a new crate:
`peepmatic-traits`. This crate acts as a header file of sorts for shared
trait/type/macro definitions.

Additionally, the `peepmatic-runtime` crate no longer depends on the
`peepmatic-macro` procedural macro crate, which should lead to faster build
times for Cranelift when it is using pre-built peephole optimizers.
2020-07-17 16:16:49 -07:00

98 lines
3.3 KiB
Rust

/// A trait to represent a typing context.
///
/// This is used by the macro-generated operator methods that create the type
/// variables for their immediates, parameters, and results. This trait is
/// implemented by the concrete typing context in `peepmatic/src/verify.rs`.
pub trait TypingContext<'a> {
/// A source span.
type Span: Copy;
/// A type variable.
type TypeVariable;
/// Create a condition code type.
fn cc(&mut self, span: Self::Span) -> Self::TypeVariable;
/// Create a boolean type with a polymorphic bit width.
///
/// Each use of `bNN` by the same operator refers to the same type variable.
#[allow(non_snake_case)]
fn bNN(&mut self, span: Self::Span) -> Self::TypeVariable;
/// Create an integer type with a polymorphic bit width.
///
/// Each use of `iNN` by the same operator refers to the same type variable.
#[allow(non_snake_case)]
fn iNN(&mut self, span: Self::Span) -> Self::TypeVariable;
/// Create an integer type with a polymorphic bit width.
///
/// Each use of `iMM` by the same operator refers to the same type variable.
#[allow(non_snake_case)]
fn iMM(&mut self, span: Self::Span) -> Self::TypeVariable;
/// Create the CPU flags type variable.
fn cpu_flags(&mut self, span: Self::Span) -> Self::TypeVariable;
/// Create a boolean type of size one bit.
fn b1(&mut self, span: Self::Span) -> Self::TypeVariable;
/// Create the void type, used as the result of operators that branch away,
/// or do not return anything.
fn void(&mut self, span: Self::Span) -> Self::TypeVariable;
/// Create a type variable that may be either a boolean or an integer.
fn bool_or_int(&mut self, span: Self::Span) -> Self::TypeVariable;
/// Create a type variable that can be any type T.
///
/// Each use of `any_t` by the same operator refers to the same type
/// variable.
fn any_t(&mut self, span: Self::Span) -> Self::TypeVariable;
}
/// The typing rules for a `TOperator` type.
///
/// This trait describes the types of immediates, parameters, and results of an
/// operator type, as well as their arity.
pub trait TypingRules {
/// Get the result type of this operator.
fn result_type<'a, C>(&self, span: C::Span, typing_context: &mut C) -> C::TypeVariable
where
C: TypingContext<'a>;
/// Get the number of immediates this operator has.
fn immediates_arity(&self) -> u8;
/// Get the types of this operator's immediates.
fn immediate_types<'a, C>(
&self,
span: C::Span,
typing_context: &mut C,
types: &mut impl Extend<C::TypeVariable>,
) where
C: TypingContext<'a>;
/// Get the number of parameters this operator has.
fn parameters_arity(&self) -> u8;
/// Get the types of this operator's parameters.
fn parameter_types<'a, C>(
&self,
span: C::Span,
typing_context: &mut C,
types: &mut impl Extend<C::TypeVariable>,
) where
C: TypingContext<'a>;
/// Is this a bit width reducing instruction?
///
/// E.g. Cranelift's `ireduce` instruction.
fn is_reduce(&self) -> bool;
/// Is this a bit width extending instruction?
///
/// E.g. Cranelift's `uextend` and `sextend` instructions.
fn is_extend(&self) -> bool;
}