diff options
author | Alexey Samsonov <samsonov@google.com> | 2014-04-30 21:34:11 +0000 |
---|---|---|
committer | Alexey Samsonov <samsonov@google.com> | 2014-04-30 21:34:11 +0000 |
commit | 414b6fb1701e321354bdccade60dd36c5ba62e4a (patch) | |
tree | 46520a489c73533eb19ee331c067501123883905 /llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | |
parent | 6759fd9fdd3c9d49c8aaf64626d5a8c59648ed10 (diff) | |
download | bcm5719-llvm-414b6fb1701e321354bdccade60dd36c5ba62e4a.tar.gz bcm5719-llvm-414b6fb1701e321354bdccade60dd36c5ba62e4a.zip |
Move logic for calculating DBG_VALUE history map into separate file/class.
Summary: No functionality change.
Test Plan: llvm regression test suite.
Reviewers: dblaikie
Reviewed By: dblaikie
Subscribers: echristo, llvm-commits
Differential Revision: http://reviews.llvm.org/D3573
llvm-svn: 207708
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 137 |
1 files changed, 18 insertions, 119 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index d9ef6c04285..e0bc4bd7239 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -1158,16 +1158,6 @@ void DwarfDebug::collectVariableInfoFromMMITable( } } -// Return true if debug value, encoded by DBG_VALUE instruction, is in a -// defined reg. -static bool isDbgValueInDefinedReg(const MachineInstr *MI) { - assert(MI->isDebugValue() && "Invalid DBG_VALUE machine instruction!"); - return MI->getNumOperands() == 3 && MI->getOperand(0).isReg() && - MI->getOperand(0).getReg() && - (MI->getOperand(1).isImm() || - (MI->getOperand(1).isReg() && MI->getOperand(1).getReg() == 0U)); -} - // Get .debug_loc entry for the instruction range starting at MI. static DebugLocEntry::Value getDebugLocValue(const MachineInstr *MI) { const MDNode *Var = MI->getDebugVariable(); @@ -1449,138 +1439,47 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) { // Assumes in correct section after the entry point. Asm->OutStreamer.EmitLabel(FunctionBeginSym); - const TargetRegisterInfo *TRI = Asm->TM.getRegisterInfo(); - // LiveUserVar - Map physreg numbers to the MDNode they contain. - std::vector<const MDNode *> LiveUserVar(TRI->getNumRegs()); - + // Collect user variables, find the end of the prologue. for (MachineFunction::const_iterator I = MF->begin(), E = MF->end(); I != E; ++I) { - bool AtBlockEntry = true; for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end(); II != IE; ++II) { const MachineInstr *MI = II; - if (MI->isDebugValue()) { assert(MI->getNumOperands() > 1 && "Invalid machine instruction!"); - - // Keep track of user variables. + // Keep track of user variables in order of appearance. Store the set + // of variables we've already seen as a set of keys in DbgValues. const MDNode *Var = MI->getDebugVariable(); - - // Variable is in a register, we need to check for clobbers. - if (isDbgValueInDefinedReg(MI)) - LiveUserVar[MI->getOperand(0).getReg()] = Var; - - // Check the history of this variable. - SmallVectorImpl<const MachineInstr *> &History = DbgValues[Var]; - if (History.empty()) { + auto IterPair = DbgValues.insert( + std::make_pair(Var, SmallVector<const MachineInstr *, 4>())); + if (IterPair.second) UserVariables.push_back(Var); - // The first mention of a function argument gets the FunctionBeginSym - // label, so arguments are visible when breaking at function entry. - DIVariable DV(Var); - if (DV.isVariable() && DV.getTag() == dwarf::DW_TAG_arg_variable && - getDISubprogram(DV.getContext()).describes(MF->getFunction())) - LabelsBeforeInsn[MI] = FunctionBeginSym; - } else { - // 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); - } - } - } - History.push_back(MI); } else { - // Not a DBG_VALUE instruction. - if (!MI->isPosition()) - AtBlockEntry = false; - // First known non-DBG_VALUE and non-frame setup location marks // the beginning of the function body. if (!MI->getFlag(MachineInstr::FrameSetup) && (PrologEndLoc.isUnknown() && !MI->getDebugLoc().isUnknown())) PrologEndLoc = MI->getDebugLoc(); - - // Check if the instruction clobbers any registers with 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 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? - DbgValueHistoryMap::iterator HistI = DbgValues.find(Var); - if (HistI == DbgValues.end()) - continue; - SmallVectorImpl<const MachineInstr *> &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. - History.push_back(MI); - } - } } } } + // Calculate history for local variables. + calculateDbgValueHistory(MF, Asm->TM.getRegisterInfo(), DbgValues); + + // Request labels for the full history. for (auto &I : DbgValues) { - SmallVectorImpl<const MachineInstr *> &History = I.second; + const SmallVectorImpl<const MachineInstr *> &History = I.second; if (History.empty()) continue; - // Make sure the final register assignments are terminated. - 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); - } - } - // Request labels for the full history. + // The first mention of a function argument gets the FunctionBeginSym + // label, so arguments are visible when breaking at function entry. + DIVariable DV(I.first); + if (DV.isVariable() && DV.getTag() == dwarf::DW_TAG_arg_variable && + getDISubprogram(DV.getContext()).describes(MF->getFunction())) + LabelsBeforeInsn[History.front()] = FunctionBeginSym; + for (const MachineInstr *MI : History) { if (MI->isDebugValue()) requestLabelBeforeInsn(MI); |