about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/debuginfo.rs54
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/mod.rs12
-rw-r--r--tests/debuginfo/constant-ordering-prologue.rs35
3 files changed, 83 insertions, 18 deletions
diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
index 5b36a11aa25..0cf19eff1b0 100644
--- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
@@ -1,4 +1,5 @@
 use std::collections::hash_map::Entry;
+use std::marker::PhantomData;
 use std::ops::Range;
 
 use rustc_data_structures::fx::FxHashMap;
@@ -14,7 +15,7 @@ use rustc_target::abi::{Abi, FieldIdx, FieldsShape, Size, VariantIdx};
 
 use super::operand::{OperandRef, OperandValue};
 use super::place::{PlaceRef, PlaceValue};
-use super::{FunctionCx, LocalRef};
+use super::{FunctionCx, LocalRef, PerLocalVarDebugInfoIndexVec};
 use crate::traits::*;
 
 pub struct FunctionDebugContext<'tcx, S, L> {
@@ -48,6 +49,17 @@ pub struct PerLocalVarDebugInfo<'tcx, D> {
     pub projection: &'tcx ty::List<mir::PlaceElem<'tcx>>,
 }
 
+/// Information needed to emit a constant.
+pub struct ConstDebugInfo<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> {
+    pub name: String,
+    pub source_info: mir::SourceInfo,
+    pub operand: OperandRef<'tcx, Bx::Value>,
+    pub dbg_var: Bx::DIVariable,
+    pub dbg_loc: Bx::DILocation,
+    pub fragment: Option<Range<Size>>,
+    pub _phantom: PhantomData<&'a ()>,
+}
+
 #[derive(Clone, Copy, Debug)]
 pub struct DebugScope<S, L> {
     pub dbg_scope: S,
@@ -427,11 +439,25 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         }
     }
 
-    pub(crate) fn debug_introduce_locals(&self, bx: &mut Bx) {
+    pub(crate) fn debug_introduce_locals(
+        &self,
+        bx: &mut Bx,
+        consts: Vec<ConstDebugInfo<'a, 'tcx, Bx>>,
+    ) {
         if bx.sess().opts.debuginfo == DebugInfo::Full || !bx.sess().fewer_names() {
             for local in self.locals.indices() {
                 self.debug_introduce_local(bx, local);
             }
+
+            for ConstDebugInfo { name, source_info, operand, dbg_var, dbg_loc, fragment, .. } in
+                consts.into_iter()
+            {
+                self.set_debug_loc(bx, source_info);
+                let base = FunctionCx::spill_operand_to_stack(operand, Some(name), bx);
+                bx.clear_dbg_loc();
+
+                bx.dbg_var_addr(dbg_var, dbg_loc, base.val.llval, Size::ZERO, &[], fragment);
+            }
         }
     }
 
@@ -439,7 +465,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
     pub(crate) fn compute_per_local_var_debug_info(
         &self,
         bx: &mut Bx,
-    ) -> Option<IndexVec<mir::Local, Vec<PerLocalVarDebugInfo<'tcx, Bx::DIVariable>>>> {
+    ) -> Option<(
+        PerLocalVarDebugInfoIndexVec<'tcx, Bx::DIVariable>,
+        Vec<ConstDebugInfo<'a, 'tcx, Bx>>,
+    )> {
         let full_debug_info = self.cx.sess().opts.debuginfo == DebugInfo::Full;
 
         let target_is_msvc = self.cx.sess().target.is_like_msvc;
@@ -449,6 +478,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         }
 
         let mut per_local = IndexVec::from_elem(vec![], &self.mir.local_decls);
