-
Notifications
You must be signed in to change notification settings - Fork 165
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 gp could be platform specific register rather than reserved for… #371
Conversation
LGTM. Thanks for proposing this. For reference: More discussion around this has been going on in: https://lists.riscv.org/g/sig-toolchains/topic/97736679#548 and #370 |
Different platforms might want to use the "platform register" for different purposes, no? If so, just defining |
@rui314 good point, I add 2 range for standard and non-stanadrd use used range, and also one for undefined one. |
I'm not sure what the undefined purpose is. Maybe we just want to reserve 2-1024 for the standard uses and 1025-2047 for nonstandard uses? |
My first thought about that undefined purpose is kind of reserved for nonstandard use, but we already defined one range for nonstandard, so yeah, that should be just 2-1024 for the standard uses and 1025-2047 for nonstandard uses |
We discussed this in the SIG Toolchain call today and agreed that this is the right solution for a RISC-V platform register as it represents the solution with the least expected ABI compatibility hassles. |
riscv-elf.adoc
Outdated
global pointer relaxation, reserved platform register or a temporary register. | ||
|
||
[horizontal] | ||
0:: This object use gp as global pointer relaxation. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What value is defined for unused gp?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even if gp is unused, is it safe to assume that gp is used for global pointer relaxation? As this has been the default behavior.
Can there be cases where gp is allowed for global pointer relaxation and no such opportunities were found in the binary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can there be cases where gp is allowed for global pointer relaxation and no such opportunities were found in the binary?
In theory we can made one program with a symbol with huge size (large then 4k) and point __global_pointer$
to the middle of the symbol, then the global pointer relaxation will have no way to relax anything, but that case should not happened in generally since __global_pointer$
is default computed by a magic (or heuristic) expression with some arithmetic with sbss/sdata.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What value is defined for unused gp?
I guess you are intend to tag the linker output as that if gp relaxation disabled? so that we can know this object has perform gp relaxation or not?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even if gp is unused, is it safe to assume that gp is used for global pointer relaxation?
It seems not. Operating system may not initialize GP with __global_pointer
and leave it with zero or some undefined value. Haiku for example do not define or use __global_pointer
because it do not distinguish executables and shared libraries.
Changes:
NOTE: GP as SCS will defined in separated PR. |
Honestly I don't feel good to add If this patch simply states that gp is platform specific, this patch will look good to me. |
IMO that could be used to sanity check and identity some information how this object/executable compiled, otherwise the only way is writing some magic script/tools to check that like google/android-riscv64#77 mentioned, a binary validator...
There is many C++ dialect, one recent happened example is relative vtables ABI for C++, I didn't ask to add a tag to identify that is because it's still Anyway, my point is we should track/record those information if possible, adding attributes could help tool to having better diagnosis message instead of silently broken, otherwise people don't have too much clue to tracking what happened when screw up things. |
When a source file uses inline assembly to initialize gp, it is impossible to determine how the user intends to use gp, unless the code adds a metadata section manually. For global pointer relaxation, the use case is resolved in the final link phase. It is not necessary, and should not be required, to use a driver option to prevent the compiler from creating an attribute or not indicating GP relaxation. While a compatibility-detecting feature may be useful, I am skeptical about its necessity and may lean toward not implementing it at all. If such a feature is deemed necessary, it can be proposed separately. In my experience, adding compatibility-detecting features in binutils/glibc leads to inconvenience for several other ports, so waiting before implementing such a feature may be valuable. As for the specific issue of global pointer relaxation, it could be included in a RISC-V Linux ABI, but I prefer that global pointer relaxation remains as the current GNU ld convention (in other words, it can be default to NOT do this in the future). glibc and musl initialize gp very early. This is compatible with application using gp for another purpose with |
For Android and Fuchsia, their decisions don't conflict with Linux ABI and they are less confined by Linux ABI decisions. They control the whole platform, the toolchain and every software piece. Regular Linux distributions have a more loose model and compatibility is likely more important. If we did something inconvenient, it would be difficult to drop all the stuff. I think there is a practical lesson to learn from AArch64 that they postpone (don't do) the AArch32 attributes thing. |
@MaskRay Thanks for sharing your thought , split |
@asb @luismarques although @rui314 you are linker expert, and I would like all linker expert is happy with this change. @Nelson1225 I need your opinion as binutils expert :) @jrtc27 FreeBSD didn't use gp relaxation, so I guess you are fine with this change, but I would like you give explicitly LGTM to this one if possible :) |
FreeBSD supports gp relaxation if you use BFD, it just uses LLD by default and so disables it in Clang (but should maybe reenable it now it's on LLD 15). |
I think although platforms can of course deviate from the standard ABI however they wish, having a suggested register for platform specific purposes makes sense. GP is convenient for this purpose and there seem to be no strong concerns about it, so all LGTM. I think you need to update the commit message so it no longer claims to introduce a new tag (as this was dropped for now I believe). |
I've left a suggested wording change for the actual patch part of this (inspired partially by #374). I don't think we should equate gp just with gp relaxation, as it might e.g. be used in hand-written assembly. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I disagree with the premise of this PR. A platform might choose to designate any register as used for an alternate purpose. No matter which register is chosen, it affects the ABI somehow.
Which is why we're constraining it so it's not a free-for-all. Otherwise you end up in a situation where something like OpenSSL needs a different copy of its crypto assembly routines for each platform because it needs to avoid each platform's reserved register. The whole point of a specification like a psABI is to impose order on the chaos so everyone agrees on what is going on; if you want to allow any register to be reserved by any platform and remain standards-compliant then why bother having an ABI at all? |
@jrtc27 indeed I perceive the intent to reserve |
This is not constructive, nor is it factually accurate. Please take this rhetoric elsewhere; it has no place in the RISC-V community. |
Hi Andrew. I don't really have a dog in this fight, but I personally think there is at least some value in giving a hint to people defining platform ABIs which register might be appropriate to use if they need one for their purposes. The fact other ABIs like AArch64 include such a recommendation perhaps provides some support for this point of view. Before further discussing which register to specify, I wanted to check if you disagree that's there's any value at all in giving such a hint? As to which register to specify - it's not a conversation I've personally been involved in, but all parties so far seem happy that for their use cases, repurposing gp wouldn't be a significant loss. I think its unfortunate if this discussion has become caught up in other suggestions about removing or deprecating gp linker relaxation on standard platforms like Linux, because I think that's a completely completely separate debate (and one I won't comment on because I haven't done the necessary research). Just to make sure I understand your concern properly - is it that choosing gp for this platform specific register might be seized upon to force a decision in a particular direction in any future debate about gp relaxations? |
Of course, I agree there's value in doing so.
That was precisely my point, although I failed to articulate it politely. |
It's probably a good thing to discuss this concern explicitly though I think. So for my part, my LGTM on this specific change is not indicative of any point of view on the best use of GP in the standard ABI as already implemented. I suspect there will be recurrent discussions about it because if you want to scavenge a register for another purpose, GP is going to be near the top of the list. But I see this PR as separate to any such discussion. |
AIUI, the range of gp is small (+/- 2kb) and probably that's why we haven't seen compiler optimizations leveraging that. To the best of my knowledge, none of the Android libraries use gp. If you have ideas on how gp can help in platforms like Android, it will be good to share such that we can realize the trade-offs being made here. OTOH, re-purposing gp for SCS essentially frees one register for general usage. This can have measurable performance improvements among large variety of workloads, specially when RISC isa is pretty reduced and register pressure is going to be an issue. |
GP relaxation is only usable by executables, not libraries, since it takes a constant value throughout execution and thus libraries would compete for its use (though I guess there's an interesting question of whether one could designate a specific library as being the One True GP User, like libc). If I remember correctly, someone from Google in the call on Monday (Elliott?) said that ~everything is a library on Android, which would explain why GP relaxation is not of much use to them? (Though perhaps something like ART could then be blessed as the One True GP User...) |
@aswaterman I'm not sure where you stand on this change, given that you've approved it now, but your comments seem to conflict with that sentiment. Can you provide some clarification on your stance and any lingering concerns? |
Although I remain concerned that this choice might be speciously used as a pretext to stop using gp relaxations in existing ABIs, I agree with @asb that this PR can go through without addressing that matter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM the intent of the patch. As I mentioned in the review, it will be nice to have some explanation on the a) use case b) requirements on the toolchain, and c) risks of using gp for platform-specific purpose without a tag.
@aswaterman I guess I might give you impression that I am not support GP relaxation in #298, but I believe you know that I did know the value of GP relaxation in specific areas, especially on the small bare-metal system, and it also gives us some extra spec score, so I am not intending to deprecate the GP relaxation. For the SCS, the ideal case is using Zisslpcfi extension, but that would be an issue since it’s not ready now, and also it still require several psABI works (not only SCS, but also landing pad stuffs), so we need to figure out a way to make it moving forward, and GP is the relative best candidate so far. And of course that’s kind of a mistake that we didn’t learn from other platforms - we didn’t reserve a platform register at the beginning, picking any other general purpose register as platform register would be more painful at this moment. Anyway, I have worked in the RISC-V world for so many years with you, I also want RISC-V to grow up :) |
… linker relaxation The usage of gp register has discussed serveral times (e.g. #298), and it reserved as special register used for linker relaxation, that could be improve perfomance and code size. However it come with some limitation, like it can't applicable on shared libraries, and it also not work well when program come with large datas since the relaxable range is only +-2KiB. Some platform like FreeBSD and Haiku never use gp in the whole system, and also this might not useful in some baremetal system with specialized memory layout, so we might consider to release the gp usage with a non-hard-ABI-breakage way. Co-authored-by: Alex Bradbury <[email protected]>
Changes:
|
Thanks everyone, It seems we have converged on this topic, I would like to wait few more day to make sure no further comment before merge :) |
PowerPC ABI have similar concept to GP register (TOC register R2) that also works in shared libraries by using special library calling convention with switching TOC register to address of called shared library and switch back on return.
The same for Haiku. Executables and shared libraries are the same except NULL entry point is allowed for shared libraries, but not for executables. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the update. The new wording looks good to me.
…R_RISCV_LO12_S. This implements support for relaxing these relocations to use the GP register to compute addresses of globals in the .sdata and .sbss sections. This feature is off by default and must be enabled by passing --relax-gp to the linker. The GP register might not always be the "global pointer". It can be used for other purposes. See discussion here riscv-non-isa/riscv-elf-psabi-doc#371 Reviewed By: MaskRay Differential Revision: https://reviews.llvm.org/D143673
@X547 thanks for provide this info, that's interesting idea we could consider in embedded ABI I think. |
Thanks everyone again :) |
@X547 I don't think PowerPC64 ELFv2 TOC is a good design:) (I have many lld patches in this area) See my summary of TOC on https://maskray.me/blog/2023-02-26-linker-notes-on-power-isa
Then we'd also need thunks when the caller and the callee may change GP. |
Can be relaxed, no? |
It can, but I am unsure about the linker complexity. Their mere existence makes a tail call no longer a tail cal. I have summarized all sorts of maintenance costs on https://maskray.me/blog/2023-02-26-linker-notes-on-power-isa |
…R_RISCV_LO12_S. This implements support for relaxing these relocations to use the GP register to compute addresses of globals in the .sdata and .sbss sections. This feature is off by default and must be enabled by passing --relax-gp to the linker. The GP register might not always be the "global pointer". It can be used for other purposes. See discussion here riscv-non-isa/riscv-elf-psabi-doc#371 Reviewed By: MaskRay Differential Revision: https://reviews.llvm.org/D143673
#387 for adding new tag for recording gp usage |
…R_RISCV_LO12_S. This implements support for relaxing these relocations to use the GP register to compute addresses of globals in the .sdata and .sbss sections. This feature is off by default and must be enabled by passing --relax-gp to the linker. The GP register might not always be the "global pointer". It can be used for other purposes. See discussion here riscv-non-isa/riscv-elf-psabi-doc#371 Reviewed By: MaskRay Differential Revision: https://reviews.llvm.org/D143673
… linker relaxation
The usage of gp register has discussed serveral times (e.g. #298 and #305), and it reserved as special register used for linker relaxation, that could be improve perfomance and code size.
However it come with some limitation, like it can't applicable on shared libraries, and it also not work well when program come with large datas since the relaxable range is only +-2KiB.
Some platform like Haiku never use gp in the whole system, and also this might not useful in some baremetal system with specialized memory layout, so we might consider to release the gp usage with a non-hard-ABI-breakage way.