Index: lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp +++ lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp @@ -8,10 +8,13 @@ //===----------------------------------------------------------------------===// #include "DbgValueHistoryCalculator.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/Support/Debug.h" #include "llvm/Target/TargetRegisterInfo.h" +#include +#include #define DEBUG_TYPE "dwarfdebug" @@ -30,119 +33,99 @@ void calculateDbgValueHistory(const MachineFunction *MF, const TargetRegisterInfo *TRI, DbgValueHistoryMap &Result) { - // LiveUserVar - Map physreg numbers to the MDNode they contain. - std::vector LiveUserVar(TRI->getNumRegs()); + // LiveUserVar - Map physreg numbers to the MDNodes they describe. + std::map> LiveUserVar; - for (MachineFunction::const_iterator I = MF->begin(), E = MF->end(); I != E; - ++I) { - bool AtBlockEntry = true; - for (const auto &MI : *I) { - if (MI.isDebugValue()) { - assert(MI.getNumOperands() > 1 && "Invalid machine instruction!"); + for (const auto &MBB : *MF) { + // Get the instruction that will be used to clobber history for + // register-described variables. + const auto &LastMBBInstr = MBB.getLastNonDebugInstr(); + bool SeenLastMBBInstr = LastMBBInstr == MBB.end(); - // Keep track of user variables. - const MDNode *Var = MI.getDebugVariable(); + for (const auto &MI : MBB) { + SeenLastMBBInstr |= &MI == LastMBBInstr; + + if (MI.isDebugValue()) { + assert(MI.getNumOperands() > 1 && "Invalid DBG_VALUE instruction!"); - // Variable is in a register, we need to check for clobbers. - if (isDbgValueInDefinedReg(&MI)) - LiveUserVar[MI.getOperand(0).getReg()] = Var; + if (SeenLastMBBInstr && isDbgValueInDefinedReg(&MI)) { + // No sense to add DBG_VALUE to history - it will be colbbered at + // the end of the basic block anyway. + DEBUG(dbgs() << "Dropping DBG_VALUE for empty range:\n" + << "\t" << MI << "\n"); + continue; + } - // Check the history of this variable. + const MDNode *Var = MI.getDebugVariable(); SmallVectorImpl &History = Result[Var]; + // If the previous DBG_VALUE is identical to the current one, don't + // do anything. + if (!History.empty() && History.back()->isIdenticalTo(&MI)) { + DEBUG(dbgs() << "Coalescing identical DBG_VALUE entries:\n" + << "\t" << History.back() << "\t" << MI << "\n"); + continue; + } + + // Specify that variable is not described by the old register + // anymore. if (!History.empty()) { - // We have seen this variable before. Try to coalesce DBG_VALUEs. const MachineInstr *Prev = History.back(); - if (Prev->isDebugValue()) { - // Coalesce identical entries at the end of History. - if (History.size() >= 2 && - Prev->isIdenticalTo(History[History.size() - 2])) { - DEBUG(dbgs() << "Coalescing identical DBG_VALUE entries:\n" - << "\t" << *Prev << "\t" - << *History[History.size() - 2] << "\n"); - History.pop_back(); - } - - // Terminate old register assignments that don't reach MI; - MachineFunction::const_iterator PrevMBB = Prev->getParent(); - if (PrevMBB != I && (!AtBlockEntry || std::next(PrevMBB) != I) && - isDbgValueInDefinedReg(Prev)) { - // Previous register assignment needs to terminate at the end of - // its basic block. - MachineBasicBlock::const_iterator LastMI = - PrevMBB->getLastNonDebugInstr(); - if (LastMI == PrevMBB->end()) { - // Drop DBG_VALUE for empty range. - DEBUG(dbgs() << "Dropping DBG_VALUE for empty range:\n" - << "\t" << *Prev << "\n"); - History.pop_back(); - } else if (std::next(PrevMBB) != PrevMBB->getParent()->end()) - // Terminate after LastMI. - History.push_back(LastMI); - } + if (Prev->isDebugValue() && isDbgValueInDefinedReg(Prev)) { + unsigned OldReg = Prev->getOperand(0).getReg(); + const auto &I = LiveUserVar.find(OldReg); + assert(I != LiveUserVar.end()); + auto &VarSet = I->second; + VarSet.erase(std::find(VarSet.begin(), VarSet.end(), Var)); + if (VarSet.empty()) + LiveUserVar.erase(I); } } + + // Set the new register that describes the variable. + if (isDbgValueInDefinedReg(&MI)) { + unsigned NewReg = MI.getOperand(0).getReg(); + LiveUserVar[NewReg].push_back(Var); + } + History.push_back(&MI); - } else { - // Not a DBG_VALUE instruction. - if (!MI.isPosition()) - AtBlockEntry = false; - - // Check if the instruction clobbers any registers with debug vars. - for (const MachineOperand &MO : MI.operands()) { - if (!MO.isReg() || !MO.isDef() || !MO.getReg()) + continue; + } + + // Not a DBG_VALUE instruction. Check if it clobbers any registers used + // to describe debug vars. + for (const MachineOperand &MO : MI.operands()) { + if (!MO.isReg() || !MO.isDef() || !MO.getReg()) + continue; + for (MCRegAliasIterator AI(MO.getReg(), TRI, true); AI.isValid(); + ++AI) { + unsigned Reg = *AI; + const auto &VarSet = LiveUserVar.find(Reg); + if (VarSet == LiveUserVar.end()) continue; - for (MCRegAliasIterator AI(MO.getReg(), TRI, true); AI.isValid(); - ++AI) { - unsigned Reg = *AI; - const MDNode *Var = LiveUserVar[Reg]; - if (!Var) - continue; - // Reg is now clobbered. - LiveUserVar[Reg] = nullptr; - - // Was MD last defined by a DBG_VALUE referring to Reg? - auto HistI = Result.find(Var); - if (HistI == Result.end()) - continue; - SmallVectorImpl &History = HistI->second; - if (History.empty()) - continue; - const MachineInstr *Prev = History.back(); - // Sanity-check: Register assignments are terminated at the end of - // their block. - if (!Prev->isDebugValue() || Prev->getParent() != MI.getParent()) - continue; - // Is the variable still in Reg? - if (!isDbgValueInDefinedReg(Prev) || - Prev->getOperand(0).getReg() != Reg) - continue; - // Var is clobbered. Make sure the next instruction gets a label. + // Iterate over all varibales described by this register and add this + // instruction to their history, clobbering it. + for (const auto &Var : VarSet->second) { + SmallVectorImpl &History = Result[Var]; History.push_back(&MI); } + // The register doesn't describe any variables anymore. + LiveUserVar.erase(VarSet); } } } - } - - // Make sure the final register assignments are terminated. - for (auto &I : Result) { - SmallVectorImpl &History = I.second; - if (History.empty()) - continue; - - const MachineInstr *Prev = History.back(); - if (Prev->isDebugValue() && isDbgValueInDefinedReg(Prev)) { - const MachineBasicBlock *PrevMBB = Prev->getParent(); - MachineBasicBlock::const_iterator LastMI = - PrevMBB->getLastNonDebugInstr(); - if (LastMI == PrevMBB->end()) - // Drop DBG_VALUE for empty range. - History.pop_back(); - else if (PrevMBB != &PrevMBB->getParent()->back()) { - // Terminate after LastMI. - History.push_back(LastMI); + // Make sure the history for variables described by registers is clobbered + // at the end of the basic block (if it's not the last BB in function). + if (&MBB == &MF->back()) + break; + for (const auto &I : LiveUserVar) { + for (const auto &Var : I.second) { + SmallVectorImpl &History = Result[Var]; + assert(!History.empty() && History.back()->getParent() == &MBB); + assert(LastMBBInstr != MBB.end()); + History.push_back(LastMBBInstr); } } + LiveUserVar.clear(); } }