This is an archive of the discontinued LLVM Phabricator instance.

[AMDGPU] Fix prologue/epilogue markers in .debug_line table for trivial functions
ClosedPublic

Authored by RamNalamothu on Aug 9 2022, 4:27 AM.

Details

Summary

All the prologue instructions should have unknown source location
co-ordinates while the epilogue instructions should have source
location of last non-debug instruction after which epilogue
instructions are insrted.

This ensures the prologue/epilogue markers are generated correctly
in the line table.

Changes are brought in from the downstream CFI patches.

Diff Detail

Event Timeline

RamNalamothu created this revision.Aug 9 2022, 4:27 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 9 2022, 4:27 AM
RamNalamothu requested review of this revision.Aug 9 2022, 4:27 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 9 2022, 4:27 AM

One nit, but the rest LGTM

llvm/lib/Target/AMDGPU/SIFrameLowering.cpp
976

Looking at other targets, I'm not sure how to interpret the case where there are no terminators. Some backends seem to assume there is always a terminator:

void MSP430FrameLowering::emitEpilogue(MachineFunction &MF,
                                       MachineBasicBlock &MBB) const {
  ...
  DebugLoc DL = MBBI->getDebugLoc();

Others also explicitly handle the case where MBB.empty(), and also use the DebugLoc of the last non-debug instruction instead of just using an empty DebugLoc():

void CSKYFrameLowering::emitEpilogue(MachineFunction &MF,
                                     MachineBasicBlock &MBB) const {
  ...
  // Get the insert location for the epilogue. If there were no terminators in
  // the block, get the last instruction.
  MachineBasicBlock::iterator MBBI = MBB.end();
  DebugLoc DL;
  if (!MBB.empty()) {
    MBBI = MBB.getFirstTerminator();
    if (MBBI == MBB.end())
      MBBI = MBB.getLastNonDebugInstr();
    DL = MBBI->getDebugLoc();

    // If this is not a terminator, the actual insert location should be after
    // the last instruction.
    if (!MBBI->isTerminator())
      MBBI = std::next(MBBI);
  }

There may be other approaches, I didn't review every Target's impl, but I think we should pick one of the existing approaches unless we have a strong reason not to.

Address review comments.

scott.linder accepted this revision.Aug 10 2022, 10:04 AM

LGTM

Maybe in the future the various versions of this could be merged, but as it stands there seems to be essentially N targets which do this N different ways, which is a problem we can't solve here.

This revision is now accepted and ready to land.Aug 10 2022, 10:04 AM
This revision was landed with ongoing or failed builds.Aug 10 2022, 10:30 AM
This revision was automatically updated to reflect the committed changes.
RamNalamothu marked an inline comment as done.
RamNalamothu added inline comments.Aug 10 2022, 10:35 AM
llvm/lib/Target/AMDGPU/SIFrameLowering.cpp
976

Thanks for catching this Scott.

What we basically would want to do here is insert epilogue instructions after the last non debug instruction but before the terminator instruction if any. And targets with branch/jump delay slots might have to consider additional scenarios.

By looking at PEI::calculateSaveRestoreBlocks(), it is possible that some of the restore blocks may not have a terminator. And checking if MBB.empty() is just for efficiency of implementation.

I think the revised patch should do for our backend.

I thought I have already submitted this reply.

foad added inline comments.Aug 22 2022, 9:31 AM
llvm/lib/Target/AMDGPU/SIFrameLowering.cpp
976

Maybe use MachineBasicBlock::{r}find{Prev}DebugLoc functions?