1 //! Peephole optimizations that can be performed while creating clif ir.
3 use cranelift_codegen::ir::{
4 condcodes::IntCC, types, InstBuilder, InstructionData, Opcode, Value, ValueDef,
6 use cranelift_frontend::FunctionBuilder;
8 /// If the given value was produced by a `bint` instruction, return it's input, otherwise return the
10 pub(crate) fn maybe_unwrap_bint(bcx: &mut FunctionBuilder<'_>, arg: Value) -> Value {
11 if let ValueDef::Result(arg_inst, 0) = bcx.func.dfg.value_def(arg) {
12 match bcx.func.dfg[arg_inst] {
13 InstructionData::Unary {
24 /// If the given value was produced by the lowering of `Rvalue::Not` return the input and true,
25 /// otherwise return the given value and false.
26 pub(crate) fn maybe_unwrap_bool_not(bcx: &mut FunctionBuilder<'_>, arg: Value) -> (Value, bool) {
27 if let ValueDef::Result(arg_inst, 0) = bcx.func.dfg.value_def(arg) {
28 match bcx.func.dfg[arg_inst] {
29 // This is the lowering of `Rvalue::Not`
30 InstructionData::IntCompareImm {
31 opcode: Opcode::IcmpImm,
35 } if imm.bits() == 0 => (arg, true),
43 pub(crate) fn make_branchable_value(bcx: &mut FunctionBuilder<'_>, arg: Value) -> Value {
44 if bcx.func.dfg.value_type(arg).is_bool() {
49 let arg_inst = if let ValueDef::Result(arg_inst, 0) = bcx.func.dfg.value_def(arg) {
55 match bcx.func.dfg[arg_inst] {
56 // This is the lowering of Rvalue::Not
57 InstructionData::Load {
63 // Using `load.i8 + uextend.i32` would legalize to `uload8 + ireduce.i8 +
64 // uextend.i32`. Just `uload8` is much faster.
65 match bcx.func.dfg.ctrl_typevar(arg_inst) {
66 types::I8 => Some(bcx.ins().uload8(types::I32, flags, ptr, offset)),
67 types::I16 => Some(bcx.ins().uload16(types::I32, flags, ptr, offset)),
75 match bcx.func.dfg.value_type(arg) {
76 types::I8 | types::I32 => {
77 // WORKAROUND for brz.i8 and brnz.i8 not yet being implemented
78 bcx.ins().uextend(types::I32, arg)