1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 11:02:59 +02:00

[LiveDebugVariables] Add cache for SkipPHIsLabelsAndDebug to prevent

iterating the same PHI/LABEL/Debug instructions repeatedly.

We run into a compiling timeout problem when building a target after its
SampleFDO profile is updated. It is because some very large blocks with
a bunch of PHIs at the beginning. LiveDebugVariables::emitDebugValues
called during VirtRegRewriter phase searchs the insertion point for those
large BBs repeatedly in SkipPHIsLabelsAndDebug, and each time
SkipPHIsLabelsAndDebug needs to go through the same set of PHIs before it
can find the first non PHI/Label/Debug instruction. This patch adds a cache
to save the last position for the sequence which has been checked in the
previous call of SkipPHIsLabelsAndDebug.

Differential Revision: https://reviews.llvm.org/D94981
This commit is contained in:
Wei Mi 2021-01-16 10:11:18 -08:00
parent 6a837450cc
commit 034d6b415f

View File

@ -145,6 +145,14 @@ using LocMap = IntervalMap<SlotIndex, DbgVariableValue, 4>;
/// Non-spilled locations are not added to the map. /// Non-spilled locations are not added to the map.
using SpillOffsetMap = DenseMap<unsigned, unsigned>; using SpillOffsetMap = DenseMap<unsigned, unsigned>;
/// Cache to save the location where it can be used as the starting
/// position as input for calling MachineBasicBlock::SkipPHIsLabelsAndDebug.
/// This is to prevent MachineBasicBlock::SkipPHIsLabelsAndDebug from
/// repeatedly searching the same set of PHIs/Labels/Debug instructions
/// if it is called many times for the same block.
using BlockSkipInstsMap =
DenseMap<MachineBasicBlock *, MachineBasicBlock::iterator>;
namespace { namespace {
class LDVImpl; class LDVImpl;
@ -181,7 +189,8 @@ class UserValue {
SlotIndex StopIdx, DbgVariableValue DbgValue, SlotIndex StopIdx, DbgVariableValue DbgValue,
bool Spilled, unsigned SpillOffset, LiveIntervals &LIS, bool Spilled, unsigned SpillOffset, LiveIntervals &LIS,
const TargetInstrInfo &TII, const TargetInstrInfo &TII,
const TargetRegisterInfo &TRI); const TargetRegisterInfo &TRI,
BlockSkipInstsMap &BBSkipInstsMap);
/// Replace OldLocNo ranges with NewRegs ranges where NewRegs /// Replace OldLocNo ranges with NewRegs ranges where NewRegs
/// is live. Returns true if any changes were made. /// is live. Returns true if any changes were made.
@ -348,7 +357,8 @@ public:
void emitDebugValues(VirtRegMap *VRM, LiveIntervals &LIS, void emitDebugValues(VirtRegMap *VRM, LiveIntervals &LIS,
const TargetInstrInfo &TII, const TargetInstrInfo &TII,
const TargetRegisterInfo &TRI, const TargetRegisterInfo &TRI,
const SpillOffsetMap &SpillOffsets); const SpillOffsetMap &SpillOffsets,
BlockSkipInstsMap &BBSkipInstsMap);
/// Return DebugLoc of this UserValue. /// Return DebugLoc of this UserValue.
DebugLoc getDebugLoc() { return dl;} DebugLoc getDebugLoc() { return dl;}
@ -365,7 +375,8 @@ class UserLabel {
/// Insert a DBG_LABEL into MBB at Idx. /// Insert a DBG_LABEL into MBB at Idx.
void insertDebugLabel(MachineBasicBlock *MBB, SlotIndex Idx, void insertDebugLabel(MachineBasicBlock *MBB, SlotIndex Idx,
LiveIntervals &LIS, const TargetInstrInfo &TII); LiveIntervals &LIS, const TargetInstrInfo &TII,
BlockSkipInstsMap &BBSkipInstsMap);
public: public:
/// Create a new UserLabel. /// Create a new UserLabel.
@ -379,7 +390,8 @@ public:
} }
/// Recreate DBG_LABEL instruction from data structures. /// Recreate DBG_LABEL instruction from data structures.
void emitDebugLabel(LiveIntervals &LIS, const TargetInstrInfo &TII); void emitDebugLabel(LiveIntervals &LIS, const TargetInstrInfo &TII,
BlockSkipInstsMap &BBSkipInstsMap);
/// Return DebugLoc of this UserLabel. /// Return DebugLoc of this UserLabel.
DebugLoc getDebugLoc() { return dl; } DebugLoc getDebugLoc() { return dl; }
@ -1282,8 +1294,8 @@ void UserValue::rewriteLocations(VirtRegMap &VRM, const MachineFunction &MF,
/// Find an iterator for inserting a DBG_VALUE instruction. /// Find an iterator for inserting a DBG_VALUE instruction.
static MachineBasicBlock::iterator static MachineBasicBlock::iterator
findInsertLocation(MachineBasicBlock *MBB, SlotIndex Idx, findInsertLocation(MachineBasicBlock *MBB, SlotIndex Idx, LiveIntervals &LIS,
LiveIntervals &LIS) { BlockSkipInstsMap &BBSkipInstsMap) {
SlotIndex Start = LIS.getMBBStartIdx(MBB); SlotIndex Start = LIS.getMBBStartIdx(MBB);
Idx = Idx.getBaseIndex(); Idx = Idx.getBaseIndex();
@ -1292,7 +1304,29 @@ findInsertLocation(MachineBasicBlock *MBB, SlotIndex Idx,
while (!(MI = LIS.getInstructionFromIndex(Idx))) { while (!(MI = LIS.getInstructionFromIndex(Idx))) {
// We've reached the beginning of MBB. // We've reached the beginning of MBB.
if (Idx == Start) { if (Idx == Start) {
MachineBasicBlock::iterator I = MBB->SkipPHIsLabelsAndDebug(MBB->begin()); // Retrieve the last PHI/Label/Debug location found when calling
// SkipPHIsLabelsAndDebug last time. Start searching from there.
//
// Note the iterator kept in BBSkipInstsMap is one step back based
// on the iterator returned by SkipPHIsLabelsAndDebug last time.
// One exception is when SkipPHIsLabelsAndDebug returns MBB->begin(),
// BBSkipInstsMap won't save it. This is to consider the case that
// new instructions may be inserted at the beginning of MBB after
// last call of SkipPHIsLabelsAndDebug. If we save MBB->begin() in
// BBSkipInstsMap, after new non-phi/non-label/non-debug instructions
// are inserted at the beginning of the MBB, the iterator in
// BBSkipInstsMap won't point to the beginning of the MBB anymore.
// Therefore The next search in SkipPHIsLabelsAndDebug will skip those
// newly added instructions and that is unwanted.
MachineBasicBlock::iterator BeginIt;
auto MapIt = BBSkipInstsMap.find(MBB);
if (MapIt == BBSkipInstsMap.end())
BeginIt = MBB->begin();
else
BeginIt = std::next(MapIt->second);
auto I = MBB->SkipPHIsLabelsAndDebug(BeginIt);
if (I != BeginIt)
BBSkipInstsMap[MBB] = std::prev(I);
return I; return I;
} }
Idx = Idx.getPrevIndex(); Idx = Idx.getPrevIndex();
@ -1332,11 +1366,13 @@ void UserValue::insertDebugValue(MachineBasicBlock *MBB, SlotIndex StartIdx,
SlotIndex StopIdx, DbgVariableValue DbgValue, SlotIndex StopIdx, DbgVariableValue DbgValue,
bool Spilled, unsigned SpillOffset, bool Spilled, unsigned SpillOffset,
LiveIntervals &LIS, const TargetInstrInfo &TII, LiveIntervals &LIS, const TargetInstrInfo &TII,
const TargetRegisterInfo &TRI) { const TargetRegisterInfo &TRI,
BlockSkipInstsMap &BBSkipInstsMap) {
SlotIndex MBBEndIdx = LIS.getMBBEndIdx(&*MBB); SlotIndex MBBEndIdx = LIS.getMBBEndIdx(&*MBB);
// Only search within the current MBB. // Only search within the current MBB.
StopIdx = (MBBEndIdx < StopIdx) ? MBBEndIdx : StopIdx; StopIdx = (MBBEndIdx < StopIdx) ? MBBEndIdx : StopIdx;
MachineBasicBlock::iterator I = findInsertLocation(MBB, StartIdx, LIS); MachineBasicBlock::iterator I =
findInsertLocation(MBB, StartIdx, LIS, BBSkipInstsMap);
// Undef values don't exist in locations so create new "noreg" register MOs // Undef values don't exist in locations so create new "noreg" register MOs
// for them. See getLocationNo(). // for them. See getLocationNo().
MachineOperand MO = MachineOperand MO =
@ -1382,9 +1418,10 @@ void UserValue::insertDebugValue(MachineBasicBlock *MBB, SlotIndex StartIdx,
} }
void UserLabel::insertDebugLabel(MachineBasicBlock *MBB, SlotIndex Idx, void UserLabel::insertDebugLabel(MachineBasicBlock *MBB, SlotIndex Idx,
LiveIntervals &LIS, LiveIntervals &LIS, const TargetInstrInfo &TII,
const TargetInstrInfo &TII) { BlockSkipInstsMap &BBSkipInstsMap) {
MachineBasicBlock::iterator I = findInsertLocation(MBB, Idx, LIS); MachineBasicBlock::iterator I =
findInsertLocation(MBB, Idx, LIS, BBSkipInstsMap);
++NumInsertedDebugLabels; ++NumInsertedDebugLabels;
BuildMI(*MBB, I, getDebugLoc(), TII.get(TargetOpcode::DBG_LABEL)) BuildMI(*MBB, I, getDebugLoc(), TII.get(TargetOpcode::DBG_LABEL))
.addMetadata(Label); .addMetadata(Label);
@ -1393,7 +1430,8 @@ void UserLabel::insertDebugLabel(MachineBasicBlock *MBB, SlotIndex Idx,
void UserValue::emitDebugValues(VirtRegMap *VRM, LiveIntervals &LIS, void UserValue::emitDebugValues(VirtRegMap *VRM, LiveIntervals &LIS,
const TargetInstrInfo &TII, const TargetInstrInfo &TII,
const TargetRegisterInfo &TRI, const TargetRegisterInfo &TRI,
const SpillOffsetMap &SpillOffsets) { const SpillOffsetMap &SpillOffsets,
BlockSkipInstsMap &BBSkipInstsMap) {
MachineFunction::iterator MFEnd = VRM->getMachineFunction().end(); MachineFunction::iterator MFEnd = VRM->getMachineFunction().end();
for (LocMap::const_iterator I = locInts.begin(); I.valid();) { for (LocMap::const_iterator I = locInts.begin(); I.valid();) {
@ -1418,7 +1456,7 @@ void UserValue::emitDebugValues(VirtRegMap *VRM, LiveIntervals &LIS,
LLVM_DEBUG(dbgs() << ' ' << printMBBReference(*MBB) << '-' << MBBEnd); LLVM_DEBUG(dbgs() << ' ' << printMBBReference(*MBB) << '-' << MBBEnd);
insertDebugValue(&*MBB, Start, Stop, DbgValue, Spilled, SpillOffset, LIS, insertDebugValue(&*MBB, Start, Stop, DbgValue, Spilled, SpillOffset, LIS,
TII, TRI); TII, TRI, BBSkipInstsMap);
// This interval may span multiple basic blocks. // This interval may span multiple basic blocks.
// Insert a DBG_VALUE into each one. // Insert a DBG_VALUE into each one.
while (Stop > MBBEnd) { while (Stop > MBBEnd) {
@ -1429,7 +1467,7 @@ void UserValue::emitDebugValues(VirtRegMap *VRM, LiveIntervals &LIS,
MBBEnd = LIS.getMBBEndIdx(&*MBB); MBBEnd = LIS.getMBBEndIdx(&*MBB);
LLVM_DEBUG(dbgs() << ' ' << printMBBReference(*MBB) << '-' << MBBEnd); LLVM_DEBUG(dbgs() << ' ' << printMBBReference(*MBB) << '-' << MBBEnd);
insertDebugValue(&*MBB, Start, Stop, DbgValue, Spilled, SpillOffset, LIS, insertDebugValue(&*MBB, Start, Stop, DbgValue, Spilled, SpillOffset, LIS,
TII, TRI); TII, TRI, BBSkipInstsMap);
} }
LLVM_DEBUG(dbgs() << '\n'); LLVM_DEBUG(dbgs() << '\n');
if (MBB == MFEnd) if (MBB == MFEnd)
@ -1439,12 +1477,13 @@ void UserValue::emitDebugValues(VirtRegMap *VRM, LiveIntervals &LIS,
} }
} }
void UserLabel::emitDebugLabel(LiveIntervals &LIS, const TargetInstrInfo &TII) { void UserLabel::emitDebugLabel(LiveIntervals &LIS, const TargetInstrInfo &TII,
BlockSkipInstsMap &BBSkipInstsMap) {
LLVM_DEBUG(dbgs() << "\t" << loc); LLVM_DEBUG(dbgs() << "\t" << loc);
MachineFunction::iterator MBB = LIS.getMBBFromIndex(loc)->getIterator(); MachineFunction::iterator MBB = LIS.getMBBFromIndex(loc)->getIterator();
LLVM_DEBUG(dbgs() << ' ' << printMBBReference(*MBB)); LLVM_DEBUG(dbgs() << ' ' << printMBBReference(*MBB));
insertDebugLabel(&*MBB, loc, LIS, TII); insertDebugLabel(&*MBB, loc, LIS, TII, BBSkipInstsMap);
LLVM_DEBUG(dbgs() << '\n'); LLVM_DEBUG(dbgs() << '\n');
} }
@ -1453,17 +1492,20 @@ void LDVImpl::emitDebugValues(VirtRegMap *VRM) {
LLVM_DEBUG(dbgs() << "********** EMITTING LIVE DEBUG VARIABLES **********\n"); LLVM_DEBUG(dbgs() << "********** EMITTING LIVE DEBUG VARIABLES **********\n");
if (!MF) if (!MF)
return; return;
BlockSkipInstsMap BBSkipInstsMap;
const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo(); const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo();
SpillOffsetMap SpillOffsets; SpillOffsetMap SpillOffsets;
for (auto &userValue : userValues) { for (auto &userValue : userValues) {
LLVM_DEBUG(userValue->print(dbgs(), TRI)); LLVM_DEBUG(userValue->print(dbgs(), TRI));
userValue->rewriteLocations(*VRM, *MF, *TII, *TRI, SpillOffsets); userValue->rewriteLocations(*VRM, *MF, *TII, *TRI, SpillOffsets);
userValue->emitDebugValues(VRM, *LIS, *TII, *TRI, SpillOffsets); userValue->emitDebugValues(VRM, *LIS, *TII, *TRI, SpillOffsets,
BBSkipInstsMap);
} }
LLVM_DEBUG(dbgs() << "********** EMITTING LIVE DEBUG LABELS **********\n"); LLVM_DEBUG(dbgs() << "********** EMITTING LIVE DEBUG LABELS **********\n");
for (auto &userLabel : userLabels) { for (auto &userLabel : userLabels) {
LLVM_DEBUG(userLabel->print(dbgs(), TRI)); LLVM_DEBUG(userLabel->print(dbgs(), TRI));
userLabel->emitDebugLabel(*LIS, *TII); userLabel->emitDebugLabel(*LIS, *TII, BBSkipInstsMap);
} }
LLVM_DEBUG(dbgs() << "********** EMITTING INSTR REFERENCES **********\n"); LLVM_DEBUG(dbgs() << "********** EMITTING INSTR REFERENCES **********\n");
@ -1475,7 +1517,8 @@ void LDVImpl::emitDebugValues(VirtRegMap *VRM) {
for (auto &P : StashedInstrReferences) { for (auto &P : StashedInstrReferences) {
const SlotIndex &Idx = P.first; const SlotIndex &Idx = P.first;
auto *MBB = Slots->getMBBFromIndex(Idx); auto *MBB = Slots->getMBBFromIndex(Idx);
MachineBasicBlock::iterator insertPos = findInsertLocation(MBB, Idx, *LIS); MachineBasicBlock::iterator insertPos =
findInsertLocation(MBB, Idx, *LIS, BBSkipInstsMap);
for (auto &Stashed : P.second) { for (auto &Stashed : P.second) {
auto MIB = BuildMI(*MF, std::get<4>(Stashed), RefII); auto MIB = BuildMI(*MF, std::get<4>(Stashed), RefII);
MIB.addImm(std::get<0>(Stashed)); MIB.addImm(std::get<0>(Stashed));
@ -1488,6 +1531,7 @@ void LDVImpl::emitDebugValues(VirtRegMap *VRM) {
} }
EmitDone = true; EmitDone = true;
BBSkipInstsMap.clear();
} }
void LiveDebugVariables::emitDebugValues(VirtRegMap *VRM) { void LiveDebugVariables::emitDebugValues(VirtRegMap *VRM) {