From 002aa8ed9026746414cc048f0ad8aefb56f4905a Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 3 Jul 2021 16:46:41 +0200 Subject: [PATCH 1/7] Don't use an allocator shim for `#[global_allocator]` This makes it possible to use liballoc/libstd in combination with `--emit obj` if you use `#[global_allocator]`. Making it work for the default libstd allocator would require weak functions, which are not well supported on all systems. --- src/allocator.rs | 73 +++++++++++++++++++++++++----------------------- 1 file changed, 38 insertions(+), 35 deletions(-) diff --git a/src/allocator.rs b/src/allocator.rs index 2c246ceb37d5..ef69d3f7800c 100644 --- a/src/allocator.rs +++ b/src/allocator.rs @@ -3,10 +3,11 @@ use crate::prelude::*; -use rustc_ast::expand::allocator::{AllocatorKind, AllocatorTy, ALLOCATOR_METHODS}; +use rustc_ast::expand::allocator::{ + alloc_error_handler_name, AllocatorKind, AllocatorTy, ALLOCATOR_METHODS, +}; use rustc_codegen_ssa::base::allocator_kind_for_codegen; use rustc_session::config::OomStrategy; -use rustc_span::symbol::sym; /// Returns whether an allocator shim was created pub(crate) fn codegen( @@ -34,41 +35,43 @@ fn codegen_inner( ) { let usize_ty = module.target_config().pointer_type(); - for method in ALLOCATOR_METHODS { - let mut arg_tys = Vec::with_capacity(method.inputs.len()); - for ty in method.inputs.iter() { - match *ty { - AllocatorTy::Layout => { - arg_tys.push(usize_ty); // size - arg_tys.push(usize_ty); // align + if kind == AllocatorKind::Default { + for method in ALLOCATOR_METHODS { + let mut arg_tys = Vec::with_capacity(method.inputs.len()); + for ty in method.inputs.iter() { + match *ty { + AllocatorTy::Layout => { + arg_tys.push(usize_ty); // size + arg_tys.push(usize_ty); // align + } + AllocatorTy::Ptr => arg_tys.push(usize_ty), + AllocatorTy::Usize => arg_tys.push(usize_ty), + + AllocatorTy::ResultPtr | AllocatorTy::Unit => panic!("invalid allocator arg"), } - AllocatorTy::Ptr => arg_tys.push(usize_ty), - AllocatorTy::Usize => arg_tys.push(usize_ty), - - AllocatorTy::ResultPtr | AllocatorTy::Unit => panic!("invalid allocator arg"), } + let output = match method.output { + AllocatorTy::ResultPtr => Some(usize_ty), + AllocatorTy::Unit => None, + + AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => { + panic!("invalid allocator output") + } + }; + + let sig = Signature { + call_conv: module.target_config().default_call_conv, + params: arg_tys.iter().cloned().map(AbiParam::new).collect(), + returns: output.into_iter().map(AbiParam::new).collect(), + }; + crate::common::create_wrapper_function( + module, + unwind_context, + sig, + &format!("__rust_{}", method.name), + &AllocatorKind::Default.fn_name(method.name), + ); } - let output = match method.output { - AllocatorTy::ResultPtr => Some(usize_ty), - AllocatorTy::Unit => None, - - AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => { - panic!("invalid allocator output") - } - }; - - let sig = Signature { - call_conv: module.target_config().default_call_conv, - params: arg_tys.iter().cloned().map(AbiParam::new).collect(), - returns: output.into_iter().map(AbiParam::new).collect(), - }; - crate::common::create_wrapper_function( - module, - unwind_context, - sig, - &format!("__rust_{}", method.name), - &kind.fn_name(method.name), - ); } let sig = Signature { @@ -81,7 +84,7 @@ fn codegen_inner( unwind_context, sig, "__rust_alloc_error_handler", - &alloc_error_handler_kind.fn_name(sym::oom), + &alloc_error_handler_name(alloc_error_handler_kind), ); let data_id = module.declare_data(OomStrategy::SYMBOL, Linkage::Export, false, false).unwrap(); From 59305092727515852a394ab2d8c66fe107dc3a21 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 3 Jul 2021 17:50:53 +0200 Subject: [PATCH 2/7] Split AllocatorKind::fn_name in global_fn_name and default_fn_name --- src/allocator.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/allocator.rs b/src/allocator.rs index ef69d3f7800c..3b74050250b2 100644 --- a/src/allocator.rs +++ b/src/allocator.rs @@ -4,7 +4,7 @@ use crate::prelude::*; use rustc_ast::expand::allocator::{ - alloc_error_handler_name, AllocatorKind, AllocatorTy, ALLOCATOR_METHODS, + alloc_error_handler_name, default_fn_name, AllocatorKind, AllocatorTy, ALLOCATOR_METHODS, }; use rustc_codegen_ssa::base::allocator_kind_for_codegen; use rustc_session::config::OomStrategy; @@ -69,7 +69,7 @@ fn codegen_inner( unwind_context, sig, &format!("__rust_{}", method.name), - &AllocatorKind::Default.fn_name(method.name), + &default_fn_name(method.name), ); } } From a1d0a902c3aa792bf3eb34d90fd9289b55d29965 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Tue, 6 Jul 2021 18:56:01 +0200 Subject: [PATCH 3/7] Use global_fn_name instead of format! --- src/allocator.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/allocator.rs b/src/allocator.rs index 3b74050250b2..c27971897a03 100644 --- a/src/allocator.rs +++ b/src/allocator.rs @@ -4,7 +4,8 @@ use crate::prelude::*; use rustc_ast::expand::allocator::{ - alloc_error_handler_name, default_fn_name, AllocatorKind, AllocatorTy, ALLOCATOR_METHODS, + alloc_error_handler_name, default_fn_name, global_fn_name, AllocatorKind, AllocatorTy, + ALLOCATOR_METHODS, }; use rustc_codegen_ssa::base::allocator_kind_for_codegen; use rustc_session::config::OomStrategy; @@ -68,7 +69,7 @@ fn codegen_inner( module, unwind_context, sig, - &format!("__rust_{}", method.name), + &global_fn_name(method.name), &default_fn_name(method.name), ); } From 2253e866a9de756c7de23179923371a2ee38629a Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 10 Sep 2022 11:33:44 +0000 Subject: [PATCH 4/7] Prevent insta-stable no alloc shim support You will need to add the following as replacement for the old __rust_* definitions when not using the alloc shim. #[no_mangle] static __rust_no_alloc_shim_is_unstable: u8 = 0; --- src/allocator.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/allocator.rs b/src/allocator.rs index c27971897a03..d4b1ae2b6138 100644 --- a/src/allocator.rs +++ b/src/allocator.rs @@ -5,7 +5,7 @@ use crate::prelude::*; use rustc_ast::expand::allocator::{ alloc_error_handler_name, default_fn_name, global_fn_name, AllocatorKind, AllocatorTy, - ALLOCATOR_METHODS, + ALLOCATOR_METHODS, NO_ALLOC_SHIM_IS_UNSTABLE, }; use rustc_codegen_ssa::base::allocator_kind_for_codegen; use rustc_session::config::OomStrategy; @@ -94,4 +94,11 @@ fn codegen_inner( let val = oom_strategy.should_panic(); data_ctx.define(Box::new([val])); module.define_data(data_id, &data_ctx).unwrap(); + + let data_id = + module.declare_data(NO_ALLOC_SHIM_IS_UNSTABLE, Linkage::Export, false, false).unwrap(); + let mut data_ctx = DataContext::new(); + data_ctx.set_align(1); + data_ctx.define(Box::new([0])); + module.define_data(data_id, &data_ctx).unwrap(); } From 8a9b38fd3bbf9d57cddb824f104fad592c7377e0 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 16 May 2023 16:04:03 +1000 Subject: [PATCH 5/7] Avoid `&format("...")` calls in error message code. Error message all end up passing into a function as an `impl Into<{D,Subd}iagnosticMessage>`. If an error message is creatd as `&format("...")` that means we allocate a string (in the `format!` call), then take a reference, and then clone (allocating again) the reference to produce the `{D,Subd}iagnosticMessage`, which is silly. This commit removes the leading `&` from a lot of these cases. This means the original `String` is moved into the `{D,Subd}iagnosticMessage`, avoiding the double allocations. This requires changing some function argument types from `&str` to `String` (when all arguments are `String`) or `impl Into<{D,Subd}iagnosticMessage>` (when some arguments are `String` and some are `&str`). --- src/pretty_clif.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pretty_clif.rs b/src/pretty_clif.rs index 27e21183c556..1007b33eca42 100644 --- a/src/pretty_clif.rs +++ b/src/pretty_clif.rs @@ -227,7 +227,7 @@ pub(crate) fn write_ir_file( // Using early_warn as no Session is available here rustc_session::early_warn( rustc_session::config::ErrorOutputType::default(), - &format!("error writing ir file: {}", err), + format!("error writing ir file: {}", err), ); } } From 74ab27c26930e8697b25a0938305b722fc080567 Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Tue, 16 May 2023 19:23:38 +0200 Subject: [PATCH 6/7] Remove `LangItems::require` It's just a short wrapper used by `tcx.require_lang_item`. Deleting it gives us a negative diff. --- src/base.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/base.rs b/src/base.rs index e9dbea1be671..25fd5ca3ae8b 100644 --- a/src/base.rs +++ b/src/base.rs @@ -966,11 +966,7 @@ fn codegen_panic_inner<'tcx>( args: &[Value], span: Span, ) { - let def_id = fx - .tcx - .lang_items() - .require(lang_item) - .unwrap_or_else(|e| fx.tcx.sess.span_fatal(span, e.to_string())); + let def_id = fx.tcx.require_lang_item(lang_item, Some(span)); let instance = Instance::mono(fx.tcx, def_id).polymorphize(fx.tcx); let symbol_name = fx.tcx.symbol_name(instance).name; From a3b816be53b5d3eae48e7291836442f6dff9e318 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Wed, 24 May 2023 14:33:43 +0000 Subject: [PATCH 7/7] Use `is_some_and`/`is_ok_and` in less obvious spots --- src/abi/mod.rs | 10 ++++------ src/base.rs | 8 ++++---- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/abi/mod.rs b/src/abi/mod.rs index 73a3e3353f3a..84e09cf0abe4 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -432,11 +432,9 @@ pub(crate) fn codegen_terminator_call<'tcx>( let is_cold = if fn_sig.abi() == Abi::RustCold { true } else { - instance - .map(|inst| { - fx.tcx.codegen_fn_attrs(inst.def_id()).flags.contains(CodegenFnAttrFlags::COLD) - }) - .unwrap_or(false) + instance.is_some_and(|inst| { + fx.tcx.codegen_fn_attrs(inst.def_id()).flags.contains(CodegenFnAttrFlags::COLD) + }) }; if is_cold { fx.bcx.set_cold_block(fx.bcx.current_block().unwrap()); @@ -470,7 +468,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( }; // Pass the caller location for `#[track_caller]`. - if instance.map(|inst| inst.def.requires_caller_location(fx.tcx)).unwrap_or(false) { + if instance.is_some_and(|inst| inst.def.requires_caller_location(fx.tcx)) { let caller_location = fx.get_caller_location(source_info); args.push(CallArgument { value: caller_location, is_owned: false }); } diff --git a/src/base.rs b/src/base.rs index 25fd5ca3ae8b..9c6a0fae327c 100644 --- a/src/base.rs +++ b/src/base.rs @@ -630,11 +630,11 @@ fn codegen_stmt<'tcx>( let to_ty = fx.monomorphize(to_ty); fn is_fat_ptr<'tcx>(fx: &FunctionCx<'_, '_, 'tcx>, ty: Ty<'tcx>) -> bool { - ty.builtin_deref(true) - .map(|ty::TypeAndMut { ty: pointee_ty, mutbl: _ }| { + ty.builtin_deref(true).is_some_and( + |ty::TypeAndMut { ty: pointee_ty, mutbl: _ }| { has_ptr_meta(fx.tcx, pointee_ty) - }) - .unwrap_or(false) + }, + ) } if is_fat_ptr(fx, from_ty) {