[RegAllocFast] Fold foldable inline asm operands under register pressure

An inline asm register operand marked foldable (from an "rm" constraint)
may be replaced with a stack slot when the register allocator runs out
of registers. The greedy allocator does that when it spills the value.
The fast allocator can't: it assigns the operands of an instruction one
at a time, and folding replaces the instruction. So it reported
"inline assembly requires more registers than available" instead.

Before allocating a block, estimate from each inline asm's own operands
whether they fit in registers, and fold as many foldable registers as
needed to make them fit, so the common case without pressure still gets
a register. Values that only live across the asm don't count, since the
allocator spills them when it needs their registers. The estimate
follows allocateInstruction():

- First all defs get distinct registers, avoiding physreg defs; then all
  uses, along with the defs still occupied while the uses are read
  (early-clobber and tied defs, see isLiveThroughDef()), get distinct
  registers, avoiding physreg uses and early-clobber physreg defs.
- A register counts against another register class as many times as one
  of its registers overlaps that class's registers, so e.g. 32-bit "rm"
  operands compete with 64-bit operands for the same registers.
- A value used by both an "rm" and an "r" operand isn't folded, since
  that frees no register.
- An input tied to a def keeps a register of its own when the allocator
  lowers the tie itself and the input is read later in the block. Kill
  flags are optional, so a missing one doesn't mean the input lives on.

Folding a register folds all of its operands at once, with one store
before the asm and one reload after it. It uses the register's own spill
slot, so that a block that reloads the register, such as an
INLINEASM_BR's indirect target, which the reload after the asm doesn't
reach, finds the value the asm wrote.

The whole thing is skipped for functions without inline asm.

Nothing in tree marks an inline asm register operand foldable yet, so
the tests set the "foldable" flag in MIR.

This follows the shape of the unmerged #74344, "[RegAllocFast] fold
foldable inline asm", with a pressure estimate instead of folding
unconditionally, per the review there.

Assisted-by: Claude Opus 5.5
3 files changed
tree: 6ab4b3e7f02b34c2a094c951d606590cb2c912f5
  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.