Files
wasmtime/cranelift/peepmatic/src/automatize.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

38 lines
1.2 KiB
Rust

//! Compile a set of linear optimizations into an automaton.
use peepmatic_automata::{Automaton, Builder};
use peepmatic_runtime::linear;
use std::fmt::Debug;
use std::hash::Hash;
/// Construct an automaton from a set of linear optimizations.
pub fn automatize<TOperator>(
opts: &linear::Optimizations<TOperator>,
) -> Automaton<linear::MatchResult, linear::MatchOp, Box<[linear::Action<TOperator>]>>
where
TOperator: Copy + Debug + Eq + Hash,
{
debug_assert!(crate::linear_passes::is_sorted_lexicographically(opts));
let mut builder =
Builder::<linear::MatchResult, linear::MatchOp, Box<[linear::Action<TOperator>]>>::new();
for opt in &opts.optimizations {
let mut insertion = builder.insert();
for inc in &opt.increments {
// Ensure that this state's associated data is this increment's
// match operation.
if let Some(op) = insertion.get_state_data() {
assert_eq!(*op, inc.operation);
} else {
insertion.set_state_data(inc.operation);
}
insertion.next(inc.expected, inc.actions.clone().into_boxed_slice());
}
insertion.finish();
}
builder.finish()
}