From 4b616299511c3de88f1052594e19940733567afe Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 16 Mar 2024 17:23:11 +0000 Subject: [PATCH 01/40] Merge commit '4cf4ffc6ba514f171b3f52d1c731063e4fc45be3' into sync_cg_clif-2024-03-16 --- .github/workflows/main.yml | 30 ++++++++++++++++---------- example/std_example.rs | 8 +++++++ patches/bcryptprimitives.rs | 22 +++++++++++++++++++ patches/stdlib-lock.toml | 7 ++----- rust-toolchain | 2 +- scripts/test_rustc_tests.sh | 2 ++ src/constant.rs | 42 +++++++++++++++++++++++++------------ 7 files changed, 83 insertions(+), 30 deletions(-) create mode 100644 patches/bcryptprimitives.rs diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 5f0f3e6549c90..526871d0c05f4 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -44,10 +44,9 @@ jobs: env: TARGET_TRIPLE: x86_64-apple-darwin # cross-compile from Linux to Windows using mingw - # FIXME The wine version in Ubuntu 22.04 is missing ProcessPrng - #- os: ubuntu-latest - # env: - # TARGET_TRIPLE: x86_64-pc-windows-gnu + - os: ubuntu-latest + env: + TARGET_TRIPLE: x86_64-pc-windows-gnu - os: ubuntu-latest env: TARGET_TRIPLE: aarch64-unknown-linux-gnu @@ -81,11 +80,11 @@ jobs: if: matrix.os == 'windows-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu' run: rustup set default-host x86_64-pc-windows-gnu - #- name: Install MinGW toolchain and wine - # if: matrix.os == 'ubuntu-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu' - # run: | - # sudo apt-get update - # sudo apt-get install -y gcc-mingw-w64-x86-64 wine-stable + - name: Install MinGW toolchain and wine + if: matrix.os == 'ubuntu-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu' + run: | + sudo apt-get update + sudo apt-get install -y gcc-mingw-w64-x86-64 wine-stable - name: Install AArch64 toolchain and qemu if: matrix.os == 'ubuntu-latest' && matrix.env.TARGET_TRIPLE == 'aarch64-unknown-linux-gnu' @@ -108,6 +107,15 @@ jobs: - name: Prepare dependencies run: ./y.sh prepare + # The Wine version shipped with Ubuntu 22.04 doesn't implement bcryptprimitives.dll + - name: Build bcryptprimitives.dll shim for Wine + if: matrix.os == 'ubuntu-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu' + run: | + rustup target add x86_64-pc-windows-gnu + mkdir wine_shims + rustc patches/bcryptprimitives.rs -Copt-level=3 -Clto=fat --out-dir wine_shims --target x86_64-pc-windows-gnu + echo "WINEPATH=$(pwd)/wine_shims" >> $GITHUB_ENV + - name: Build run: ./y.sh build --sysroot none @@ -234,11 +242,11 @@ jobs: if: matrix.os == 'windows-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu' run: rustup set default-host x86_64-pc-windows-gnu - - name: Install MinGW toolchain and wine + - name: Install MinGW toolchain if: matrix.os == 'ubuntu-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu' run: | sudo apt-get update - sudo apt-get install -y gcc-mingw-w64-x86-64 wine-stable + sudo apt-get install -y gcc-mingw-w64-x86-64 - name: Prepare dependencies run: ./y.sh prepare diff --git a/example/std_example.rs b/example/std_example.rs index 9bd2ab5c638c1..2fee912e52ccf 100644 --- a/example/std_example.rs +++ b/example/std_example.rs @@ -167,6 +167,14 @@ fn main() { transmute_fat_pointer(); rust_call_abi(); + + const fn no_str() -> Option> { + None + } + + static STATIC_WITH_MAYBE_NESTED_BOX: &Option> = &no_str(); + + println!("{:?}", STATIC_WITH_MAYBE_NESTED_BOX); } fn panic(_: u128) { diff --git a/patches/bcryptprimitives.rs b/patches/bcryptprimitives.rs new file mode 100644 index 0000000000000..4d186485aac1d --- /dev/null +++ b/patches/bcryptprimitives.rs @@ -0,0 +1,22 @@ +// Shim for bcryptprimitives.dll. The Wine version shipped with Ubuntu 22.04 +// doesn't support it yet. Authored by @ChrisDenton + +#![crate_type = "cdylib"] +#![allow(nonstandard_style)] + +#[no_mangle] +pub unsafe extern "system" fn ProcessPrng(mut pbData: *mut u8, mut cbData: usize) -> i32 { + while cbData > 0 { + let size = core::cmp::min(cbData, u32::MAX as usize); + RtlGenRandom(pbData, size as u32); + cbData -= size; + pbData = pbData.add(size); + } + 1 +} + +#[link(name = "advapi32")] +extern "system" { + #[link_name = "SystemFunction036"] + pub fn RtlGenRandom(RandomBuffer: *mut u8, RandomBufferLength: u32) -> u8; +} diff --git a/patches/stdlib-lock.toml b/patches/stdlib-lock.toml index 369f9c88be112..a72fa2c62a96c 100644 --- a/patches/stdlib-lock.toml +++ b/patches/stdlib-lock.toml @@ -42,12 +42,9 @@ checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" [[package]] name = "cc" -version = "1.0.83" +version = "1.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" -dependencies = [ - "libc", -] +checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" [[package]] name = "cfg-if" diff --git a/rust-toolchain b/rust-toolchain index e9f225b4e9e17..f3cd4cbe49354 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-03-08" +channel = "nightly-2024-03-16" components = ["rust-src", "rustc-dev", "llvm-tools"] diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index e884577d519da..9b360fb303624 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -83,6 +83,7 @@ rm -r tests/run-make/symbols-include-type-name # --emit=asm not supported rm -r tests/run-make/target-specs # i686 not supported by Cranelift rm -r tests/run-make/mismatching-target-triples # same rm tests/ui/asm/x86_64/issue-96797.rs # const and sym inline asm operands don't work entirely correctly +rm tests/ui/asm/x86_64/goto.rs # inline asm labels not supported # requires LTO rm -r tests/run-make/cdylib @@ -121,6 +122,7 @@ rm -r tests/run-make/optimization-remarks-dir # remarks are LLVM specific rm tests/ui/mir/mir_misc_casts.rs # depends on deduplication of constants rm tests/ui/mir/mir_raw_fat_ptr.rs # same rm tests/ui/consts/issue-33537.rs # same +rm tests/ui/consts/const-mut-refs-crate.rs # same # rustdoc-clif passes extra args, suppressing the help message when no args are passed rm -r tests/run-make/issue-88756-default-output diff --git a/src/constant.rs b/src/constant.rs index cec479218b71f..39fa277fedc55 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -53,7 +53,11 @@ pub(crate) fn codegen_tls_ref<'tcx>( let call = fx.bcx.ins().call(func_ref, &[]); fx.bcx.func.dfg.first_result(call) } else { - let data_id = data_id_for_static(fx.tcx, fx.module, def_id, false); + let data_id = data_id_for_static( + fx.tcx, fx.module, def_id, false, + // For a declaration the stated mutability doesn't matter. + false, + ); let local_data_id = fx.module.declare_data_in_func(data_id, &mut fx.bcx.func); if fx.clif_comments.enabled() { fx.add_comment(local_data_id, format!("tls {:?}", def_id)); @@ -164,7 +168,11 @@ pub(crate) fn codegen_const_value<'tcx>( } GlobalAlloc::Static(def_id) => { assert!(fx.tcx.is_static(def_id)); - let data_id = data_id_for_static(fx.tcx, fx.module, def_id, false); + let data_id = data_id_for_static( + fx.tcx, fx.module, def_id, false, + // For a declaration the stated mutability doesn't matter. + false, + ); let local_data_id = fx.module.declare_data_in_func(data_id, &mut fx.bcx.func); if fx.clif_comments.enabled() { @@ -232,21 +240,19 @@ fn data_id_for_static( module: &mut dyn Module, def_id: DefId, definition: bool, + definition_writable: bool, ) -> DataId { let attrs = tcx.codegen_fn_attrs(def_id); let instance = Instance::mono(tcx, def_id).polymorphize(tcx); let symbol_name = tcx.symbol_name(instance).name; - let ty = instance.ty(tcx, ParamEnv::reveal_all()); - let is_mutable = if tcx.is_mutable_static(def_id) { - true - } else { - !ty.is_freeze(tcx, ParamEnv::reveal_all()) - }; - let align = tcx.layout_of(ParamEnv::reveal_all().and(ty)).unwrap().align.pref.bytes(); if let Some(import_linkage) = attrs.import_linkage { assert!(!definition); + assert!(!tcx.is_mutable_static(def_id)); + + let ty = instance.ty(tcx, ParamEnv::reveal_all()); + let align = tcx.layout_of(ParamEnv::reveal_all().and(ty)).unwrap().align.pref.bytes(); let linkage = if import_linkage == rustc_middle::mir::mono::Linkage::ExternalWeak || import_linkage == rustc_middle::mir::mono::Linkage::WeakAny @@ -259,7 +265,7 @@ fn data_id_for_static( let data_id = match module.declare_data( symbol_name, linkage, - is_mutable, + false, attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL), ) { Ok(data_id) => data_id, @@ -307,7 +313,7 @@ fn data_id_for_static( let data_id = match module.declare_data( symbol_name, linkage, - is_mutable, + definition_writable, attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL), ) { Ok(data_id) => data_id, @@ -341,7 +347,13 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant let alloc = tcx.eval_static_initializer(def_id).unwrap(); - let data_id = data_id_for_static(tcx, module, def_id, true); + let data_id = data_id_for_static( + tcx, + module, + def_id, + true, + alloc.inner().mutability == Mutability::Mut, + ); (data_id, alloc, section_name) } }; @@ -421,7 +433,11 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant // Don't push a `TodoItem::Static` here, as it will cause statics used by // multiple crates to be duplicated between them. It isn't necessary anyway, // as it will get pushed by `codegen_static` when necessary. - data_id_for_static(tcx, module, def_id, false) + data_id_for_static( + tcx, module, def_id, false, + // For a declaration the stated mutability doesn't matter. + false, + ) } }; From e46114fdc880cded537697a25ba0cf04f242ca82 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Fri, 15 Mar 2024 14:13:11 -0400 Subject: [PATCH 02/40] Handle calls to upstream monomorphizations in compiler_builtins --- src/abi/mod.rs | 14 ++++++++++++++ src/base.rs | 7 +++++++ src/lib.rs | 1 + 3 files changed, 22 insertions(+) diff --git a/src/abi/mod.rs b/src/abi/mod.rs index 6e846d721f2e2..b33587f8948b9 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -8,8 +8,11 @@ use std::borrow::Cow; use cranelift_codegen::ir::SigRef; use cranelift_module::ModuleError; +use rustc_codegen_ssa::errors::CompilerBuiltinsCannotCall; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::ty::layout::FnAbiOf; +use rustc_middle::ty::print::with_no_trimmed_paths; +use rustc_monomorphize::is_call_from_compiler_builtins_to_upstream_monomorphization; use rustc_session::Session; use rustc_span::source_map::Spanned; use rustc_target::abi::call::{Conv, FnAbi}; @@ -372,6 +375,17 @@ pub(crate) fn codegen_terminator_call<'tcx>( ty::Instance::expect_resolve(fx.tcx, ty::ParamEnv::reveal_all(), def_id, fn_args) .polymorphize(fx.tcx); + if is_call_from_compiler_builtins_to_upstream_monomorphization(fx.tcx, instance) { + if target.is_some() { + let caller = with_no_trimmed_paths!(fx.tcx.def_path_str(fx.instance.def_id())); + let callee = with_no_trimmed_paths!(fx.tcx.def_path_str(def_id)); + fx.tcx.dcx().emit_err(CompilerBuiltinsCannotCall { caller, callee }); + } else { + fx.bcx.ins().trap(TrapCode::User(0)); + return; + } + } + if fx.tcx.symbol_name(instance).name.starts_with("llvm.") { crate::intrinsics::codegen_llvm_intrinsic_call( fx, diff --git a/src/base.rs b/src/base.rs index 2415c2c90b22c..047dc56a32ead 100644 --- a/src/base.rs +++ b/src/base.rs @@ -8,6 +8,7 @@ use rustc_index::IndexVec; use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::layout::FnAbiOf; use rustc_middle::ty::print::with_no_trimmed_paths; +use rustc_monomorphize::is_call_from_compiler_builtins_to_upstream_monomorphization; use crate::constant::ConstantCx; use crate::debuginfo::FunctionDebugContext; @@ -999,6 +1000,12 @@ fn codegen_panic_inner<'tcx>( let def_id = fx.tcx.require_lang_item(lang_item, span); let instance = Instance::mono(fx.tcx, def_id).polymorphize(fx.tcx); + + if is_call_from_compiler_builtins_to_upstream_monomorphization(fx.tcx, instance) { + fx.bcx.ins().trap(TrapCode::User(0)); + return; + } + let symbol_name = fx.tcx.symbol_name(instance).name; fx.lib_call( diff --git a/src/lib.rs b/src/lib.rs index 7e2e1f7c6ac07..a59a39074f8c0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -21,6 +21,7 @@ extern crate rustc_hir; extern crate rustc_incremental; extern crate rustc_index; extern crate rustc_metadata; +extern crate rustc_monomorphize; extern crate rustc_session; extern crate rustc_span; extern crate rustc_target; From eeca87b8c7316c017f50b4e22b47164926ef24fe Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 14 Mar 2024 09:10:28 +0000 Subject: [PATCH 03/40] Avoid various uses of `Option` in favor of using `DUMMY_SP` in the few cases that used `None` --- src/constant.rs | 2 +- src/intrinsics/mod.rs | 6 ++++-- src/intrinsics/simd.rs | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/constant.rs b/src/constant.rs index 39fa277fedc55..fc9b0f6ef024f 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -74,7 +74,7 @@ pub(crate) fn eval_mir_constant<'tcx>( let cv = fx.monomorphize(constant.const_); // This cannot fail because we checked all required_consts in advance. let val = cv - .eval(fx.tcx, ty::ParamEnv::reveal_all(), Some(constant.span)) + .eval(fx.tcx, ty::ParamEnv::reveal_all(), constant.span) .expect("erroneous constant missed by mono item collection"); (val, cv.ty()) } diff --git a/src/intrinsics/mod.rs b/src/intrinsics/mod.rs index 8b86a116df1fd..c802d9bbefbed 100644 --- a/src/intrinsics/mod.rs +++ b/src/intrinsics/mod.rs @@ -728,8 +728,10 @@ fn codegen_regular_intrinsic_call<'tcx>( | sym::variant_count => { intrinsic_args!(fx, args => (); intrinsic); - let const_val = - fx.tcx.const_eval_instance(ParamEnv::reveal_all(), instance, None).unwrap(); + let const_val = fx + .tcx + .const_eval_instance(ParamEnv::reveal_all(), instance, source_info.span) + .unwrap(); let val = crate::constant::codegen_const_value(fx, const_val, ret.layout().ty); ret.write_cvalue(fx, val); } diff --git a/src/intrinsics/simd.rs b/src/intrinsics/simd.rs index 79da970a58efe..4d55a95aa9db7 100644 --- a/src/intrinsics/simd.rs +++ b/src/intrinsics/simd.rs @@ -131,7 +131,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( let idx = generic_args[2] .expect_const() - .eval(fx.tcx, ty::ParamEnv::reveal_all(), Some(span)) + .eval(fx.tcx, ty::ParamEnv::reveal_all(), span) .unwrap() .unwrap_branch(); From 1aac27e6b6f0a3cb86434803cd7a2535c7587f82 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 18 Mar 2024 13:59:53 +0000 Subject: [PATCH 04/40] Rustup to rustc 1.79.0-nightly (eb45c8444 2024-03-17) --- patches/0022-coretests-Disable-not-compiling-tests.patch | 2 +- rust-toolchain | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/patches/0022-coretests-Disable-not-compiling-tests.patch b/patches/0022-coretests-Disable-not-compiling-tests.patch index 5442c3cef9ec2..7cf7f86700eaf 100644 --- a/patches/0022-coretests-Disable-not-compiling-tests.patch +++ b/patches/0022-coretests-Disable-not-compiling-tests.patch @@ -39,6 +39,6 @@ index 42a26ae..5ac1042 100644 +#![cfg(test)] #![feature(alloc_layout_extra)] #![feature(array_chunks)] - #![feature(array_windows)] + #![feature(array_ptr_get)] -- 2.21.0 (Apple Git-122) diff --git a/rust-toolchain b/rust-toolchain index f3cd4cbe49354..31aec1131e528 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-03-16" +channel = "nightly-2024-03-18" components = ["rust-src", "rustc-dev", "llvm-tools"] From b64079d6313446bbb40cf6c467c1e2d068f8f682 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 18 Mar 2024 14:08:59 +0000 Subject: [PATCH 05/40] Re-enable rmake.rs tests as a compiletest bug has been fixed --- scripts/test_rustc_tests.sh | 8 -------- 1 file changed, 8 deletions(-) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 9b360fb303624..b7808b6f4c3de 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -10,14 +10,6 @@ pushd rust command -v rg >/dev/null 2>&1 || cargo install ripgrep -# FIXME(rust-lang/rust#122196) fix stage0 rmake.rs run-make tests and remove -# this workaround -for test in $(ls tests/run-make); do - if [[ -e "tests/run-make/$test/rmake.rs" ]]; then - rm -r "tests/run-make/$test" - fi -done - # FIXME remove this workaround once ICE tests no longer emit an outdated nightly message for test in $(rg -i --files-with-matches "//@(\[.*\])? failure-status: 101" tests/ui); do echo "rm $test" From c49f6080629e4e0b788a8b58225e1ba35a3dbf1e Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 18 Mar 2024 15:10:23 +0000 Subject: [PATCH 06/40] Several refactorings to constant.rs * Move the done hash set from ConstantCx to define_all_allocs. * Move check if alloc has already been defined to the start of the loop. * Extract helper function for vtables. --- src/constant.rs | 50 +++++++++++++++++++++++++------------------------ src/vtable.rs | 8 +++----- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/constant.rs b/src/constant.rs index 39fa277fedc55..737406a0d4ab6 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -6,17 +6,16 @@ use cranelift_module::*; use rustc_data_structures::fx::FxHashSet; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::mir::interpret::{read_target_uint, AllocId, GlobalAlloc, Scalar}; -use rustc_middle::ty::ScalarInt; +use rustc_middle::ty::{Binder, ExistentialTraitRef, ScalarInt}; use crate::prelude::*; pub(crate) struct ConstantCx { todo: Vec, - done: FxHashSet, anon_allocs: FxHashMap, } -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] enum TodoItem { Alloc(AllocId), Static(DefId), @@ -24,12 +23,11 @@ enum TodoItem { impl ConstantCx { pub(crate) fn new() -> Self { - ConstantCx { todo: vec![], done: FxHashSet::default(), anon_allocs: FxHashMap::default() } + ConstantCx { todo: vec![], anon_allocs: FxHashMap::default() } } pub(crate) fn finalize(mut self, tcx: TyCtxt<'_>, module: &mut dyn Module) { define_all_allocs(tcx, module, &mut self); - self.done.clear(); } } @@ -153,14 +151,12 @@ pub(crate) fn codegen_const_value<'tcx>( fx.bcx.ins().func_addr(fx.pointer_type, local_func_id) } GlobalAlloc::VTable(ty, trait_ref) => { - let alloc_id = fx.tcx.vtable_allocation((ty, trait_ref)); - let alloc = fx.tcx.global_alloc(alloc_id).unwrap_memory(); - // FIXME: factor this common code with the `Memory` arm into a function? - let data_id = data_id_for_alloc_id( + let data_id = data_id_for_vtable( + fx.tcx, &mut fx.constants_cx, fx.module, - alloc_id, - alloc.inner().mutability, + ty, + trait_ref, ); let local_data_id = fx.module.declare_data_in_func(data_id, &mut fx.bcx.func); @@ -208,12 +204,8 @@ fn pointer_for_allocation<'tcx>( alloc_id: AllocId, ) -> crate::pointer::Pointer { let alloc = fx.tcx.global_alloc(alloc_id).unwrap_memory(); - let data_id = data_id_for_alloc_id( - &mut fx.constants_cx, - &mut *fx.module, - alloc_id, - alloc.inner().mutability, - ); + let data_id = + data_id_for_alloc_id(&mut fx.constants_cx, fx.module, alloc_id, alloc.inner().mutability); let local_data_id = fx.module.declare_data_in_func(data_id, &mut fx.bcx.func); if fx.clif_comments.enabled() { @@ -235,6 +227,17 @@ pub(crate) fn data_id_for_alloc_id( .or_insert_with(|| module.declare_anonymous_data(mutability.is_mut(), false).unwrap()) } +pub(crate) fn data_id_for_vtable<'tcx>( + tcx: TyCtxt<'tcx>, + cx: &mut ConstantCx, + module: &mut dyn Module, + ty: Ty<'tcx>, + trait_ref: Option>>, +) -> DataId { + let alloc_id = tcx.vtable_allocation((ty, trait_ref)); + data_id_for_alloc_id(cx, module, alloc_id, Mutability::Not) +} + fn data_id_for_static( tcx: TyCtxt<'_>, module: &mut dyn Module, @@ -327,7 +330,12 @@ fn data_id_for_static( } fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut ConstantCx) { + let mut done = FxHashSet::default(); while let Some(todo_item) = cx.todo.pop() { + if !done.insert(todo_item) { + continue; + } + let (data_id, alloc, section_name) = match todo_item { TodoItem::Alloc(alloc_id) => { let alloc = match tcx.global_alloc(alloc_id) { @@ -358,10 +366,6 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant } }; - if cx.done.contains(&data_id) { - continue; - } - let mut data = DataDescription::new(); let alloc = alloc.inner(); data.set_align(alloc.align.bytes()); @@ -418,8 +422,7 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant data_id_for_alloc_id(cx, module, alloc_id, target_alloc.inner().mutability) } GlobalAlloc::VTable(ty, trait_ref) => { - let alloc_id = tcx.vtable_allocation((ty, trait_ref)); - data_id_for_alloc_id(cx, module, alloc_id, Mutability::Not) + data_id_for_vtable(tcx, cx, module, ty, trait_ref) } GlobalAlloc::Static(def_id) => { if tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::THREAD_LOCAL) @@ -446,7 +449,6 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant } module.define_data(data_id, &data).unwrap(); - cx.done.insert(data_id); } assert!(cx.todo.is_empty(), "{:?}", cx.todo); diff --git a/src/vtable.rs b/src/vtable.rs index d2254d4c15e6f..86ebf37d105f6 100644 --- a/src/vtable.rs +++ b/src/vtable.rs @@ -2,7 +2,7 @@ //! //! See `rustc_codegen_ssa/src/meth.rs` for reference. -use crate::constant::data_id_for_alloc_id; +use crate::constant::data_id_for_vtable; use crate::prelude::*; pub(crate) fn vtable_memflags() -> MemFlags { @@ -92,12 +92,10 @@ pub(crate) fn get_vtable<'tcx>( ty: Ty<'tcx>, trait_ref: Option>, ) -> Value { - let alloc_id = fx.tcx.vtable_allocation((ty, trait_ref)); - let data_id = - data_id_for_alloc_id(&mut fx.constants_cx, &mut *fx.module, alloc_id, Mutability::Not); + let data_id = data_id_for_vtable(fx.tcx, &mut fx.constants_cx, fx.module, ty, trait_ref); let local_data_id = fx.module.declare_data_in_func(data_id, fx.bcx.func); if fx.clif_comments.enabled() { - fx.add_comment(local_data_id, format!("vtable: {:?}", alloc_id)); + fx.add_comment(local_data_id, "vtable"); } fx.bcx.ins().global_value(fx.pointer_type, local_data_id) } From 06ef32c86251ba3a54ced4d8bf074f95ee30bc62 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 5 Mar 2024 17:50:07 +0000 Subject: [PATCH 07/40] Make ptr_guaranteed_cmp a rustc_intrinsic and favor its body over backends implementing it --- src/intrinsics/mod.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/intrinsics/mod.rs b/src/intrinsics/mod.rs index c802d9bbefbed..25694af78f17e 100644 --- a/src/intrinsics/mod.rs +++ b/src/intrinsics/mod.rs @@ -757,13 +757,6 @@ fn codegen_regular_intrinsic_call<'tcx>( ret.write_cvalue(fx, val); } - sym::ptr_guaranteed_cmp => { - intrinsic_args!(fx, args => (a, b); intrinsic); - - let val = crate::num::codegen_ptr_binop(fx, BinOp::Eq, a, b).load_scalar(fx); - ret.write_cvalue(fx, CValue::by_val(val, fx.layout_of(fx.tcx.types.u8))); - } - sym::caller_location => { intrinsic_args!(fx, args => (); intrinsic); From eb752bc6a79e13eb779eeeba7f589aef58f80e9f Mon Sep 17 00:00:00 2001 From: BeetleFunk <124721033+BeetleFunk@users.noreply.github.com> Date: Thu, 21 Mar 2024 11:59:03 -0400 Subject: [PATCH 08/40] Avoid ICE when global_asm const operand fails to evaluate --- src/global_asm.rs | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/src/global_asm.rs b/src/global_asm.rs index 44650898de897..5a0cd3990f2a7 100644 --- a/src/global_asm.rs +++ b/src/global_asm.rs @@ -8,6 +8,7 @@ use std::sync::Arc; use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_hir::{InlineAsmOperand, ItemId}; +use rustc_middle::mir::interpret::ErrorHandled; use rustc_session::config::{OutputFilenames, OutputType}; use rustc_target::asm::InlineAsmArch; @@ -32,18 +33,27 @@ pub(crate) fn codegen_global_asm_item(tcx: TyCtxt<'_>, global_asm: &mut String, InlineAsmTemplatePiece::Placeholder { operand_idx, modifier: _, span: op_sp } => { match asm.operands[operand_idx].0 { InlineAsmOperand::Const { ref anon_const } => { - let const_value = - tcx.const_eval_poly(anon_const.def_id.to_def_id()).unwrap_or_else( - |_| span_bug!(op_sp, "asm const cannot be resolved"), - ); - let ty = tcx.typeck_body(anon_const.body).node_type(anon_const.hir_id); - let string = rustc_codegen_ssa::common::asm_const_to_str( - tcx, - op_sp, - const_value, - RevealAllLayoutCx(tcx).layout_of(ty), - ); - global_asm.push_str(&string); + match tcx.const_eval_poly(anon_const.def_id.to_def_id()) { + Ok(const_value) => { + let ty = tcx + .typeck_body(anon_const.body) + .node_type(anon_const.hir_id); + let string = rustc_codegen_ssa::common::asm_const_to_str( + tcx, + op_sp, + const_value, + RevealAllLayoutCx(tcx).layout_of(ty), + ); + global_asm.push_str(&string); + } + Err(ErrorHandled::Reported { .. }) => { + // An error has already been reported and compilation is + // guaranteed to fail if execution hits this path. + } + Err(ErrorHandled::TooGeneric(_)) => { + span_bug!(op_sp, "asm const cannot be resolved; too generic"); + } + } } InlineAsmOperand::SymFn { anon_const } => { if cfg!(not(feature = "inline_asm_sym")) { From dfc1bd751674a3715221a8bb6791043d1a2e0664 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 21 Mar 2024 16:50:21 -0400 Subject: [PATCH 09/40] Eagerly convert some ctors to use their specialized ctors --- src/abi/mod.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/abi/mod.rs b/src/abi/mod.rs index 6e846d721f2e2..cdfbbe7b6744d 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -663,11 +663,7 @@ pub(crate) fn codegen_drop<'tcx>( let arg_value = drop_place.place_ref( fx, - fx.layout_of(Ty::new_ref( - fx.tcx, - fx.tcx.lifetimes.re_erased, - TypeAndMut { ty, mutbl: crate::rustc_hir::Mutability::Mut }, - )), + fx.layout_of(Ty::new_mut_ref(fx.tcx, fx.tcx.lifetimes.re_erased, ty)), ); let arg_value = adjust_arg_for_abi(fx, arg_value, &fn_abi.args[0], true); From 155b46aeb2076c622965204a5aa84a32e2c32a55 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 21 Mar 2024 17:11:06 -0400 Subject: [PATCH 10/40] Programmatically convert some of the pat ctors --- src/common.rs | 4 ++-- src/unsize.rs | 6 ++---- src/value_and_place.rs | 9 ++------- 3 files changed, 6 insertions(+), 13 deletions(-) diff --git a/src/common.rs b/src/common.rs index 7e29d407a1fa3..a7c3d68ff8cfb 100644 --- a/src/common.rs +++ b/src/common.rs @@ -69,7 +69,7 @@ fn clif_type_from_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option unimplemented!("f16_f128"), }, ty::FnPtr(_) => pointer_ty(tcx), - ty::RawPtr(TypeAndMut { ty: pointee_ty, mutbl: _ }) | ty::Ref(_, pointee_ty, _) => { + ty::RawPtr(pointee_ty, _) | ty::Ref(_, pointee_ty, _) => { if has_ptr_meta(tcx, *pointee_ty) { return None; } else { @@ -89,7 +89,7 @@ fn clif_pair_type_from_ty<'tcx>( ty::Tuple(types) if types.len() == 2 => { (clif_type_from_ty(tcx, types[0])?, clif_type_from_ty(tcx, types[1])?) } - ty::RawPtr(TypeAndMut { ty: pointee_ty, mutbl: _ }) | ty::Ref(_, pointee_ty, _) => { + ty::RawPtr(pointee_ty, _) | ty::Ref(_, pointee_ty, _) => { if has_ptr_meta(tcx, *pointee_ty) { (pointer_ty(tcx), pointer_ty(tcx)) } else { diff --git a/src/unsize.rs b/src/unsize.rs index 7b61dc64cb1ae..f33bacb99a3fa 100644 --- a/src/unsize.rs +++ b/src/unsize.rs @@ -70,10 +70,8 @@ fn unsize_ptr<'tcx>( ) -> (Value, Value) { match (&src_layout.ty.kind(), &dst_layout.ty.kind()) { (&ty::Ref(_, a, _), &ty::Ref(_, b, _)) - | (&ty::Ref(_, a, _), &ty::RawPtr(ty::TypeAndMut { ty: b, .. })) - | (&ty::RawPtr(ty::TypeAndMut { ty: a, .. }), &ty::RawPtr(ty::TypeAndMut { ty: b, .. })) => { - (src, unsized_info(fx, *a, *b, old_info)) - } + | (&ty::Ref(_, a, _), &ty::RawPtr(b, _)) + | (&ty::RawPtr(a, _), &ty::RawPtr(b, _)) => (src, unsized_info(fx, *a, *b, old_info)), (&ty::Adt(def_a, _), &ty::Adt(def_b, _)) => { assert_eq!(def_a, def_b); diff --git a/src/value_and_place.rs b/src/value_and_place.rs index f016e6950d48d..fc5b88a54fe5a 100644 --- a/src/value_and_place.rs +++ b/src/value_and_place.rs @@ -865,15 +865,10 @@ pub(crate) fn assert_assignable<'tcx>( return; } match (from_ty.kind(), to_ty.kind()) { - (ty::Ref(_, a, _), ty::Ref(_, b, _)) - | ( - ty::RawPtr(TypeAndMut { ty: a, mutbl: _ }), - ty::RawPtr(TypeAndMut { ty: b, mutbl: _ }), - ) => { + (ty::Ref(_, a, _), ty::Ref(_, b, _)) | (ty::RawPtr(a, _), ty::RawPtr(b, _)) => { assert_assignable(fx, *a, *b, limit - 1); } - (ty::Ref(_, a, _), ty::RawPtr(TypeAndMut { ty: b, mutbl: _ })) - | (ty::RawPtr(TypeAndMut { ty: a, mutbl: _ }), ty::Ref(_, b, _)) => { + (ty::Ref(_, a, _), ty::RawPtr(b, _)) | (ty::RawPtr(a, _), ty::Ref(_, b, _)) => { assert_assignable(fx, *a, *b, limit - 1); } (ty::FnPtr(_), ty::FnPtr(_)) => { From ae0e6e22f09fbfbcf7b1252d80c90ad8a423e10d Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 22 Mar 2024 18:34:00 +0000 Subject: [PATCH 11/40] Update to Cranelift 0.106 --- Cargo.lock | 56 +++++++++++++++++++++++++++--------------------------- Cargo.toml | 12 ++++++------ 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e308cf80284ad..8fdc1941de88f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -46,18 +46,18 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cranelift-bforest" -version = "0.105.2" +version = "0.106.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9515fcc42b6cb5137f76b84c1a6f819782d0cf12473d145d3bc5cd67eedc8bc2" +checksum = "6a535eb1cf5a6003197dc569320c40c1cb2d2f97ef5d5348eebf067f20957381" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-codegen" -version = "0.105.2" +version = "0.106.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad827c6071bfe6d22de1bc331296a29f9ddc506ff926d8415b435ec6a6efce0" +checksum = "11b5066db32cec1492573827183af2142d2d88fe85a83cfc9e73f0f63d3788d4" dependencies = [ "bumpalo", "cranelift-bforest", @@ -76,39 +76,39 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" -version = "0.105.2" +version = "0.106.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10e6b36237a9ca2ce2fb4cc7741d418a080afa1327402138412ef85d5367bef1" +checksum = "64942e5774308e835fbad4dd25f253105412c90324631910e1ec27963147bddb" dependencies = [ "cranelift-codegen-shared", ] [[package]] name = "cranelift-codegen-shared" -version = "0.105.2" +version = "0.106.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c36bf4bfb86898a94ccfa773a1f86e8a5346b1983ff72059bdd2db4600325251" +checksum = "c39c33db9a86dd6d8d04166a10c53deb477aeea3500eaaefca682e4eda9bb986" [[package]] name = "cranelift-control" -version = "0.105.2" +version = "0.106.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cbf36560e7a6bd1409ca91e7b43b2cc7ed8429f343d7605eadf9046e8fac0d0" +checksum = "4b7fc4937613aea3156a0538800a17bf56f345a5da2e79ae3df58488c93d867f" dependencies = [ "arbitrary", ] [[package]] name = "cranelift-entity" -version = "0.105.2" +version = "0.106.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a71e11061a75b1184c09bea97c026a88f08b59ade96a7bb1f259d4ea0df2e942" +checksum = "f85575e79a153ce1ddbfb7fe1813519b4bfe1eb200cc9c8353b45ad123ae4d36" [[package]] name = "cranelift-frontend" -version = "0.105.2" +version = "0.106.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af5d4da63143ee3485c7bcedde0a818727d737d1083484a0ceedb8950c89e495" +checksum = "bbc31d6c0ab2249fe0c21e988256b42f5f401ab2673b4fc40076c82a698bdfb9" dependencies = [ "cranelift-codegen", "log", @@ -118,15 +118,15 @@ dependencies = [ [[package]] name = "cranelift-isle" -version = "0.105.2" +version = "0.106.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "457a9832b089e26f5eea70dcf49bed8ec6edafed630ce7c83161f24d46ab8085" +checksum = "dc14f37e3314c0e4c53779c2f46753bf242efff76ee9473757a1fff3b495ad37" [[package]] name = "cranelift-jit" -version = "0.105.2" +version = "0.106.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0af95fe68d5a10919012c8db82b1d59820405b8001c8c6d05f94b08031334fa9" +checksum = "cfdd1942f3233176a68c285380dbc84ff0440246a1bce308611c0a385b56ab18" dependencies = [ "anyhow", "cranelift-codegen", @@ -144,9 +144,9 @@ dependencies = [ [[package]] name = "cranelift-module" -version = "0.105.2" +version = "0.106.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11b0b201fa10a4014062d4c56c307c8d18fdf9a84cb5279efe6080241f42c7a7" +checksum = "121b2b5a16912554a1b9aace75b9b21eca49f28e33cbfbad4786dd9bc5361a5c" dependencies = [ "anyhow", "cranelift-codegen", @@ -155,9 +155,9 @@ dependencies = [ [[package]] name = "cranelift-native" -version = "0.105.2" +version = "0.106.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b490d579df1ce365e1ea359e24ed86d82289fa785153327c2f6a69a59a731e4" +checksum = "2ea5375f76ab31f9800a23fb2b440810286a6f669a3eb467cdd7ff255ea64268" dependencies = [ "cranelift-codegen", "libc", @@ -166,9 +166,9 @@ dependencies = [ [[package]] name = "cranelift-object" -version = "0.105.2" +version = "0.106.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb7e821ac6db471bcdbd004e5a4fa0d374f1046bd3a2ce278c332e0b0c01ca63" +checksum = "f34e04419ab41661e973d90a73aa7b12771455394dae7a69b101a9b7e7589db7" dependencies = [ "anyhow", "cranelift-codegen", @@ -392,9 +392,9 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.12.12" +version = "0.12.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c39fd04924ca3a864207c66fc2cd7d22d7c016007f9ce846cbb9326331930a" +checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f" [[package]] name = "unicode-ident" @@ -410,9 +410,9 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "wasmtime-jit-icache-coherence" -version = "18.0.2" +version = "19.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33f4121cb29dda08139b2824a734dd095d83ce843f2d613a84eb580b9cfc17ac" +checksum = "2796e4b4989db62899d2117e1e0258b839d088c044591b14e3a0396e7b3ae53a" dependencies = [ "cfg-if", "libc", diff --git a/Cargo.toml b/Cargo.toml index c0b9e27b179d3..d8a855b038307 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,12 +8,12 @@ crate-type = ["dylib"] [dependencies] # These have to be in sync with each other -cranelift-codegen = { version = "0.105.2", default-features = false, features = ["std", "unwind", "all-arch"] } -cranelift-frontend = { version = "0.105.2" } -cranelift-module = { version = "0.105.2" } -cranelift-native = { version = "0.105.2" } -cranelift-jit = { version = "0.105.2", optional = true } -cranelift-object = { version = "0.105.2" } +cranelift-codegen = { version = "0.106.0", default-features = false, features = ["std", "unwind", "all-arch"] } +cranelift-frontend = { version = "0.106.0" } +cranelift-module = { version = "0.106.0" } +cranelift-native = { version = "0.106.0" } +cranelift-jit = { version = "0.106.0", optional = true } +cranelift-object = { version = "0.106.0" } target-lexicon = "0.12.0" gimli = { version = "0.28", default-features = false, features = ["write"]} object = { version = "0.32", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] } From e2cc8ebd87da39cef9dde3ab209826a1f5880b5a Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 22 Mar 2024 18:51:59 +0000 Subject: [PATCH 12/40] Rustup to rustc 1.79.0-nightly (0ad927c0c 2024-03-21) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 31aec1131e528..1901f699b9dc1 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-03-18" +channel = "nightly-2024-03-22" components = ["rust-src", "rustc-dev", "llvm-tools"] From 593228373d175650bb1033814f515df2e15a489d Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 22 Mar 2024 18:58:36 +0000 Subject: [PATCH 13/40] Remove workaround for UB in cranelift-jit that has been fixed --- src/constant.rs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/constant.rs b/src/constant.rs index c400059939411..690e8fe0e20ae 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -388,13 +388,7 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant } let bytes = alloc.inspect_with_uninit_and_ptr_outside_interpreter(0..alloc.len()).to_vec(); - if bytes.is_empty() { - // FIXME(bytecodealliance/wasmtime#7918) cranelift-jit has a bug where it causes UB on - // empty data objects - data.define(Box::new([0])); - } else { - data.define(bytes.into_boxed_slice()); - } + data.define(bytes.into_boxed_slice()); for &(offset, prov) in alloc.provenance().ptrs().iter() { let alloc_id = prov.alloc_id(); From a517adc66e30b695dc96778d1699dd17751e6cec Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 17 Mar 2024 10:12:25 +0100 Subject: [PATCH 14/40] move assert_unsafe_preconditions to its own file These macros and functions are not intrinsics, after all. --- src/base.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/base.rs b/src/base.rs index 047dc56a32ead..dbce6d165d2d3 100644 --- a/src/base.rs +++ b/src/base.rs @@ -780,7 +780,7 @@ fn codegen_stmt<'tcx>( NullOp::OffsetOf(fields) => { layout.offset_of_subfield(fx, fields.iter()).bytes() } - NullOp::UbCheck(_) => { + NullOp::UbChecks => { let val = fx.tcx.sess.opts.debug_assertions; let val = CValue::by_val( fx.bcx.ins().iconst(types::I8, i64::try_from(val).unwrap()), From 4609a48d6a0f9bfcedcf622e19646cc2400fa98f Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 24 Mar 2024 21:42:32 -0400 Subject: [PATCH 15/40] Add async-closures/once.rs back to cranelift tests --- scripts/test_rustc_tests.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 9b360fb303624..fcf3ba0357487 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -154,7 +154,6 @@ rm tests/ui/codegen/subtyping-enforces-type-equality.rs # assert_assignable bug # ====================== rm tests/ui/backtrace.rs # TODO warning rm tests/ui/process/nofile-limit.rs # TODO some AArch64 linking issue -rm tests/ui/async-await/async-closures/once.rs # FIXME bug in the rustc FnAbi calculation code rm tests/ui/stdio-is-blocking.rs # really slow with unoptimized libstd From 0231d65cec8e6e48a0e46f1e285901f743d05896 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 25 Mar 2024 14:05:11 +0000 Subject: [PATCH 16/40] Rustup to rustc 1.79.0-nightly (0824b300e 2024-03-24) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 1901f699b9dc1..3845b57b91d02 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-03-22" +channel = "nightly-2024-03-25" components = ["rust-src", "rustc-dev", "llvm-tools"] From c53025b45d741955fee5c1bb25fdee25676abe96 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 25 Mar 2024 14:19:07 +0000 Subject: [PATCH 17/40] Add needs-unwind annotations to a couple of tests --- scripts/test_rustc_tests.sh | 6 ------ 1 file changed, 6 deletions(-) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 9b360fb303624..7f47fd972c44d 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -41,12 +41,6 @@ rm tests/ui/parser/unclosed-delimiter-in-dep.rs # submodule contains //~ERROR # missing features # ================ -# requires stack unwinding -# FIXME add needs-unwind to these tests -rm -r tests/run-make/libtest-junit -rm tests/ui/asm/may_unwind.rs -rm tests/ui/stable-mir-print/basic_function.rs - # extra warning about -Cpanic=abort for proc macros rm tests/ui/proc-macro/crt-static.rs rm tests/ui/proc-macro/proc-macro-deprecated-attr.rs From 187decaf18a2ceb9d1e8e04bd273de807318526b Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 25 Mar 2024 14:29:11 +0000 Subject: [PATCH 18/40] Fix rustc test suite --- scripts/test_rustc_tests.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index b7808b6f4c3de..d3d1477bdecc5 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -123,6 +123,7 @@ rm -r tests/run-make/issue-88756-default-output # should work when using ./x.py test the way it is intended # ============================================================ rm -r tests/run-make/remap-path-prefix-dwarf # requires llvm-dwarfdump +rm -r tests/run-make/compiler-builtins # Expects lib/rustlib/src/rust to contains the standard library source # genuine bugs # ============ From 654ce59f701b05fb15ef6c009988a4d0fc4b34c4 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 25 Mar 2024 14:41:19 +0000 Subject: [PATCH 19/40] Remove ignore for fixed rustc test --- scripts/test_rustc_tests.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index d3d1477bdecc5..7e4a1a5c787b6 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -49,7 +49,6 @@ rm tests/ui/proc-macro/allowed-signatures.rs rm tests/ui/proc-macro/no-mangle-in-proc-macro-issue-111888.rs # vendor intrinsics -rm tests/ui/simd/array-type.rs # "Index argument for `simd_insert` is not a constant" rm tests/ui/asm/x86_64/evex512-implicit-feature.rs # unimplemented AVX512 x86 vendor intrinsic # exotic linkages From 49777c3bfacc927b8c0771217b027d9ee287b6dc Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 25 Mar 2024 14:24:08 +0000 Subject: [PATCH 20/40] Add needs-unwind for proc macro tests Rustc gives a warning when compiling proc macros with panic=abort. --- scripts/test_rustc_tests.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 7f47fd972c44d..b6651fa28919b 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -41,15 +41,6 @@ rm tests/ui/parser/unclosed-delimiter-in-dep.rs # submodule contains //~ERROR # missing features # ================ -# extra warning about -Cpanic=abort for proc macros -rm tests/ui/proc-macro/crt-static.rs -rm tests/ui/proc-macro/proc-macro-deprecated-attr.rs -rm tests/ui/proc-macro/quote-debug.rs -rm tests/ui/proc-macro/no-missing-docs.rs -rm tests/ui/rust-2018/proc-macro-crate-in-paths.rs -rm tests/ui/proc-macro/allowed-signatures.rs -rm tests/ui/proc-macro/no-mangle-in-proc-macro-issue-111888.rs - # vendor intrinsics rm tests/ui/simd/array-type.rs # "Index argument for `simd_insert` is not a constant" rm tests/ui/asm/x86_64/evex512-implicit-feature.rs # unimplemented AVX512 x86 vendor intrinsic From 60921608f794a217be1bc923b525e4d4c5b8109b Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 26 Mar 2024 09:56:55 +0000 Subject: [PATCH 21/40] Rustup to rustc 1.79.0-nightly (5f2c7d2bf 2024-03-25) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 3845b57b91d02..e9e7f90bbb487 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-03-25" +channel = "nightly-2024-03-26" components = ["rust-src", "rustc-dev", "llvm-tools"] From dc6595ddbc94173289092d653215e4add8c666e2 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 26 Mar 2024 10:18:44 +0000 Subject: [PATCH 22/40] Implement nearbyintf32 and nearbyintf64 and remove two test ignores --- scripts/test_rustc_tests.sh | 3 --- src/intrinsics/mod.rs | 5 +++++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 3a28e1d53b753..63f4ef9464a15 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -50,7 +50,6 @@ rm -r tests/run-make/c-link-to-rust-va-list-fn # requires callee side vararg sup rm -r tests/run-pass-valgrind/unsized-locals # misc unimplemented things -rm tests/ui/intrinsics/intrinsic-nearby.rs # unimplemented nearbyintf32 and nearbyintf64 intrinsics rm tests/ui/target-feature/missing-plusminus.rs # error not implemented rm -r tests/run-make/emit-named-files # requires full --emit support rm -r tests/run-make/repr128-dwarf # debuginfo test @@ -125,8 +124,6 @@ rm -r tests/run-make/compressed-debuginfo rm -r tests/run-make/extern-fn-explicit-align # argument alignment not yet supported -rm tests/ui/codegen/subtyping-enforces-type-equality.rs # assert_assignable bug with Coroutine's - # bugs in the test suite # ====================== rm tests/ui/backtrace.rs # TODO warning diff --git a/src/intrinsics/mod.rs b/src/intrinsics/mod.rs index 25694af78f17e..0b213ff826969 100644 --- a/src/intrinsics/mod.rs +++ b/src/intrinsics/mod.rs @@ -341,6 +341,8 @@ fn codegen_float_intrinsic_call<'tcx>( sym::roundf64 => ("round", 1, fx.tcx.types.f64, types::F64), sym::roundevenf32 => ("roundevenf", 1, fx.tcx.types.f32, types::F32), sym::roundevenf64 => ("roundeven", 1, fx.tcx.types.f64, types::F64), + sym::nearbyintf32 => ("nearbyintf", 1, fx.tcx.types.f32, types::F32), + sym::nearbyintf64 => ("nearbyint", 1, fx.tcx.types.f64, types::F64), sym::sinf32 => ("sinf", 1, fx.tcx.types.f32, types::F32), sym::sinf64 => ("sin", 1, fx.tcx.types.f64, types::F64), sym::cosf32 => ("cosf", 1, fx.tcx.types.f32, types::F32), @@ -392,6 +394,8 @@ fn codegen_float_intrinsic_call<'tcx>( | sym::ceilf64 | sym::truncf32 | sym::truncf64 + | sym::nearbyintf32 + | sym::nearbyintf64 | sym::sqrtf32 | sym::sqrtf64 => { let val = match intrinsic { @@ -399,6 +403,7 @@ fn codegen_float_intrinsic_call<'tcx>( sym::floorf32 | sym::floorf64 => fx.bcx.ins().floor(args[0]), sym::ceilf32 | sym::ceilf64 => fx.bcx.ins().ceil(args[0]), sym::truncf32 | sym::truncf64 => fx.bcx.ins().trunc(args[0]), + sym::nearbyintf32 | sym::nearbyintf64 => fx.bcx.ins().nearest(args[0]), sym::sqrtf32 | sym::sqrtf64 => fx.bcx.ins().sqrt(args[0]), _ => unreachable!(), }; From ad1886a5f0a6a56e9ee9c22ca80e1bcd27d4edd8 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 26 Mar 2024 10:27:19 +0000 Subject: [PATCH 23/40] Fix rustdoc help message when no args are passed --- scripts/rustc-clif.rs | 7 ++++--- scripts/rustdoc-clif.rs | 12 +++++++++--- scripts/test_rustc_tests.sh | 3 --- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/scripts/rustc-clif.rs b/scripts/rustc-clif.rs index 550f20515536e..92defd21cd9bc 100644 --- a/scripts/rustc-clif.rs +++ b/scripts/rustc-clif.rs @@ -26,9 +26,10 @@ fn main() { codegen_backend_arg.push(cg_clif_dylib_path); args.push(codegen_backend_arg); } - if !passed_args.iter().any(|arg| { - arg == "--sysroot" || arg.to_str().is_some_and(|s| s.starts_with("--sysroot=")) - }) { + if !passed_args + .iter() + .any(|arg| arg == "--sysroot" || arg.to_str().is_some_and(|s| s.starts_with("--sysroot="))) + { args.push(OsString::from("--sysroot")); args.push(OsString::from(sysroot.to_str().unwrap())); } diff --git a/scripts/rustdoc-clif.rs b/scripts/rustdoc-clif.rs index f7d1bdbc4c6ff..1cad312bb7918 100644 --- a/scripts/rustdoc-clif.rs +++ b/scripts/rustdoc-clif.rs @@ -26,12 +26,18 @@ fn main() { codegen_backend_arg.push(cg_clif_dylib_path); args.push(codegen_backend_arg); } - if !passed_args.iter().any(|arg| { - arg == "--sysroot" || arg.to_str().is_some_and(|s| s.starts_with("--sysroot=")) - }) { + if !passed_args + .iter() + .any(|arg| arg == "--sysroot" || arg.to_str().is_some_and(|s| s.starts_with("--sysroot="))) + { args.push(OsString::from("--sysroot")); args.push(OsString::from(sysroot.to_str().unwrap())); } + if passed_args.is_empty() { + // Don't pass any arguments when the user didn't pass any arguments + // either to ensure the help message is shown. + args.clear(); + } args.extend(passed_args); let rustdoc = if let Some(rustdoc) = option_env!("RUSTDOC") { diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 63f4ef9464a15..a6f25c3f81945 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -99,9 +99,6 @@ rm tests/ui/mir/mir_raw_fat_ptr.rs # same rm tests/ui/consts/issue-33537.rs # same rm tests/ui/consts/const-mut-refs-crate.rs # same -# rustdoc-clif passes extra args, suppressing the help message when no args are passed -rm -r tests/run-make/issue-88756-default-output - # doesn't work due to the way the rustc test suite is invoked. # should work when using ./x.py test the way it is intended # ============================================================ From 23868af850dab115306f7dd7e2dcb334dd97afd4 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 26 Mar 2024 10:55:46 +0000 Subject: [PATCH 24/40] Correctly implement --emit --- scripts/test_rustc_tests.sh | 24 ++--- src/driver/aot.rs | 196 +++++++++++++++++++++++++++++++++--- src/lib.rs | 11 +- 3 files changed, 201 insertions(+), 30 deletions(-) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index a6f25c3f81945..2c1cff51014fc 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -51,10 +51,8 @@ rm -r tests/run-pass-valgrind/unsized-locals # misc unimplemented things rm tests/ui/target-feature/missing-plusminus.rs # error not implemented -rm -r tests/run-make/emit-named-files # requires full --emit support rm -r tests/run-make/repr128-dwarf # debuginfo test rm -r tests/run-make/split-debuginfo # same -rm -r tests/run-make/symbols-include-type-name # --emit=asm not supported rm -r tests/run-make/target-specs # i686 not supported by Cranelift rm -r tests/run-make/mismatching-target-triples # same rm tests/ui/asm/x86_64/issue-96797.rs # const and sym inline asm operands don't work entirely correctly @@ -92,6 +90,17 @@ rm tests/ui/abi/stack-protector.rs # requires stack protector support rm -r tests/run-make/emit-stack-sizes # requires support for -Z emit-stack-sizes rm -r tests/run-make/optimization-remarks-dir # remarks are LLVM specific +# requires asm, llvm-ir and/or llvm-bc emit support +# ============================================= +rm -r tests/run-make/emit-named-files +rm -r tests/run-make/issue-30063 +rm -r tests/run-make/multiple-emits +rm -r tests/run-make/output-type-permutations +rm -r tests/run-make/emit-to-stdout +rm -r tests/run-make/compressed-debuginfo +rm -r tests/run-make/symbols-include-type-name + + # giving different but possibly correct results # ============================================= rm tests/ui/mir/mir_misc_casts.rs # depends on deduplication of constants @@ -109,17 +118,8 @@ rm -r tests/run-make/compiler-builtins # Expects lib/rustlib/src/rust to contain # ============ rm tests/incremental/spike-neg1.rs # errors out for some reason rm tests/incremental/spike-neg2.rs # same - -rm -r tests/run-make/issue-51671 # wrong filename given in case of --emit=obj -rm -r tests/run-make/issue-30063 # same -rm -r tests/run-make/multiple-emits # same -rm -r tests/run-make/output-type-permutations # same -rm -r tests/run-make/used # same -rm -r tests/run-make/no-alloc-shim -rm -r tests/run-make/emit-to-stdout -rm -r tests/run-make/compressed-debuginfo - rm -r tests/run-make/extern-fn-explicit-align # argument alignment not yet supported +rm -r tests/run-make/panic-abort-eh_frame # .eh_frame emitted with panic=abort # bugs in the test suite # ====================== diff --git a/src/driver/aot.rs b/src/driver/aot.rs index 757082a5fed1c..4a28b2d93fabb 100644 --- a/src/driver/aot.rs +++ b/src/driver/aot.rs @@ -1,22 +1,25 @@ //! The AOT driver uses [`cranelift_object`] to write object files suitable for linking into a //! standalone executable. -use std::fs::File; -use std::path::PathBuf; +use std::fs::{self, File}; +use std::path::{Path, PathBuf}; use std::sync::Arc; use std::thread::JoinHandle; use cranelift_object::{ObjectBuilder, ObjectModule}; use rustc_codegen_ssa::assert_module_sources::CguReuse; +use rustc_codegen_ssa::back::link::ensure_removed; use rustc_codegen_ssa::back::metadata::create_compressed_metadata_file; use rustc_codegen_ssa::base::determine_cgu_reuse; +use rustc_codegen_ssa::errors as ssa_errors; use rustc_codegen_ssa::{CodegenResults, CompiledModule, CrateInfo, ModuleKind}; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_metadata::fs::copy_to_stdout; use rustc_metadata::EncodedMetadata; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; use rustc_middle::mir::mono::{CodegenUnit, MonoItem}; -use rustc_session::config::{DebugInfo, OutputFilenames, OutputType}; +use rustc_session::config::{DebugInfo, OutFileName, OutputFilenames, OutputType}; use rustc_session::Session; use crate::concurrency_limiter::{ConcurrencyLimiter, ConcurrencyLimiterToken}; @@ -53,6 +56,7 @@ impl OngoingCodegen { pub(crate) fn join( self, sess: &Session, + outputs: &OutputFilenames, backend_config: &BackendConfig, ) -> (CodegenResults, FxIndexMap) { let mut work_products = FxIndexMap::default(); @@ -110,17 +114,183 @@ impl OngoingCodegen { sess.dcx().abort_if_errors(); - ( - CodegenResults { - modules, - allocator_module: self.allocator_module, - metadata_module: self.metadata_module, - metadata: self.metadata, - crate_info: self.crate_info, - }, - work_products, - ) + let codegen_results = CodegenResults { + modules, + allocator_module: self.allocator_module, + metadata_module: self.metadata_module, + metadata: self.metadata, + crate_info: self.crate_info, + }; + + produce_final_output_artifacts(sess, &codegen_results, outputs); + + (codegen_results, work_products) + } +} + +// Adapted from https://github.com/rust-lang/rust/blob/73476d49904751f8d90ce904e16dfbc278083d2c/compiler/rustc_codegen_ssa/src/back/write.rs#L547C1-L706C2 +fn produce_final_output_artifacts( + sess: &Session, + codegen_results: &CodegenResults, + crate_output: &OutputFilenames, +) { + let user_wants_bitcode = false; + let mut user_wants_objects = false; + + // Produce final compile outputs. + let copy_gracefully = |from: &Path, to: &OutFileName| match to { + OutFileName::Stdout => { + if let Err(e) = copy_to_stdout(from) { + sess.dcx().emit_err(ssa_errors::CopyPath::new(from, to.as_path(), e)); + } + } + OutFileName::Real(path) => { + if let Err(e) = fs::copy(from, path) { + sess.dcx().emit_err(ssa_errors::CopyPath::new(from, path, e)); + } + } + }; + + let copy_if_one_unit = |output_type: OutputType, keep_numbered: bool| { + if codegen_results.modules.len() == 1 { + // 1) Only one codegen unit. In this case it's no difficulty + // to copy `foo.0.x` to `foo.x`. + let module_name = Some(&codegen_results.modules[0].name[..]); + let path = crate_output.temp_path(output_type, module_name); + let output = crate_output.path(output_type); + if !output_type.is_text_output() && output.is_tty() { + sess.dcx() + .emit_err(ssa_errors::BinaryOutputToTty { shorthand: output_type.shorthand() }); + } else { + copy_gracefully(&path, &output); + } + if !sess.opts.cg.save_temps && !keep_numbered { + // The user just wants `foo.x`, not `foo.#module-name#.x`. + ensure_removed(sess.dcx(), &path); + } + } else { + let extension = crate_output + .temp_path(output_type, None) + .extension() + .unwrap() + .to_str() + .unwrap() + .to_owned(); + + if crate_output.outputs.contains_explicit_name(&output_type) { + // 2) Multiple codegen units, with `--emit foo=some_name`. We have + // no good solution for this case, so warn the user. + sess.dcx().emit_warn(ssa_errors::IgnoringEmitPath { extension }); + } else if crate_output.single_output_file.is_some() { + // 3) Multiple codegen units, with `-o some_name`. We have + // no good solution for this case, so warn the user. + sess.dcx().emit_warn(ssa_errors::IgnoringOutput { extension }); + } else { + // 4) Multiple codegen units, but no explicit name. We + // just leave the `foo.0.x` files in place. + // (We don't have to do any work in this case.) + } + } + }; + + // Flag to indicate whether the user explicitly requested bitcode. + // Otherwise, we produced it only as a temporary output, and will need + // to get rid of it. + for output_type in crate_output.outputs.keys() { + match *output_type { + OutputType::Bitcode => { + // Cranelift doesn't have bitcode + // user_wants_bitcode = true; + // // Copy to .bc, but always keep the .0.bc. There is a later + // // check to figure out if we should delete .0.bc files, or keep + // // them for making an rlib. + // copy_if_one_unit(OutputType::Bitcode, true); + } + OutputType::LlvmAssembly => { + // Cranelift IR text already emitted during codegen + // copy_if_one_unit(OutputType::LlvmAssembly, false); + } + OutputType::Assembly => { + // Currently no support for emitting raw assembly files + // copy_if_one_unit(OutputType::Assembly, false); + } + OutputType::Object => { + user_wants_objects = true; + copy_if_one_unit(OutputType::Object, true); + } + OutputType::Mir | OutputType::Metadata | OutputType::Exe | OutputType::DepInfo => {} + } + } + + // Clean up unwanted temporary files. + + // We create the following files by default: + // - #crate#.#module-name#.bc + // - #crate#.#module-name#.o + // - #crate#.crate.metadata.bc + // - #crate#.crate.metadata.o + // - #crate#.o (linked from crate.##.o) + // - #crate#.bc (copied from crate.##.bc) + // We may create additional files if requested by the user (through + // `-C save-temps` or `--emit=` flags). + + if !sess.opts.cg.save_temps { + // Remove the temporary .#module-name#.o objects. If the user didn't + // explicitly request bitcode (with --emit=bc), and the bitcode is not + // needed for building an rlib, then we must remove .#module-name#.bc as + // well. + + // Specific rules for keeping .#module-name#.bc: + // - If the user requested bitcode (`user_wants_bitcode`), and + // codegen_units > 1, then keep it. + // - If the user requested bitcode but codegen_units == 1, then we + // can toss .#module-name#.bc because we copied it to .bc earlier. + // - If we're not building an rlib and the user didn't request + // bitcode, then delete .#module-name#.bc. + // If you change how this works, also update back::link::link_rlib, + // where .#module-name#.bc files are (maybe) deleted after making an + // rlib. + let needs_crate_object = crate_output.outputs.contains_key(&OutputType::Exe); + + let keep_numbered_bitcode = user_wants_bitcode && sess.codegen_units().as_usize() > 1; + + let keep_numbered_objects = + needs_crate_object || (user_wants_objects && sess.codegen_units().as_usize() > 1); + + for module in codegen_results.modules.iter() { + if let Some(ref path) = module.object { + if !keep_numbered_objects { + ensure_removed(sess.dcx(), path); + } + } + + if let Some(ref path) = module.dwarf_object { + if !keep_numbered_objects { + ensure_removed(sess.dcx(), path); + } + } + + if let Some(ref path) = module.bytecode { + if !keep_numbered_bitcode { + ensure_removed(sess.dcx(), path); + } + } + } + + if !user_wants_bitcode { + if let Some(ref allocator_module) = codegen_results.allocator_module { + if let Some(ref path) = allocator_module.bytecode { + ensure_removed(sess.dcx(), path); + } + } + } } + + // We leave the following files around by default: + // - #crate#.o + // - #crate#.crate.metadata.o + // - #crate#.bc + // These are used in linking steps and will be cleaned up afterward. } fn make_module(sess: &Session, backend_config: &BackendConfig, name: String) -> ObjectModule { diff --git a/src/lib.rs b/src/lib.rs index a59a39074f8c0..a121ac75a2876 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -233,12 +233,13 @@ impl CodegenBackend for CraneliftCodegenBackend { &self, ongoing_codegen: Box, sess: &Session, - _outputs: &OutputFilenames, + outputs: &OutputFilenames, ) -> (CodegenResults, FxIndexMap) { - ongoing_codegen - .downcast::() - .unwrap() - .join(sess, self.config.borrow().as_ref().unwrap()) + ongoing_codegen.downcast::().unwrap().join( + sess, + outputs, + self.config.borrow().as_ref().unwrap(), + ) } fn link( From 34d0f6a1d41de0e9111646b55e959022dff21eb1 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 26 Mar 2024 11:03:50 +0000 Subject: [PATCH 25/40] Re-enable fixed rustc test --- scripts/test_rustc_tests.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 2c1cff51014fc..96f71bcf7670d 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -123,7 +123,6 @@ rm -r tests/run-make/panic-abort-eh_frame # .eh_frame emitted with panic=abort # bugs in the test suite # ====================== -rm tests/ui/backtrace.rs # TODO warning rm tests/ui/process/nofile-limit.rs # TODO some AArch64 linking issue rm tests/ui/stdio-is-blocking.rs # really slow with unoptimized libstd From 09ec683ae72086278db2ba8fa0d6168814b51b93 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 27 Mar 2024 10:57:13 +0000 Subject: [PATCH 26/40] Emit DW_AT_frame_base debuginfo attribute --- src/debuginfo/mod.rs | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/debuginfo/mod.rs b/src/debuginfo/mod.rs index 2d9c2ecdbc2be..56307aa3bb93a 100644 --- a/src/debuginfo/mod.rs +++ b/src/debuginfo/mod.rs @@ -8,10 +8,10 @@ mod unwind; use cranelift_codegen::ir::Endianness; use cranelift_codegen::isa::TargetIsa; use gimli::write::{ - Address, AttributeValue, DwarfUnit, FileId, LineProgram, LineString, Range, RangeList, - UnitEntryId, + Address, AttributeValue, DwarfUnit, Expression, FileId, LineProgram, LineString, Range, + RangeList, UnitEntryId, }; -use gimli::{Encoding, Format, LineEncoding, RunTimeEndian}; +use gimli::{AArch64, Encoding, Format, LineEncoding, Register, RiscV, RunTimeEndian, X86_64}; use indexmap::IndexSet; use rustc_session::Session; @@ -28,6 +28,7 @@ pub(crate) struct DebugContext { dwarf: DwarfUnit, unit_range_list: RangeList, + stack_pointer_register: Register, should_remap_filepaths: bool, } @@ -60,6 +61,15 @@ impl DebugContext { Endianness::Big => RunTimeEndian::Big, }; + let stack_pointer_register = match isa.triple().architecture { + target_lexicon::Architecture::Aarch64(_) => AArch64::SP, + target_lexicon::Architecture::Riscv64(_) => RiscV::SP, + target_lexicon::Architecture::X86_64 | target_lexicon::Architecture::X86_64h => { + X86_64::RSP + } + _ => Register(u16::MAX), + }; + let mut dwarf = DwarfUnit::new(encoding); let should_remap_filepaths = tcx.sess.should_prefer_remapped_for_codegen(); @@ -111,6 +121,7 @@ impl DebugContext { endian, dwarf, unit_range_list: RangeList(Vec::new()), + stack_pointer_register, should_remap_filepaths, } } @@ -135,6 +146,10 @@ impl DebugContext { entry.set(gimli::DW_AT_name, AttributeValue::StringRef(name_id)); entry.set(gimli::DW_AT_linkage_name, AttributeValue::StringRef(name_id)); + let mut frame_base_expr = Expression::new(); + frame_base_expr.op_reg(self.stack_pointer_register); + entry.set(gimli::DW_AT_frame_base, AttributeValue::Exprloc(frame_base_expr)); + entry.set(gimli::DW_AT_decl_file, AttributeValue::FileIndex(Some(file_id))); entry.set(gimli::DW_AT_decl_line, AttributeValue::Udata(line)); entry.set(gimli::DW_AT_decl_column, AttributeValue::Udata(column)); From c76c269aa466b786d4ca3a78dae9cb84912406ed Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 27 Mar 2024 11:04:35 +0000 Subject: [PATCH 27/40] Reduce debuginfo divergence between cg_llvm and cg_clif --- src/debuginfo/mod.rs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/debuginfo/mod.rs b/src/debuginfo/mod.rs index 56307aa3bb93a..44ee2b822a9d5 100644 --- a/src/debuginfo/mod.rs +++ b/src/debuginfo/mod.rs @@ -142,17 +142,25 @@ impl DebugContext { let entry_id = self.dwarf.unit.add(scope, gimli::DW_TAG_subprogram); let entry = self.dwarf.unit.get_mut(entry_id); let name_id = self.dwarf.strings.add(name); - // Gdb requires DW_AT_name. Otherwise the DW_TAG_subprogram is skipped. - entry.set(gimli::DW_AT_name, AttributeValue::StringRef(name_id)); - entry.set(gimli::DW_AT_linkage_name, AttributeValue::StringRef(name_id)); + + // These will be replaced in FunctionDebugContext::finalize. They are + // only defined here to ensure that the order of the attributes matches + // rustc. + entry.set(gimli::DW_AT_low_pc, AttributeValue::Udata(0)); + entry.set(gimli::DW_AT_high_pc, AttributeValue::Udata(0)); let mut frame_base_expr = Expression::new(); frame_base_expr.op_reg(self.stack_pointer_register); entry.set(gimli::DW_AT_frame_base, AttributeValue::Exprloc(frame_base_expr)); + // Gdb requires DW_AT_name. Otherwise the DW_TAG_subprogram is skipped. + // FIXME only include the function name and not the full mangled symbol + entry.set(gimli::DW_AT_name, AttributeValue::StringRef(name_id)); + entry.set(gimli::DW_AT_decl_file, AttributeValue::FileIndex(Some(file_id))); entry.set(gimli::DW_AT_decl_line, AttributeValue::Udata(line)); - entry.set(gimli::DW_AT_decl_column, AttributeValue::Udata(column)); + + // FIXME set DW_AT_external as appropriate FunctionDebugContext { entry_id, From e48d7d242fcf378d66d27dddea546029239bd5c6 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 27 Mar 2024 12:43:47 +0000 Subject: [PATCH 28/40] Emit namespace debuginfo --- src/base.rs | 2 +- src/debuginfo/mod.rs | 63 +++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 60 insertions(+), 5 deletions(-) diff --git a/src/base.rs b/src/base.rs index dbce6d165d2d3..4e60f820594bf 100644 --- a/src/base.rs +++ b/src/base.rs @@ -70,7 +70,7 @@ pub(crate) fn codegen_fn<'tcx>( let clif_comments = crate::pretty_clif::CommentWriter::new(tcx, instance); let func_debug_cx = if let Some(debug_context) = &mut cx.debug_context { - Some(debug_context.define_function(tcx, &symbol_name, mir.span)) + Some(debug_context.define_function(tcx, instance, &symbol_name, mir.span)) } else { None }; diff --git a/src/debuginfo/mod.rs b/src/debuginfo/mod.rs index 44ee2b822a9d5..2b5f472c5fc70 100644 --- a/src/debuginfo/mod.rs +++ b/src/debuginfo/mod.rs @@ -13,6 +13,8 @@ use gimli::write::{ }; use gimli::{AArch64, Encoding, Format, LineEncoding, Register, RiscV, RunTimeEndian, X86_64}; use indexmap::IndexSet; +use rustc_codegen_ssa::debuginfo::type_names; +use rustc_hir::def_id::DefIdMap; use rustc_session::Session; pub(crate) use self::emit::{DebugReloc, DebugRelocName}; @@ -29,6 +31,7 @@ pub(crate) struct DebugContext { dwarf: DwarfUnit, unit_range_list: RangeList, stack_pointer_register: Register, + namespace_map: DefIdMap, should_remap_filepaths: bool, } @@ -122,14 +125,42 @@ impl DebugContext { dwarf, unit_range_list: RangeList(Vec::new()), stack_pointer_register, + namespace_map: DefIdMap::default(), should_remap_filepaths, } } - pub(crate) fn define_function( + fn item_namespace(&mut self, tcx: TyCtxt<'_>, def_id: DefId) -> UnitEntryId { + if let Some(&scope) = self.namespace_map.get(&def_id) { + return scope; + } + + let def_key = tcx.def_key(def_id); + let parent_scope = def_key + .parent + .map(|parent| self.item_namespace(tcx, DefId { krate: def_id.krate, index: parent })) + .unwrap_or(self.dwarf.unit.root()); + + let namespace_name = { + let mut output = String::new(); + type_names::push_item_name(tcx, def_id, false, &mut output); + output + }; + let namespace_name_id = self.dwarf.strings.add(namespace_name); + + let scope = self.dwarf.unit.add(parent_scope, gimli::DW_TAG_namespace); + let scope_entry = self.dwarf.unit.get_mut(scope); + scope_entry.set(gimli::DW_AT_name, AttributeValue::StringRef(namespace_name_id)); + + self.namespace_map.insert(def_id, scope); + scope + } + + pub(crate) fn define_function<'tcx>( &mut self, - tcx: TyCtxt<'_>, - name: &str, + tcx: TyCtxt<'tcx>, + instance: Instance<'tcx>, + linkage_name: &str, function_span: Span, ) -> FunctionDebugContext { let (file, line, column) = DebugContext::get_span_loc(tcx, function_span, function_span); @@ -137,10 +168,31 @@ impl DebugContext { let file_id = self.add_source_file(&file); // FIXME: add to appropriate scope instead of root - let scope = self.dwarf.unit.root(); + let scope = self.item_namespace(tcx, tcx.parent(instance.def_id())); + + let mut name = String::new(); + type_names::push_item_name(tcx, instance.def_id(), false, &mut name); + + // Find the enclosing function, in case this is a closure. + let enclosing_fn_def_id = tcx.typeck_root_def_id(instance.def_id()); + + // We look up the generics of the enclosing function and truncate the args + // to their length in order to cut off extra stuff that might be in there for + // closures or coroutines. + let generics = tcx.generics_of(enclosing_fn_def_id); + let args = instance.args.truncate_to(tcx, generics); + + type_names::push_generic_params( + tcx, + tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), args), + enclosing_fn_def_id, + &mut name, + ); let entry_id = self.dwarf.unit.add(scope, gimli::DW_TAG_subprogram); let entry = self.dwarf.unit.get_mut(entry_id); + let linkage_name_id = + if name != linkage_name { Some(self.dwarf.strings.add(linkage_name)) } else { None }; let name_id = self.dwarf.strings.add(name); // These will be replaced in FunctionDebugContext::finalize. They are @@ -153,6 +205,9 @@ impl DebugContext { frame_base_expr.op_reg(self.stack_pointer_register); entry.set(gimli::DW_AT_frame_base, AttributeValue::Exprloc(frame_base_expr)); + if let Some(linkage_name_id) = linkage_name_id { + entry.set(gimli::DW_AT_linkage_name, AttributeValue::StringRef(linkage_name_id)); + } // Gdb requires DW_AT_name. Otherwise the DW_TAG_subprogram is skipped. // FIXME only include the function name and not the full mangled symbol entry.set(gimli::DW_AT_name, AttributeValue::StringRef(name_id)); From 98eaaeda111673c617134fe2dcd3f10bb6dfc2f0 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 27 Mar 2024 12:57:24 +0000 Subject: [PATCH 29/40] Match unit names with cg_llvm --- src/debuginfo/mod.rs | 10 ++++++++-- src/lib.rs | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/debuginfo/mod.rs b/src/debuginfo/mod.rs index 2b5f472c5fc70..4232018916fc8 100644 --- a/src/debuginfo/mod.rs +++ b/src/debuginfo/mod.rs @@ -43,7 +43,7 @@ pub(crate) struct FunctionDebugContext { } impl DebugContext { - pub(crate) fn new(tcx: TyCtxt<'_>, isa: &dyn TargetIsa) -> Self { + pub(crate) fn new(tcx: TyCtxt<'_>, isa: &dyn TargetIsa, cgu_name: &str) -> Self { let encoding = Encoding { format: Format::Dwarf32, // FIXME this should be configurable @@ -108,7 +108,7 @@ impl DebugContext { dwarf.unit.line_program = line_program; { - let name = dwarf.strings.add(name); + let name = dwarf.strings.add(format!("{name}/@/{cgu_name}")); let comp_dir = dwarf.strings.add(comp_dir); let root = dwarf.unit.root(); @@ -116,6 +116,12 @@ impl DebugContext { root.set(gimli::DW_AT_producer, AttributeValue::StringRef(dwarf.strings.add(producer))); root.set(gimli::DW_AT_language, AttributeValue::Language(gimli::DW_LANG_Rust)); root.set(gimli::DW_AT_name, AttributeValue::StringRef(name)); + + // This will be replaced when emitting the debuginfo. It is only + // defined here to ensure that the order of the attributes matches + // rustc. + root.set(gimli::DW_AT_stmt_list, AttributeValue::Udata(0)); + root.set(gimli::DW_AT_comp_dir, AttributeValue::StringRef(comp_dir)); root.set(gimli::DW_AT_low_pc, AttributeValue::Address(Address::Constant(0))); } diff --git a/src/lib.rs b/src/lib.rs index a121ac75a2876..d0ab64a558490 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -148,7 +148,7 @@ impl CodegenCx { let unwind_context = UnwindContext::new(isa, matches!(backend_config.codegen_mode, CodegenMode::Aot)); let debug_context = if debug_info && !tcx.sess.target.options.is_like_windows { - Some(DebugContext::new(tcx, isa)) + Some(DebugContext::new(tcx, isa, cgu_name.as_str())) } else { None }; From a64387bb6be6360df09e4844c35d63b50b20262e Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 27 Mar 2024 13:28:40 +0000 Subject: [PATCH 30/40] Emit DW_AT_external if applicable --- src/debuginfo/mod.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/debuginfo/mod.rs b/src/debuginfo/mod.rs index 4232018916fc8..ef68419975695 100644 --- a/src/debuginfo/mod.rs +++ b/src/debuginfo/mod.rs @@ -221,6 +221,10 @@ impl DebugContext { entry.set(gimli::DW_AT_decl_file, AttributeValue::FileIndex(Some(file_id))); entry.set(gimli::DW_AT_decl_line, AttributeValue::Udata(line)); + if tcx.is_reachable_non_generic(instance.def_id()) { + entry.set(gimli::DW_AT_external, AttributeValue::FlagPresent); + } + // FIXME set DW_AT_external as appropriate FunctionDebugContext { From 41246b2cf629a0b2699360f35952cff8a7d3d784 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 27 Mar 2024 13:35:11 +0000 Subject: [PATCH 31/40] Remove fixed todos --- src/debuginfo/mod.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/debuginfo/mod.rs b/src/debuginfo/mod.rs index ef68419975695..b541cf0512e1a 100644 --- a/src/debuginfo/mod.rs +++ b/src/debuginfo/mod.rs @@ -215,7 +215,6 @@ impl DebugContext { entry.set(gimli::DW_AT_linkage_name, AttributeValue::StringRef(linkage_name_id)); } // Gdb requires DW_AT_name. Otherwise the DW_TAG_subprogram is skipped. - // FIXME only include the function name and not the full mangled symbol entry.set(gimli::DW_AT_name, AttributeValue::StringRef(name_id)); entry.set(gimli::DW_AT_decl_file, AttributeValue::FileIndex(Some(file_id))); @@ -225,8 +224,6 @@ impl DebugContext { entry.set(gimli::DW_AT_external, AttributeValue::FlagPresent); } - // FIXME set DW_AT_external as appropriate - FunctionDebugContext { entry_id, function_source_loc: (file_id, line, column), From 1f75f0fcad63b577ed38d5cf10b62c5af47a3269 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 27 Mar 2024 14:14:30 +0000 Subject: [PATCH 32/40] Move FileId caching to DebugContext::add_source_file --- src/base.rs | 1 - src/common.rs | 29 +---------- src/debuginfo/line_info.rs | 99 ++++++++++++++++++++------------------ src/debuginfo/mod.rs | 7 +-- 4 files changed, 58 insertions(+), 78 deletions(-) diff --git a/src/base.rs b/src/base.rs index 4e60f820594bf..9c66fa6d9ccac 100644 --- a/src/base.rs +++ b/src/base.rs @@ -95,7 +95,6 @@ pub(crate) fn codegen_fn<'tcx>( caller_location: None, // set by `codegen_fn_prelude` clif_comments, - last_source_file: None, next_ssa_var: 0, }; diff --git a/src/common.rs b/src/common.rs index a7c3d68ff8cfb..b038c7194cd57 100644 --- a/src/common.rs +++ b/src/common.rs @@ -1,12 +1,9 @@ use cranelift_codegen::isa::TargetFrontendConfig; -use gimli::write::FileId; -use rustc_data_structures::sync::Lrc; use rustc_index::IndexVec; use rustc_middle::ty::layout::{ FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOfHelpers, }; use rustc_span::source_map::Spanned; -use rustc_span::SourceFile; use rustc_target::abi::call::FnAbi; use rustc_target::abi::{Integer, Primitive}; use rustc_target::spec::{HasTargetSpec, Target}; @@ -305,11 +302,6 @@ pub(crate) struct FunctionCx<'m, 'clif, 'tcx: 'm> { pub(crate) clif_comments: crate::pretty_clif::CommentWriter, - /// Last accessed source file and it's debuginfo file id. - /// - /// For optimization purposes only - pub(crate) last_source_file: Option<(Lrc, FileId)>, - /// This should only be accessed by `CPlace::new_var`. pub(crate) next_ssa_var: u32, } @@ -419,25 +411,8 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { pub(crate) fn set_debug_loc(&mut self, source_info: mir::SourceInfo) { if let Some(debug_context) = &mut self.cx.debug_context { - let (file, line, column) = - DebugContext::get_span_loc(self.tcx, self.mir.span, source_info.span); - - // add_source_file is very slow. - // Optimize for the common case of the current file not being changed. - let mut cached_file_id = None; - if let Some((ref last_source_file, last_file_id)) = self.last_source_file { - // If the allocations are not equal, the files may still be equal, but that - // doesn't matter, as this is just an optimization. - if rustc_data_structures::sync::Lrc::ptr_eq(last_source_file, &file) { - cached_file_id = Some(last_file_id); - } - } - - let file_id = if let Some(file_id) = cached_file_id { - file_id - } else { - debug_context.add_source_file(&file) - }; + let (file_id, line, column) = + debug_context.get_span_loc(self.tcx, self.mir.span, source_info.span); let source_loc = self.func_debug_cx.as_mut().unwrap().add_dbg_loc(file_id, line, column); diff --git a/src/debuginfo/line_info.rs b/src/debuginfo/line_info.rs index d1b21d0a0b6c5..916abf3186992 100644 --- a/src/debuginfo/line_info.rs +++ b/src/debuginfo/line_info.rs @@ -8,7 +8,6 @@ use cranelift_codegen::MachSrcLoc; use gimli::write::{ Address, AttributeValue, FileId, FileInfo, LineProgram, LineString, LineStringTable, }; -use rustc_data_structures::sync::Lrc; use rustc_span::{ FileName, Pos, SourceFile, SourceFileAndLine, SourceFileHash, SourceFileHashAlgorithm, }; @@ -60,10 +59,11 @@ fn make_file_info(hash: SourceFileHash) -> Option { impl DebugContext { pub(crate) fn get_span_loc( + &mut self, tcx: TyCtxt<'_>, function_span: Span, span: Span, - ) -> (Lrc, u64, u64) { + ) -> (FileId, u64, u64) { // Based on https://github.com/rust-lang/rust/blob/e369d87b015a84653343032833d65d0545fd3f26/src/librustc_codegen_ssa/mir/mod.rs#L116-L131 // In order to have a good line stepping behavior in debugger, we overwrite debug // locations of macro expansions with that of the outermost expansion site (when the macro is @@ -71,61 +71,66 @@ impl DebugContext { let span = tcx.collapsed_debuginfo(span, function_span); match tcx.sess.source_map().lookup_line(span.lo()) { Ok(SourceFileAndLine { sf: file, line }) => { + let file_id = self.add_source_file(&file); let line_pos = file.lines()[line]; let col = file.relative_position(span.lo()) - line_pos; - (file, u64::try_from(line).unwrap() + 1, u64::from(col.to_u32()) + 1) + (file_id, u64::try_from(line).unwrap() + 1, u64::from(col.to_u32()) + 1) } - Err(file) => (file, 0, 0), + Err(file) => (self.add_source_file(&file), 0, 0), } } pub(crate) fn add_source_file(&mut self, source_file: &SourceFile) -> FileId { - let line_program: &mut LineProgram = &mut self.dwarf.unit.line_program; - let line_strings: &mut LineStringTable = &mut self.dwarf.line_strings; - - match &source_file.name { - FileName::Real(path) => { - let (dir_path, file_name) = - split_path_dir_and_file(if self.should_remap_filepaths { - path.remapped_path_if_available() - } else { - path.local_path_if_available() - }); - let dir_name = osstr_as_utf8_bytes(dir_path.as_os_str()); - let file_name = osstr_as_utf8_bytes(file_name); - - let dir_id = if !dir_name.is_empty() { - let dir_name = LineString::new(dir_name, line_program.encoding(), line_strings); - line_program.add_directory(dir_name) - } else { - line_program.default_directory() - }; - let file_name = LineString::new(file_name, line_program.encoding(), line_strings); - - let info = make_file_info(source_file.src_hash); - - line_program.file_has_md5 &= info.is_some(); - line_program.add_file(file_name, dir_id, info) - } - // FIXME give more appropriate file names - filename => { - let dir_id = line_program.default_directory(); - let dummy_file_name = LineString::new( - filename - .display(if self.should_remap_filepaths { - FileNameDisplayPreference::Remapped + let cache_key = (source_file.stable_id, source_file.src_hash); + *self.created_files.entry(cache_key).or_insert_with(|| { + let line_program: &mut LineProgram = &mut self.dwarf.unit.line_program; + let line_strings: &mut LineStringTable = &mut self.dwarf.line_strings; + + match &source_file.name { + FileName::Real(path) => { + let (dir_path, file_name) = + split_path_dir_and_file(if self.should_remap_filepaths { + path.remapped_path_if_available() } else { - FileNameDisplayPreference::Local - }) - .to_string() - .into_bytes(), - line_program.encoding(), - line_strings, - ); - line_program.add_file(dummy_file_name, dir_id, None) + path.local_path_if_available() + }); + let dir_name = osstr_as_utf8_bytes(dir_path.as_os_str()); + let file_name = osstr_as_utf8_bytes(file_name); + + let dir_id = if !dir_name.is_empty() { + let dir_name = + LineString::new(dir_name, line_program.encoding(), line_strings); + line_program.add_directory(dir_name) + } else { + line_program.default_directory() + }; + let file_name = + LineString::new(file_name, line_program.encoding(), line_strings); + + let info = make_file_info(source_file.src_hash); + + line_program.file_has_md5 &= info.is_some(); + line_program.add_file(file_name, dir_id, info) + } + filename => { + let dir_id = line_program.default_directory(); + let dummy_file_name = LineString::new( + filename + .display(if self.should_remap_filepaths { + FileNameDisplayPreference::Remapped + } else { + FileNameDisplayPreference::Local + }) + .to_string() + .into_bytes(), + line_program.encoding(), + line_strings, + ); + line_program.add_file(dummy_file_name, dir_id, None) + } } - } + }) } } diff --git a/src/debuginfo/mod.rs b/src/debuginfo/mod.rs index b541cf0512e1a..172e72c0e2639 100644 --- a/src/debuginfo/mod.rs +++ b/src/debuginfo/mod.rs @@ -16,6 +16,7 @@ use indexmap::IndexSet; use rustc_codegen_ssa::debuginfo::type_names; use rustc_hir::def_id::DefIdMap; use rustc_session::Session; +use rustc_span::{SourceFileHash, StableSourceFileId}; pub(crate) use self::emit::{DebugReloc, DebugRelocName}; pub(crate) use self::unwind::UnwindContext; @@ -30,6 +31,7 @@ pub(crate) struct DebugContext { dwarf: DwarfUnit, unit_range_list: RangeList, + created_files: FxHashMap<(StableSourceFileId, SourceFileHash), FileId>, stack_pointer_register: Register, namespace_map: DefIdMap, @@ -130,6 +132,7 @@ impl DebugContext { endian, dwarf, unit_range_list: RangeList(Vec::new()), + created_files: FxHashMap::default(), stack_pointer_register, namespace_map: DefIdMap::default(), should_remap_filepaths, @@ -169,9 +172,7 @@ impl DebugContext { linkage_name: &str, function_span: Span, ) -> FunctionDebugContext { - let (file, line, column) = DebugContext::get_span_loc(tcx, function_span, function_span); - - let file_id = self.add_source_file(&file); + let (file_id, line, column) = self.get_span_loc(tcx, function_span, function_span); // FIXME: add to appropriate scope instead of root let scope = self.item_namespace(tcx, tcx.parent(instance.def_id())); From f086e7abaf2fc954a2801231bfe3aa4508b8f424 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 27 Mar 2024 15:00:41 +0000 Subject: [PATCH 33/40] Allow debuginfo to reference global variables --- src/debuginfo/emit.rs | 15 +++++++++++++++ src/debuginfo/line_info.rs | 18 +++++------------- src/debuginfo/mod.rs | 19 +++++++------------ src/debuginfo/object.rs | 13 ++++++++----- src/debuginfo/unwind.rs | 10 ++++------ 5 files changed, 39 insertions(+), 36 deletions(-) diff --git a/src/debuginfo/emit.rs b/src/debuginfo/emit.rs index 81b819a554647..d376766966d65 100644 --- a/src/debuginfo/emit.rs +++ b/src/debuginfo/emit.rs @@ -1,5 +1,6 @@ //! Write the debuginfo into an object file. +use cranelift_module::{DataId, FuncId}; use cranelift_object::ObjectProduct; use gimli::write::{Address, AttributeValue, EndianVec, Result, Sections, Writer}; use gimli::{RunTimeEndian, SectionId}; @@ -8,6 +9,19 @@ use rustc_data_structures::fx::FxHashMap; use super::object::WriteDebugInfo; use super::DebugContext; +pub(super) fn address_for_func(func_id: FuncId) -> Address { + let symbol = func_id.as_u32(); + assert!(symbol & 1 << 31 == 0); + Address::Symbol { symbol: symbol as usize, addend: 0 } +} + +#[allow(dead_code)] +pub(super) fn address_for_data(data_id: DataId) -> Address { + let symbol = data_id.as_u32(); + assert!(symbol & 1 << 31 == 0); + Address::Symbol { symbol: (symbol | 1 << 31) as usize, addend: 0 } +} + impl DebugContext { pub(crate) fn emit(&mut self, product: &mut ObjectProduct) { let unit_range_list_id = self.dwarf.unit.ranges.add(self.unit_range_list.clone()); @@ -171,6 +185,7 @@ impl Writer for WriterRelocate { gimli::DW_EH_PE_pcrel => { let size = match eh_pe.format() { gimli::DW_EH_PE_sdata4 => 4, + gimli::DW_EH_PE_sdata8 => 8, _ => return Err(gimli::write::Error::UnsupportedPointerEncoding(eh_pe)), }; self.relocs.push(DebugReloc { diff --git a/src/debuginfo/line_info.rs b/src/debuginfo/line_info.rs index 916abf3186992..380eba437c270 100644 --- a/src/debuginfo/line_info.rs +++ b/src/debuginfo/line_info.rs @@ -5,13 +5,12 @@ use std::path::{Component, Path}; use cranelift_codegen::binemit::CodeOffset; use cranelift_codegen::MachSrcLoc; -use gimli::write::{ - Address, AttributeValue, FileId, FileInfo, LineProgram, LineString, LineStringTable, -}; +use gimli::write::{AttributeValue, FileId, FileInfo, LineProgram, LineString, LineStringTable}; use rustc_span::{ FileName, Pos, SourceFile, SourceFileAndLine, SourceFileHash, SourceFileHashAlgorithm, }; +use crate::debuginfo::emit::address_for_func; use crate::debuginfo::FunctionDebugContext; use crate::prelude::*; @@ -143,7 +142,7 @@ impl FunctionDebugContext { pub(super) fn create_debug_lines( &mut self, debug_context: &mut DebugContext, - symbol: usize, + func_id: FuncId, context: &Context, ) -> CodeOffset { let create_row_for_span = @@ -156,11 +155,7 @@ impl FunctionDebugContext { debug_context.dwarf.unit.line_program.generate_row(); }; - debug_context - .dwarf - .unit - .line_program - .begin_sequence(Some(Address::Symbol { symbol, addend: 0 })); + debug_context.dwarf.unit.line_program.begin_sequence(Some(address_for_func(func_id))); let mut func_end = 0; @@ -183,10 +178,7 @@ impl FunctionDebugContext { assert_ne!(func_end, 0); let entry = debug_context.dwarf.unit.get_mut(self.entry_id); - entry.set( - gimli::DW_AT_low_pc, - AttributeValue::Address(Address::Symbol { symbol, addend: 0 }), - ); + entry.set(gimli::DW_AT_low_pc, AttributeValue::Address(address_for_func(func_id))); entry.set(gimli::DW_AT_high_pc, AttributeValue::Udata(u64::from(func_end))); func_end diff --git a/src/debuginfo/mod.rs b/src/debuginfo/mod.rs index 172e72c0e2639..3bf75e989c563 100644 --- a/src/debuginfo/mod.rs +++ b/src/debuginfo/mod.rs @@ -20,6 +20,7 @@ use rustc_span::{SourceFileHash, StableSourceFileId}; pub(crate) use self::emit::{DebugReloc, DebugRelocName}; pub(crate) use self::unwind::UnwindContext; +use crate::debuginfo::emit::address_for_func; use crate::prelude::*; pub(crate) fn producer(sess: &Session) -> String { @@ -174,7 +175,6 @@ impl DebugContext { ) -> FunctionDebugContext { let (file_id, line, column) = self.get_span_loc(tcx, function_span, function_span); - // FIXME: add to appropriate scope instead of root let scope = self.item_namespace(tcx, tcx.parent(instance.def_id())); let mut name = String::new(); @@ -240,21 +240,16 @@ impl FunctionDebugContext { func_id: FuncId, context: &Context, ) { - let symbol = func_id.as_u32() as usize; + let end = self.create_debug_lines(debug_context, func_id, context); - let end = self.create_debug_lines(debug_context, symbol, context); - - debug_context.unit_range_list.0.push(Range::StartLength { - begin: Address::Symbol { symbol, addend: 0 }, - length: u64::from(end), - }); + debug_context + .unit_range_list + .0 + .push(Range::StartLength { begin: address_for_func(func_id), length: u64::from(end) }); let func_entry = debug_context.dwarf.unit.get_mut(self.entry_id); // Gdb requires both DW_AT_low_pc and DW_AT_high_pc. Otherwise the DW_TAG_subprogram is skipped. - func_entry.set( - gimli::DW_AT_low_pc, - AttributeValue::Address(Address::Symbol { symbol, addend: 0 }), - ); + func_entry.set(gimli::DW_AT_low_pc, AttributeValue::Address(address_for_func(func_id))); // Using Udata for DW_AT_high_pc requires at least DWARF4 func_entry.set(gimli::DW_AT_high_pc, AttributeValue::Udata(u64::from(end))); } diff --git a/src/debuginfo/object.rs b/src/debuginfo/object.rs index f1840a7bf7303..27eabd8a0a616 100644 --- a/src/debuginfo/object.rs +++ b/src/debuginfo/object.rs @@ -1,4 +1,4 @@ -use cranelift_module::FuncId; +use cranelift_module::{DataId, FuncId}; use cranelift_object::ObjectProduct; use gimli::SectionId; use object::write::{Relocation, StandardSegment}; @@ -57,10 +57,13 @@ impl WriteDebugInfo for ObjectProduct { let (symbol, symbol_offset) = match reloc.name { DebugRelocName::Section(id) => (section_map.get(&id).unwrap().1, 0), DebugRelocName::Symbol(id) => { - let symbol_id = self.function_symbol(FuncId::from_u32(id.try_into().unwrap())); - self.object - .symbol_section_and_offset(symbol_id) - .expect("Debug reloc for undef sym???") + let id = id.try_into().unwrap(); + let symbol_id = if id & 1 << 31 == 0 { + self.function_symbol(FuncId::from_u32(id)) + } else { + self.data_symbol(DataId::from_u32(id & !(1 << 31))) + }; + self.object.symbol_section_and_offset(symbol_id).unwrap_or((symbol_id, 0)) } }; self.object diff --git a/src/debuginfo/unwind.rs b/src/debuginfo/unwind.rs index 35278e6fb29d3..96ab7a29205bf 100644 --- a/src/debuginfo/unwind.rs +++ b/src/debuginfo/unwind.rs @@ -3,9 +3,10 @@ use cranelift_codegen::ir::Endianness; use cranelift_codegen::isa::{unwind::UnwindInfo, TargetIsa}; use cranelift_object::ObjectProduct; -use gimli::write::{Address, CieId, EhFrame, FrameTable, Section}; +use gimli::write::{CieId, EhFrame, FrameTable, Section}; use gimli::RunTimeEndian; +use super::emit::address_for_func; use super::object::WriteDebugInfo; use crate::prelude::*; @@ -47,11 +48,8 @@ impl UnwindContext { match unwind_info { UnwindInfo::SystemV(unwind_info) => { - self.frame_table.add_fde( - self.cie_id.unwrap(), - unwind_info - .to_fde(Address::Symbol { symbol: func_id.as_u32() as usize, addend: 0 }), - ); + self.frame_table + .add_fde(self.cie_id.unwrap(), unwind_info.to_fde(address_for_func(func_id))); } UnwindInfo::WindowsX64(_) => { // FIXME implement this From 4b80941ae36ce0e49ecbb772872108e4808b2c4a Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 27 Mar 2024 16:53:12 +0000 Subject: [PATCH 34/40] Add debuginfo for statics Most types are still unimplemented and get a placeholder byte array instead. --- src/constant.rs | 8 +- src/debuginfo/emit.rs | 1 - src/debuginfo/mod.rs | 77 +++++++++++++++++++- src/debuginfo/types.rs | 162 +++++++++++++++++++++++++++++++++++++++++ src/driver/aot.rs | 7 +- 5 files changed, 251 insertions(+), 4 deletions(-) create mode 100644 src/debuginfo/types.rs diff --git a/src/constant.rs b/src/constant.rs index 690e8fe0e20ae..635ed6c8e88b1 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -31,10 +31,16 @@ impl ConstantCx { } } -pub(crate) fn codegen_static(tcx: TyCtxt<'_>, module: &mut dyn Module, def_id: DefId) { +pub(crate) fn codegen_static(tcx: TyCtxt<'_>, module: &mut dyn Module, def_id: DefId) -> DataId { let mut constants_cx = ConstantCx::new(); constants_cx.todo.push(TodoItem::Static(def_id)); constants_cx.finalize(tcx, module); + + data_id_for_static( + tcx, module, def_id, false, + // For a declaration the stated mutability doesn't matter. + false, + ) } pub(crate) fn codegen_tls_ref<'tcx>( diff --git a/src/debuginfo/emit.rs b/src/debuginfo/emit.rs index d376766966d65..36af7d4450d04 100644 --- a/src/debuginfo/emit.rs +++ b/src/debuginfo/emit.rs @@ -15,7 +15,6 @@ pub(super) fn address_for_func(func_id: FuncId) -> Address { Address::Symbol { symbol: symbol as usize, addend: 0 } } -#[allow(dead_code)] pub(super) fn address_for_data(data_id: DataId) -> Address { let symbol = data_id.as_u32(); assert!(symbol & 1 << 31 == 0); diff --git a/src/debuginfo/mod.rs b/src/debuginfo/mod.rs index 3bf75e989c563..2bab897dbcd87 100644 --- a/src/debuginfo/mod.rs +++ b/src/debuginfo/mod.rs @@ -3,10 +3,12 @@ mod emit; mod line_info; mod object; +mod types; mod unwind; use cranelift_codegen::ir::Endianness; use cranelift_codegen::isa::TargetIsa; +use cranelift_module::DataId; use gimli::write::{ Address, AttributeValue, DwarfUnit, Expression, FileId, LineProgram, LineString, Range, RangeList, UnitEntryId, @@ -14,13 +16,15 @@ use gimli::write::{ use gimli::{AArch64, Encoding, Format, LineEncoding, Register, RiscV, RunTimeEndian, X86_64}; use indexmap::IndexSet; use rustc_codegen_ssa::debuginfo::type_names; +use rustc_hir::def::DefKind; use rustc_hir::def_id::DefIdMap; use rustc_session::Session; use rustc_span::{SourceFileHash, StableSourceFileId}; pub(crate) use self::emit::{DebugReloc, DebugRelocName}; +pub(crate) use self::types::TypeDebugContext; pub(crate) use self::unwind::UnwindContext; -use crate::debuginfo::emit::address_for_func; +use crate::debuginfo::emit::{address_for_data, address_for_func}; use crate::prelude::*; pub(crate) fn producer(sess: &Session) -> String { @@ -35,6 +39,7 @@ pub(crate) struct DebugContext { created_files: FxHashMap<(StableSourceFileId, SourceFileHash), FileId>, stack_pointer_register: Register, namespace_map: DefIdMap, + array_size_type: UnitEntryId, should_remap_filepaths: bool, } @@ -129,6 +134,19 @@ impl DebugContext { root.set(gimli::DW_AT_low_pc, AttributeValue::Address(Address::Constant(0))); } + let array_size_type = dwarf.unit.add(dwarf.unit.root(), gimli::DW_TAG_base_type); + let array_size_type_entry = dwarf.unit.get_mut(array_size_type); + array_size_type_entry.set( + gimli::DW_AT_name, + AttributeValue::StringRef(dwarf.strings.add("__ARRAY_SIZE_TYPE__")), + ); + array_size_type_entry + .set(gimli::DW_AT_encoding, AttributeValue::Encoding(gimli::DW_ATE_unsigned)); + array_size_type_entry.set( + gimli::DW_AT_byte_size, + AttributeValue::Udata(isa.frontend_config().pointer_bytes().into()), + ); + DebugContext { endian, dwarf, @@ -136,6 +154,7 @@ impl DebugContext { created_files: FxHashMap::default(), stack_pointer_register, namespace_map: DefIdMap::default(), + array_size_type, should_remap_filepaths, } } @@ -231,6 +250,62 @@ impl DebugContext { source_loc_set: IndexSet::new(), } } + + // Adapted from https://github.com/rust-lang/rust/blob/10a7aa14fed9b528b74b0f098c4899c37c09a9c7/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs#L1288-L1346 + pub(crate) fn define_static<'tcx>( + &mut self, + tcx: TyCtxt<'tcx>, + type_dbg: &mut TypeDebugContext<'tcx>, + def_id: DefId, + data_id: DataId, + ) { + let DefKind::Static { nested, .. } = tcx.def_kind(def_id) else { bug!() }; + if nested { + return; + } + + let scope = self.item_namespace(tcx, tcx.parent(def_id)); + + let span = tcx.def_span(def_id); + let (file_id, line, _column) = self.get_span_loc(tcx, span, span); + + let static_type = Instance::mono(tcx, def_id).ty(tcx, ty::ParamEnv::reveal_all()); + let static_layout = tcx.layout_of(ty::ParamEnv::reveal_all().and(static_type)).unwrap(); + // FIXME use the actual type layout + let type_id = self.debug_type(tcx, type_dbg, static_type); + + let name = tcx.item_name(def_id); + let linkage_name = tcx.symbol_name(Instance::mono(tcx, def_id)).name; + + let entry_id = self.dwarf.unit.add(scope, gimli::DW_TAG_variable); + let entry = self.dwarf.unit.get_mut(entry_id); + let linkage_name_id = if name.as_str() != linkage_name { + Some(self.dwarf.strings.add(linkage_name)) + } else { + None + }; + let name_id = self.dwarf.strings.add(name.as_str()); + + entry.set(gimli::DW_AT_name, AttributeValue::StringRef(name_id)); + entry.set(gimli::DW_AT_type, AttributeValue::UnitRef(type_id)); + + if tcx.is_reachable_non_generic(def_id) { + entry.set(gimli::DW_AT_external, AttributeValue::FlagPresent); + } + + entry.set(gimli::DW_AT_decl_file, AttributeValue::FileIndex(Some(file_id))); + entry.set(gimli::DW_AT_decl_line, AttributeValue::Udata(line)); + + entry.set(gimli::DW_AT_alignment, AttributeValue::Udata(static_layout.align.pref.bytes())); + + let mut expr = Expression::new(); + expr.op_addr(address_for_data(data_id)); + entry.set(gimli::DW_AT_location, AttributeValue::Exprloc(expr)); + + if let Some(linkage_name_id) = linkage_name_id { + entry.set(gimli::DW_AT_linkage_name, AttributeValue::StringRef(linkage_name_id)); + } + } } impl FunctionDebugContext { diff --git a/src/debuginfo/types.rs b/src/debuginfo/types.rs new file mode 100644 index 0000000000000..650de945c7bbc --- /dev/null +++ b/src/debuginfo/types.rs @@ -0,0 +1,162 @@ +// Adapted from https://github.com/rust-lang/rust/blob/10a7aa14fed9b528b74b0f098c4899c37c09a9c7/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs + +use gimli::write::{AttributeValue, UnitEntryId}; +use rustc_codegen_ssa::debuginfo::type_names; +use rustc_data_structures::fx::FxHashMap; +use rustc_middle::ty::{self, Ty, TyCtxt}; + +use crate::{has_ptr_meta, DebugContext}; + +#[derive(Default)] +pub(crate) struct TypeDebugContext<'tcx> { + type_map: FxHashMap, UnitEntryId>, +} + +/// Returns from the enclosing function if the type debuginfo node with the given +/// unique ID can be found in the type map. +macro_rules! return_if_type_created_in_meantime { + ($type_dbg:expr, $ty:expr) => { + if let Some(&type_id) = $type_dbg.type_map.get(&$ty) { + return type_id; + } + }; +} + +impl DebugContext { + pub(crate) fn debug_type<'tcx>( + &mut self, + tcx: TyCtxt<'tcx>, + type_dbg: &mut TypeDebugContext<'tcx>, + ty: Ty<'tcx>, + ) -> UnitEntryId { + if let Some(&type_id) = type_dbg.type_map.get(&ty) { + return type_id; + } + + let type_id = match ty.kind() { + ty::Never | ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) => { + self.basic_type(tcx, ty) + } + ty::Tuple(elems) if elems.is_empty() => self.basic_type(tcx, ty), + ty::Array(elem_ty, len) => self.array_type( + tcx, + type_dbg, + *elem_ty, + len.eval_target_usize(tcx, ty::ParamEnv::reveal_all()), + ), + // ty::Slice(_) | ty::Str + // ty::Dynamic + // ty::Foreign + ty::RawPtr(pointee_type, _) | ty::Ref(_, pointee_type, _) => { + self.pointer_type(tcx, type_dbg, ty, *pointee_type) + } + // ty::Adt(def, args) if def.is_box() && args.get(1).map_or(true, |arg| cx.layout_of(arg.expect_ty()).is_1zst()) + // ty::FnDef(..) | ty::FnPtr(..) + // ty::Closure(..) + // ty::Adt(def, ..) + // ty::Tuple(_) + // ty::Param(_) + // FIXME implement remaining types and add unreachable!() to the fallback branch + _ => self.placeholder_for_type(tcx, type_dbg, ty), + }; + + type_dbg.type_map.insert(ty, type_id); + + type_id + } + + fn basic_type<'tcx>(&mut self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> UnitEntryId { + let (name, encoding) = match ty.kind() { + ty::Never => ("!", gimli::DW_ATE_unsigned), + ty::Tuple(elems) if elems.is_empty() => ("()", gimli::DW_ATE_unsigned), + ty::Bool => ("bool", gimli::DW_ATE_boolean), + ty::Char => ("char", gimli::DW_ATE_UTF), + ty::Int(int_ty) => (int_ty.name_str(), gimli::DW_ATE_signed), + ty::Uint(uint_ty) => (uint_ty.name_str(), gimli::DW_ATE_unsigned), + ty::Float(float_ty) => (float_ty.name_str(), gimli::DW_ATE_float), + _ => unreachable!(), + }; + + let type_id = self.dwarf.unit.add(self.dwarf.unit.root(), gimli::DW_TAG_base_type); + let type_entry = self.dwarf.unit.get_mut(type_id); + type_entry.set(gimli::DW_AT_name, AttributeValue::StringRef(self.dwarf.strings.add(name))); + type_entry.set(gimli::DW_AT_encoding, AttributeValue::Encoding(encoding)); + type_entry.set( + gimli::DW_AT_byte_size, + AttributeValue::Udata( + tcx.layout_of(ty::ParamEnv::reveal_all().and(ty)).expect("FIXME").size.bytes(), + ), + ); + + type_id + } + + fn array_type<'tcx>( + &mut self, + tcx: TyCtxt<'tcx>, + type_dbg: &mut TypeDebugContext<'tcx>, + elem_ty: Ty<'tcx>, + len: u64, + ) -> UnitEntryId { + let elem_dw_ty = self.debug_type(tcx, type_dbg, elem_ty); + + return_if_type_created_in_meantime!(type_dbg, elem_ty); + + let array_type_id = self.dwarf.unit.add(self.dwarf.unit.root(), gimli::DW_TAG_array_type); + let array_type_entry = self.dwarf.unit.get_mut(array_type_id); + array_type_entry.set(gimli::DW_AT_type, AttributeValue::UnitRef(elem_dw_ty)); + + let subrange_id = self.dwarf.unit.add(array_type_id, gimli::DW_TAG_subrange_type); + let subrange_entry = self.dwarf.unit.get_mut(subrange_id); + subrange_entry.set(gimli::DW_AT_type, AttributeValue::UnitRef(self.array_size_type)); + subrange_entry.set(gimli::DW_AT_lower_bound, AttributeValue::Udata(0)); + subrange_entry.set(gimli::DW_AT_count, AttributeValue::Udata(len)); + + array_type_id + } + + fn pointer_type<'tcx>( + &mut self, + tcx: TyCtxt<'tcx>, + type_dbg: &mut TypeDebugContext<'tcx>, + ptr_type: Ty<'tcx>, + pointee_type: Ty<'tcx>, + ) -> UnitEntryId { + let pointee_dw_ty = self.debug_type(tcx, type_dbg, pointee_type); + + return_if_type_created_in_meantime!(type_dbg, ptr_type); + + let name = type_names::compute_debuginfo_type_name(tcx, ptr_type, true); + + if !has_ptr_meta(tcx, ptr_type) { + let pointer_type_id = + self.dwarf.unit.add(self.dwarf.unit.root(), gimli::DW_TAG_pointer_type); + let pointer_entry = self.dwarf.unit.get_mut(pointer_type_id); + pointer_entry.set(gimli::DW_AT_type, AttributeValue::UnitRef(pointee_dw_ty)); + pointer_entry + .set(gimli::DW_AT_name, AttributeValue::StringRef(self.dwarf.strings.add(name))); + + pointer_type_id + } else { + // FIXME implement debuginfo for fat pointers + self.placeholder_for_type(tcx, type_dbg, ptr_type) + } + } + + fn placeholder_for_type<'tcx>( + &mut self, + tcx: TyCtxt<'tcx>, + type_dbg: &mut TypeDebugContext<'tcx>, + ty: Ty<'tcx>, + ) -> UnitEntryId { + self.debug_type( + tcx, + type_dbg, + Ty::new_array( + tcx, + tcx.types.u8, + tcx.layout_of(ty::ParamEnv::reveal_all().and(ty)).unwrap().size.bytes(), + ), + ) + } +} diff --git a/src/driver/aot.rs b/src/driver/aot.rs index 4a28b2d93fabb..e5caceab3456a 100644 --- a/src/driver/aot.rs +++ b/src/driver/aot.rs @@ -23,6 +23,7 @@ use rustc_session::config::{DebugInfo, OutFileName, OutputFilenames, OutputType} use rustc_session::Session; use crate::concurrency_limiter::{ConcurrencyLimiter, ConcurrencyLimiterToken}; +use crate::debuginfo::TypeDebugContext; use crate::global_asm::GlobalAsmConfig; use crate::{prelude::*, BackendConfig}; @@ -460,6 +461,7 @@ fn module_codegen( tcx.sess.opts.debuginfo != DebugInfo::None, cgu_name, ); + let mut type_dbg = TypeDebugContext::default(); super::predefine_mono_items(tcx, &mut module, &mono_items); let mut codegened_functions = vec![]; for (mono_item, _) in mono_items { @@ -475,7 +477,10 @@ fn module_codegen( codegened_functions.push(codegened_function); } MonoItem::Static(def_id) => { - crate::constant::codegen_static(tcx, &mut module, def_id) + let data_id = crate::constant::codegen_static(tcx, &mut module, def_id); + if let Some(debug_context) = &mut cx.debug_context { + debug_context.define_static(tcx, &mut type_dbg, def_id, data_id); + } } MonoItem::GlobalAsm(item_id) => { crate::global_asm::codegen_global_asm_item( From fee1204ffa7d5c989a2cb76d6b3bb8daa51af811 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 27 Mar 2024 19:49:20 +0000 Subject: [PATCH 35/40] Stop taking FunctionCx's fn_abi field --- src/abi/mod.rs | 7 ++----- src/abi/returning.rs | 26 +++++++------------------- src/base.rs | 2 +- src/common.rs | 2 +- 4 files changed, 11 insertions(+), 26 deletions(-) diff --git a/src/abi/mod.rs b/src/abi/mod.rs index b0af421008acc..6363a0d59a4f2 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -222,17 +222,15 @@ pub(crate) fn codegen_fn_prelude<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, start_ Spread(Vec>>), } - let fn_abi = fx.fn_abi.take().unwrap(); - // FIXME implement variadics in cranelift - if fn_abi.c_variadic { + if fx.fn_abi.c_variadic { fx.tcx.dcx().span_fatal( fx.mir.span, "Defining variadic functions is not yet supported by Cranelift", ); } - let mut arg_abis_iter = fn_abi.args.iter(); + let mut arg_abis_iter = fx.fn_abi.args.iter(); let func_params = fx .mir @@ -279,7 +277,6 @@ pub(crate) fn codegen_fn_prelude<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, start_ } assert!(arg_abis_iter.next().is_none(), "ArgAbi left behind"); - fx.fn_abi = Some(fn_abi); assert!(block_params_iter.next().is_none(), "arg_value left behind"); self::comments::add_locals_header_comment(fx); diff --git a/src/abi/returning.rs b/src/abi/returning.rs index 0799a22c6e168..e0f399e616e5d 100644 --- a/src/abi/returning.rs +++ b/src/abi/returning.rs @@ -12,27 +12,15 @@ pub(super) fn codegen_return_param<'tcx>( ssa_analyzed: &rustc_index::IndexSlice, block_params_iter: &mut impl Iterator, ) -> CPlace<'tcx> { - let (ret_place, ret_param): (_, SmallVec<[_; 2]>) = match fx.fn_abi.as_ref().unwrap().ret.mode { + let (ret_place, ret_param): (_, SmallVec<[_; 2]>) = match fx.fn_abi.ret.mode { PassMode::Ignore | PassMode::Direct(_) | PassMode::Pair(_, _) | PassMode::Cast { .. } => { - let is_ssa = - ssa_analyzed[RETURN_PLACE].is_ssa(fx, fx.fn_abi.as_ref().unwrap().ret.layout.ty); - ( - super::make_local_place( - fx, - RETURN_PLACE, - fx.fn_abi.as_ref().unwrap().ret.layout, - is_ssa, - ), - smallvec![], - ) + let is_ssa = ssa_analyzed[RETURN_PLACE].is_ssa(fx, fx.fn_abi.ret.layout.ty); + (super::make_local_place(fx, RETURN_PLACE, fx.fn_abi.ret.layout, is_ssa), smallvec![]) } PassMode::Indirect { attrs: _, meta_attrs: None, on_stack: _ } => { let ret_param = block_params_iter.next().unwrap(); assert_eq!(fx.bcx.func.dfg.value_type(ret_param), fx.pointer_type); - ( - CPlace::for_ptr(Pointer::new(ret_param), fx.fn_abi.as_ref().unwrap().ret.layout), - smallvec![ret_param], - ) + (CPlace::for_ptr(Pointer::new(ret_param), fx.fn_abi.ret.layout), smallvec![ret_param]) } PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ } => { unreachable!("unsized return value") @@ -45,8 +33,8 @@ pub(super) fn codegen_return_param<'tcx>( Some(RETURN_PLACE), None, &ret_param, - &fx.fn_abi.as_ref().unwrap().ret.mode, - fx.fn_abi.as_ref().unwrap().ret.layout, + &fx.fn_abi.ret.mode, + fx.fn_abi.ret.layout, ); ret_place @@ -115,7 +103,7 @@ pub(super) fn codegen_with_call_return_arg<'tcx>( /// Codegen a return instruction with the right return value(s) if any. pub(crate) fn codegen_return(fx: &mut FunctionCx<'_, '_, '_>) { - match fx.fn_abi.as_ref().unwrap().ret.mode { + match fx.fn_abi.ret.mode { PassMode::Ignore | PassMode::Indirect { attrs: _, meta_attrs: None, on_stack: _ } => { fx.bcx.ins().return_(&[]); } diff --git a/src/base.rs b/src/base.rs index 9c66fa6d9ccac..049023f1560fd 100644 --- a/src/base.rs +++ b/src/base.rs @@ -87,7 +87,7 @@ pub(crate) fn codegen_fn<'tcx>( instance, symbol_name, mir, - fn_abi: Some(RevealAllLayoutCx(tcx).fn_abi_of_instance(instance, ty::List::empty())), + fn_abi: RevealAllLayoutCx(tcx).fn_abi_of_instance(instance, ty::List::empty()), bcx, block_map, diff --git a/src/common.rs b/src/common.rs index b038c7194cd57..cf0b065414d88 100644 --- a/src/common.rs +++ b/src/common.rs @@ -291,7 +291,7 @@ pub(crate) struct FunctionCx<'m, 'clif, 'tcx: 'm> { pub(crate) instance: Instance<'tcx>, pub(crate) symbol_name: String, pub(crate) mir: &'tcx Body<'tcx>, - pub(crate) fn_abi: Option<&'tcx FnAbi<'tcx, Ty<'tcx>>>, + pub(crate) fn_abi: &'tcx FnAbi<'tcx, Ty<'tcx>>, pub(crate) bcx: FunctionBuilder<'clif>, pub(crate) block_map: IndexVec, From 55a2446a53272ca6a34ebbcd09166e02749ccd1b Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 27 Mar 2024 20:07:36 +0000 Subject: [PATCH 36/40] Don't panic when layout can't be computed and fix generation of array type debuginfo --- src/debuginfo/types.rs | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/debuginfo/types.rs b/src/debuginfo/types.rs index 650de945c7bbc..7e5fafdd544aa 100644 --- a/src/debuginfo/types.rs +++ b/src/debuginfo/types.rs @@ -3,9 +3,10 @@ use gimli::write::{AttributeValue, UnitEntryId}; use rustc_codegen_ssa::debuginfo::type_names; use rustc_data_structures::fx::FxHashMap; +use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::{self, Ty, TyCtxt}; -use crate::{has_ptr_meta, DebugContext}; +use crate::{has_ptr_meta, DebugContext, RevealAllLayoutCx}; #[derive(Default)] pub(crate) struct TypeDebugContext<'tcx> { @@ -41,6 +42,7 @@ impl DebugContext { ty::Array(elem_ty, len) => self.array_type( tcx, type_dbg, + ty, *elem_ty, len.eval_target_usize(tcx, ty::ParamEnv::reveal_all()), ), @@ -83,9 +85,7 @@ impl DebugContext { type_entry.set(gimli::DW_AT_encoding, AttributeValue::Encoding(encoding)); type_entry.set( gimli::DW_AT_byte_size, - AttributeValue::Udata( - tcx.layout_of(ty::ParamEnv::reveal_all().and(ty)).expect("FIXME").size.bytes(), - ), + AttributeValue::Udata(RevealAllLayoutCx(tcx).layout_of(ty).size.bytes()), ); type_id @@ -95,12 +95,13 @@ impl DebugContext { &mut self, tcx: TyCtxt<'tcx>, type_dbg: &mut TypeDebugContext<'tcx>, + array_ty: Ty<'tcx>, elem_ty: Ty<'tcx>, len: u64, ) -> UnitEntryId { let elem_dw_ty = self.debug_type(tcx, type_dbg, elem_ty); - return_if_type_created_in_meantime!(type_dbg, elem_ty); + return_if_type_created_in_meantime!(type_dbg, array_ty); let array_type_id = self.dwarf.unit.add(self.dwarf.unit.root(), gimli::DW_TAG_array_type); let array_type_entry = self.dwarf.unit.get_mut(array_type_id); @@ -152,11 +153,7 @@ impl DebugContext { self.debug_type( tcx, type_dbg, - Ty::new_array( - tcx, - tcx.types.u8, - tcx.layout_of(ty::ParamEnv::reveal_all().and(ty)).unwrap().size.bytes(), - ), + Ty::new_array(tcx, tcx.types.u8, RevealAllLayoutCx(tcx).layout_of(ty).size.bytes()), ) } } From 0634aedbb7a1fba46a7991527b9d5c4517fb6924 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 27 Mar 2024 20:29:50 +0000 Subject: [PATCH 37/40] Implement debug_type for tuples --- src/debuginfo/types.rs | 47 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/src/debuginfo/types.rs b/src/debuginfo/types.rs index 7e5fafdd544aa..7baf0a3868d2c 100644 --- a/src/debuginfo/types.rs +++ b/src/debuginfo/types.rs @@ -56,7 +56,7 @@ impl DebugContext { // ty::FnDef(..) | ty::FnPtr(..) // ty::Closure(..) // ty::Adt(def, ..) - // ty::Tuple(_) + ty::Tuple(components) => self.tuple_type(tcx, type_dbg, ty, *components), // ty::Param(_) // FIXME implement remaining types and add unreachable!() to the fallback branch _ => self.placeholder_for_type(tcx, type_dbg, ty), @@ -144,6 +144,51 @@ impl DebugContext { } } + fn tuple_type<'tcx>( + &mut self, + tcx: TyCtxt<'tcx>, + type_dbg: &mut TypeDebugContext<'tcx>, + tuple_type: Ty<'tcx>, + components: &'tcx [Ty<'tcx>], + ) -> UnitEntryId { + let components = components + .into_iter() + .map(|&ty| (ty, self.debug_type(tcx, type_dbg, ty))) + .collect::>(); + + return_if_type_created_in_meantime!(type_dbg, tuple_type); + + let name = type_names::compute_debuginfo_type_name(tcx, tuple_type, false); + let layout = RevealAllLayoutCx(tcx).layout_of(tuple_type); + + let tuple_type_id = + self.dwarf.unit.add(self.dwarf.unit.root(), gimli::DW_TAG_structure_type); + let tuple_entry = self.dwarf.unit.get_mut(tuple_type_id); + tuple_entry.set(gimli::DW_AT_name, AttributeValue::StringRef(self.dwarf.strings.add(name))); + tuple_entry.set(gimli::DW_AT_byte_size, AttributeValue::Udata(layout.size.bytes())); + tuple_entry.set(gimli::DW_AT_alignment, AttributeValue::Udata(layout.align.pref.bytes())); + + for (i, (ty, dw_ty)) in components.into_iter().enumerate() { + let member_id = self.dwarf.unit.add(tuple_type_id, gimli::DW_TAG_member); + let member_entry = self.dwarf.unit.get_mut(member_id); + member_entry.set( + gimli::DW_AT_name, + AttributeValue::StringRef(self.dwarf.strings.add(format!("__{i}"))), + ); + member_entry.set(gimli::DW_AT_type, AttributeValue::UnitRef(dw_ty)); + member_entry.set( + gimli::DW_AT_alignment, + AttributeValue::Udata(RevealAllLayoutCx(tcx).layout_of(ty).align.pref.bytes()), + ); + member_entry.set( + gimli::DW_AT_data_member_location, + AttributeValue::Udata(layout.fields.offset(i).bytes()), + ); + } + + tuple_type_id + } + fn placeholder_for_type<'tcx>( &mut self, tcx: TyCtxt<'tcx>, From 4f0cde1e51dbfb20a2260a0fc83a5c1359b4dc9d Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 27 Mar 2024 20:36:49 +0000 Subject: [PATCH 38/40] Define return type for functions in debuginfo --- src/base.rs | 9 ++++++--- src/debuginfo/mod.rs | 10 ++++++++++ src/driver/aot.rs | 1 + src/driver/jit.rs | 10 +++++++++- 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/base.rs b/src/base.rs index 049023f1560fd..b4ea4e10a3d0f 100644 --- a/src/base.rs +++ b/src/base.rs @@ -11,7 +11,7 @@ use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_monomorphize::is_call_from_compiler_builtins_to_upstream_monomorphization; use crate::constant::ConstantCx; -use crate::debuginfo::FunctionDebugContext; +use crate::debuginfo::{FunctionDebugContext, TypeDebugContext}; use crate::prelude::*; use crate::pretty_clif::CommentWriter; @@ -26,6 +26,7 @@ pub(crate) struct CodegenedFunction { pub(crate) fn codegen_fn<'tcx>( tcx: TyCtxt<'tcx>, cx: &mut crate::CodegenCx, + type_dbg: &mut TypeDebugContext<'tcx>, cached_func: Function, module: &mut dyn Module, instance: Instance<'tcx>, @@ -69,8 +70,10 @@ pub(crate) fn codegen_fn<'tcx>( let pointer_type = target_config.pointer_type(); let clif_comments = crate::pretty_clif::CommentWriter::new(tcx, instance); + let fn_abi = RevealAllLayoutCx(tcx).fn_abi_of_instance(instance, ty::List::empty()); + let func_debug_cx = if let Some(debug_context) = &mut cx.debug_context { - Some(debug_context.define_function(tcx, instance, &symbol_name, mir.span)) + Some(debug_context.define_function(tcx, type_dbg, instance, fn_abi, &symbol_name, mir.span)) } else { None }; @@ -87,7 +90,7 @@ pub(crate) fn codegen_fn<'tcx>( instance, symbol_name, mir, - fn_abi: RevealAllLayoutCx(tcx).fn_abi_of_instance(instance, ty::List::empty()), + fn_abi, bcx, block_map, diff --git a/src/debuginfo/mod.rs b/src/debuginfo/mod.rs index 2bab897dbcd87..1bb0e59051372 100644 --- a/src/debuginfo/mod.rs +++ b/src/debuginfo/mod.rs @@ -20,6 +20,7 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::DefIdMap; use rustc_session::Session; use rustc_span::{SourceFileHash, StableSourceFileId}; +use rustc_target::abi::call::FnAbi; pub(crate) use self::emit::{DebugReloc, DebugRelocName}; pub(crate) use self::types::TypeDebugContext; @@ -188,7 +189,9 @@ impl DebugContext { pub(crate) fn define_function<'tcx>( &mut self, tcx: TyCtxt<'tcx>, + type_dbg: &mut TypeDebugContext<'tcx>, instance: Instance<'tcx>, + fn_abi: &'tcx FnAbi<'tcx, Ty<'tcx>>, linkage_name: &str, function_span: Span, ) -> FunctionDebugContext { @@ -240,7 +243,14 @@ impl DebugContext { entry.set(gimli::DW_AT_decl_file, AttributeValue::FileIndex(Some(file_id))); entry.set(gimli::DW_AT_decl_line, AttributeValue::Udata(line)); + if !fn_abi.ret.is_ignore() { + let return_dw_ty = self.debug_type(tcx, type_dbg, fn_abi.ret.layout.ty); + let entry = self.dwarf.unit.get_mut(entry_id); + entry.set(gimli::DW_AT_type, AttributeValue::UnitRef(return_dw_ty)); + } + if tcx.is_reachable_non_generic(instance.def_id()) { + let entry = self.dwarf.unit.get_mut(entry_id); entry.set(gimli::DW_AT_external, AttributeValue::FlagPresent); } diff --git a/src/driver/aot.rs b/src/driver/aot.rs index e5caceab3456a..75268341a4fe0 100644 --- a/src/driver/aot.rs +++ b/src/driver/aot.rs @@ -470,6 +470,7 @@ fn module_codegen( let codegened_function = crate::base::codegen_fn( tcx, &mut cx, + &mut type_dbg, Function::new(), &mut module, inst, diff --git a/src/driver/jit.rs b/src/driver/jit.rs index 6b2b946db02b6..6dbc3f191278d 100644 --- a/src/driver/jit.rs +++ b/src/driver/jit.rs @@ -12,6 +12,7 @@ use rustc_middle::mir::mono::MonoItem; use rustc_session::Session; use rustc_span::Symbol; +use crate::debuginfo::TypeDebugContext; use crate::{prelude::*, BackendConfig}; use crate::{CodegenCx, CodegenMode}; @@ -229,7 +230,14 @@ pub(crate) fn codegen_and_compile_fn<'tcx>( crate::PrintOnPanic(|| format!("{:?} {}", instance, tcx.symbol_name(instance).name)); let cached_func = std::mem::replace(&mut cached_context.func, Function::new()); - let codegened_func = crate::base::codegen_fn(tcx, cx, cached_func, module, instance); + let codegened_func = crate::base::codegen_fn( + tcx, + cx, + &mut TypeDebugContext::default(), + cached_func, + module, + instance, + ); crate::base::compile_fn(cx, cached_context, module, codegened_func); }); From ef0b3d1def7cb38df376768810aae31de44b349e Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 28 Mar 2024 11:17:20 +0000 Subject: [PATCH 39/40] Rustup to rustc 1.79.0-nightly (c9f8f3438 2024-03-27) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index e9e7f90bbb487..612fc61ec27df 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-03-26" +channel = "nightly-2024-03-28" components = ["rust-src", "rustc-dev", "llvm-tools"] From 09fae60a86b848a2fc0ad219ecc4e438dc1eef86 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 28 Mar 2024 11:38:15 +0000 Subject: [PATCH 40/40] Fix rustc test suite --- scripts/test_rustc_tests.sh | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 96f71bcf7670d..f42a008dc0c10 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -145,6 +145,19 @@ index ea06b620c4c..b969d0009c6 100644 ifdef RUSTC_LINKER RUSTC := \$(RUSTC) -Clinker='\$(RUSTC_LINKER)' RUSTDOC := \$(RUSTDOC) -Clinker='\$(RUSTC_LINKER)' +diff --git a/src/tools/run-make-support/src/rustdoc.rs b/src/tools/run-make-support/src/rustdoc.rs +index 9607ff02f96..b7d97caf9a2 100644 +--- a/src/tools/run-make-support/src/rustdoc.rs ++++ b/src/tools/run-make-support/src/rustdoc.rs +@@ -34,8 +34,6 @@ pub fn bare() -> Self { + /// Construct a \`rustdoc\` invocation with \`-L \$(TARGET_RPATH_DIR)\` set. + pub fn new() -> Self { + let mut cmd = setup_common(); +- let target_rpath_dir = env::var_os("TARGET_RPATH_DIR").unwrap(); +- cmd.arg(format!("-L{}", target_rpath_dir.to_string_lossy())); + Self { cmd } + } + EOF echo "[TEST] rustc test suite"