From: "Joonas Niilola" <juippis@gentoo.org>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] repo/gentoo:master commit in: dev-lang/rust/files/, dev-lang/rust/
Date: Tue, 10 Dec 2024 07:22:15 +0000 (UTC) [thread overview]
Message-ID: <1733815200.418188d532488b5ecfeaf19e938bed3f1aaa6d15.juippis@gentoo> (raw)
commit: 418188d532488b5ecfeaf19e938bed3f1aaa6d15
Author: Joonas Niilola <juippis <AT> gentoo <DOT> org>
AuthorDate: Tue Dec 10 07:20:00 2024 +0000
Commit: Joonas Niilola <juippis <AT> gentoo <DOT> org>
CommitDate: Tue Dec 10 07:20:00 2024 +0000
URL: https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=418188d5
dev-lang/rust: fix LLVM assertion with debug info in 1.83.0
- the patch is rebased for 1.83, but merged upstream to 1.84.
Closes: https://bugs.gentoo.org/946158
Signed-off-by: Joonas Niilola <juippis <AT> gentoo.org>
.../rust/files/1.83.0-dwarf-llvm-assertion.patch | 242 +++++++++++++++++++++
.../{rust-1.83.0.ebuild => rust-1.83.0-r1.ebuild} | 1 +
2 files changed, 243 insertions(+)
diff --git a/dev-lang/rust/files/1.83.0-dwarf-llvm-assertion.patch b/dev-lang/rust/files/1.83.0-dwarf-llvm-assertion.patch
new file mode 100644
index 000000000000..64d00ac0aaaf
--- /dev/null
+++ b/dev-lang/rust/files/1.83.0-dwarf-llvm-assertion.patch
@@ -0,0 +1,242 @@
+From 1dc106121b62562ead6e7d612fa136dc4b35cd5d Mon Sep 17 00:00:00 2001
+From: Kyle Huey <khuey@kylehuey.com>
+Date: Mon, 4 Nov 2024 11:38:14 -0800
+Subject: [PATCH] Add discriminators to DILocations when multiple functions are
+ inlined into a single point.
+
+LLVM does not expect to ever see multiple dbg_declares for the same variable at the same
+location with different values. proc-macros make it possible for arbitrary code,
+including multiple calls that get inlined, to happen at any given location in the source
+code. Add discriminators when that happens so these locations are different to LLVM.
+
+This may interfere with the AddDiscriminators pass in LLVM, which is added by the
+unstable flag -Zdebug-info-for-profiling.
+
+Fixes #131944
+---
+ .../src/debuginfo/create_scope_map.rs | 60 ++++++++++++++++++-
+ compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 4 ++
+ .../rustc_llvm/llvm-wrapper/RustWrapper.cpp | 8 +++
+ .../auxiliary/macro_def.rs | 11 ++++
+ .../mir_inlined_twice_var_locs.rs | 53 ++++++++++++++++
+ 5 files changed, 133 insertions(+), 3 deletions(-)
+ create mode 100644 tests/codegen/debuginfo-proc-macro/auxiliary/macro_def.rs
+ create mode 100644 tests/codegen/debuginfo-proc-macro/mir_inlined_twice_var_locs.rs
+
+diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs b/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs
+index ac6c2fb1b83a6..0f1909486ec7e 100644
+--- a/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs
++++ b/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs
+@@ -1,11 +1,15 @@
++use std::collections::hash_map::Entry;
++
+ use rustc_codegen_ssa::mir::debuginfo::{DebugScope, FunctionDebugContext};
+ use rustc_codegen_ssa::traits::*;
++use rustc_data_structures::fx::FxHashMap;
+ use rustc_index::Idx;
+ use rustc_index::bit_set::BitSet;
+ use rustc_middle::mir::{Body, SourceScope};
+ use rustc_middle::ty::layout::FnAbiOf;
+ use rustc_middle::ty::{self, Instance};
+ use rustc_session::config::DebugInfo;
++use rustc_span::BytePos;
+
+ use super::metadata::file_metadata;
+ use super::utils::DIB;
+@@ -37,10 +41,20 @@ pub(crate) fn compute_mir_scopes<'ll, 'tcx>(
+ None
+ };
+ let mut instantiated = BitSet::new_empty(mir.source_scopes.len());
++ let mut discriminators = FxHashMap::default();
+ // Instantiate all scopes.
+ for idx in 0..mir.source_scopes.len() {
+ let scope = SourceScope::new(idx);
+- make_mir_scope(cx, instance, mir, &variables, debug_context, &mut instantiated, scope);
++ make_mir_scope(
++ cx,
++ instance,
++ mir,
++ &variables,
++ debug_context,
++ &mut instantiated,
++ &mut discriminators,
++ scope,
++ );
+ }
+ assert!(instantiated.count() == mir.source_scopes.len());
+ }
+@@ -52,6 +66,7 @@ fn make_mir_scope<'ll, 'tcx>(
+ variables: &Option<BitSet<SourceScope>>,
+ debug_context: &mut FunctionDebugContext<'tcx, &'ll DIScope, &'ll DILocation>,
+ instantiated: &mut BitSet<SourceScope>,
++ discriminators: &mut FxHashMap<BytePos, u32>,
+ scope: SourceScope,
+ ) {
+ if instantiated.contains(scope) {
+@@ -60,7 +75,16 @@ fn make_mir_scope<'ll, 'tcx>(
+
+ let scope_data = &mir.source_scopes[scope];
+ let parent_scope = if let Some(parent) = scope_data.parent_scope {
+- make_mir_scope(cx, instance, mir, variables, debug_context, instantiated, parent);
++ make_mir_scope(
++ cx,
++ instance,
++ mir,
++ variables,
++ debug_context,
++ instantiated,
++ discriminators,
++ parent,
++ );
+ debug_context.scopes[parent]
+ } else {
+ // The root is the function itself.
+@@ -117,7 +141,37 @@ fn make_mir_scope<'ll, 'tcx>(
+ // FIXME(eddyb) this doesn't account for the macro-related
+ // `Span` fixups that `rustc_codegen_ssa::mir::debuginfo` does.
+ let callsite_scope = parent_scope.adjust_dbg_scope_for_span(cx, callsite_span);
+- cx.dbg_loc(callsite_scope, parent_scope.inlined_at, callsite_span)
++ let loc = cx.dbg_loc(callsite_scope, parent_scope.inlined_at, callsite_span);
++
++ // NB: In order to produce proper debug info for variables (particularly
++ // arguments) in multiply-inline functions, LLVM expects to see a single
++ // DILocalVariable with multiple different DILocations in the IR. While
++ // the source information for each DILocation would be identical, their
++ // inlinedAt attributes will be unique to the particular callsite.
++ //
++ // We generate DILocations here based on the callsite's location in the
++ // source code. A single location in the source code usually can't
++ // produce multiple distinct calls so this mostly works, until
++ // proc-macros get involved. A proc-macro can generate multiple calls
++ // at the same span, which breaks the assumption that we're going to
++ // produce a unique DILocation for every scope we process here. We
++ // have to explicitly add discriminators if we see inlines into the
++ // same source code location.
++ //
++ // Note further that we can't key this hashtable on the span itself,
++ // because these spans could have distinct SyntaxContexts. We have
++ // to key on exactly what we're giving to LLVM.
++ match discriminators.entry(callsite_span.lo()) {
++ Entry::Occupied(mut o) => {
++ *o.get_mut() += 1;
++ unsafe { llvm::LLVMRustDILocationCloneWithBaseDiscriminator(loc, *o.get()) }
++ .expect("Failed to encode discriminator in DILocation")
++ }
++ Entry::Vacant(v) => {
++ v.insert(0);
++ loc
++ }
++ }
+ });
+
+ debug_context.scopes[scope] = DebugScope {
+diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+index 3d2e270a3868e..75a5ec44c2285 100644
+--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
++++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+@@ -2174,6 +2174,10 @@ unsafe extern "C" {
+ Scope: &'a DIScope,
+ InlinedAt: Option<&'a DILocation>,
+ ) -> &'a DILocation;
++ pub fn LLVMRustDILocationCloneWithBaseDiscriminator<'a>(
++ Location: &'a DILocation,
++ BD: c_uint,
++ ) -> Option<&'a DILocation>;
+ pub fn LLVMRustDIBuilderCreateOpDeref() -> u64;
+ pub fn LLVMRustDIBuilderCreateOpPlusUconst() -> u64;
+ pub fn LLVMRustDIBuilderCreateOpLLVMFragment() -> u64;
+diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
+index 9330c83b7f230..cd70c3f266920 100644
+--- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
++++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
+@@ -1305,6 +1305,14 @@ LLVMRustDIBuilderCreateDebugLocation(unsigned Line, unsigned Column,
+ return wrap(Loc);
+ }
+
++extern "C" LLVMMetadataRef
++LLVMRustDILocationCloneWithBaseDiscriminator(LLVMMetadataRef Location,
++ unsigned BD) {
++ DILocation *Loc = unwrapDIPtr<DILocation>(Location);
++ auto NewLoc = Loc->cloneWithBaseDiscriminator(BD);
++ return wrap(NewLoc.has_value() ? NewLoc.value() : nullptr);
++}
++
+ extern "C" uint64_t LLVMRustDIBuilderCreateOpDeref() {
+ return dwarf::DW_OP_deref;
+ }
+diff --git a/tests/codegen/debuginfo-proc-macro/auxiliary/macro_def.rs b/tests/codegen/debuginfo-proc-macro/auxiliary/macro_def.rs
+new file mode 100644
+index 0000000000000..159ecfd09743d
+--- /dev/null
++++ b/tests/codegen/debuginfo-proc-macro/auxiliary/macro_def.rs
+@@ -0,0 +1,11 @@
++//@ force-host
++//@ no-prefer-dynamic
++#![crate_type = "proc-macro"]
++
++extern crate proc_macro;
++use proc_macro::*;
++
++#[proc_macro]
++pub fn square_twice(_item: TokenStream) -> TokenStream {
++ "(square(env::vars().count() as i32), square(env::vars().count() as i32))".parse().unwrap()
++}
+diff --git a/tests/codegen/debuginfo-proc-macro/mir_inlined_twice_var_locs.rs b/tests/codegen/debuginfo-proc-macro/mir_inlined_twice_var_locs.rs
+new file mode 100644
+index 0000000000000..c3858044c0c9f
+--- /dev/null
++++ b/tests/codegen/debuginfo-proc-macro/mir_inlined_twice_var_locs.rs
+@@ -0,0 +1,53 @@
++//@ min-llvm-version: 19
++//@ compile-flags: -Cdebuginfo=2 -Copt-level=0 -Zmir-enable-passes=+Inline
++// MSVC is different because of the individual allocas.
++//@ ignore-msvc
++
++//@ aux-build:macro_def.rs
++
++// Find the variable.
++// CHECK-DAG: ![[#var_dbg:]] = !DILocalVariable(name: "n",{{( arg: 1,)?}} scope: ![[#var_scope:]]
++
++// Find both dbg_declares. These will proceed the variable metadata, of course, so we're looking
++// backwards.
++// CHECK-DAG: dbg_declare(ptr %n.dbg.spill{{[0-9]}}, ![[#var_dbg]], !DIExpression(), ![[#var_loc2:]])
++// CHECK-DAG: dbg_declare(ptr %n.dbg.spill, ![[#var_dbg]], !DIExpression(), ![[#var_loc1:]])
++
++// Find the first location definition, looking forwards again.
++// CHECK: ![[#var_loc1]] = !DILocation
++// CHECK-SAME: scope: ![[#var_scope:]], inlinedAt: ![[#var_inlinedAt1:]]
++
++// Find the first location's inlinedAt
++// NB: If we fail here it's *probably* because we failed to produce two
++// different locations and ended up reusing an earlier one.
++// CHECK: ![[#var_inlinedAt1]] = !DILocation
++// CHECK-SAME: scope: ![[var_inlinedAt1_scope:]]
++
++// Find the second location definition, still looking forwards.
++// NB: If we failed to produce two different locations, the test will
++// definitely fail by this point (if it hasn't already) because we won't
++// be able to find the same line again.
++// CHECK: ![[#var_loc2]] = !DILocation
++// CHECK-SAME: scope: ![[#var_scope]], inlinedAt: ![[#var_inlinedAt2:]]
++
++// Find the second location's inlinedAt.
++// CHECK: ![[#var_inlinedAt2]] = !DILocation
++// CHECK-SAME: scope: ![[#var_inlinedAt2_scope:]]
++
++// Finally, check that a discriminator was emitted for the second scope.
++// FIXMEkhuey ideally we would check that *either* scope has a discriminator
++// but I don't know that it's possible to check that with FileCheck.
++// CHECK: ![[#var_inlinedAt2_scope]] = !DILexicalBlockFile
++// CHECK-SAME: discriminator: [[#]]
++extern crate macro_def;
++
++use std::env;
++
++fn square(n: i32) -> i32 {
++ n * n
++}
++
++fn main() {
++ let (z1, z2) = macro_def::square_twice!();
++ println!("{z1} == {z2}");
++}
diff --git a/dev-lang/rust/rust-1.83.0.ebuild b/dev-lang/rust/rust-1.83.0-r1.ebuild
similarity index 99%
rename from dev-lang/rust/rust-1.83.0.ebuild
rename to dev-lang/rust/rust-1.83.0-r1.ebuild
index b0585b3218c1..db171b2fb483 100644
--- a/dev-lang/rust/rust-1.83.0.ebuild
+++ b/dev-lang/rust/rust-1.83.0-r1.ebuild
@@ -135,6 +135,7 @@ PATCHES=(
"${FILESDIR}"/1.83.0-cross-compile-libz.patch
#"${FILESDIR}"/1.72.0-bump-libc-deps-to-0.2.146.patch # pending refresh
"${FILESDIR}"/1.67.0-doc-wasm.patch
+ "${FILESDIR}"/1.83.0-dwarf-llvm-assertion.patch
)
clear_vendor_checksums() {
next reply other threads:[~2024-12-10 7:22 UTC|newest]
Thread overview: 37+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-12-10 7:22 Joonas Niilola [this message]
-- strict thread matches above, loose matches on Subject: below --
2025-02-25 19:29 [gentoo-commits] repo/gentoo:master commit in: dev-lang/rust/files/, dev-lang/rust/ Sam James
2025-02-05 18:33 Arthur Zamarin
2024-12-01 8:23 Arthur Zamarin
2024-10-12 4:04 Sam James
2024-02-11 6:01 Sam James
2023-10-02 8:13 WANG Xuerui
2023-08-04 12:30 WANG Xuerui
2023-07-20 18:48 Ionen Wolkens
2023-02-09 20:36 Georgy Yakovlev
2022-11-13 19:14 Georgy Yakovlev
2022-10-20 18:19 Georgy Yakovlev
2022-10-13 17:41 Georgy Yakovlev
2022-09-23 20:06 Georgy Yakovlev
2022-09-16 1:46 Georgy Yakovlev
2022-09-15 3:15 Georgy Yakovlev
2021-12-06 22:42 Georgy Yakovlev
2021-08-09 19:03 Georgy Yakovlev
2021-06-18 9:16 Georgy Yakovlev
2021-06-18 7:46 Georgy Yakovlev
2021-05-02 16:45 Georgy Yakovlev
2021-04-18 1:24 Georgy Yakovlev
2021-04-05 4:27 Georgy Yakovlev
2020-11-24 0:41 Georgy Yakovlev
2020-10-28 1:42 Georgy Yakovlev
2020-06-05 8:53 Stefan Strogin
2020-04-10 11:28 Stefan Strogin
2020-03-28 19:08 Georgy Yakovlev
2019-09-26 22:06 Georgy Yakovlev
2019-06-19 0:35 Georgy Yakovlev
2019-05-26 6:27 Georgy Yakovlev
2019-04-24 16:31 Georgy Yakovlev
2019-04-14 8:03 Georgy Yakovlev
2019-03-07 4:40 Georgy Yakovlev
2019-01-26 3:50 Georgy Yakovlev
2018-10-18 9:05 Dirkjan Ochtman
2016-10-24 5:27 Doug Goldstein
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1733815200.418188d532488b5ecfeaf19e938bed3f1aaa6d15.juippis@gentoo \
--to=juippis@gentoo.org \
--cc=gentoo-commits@lists.gentoo.org \
--cc=gentoo-dev@lists.gentoo.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox