[ArgPromotion] Add DW_CC_nocall to DISubprogram (#178973)

ArgumentPromotion pass may change function signatures. If this happens
and debuginfo is enabled, adding DW_CC_nocall allows dwarf to generate
    DW_AT_calling_convention        (DW_CC_nocall)
for DW_TAG_subprogram.
DeadArgumentElimination ([1]) already has similar implementation.

The pahole tool ([2]) is used in linux kernel build to generate vmlinux
BTF. One of its input is linux kernel dwarf. Currently, pahole
checks *all* DW_TAG_subprogram functions and find whether the source
signature matches the architecture ABI or not. If mismatch, pahole will
try to do some adjustment for those parameters. See [3]
and function parameter__new().

The linux kernel typically has ~65K functions and roughly 1100 functions
may have signature changed due to compile optimization. Without
DW_CC_nocall,
signatures of all of 64K functions will be checked in parameter__new().
But with DW_CC_nocall, the number of functions to checked is only 1100,
much smaller.

If DW_CC_nocall is not available, pahole may needs to parse complicated
locations. Even if the signature is not changed, pahole may not be able to
decide that the location matches function signature, and will incorrectly
exclude this function for vmlinux BTF.

So overall, adding DW_CC_nocall in ArgumentPromotion can help pahole
with less build time and more correct function encoding in vmlinux BTF.

With change in ArgumentPromotion.cpp, the test dbg.ll will fail since
the subroutine type is null. The non-null subroutine type is added so
the test can pass.

Without change in ArgumentPromotion.cpp, the dbg.ll will have
  ...
  !3 = distinct !DISubprogram(name: "test", scope: null, file: !2, line: 3, type: !4,
       scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !1)
  !4 = !DISubroutineType(types: !5)
  !5 = !{null, !6}
  ...

With change in Argumentpromotion.cpp, the dbg.ll will have
  ...
  !3 = distinct !DISubprogram(name: "test", scope: null, file: !2, line: 3, type: !4,
       scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !1)
  !4 = !DISubroutineType(cc: DW_CC_nocall, types: !5)
  !5 = !{null, !6}

Eventually, DW_CC_nocall will be encoded in dwarf.

  [1] https://github.com/llvm/llvm-project/commit/340b0ca90095d838f095271aaa1098fa1bd5ecbe
  [2] https://git.kernel.org/pub/scm/devel/pahole/pahole.git
  [3] https://git.kernel.org/pub/scm/devel/pahole/pahole.git/tree/dwarf_loader.c
2 files changed
tree: 5c5c9eec7783d2d42e2168232779ba660395354b
  1. .ci/
  2. .github/
  3. bolt/
  4. clang/
  5. clang-tools-extra/
  6. cmake/
  7. compiler-rt/
  8. cross-project-tests/
  9. flang/
  10. flang-rt/
  11. libc/
  12. libclc/
  13. libcxx/
  14. libcxxabi/
  15. libsycl/
  16. libunwind/
  17. lld/
  18. lldb/
  19. llvm/
  20. llvm-libgcc/
  21. mlir/
  22. offload/
  23. openmp/
  24. orc-rt/
  25. polly/
  26. runtimes/
  27. third-party/
  28. utils/
  29. .clang-format
  30. .clang-format-ignore
  31. .clang-tidy
  32. .git-blame-ignore-revs
  33. .gitattributes
  34. .gitignore
  35. .mailmap
  36. CODE_OF_CONDUCT.md
  37. CONTRIBUTING.md
  38. LICENSE.TXT
  39. pyproject.toml
  40. README.md
  41. SECURITY.md
README.md

The LLVM Compiler Infrastructure

OpenSSF Scorecard OpenSSF Best Practices libc++

Welcome to the LLVM project!

This repository contains the source code for LLVM, a toolkit for the construction of highly optimized compilers, optimizers, and run-time environments.

The LLVM project has multiple components. The core of the project is itself called “LLVM”. This contains all of the tools, libraries, and header files needed to process intermediate representations and convert them into object files. Tools include an assembler, disassembler, bitcode analyzer, and bitcode optimizer.

C-like languages use the Clang frontend. This component compiles C, C++, Objective-C, and Objective-C++ code into LLVM bitcode -- and from there into object files, using LLVM.

Other components include: the libc++ C++ standard library, the LLD linker, and more.

Getting the Source Code and Building LLVM

Consult the Getting Started with LLVM page for information on building and running LLVM.

For information on how to contribute to the LLVM project, please take a look at the Contributing to LLVM guide.

Getting in touch

Join the LLVM Discourse forums, Discord chat, LLVM Office Hours or Regular sync-ups.

The LLVM project has adopted a code of conduct for participants to all modes of communication within the project.