Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Relax GOT indirection into PC-relative addressing #397

Merged
merged 1 commit into from
Dec 10, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions riscv-elf.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -1573,6 +1573,80 @@ optimize code size and performance of the symbol accessing.

NOTE: Tag_RISCV_x3_reg_usage is treated as 0 if it is not present.

==== GOT load relaxation

Target Relocation:: R_RISCV_GOT_HI20, R_RISCV_PCREL_LO12_I

Description:: This relaxation can relax a GOT indirection into load
immediate or PC-relative addressing. This relaxation is intended to
optimize the `lga` assembly pseudo-instruction (and thus `la` for
PIC objects), which loads a symbol's address from a GOT entry with
an `auipc` + `l[w|d]` instruction pair.

Condition::
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The language in here needs tweaking to more obviously cover the case when a single GOT_HI20 is shared by multiple PCREL_LO12_I

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we want to handle such case. This optimization is to relax la and not others. It looks like a GOT_HI20 is almost always paired with a PCREL_LO_I that immediately follows, so this should be sufficient.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LLVM does not model them as a pair, it models them as independent instructions. In practice you will put them together to benefit from macro-op fusion, but there's no requirement to do so in the ABI or in LLVM's internals, so the ABI should not start to introduce arbitrary restrictions that have no technical grounding other than being marginally more annoying to write a specification for. Please specify the actual necessary restrictions.

- Both `R_RISCV_GOT_HI20` and `R_RISCV_PCREL_LO12_I` are marked with
`R_RISCV_RELAX`.

- The symbol pointed to by `R_RISCV_PCREL_LO12_I` is at the location to
which `R_RISCV_GOT_HI20` refers.

- If the symbol is absolute, its address is within `0x0` ~ `0x7ff` or
`0xfffffffffffff800` ~ `0xffffffffffffffff` for RV64 and
`0xfffff800` ~ `0xffffffff` for RV32.
Note that an undefined weak symbol satisfies this condition because
such a symbol is handled as if it were an absolute symbol at address 0.

- If the symbol is relative, it's bound at link time to be within the
object. It should not be of the GNU ifunc type. Additionally, the offset
between the location to which `R_RISCV_GOT_HI20` refers and the target
symbol should be within a range of +-2GiB.

Relaxation::
- The `auipc` instruction associated with `R_RISCV_GOT_HI20` can be
removed if the symbol is absolute.

- The instruction or instructions associated with `R_RISCV_PCREL_LO12_I`
can be rewritten to either `c.li` or `addi` to materialize the symbol's
address directly in a register.

- If this relaxation eliminates all references to the symbol's GOT slot,
the linker may opt not to create a GOT slot for that symbol.

Example::
+
--
Relaxation candidate:
[,asm]
----
label:
auipc tX, 0 # R_RISCV_GOT_HI20 (symbol), R_RISCV_RELAX
l[w|d] tY, 0(tX) # R_RISCV_PCREL_LO12_I (label), R_RISCV_RELAX
----

Relaxation result (absolute symbol whose address can be represented as
a 6-bit signed integer and if the RVC instruction is permitted):

[,asm]
----
c.li tY, <symbol-value>
----

Relaxation result (absolute symbol and did not meet the above condition
to use `c.li`):

[,asm]
----
addi tY, zero, <symbol-value>
----

Relaxation result (relative symbol):
[,asm]
----
auipc tX, <hi>
addi tY, tX, <lo>
----
--

==== Zero-page Relaxation

Target Relocation:: R_RISCV_HI20, R_RISCV_LO12_I, R_RISCV_LO12_S
Expand Down
Loading