diff options
author | Job Noorman <jnoorman@igalia.com> | 2023-05-17 11:24:48 +0200 |
---|---|---|
committer | Job Noorman <jnoorman@igalia.com> | 2023-05-17 11:35:19 +0200 |
commit | 310473c536dd4837934832d1b5454d212f15d5cc (patch) | |
tree | 9924936dddf7b9d1e029f193634673d3aa196c67 /llvm/lib/Support/Error.cpp | |
parent | 348d0a6bf66be8816c26a387c0a023225afe6e34 (diff) | |
download | llvm-310473c536dd4837934832d1b5454d212f15d5cc.zip llvm-310473c536dd4837934832d1b5454d212f15d5cc.tar.gz llvm-310473c536dd4837934832d1b5454d212f15d5cc.tar.bz2 |
[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
Diffstat (limited to 'llvm/lib/Support/Error.cpp')
0 files changed, 0 insertions, 0 deletions