diff --git a/cranelift/codegen/src/peepmatic.rs b/cranelift/codegen/src/peepmatic.rs index ba9aeb38d5..1ea2031bfa 100644 --- a/cranelift/codegen/src/peepmatic.rs +++ b/cranelift/codegen/src/peepmatic.rs @@ -196,7 +196,7 @@ fn const_to_value<'a>(builder: impl InstBuilder<'a>, c: Constant, root: Inst) -> Constant::Int(x, width) => { let width = bit_width(builder.data_flow_graph(), width, root); let ty = match width { - 1 | 8 => types::I8, + 8 => types::I8, 16 => types::I16, 32 => types::I32, 64 => types::I64, @@ -407,7 +407,7 @@ fn get_argument(dfg: &DataFlowGraph, inst: Inst, i: usize) -> Option { fn peepmatic_ty_to_ir_ty(ty: Type, dfg: &DataFlowGraph, root: Inst) -> types::Type { match (ty.kind, bit_width(dfg, ty.bit_width, root)) { - (Kind::Int, 1) | (Kind::Int, 8) => types::I8, + (Kind::Int, 8) => types::I8, (Kind::Int, 16) => types::I16, (Kind::Int, 32) => types::I32, (Kind::Int, 64) => types::I64, diff --git a/cranelift/peepmatic/crates/runtime/src/linear.rs b/cranelift/peepmatic/crates/runtime/src/linear.rs index a51159f708..f156311740 100644 --- a/cranelift/peepmatic/crates/runtime/src/linear.rs +++ b/cranelift/peepmatic/crates/runtime/src/linear.rs @@ -53,6 +53,9 @@ pub fn bool_to_match_result(b: bool) -> MatchResult { unsafe { Ok(NonZeroU32::new_unchecked(b + 1)) } } +/// A partial match of an optimization's LHS and partial construction of its +/// RHS. +/// /// An increment is a matching operation, the expected result from that /// operation to continue to the next increment, and the actions to take to /// build up the LHS scope and RHS instructions given that we got the expected @@ -156,17 +159,18 @@ pub struct LhsId(pub u16); pub struct RhsId(pub u16); /// An action to perform when transitioning between states in the automata. +/// +/// When evaluating actions, the `i^th` action implicitly defines the +/// `RhsId(i)`. #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] pub enum Action { - /// Implicitly define the n^th built up RHS instruction as something from - /// the left-hand side. + /// Reuse something from the left-hand side. GetLhs { /// The path to the instruction or value. path: PathId, }, - /// Implicitly define the n^th RHS instruction as the result of the - /// compile-time evaluation off this unquote operation. + /// Perform compile-time evaluation. UnaryUnquote { /// The unquote operator. operator: UnquoteOperator, @@ -174,8 +178,7 @@ pub enum Action { operand: RhsId, }, - /// Implicitly define the n^th RHS instruction as the result of the - /// compile-time evaluation off this unquote operation. + /// Perform compile-time evaluation. BinaryUnquote { /// The unquote operator. operator: UnquoteOperator, @@ -183,7 +186,7 @@ pub enum Action { operands: [RhsId; 2], }, - /// Implicitly define the n^th RHS as an integer constant. + /// Create an integer constant. MakeIntegerConst { /// The constant integer value. value: IntegerId, @@ -191,7 +194,7 @@ pub enum Action { bit_width: BitWidth, }, - /// Implicitly define the n^th RHS as a boolean constant. + /// Create a boolean constant. MakeBooleanConst { /// The constant boolean value. value: bool, @@ -199,14 +202,13 @@ pub enum Action { bit_width: BitWidth, }, - /// Implicitly defint the n^th RHS as a condition code. + /// Create a condition code. MakeConditionCode { /// The condition code. cc: ConditionCode, }, - /// Implicitly define the n^th RHS instruction by making a unary - /// instruction. + /// Make a unary instruction. MakeUnaryInst { /// The operand for this instruction. operand: RhsId, @@ -216,8 +218,7 @@ pub enum Action { operator: Operator, }, - /// Implicitly define the n^th RHS instruction by making a binary - /// instruction. + /// Make a binary instruction. MakeBinaryInst { /// The opcode for this instruction. operator: Operator, @@ -227,8 +228,7 @@ pub enum Action { operands: [RhsId; 2], }, - /// Implicitly define the n^th RHS instruction by making a ternary - /// instruction. + /// Make a ternary instruction. MakeTernaryInst { /// The opcode for this instruction. operator: Operator, diff --git a/cranelift/peepmatic/crates/runtime/src/paths.rs b/cranelift/peepmatic/crates/runtime/src/paths.rs index d826ba76bb..f824f19a74 100644 --- a/cranelift/peepmatic/crates/runtime/src/paths.rs +++ b/cranelift/peepmatic/crates/runtime/src/paths.rs @@ -54,17 +54,17 @@ pub struct PathId(u16); /// path mapping. #[derive(Debug, Default)] pub struct PathInterner { - // A map from a path (whose owned data is inside `arena`) to the canonical - // `PathId` we assigned it when interning it. + /// A map from a path (whose owned data is inside `arena`) to the canonical + /// `PathId` we assigned it when interning it. map: HashMap, - // A map from a `PathId` index to an unsafe, self-borrowed path pointing - // into `arena`. It is safe to given these out as safe `Path`s, as long as - // the lifetime is not longer than this `PathInterner`'s lifetime. + /// A map from a `PathId` index to an unsafe, self-borrowed path pointing + /// into `arena`. It is safe to given these out as safe `Path`s, as long as + /// the lifetime is not longer than this `PathInterner`'s lifetime. paths: Vec, - // Bump allocation arena for path data. The bump arena ensures that these - // allocations never move, and are therefore safe for self-references. + /// Bump allocation arena for path data. The bump arena ensures that these + /// allocations never move, and are therefore safe for self-references. arena: bumpalo::Bump, } diff --git a/cranelift/peepmatic/src/linearize.rs b/cranelift/peepmatic/src/linearize.rs index eb03853fa2..9f7c1fe602 100644 --- a/cranelift/peepmatic/src/linearize.rs +++ b/cranelift/peepmatic/src/linearize.rs @@ -599,13 +599,17 @@ mod tests { let mut i = |i: u64| integers.intern(i); #[allow(unused_variables)] - let expected = $make_expected(&mut p, &mut i); + let make_expected: fn( + &mut dyn FnMut(&[u8]) -> PathId, + &mut dyn FnMut(u64) -> IntegerId, + ) -> Vec = $make_expected; + let expected = make_expected(&mut p, &mut i); dbg!(&expected); let actual = linearize_optimization(&mut paths, &mut integers, &opts.optimizations[0]); - dbg!(&actual); + dbg!(&actual.increments); - assert_eq!(expected, actual); + assert_eq!(expected, actual.increments); } }; } @@ -617,234 +621,192 @@ mod tests { (is-power-of-two $C)) (ishl $x $C)) ", - |p: &mut dyn FnMut(&[u8]) -> PathId, i: &mut dyn FnMut(u64) -> IntegerId| { - linear::Optimization { - increments: vec![ - linear::Increment { - operation: Opcode { path: p(&[0]) }, - expected: Ok(NonZeroU32::new(Operator::Imul as _).unwrap()), - actions: vec![ - GetLhs { path: p(&[0, 0]) }, - GetLhs { path: p(&[0, 1]) }, - MakeBinaryInst { - operator: Operator::Ishl, - r#type: Type { - kind: Kind::Int, - bit_width: BitWidth::Polymorphic, - }, - operands: [linear::RhsId(0), linear::RhsId(1)], - }, - ], - }, - linear::Increment { - operation: Nop, - expected: Err(Else), - actions: vec![], - }, - linear::Increment { - operation: IsConst { path: p(&[0, 1]) }, - expected: bool_to_match_result(true), - actions: vec![], - }, - linear::Increment { - operation: IsPowerOfTwo { path: p(&[0, 1]) }, - expected: bool_to_match_result(true), - actions: vec![], + |p, i| vec![ + linear::Increment { + operation: Opcode { path: p(&[0]) }, + expected: Ok(NonZeroU32::new(Operator::Imul as _).unwrap()), + actions: vec![ + GetLhs { path: p(&[0, 0]) }, + GetLhs { path: p(&[0, 1]) }, + MakeBinaryInst { + operator: Operator::Ishl, + r#type: Type { + kind: Kind::Int, + bit_width: BitWidth::Polymorphic, + }, + operands: [linear::RhsId(0), linear::RhsId(1)], }, ], - } - }, + }, + linear::Increment { + operation: Nop, + expected: Err(Else), + actions: vec![], + }, + linear::Increment { + operation: IsConst { path: p(&[0, 1]) }, + expected: bool_to_match_result(true), + actions: vec![], + }, + linear::Increment { + operation: IsPowerOfTwo { path: p(&[0, 1]) }, + expected: bool_to_match_result(true), + actions: vec![], + }, + ], ); - linearizes_to!( - variable_pattern_id_optimization, - "(=> $x $x)", - |p: &mut dyn FnMut(&[u8]) -> PathId, i: &mut dyn FnMut(u64) -> IntegerId| { - linear::Optimization { - increments: vec![linear::Increment { - operation: Nop, - expected: Err(Else), - actions: vec![GetLhs { path: p(&[0]) }], - }], - } - }, - ); + linearizes_to!(variable_pattern_id_optimization, "(=> $x $x)", |p, i| vec![ + linear::Increment { + operation: Nop, + expected: Err(Else), + actions: vec![GetLhs { path: p(&[0]) }], + } + ]); - linearizes_to!( - constant_pattern_id_optimization, - "(=> $C $C)", - |p: &mut dyn FnMut(&[u8]) -> PathId, i: &mut dyn FnMut(u64) -> IntegerId| { - linear::Optimization { - increments: vec![linear::Increment { - operation: IsConst { path: p(&[0]) }, - expected: bool_to_match_result(true), - actions: vec![GetLhs { path: p(&[0]) }], - }], - } - }, - ); + linearizes_to!(constant_pattern_id_optimization, "(=> $C $C)", |p, i| vec![ + linear::Increment { + operation: IsConst { path: p(&[0]) }, + expected: bool_to_match_result(true), + actions: vec![GetLhs { path: p(&[0]) }], + } + ]); linearizes_to!( boolean_literal_id_optimization, "(=> true true)", - |p: &mut dyn FnMut(&[u8]) -> PathId, i: &mut dyn FnMut(u64) -> IntegerId| { - linear::Optimization { - increments: vec![linear::Increment { - operation: BooleanValue { path: p(&[0]) }, - expected: bool_to_match_result(true), - actions: vec![MakeBooleanConst { - value: true, - bit_width: BitWidth::Polymorphic, - }], - }], - } - }, + |p, i| vec![linear::Increment { + operation: BooleanValue { path: p(&[0]) }, + expected: bool_to_match_result(true), + actions: vec![MakeBooleanConst { + value: true, + bit_width: BitWidth::Polymorphic, + }], + }] ); - linearizes_to!( - number_literal_id_optimization, - "(=> 5 5)", - |p: &mut dyn FnMut(&[u8]) -> PathId, i: &mut dyn FnMut(u64) -> IntegerId| { - linear::Optimization { - increments: vec![linear::Increment { - operation: IntegerValue { path: p(&[0]) }, - expected: Ok(i(5).into()), - actions: vec![MakeIntegerConst { - value: i(5), - bit_width: BitWidth::Polymorphic, - }], - }], - } - }, - ); + linearizes_to!(number_literal_id_optimization, "(=> 5 5)", |p, i| vec![ + linear::Increment { + operation: IntegerValue { path: p(&[0]) }, + expected: Ok(i(5).into()), + actions: vec![MakeIntegerConst { + value: i(5), + bit_width: BitWidth::Polymorphic, + }], + } + ]); linearizes_to!( operation_id_optimization, "(=> (iconst $C) (iconst $C))", - |p: &mut dyn FnMut(&[u8]) -> PathId, i: &mut dyn FnMut(u64) -> IntegerId| { - linear::Optimization { - increments: vec![ - linear::Increment { - operation: Opcode { path: p(&[0]) }, - expected: Ok(NonZeroU32::new(Operator::Iconst as _).unwrap()), - actions: vec![ - GetLhs { path: p(&[0, 0]) }, - MakeUnaryInst { - operator: Operator::Iconst, - r#type: Type { - kind: Kind::Int, - bit_width: BitWidth::Polymorphic, - }, - operand: linear::RhsId(0), - }, - ], - }, - linear::Increment { - operation: IsConst { path: p(&[0, 0]) }, - expected: bool_to_match_result(true), - actions: vec![], + |p, i| vec![ + linear::Increment { + operation: Opcode { path: p(&[0]) }, + expected: Ok(NonZeroU32::new(Operator::Iconst as _).unwrap()), + actions: vec![ + GetLhs { path: p(&[0, 0]) }, + MakeUnaryInst { + operator: Operator::Iconst, + r#type: Type { + kind: Kind::Int, + bit_width: BitWidth::Polymorphic, + }, + operand: linear::RhsId(0), }, ], - } - }, + }, + linear::Increment { + operation: IsConst { path: p(&[0, 0]) }, + expected: bool_to_match_result(true), + actions: vec![], + }, + ] ); linearizes_to!( redundant_bor, "(=> (bor $x (bor $x $y)) (bor $x $y))", - |p: &mut dyn FnMut(&[u8]) -> PathId, i: &mut dyn FnMut(u64) -> IntegerId| { - linear::Optimization { - increments: vec![ - linear::Increment { - operation: Opcode { path: p(&[0]) }, - expected: Ok(NonZeroU32::new(Operator::Bor as _).unwrap()), - actions: vec![ - GetLhs { path: p(&[0, 0]) }, - GetLhs { - path: p(&[0, 1, 1]), - }, - MakeBinaryInst { - operator: Operator::Bor, - r#type: Type { - kind: Kind::Int, - bit_width: BitWidth::Polymorphic, - }, - operands: [linear::RhsId(0), linear::RhsId(1)], - }, - ], + |p, i| vec![ + linear::Increment { + operation: Opcode { path: p(&[0]) }, + expected: Ok(NonZeroU32::new(Operator::Bor as _).unwrap()), + actions: vec![ + GetLhs { path: p(&[0, 0]) }, + GetLhs { + path: p(&[0, 1, 1]), }, - linear::Increment { - operation: Nop, - expected: Err(Else), - actions: vec![], - }, - linear::Increment { - operation: Opcode { path: p(&[0, 1]) }, - expected: Ok(NonZeroU32::new(Operator::Bor as _).unwrap()), - actions: vec![], - }, - linear::Increment { - operation: Eq { - path_a: p(&[0, 1, 0]), - path_b: p(&[0, 0]), + MakeBinaryInst { + operator: Operator::Bor, + r#type: Type { + kind: Kind::Int, + bit_width: BitWidth::Polymorphic, }, - expected: bool_to_match_result(true), - actions: vec![], - }, - linear::Increment { - operation: Nop, - expected: Err(Else), - actions: vec![], + operands: [linear::RhsId(0), linear::RhsId(1)], }, ], - } - }, + }, + linear::Increment { + operation: Nop, + expected: Err(Else), + actions: vec![], + }, + linear::Increment { + operation: Opcode { path: p(&[0, 1]) }, + expected: Ok(NonZeroU32::new(Operator::Bor as _).unwrap()), + actions: vec![], + }, + linear::Increment { + operation: Eq { + path_a: p(&[0, 1, 0]), + path_b: p(&[0, 0]), + }, + expected: bool_to_match_result(true), + actions: vec![], + }, + linear::Increment { + operation: Nop, + expected: Err(Else), + actions: vec![], + }, + ] ); linearizes_to!( large_integers, // u64::MAX "(=> 18446744073709551615 0)", - |p: &mut dyn FnMut(&[u8]) -> PathId, i: &mut dyn FnMut(u64) -> IntegerId| { - linear::Optimization { - increments: vec![linear::Increment { - operation: IntegerValue { path: p(&[0]) }, - expected: Ok(i(std::u64::MAX).into()), - actions: vec![MakeIntegerConst { - value: i(0), - bit_width: BitWidth::Polymorphic, - }], - }], - } - } + |p, i| vec![linear::Increment { + operation: IntegerValue { path: p(&[0]) }, + expected: Ok(i(std::u64::MAX).into()), + actions: vec![MakeIntegerConst { + value: i(0), + bit_width: BitWidth::Polymorphic, + }], + }] ); linearizes_to!( ireduce_with_type_ascription, "(=> (ireduce{i32} $x) 0)", - |p: &mut dyn FnMut(&[u8]) -> PathId, i: &mut dyn FnMut(u64) -> IntegerId| { - linear::Optimization { - increments: vec![ - linear::Increment { - operation: Opcode { path: p(&[0]) }, - expected: Ok(NonZeroU32::new(Operator::Ireduce as _).unwrap()), - actions: vec![MakeIntegerConst { - value: i(0), - bit_width: BitWidth::ThirtyTwo, - }], - }, - linear::Increment { - operation: linear::MatchOp::BitWidth { path: p(&[0]) }, - expected: Ok(NonZeroU32::new(32).unwrap()), - actions: vec![], - }, - linear::Increment { - operation: Nop, - expected: Err(Else), - actions: vec![], - }, - ], - } - } + |p, i| vec![ + linear::Increment { + operation: Opcode { path: p(&[0]) }, + expected: Ok(NonZeroU32::new(Operator::Ireduce as _).unwrap()), + actions: vec![MakeIntegerConst { + value: i(0), + bit_width: BitWidth::ThirtyTwo, + }], + }, + linear::Increment { + operation: linear::MatchOp::BitWidth { path: p(&[0]) }, + expected: Ok(NonZeroU32::new(32).unwrap()), + actions: vec![], + }, + linear::Increment { + operation: Nop, + expected: Err(Else), + actions: vec![], + }, + ] ); }