https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116620
Bug ID: 116620 Summary: Feature request: type attribute to control storage size of pointers Product: gcc Version: 15.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: stephane at syena dot net Target Milestone: --- I'm working specifically with aarch64 but I think this could benefit other targets. It is a known fact that having 64 bits pointer is a waste of bits on this architecture and I found several suggestions to try and use 32 bits pointers instead in past reports. One problem of the proposed approaches was that they would likely break ABI and Kernel / lib interfaces, which was probably bringing more pain than benefits. The burden of 64 bits pointer mostly impacts storage (which in turn can manifest performance impacts since cache lines are less efficiently used). I am also seeing storage size savings as a way to reduce translation tables depth by working with a smaller virtual space (again, potential performances gain and also lower VM management complexity). My proposition lies in defining a data attribute that controls the storage size of pointers. This attribute would be applicable to both data symbols (global variables) and fields of complex types (struct, unions). I expect (but I may be wrong) that impacts would be limited to the generation of load / store instructions so that the stored 32 bits value is extended as a 64 bit one in the processor register. Since the attribute would only be applied on data/structures that are declared with it, control lies fully in the hand of the designer of this structures, which I expect to be the designer of the relevant kernel API, lib API, application interface. possible attribute syntax: void *ptr __attribute((uptr32)); // stored as an unsigned 32 bit value. void *ptr __attribute((sptr32)); // stored as a signed 32 bit value. void *ptr __attribute((storeas(32,unsigned))) void *ptr __attribute((storeas(32,signed))) uptr32 can cover addresses in the 4GB lower range. sptr32 can cover addressed in the 2GB lower range as well as in the upper 2GB range (using sign overflow). aarch64 have specific virtual spaces from 0 to 2ˆN and 2^(64-M) to 2^64, where N and M are configurable parameters of the MMU, so this signed form has its use (it is actually the one I'm invested in the most). I am currently using casts to turn 32-bit scalars I use for storage into pointers but there are several downsides to this: - My code looks slightly less clear. - My pointers are no longer understood as such in debug because DWARF info has them as scalars... until the point I cast them in the code. - The generated code looks like it could lose a few instructions (eg when using the signed 32 bit version, I see loadw (load 32 bit) instructions, followed by stxw (sign extend from 32 to 64) ones upon cast. With my data declared as pointer with a 32 bit storage, I would expect to see loadsw (load of 32 bit with sign extension to 64). The concept could be extended to 16 bits pointers or any other size if it make sense for target architectures, but the space gain may be less tangible.