diff options
| author | Ralf Jung <post@ralfj.de> | 2025-01-08 09:23:40 +0100 |
|---|---|---|
| committer | Ralf Jung <post@ralfj.de> | 2025-01-08 09:23:40 +0100 |
| commit | 2d180714e14b34e36bf883bdf706ebaf5fa96754 (patch) | |
| tree | 36b4829675d832d323283fc37457f6509f8a519c /compiler/rustc_codegen_cranelift/src | |
| parent | fc4a52f598f6259a98964aa3290e9e74e396c1e3 (diff) | |
| parent | 67f49010adf4ec3238564ec072b3652179813dd1 (diff) | |
| download | rust-2d180714e14b34e36bf883bdf706ebaf5fa96754.tar.gz rust-2d180714e14b34e36bf883bdf706ebaf5fa96754.zip | |
Merge from rustc
Diffstat (limited to 'compiler/rustc_codegen_cranelift/src')
8 files changed, 57 insertions, 67 deletions
diff --git a/compiler/rustc_codegen_cranelift/src/codegen_i128.rs b/compiler/rustc_codegen_cranelift/src/codegen_i128.rs index 734574338d0..025667e66b2 100644 --- a/compiler/rustc_codegen_cranelift/src/codegen_i128.rs +++ b/compiler/rustc_codegen_cranelift/src/codegen_i128.rs @@ -62,9 +62,8 @@ pub(crate) fn maybe_codegen<'tcx>( } } -pub(crate) fn maybe_codegen_checked<'tcx>( +pub(crate) fn maybe_codegen_mul_checked<'tcx>( fx: &mut FunctionCx<'_, '_, 'tcx>, - bin_op: BinOp, lhs: CValue<'tcx>, rhs: CValue<'tcx>, ) -> Option<CValue<'tcx>> { @@ -78,32 +77,19 @@ pub(crate) fn maybe_codegen_checked<'tcx>( let is_signed = type_sign(lhs.layout().ty); - match bin_op { - BinOp::BitAnd | BinOp::BitOr | BinOp::BitXor => unreachable!(), - BinOp::Add | BinOp::Sub => None, - BinOp::Mul => { - let out_ty = Ty::new_tup(fx.tcx, &[lhs.layout().ty, fx.tcx.types.bool]); - let out_place = CPlace::new_stack_slot(fx, fx.layout_of(out_ty)); - let param_types = vec![ - AbiParam::special(fx.pointer_type, ArgumentPurpose::StructReturn), - AbiParam::new(types::I128), - AbiParam::new(types::I128), - ]; - let args = [out_place.to_ptr().get_addr(fx), lhs.load_scalar(fx), rhs.load_scalar(fx)]; - fx.lib_call( - if is_signed { "__rust_i128_mulo" } else { "__rust_u128_mulo" }, - param_types, - vec![], - &args, - ); - Some(out_place.to_cvalue(fx)) - } - BinOp::AddUnchecked | BinOp::SubUnchecked | BinOp::MulUnchecked => unreachable!(), - BinOp::AddWithOverflow | BinOp::SubWithOverflow | BinOp::MulWithOverflow => unreachable!(), - BinOp::Offset => unreachable!("offset should only be used on pointers, not 128bit ints"), - BinOp::Div | BinOp::Rem => unreachable!(), - BinOp::Cmp => unreachable!(), - BinOp::Lt | BinOp::Le | BinOp::Eq | BinOp::Ge | BinOp::Gt | BinOp::Ne => unreachable!(), - BinOp::Shl | BinOp::ShlUnchecked | BinOp::Shr | BinOp::ShrUnchecked => unreachable!(), - } + let out_ty = Ty::new_tup(fx.tcx, &[lhs.layout().ty, fx.tcx.types.bool]); + let out_place = CPlace::new_stack_slot(fx, fx.layout_of(out_ty)); + let param_types = vec![ + AbiParam::special(fx.pointer_type, ArgumentPurpose::StructReturn), + AbiParam::new(types::I128), + AbiParam::new(types::I128), + ]; + let args = [out_place.to_ptr().get_addr(fx), lhs.load_scalar(fx), rhs.load_scalar(fx)]; + fx.lib_call( + if is_signed { "__rust_i128_mulo" } else { "__rust_u128_mulo" }, + param_types, + vec![], + &args, + ); + Some(out_place.to_cvalue(fx)) } diff --git a/compiler/rustc_codegen_cranelift/src/driver/aot.rs b/compiler/rustc_codegen_cranelift/src/driver/aot.rs index 4fc30b69123..fe578e44770 100644 --- a/compiler/rustc_codegen_cranelift/src/driver/aot.rs +++ b/compiler/rustc_codegen_cranelift/src/driver/aot.rs @@ -333,10 +333,9 @@ fn make_module(sess: &Session, name: String) -> UnwindModule<ObjectModule> { let mut builder = ObjectBuilder::new(isa, name + ".o", cranelift_module::default_libcall_names()).unwrap(); - // Unlike cg_llvm, cg_clif defaults to disabling -Zfunction-sections. For cg_llvm binary size - // is important, while cg_clif cares more about compilation times. Enabling -Zfunction-sections - // can easily double the amount of time necessary to perform linking. - builder.per_function_section(sess.opts.unstable_opts.function_sections.unwrap_or(false)); + builder.per_function_section( + sess.opts.unstable_opts.function_sections.unwrap_or(sess.target.function_sections), + ); UnwindModule::new(ObjectModule::new(builder), true) } diff --git a/compiler/rustc_codegen_cranelift/src/driver/jit.rs b/compiler/rustc_codegen_cranelift/src/driver/jit.rs index eaab3362c7e..9ca930e14da 100644 --- a/compiler/rustc_codegen_cranelift/src/driver/jit.rs +++ b/compiler/rustc_codegen_cranelift/src/driver/jit.rs @@ -287,7 +287,7 @@ fn dep_symbol_lookup_fn( let mut dylib_paths = Vec::new(); - let data = &crate_info.dependency_formats[&rustc_session::config::CrateType::Executable].1; + let data = &crate_info.dependency_formats[&rustc_session::config::CrateType::Executable]; // `used_crates` is in reverse postorder in terms of dependencies. Reverse the order here to // get a postorder which ensures that all dependencies of a dylib are loaded before the dylib // itself. This helps the dynamic linker to find dylibs not in the regular dynamic library diff --git a/compiler/rustc_codegen_cranelift/src/driver/mod.rs b/compiler/rustc_codegen_cranelift/src/driver/mod.rs index fb0eed07c19..ffd47cace38 100644 --- a/compiler/rustc_codegen_cranelift/src/driver/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/driver/mod.rs @@ -73,12 +73,14 @@ impl Drop for TimingGuard { impl cranelift_codegen::timing::Profiler for MeasuremeProfiler { fn start_pass(&self, pass: cranelift_codegen::timing::Pass) -> Box<dyn std::any::Any> { - let mut timing_guard = - TimingGuard { profiler: std::mem::ManuallyDrop::new(self.0.clone()), inner: None }; + let mut timing_guard = Box::new(TimingGuard { + profiler: std::mem::ManuallyDrop::new(self.0.clone()), + inner: None, + }); timing_guard.inner = Some( unsafe { &*(&*timing_guard.profiler as &SelfProfilerRef as *const SelfProfilerRef) } .generic_activity(pass.description()), ); - Box::new(timing_guard) + timing_guard } } diff --git a/compiler/rustc_codegen_cranelift/src/inline_asm.rs b/compiler/rustc_codegen_cranelift/src/inline_asm.rs index 33726056cc1..6ff75f75d3b 100644 --- a/compiler/rustc_codegen_cranelift/src/inline_asm.rs +++ b/compiler/rustc_codegen_cranelift/src/inline_asm.rs @@ -136,7 +136,7 @@ pub(crate) fn codegen_inline_asm_terminator<'tcx>( fx.bcx.ins().jump(destination_block, &[]); } None => { - fx.bcx.ins().trap(TrapCode::user(0 /* unreachable */).unwrap()); + fx.bcx.ins().trap(TrapCode::user(1 /* unreachable */).unwrap()); } } } diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs index e0ebe30752a..6d71b8e8aba 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs @@ -1136,7 +1136,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( _ => { fx.tcx.dcx().span_err(span, format!("Unknown SIMD intrinsic {}", intrinsic)); // Prevent verifier error - fx.bcx.ins().trap(TrapCode::user(0 /* unreachable */).unwrap()); + fx.bcx.ins().trap(TrapCode::user(1 /* unreachable */).unwrap()); return; } } diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index c38ef82e5b8..dc5d80e7a34 100644 --- a/compiler/rustc_codegen_cranelift/src/lib.rs +++ b/compiler/rustc_codegen_cranelift/src/lib.rs @@ -27,6 +27,8 @@ extern crate rustc_metadata; extern crate rustc_session; extern crate rustc_span; extern crate rustc_target; +#[macro_use] +extern crate tracing; // This prevents duplicating functions and statics that are already part of the host rustc process. #[allow(unused_extern_crates)] @@ -208,6 +210,7 @@ impl CodegenBackend for CraneliftCodegenBackend { need_metadata_module: bool, ) -> Box<dyn Any> { tcx.dcx().abort_if_errors(); + info!("codegen crate {}", tcx.crate_name(LOCAL_CRATE)); let config = self.config.clone().unwrap_or_else(|| { BackendConfig::from_opts(&tcx.sess.opts.cg.llvm_args) .unwrap_or_else(|err| tcx.sess.dcx().fatal(err)) diff --git a/compiler/rustc_codegen_cranelift/src/num.rs b/compiler/rustc_codegen_cranelift/src/num.rs index fb18f45d7dc..f44e2459a78 100644 --- a/compiler/rustc_codegen_cranelift/src/num.rs +++ b/compiler/rustc_codegen_cranelift/src/num.rs @@ -2,10 +2,10 @@ use crate::prelude::*; -pub(crate) fn bin_op_to_intcc(bin_op: BinOp, signed: bool) -> Option<IntCC> { +pub(crate) fn bin_op_to_intcc(bin_op: BinOp, signed: bool) -> IntCC { use BinOp::*; use IntCC::*; - Some(match bin_op { + match bin_op { Eq => Equal, Lt => { if signed { @@ -36,8 +36,8 @@ pub(crate) fn bin_op_to_intcc(bin_op: BinOp, signed: bool) -> Option<IntCC> { UnsignedGreaterThan } } - _ => return None, - }) + _ => unreachable!(), + } } fn codegen_three_way_compare<'tcx>( @@ -48,8 +48,8 @@ fn codegen_three_way_compare<'tcx>( ) -> CValue<'tcx> { // This emits `(lhs > rhs) - (lhs < rhs)`, which is cranelift's preferred form per // <https://github.com/bytecodealliance/wasmtime/blob/8052bb9e3b792503b225f2a5b2ba3bc023bff462/cranelift/codegen/src/prelude_opt.isle#L41-L47> - let gt_cc = crate::num::bin_op_to_intcc(BinOp::Gt, signed).unwrap(); - let lt_cc = crate::num::bin_op_to_intcc(BinOp::Lt, signed).unwrap(); + let gt_cc = crate::num::bin_op_to_intcc(BinOp::Gt, signed); + let lt_cc = crate::num::bin_op_to_intcc(BinOp::Lt, signed); let gt = fx.bcx.ins().icmp(gt_cc, lhs, rhs); let lt = fx.bcx.ins().icmp(lt_cc, lhs, rhs); let val = fx.bcx.ins().isub(gt, lt); @@ -63,11 +63,7 @@ fn codegen_compare_bin_op<'tcx>( lhs: Value, rhs: Value, ) -> CValue<'tcx> { - if bin_op == BinOp::Cmp { - return codegen_three_way_compare(fx, signed, lhs, rhs); - } - - let intcc = crate::num::bin_op_to_intcc(bin_op, signed).unwrap(); + let intcc = crate::num::bin_op_to_intcc(bin_op, signed); let val = fx.bcx.ins().icmp(intcc, lhs, rhs); CValue::by_val(val, fx.layout_of(fx.tcx.types.bool)) } @@ -79,7 +75,7 @@ pub(crate) fn codegen_binop<'tcx>( in_rhs: CValue<'tcx>, ) -> CValue<'tcx> { match bin_op { - BinOp::Eq | BinOp::Lt | BinOp::Le | BinOp::Ne | BinOp::Ge | BinOp::Gt | BinOp::Cmp => { + BinOp::Eq | BinOp::Lt | BinOp::Le | BinOp::Ne | BinOp::Ge | BinOp::Gt => { match in_lhs.layout().ty.kind() { ty::Bool | ty::Uint(_) | ty::Int(_) | ty::Char => { let signed = type_sign(in_lhs.layout().ty); @@ -91,6 +87,16 @@ pub(crate) fn codegen_binop<'tcx>( _ => {} } } + BinOp::Cmp => match in_lhs.layout().ty.kind() { + ty::Bool | ty::Uint(_) | ty::Int(_) | ty::Char => { + let signed = type_sign(in_lhs.layout().ty); + let lhs = in_lhs.load_scalar(fx); + let rhs = in_rhs.load_scalar(fx); + + return codegen_three_way_compare(fx, signed, lhs, rhs); + } + _ => {} + }, _ => {} } @@ -200,10 +206,6 @@ pub(crate) fn codegen_checked_int_binop<'tcx>( let lhs = in_lhs.load_scalar(fx); let rhs = in_rhs.load_scalar(fx); - if let Some(res) = crate::codegen_i128::maybe_codegen_checked(fx, bin_op, in_lhs, in_rhs) { - return res; - } - let signed = type_sign(in_lhs.layout().ty); let (res, has_overflow) = match bin_op { @@ -236,6 +238,10 @@ pub(crate) fn codegen_checked_int_binop<'tcx>( (val, has_overflow) } BinOp::Mul => { + if let Some(res) = crate::codegen_i128::maybe_codegen_mul_checked(fx, in_lhs, in_rhs) { + return res; + } + let ty = fx.bcx.func.dfg.value_type(lhs); match ty { types::I8 | types::I16 | types::I32 if !signed => { @@ -357,14 +363,12 @@ pub(crate) fn codegen_float_binop<'tcx>( _ => bug!(), }; - let ret_val = fx.lib_call( + fx.lib_call( name, vec![AbiParam::new(ty), AbiParam::new(ty)], vec![AbiParam::new(ty)], &[lhs, rhs], - )[0]; - - return CValue::by_val(ret_val, in_lhs.layout()); + )[0] } BinOp::Eq | BinOp::Lt | BinOp::Le | BinOp::Ne | BinOp::Ge | BinOp::Gt => { let fltcc = match bin_op { @@ -431,13 +435,9 @@ pub(crate) fn codegen_ptr_binop<'tcx>( BinOp::Lt | BinOp::Le | BinOp::Ge | BinOp::Gt => { let ptr_eq = fx.bcx.ins().icmp(IntCC::Equal, lhs_ptr, rhs_ptr); - let ptr_cmp = - fx.bcx.ins().icmp(bin_op_to_intcc(bin_op, false).unwrap(), lhs_ptr, rhs_ptr); - let extra_cmp = fx.bcx.ins().icmp( - bin_op_to_intcc(bin_op, false).unwrap(), - lhs_extra, - rhs_extra, - ); + let ptr_cmp = fx.bcx.ins().icmp(bin_op_to_intcc(bin_op, false), lhs_ptr, rhs_ptr); + let extra_cmp = + fx.bcx.ins().icmp(bin_op_to_intcc(bin_op, false), lhs_extra, rhs_extra); fx.bcx.ins().select(ptr_eq, extra_cmp, ptr_cmp) } |
