aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp')
-rw-r--r--llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp100
1 files changed, 65 insertions, 35 deletions
diff --git a/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp b/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp
index 61d127d..c7b6311 100644
--- a/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp
+++ b/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp
@@ -148,6 +148,20 @@ static cl::opt<bool> EmulateOldLDV("emulate-old-livedebugvalues", cl::Hidden,
cl::desc("Act like old LiveDebugValues did"),
cl::init(false));
+// Limit for the maximum number of stack slots we should track, past which we
+// will ignore any spills. InstrRefBasedLDV gathers detailed information on all
+// stack slots which leads to high memory consumption, and in some scenarios
+// (such as asan with very many locals) the working set of the function can be
+// very large, causing many spills. In these scenarios, it is very unlikely that
+// the developer has hundreds of variables live at the same time that they're
+// carefully thinking about -- instead, they probably autogenerated the code.
+// When this happens, gracefully stop tracking excess spill slots, rather than
+// consuming all the developer's memory.
+static cl::opt<unsigned>
+ StackWorkingSetLimit("livedebugvalues-max-stack-slots", cl::Hidden,
+ cl::desc("livedebugvalues-stack-ws-limit"),
+ cl::init(250));
+
/// Tracker for converting machine value locations and variable values into
/// variable locations (the output of LiveDebugValues), recorded as DBG_VALUEs
/// specifying block live-in locations and transfers within blocks.
@@ -757,9 +771,15 @@ void MLocTracker::writeRegMask(const MachineOperand *MO, unsigned CurBB,
Masks.push_back(std::make_pair(MO, InstID));
}
-SpillLocationNo MLocTracker::getOrTrackSpillLoc(SpillLoc L) {
+Optional<SpillLocationNo> MLocTracker::getOrTrackSpillLoc(SpillLoc L) {
SpillLocationNo SpillID(SpillLocs.idFor(L));
+
if (SpillID.id() == 0) {
+ // If there is no location, and we have reached the limit of how many stack
+ // slots to track, then don't track this one.
+ if (SpillLocs.size() >= StackWorkingSetLimit)
+ return None;
+
// Spill location is untracked: create record for this one, and all
// subregister slots too.
SpillID = SpillLocationNo(SpillLocs.insert(L));
@@ -898,7 +918,7 @@ bool InstrRefBasedLDV::isCalleeSaved(LocIdx L) const {
// void InstrRefBasedLDV::printVarLocInMBB(..)
#endif
-SpillLocationNo
+Optional<SpillLocationNo>
InstrRefBasedLDV::extractSpillBaseRegAndOffset(const MachineInstr &MI) {
assert(MI.hasOneMemOperand() &&
"Spill instruction does not have exactly one memory operand?");
@@ -913,8 +933,11 @@ InstrRefBasedLDV::extractSpillBaseRegAndOffset(const MachineInstr &MI) {
return MTracker->getOrTrackSpillLoc({Reg, Offset});
}
-Optional<LocIdx> InstrRefBasedLDV::findLocationForMemOperand(const MachineInstr &MI) {
- SpillLocationNo SpillLoc = extractSpillBaseRegAndOffset(MI);
+Optional<LocIdx>
+InstrRefBasedLDV::findLocationForMemOperand(const MachineInstr &MI) {
+ Optional<SpillLocationNo> SpillLoc = extractSpillBaseRegAndOffset(MI);
+ if (!SpillLoc)
+ return None;
// Where in the stack slot is this value defined -- i.e., what size of value
// is this? An important question, because it could be loaded into a register
@@ -930,7 +953,7 @@ Optional<LocIdx> InstrRefBasedLDV::findLocationForMemOperand(const MachineInstr
// occur, but the safe action is to indicate the variable is optimised out.
return None;
- unsigned SpillID = MTracker->getSpillIDWithIdx(SpillLoc, IdxIt->second);
+ unsigned SpillID = MTracker->getSpillIDWithIdx(*SpillLoc, IdxIt->second);
return MTracker->getSpillMLoc(SpillID);
}
@@ -1251,7 +1274,12 @@ bool InstrRefBasedLDV::transferDebugPHI(MachineInstr &MI) {
Register Base;
StackOffset Offs = TFI->getFrameIndexReference(*MI.getMF(), FI, Base);
SpillLoc SL = {Base, Offs};
- SpillLocationNo SpillNo = MTracker->getOrTrackSpillLoc(SL);
+ Optional<SpillLocationNo> SpillNo = MTracker->getOrTrackSpillLoc(SL);
+
+ // We might be able to find a value, but have chosen not to, to avoid
+ // tracking too much stack information.
+ if (!SpillNo)
+ return true;
// Problem: what value should we extract from the stack? LLVM does not
// record what size the last store to the slot was, and it would become
@@ -1263,7 +1291,7 @@ bool InstrRefBasedLDV::transferDebugPHI(MachineInstr &MI) {
Optional<ValueIDNum> Result = None;
Optional<LocIdx> SpillLoc = None;
for (unsigned CS : CandidateSizes) {
- unsigned SpillID = MTracker->getLocID(SpillNo, {CS, 0});
+ unsigned SpillID = MTracker->getLocID(*SpillNo, {CS, 0});
SpillLoc = MTracker->getSpillMLoc(SpillID);
ValueIDNum Val = MTracker->readMLoc(*SpillLoc);
// If this value was defined in it's own position, then it was probably
@@ -1280,7 +1308,7 @@ bool InstrRefBasedLDV::transferDebugPHI(MachineInstr &MI) {
// "supposed" to be is more complex, and benefits a small number of
// locations.
if (!Result) {
- unsigned SpillID = MTracker->getLocID(SpillNo, {64, 0});
+ unsigned SpillID = MTracker->getLocID(*SpillNo, {64, 0});
SpillLoc = MTracker->getSpillMLoc(SpillID);
Result = MTracker->readMLoc(*SpillLoc);
}
@@ -1357,11 +1385,12 @@ void InstrRefBasedLDV::transferRegisterDef(MachineInstr &MI) {
// If this instruction writes to a spill slot, def that slot.
if (hasFoldedStackStore(MI)) {
- SpillLocationNo SpillNo = extractSpillBaseRegAndOffset(MI);
- for (unsigned int I = 0; I < MTracker->NumSlotIdxes; ++I) {
- unsigned SpillID = MTracker->getSpillIDWithIdx(SpillNo, I);
- LocIdx L = MTracker->getSpillMLoc(SpillID);
- MTracker->setMLoc(L, ValueIDNum(CurBB, CurInst, L));
+ if (Optional<SpillLocationNo> SpillNo = extractSpillBaseRegAndOffset(MI)) {
+ for (unsigned int I = 0; I < MTracker->NumSlotIdxes; ++I) {
+ unsigned SpillID = MTracker->getSpillIDWithIdx(*SpillNo, I);
+ LocIdx L = MTracker->getSpillMLoc(SpillID);
+ MTracker->setMLoc(L, ValueIDNum(CurBB, CurInst, L));
+ }
}
}
@@ -1396,11 +1425,12 @@ void InstrRefBasedLDV::transferRegisterDef(MachineInstr &MI) {
// Tell TTracker about any folded stack store.
if (hasFoldedStackStore(MI)) {
- SpillLocationNo SpillNo = extractSpillBaseRegAndOffset(MI);
- for (unsigned int I = 0; I < MTracker->NumSlotIdxes; ++I) {
- unsigned SpillID = MTracker->getSpillIDWithIdx(SpillNo, I);
- LocIdx L = MTracker->getSpillMLoc(SpillID);
- TTracker->clobberMloc(L, MI.getIterator(), true);
+ if (Optional<SpillLocationNo> SpillNo = extractSpillBaseRegAndOffset(MI)) {
+ for (unsigned int I = 0; I < MTracker->NumSlotIdxes; ++I) {
+ unsigned SpillID = MTracker->getSpillIDWithIdx(*SpillNo, I);
+ LocIdx L = MTracker->getSpillMLoc(SpillID);
+ TTracker->clobberMloc(L, MI.getIterator(), true);
+ }
}
}
}
@@ -1436,23 +1466,24 @@ void InstrRefBasedLDV::performCopy(Register SrcRegNum, Register DstRegNum) {
}
}
-bool InstrRefBasedLDV::isSpillInstruction(const MachineInstr &MI,
- MachineFunction *MF) {
+Optional<SpillLocationNo>
+InstrRefBasedLDV::isSpillInstruction(const MachineInstr &MI,
+ MachineFunction *MF) {
// TODO: Handle multiple stores folded into one.
if (!MI.hasOneMemOperand())
- return false;
+ return None;
// Reject any memory operand that's aliased -- we can't guarantee its value.
auto MMOI = MI.memoperands_begin();
const PseudoSourceValue *PVal = (*MMOI)->getPseudoValue();
if (PVal->isAliased(MFI))
- return false;
+ return None;
if (!MI.getSpillSize(TII) && !MI.getFoldedSpillSize(TII))
- return false; // This is not a spill instruction, since no valid size was
- // returned from either function.
+ return None; // This is not a spill instruction, since no valid size was
+ // returned from either function.
- return true;
+ return extractSpillBaseRegAndOffset(MI);
}
bool InstrRefBasedLDV::isLocationSpill(const MachineInstr &MI,
@@ -1509,13 +1540,11 @@ bool InstrRefBasedLDV::transferSpillOrRestoreInst(MachineInstr &MI) {
// First, if there are any DBG_VALUEs pointing at a spill slot that is
// written to, terminate that variable location. The value in memory
// will have changed. DbgEntityHistoryCalculator doesn't try to detect this.
- if (isSpillInstruction(MI, MF)) {
- SpillLocationNo Loc = extractSpillBaseRegAndOffset(MI);
-
+ if (Optional<SpillLocationNo> Loc = isSpillInstruction(MI, MF)) {
// Un-set this location and clobber, so that earlier locations don't
// continue past this store.
for (unsigned SlotIdx = 0; SlotIdx < MTracker->NumSlotIdxes; ++SlotIdx) {
- unsigned SpillID = MTracker->getSpillIDWithIdx(Loc, SlotIdx);
+ unsigned SpillID = MTracker->getSpillIDWithIdx(*Loc, SlotIdx);
Optional<LocIdx> MLoc = MTracker->getSpillMLoc(SpillID);
if (!MLoc)
continue;
@@ -1533,7 +1562,9 @@ bool InstrRefBasedLDV::transferSpillOrRestoreInst(MachineInstr &MI) {
// Try to recognise spill and restore instructions that may transfer a value.
if (isLocationSpill(MI, MF, Reg)) {
- SpillLocationNo Loc = extractSpillBaseRegAndOffset(MI);
+ // isLocationSpill returning true should guarantee we can extract a
+ // location.
+ SpillLocationNo Loc = *extractSpillBaseRegAndOffset(MI);
auto DoTransfer = [&](Register SrcReg, unsigned SpillID) {
auto ReadValue = MTracker->readReg(SrcReg);
@@ -1560,10 +1591,9 @@ bool InstrRefBasedLDV::transferSpillOrRestoreInst(MachineInstr &MI) {
unsigned SpillID = MTracker->getLocID(Loc, {Size, 0});
DoTransfer(Reg, SpillID);
} else {
- Optional<SpillLocationNo> OptLoc = isRestoreInstruction(MI, MF, Reg);
- if (!OptLoc)
+ Optional<SpillLocationNo> Loc = isRestoreInstruction(MI, MF, Reg);
+ if (!Loc)
return false;
- SpillLocationNo Loc = *OptLoc;
// Assumption: we're reading from the base of the stack slot, not some
// offset into it. It seems very unlikely LLVM would ever generate
@@ -1590,13 +1620,13 @@ bool InstrRefBasedLDV::transferSpillOrRestoreInst(MachineInstr &MI) {
for (MCSubRegIterator SRI(Reg, TRI, false); SRI.isValid(); ++SRI) {
unsigned Subreg = TRI->getSubRegIndex(Reg, *SRI);
- unsigned SpillID = MTracker->getLocID(Loc, Subreg);
+ unsigned SpillID = MTracker->getLocID(*Loc, Subreg);
DoTransfer(*SRI, SpillID);
}
// Directly look up this registers slot idx by size, and transfer.
unsigned Size = TRI->getRegSizeInBits(Reg, *MRI);
- unsigned SpillID = MTracker->getLocID(Loc, {Size, 0});
+ unsigned SpillID = MTracker->getLocID(*Loc, {Size, 0});
DoTransfer(Reg, SpillID);
}
return true;