This is an archive of the discontinued LLVM Phabricator instance.

[llvm] Add DW_CC_nocall to function debug metadata when either return values or arguments are removed
ClosedPublic

Authored by RamNalamothu on Jun 6 2022, 10:59 AM.

Details

Summary

Adding the DW_CC_nocall calling convention to the function debug metadata is needed when either the return values or the arguments of a function are removed as this helps in informing debugger that it may not be safe to call this function or try to interpret the return value.
This translates to setting DW_AT_calling_convention with DW_CC_nocall for appropriate DWARF DIEs.

The DWARF5 spec (section 3.3.1.1 Calling Convention Information) says:

If the DW_AT_calling_convention attribute is not present, or its value is the constant DW_CC_normal, then the subroutine may be safely called by obeying the standard calling conventions of the target architecture. If the value of the calling convention attribute is the constant DW_CC_nocall, the subroutine does not obey standard calling conventions, and it may not be safe for the debugger to call this subroutine.

Diff Detail

Event Timeline

RamNalamothu created this revision.Jun 6 2022, 10:59 AM
Herald added a project: Restricted Project. · View Herald TranscriptJun 6 2022, 10:59 AM
RamNalamothu requested review of this revision.Jun 6 2022, 10:59 AM
Herald added a project: Restricted Project. · View Herald TranscriptJun 6 2022, 10:59 AM
dblaikie added inline comments.Jun 6 2022, 4:47 PM
llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp
1080–1081

I think this FIXME is correct, and we should probably just check if the type matches or not. Happy for that to go into this change rather than being a separate one - and if someone figures out some needle-threading nuance where the types might mismatch but still be call-compatible, they can add that back in later.

llvm/test/Transforms/DeadArgElim/2010-04-30-DbgInfo.ll
4–6

Generally we don't use 'grep' for tests in LLVM (very old pre-FileCheck tests use this sometimes, but we try to avoid doing it in new tests)

Please update these to use FileCheck (& you can probably leave the RUN line as-is, I think - without needing to introduce the %t and cat usage)

RamNalamothu retitled this revision from [llvm][DeadArgumentElimination] Add DW_CC_nocall to function metadata when all return values are removed to [llvm] Add DW_CC_nocall to function debug metadata when either return values or arguments are removed.
RamNalamothu edited the summary of this revision. (Show Details)

Address review feedback.

RamNalamothu marked 2 inline comments as done.Jun 7 2022, 1:16 AM
RamNalamothu added inline comments.
llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp
1080–1081

Done.

llvm/test/Transforms/DeadArgElim/2010-04-30-DbgInfo.ll
4–6

Fixed.

I didn't knew about that. Thanks for sharing it with me.

dblaikie added inline comments.Jun 7 2022, 10:57 AM
llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp
1083

What happens if there are two subprograms using the same type? Do they both end up getting their CC changed? Maybe this code needs to get the type, duplicate it, then set it?

RamNalamothu marked 2 inline comments as done.

Address feedback.

RamNalamothu marked an inline comment as done.Jun 12 2022, 12:40 AM
RamNalamothu added inline comments.
llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp
1083

Ah, yes.

Fixed that. Thank you.

RamNalamothu marked an inline comment as done.

Removed llvm/IR/Metadata.h header inclusion.

dblaikie added inline comments.Jun 13 2022, 2:20 PM
llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp
1085–1088

Writing a loop to do this seems unfortunate when it should always be a known operand number - perhaps there's some nicer way to do this? (while keeping it maintainable/not hardcoding an operand number in this code)

Are there other examples of field updates we could draw inspiration from?

RamNalamothu added inline comments.Jun 13 2022, 6:52 PM
llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp
1085–1088

I couldn't figure out any other simpler way to do this.

I don't think the operand numbers are fixed/known (e.g. see llvm/test/DebugInfo/Generic/array.ll and llvm/test/DebugInfo/Generic/enum.ll).

And in all the code browsing I did, I haven't seen any other examples that could help with this. Please correct me if I missed something.

RamNalamothu added inline comments.Jun 13 2022, 9:30 PM
llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp
1085–1088

I don't think the operand numbers are fixed/known (e.g. see llvm/test/DebugInfo/Generic/array.ll and llvm/test/DebugInfo/Generic/enum.ll).

I mean, looking at DISubprogram node in those LIT tests convey that the type operand can be anywhere and not at a fixed position.

scott.linder added inline comments.Jun 14 2022, 10:16 AM
llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp
1085–1088

Can you define a new method DISubprogram::replaceType(DIType *T) { replaceOperandWith(4, T); } and use that? There is already e.g. void DISubprogram::replaceUnit(DICompileUnit *CU) { replaceOperandWith(5, CU); }

With either implementation, are we only ever mutating non-uniqued DISubprogram nodes? I believe DISubprogram nodes for declarations may be uniqued, but it seems like this pass can only be making changes when the definition is available, so we are safe?

Address feedback.

RamNalamothu marked 2 inline comments as done.Jun 14 2022, 1:10 PM
RamNalamothu added inline comments.
llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp
1085–1088

Thanks @scott.linder for the suggestion. Not sure how I missed this.

Yes, the DAE works only on the definitions and I have added an assert(isDistinct()) to the new method as well.

dblaikie accepted this revision.Jun 14 2022, 1:48 PM

Sounds good, thanks!

This revision is now accepted and ready to land.Jun 14 2022, 1:48 PM
This revision was landed with ongoing or failed builds.Jun 14 2022, 3:00 PM
This revision was automatically updated to reflect the committed changes.
RamNalamothu marked an inline comment as done.