Is there a GCC keyword to allow structure-reordering?
Asked Answered
D

4

28

I know why GCC doesn't re-order members of a structure by default, but I seldom write code that relies on the order of the structure, so is there some way I can flag my structures to be automaticly reordered?

Deckle answered 3/2, 2013 at 9:52 Comment(9)
Why would you want your struct members to be reordered?Earlineearls
@H2CO3 Because I'm on a tight-memory system, and I always have to do calculations by hand to make sure the least amount of padding is used.Deckle
Oh, I see. Interesting enough (+1).Earlineearls
What is about using of union for this purpose?Poyssick
@Joshua Does your architecture allow unaligned memory access ?Cormorant
@duDE: a union and a struct are rather different things.Bookbindery
@Cormorant I believe so, but turning them into packed structures is not the answer, because it will just remove the padding, but does not re-order for optimal memory-aligned. I want what I do manually: memory-aligned with the least amount of padding.Deckle
@Joshua Oh I see. You want to have the cake and eat it. Perhaps you could preprocess (flex ?) your files and rearrange the members.Cormorant
Assuming your platform uses ELF, you can use pahole from dwarves to find structures that may be reordered, and also automatically repack these.Corniculate
F
22

Previous GCC versions have the -fipa-struct-reorg option to allow structure reordering in -fwhole-program + -combine mode.

  • -fipa-struct-reorg

    Perform structure reorganization optimization, that change C-like structures layout in order to better utilize spatial locality. This transformation is affective for programs containing arrays of structures. Available in two compilation modes: profile-based (enabled with -fprofile-generate) or static (which uses built-in heuristics). Require -fipa-type-escape to provide the safety of this transformation. It works only in whole program mode, so it requires -fwhole-program and -combine to be enabled. Structures considered 'cold' by this transformation are not affected (see --param struct-reorg-cold-struct-ratio=value).

It was removed since GCC 4.8.x due to the below reasons in the release note

The struct reorg and matrix reorg optimizations (command-line options -fipa-struct-reorg and -fipa-matrix-reorg) have been removed. They did not always work correctly, nor did they work with link-time optimization (LTO), hence were only applicable to programs consisting of a single translation unit.

However you can still try the struct-reorg-branch on GCC SVN or the github mirror out on your own risk as it's still in active development.

You can also reorder the fields with the clang-reorder-fields tool in clang-tools-extra

See also

Futch answered 28/2, 2015 at 9:42 Comment(0)
B
5

As a side note, the Linux kernel implements a gcc plugin to introduce an attribute named randomize_layout. The goal is to use it in the definition of the structures to make the compiler randomize the order of the fields. Linux kernel uses it for the sake of security to counter attacks that need to know the layout of structures. For example the cred structure is defined as follow in include/linux/cred.h:

struct cred {
    atomic_t    usage;
#ifdef CONFIG_DEBUG_CREDENTIALS
    atomic_t    subscribers;    /* number of processes subscribed */
    void        *put_addr;
[...]
    struct user_struct *user;   /* real user ID subscription */
    struct user_namespace *user_ns; /* user_ns the caps and keyrings are relative to. */
    struct group_info *group_info;  /* supplementary groups for euid/fsgid */
    /* RCU deletion */
    union {
        int non_rcu;            /* Can we skip RCU deletion? */
        struct rcu_head rcu;        /* RCU deletion hook */
    };
} __randomize_layout;

The __randomize_layout tag is defined in include/linux/compiler-gcc.h of the Linux source tree as:

#define __randomize_layout __attribute__((randomize_layout))
Basso answered 14/11, 2020 at 20:47 Comment(2)
First URL to the GCC plugin is brokenIntrauterine
Thank you for the comment. Link updated.Basso
T
2

There is no such option in GCC. And, I sure, it can not be introduced in any sensible fashion. About padding optimizations please look at this discussion.

The only exception I know is hot/cold structure fields splitting, that can be done in some cases (still I am not sure, that GCC can do it even in profile-guided mode, I know ICC can). This feature is not under user control and is performed on call-graphs where conservativeness of such transformation over data-flow is provable.

Thieve answered 3/2, 2013 at 10:5 Comment(5)
Why could it not be introduced? If I specify the __packed attribute, I'm telling GCC to threat the structure differently, so what would be wrong with a __reorder attribute? But it seems my question is a duplicate of the question you linked.Deckle
@Joshua From memory the C standard specifies that struct members must be ordered in memory the same as the order in definition. Using the packed attribute preserves ordering. A reorder attribute would not. I realise this is not a discussion about standard compliance though.Teahan
I think reason why it could not be introduced is deeper, then just standard compliance. At least we do not care much about packed structures, nested functions, etc. But packed is up to user. Reorder lefts it up to compiler how to reorder and whether reorder or not. So, being introduced, it will require on possible reordering of fields, accurate points-to analysis to reorder all references as well, and references to references, and so on. This will probably multiply time of compilation several times.Thieve
@KonstantinVladimirov It's not only the standard compliance. C and C++ programs are routinely built from a number of different source files and libraries. You cannot change the order or packing once the library has been compiled. And you don't want to have differently ordered members in the same structure in different modules.Augite
the "hot/cold structure fields splitting" technique is really interesting :)Futch
S
1

I think it is possible to reorganize/split elements of struct when you are compiling the whole program (lto mode, use -flto flag). In that case you have complete picture of the program, and for the symbols which do not escape it should be possible to reorder them for better cache behavior etc.

In the gcc trunk this is under active development. This was presented in GNU cauldron 2015. You might want to try gcc trunk or the struct-reorg-branch.

https://gcc.gnu.org/wiki/cauldron2015?action=AttachFile&do=view&target=Olga+Golovanevsky_+Memory+Layout+Optimizations+of+Structures+and+Objects.pdf

Sardine answered 12/9, 2015 at 4:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.