@@ -9,7 +9,7 @@ use rustc_span::symbol::{kw, Symbol};
99use rustc_span:: { BytePos , Span } ;
1010use rustc_target:: abi:: { LayoutOf , Size } ;
1111
12- use super :: operand:: OperandValue ;
12+ use super :: operand:: { OperandRef , OperandValue } ;
1313use super :: place:: PlaceRef ;
1414use super :: { FunctionCx , LocalRef } ;
1515
@@ -111,6 +111,24 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
111111 }
112112 }
113113
114+ fn spill_operand_to_stack (
115+ operand : & OperandRef < ' tcx , Bx :: Value > ,
116+ name : Option < String > ,
117+ bx : & mut Bx ,
118+ ) -> PlaceRef < ' tcx , Bx :: Value > {
119+ // "Spill" the value onto the stack, for debuginfo,
120+ // without forcing non-debuginfo uses of the local
121+ // to also load from the stack every single time.
122+ // FIXME(#68817) use `llvm.dbg.value` instead,
123+ // at least for the cases which LLVM handles correctly.
124+ let spill_slot = PlaceRef :: alloca ( bx, operand. layout ) ;
125+ if let Some ( name) = name {
126+ bx. set_var_name ( spill_slot. llval , & ( name + ".dbg.spill" ) ) ;
127+ }
128+ operand. val . store ( bx, spill_slot) ;
129+ spill_slot
130+ }
131+
114132 /// Apply debuginfo and/or name, after creating the `alloca` for a local,
115133 /// or initializing the local with an operand (whichever applies).
116134 pub fn debug_introduce_local ( & self , bx : & mut Bx , local : mir:: Local ) {
@@ -225,17 +243,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
225243 return ;
226244 }
227245
228- // "Spill" the value onto the stack, for debuginfo,
229- // without forcing non-debuginfo uses of the local
230- // to also load from the stack every single time.
231- // FIXME(#68817) use `llvm.dbg.value` instead,
232- // at least for the cases which LLVM handles correctly.
233- let spill_slot = PlaceRef :: alloca ( bx, operand. layout ) ;
234- if let Some ( name) = name {
235- bx. set_var_name ( spill_slot. llval , & ( name + ".dbg.spill" ) ) ;
236- }
237- operand. val . store ( bx, spill_slot) ;
238- spill_slot
246+ Self :: spill_operand_to_stack ( operand, name, bx)
239247 }
240248
241249 LocalRef :: Place ( place) => * place,
@@ -310,6 +318,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
310318 /// Partition all `VarDebugInfo` in `self.mir`, by their base `Local`.
311319 pub fn compute_per_local_var_debug_info (
312320 & self ,
321+ bx : & mut Bx ,
313322 ) -> Option < IndexVec < mir:: Local , Vec < PerLocalVarDebugInfo < ' tcx , Bx :: DIVariable > > > > {
314323 let full_debug_info = self . cx . sess ( ) . opts . debuginfo == DebugInfo :: Full ;
315324
@@ -324,22 +333,30 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
324333 } else {
325334 ( None , var. source_info . span )
326335 } ;
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+ }
358+ } ;
327359 let dbg_var = scope. map ( |scope| {
328- let place = var. place ;
329- let var_ty = self . monomorphized_place_ty ( place. as_ref ( ) ) ;
330- let var_kind = if self . mir . local_kind ( place. local ) == mir:: LocalKind :: Arg
331- && place. projection . is_empty ( )
332- && var. source_info . scope == mir:: OUTERMOST_SOURCE_SCOPE
333- {
334- let arg_index = place. local . index ( ) - 1 ;
335-
336- // FIXME(eddyb) shouldn't `ArgumentVariable` indices be
337- // offset in closures to account for the hidden environment?
338- // Also, is this `+ 1` needed at all?
339- VariableKind :: ArgumentVariable ( arg_index + 1 )
340- } else {
341- VariableKind :: LocalVariable
342- } ;
343360 self . cx . create_dbg_var (
344361 self . debug_context . as_ref ( ) . unwrap ( ) ,
345362 var. name ,
@@ -350,12 +367,29 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
350367 )
351368 } ) ;
352369
353- per_local[ var. place . local ] . push ( PerLocalVarDebugInfo {
354- name : var. name ,
355- source_info : var. source_info ,
356- dbg_var,
357- projection : var. place . projection ,
358- } ) ;
370+ match var. value {
371+ mir:: VarDebugInfoContents :: Place ( place) => {
372+ per_local[ place. local ] . push ( PerLocalVarDebugInfo {
373+ name : var. name ,
374+ source_info : var. source_info ,
375+ dbg_var,
376+ projection : place. projection ,
377+ } ) ;
378+ }
379+ mir:: VarDebugInfoContents :: Const ( c) => {
380+ if let ( Some ( scope) , Some ( dbg_var) ) = ( scope, dbg_var) {
381+ if let Ok ( operand) = self . eval_mir_constant_to_operand ( bx, & c) {
382+ let base = Self :: spill_operand_to_stack (
383+ & operand,
384+ Some ( var. name . to_string ( ) ) ,
385+ bx,
386+ ) ;
387+
388+ bx. dbg_var_addr ( dbg_var, scope, base. llval , Size :: ZERO , & [ ] , span) ;
389+ }
390+ }
391+ }
392+ }
359393 }
360394 Some ( per_local)
361395 }
0 commit comments