Index: llvm/lib/CodeGen/LiveDebugValues.cpp =================================================================== --- llvm/lib/CodeGen/LiveDebugValues.cpp +++ llvm/lib/CodeGen/LiveDebugValues.cpp @@ -89,6 +89,24 @@ return MI.getOperand(0).isReg() ? MI.getOperand(0).getReg() : Register(); } +/// If \p Op is a stack or frame register return true, otherwise return false. +/// This is used to avoid basing the debug entry values on the registers, since +/// we do not support it at the moment. +static bool isRegOtherThanSPAndFP(const MachineOperand &Op, + const MachineInstr &MI, + const TargetRegisterInfo *TRI) { + if (!Op.isReg()) + return false; + + const MachineFunction *MF = MI.getParent()->getParent(); + const TargetLowering *TLI = MF->getSubtarget().getTargetLowering(); + unsigned SP = TLI->getStackPointerRegisterToSaveRestore(); + Register FP = TRI->getFrameRegister(*MF); + Register Reg = Op.getReg(); + + return Reg && Reg != SP && Reg != FP; +} + namespace { class LiveDebugValues : public MachineFunctionPass { @@ -456,6 +474,13 @@ bool isLocationSpill(const MachineInstr &MI, MachineFunction *MF, unsigned &Reg); + /// Returns true if the given machine instruction is a debug value which we + /// can emit entry values for. + /// + /// Currently, we generate debug entry values only for parameters that are + /// unmodified throughout the function and located in a register. + bool isEntryValueCandidate(const MachineInstr &MI) const; + /// If a given instruction is identified as a spill, return the spill location /// and set \p Reg to the spilled register. Optional isRestoreInstruction(const MachineInstr &MI, @@ -1249,6 +1274,39 @@ } } +bool LiveDebugValues::isEntryValueCandidate(const MachineInstr &MI) const { + if (!MI.isDebugValue()) + return false; + + // TODO: Add support for local variables that are expressed in terms of + // parameters entry values. + // TODO: Add support for modified arguments that can be expressed + // by using its entry value. + auto *DIVar = MI.getDebugVariable(); + if (!DIVar->isParameter() || !DIVar->isNotModified()) + return false; + + // Do not consider parameters that belong to an inlined function. + if (MI.getDebugLoc()->getInlinedAt()) + return false; + + // Do not consider indirect debug values (TODO: explain why). + if (MI.isIndirectDebugValue()) + return false; + + // Only consider parameters that are described using registers. Parameters + // that are passed on the stack are not yet supported, so ignore debug + // values that are described by the frame or stack pointer. + if (!isRegOtherThanSPAndFP(MI.getOperand(0), MI, TRI)) + return false; + + // TODO: Add support for parameters that are described as fragments. + if (MI.getDebugExpression()->isFragment()) + return false; + + return true; +} + /// Calculate the liveness information for the given machine function and /// extend ranges across basic blocks. bool LiveDebugValues::ExtendRanges(MachineFunction &MF) { @@ -1285,42 +1343,17 @@ std::greater> Pending; - // Besides parameter's modification, check whether a DBG_VALUE is inlined - // in order to deduce whether the variable that it tracks comes from - // a different function. If that is the case we can't track its entry value. - auto IsUnmodifiedFuncParam = [&](const MachineInstr &MI) { - auto *DIVar = MI.getDebugVariable(); - return DIVar->isParameter() && DIVar->isNotModified() && - !MI.getDebugLoc()->getInlinedAt(); - }; - - const TargetLowering *TLI = MF.getSubtarget().getTargetLowering(); - unsigned SP = TLI->getStackPointerRegisterToSaveRestore(); - Register FP = TRI->getFrameRegister(MF); - auto IsRegOtherThanSPAndFP = [&](const MachineOperand &Op) -> bool { - return Op.isReg() && Op.getReg() != SP && Op.getReg() != FP; - }; - // Working set of currently collected debug variables mapped to DBG_VALUEs // representing candidates for production of debug entry values. DebugParamMap DebugEntryVals; - MachineBasicBlock &First_MBB = *(MF.begin()); // Only in the case of entry MBB collect DBG_VALUEs representing // function parameters in order to generate debug entry values for them. - // Currently, we generate debug entry values only for parameters that are - // unmodified throughout the function and located in a register. - // TODO: Add support for parameters that are described as fragments. - // TODO: Add support for modified arguments that can be expressed - // by using its entry value. - // TODO: Add support for local variables that are expressed in terms of - // parameters entry values. + MachineBasicBlock &First_MBB = *(MF.begin()); for (auto &MI : First_MBB) - if (MI.isDebugValue() && IsUnmodifiedFuncParam(MI) && - !MI.isIndirectDebugValue() && IsRegOtherThanSPAndFP(MI.getOperand(0)) && - !DebugEntryVals.count(MI.getDebugVariable()) && - !MI.getDebugExpression()->isFragment()) - DebugEntryVals[MI.getDebugVariable()] = &MI; + if (isEntryValueCandidate(MI)) + if (!DebugEntryVals.count(MI.getDebugVariable())) + DebugEntryVals[MI.getDebugVariable()] = &MI; // Initialize per-block structures and scan for fragment overlaps. for (auto &MBB : MF) {