@@ -8,7 +8,7 @@ use rustc_span::symbol::{kw, Symbol};
88use rustc_span:: { BytePos , Span } ;
99use rustc_target:: abi:: { LayoutOf , Size } ;
1010
11- use super :: operand:: OperandValue ;
11+ use super :: operand:: { OperandRef , OperandValue } ;
1212use super :: place:: PlaceRef ;
1313use super :: { FunctionCx , LocalRef } ;
1414
@@ -116,6 +116,24 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
116116 span
117117 }
118118
119+ fn spill_operand_to_stack (
120+ operand : & OperandRef < ' tcx , Bx :: Value > ,
121+ name : Option < String > ,
122+ bx : & mut Bx ,
123+ ) -> PlaceRef < ' tcx , Bx :: Value > {
124+ // "Spill" the value onto the stack, for debuginfo,
125+ // without forcing non-debuginfo uses of the local
126+ // to also load from the stack every single time.
127+ // FIXME(#68817) use `llvm.dbg.value` instead,
128+ // at least for the cases which LLVM handles correctly.
129+ let spill_slot = PlaceRef :: alloca ( bx, operand. layout ) ;
130+ if let Some ( name) = name {
131+ bx. set_var_name ( spill_slot. llval , & ( name + ".dbg.spill" ) ) ;
132+ }
133+ operand. val . store ( bx, spill_slot) ;
134+ spill_slot
135+ }
136+
119137 /// Apply debuginfo and/or name, after creating the `alloca` for a local,
120138 /// or initializing the local with an operand (whichever applies).
121139 pub fn debug_introduce_local ( & self , bx : & mut Bx , local : mir:: Local ) {
@@ -226,17 +244,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
226244 return ;
227245 }
228246
229- // "Spill" the value onto the stack, for debuginfo,
230- // without forcing non-debuginfo uses of the local
231- // to also load from the stack every single time.
232- // FIXME(#68817) use `llvm.dbg.value` instead,
233- // at least for the cases which LLVM handles correctly.
234- let spill_slot = PlaceRef :: alloca ( bx, operand. layout ) ;
235- if let Some ( name) = name {
236- bx. set_var_name ( spill_slot. llval , & ( name + ".dbg.spill" ) ) ;
237- }
238- operand. val . store ( bx, spill_slot) ;
239- spill_slot
247+ Self :: spill_operand_to_stack ( operand, name, bx)
240248 }
241249
242250 LocalRef :: Place ( place) => * place,
@@ -308,6 +316,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
308316 /// Partition all `VarDebugInfo` in `self.mir`, by their base `Local`.
309317 pub fn compute_per_local_var_debug_info (
310318 & self ,
319+ bx : & mut Bx ,
311320 ) -> Option < IndexVec < mir:: Local , Vec < PerLocalVarDebugInfo < ' tcx , Bx :: DIVariable > > > > {
312321 let full_debug_info = self . cx . sess ( ) . opts . debuginfo == DebugInfo :: Full ;
313322
@@ -322,31 +331,63 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
322331 } else {
323332 None
324333 } ;
334+
325335 let dbg_var = dbg_scope_and_span. map ( |( dbg_scope, _, span) | {
326- let place = var. place ;
327- let var_ty = self . monomorphized_place_ty ( place. as_ref ( ) ) ;
328- let var_kind = if self . mir . local_kind ( place. local ) == mir:: LocalKind :: Arg
329- && place. projection . is_empty ( )
330- && var. source_info . scope == mir:: OUTERMOST_SOURCE_SCOPE
331- {
332- let arg_index = place. local . index ( ) - 1 ;
333-
334- // FIXME(eddyb) shouldn't `ArgumentVariable` indices be
335- // offset in closures to account for the hidden environment?
336- // Also, is this `+ 1` needed at all?
337- VariableKind :: ArgumentVariable ( arg_index + 1 )
338- } else {
339- VariableKind :: LocalVariable
336+ let ( var_ty, var_kind) = match var. value {
337+ mir:: VarDebugInfoContents :: Place ( place) => {
338+ let var_ty = self . monomorphized_place_ty ( place. as_ref ( ) ) ;
339+ let var_kind = if self . mir . local_kind ( place. local ) == mir:: LocalKind :: Arg
340+ && place. projection . is_empty ( )
341+ && var. source_info . scope == mir:: OUTERMOST_SOURCE_SCOPE
342+ {
343+ let arg_index = place. local . index ( ) - 1 ;
344+
345+ // FIXME(eddyb) shouldn't `ArgumentVariable` indices be
346+ // offset in closures to account for the hidden environment?
347+ // Also, is this `+ 1` needed at all?
348+ VariableKind :: ArgumentVariable ( arg_index + 1 )
349+ } else {
350+ VariableKind :: LocalVariable
351+ } ;
352+ ( var_ty, var_kind)
353+ }
354+ mir:: VarDebugInfoContents :: Const ( c) => {
355+ let ty = self . monomorphize ( c. literal . ty ) ;
356+ ( ty, VariableKind :: LocalVariable )
357+ }
340358 } ;
359+
341360 self . cx . create_dbg_var ( var. name , var_ty, dbg_scope, var_kind, span)
342361 } ) ;
343362
344- per_local[ var. place . local ] . push ( PerLocalVarDebugInfo {
345- name : var. name ,
346- source_info : var. source_info ,
347- dbg_var,
348- projection : var. place . projection ,
349- } ) ;
363+ match var. value {
364+ mir:: VarDebugInfoContents :: Place ( place) => {
365+ per_local[ place. local ] . push ( PerLocalVarDebugInfo {
366+ name : var. name ,
367+ source_info : var. source_info ,
368+ dbg_var,
369+ projection : place. projection ,
370+ } ) ;
371+ }
372+ mir:: VarDebugInfoContents :: Const ( c) => {
373+ if let Some ( dbg_var) = dbg_var {
374+ let dbg_loc = match self . dbg_loc ( var. source_info ) {
375+ Some ( dbg_loc) => dbg_loc,
376+ None => continue ,
377+ } ;
378+
379+ if let Ok ( operand) = self . eval_mir_constant_to_operand ( bx, & c) {
380+ let base = Self :: spill_operand_to_stack (
381+ & operand,
382+ Some ( var. name . to_string ( ) ) ,
383+ bx,
384+ ) ;
385+
386+ bx. dbg_var_addr ( dbg_var, dbg_loc, base. llval , Size :: ZERO , & [ ] ) ;
387+ }
388+ }
389+ }
390+ }
350391 }
351392 Some ( per_local)
352393 }
0 commit comments