public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
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() {


             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