Skip to content

Commit 27091e6

Browse files
committed
[PEI][NFC] Refactoring of the debug instructions frame index replacement
This is required for the upcoming backward PEI::replaceFrameIndices version. Both forward and backward versions will use same code for debug instruction processing. Reviewed By: arsenm Differential Revision: https://reviews.llvm.org/D137741
1 parent 0436cf5 commit 27091e6

File tree

1 file changed

+86
-73
lines changed

1 file changed

+86
-73
lines changed

llvm/lib/CodeGen/PrologEpilogInserter.cpp

Lines changed: 86 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,9 @@ class PEI : public MachineFunctionPass {
128128
void replaceFrameIndices(MachineFunction &MF);
129129
void replaceFrameIndices(MachineBasicBlock *BB, MachineFunction &MF,
130130
int &SPAdj);
131+
bool replaceFrameIndexDebugInstr(MachineFunction &MF, MachineInstr &MI,
132+
unsigned OpIdx, int SPAdj = 0);
133+
131134
void insertPrologEpilogCode(MachineFunction &MF);
132135
void insertZeroCallUsedRegs(MachineFunction &MF);
133136
};
@@ -1353,6 +1356,88 @@ void PEI::replaceFrameIndices(MachineFunction &MF) {
13531356
}
13541357
}
13551358

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+
13561441
void PEI::replaceFrameIndices(MachineBasicBlock *BB, MachineFunction &MF,
13571442
int &SPAdj) {
13581443
assert(MF.getSubtarget().getRegisterInfo() &&
@@ -1384,80 +1469,8 @@ void PEI::replaceFrameIndices(MachineBasicBlock *BB, MachineFunction &MF,
13841469
// Frame indices in debug values are encoded in a target independent
13851470
// way with simply the frame index and offset rather than any
13861471
// 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))
14391473
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-
}
14611474

14621475
// Some instructions (e.g. inline asm instructions) can have
14631476
// multiple frame indices and/or cause eliminateFrameIndex

0 commit comments

Comments
 (0)