]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_codegen_cranelift/src/optimize/peephole.rs
Auto merge of #99334 - NiklasJonsson:84447/error-privacy, r=oli-obk
[rust.git] / compiler / rustc_codegen_cranelift / src / optimize / peephole.rs
1 //! Peephole optimizations that can be performed while creating clif ir.
2
3 use cranelift_codegen::ir::{condcodes::IntCC, InstructionData, Opcode, Value, ValueDef};
4 use cranelift_frontend::FunctionBuilder;
5
6 /// If the given value was produced by a `bint` instruction, return it's input, otherwise return the
7 /// given value.
8 pub(crate) fn maybe_unwrap_bint(bcx: &mut FunctionBuilder<'_>, arg: Value) -> Value {
9     if let ValueDef::Result(arg_inst, 0) = bcx.func.dfg.value_def(arg) {
10         match bcx.func.dfg[arg_inst] {
11             InstructionData::Unary { opcode: Opcode::Bint, arg } => arg,
12             _ => arg,
13         }
14     } else {
15         arg
16     }
17 }
18
19 /// If the given value was produced by the lowering of `Rvalue::Not` return the input and true,
20 /// otherwise return the given value and false.
21 pub(crate) fn maybe_unwrap_bool_not(bcx: &mut FunctionBuilder<'_>, arg: Value) -> (Value, bool) {
22     if let ValueDef::Result(arg_inst, 0) = bcx.func.dfg.value_def(arg) {
23         match bcx.func.dfg[arg_inst] {
24             // This is the lowering of `Rvalue::Not`
25             InstructionData::IntCompareImm {
26                 opcode: Opcode::IcmpImm,
27                 cond: IntCC::Equal,
28                 arg,
29                 imm,
30             } if imm.bits() == 0 => (arg, true),
31             _ => (arg, false),
32         }
33     } else {
34         (arg, false)
35     }
36 }
37
38 /// Returns whether the branch is statically known to be taken or `None` if it isn't statically known.
39 pub(crate) fn maybe_known_branch_taken(
40     bcx: &FunctionBuilder<'_>,
41     arg: Value,
42     test_zero: bool,
43 ) -> Option<bool> {
44     let arg_inst = if let ValueDef::Result(arg_inst, 0) = bcx.func.dfg.value_def(arg) {
45         arg_inst
46     } else {
47         return None;
48     };
49
50     match bcx.func.dfg[arg_inst] {
51         InstructionData::UnaryBool { opcode: Opcode::Bconst, imm } => {
52             if test_zero {
53                 Some(!imm)
54             } else {
55                 Some(imm)
56             }
57         }
58         InstructionData::UnaryImm { opcode: Opcode::Iconst, imm } => {
59             if test_zero {
60                 Some(imm.bits() == 0)
61             } else {
62                 Some(imm.bits() != 0)
63             }
64         }
65         _ => None,
66     }
67 }