@@ -9,7 +9,7 @@ use rustc_span::symbol::{kw, Symbol};
9
9
use rustc_span:: { BytePos , Span } ;
10
10
use rustc_target:: abi:: { LayoutOf , Size } ;
11
11
12
- use super :: operand:: OperandValue ;
12
+ use super :: operand:: { OperandRef , OperandValue } ;
13
13
use super :: place:: PlaceRef ;
14
14
use super :: { FunctionCx , LocalRef } ;
15
15
@@ -111,6 +111,24 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
111
111
}
112
112
}
113
113
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
+
114
132
/// Apply debuginfo and/or name, after creating the `alloca` for a local,
115
133
/// or initializing the local with an operand (whichever applies).
116
134
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> {
225
243
return ;
226
244
}
227
245
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)
239
247
}
240
248
241
249
LocalRef :: Place ( place) => * place,
@@ -310,6 +318,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
310
318
/// Partition all `VarDebugInfo` in `self.mir`, by their base `Local`.
311
319
pub fn compute_per_local_var_debug_info (
312
320
& self ,
321
+ bx : & mut Bx ,
313
322
) -> Option < IndexVec < mir:: Local , Vec < PerLocalVarDebugInfo < ' tcx , Bx :: DIVariable > > > > {
314
323
let full_debug_info = self . cx . sess ( ) . opts . debuginfo == DebugInfo :: Full ;
315
324
@@ -324,22 +333,30 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
324
333
} else {
325
334
( None , var. source_info . span )
326
335
} ;
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
+ } ;
327
359
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
- } ;
343
360
self . cx . create_dbg_var (
344
361
self . debug_context . as_ref ( ) . unwrap ( ) ,
345
362
var. name ,
@@ -350,12 +367,29 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
350
367
)
351
368
} ) ;
352
369
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
+ }
359
393
}
360
394
Some ( per_local)
361
395
}
0 commit comments