[all-commits] [llvm/llvm-project] 348d0a: [JITLink] Add target features to LinkGraph

Job Noorman via All-commits all-commits at lists.llvm.org
Wed May 17 02:35:45 PDT 2023


  Branch: refs/heads/main
  Home:   https://github.com/llvm/llvm-project
  Commit: 348d0a6bf66be8816c26a387c0a023225afe6e34
      https://github.com/llvm/llvm-project/commit/348d0a6bf66be8816c26a387c0a023225afe6e34
  Author: Job Noorman <jnoorman at igalia.com>
  Date:   2023-05-17 (Wed, 17 May 2023)

  Changed paths:
    M llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h
    M llvm/lib/ExecutionEngine/JITLink/CMakeLists.txt
    M llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.cpp
    M llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.h
    M llvm/lib/ExecutionEngine/JITLink/COFF_x86_64.cpp
    M llvm/lib/ExecutionEngine/JITLink/ELFLinkGraphBuilder.h
    M llvm/lib/ExecutionEngine/JITLink/ELF_aarch32.cpp
    M llvm/lib/ExecutionEngine/JITLink/ELF_aarch64.cpp
    M llvm/lib/ExecutionEngine/JITLink/ELF_i386.cpp
    M llvm/lib/ExecutionEngine/JITLink/ELF_loongarch.cpp
    M llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp
    M llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp
    M llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.cpp
    M llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.h
    M llvm/lib/ExecutionEngine/JITLink/MachO_arm64.cpp
    M llvm/lib/ExecutionEngine/JITLink/MachO_x86_64.cpp

  Log Message:
  -----------
  [JITLink] Add target features to LinkGraph

This patch adds SubtargetFeatures to LinkGraph. Similar to Triple, some
targets might use this information while linking.

One example, and the reason this patch was written, is linker relaxation
on RISC-V: different relaxations are possible depending on if the C
extension is enabled.

Note that the features are stored as `std::vector<std::string>` to prevent a
public dependency on MC. There is still a private dependency to be able to
convert SubtargetFeatures to a vector.

Reviewed By: lhames

Differential Revision: https://reviews.llvm.org/D149522


  Commit: 310473c536dd4837934832d1b5454d212f15d5cc
      https://github.com/llvm/llvm-project/commit/310473c536dd4837934832d1b5454d212f15d5cc
  Author: Job Noorman <jnoorman at igalia.com>
  Date:   2023-05-17 (Wed, 17 May 2023)

  Changed paths:
    M llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h
    M llvm/include/llvm/ExecutionEngine/JITLink/riscv.h
    M llvm/lib/ExecutionEngine/JITLink/ELF_riscv.cpp
    M llvm/lib/ExecutionEngine/JITLink/riscv.cpp
    A llvm/test/ExecutionEngine/JITLink/RISCV/ELF_relax_align.s
    A llvm/test/ExecutionEngine/JITLink/RISCV/ELF_relax_align_rvc.s
    A llvm/test/ExecutionEngine/JITLink/RISCV/ELF_relax_call.s
    A llvm/test/ExecutionEngine/JITLink/RISCV/ELF_relax_call_boundary.s
    A llvm/test/ExecutionEngine/JITLink/RISCV/ELF_relax_call_rvc.s

  Log Message:
  -----------
  [JITLink][RISCV] Implement linker relaxation

This patch is essentially an adaption of LLD's algorithm to JITLink.
Currently, only relaxing R_RISCV_CALL(_PLT) and R_RISCV_ALIGN is
implemented, other relocations can follow later.

>From a high level, the algorithm works as follows. In the first phase
(relaxBlock), we iteratively try to relax all instructions that have a
R_RISCV_RELAX relocation:
- If, based on the current symbol values, an instruction sequence can be
  relaxed (i.e., replaced by a shorter instruction), we record how many
  bytes would be removed, the new instruction (Writes), and the new
  relocation type (EdgeKinds).
- We keep track of the total number of bytes that got removed up to each
  relocation in the RelocDeltas array. This is the cumulative sum of the
  number of bytes removed for each relocation.
- Symbol values and sizes are updated based on the number of removed
  bytes.
- If for any relocation, the current RelocDeltas value doesn't match the
  one from the previous iteration, something changed and we need to run
  another iteration as some symbols might now have different values.

In the second phase (finalizeBlockRelax), all code is moved based on
RelocDeltas, the relaxed instructions are rewritten using Writes, and
R_RISCV_ALIGN is handled (moving instructions to ensure alignment and
inserting the correct NOP-sequence if needed). Finally, edge kinds and
offsets are updated and all R_RISCV_RELAX and R_RISCV_ALIGN edges are
removed (they are not needed anymore for the fixup linking stage).

Linker relaxation is implemented as a pass and added to PreFixupPasses
in the default configuration on RISC-V.

Since linker relaxation removes instructions, the memory for blocks
should ideally be reallocated. However, I believe this is currently not
possible in JITLink. Therefore, relaxation directly modifies the memory
of blocks, reducing the number of instructions but not the size of
blocks. I'm not very familiar with JITLink's memory allocators so I
might be overlooking something here, though.

Note on testing: some of the tests rely on the debug output of
llvm-jitlink. The main reason for this is the verification of symbol
sizes (which may change due to relaxation). I don't believe this can be
done using jitlink-check checks alone.

Note that there is a slightly unrelated change that makes
Symbol::setOffset public to be able to update symbol offsets during
relaxation.

Reviewed By: lhames

Differential Revision: https://reviews.llvm.org/D149526


  Commit: d045f1d393317962251ba6dc58e3f8edc7e2fd99
      https://github.com/llvm/llvm-project/commit/d045f1d393317962251ba6dc58e3f8edc7e2fd99
  Author: Job Noorman <jnoorman at igalia.com>
  Date:   2023-05-17 (Wed, 17 May 2023)

  Changed paths:
    M llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
    M llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
    M llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h
    M llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
    M llvm/test/MC/RISCV/fixups-invalid.s
    M llvm/test/MC/RISCV/rv32i-aliases-valid.s
    M llvm/test/MC/RISCV/rv64i-aliases-valid.s

  Log Message:
  -----------
  [RISCV] Allow LI with symbol difference as constant

This patch lets the assembler accept code like the following:

.Lbuf: ...
.set .Lbuf_len, . - .Lbuf
li a0, .Lbuf_len

It works by translating such instances of LI into an ADDI and inserting
the correct constant value via a new fixup.

Note that this means that the constant value is restricted to 12 bits
since we cannot insert new instructions during the relaxation stage.
Binutils seems to have the same restriction though.

This patch also fixes a small issue where the SMLoc of an LI wasn't
propagated when translated to ADDI. While this is technically unrelated
to the main functionality of this patch, it improves error messages
related to the new use of LI.

This patch does _not_ allow I-type instructions to take such symbolic
constants as well. While technically possible (and allowed by binutils),
it's probably better to implement this in another patch.

Fixes #57461

Reviewed By: asb

Differential Revision: https://reviews.llvm.org/D135960


Compare: https://github.com/llvm/llvm-project/compare/080ee850c639...d045f1d39331


More information about the All-commits mailing list