From 698f8c2f01ea549d77d7dc3338a12e04c11057b9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:02:58 +0200 Subject: Adding upstream version 1.64.0+dfsg1. Signed-off-by: Daniel Baumann --- .../rustc_codegen_cranelift/src/optimize/mod.rs | 20 +++++++ .../src/optimize/peephole.rs | 67 ++++++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 compiler/rustc_codegen_cranelift/src/optimize/mod.rs create mode 100644 compiler/rustc_codegen_cranelift/src/optimize/peephole.rs (limited to 'compiler/rustc_codegen_cranelift/src/optimize') diff --git a/compiler/rustc_codegen_cranelift/src/optimize/mod.rs b/compiler/rustc_codegen_cranelift/src/optimize/mod.rs new file mode 100644 index 000000000..d1f89adb3 --- /dev/null +++ b/compiler/rustc_codegen_cranelift/src/optimize/mod.rs @@ -0,0 +1,20 @@ +//! Various optimizations specific to cg_clif + +use cranelift_codegen::isa::TargetIsa; + +use crate::prelude::*; + +pub(crate) mod peephole; + +pub(crate) fn optimize_function<'tcx>( + tcx: TyCtxt<'tcx>, + isa: &dyn TargetIsa, + instance: Instance<'tcx>, + ctx: &mut Context, + clif_comments: &mut crate::pretty_clif::CommentWriter, +) { + // FIXME classify optimizations over opt levels once we have more + + crate::pretty_clif::write_clif_file(tcx, "preopt", isa, instance, &ctx.func, &*clif_comments); + crate::base::verify_func(tcx, &*clif_comments, &ctx.func); +} diff --git a/compiler/rustc_codegen_cranelift/src/optimize/peephole.rs b/compiler/rustc_codegen_cranelift/src/optimize/peephole.rs new file mode 100644 index 000000000..d637b4d89 --- /dev/null +++ b/compiler/rustc_codegen_cranelift/src/optimize/peephole.rs @@ -0,0 +1,67 @@ +//! Peephole optimizations that can be performed while creating clif ir. + +use cranelift_codegen::ir::{condcodes::IntCC, InstructionData, Opcode, Value, ValueDef}; +use cranelift_frontend::FunctionBuilder; + +/// If the given value was produced by a `bint` instruction, return it's input, otherwise return the +/// given value. +pub(crate) fn maybe_unwrap_bint(bcx: &mut FunctionBuilder<'_>, arg: Value) -> Value { + if let ValueDef::Result(arg_inst, 0) = bcx.func.dfg.value_def(arg) { + match bcx.func.dfg[arg_inst] { + InstructionData::Unary { opcode: Opcode::Bint, arg } => arg, + _ => arg, + } + } else { + arg + } +} + +/// If the given value was produced by the lowering of `Rvalue::Not` return the input and true, +/// otherwise return the given value and false. +pub(crate) fn maybe_unwrap_bool_not(bcx: &mut FunctionBuilder<'_>, arg: Value) -> (Value, bool) { + if let ValueDef::Result(arg_inst, 0) = bcx.func.dfg.value_def(arg) { + match bcx.func.dfg[arg_inst] { + // This is the lowering of `Rvalue::Not` + InstructionData::IntCompareImm { + opcode: Opcode::IcmpImm, + cond: IntCC::Equal, + arg, + imm, + } if imm.bits() == 0 => (arg, true), + _ => (arg, false), + } + } else { + (arg, false) + } +} + +/// Returns whether the branch is statically known to be taken or `None` if it isn't statically known. +pub(crate) fn maybe_known_branch_taken( + bcx: &FunctionBuilder<'_>, + arg: Value, + test_zero: bool, +) -> Option { + let arg_inst = if let ValueDef::Result(arg_inst, 0) = bcx.func.dfg.value_def(arg) { + arg_inst + } else { + return None; + }; + + match bcx.func.dfg[arg_inst] { + InstructionData::UnaryBool { opcode: Opcode::Bconst, imm } => { + if test_zero { + Some(!imm) + } else { + Some(imm) + } + } + InstructionData::UnaryImm { opcode: Opcode::Iconst, imm } => { + if test_zero { + Some(imm.bits() == 0) + } else { + Some(imm.bits() != 0) + } + } + _ => None, + } +} -- cgit v1.2.3