@@ -26,8 +26,8 @@ use crate::CodegenError;
26
26
use crate :: { machinst:: * , trace_log_enabled} ;
27
27
use crate :: { LabelValueLoc , ValueLocRange } ;
28
28
use regalloc2:: {
29
- Edit , Function as RegallocFunction , InstOrEdit , InstRange , MachineEnv , Operand ,
30
- OperandConstraint , OperandKind , PRegSet , RegClass ,
29
+ Edit , Function as RegallocFunction , InstOrEdit , InstPosition , InstRange , MachineEnv , Operand ,
30
+ OperandConstraint , OperandKind , PRegSet , ProgPoint , RegClass ,
31
31
} ;
32
32
use rustc_hash:: FxHashMap ;
33
33
@@ -381,18 +381,37 @@ impl<I: VCodeInst> VCodeBuilder<I> {
381
381
382
382
/// Add a debug value label to a register.
383
383
pub fn add_value_label ( & mut self , reg : Reg , label : ValueLabel ) {
384
- // We'll fix up labels in reverse(). Because we're generating
385
- // code bottom-to-top, the liverange of the label goes *from*
386
- // the last index at which was defined (or 0, which is the end
387
- // of the eventual function) *to* just this instruction, and
388
- // no further.
389
- let inst = InsnIndex :: new ( self . vcode . insts . len ( ) ) ;
384
+ // 1) In the reversed order, we consider the instructions
385
+ // that define ranges in the "debug_info" array to refer
386
+ // to the IP **after** them (when reversed):
387
+ // IP[2]__| Inst 3 |
388
+ // IP[1]__| Inst 2 |
389
+ // IP[0]__| Inst 1 |
390
+ // | Inst 0 |
391
+ // This is so that we can represent IP[<function start>],
392
+ // done at the cost of not being to represent IP[<function end>],
393
+ // which is OK since no values will be live at that point.
394
+ // 2) The live range for "reg" begins at the current IP
395
+ // and continues until the next, in execution order,
396
+ // VReg that defines "label". Since the ranges are open
397
+ // at the end, the subtraction of 1 cancels out:
398
+ // [last..current IP] <=>
399
+ // [last..last emitted inst index] <=>
400
+ // [last..next_inst_index - 1] <=>
401
+ // [last..next_inst_index)
402
+ //
403
+ let next_inst_index = self . vcode . insts . len ( ) ;
404
+ if next_inst_index == 0 {
405
+ // This would produce a defective [0..0) range.
406
+ return ;
407
+ }
408
+ let next_inst = InsnIndex :: new ( next_inst_index) ;
390
409
let labels = self . debug_info . entry ( label) . or_insert_with ( || vec ! [ ] ) ;
391
410
let last = labels
392
411
. last ( )
393
412
. map ( |( _start, end, _vreg) | * end)
394
413
. unwrap_or ( InsnIndex :: new ( 0 ) ) ;
395
- labels. push ( ( last, inst , reg. into ( ) ) ) ;
414
+ labels. push ( ( last, next_inst , reg. into ( ) ) ) ;
396
415
}
397
416
398
417
/// Access the constants.
@@ -1163,11 +1182,20 @@ impl<I: VCodeInst> VCode<I> {
1163
1182
for & ( label, from, to, alloc) in & regalloc. debug_locations {
1164
1183
let label = ValueLabel :: from_u32 ( label) ;
1165
1184
let ranges = value_labels_ranges. entry ( label) . or_insert_with ( || vec ! [ ] ) ;
1166
- let from_offset = inst_offsets[ from. inst ( ) . index ( ) ] ;
1167
- let to_offset = if to. inst ( ) . index ( ) == inst_offsets. len ( ) {
1185
+ let prog_point_to_inst = |prog_point : ProgPoint | {
1186
+ let mut inst = prog_point. inst ( ) ;
1187
+ if prog_point. pos ( ) == InstPosition :: After {
1188
+ inst = inst. next ( ) ;
1189
+ }
1190
+ inst. index ( )
1191
+ } ;
1192
+ let from_inst_index = prog_point_to_inst ( from) ;
1193
+ let to_inst_index = prog_point_to_inst ( to) ;
1194
+ let from_offset = inst_offsets[ from_inst_index] ;
1195
+ let to_offset = if to_inst_index == inst_offsets. len ( ) {
1168
1196
func_body_len
1169
1197
} else {
1170
- inst_offsets[ to . inst ( ) . index ( ) ]
1198
+ inst_offsets[ to_inst_index ]
1171
1199
} ;
1172
1200
1173
1201
// Empty ranges or unavailable offsets can happen
@@ -1193,34 +1221,18 @@ impl<I: VCodeInst> VCode<I> {
1193
1221
LabelValueLoc :: CFAOffset ( cfa_to_sp_offset + slot_offset)
1194
1222
} ;
1195
1223
1196
- // ValueLocRanges are recorded by *instruction-end
1197
- // offset*. `from_offset` is the *start* of the
1198
- // instruction; that is the same as the end of another
1199
- // instruction, so we only want to begin coverage once
1200
- // we are past the previous instruction's end.
1201
- let start = from_offset + 1 ;
1202
-
1203
- // Likewise, `end` is exclusive, but we want to
1204
- // *include* the end of the last
1205
- // instruction. `to_offset` is the start of the
1206
- // `to`-instruction, which is the exclusive end, i.e.,
1207
- // the first instruction not covered. That
1208
- // instruction's start is the same as the end of the
1209
- // last instruction that is included, so we go one
1210
- // byte further to be sure to include it.
1211
- let end = to_offset + 1 ;
1212
-
1213
1224
// Coalesce adjacent ranges that for the same location
1214
1225
// to minimize output size here and for the consumers.
1215
1226
if let Some ( last_loc_range) = ranges. last_mut ( ) {
1216
- if last_loc_range. loc == loc && last_loc_range. end == start {
1227
+ if last_loc_range. loc == loc && last_loc_range. end == from_offset {
1217
1228
trace ! (
1218
- "Extending debug range for {:?} in {:?} to {} " ,
1229
+ "Extending debug range for {:?} in {:?} to Inst {} ({}) " ,
1219
1230
label,
1220
1231
loc,
1221
- end
1232
+ to_inst_index,
1233
+ to_offset
1222
1234
) ;
1223
- last_loc_range. end = end ;
1235
+ last_loc_range. end = to_offset ;
1224
1236
continue ;
1225
1237
}
1226
1238
}
@@ -1229,13 +1241,17 @@ impl<I: VCodeInst> VCode<I> {
1229
1241
"Recording debug range for {:?} in {:?}: [Inst {}..Inst {}) [{}..{})" ,
1230
1242
label,
1231
1243
loc,
1232
- from . inst ( ) . index ( ) ,
1233
- to . inst ( ) . index ( ) ,
1234
- start ,
1235
- end
1244
+ from_inst_index ,
1245
+ to_inst_index ,
1246
+ from_offset ,
1247
+ to_offset
1236
1248
) ;
1237
1249
1238
- ranges. push ( ValueLocRange { loc, start, end } ) ;
1250
+ ranges. push ( ValueLocRange {
1251
+ loc,
1252
+ start : from_offset,
1253
+ end : to_offset,
1254
+ } ) ;
1239
1255
}
1240
1256
1241
1257
value_labels_ranges
@@ -1279,10 +1295,10 @@ impl<I: VCodeInst> VCode<I> {
1279
1295
enum Row {
1280
1296
Head ,
1281
1297
Line ,
1282
- Inst ( usize ) ,
1298
+ Inst ( usize , usize ) ,
1283
1299
}
1284
1300
1285
- let mut widths = vec ! [ 0 ; 2 + 2 * labels. len( ) ] ;
1301
+ let mut widths = vec ! [ 0 ; 3 + 2 * labels. len( ) ] ;
1286
1302
let mut row = String :: new ( ) ;
1287
1303
let mut output_row = |row_kind : Row , mode : Mode | {
1288
1304
let mut column_index = 0 ;
@@ -1320,6 +1336,7 @@ impl<I: VCodeInst> VCode<I> {
1320
1336
1321
1337
match row_kind {
1322
1338
Row :: Head => {
1339
+ output_cell ! ( "BB" ) ;
1323
1340
output_cell ! ( "Inst" ) ;
1324
1341
output_cell ! ( "IP" ) ;
1325
1342
for label in & labels {
@@ -1328,21 +1345,23 @@ impl<I: VCodeInst> VCode<I> {
1328
1345
}
1329
1346
Row :: Line => {
1330
1347
debug_assert ! ( mode == Mode :: Emit ) ;
1331
- output_cell_impl ! ( '-' , 1 , "" ) ;
1332
- output_cell_impl ! ( '-' , 1 , "" ) ;
1348
+ for _ in 0 ..3 {
1349
+ output_cell_impl ! ( '-' , 1 , "" ) ;
1350
+ }
1333
1351
for _ in & labels {
1334
1352
output_cell_impl ! ( '-' , 2 , "" ) ;
1335
1353
}
1336
1354
}
1337
- Row :: Inst ( inst_index) => {
1355
+ Row :: Inst ( block_index, inst_index) => {
1356
+ debug_assert ! ( inst_index < self . num_insts( ) ) ;
1357
+ if self . block_ranges . get ( block_index) . start == inst_index {
1358
+ output_cell ! ( "B{}" , block_index) ;
1359
+ } else {
1360
+ output_cell ! ( "" ) ;
1361
+ }
1338
1362
output_cell ! ( "Inst {inst_index} " ) ;
1339
1363
output_cell ! ( "{} " , inst_offsets[ inst_index] ) ;
1340
1364
1341
- // The ranges which we query below operate on the logic of
1342
- // "IP(inst) == IP after inst", while the rows of our table
1343
- // represent IPs 'before' "inst", so we need to convert "inst"
1344
- // into these "IP after" coordinates.
1345
- let inst_ip_index = inst_index. wrapping_sub ( 1 ) ;
1346
1365
for label in & labels {
1347
1366
// First, the VReg.
1348
1367
use regalloc2:: Inst ;
@@ -1364,12 +1383,12 @@ impl<I: VCodeInst> VCode<I> {
1364
1383
}
1365
1384
} ;
1366
1385
let vreg_index =
1367
- vregs. binary_search_by ( |( l, s, e, _) | vreg_cmp ( inst_ip_index , l, s, e) ) ;
1386
+ vregs. binary_search_by ( |( l, s, e, _) | vreg_cmp ( inst_index , l, s, e) ) ;
1368
1387
if let Ok ( vreg_index) = vreg_index {
1369
1388
let mut prev_vreg = None ;
1370
- if inst_ip_index > 0 {
1389
+ if inst_index > 0 {
1371
1390
let prev_vreg_index = vregs. binary_search_by ( |( l, s, e, _) | {
1372
- vreg_cmp ( inst_ip_index - 1 , l, s, e)
1391
+ vreg_cmp ( inst_index - 1 , l, s, e)
1373
1392
} ) ;
1374
1393
if let Ok ( prev_vreg_index) = prev_vreg_index {
1375
1394
prev_vreg = Some ( vregs[ prev_vreg_index] . 3 ) ;
@@ -1387,13 +1406,14 @@ impl<I: VCodeInst> VCode<I> {
1387
1406
}
1388
1407
1389
1408
// Second, the allocated location.
1409
+ let inst_prog_point = ProgPoint :: before ( Inst :: new ( inst_index) ) ;
1390
1410
let range_index = regalloc. debug_locations . binary_search_by (
1391
1411
|( range_label, range_start, range_end, _) | match range_label. cmp ( label)
1392
1412
{
1393
1413
Ordering :: Equal => {
1394
- if range_end. inst ( ) . index ( ) <= inst_ip_index {
1414
+ if * range_end <= inst_prog_point {
1395
1415
Ordering :: Less
1396
- } else if range_start. inst ( ) . index ( ) > inst_ip_index {
1416
+ } else if * range_start > inst_prog_point {
1397
1417
Ordering :: Greater
1398
1418
} else {
1399
1419
Ordering :: Equal
@@ -1423,15 +1443,19 @@ impl<I: VCodeInst> VCode<I> {
1423
1443
}
1424
1444
} ;
1425
1445
1426
- for inst_index in 0 ..inst_offsets. len ( ) {
1427
- output_row ( Row :: Inst ( inst_index) , Mode :: Measure ) ;
1446
+ for block_index in 0 ..self . num_blocks ( ) {
1447
+ for inst_index in self . block_ranges . get ( block_index) {
1448
+ output_row ( Row :: Inst ( block_index, inst_index) , Mode :: Measure ) ;
1449
+ }
1428
1450
}
1429
1451
output_row ( Row :: Head , Mode :: Measure ) ;
1430
1452
1431
1453
output_row ( Row :: Head , Mode :: Emit ) ;
1432
1454
output_row ( Row :: Line , Mode :: Emit ) ;
1433
- for inst_index in 0 ..inst_offsets. len ( ) {
1434
- output_row ( Row :: Inst ( inst_index) , Mode :: Emit ) ;
1455
+ for block_index in 0 ..self . num_blocks ( ) {
1456
+ for inst_index in self . block_ranges . get ( block_index) {
1457
+ output_row ( Row :: Inst ( block_index, inst_index) , Mode :: Emit ) ;
1458
+ }
1435
1459
}
1436
1460
}
1437
1461
0 commit comments