cranelift: Port most of simple_preopt.rs over to the peepmatic DSL
This ports all of the identity, no-op, simplification, and canonicalization related optimizations over from being hand-coded to the `peepmatic` DSL. This does not handle the branch-to-branch optimizations or most of the divide-by-constant optimizations.
This commit is contained in:
@@ -234,11 +234,7 @@ impl DataFlowGraph {
|
||||
|
||||
/// Get the type of a value.
|
||||
pub fn value_type(&self, v: Value) -> Type {
|
||||
match self.values[v] {
|
||||
ValueData::Inst { ty, .. }
|
||||
| ValueData::Param { ty, .. }
|
||||
| ValueData::Alias { ty, .. } => ty,
|
||||
}
|
||||
self.values[v].ty()
|
||||
}
|
||||
|
||||
/// Get the definition of a value.
|
||||
@@ -383,9 +379,14 @@ pub enum ValueDef {
|
||||
impl ValueDef {
|
||||
/// Unwrap the instruction where the value was defined, or panic.
|
||||
pub fn unwrap_inst(&self) -> Inst {
|
||||
self.inst().expect("Value is not an instruction result")
|
||||
}
|
||||
|
||||
/// Get the instruction where the value was defined, if any.
|
||||
pub fn inst(&self) -> Option<Inst> {
|
||||
match *self {
|
||||
Self::Result(inst, _) => inst,
|
||||
_ => panic!("Value is not an instruction result"),
|
||||
Self::Result(inst, _) => Some(inst),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -428,6 +429,16 @@ enum ValueData {
|
||||
Alias { ty: Type, original: Value },
|
||||
}
|
||||
|
||||
impl ValueData {
|
||||
fn ty(&self) -> Type {
|
||||
match *self {
|
||||
ValueData::Inst { ty, .. }
|
||||
| ValueData::Param { ty, .. }
|
||||
| ValueData::Alias { ty, .. } => ty,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Instructions.
|
||||
///
|
||||
impl DataFlowGraph {
|
||||
|
||||
@@ -308,6 +308,30 @@ impl Function {
|
||||
// function, assume it is not a leaf.
|
||||
self.dfg.signatures.is_empty()
|
||||
}
|
||||
|
||||
/// Replace the `dst` instruction's data with the `src` instruction's data
|
||||
/// and then remove `src`.
|
||||
///
|
||||
/// `src` and its result values should not be used at all, as any uses would
|
||||
/// be left dangling after calling this method.
|
||||
///
|
||||
/// `src` and `dst` must have the same number of resulting values, and
|
||||
/// `src`'s i^th value must have the same type as `dst`'s i^th value.
|
||||
pub fn transplant_inst(&mut self, dst: Inst, src: Inst) {
|
||||
debug_assert_eq!(
|
||||
self.dfg.inst_results(dst).len(),
|
||||
self.dfg.inst_results(src).len()
|
||||
);
|
||||
debug_assert!(self
|
||||
.dfg
|
||||
.inst_results(dst)
|
||||
.iter()
|
||||
.zip(self.dfg.inst_results(src))
|
||||
.all(|(a, b)| self.dfg.value_type(*a) == self.dfg.value_type(*b)));
|
||||
|
||||
self.dfg[dst] = self.dfg[src].clone();
|
||||
self.layout.remove_inst(src);
|
||||
}
|
||||
}
|
||||
|
||||
/// Additional annotations for function display.
|
||||
|
||||
@@ -11,9 +11,7 @@ use core::fmt::{self, Display, Formatter};
|
||||
use core::ops::{Deref, DerefMut};
|
||||
use core::str::FromStr;
|
||||
|
||||
use crate::ir;
|
||||
use crate::ir::types;
|
||||
use crate::ir::{Block, FuncRef, JumpTable, SigRef, Type, Value};
|
||||
use crate::ir::{self, trapcode::TrapCode, types, Block, FuncRef, JumpTable, SigRef, Type, Value};
|
||||
use crate::isa;
|
||||
|
||||
use crate::bitset::BitSet;
|
||||
@@ -257,6 +255,30 @@ impl InstructionData {
|
||||
}
|
||||
}
|
||||
|
||||
/// If this is a trapping instruction, get its trap code. Otherwise, return
|
||||
/// `None`.
|
||||
pub fn trap_code(&self) -> Option<TrapCode> {
|
||||
match *self {
|
||||
Self::CondTrap { code, .. }
|
||||
| Self::FloatCondTrap { code, .. }
|
||||
| Self::IntCondTrap { code, .. }
|
||||
| Self::Trap { code, .. } => Some(code),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// If this is a trapping instruction, get an exclusive reference to its
|
||||
/// trap code. Otherwise, return `None`.
|
||||
pub fn trap_code_mut(&mut self) -> Option<&mut TrapCode> {
|
||||
match self {
|
||||
Self::CondTrap { code, .. }
|
||||
| Self::FloatCondTrap { code, .. }
|
||||
| Self::IntCondTrap { code, .. }
|
||||
| Self::Trap { code, .. } => Some(code),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Return information about a call instruction.
|
||||
///
|
||||
/// Any instruction that can call another function reveals its call signature here.
|
||||
|
||||
Reference in New Issue
Block a user