Index: lib/CodeGen/LiveDebugValues.cpp =================================================================== --- lib/CodeGen/LiveDebugValues.cpp +++ lib/CodeGen/LiveDebugValues.cpp @@ -143,15 +143,23 @@ typedef SparseBitVector<> VarLocSet; typedef SmallDenseMap VarLocInMBB; - /// This holds the working set of currently open ranges. For fast - /// access, this is done both as a set of VarLocIDs, and a map of - /// DebugVariable to recent VarLocID. Note that a DBG_VALUE ends all - /// previous open ranges for the same variable. + /// This holds the working set of currently open ranges. The + /// canonical list is implemented as a set of VarLocIDs. Redundant + /// data structures exist for optimization purposes: + /// + /// - For fast access in transferDebugValue() a map from + /// DebugVariable to recent VarLocID is stored. Note that a + /// DBG_VALUE ends all previous open ranges for the same variable. + /// + /// - For fast access in transferRegisterDef, a bitvector of + /// registers holding DebugVariables is stored. class OpenRangesSet { VarLocSet VarLocs; SmallDenseMap Vars; + BitVector Regs; public: + OpenRangesSet(unsigned NumRegs) : Regs(NumRegs) {} const VarLocSet &getVarLocs() const { return VarLocs; } /// Terminate all open ranges for Var by removing it from the set. @@ -164,24 +172,38 @@ } } - /// Terminate all open ranges listed in \c KillSet by removing + /// Terminate ranges of all registers listed in \c ClobberedRegs by removing /// them from the set. - void erase(const VarLocSet &KillSet, const VarLocMap &VarLocIDs) { + void erase(BitVector &ClobberedRegs, const VarLocMap &VarLocIDs, + const MCRegisterInfo *TRI) { + VarLocSet KillSet; + ClobberedRegs &= Regs; + if (ClobberedRegs.any()) + for (unsigned ID : VarLocs) + if (unsigned RegNo = VarLocIDs[ID].isDescribedByReg()) + for (MCRegAliasIterator RAI(RegNo, TRI, true); RAI.isValid(); ++RAI) + if (ClobberedRegs[*RAI]) { + KillSet.set(ID); + Vars.erase(VarLocIDs[ID].Var); + Regs.reset(*RAI); + } VarLocs.intersectWithComplement(KillSet); - for (unsigned ID : KillSet) - Vars.erase(VarLocIDs[ID].Var); } /// Insert a new range into the set. - void insert(unsigned VarLocID, DebugVariableBase Var) { + void insert(unsigned VarLocID, DebugVariableBase Var, unsigned RegNo, + const MCRegisterInfo *TRI) { VarLocs.set(VarLocID); Vars.insert({Var, VarLocID}); + for (MCRegAliasIterator RAI(RegNo, TRI, true); RAI.isValid(); ++RAI) + Regs.set(*RAI); } /// Empty the set. void clear() { VarLocs.clear(); Vars.clear(); + Regs.reset(); } /// Return whether the set is empty or not. @@ -292,10 +314,10 @@ // Add the VarLoc to OpenRanges from this DBG_VALUE. // TODO: Currently handles DBG_VALUE which has only reg as location. - if (isDbgValueDescribedByReg(MI)) { + if (unsigned RegNo = isDbgValueDescribedByReg(MI)) { VarLoc VL(MI); unsigned ID = VarLocIDs.insert(VL); - OpenRanges.insert(ID, VL.Var); + OpenRanges.insert(ID, VL.Var, RegNo, TRI); } } @@ -306,28 +328,24 @@ MachineFunction *MF = MI.getParent()->getParent(); const TargetLowering *TLI = MF->getSubtarget().getTargetLowering(); unsigned SP = TLI->getStackPointerRegisterToSaveRestore(); - SparseBitVector<> KillSet; + BitVector ClobberedRegs(TRI->getNumRegs()); for (const MachineOperand &MO : MI.operands()) { if (MO.isReg() && MO.isDef() && MO.getReg() && TRI->isPhysicalRegister(MO.getReg())) { // Remove ranges of all aliased registers. - for (MCRegAliasIterator RAI(MO.getReg(), TRI, true); RAI.isValid(); ++RAI) - for (unsigned ID : OpenRanges.getVarLocs()) - if (VarLocIDs[ID].isDescribedByReg() == *RAI) - KillSet.set(ID); + ClobberedRegs.set(MO.getReg()); } else if (MO.isRegMask()) { // Remove ranges of all clobbered registers. Register masks don't usually // list SP as preserved. While the debug info may be off for an // instruction or two around callee-cleanup calls, transferring the // DEBUG_VALUE across the call is still a better user experience. - for (unsigned ID : OpenRanges.getVarLocs()) { - unsigned Reg = VarLocIDs[ID].isDescribedByReg(); - if (Reg && Reg != SP && MO.clobbersPhysReg(Reg)) - KillSet.set(ID); - } + BitVector Mask(TRI->getNumRegs()); + Mask.setBitsNotInMask(MO.getRegMask()); + Mask.reset(SP); + ClobberedRegs |= Mask; } } - OpenRanges.erase(KillSet, VarLocIDs); + OpenRanges.erase(ClobberedRegs, VarLocIDs, TRI); } /// Terminate all open ranges at the end of the current basic block. @@ -429,8 +447,9 @@ bool MBBJoined = false; VarLocMap VarLocIDs; // Map VarLoc<>unique ID for use in bitvectors. - OpenRangesSet OpenRanges; // Ranges that are open until end of bb. - VarLocInMBB OutLocs; // Ranges that exist beyond bb. + OpenRangesSet OpenRanges( + TRI->getNumRegs()); // Ranges that are open until end of bb. + VarLocInMBB OutLocs; // Ranges that exist beyond bb. VarLocInMBB InLocs; // Ranges that are incoming after joining. DenseMap OrderToBB;