@@ -148,6 +148,20 @@ static cl::opt<bool> EmulateOldLDV("emulate-old-livedebugvalues", cl::Hidden,
148148 cl::desc (" Act like old LiveDebugValues did" ),
149149 cl::init(false ));
150150
151+ // Limit for the maximum number of stack slots we should track, past which we
152+ // will ignore any spills. InstrRefBasedLDV gathers detailed information on all
153+ // stack slots which leads to high memory consumption, and in some scenarios
154+ // (such as asan with very many locals) the working set of the function can be
155+ // very large, causing many spills. In these scenarios, it is very unlikely that
156+ // the developer has hundreds of variables live at the same time that they're
157+ // carefully thinking about -- instead, they probably autogenerated the code.
158+ // When this happens, gracefully stop tracking excess spill slots, rather than
159+ // consuming all the developer's memory.
160+ static cl::opt<unsigned >
161+ StackWorkingSetLimit (" livedebugvalues-max-stack-slots" , cl::Hidden,
162+ cl::desc (" livedebugvalues-stack-ws-limit" ),
163+ cl::init(250 ));
164+
151165// / Tracker for converting machine value locations and variable values into
152166// / variable locations (the output of LiveDebugValues), recorded as DBG_VALUEs
153167// / specifying block live-in locations and transfers within blocks.
@@ -757,9 +771,15 @@ void MLocTracker::writeRegMask(const MachineOperand *MO, unsigned CurBB,
757771 Masks.push_back (std::make_pair (MO, InstID));
758772}
759773
760- SpillLocationNo MLocTracker::getOrTrackSpillLoc (SpillLoc L) {
774+ Optional< SpillLocationNo> MLocTracker::getOrTrackSpillLoc (SpillLoc L) {
761775 SpillLocationNo SpillID (SpillLocs.idFor (L));
776+
762777 if (SpillID.id () == 0 ) {
778+ // If there is no location, and we have reached the limit of how many stack
779+ // slots to track, then don't track this one.
780+ if (SpillLocs.size () >= StackWorkingSetLimit)
781+ return None;
782+
763783 // Spill location is untracked: create record for this one, and all
764784 // subregister slots too.
765785 SpillID = SpillLocationNo (SpillLocs.insert (L));
@@ -898,7 +918,7 @@ bool InstrRefBasedLDV::isCalleeSaved(LocIdx L) const {
898918// void InstrRefBasedLDV::printVarLocInMBB(..)
899919#endif
900920
901- SpillLocationNo
921+ Optional< SpillLocationNo>
902922InstrRefBasedLDV::extractSpillBaseRegAndOffset (const MachineInstr &MI) {
903923 assert (MI.hasOneMemOperand () &&
904924 " Spill instruction does not have exactly one memory operand?" );
@@ -913,8 +933,11 @@ InstrRefBasedLDV::extractSpillBaseRegAndOffset(const MachineInstr &MI) {
913933 return MTracker->getOrTrackSpillLoc ({Reg, Offset});
914934}
915935
916- Optional<LocIdx> InstrRefBasedLDV::findLocationForMemOperand (const MachineInstr &MI) {
917- SpillLocationNo SpillLoc = extractSpillBaseRegAndOffset (MI);
936+ Optional<LocIdx>
937+ InstrRefBasedLDV::findLocationForMemOperand (const MachineInstr &MI) {
938+ Optional<SpillLocationNo> SpillLoc = extractSpillBaseRegAndOffset (MI);
939+ if (!SpillLoc)
940+ return None;
918941
919942 // Where in the stack slot is this value defined -- i.e., what size of value
920943 // is this? An important question, because it could be loaded into a register
@@ -930,7 +953,7 @@ Optional<LocIdx> InstrRefBasedLDV::findLocationForMemOperand(const MachineInstr
930953 // occur, but the safe action is to indicate the variable is optimised out.
931954 return None;
932955
933- unsigned SpillID = MTracker->getSpillIDWithIdx (SpillLoc, IdxIt->second );
956+ unsigned SpillID = MTracker->getSpillIDWithIdx (* SpillLoc, IdxIt->second );
934957 return MTracker->getSpillMLoc (SpillID);
935958}
936959
@@ -1251,7 +1274,12 @@ bool InstrRefBasedLDV::transferDebugPHI(MachineInstr &MI) {
12511274 Register Base;
12521275 StackOffset Offs = TFI->getFrameIndexReference (*MI.getMF (), FI, Base);
12531276 SpillLoc SL = {Base, Offs};
1254- SpillLocationNo SpillNo = MTracker->getOrTrackSpillLoc (SL);
1277+ Optional<SpillLocationNo> SpillNo = MTracker->getOrTrackSpillLoc (SL);
1278+
1279+ // We might be able to find a value, but have chosen not to, to avoid
1280+ // tracking too much stack information.
1281+ if (!SpillNo)
1282+ return true ;
12551283
12561284 // Problem: what value should we extract from the stack? LLVM does not
12571285 // record what size the last store to the slot was, and it would become
@@ -1263,7 +1291,7 @@ bool InstrRefBasedLDV::transferDebugPHI(MachineInstr &MI) {
12631291 Optional<ValueIDNum> Result = None;
12641292 Optional<LocIdx> SpillLoc = None;
12651293 for (unsigned CS : CandidateSizes) {
1266- unsigned SpillID = MTracker->getLocID (SpillNo, {CS, 0 });
1294+ unsigned SpillID = MTracker->getLocID (* SpillNo, {CS, 0 });
12671295 SpillLoc = MTracker->getSpillMLoc (SpillID);
12681296 ValueIDNum Val = MTracker->readMLoc (*SpillLoc);
12691297 // If this value was defined in it's own position, then it was probably
@@ -1280,7 +1308,7 @@ bool InstrRefBasedLDV::transferDebugPHI(MachineInstr &MI) {
12801308 // "supposed" to be is more complex, and benefits a small number of
12811309 // locations.
12821310 if (!Result) {
1283- unsigned SpillID = MTracker->getLocID (SpillNo, {64 , 0 });
1311+ unsigned SpillID = MTracker->getLocID (* SpillNo, {64 , 0 });
12841312 SpillLoc = MTracker->getSpillMLoc (SpillID);
12851313 Result = MTracker->readMLoc (*SpillLoc);
12861314 }
@@ -1357,11 +1385,12 @@ void InstrRefBasedLDV::transferRegisterDef(MachineInstr &MI) {
13571385
13581386 // If this instruction writes to a spill slot, def that slot.
13591387 if (hasFoldedStackStore (MI)) {
1360- SpillLocationNo SpillNo = extractSpillBaseRegAndOffset (MI);
1361- for (unsigned int I = 0 ; I < MTracker->NumSlotIdxes ; ++I) {
1362- unsigned SpillID = MTracker->getSpillIDWithIdx (SpillNo, I);
1363- LocIdx L = MTracker->getSpillMLoc (SpillID);
1364- MTracker->setMLoc (L, ValueIDNum (CurBB, CurInst, L));
1388+ if (Optional<SpillLocationNo> SpillNo = extractSpillBaseRegAndOffset (MI)) {
1389+ for (unsigned int I = 0 ; I < MTracker->NumSlotIdxes ; ++I) {
1390+ unsigned SpillID = MTracker->getSpillIDWithIdx (*SpillNo, I);
1391+ LocIdx L = MTracker->getSpillMLoc (SpillID);
1392+ MTracker->setMLoc (L, ValueIDNum (CurBB, CurInst, L));
1393+ }
13651394 }
13661395 }
13671396
@@ -1398,11 +1427,12 @@ void InstrRefBasedLDV::transferRegisterDef(MachineInstr &MI) {
13981427
13991428 // Tell TTracker about any folded stack store.
14001429 if (hasFoldedStackStore (MI)) {
1401- SpillLocationNo SpillNo = extractSpillBaseRegAndOffset (MI);
1402- for (unsigned int I = 0 ; I < MTracker->NumSlotIdxes ; ++I) {
1403- unsigned SpillID = MTracker->getSpillIDWithIdx (SpillNo, I);
1404- LocIdx L = MTracker->getSpillMLoc (SpillID);
1405- TTracker->clobberMloc (L, MI.getIterator (), true );
1430+ if (Optional<SpillLocationNo> SpillNo = extractSpillBaseRegAndOffset (MI)) {
1431+ for (unsigned int I = 0 ; I < MTracker->NumSlotIdxes ; ++I) {
1432+ unsigned SpillID = MTracker->getSpillIDWithIdx (*SpillNo, I);
1433+ LocIdx L = MTracker->getSpillMLoc (SpillID);
1434+ TTracker->clobberMloc (L, MI.getIterator (), true );
1435+ }
14061436 }
14071437 }
14081438}
@@ -1438,23 +1468,24 @@ void InstrRefBasedLDV::performCopy(Register SrcRegNum, Register DstRegNum) {
14381468 }
14391469}
14401470
1441- bool InstrRefBasedLDV::isSpillInstruction (const MachineInstr &MI,
1442- MachineFunction *MF) {
1471+ Optional<SpillLocationNo>
1472+ InstrRefBasedLDV::isSpillInstruction (const MachineInstr &MI,
1473+ MachineFunction *MF) {
14431474 // TODO: Handle multiple stores folded into one.
14441475 if (!MI.hasOneMemOperand ())
1445- return false ;
1476+ return None ;
14461477
14471478 // Reject any memory operand that's aliased -- we can't guarantee its value.
14481479 auto MMOI = MI.memoperands_begin ();
14491480 const PseudoSourceValue *PVal = (*MMOI)->getPseudoValue ();
14501481 if (PVal->isAliased (MFI))
1451- return false ;
1482+ return None ;
14521483
14531484 if (!MI.getSpillSize (TII) && !MI.getFoldedSpillSize (TII))
1454- return false ; // This is not a spill instruction, since no valid size was
1455- // returned from either function.
1485+ return None ; // This is not a spill instruction, since no valid size was
1486+ // returned from either function.
14561487
1457- return true ;
1488+ return extractSpillBaseRegAndOffset (MI) ;
14581489}
14591490
14601491bool InstrRefBasedLDV::isLocationSpill (const MachineInstr &MI,
@@ -1511,13 +1542,11 @@ bool InstrRefBasedLDV::transferSpillOrRestoreInst(MachineInstr &MI) {
15111542 // First, if there are any DBG_VALUEs pointing at a spill slot that is
15121543 // written to, terminate that variable location. The value in memory
15131544 // will have changed. DbgEntityHistoryCalculator doesn't try to detect this.
1514- if (isSpillInstruction (MI, MF)) {
1515- SpillLocationNo Loc = extractSpillBaseRegAndOffset (MI);
1516-
1545+ if (Optional<SpillLocationNo> Loc = isSpillInstruction (MI, MF)) {
15171546 // Un-set this location and clobber, so that earlier locations don't
15181547 // continue past this store.
15191548 for (unsigned SlotIdx = 0 ; SlotIdx < MTracker->NumSlotIdxes ; ++SlotIdx) {
1520- unsigned SpillID = MTracker->getSpillIDWithIdx (Loc, SlotIdx);
1549+ unsigned SpillID = MTracker->getSpillIDWithIdx (* Loc, SlotIdx);
15211550 Optional<LocIdx> MLoc = MTracker->getSpillMLoc (SpillID);
15221551 if (!MLoc)
15231552 continue ;
@@ -1535,7 +1564,9 @@ bool InstrRefBasedLDV::transferSpillOrRestoreInst(MachineInstr &MI) {
15351564
15361565 // Try to recognise spill and restore instructions that may transfer a value.
15371566 if (isLocationSpill (MI, MF, Reg)) {
1538- SpillLocationNo Loc = extractSpillBaseRegAndOffset (MI);
1567+ // isLocationSpill returning true should guarantee we can extract a
1568+ // location.
1569+ SpillLocationNo Loc = *extractSpillBaseRegAndOffset (MI);
15391570
15401571 auto DoTransfer = [&](Register SrcReg, unsigned SpillID) {
15411572 auto ReadValue = MTracker->readReg (SrcReg);
@@ -1562,10 +1593,9 @@ bool InstrRefBasedLDV::transferSpillOrRestoreInst(MachineInstr &MI) {
15621593 unsigned SpillID = MTracker->getLocID (Loc, {Size, 0 });
15631594 DoTransfer (Reg, SpillID);
15641595 } else {
1565- Optional<SpillLocationNo> OptLoc = isRestoreInstruction (MI, MF, Reg);
1566- if (!OptLoc )
1596+ Optional<SpillLocationNo> Loc = isRestoreInstruction (MI, MF, Reg);
1597+ if (!Loc )
15671598 return false ;
1568- SpillLocationNo Loc = *OptLoc;
15691599
15701600 // Assumption: we're reading from the base of the stack slot, not some
15711601 // offset into it. It seems very unlikely LLVM would ever generate
@@ -1592,13 +1622,13 @@ bool InstrRefBasedLDV::transferSpillOrRestoreInst(MachineInstr &MI) {
15921622
15931623 for (MCSubRegIterator SRI (Reg, TRI, false ); SRI.isValid (); ++SRI) {
15941624 unsigned Subreg = TRI->getSubRegIndex (Reg, *SRI);
1595- unsigned SpillID = MTracker->getLocID (Loc, Subreg);
1625+ unsigned SpillID = MTracker->getLocID (* Loc, Subreg);
15961626 DoTransfer (*SRI, SpillID);
15971627 }
15981628
15991629 // Directly look up this registers slot idx by size, and transfer.
16001630 unsigned Size = TRI->getRegSizeInBits (Reg, *MRI);
1601- unsigned SpillID = MTracker->getLocID (Loc, {Size, 0 });
1631+ unsigned SpillID = MTracker->getLocID (* Loc, {Size, 0 });
16021632 DoTransfer (Reg, SpillID);
16031633 }
16041634 return true ;
0 commit comments