@@ -128,6 +128,9 @@ class PEI : public MachineFunctionPass {
128
128
void replaceFrameIndices (MachineFunction &MF);
129
129
void replaceFrameIndices (MachineBasicBlock *BB, MachineFunction &MF,
130
130
int &SPAdj);
131
+ bool replaceFrameIndexDebugInstr (MachineFunction &MF, MachineInstr &MI,
132
+ unsigned OpIdx, int SPAdj = 0 );
133
+
131
134
void insertPrologEpilogCode (MachineFunction &MF);
132
135
void insertZeroCallUsedRegs (MachineFunction &MF);
133
136
};
@@ -1353,6 +1356,88 @@ void PEI::replaceFrameIndices(MachineFunction &MF) {
1353
1356
}
1354
1357
}
1355
1358
1359
+ bool PEI::replaceFrameIndexDebugInstr (MachineFunction &MF, MachineInstr &MI,
1360
+ unsigned OpIdx, int SPAdj) {
1361
+ const TargetFrameLowering *TFI = MF.getSubtarget ().getFrameLowering ();
1362
+ const TargetRegisterInfo &TRI = *MF.getSubtarget ().getRegisterInfo ();
1363
+ if (MI.isDebugValue ()) {
1364
+
1365
+ MachineOperand &Op = MI.getOperand (OpIdx);
1366
+ assert (MI.isDebugOperand (&Op) &&
1367
+ " Frame indices can only appear as a debug operand in a DBG_VALUE*"
1368
+ " machine instruction" );
1369
+ Register Reg;
1370
+ unsigned FrameIdx = Op.getIndex ();
1371
+ unsigned Size = MF.getFrameInfo ().getObjectSize (FrameIdx);
1372
+
1373
+ StackOffset Offset = TFI->getFrameIndexReference (MF, FrameIdx, Reg);
1374
+ Op.ChangeToRegister (Reg, false /* isDef*/ );
1375
+
1376
+ const DIExpression *DIExpr = MI.getDebugExpression ();
1377
+
1378
+ // If we have a direct DBG_VALUE, and its location expression isn't
1379
+ // currently complex, then adding an offset will morph it into a
1380
+ // complex location that is interpreted as being a memory address.
1381
+ // This changes a pointer-valued variable to dereference that pointer,
1382
+ // which is incorrect. Fix by adding DW_OP_stack_value.
1383
+
1384
+ if (MI.isNonListDebugValue ()) {
1385
+ unsigned PrependFlags = DIExpression::ApplyOffset;
1386
+ if (!MI.isIndirectDebugValue () && !DIExpr->isComplex ())
1387
+ PrependFlags |= DIExpression::StackValue;
1388
+
1389
+ // If we have DBG_VALUE that is indirect and has a Implicit location
1390
+ // expression need to insert a deref before prepending a Memory
1391
+ // location expression. Also after doing this we change the DBG_VALUE
1392
+ // to be direct.
1393
+ if (MI.isIndirectDebugValue () && DIExpr->isImplicit ()) {
1394
+ SmallVector<uint64_t , 2 > Ops = {dwarf::DW_OP_deref_size, Size};
1395
+ bool WithStackValue = true ;
1396
+ DIExpr = DIExpression::prependOpcodes (DIExpr, Ops, WithStackValue);
1397
+ // Make the DBG_VALUE direct.
1398
+ MI.getDebugOffset ().ChangeToRegister (0 , false );
1399
+ }
1400
+ DIExpr = TRI.prependOffsetExpression (DIExpr, PrependFlags, Offset);
1401
+ } else {
1402
+ // The debug operand at DebugOpIndex was a frame index at offset
1403
+ // `Offset`; now the operand has been replaced with the frame
1404
+ // register, we must add Offset with `register x, plus Offset`.
1405
+ unsigned DebugOpIndex = MI.getDebugOperandIndex (&Op);
1406
+ SmallVector<uint64_t , 3 > Ops;
1407
+ TRI.getOffsetOpcodes (Offset, Ops);
1408
+ DIExpr = DIExpression::appendOpsToArg (DIExpr, Ops, DebugOpIndex);
1409
+ }
1410
+ MI.getDebugExpressionOp ().setMetadata (DIExpr);
1411
+ return true ;
1412
+ }
1413
+
1414
+ if (MI.isDebugPHI ()) {
1415
+ // Allow stack ref to continue onwards.
1416
+ return true ;
1417
+ }
1418
+
1419
+ // TODO: This code should be commoned with the code for
1420
+ // PATCHPOINT. There's no good reason for the difference in
1421
+ // implementation other than historical accident. The only
1422
+ // remaining difference is the unconditional use of the stack
1423
+ // pointer as the base register.
1424
+ if (MI.getOpcode () == TargetOpcode::STATEPOINT) {
1425
+ assert ((!MI.isDebugValue () || OpIdx == 0 ) &&
1426
+ " Frame indicies can only appear as the first operand of a "
1427
+ " DBG_VALUE machine instruction" );
1428
+ Register Reg;
1429
+ MachineOperand &Offset = MI.getOperand (OpIdx + 1 );
1430
+ StackOffset refOffset = TFI->getFrameIndexReferencePreferSP (
1431
+ MF, MI.getOperand (OpIdx).getIndex (), Reg, /* IgnoreSPUpdates*/ false );
1432
+ assert (!refOffset.getScalable () &&
1433
+ " Frame offsets with a scalable component are not supported" );
1434
+ Offset.setImm (Offset.getImm () + refOffset.getFixed () + SPAdj);
1435
+ MI.getOperand (OpIdx).ChangeToRegister (Reg, false /* isDef*/ );
1436
+ return true ;
1437
+ }
1438
+ return false ;
1439
+ }
1440
+
1356
1441
void PEI::replaceFrameIndices (MachineBasicBlock *BB, MachineFunction &MF,
1357
1442
int &SPAdj) {
1358
1443
assert (MF.getSubtarget ().getRegisterInfo () &&
@@ -1384,80 +1469,8 @@ void PEI::replaceFrameIndices(MachineBasicBlock *BB, MachineFunction &MF,
1384
1469
// Frame indices in debug values are encoded in a target independent
1385
1470
// way with simply the frame index and offset rather than any
1386
1471
// target-specific addressing mode.
1387
- if (MI.isDebugValue ()) {
1388
- MachineOperand &Op = MI.getOperand (i);
1389
- assert (
1390
- MI.isDebugOperand (&Op) &&
1391
- " Frame indices can only appear as a debug operand in a DBG_VALUE*"
1392
- " machine instruction" );
1393
- Register Reg;
1394
- unsigned FrameIdx = Op.getIndex ();
1395
- unsigned Size = MF.getFrameInfo ().getObjectSize (FrameIdx);
1396
-
1397
- StackOffset Offset =
1398
- TFI->getFrameIndexReference (MF, FrameIdx, Reg);
1399
- Op.ChangeToRegister (Reg, false /* isDef*/ );
1400
-
1401
- const DIExpression *DIExpr = MI.getDebugExpression ();
1402
-
1403
- // If we have a direct DBG_VALUE, and its location expression isn't
1404
- // currently complex, then adding an offset will morph it into a
1405
- // complex location that is interpreted as being a memory address.
1406
- // This changes a pointer-valued variable to dereference that pointer,
1407
- // which is incorrect. Fix by adding DW_OP_stack_value.
1408
-
1409
- if (MI.isNonListDebugValue ()) {
1410
- unsigned PrependFlags = DIExpression::ApplyOffset;
1411
- if (!MI.isIndirectDebugValue () && !DIExpr->isComplex ())
1412
- PrependFlags |= DIExpression::StackValue;
1413
-
1414
- // If we have DBG_VALUE that is indirect and has a Implicit location
1415
- // expression need to insert a deref before prepending a Memory
1416
- // location expression. Also after doing this we change the DBG_VALUE
1417
- // to be direct.
1418
- if (MI.isIndirectDebugValue () && DIExpr->isImplicit ()) {
1419
- SmallVector<uint64_t , 2 > Ops = {dwarf::DW_OP_deref_size, Size};
1420
- bool WithStackValue = true ;
1421
- DIExpr = DIExpression::prependOpcodes (DIExpr, Ops, WithStackValue);
1422
- // Make the DBG_VALUE direct.
1423
- MI.getDebugOffset ().ChangeToRegister (0 , false );
1424
- }
1425
- DIExpr = TRI.prependOffsetExpression (DIExpr, PrependFlags, Offset);
1426
- } else {
1427
- // The debug operand at DebugOpIndex was a frame index at offset
1428
- // `Offset`; now the operand has been replaced with the frame
1429
- // register, we must add Offset with `register x, plus Offset`.
1430
- unsigned DebugOpIndex = MI.getDebugOperandIndex (&Op);
1431
- SmallVector<uint64_t , 3 > Ops;
1432
- TRI.getOffsetOpcodes (Offset, Ops);
1433
- DIExpr = DIExpression::appendOpsToArg (DIExpr, Ops, DebugOpIndex);
1434
- }
1435
- MI.getDebugExpressionOp ().setMetadata (DIExpr);
1436
- continue ;
1437
- } else if (MI.isDebugPHI ()) {
1438
- // Allow stack ref to continue onwards.
1472
+ if (replaceFrameIndexDebugInstr (MF, MI, i, SPAdj))
1439
1473
continue ;
1440
- }
1441
-
1442
- // TODO: This code should be commoned with the code for
1443
- // PATCHPOINT. There's no good reason for the difference in
1444
- // implementation other than historical accident. The only
1445
- // remaining difference is the unconditional use of the stack
1446
- // pointer as the base register.
1447
- if (MI.getOpcode () == TargetOpcode::STATEPOINT) {
1448
- assert ((!MI.isDebugValue () || i == 0 ) &&
1449
- " Frame indicies can only appear as the first operand of a "
1450
- " DBG_VALUE machine instruction" );
1451
- Register Reg;
1452
- MachineOperand &Offset = MI.getOperand (i + 1 );
1453
- StackOffset refOffset = TFI->getFrameIndexReferencePreferSP (
1454
- MF, MI.getOperand (i).getIndex (), Reg, /* IgnoreSPUpdates*/ false );
1455
- assert (!refOffset.getScalable () &&
1456
- " Frame offsets with a scalable component are not supported" );
1457
- Offset.setImm (Offset.getImm () + refOffset.getFixed () + SPAdj);
1458
- MI.getOperand (i).ChangeToRegister (Reg, false /* isDef*/ );
1459
- continue ;
1460
- }
1461
1474
1462
1475
// Some instructions (e.g. inline asm instructions) can have
1463
1476
// multiple frame indices and/or cause eliminateFrameIndex
0 commit comments