@@ -8,7 +8,7 @@ use rustc_span::symbol::{kw, Symbol};
8
8
use rustc_span:: { BytePos , Span } ;
9
9
use rustc_target:: abi:: { LayoutOf , Size } ;
10
10
11
- use super :: operand:: OperandValue ;
11
+ use super :: operand:: { OperandRef , OperandValue } ;
12
12
use super :: place:: PlaceRef ;
13
13
use super :: { FunctionCx , LocalRef } ;
14
14
@@ -116,6 +116,24 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
116
116
span
117
117
}
118
118
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
+
119
137
/// Apply debuginfo and/or name, after creating the `alloca` for a local,
120
138
/// or initializing the local with an operand (whichever applies).
121
139
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> {
226
244
return ;
227
245
}
228
246
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)
240
248
}
241
249
242
250
LocalRef :: Place ( place) => * place,
@@ -308,6 +316,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
308
316
/// Partition all `VarDebugInfo` in `self.mir`, by their base `Local`.
309
317
pub fn compute_per_local_var_debug_info (
310
318
& self ,
319
+ bx : & mut Bx ,
311
320
) -> Option < IndexVec < mir:: Local , Vec < PerLocalVarDebugInfo < ' tcx , Bx :: DIVariable > > > > {
312
321
let full_debug_info = self . cx . sess ( ) . opts . debuginfo == DebugInfo :: Full ;
313
322
@@ -322,31 +331,63 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
322
331
} else {
323
332
None
324
333
} ;
334
+
325
335
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
+ }
340
358
} ;
359
+
341
360
self . cx . create_dbg_var ( var. name , var_ty, dbg_scope, var_kind, span)
342
361
} ) ;
343
362
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
+ }
350
391
}
351
392
Some ( per_local)
352
393
}
0 commit comments