Re: [arm-gnu] -funit-at-a-time
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [arm-gnu] -funit-at-a-time



IMHO:

On Tuesday 30 August 2005 10:36, Mark Mitchell wrote:
> Bryce Schober wrote:
> > I just realized that in our compiler upgrade from 3.3.0 to 4.0.1 (yes,
> > I realize that this is a huge jump...), -O2 is breaking us. We were
> > depending on the emitted order of const (non-)variables destined for
> > our flash image. I now realize that this is something we probably
> > shouldn't have been depending on to start with, but it seems that it
> > would be a fairly common requirement for deeply embedded work. I see
> > that the manual says "As a temporary workaround, -fno-unit-at-a-time
> > can be used, but this scheme may not be supported by future releases
> > of GCC." Should I be worried about using this workaround in the long
> > term? What other method would I use to determine the emitted order of
> > consts?

Can you explain a bit better, or point me towards a url that better describes 
the problem.

Is it just that the ordering of variables being emitted is not in declaration 
sequence? That would be a dangerous thing to assume, IMHO. All your 
assumptions should be in accordance with the C spec.

It sounds a bit like a similar problem I had when I needed to control 
placement of a flash header that looked like:

const unsigned image_length;
const unsigned start_address;
... check sums etc.


IMHO the correct way to do this is one of:

1) Use an ld script to place things as you need them. You can use 
-fdata-sections to get individual sections for better placement granularity.

2) Use a structure for anything that is order dependent. To do otherwise is 
dangerous.

3) Pull out special tables etc (eg. flash image headers) and put them in 
assembler files where you have a lot more control over what is going on. Then 
use a custom ld section to place this.

I opted finally for the last one because it did what I wanted predictably and 
I know that it will work with any compiler changes down the track.

>
> You're right to worry.  For example, in C++, -fno-unit-at-a-time is no
> longer supported, and you will always get the re-ordering behavior.
> We're also working on projects that may result in reordering globals to
> get better cache behavior.
>
> There are two tricks you could use.
>
> One trick is to put everything into a structure, like:
>
>    struct globals {
>      int i;
>      int j;
>    };
>
>    static globals g;
>
> Then, use "g.i" instead of "i".  The compiler will keep the structure
> together.  The other is to explicitly place the variables in particular
> sections (using the attribute((section("...")) syntax) and then user a
> linker script to control the section order.

IMHO anyhing that requires pragmas or special C code syntax including 
attributes and __irq__ etc is broken. Most embedded code needs to be 
compilable with many compilers (eg. when you reuse code, or compile it in a 
test bed using a different environment), so anything that is not portable 
gets very ugly very quickly.

>
> Neither of these work with constants that are emitted by the compiler,
> like when you write:
>
>    const char *s = "A string";
>    const float f = 5.0f;
>
> There's no way to control placement of those constants.
>
> GCC should probably be augmented with an explicit placement directive of
> some kind, or a pragma to disable reordering around a block of
> variables.  We do add features like this for our customers when their
> needs are sufficiently general-purpose.

Added features could work, so long as this does not lead to forking which does 
nobody any good. However adding features then adds more testing etc down the 
road.