+        let mut constants = vec![];
         let mut params_seen: FxHashMap<_, Bx::DIVariable> = Default::default();
         for var in &self.mir.var_debug_info {
             let dbg_scope_and_span = if full_debug_info {
@@ -545,23 +575,19 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                         let Some(dbg_loc) = self.dbg_loc(var.source_info) else { continue };
 
                         let operand = self.eval_mir_constant_to_operand(bx, &c);
-                        self.set_debug_loc(bx, var.source_info);
-                        let base =
-                            Self::spill_operand_to_stack(operand, Some(var.name.to_string()), bx);
-                        bx.clear_dbg_loc();
-
-                        bx.dbg_var_addr(
+                        constants.push(ConstDebugInfo {
+                            name: var.name.to_string(),
+                            source_info: var.source_info,
+                            operand,
                             dbg_var,
                             dbg_loc,
-                            base.val.llval,
-                            Size::ZERO,
-                            &[],
                             fragment,
-                        );
+                            _phantom: PhantomData,
+                        });
                     }
                 }
             }
         }
-        Some(per_local)
+        Some((per_local, constants))
     }
 }
diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs
index 61e9b9bd774..7e9cca4f366 100644
--- a/compiler/rustc_codegen_ssa/src/mir/mod.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs
@@ -41,6 +41,9 @@ enum CachedLlbb<T> {
     Skip,
 }
 
+type PerLocalVarDebugInfoIndexVec<'tcx, V> =
+    IndexVec<mir::Local, Vec<PerLocalVarDebugInfo<'tcx, V>>>;
+
 /// Master context for codegenning from MIR.
 pub struct FunctionCx<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> {
     instance: Instance<'tcx>,
@@ -107,8 +110,7 @@ pub struct FunctionCx<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> {
 
     /// All `VarDebugInfo` from the MIR body, partitioned by `Local`.
     /// This is `None` if no variable debuginfo/names are needed.
-    per_local_var_debug_info:
-        Option<IndexVec<mir::Local, Vec<PerLocalVarDebugInfo<'tcx, Bx::DIVariable>>>>,
+    per_local_var_debug_info: Option<PerLocalVarDebugInfoIndexVec<'tcx, Bx::DIVariable>>,
 
     /// Caller location propagated if this function has `#[track_caller]`.
     caller_location: Option<OperandRef<'tcx, Bx::Value>>,
@@ -216,7 +218,9 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
     // monomorphization, and if there is an error during collection then codegen never starts -- so
     // we don't have to do it again.
 
-    fx.per_local_var_debug_info = fx.compute_per_local_var_debug_info(&mut start_bx);
+    let (per_local_var_debug_info, consts_debug_info) =
+        fx.compute_per_local_var_debug_info(&mut start_bx).unzip();
+    fx.per_local_var_debug_info = per_local_var_debug_info;
 
     let memory_locals = analyze::non_ssa_locals(&fx);
 
@@ -267,7 +271,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
     fx.initialize_locals(local_values);
 
     // Apply debuginfo to the newly allocated locals.
-    fx.debug_introduce_locals(&mut start_bx);
+    fx.debug_introduce_locals(&mut start_bx, consts_debug_info.unwrap_or_default());
 
     // If the backend supports coverage, and coverage is enabled for this function,
     // do any necessary start-of-function codegen (e.g. locals for MC/DC bitmaps).
diff --git a/tests/debuginfo/constant-ordering-prologue.rs b/tests/debuginfo/constant-ordering-prologue.rs
new file mode 100644
index 00000000000..f2d4fd37ce3
--- /dev/null
+++ b/tests/debuginfo/constant-ordering-prologue.rs
@@ -0,0 +1,35 @@
+//@ min-lldb-version: 310
+
+//@ compile-flags:-g
+
+// === GDB TESTS ===================================================================================
+
+// gdb-command:break constant_ordering_prologue::binding
+// gdb-command:run
+
+// gdb-command:print a
+// gdb-check: = 19
+// gdb-command:print b
+// gdb-check: = 20
+// gdb-command:print c
+// gdb-check: = 21.5
+
+// === LLDB TESTS ==================================================================================
+
+// lldb-command:b "constant_ordering_prologue::binding"
+// lldb-command:run
+
+// lldb-command:print a
+// lldb-check: = 19
+// lldb-command:print b
+// lldb-check: = 20
+// lldb-command:print c
+// lldb-check: = 21.5
+
+fn binding(a: i64, b: u64, c: f64) {
+    let x = 0;
+}
+
+fn main() {
+    binding(19, 20, 21.5);
+}