On 2010-06-17, JMGross <[email protected]> wrote:

[I don't suppose you could wrap lines in your posts?]

> Not with the gc-sections feature. But I'm pretty sure it happened
> with object files and not just libraries. (And I'm sure that no
> libraries were linked before the object files, but maybe dependent
> libraries in the wrong order)

I've never heard of that issue occuring with object files, and based
on my understanding of how the linker works, I don't see how it could
happen.

> But it is possible that the setup made a library first from part of
> the object files and then linked it.

It will definitely happen with library files.  When the linker
encounters a library file, it will only pull in from the library the
objects required to resolve any as-yet unresolved symbols.

>>> If these compiler flags allow treating different functions in the
>>> same files to be kept or discarded depending of whether they are
>>> used, it's obvious that they need to be be considered unused when
>>> they haven't been referenced yet.
>
>>The garbage collection algorithm used by the linker shouldn't depend
>>what order you link the object files.  If you've got examples where it
>>seems to matter, please post it because that's a bug and needs to be
>>fixed.
>
> I'm sorry, but everything that could be used to check or even
> reproduce this behaviour has been relocated to the null device long
> ago.

If you do come across a case of -ffunction-sections and -gc-sections
not working, please post it.  It should work, and I know for a fact
that it used to.

>>> Unless the linker has been greatly improved since then, the problem
>>> should be there. Maybe I'm wrong.
>
>> You seem to be assuming a single-pass linker.  It works in two passes.
>> First it reads all of the object files.  Then it starts at all of the
>> nodes (symbols) marked as "keep" and traverses the reference graph
>> marking all reachable nodes.
>> When it's done traversing the graph, it discards any nodes that
>> haven't been reached from the initial set of "keep" nodes.
>

> When I read last time about the inner workings of the linking
> process, things were different, But of course there have been many
> improvements in the past years and I didn't really care anyway. And
> with todays surplus of memory and CPU power, it makes no difference
> keeping everything first and sorting out things later.
>
>>> About the reduced effectiveness of the optimization, this one is
>>> obvious. If the linker is allowed to include or discard parts of a
>>> compilation unit depending of their usage, the compiler may not do
>>> any optimization that crosses the boundary between functions.
>
>> I'm afraid that's not at all obvious to me.
>
>> Example: A C file contains two functions: foo() and bar().  foo() is
>> called by various external functions.  bar() is called only by foo().
>> The compiler can inline bar() without causing any problems.
>
> Sure, but the optimization process sometimes generates code where 
> foo() and bar() share common code after optimization.

You said that "compile may not do any optimization that crosses the
boundary between functions."  Now you're saying it's only certain
_types_ of cross-function optimization that can't be done.  That may
be true, though I can't think of any.

> If foo() is kept and bar() is not, what about the shared code?

The compiler could put the shared code in a third section and call it
from both foo() and bar().

> After (re-)reading the explanation of -ffunction-sections, it looks
> like every function is placed in its own section, so the optimizer
> should not optimize across functions anyway, generating
> less-efficient code since it isn't known at compile-time whether the
> shared code will be still available after linking.

The compiler could take measures to make sure that the shared code is
avaialable whether either foo() or bar() is called.  But this is all
rather academic without looking at real code that is somehow adversely
affected by the --functions-section option.

> I'm sure I've seen this kind of optimizations not too long ago. But
> don't ask me for an example.

OK, but there's not much we can do to address worries for which you
don't have any real examples.

> Of cource the outcome won't be less efficient than having both
> functions in separate compilation units.
>
> I'd really like to put this kind of options (including optimization
> settings) into the appropriate source file only (by a pragma) instead
> of having them active for the whole project (unless one wants to make
> rather complex makefiles)

yes, that would be nice, but it would be very difficult due to some
fundamental architecture decisions that were made in both gcc and
binutils a long time ago.

> Anyway, I just tried to use the -ffunction-sections and -gc-sections
> flags and while the compiler now places the functions in separate
> sections like ".text.foo", the linker does not remove them from the
> build at all.

Then somebody has done something to break the linker.  I used to rely
on those features, and I know that they worked -- when I turned them
off, the code didn't fit into the flash.

I know I'm probably starting to sound repetitive, but can you provide
a real example so that we can try to fix that feature?

> And I'm certain that the two functions in question are not referenced
> ever as I just added them to the code. Also, I added some
> sections/moved the vector table and the code/data in these sections
> is never referenced anywhere, yet they are still in the binary. (and
> I do not explicitely keep them in the linker script). I wonder what's
> (not) going on. It's ld 060404, part of the mspgcc build from
> 12/2008.

The last fix to gcc for -ffunction-sections -fdata-sections support
went in at the end of May 2008, so I would expect the 12/2008 build of
gcc to work.  I'm not sure what "ld 060404" means.  ld should have
version number like 2.19.3.  What I can say is that it worked for me
the last time I tried it, and others have reported it working more
recently.

> Even more, I think the linker will keep everything I feed it as
> source file, whether anything in an object file is ever used or not.
> I normally only include those object files which _are_ in use, but...
> I just included a completely unrelated file with never-used functions
> into the makefile and my binary has grown. So what's wrong?

I have no way of knowing unless you provide an example.

>> IIRC, the linker will convert "long" branches into short/relative
>> jumps at link time.  At least it does that for all the other targets
>> I use...
>
> interesting. Still two wasted bytes (I don't think the linker will
> move the following code and adjust any other jumps if necessary),

Yes, if the linker supports changing address modes, then it does
move the following code.

> but faster. I wonder if this is done for branches with unrelocated
> destinations or with already linked ones too?

I've only personally witnessed it for instructions containing
relocated addresses.

> I'm just curious. Altering the assembly instructions is nothing a
> linker should do imho.

Then don't enable that option.  For Gnu binutils it's called
"--relax".

>>> Also, some addressing modes cannot be used under such a setup.
>>I don't understand why.  Can you provide an actual example?
>
> I'm not sure whether the compiler ever uses relative addressing modes
> but I doubt this will be usable if the destination is in a different
> segment. A fixed distance to the destination is the base of relative
> addressing. And with separate segments there is no such fixed
> position.

Again, stuff like that can be fixed up at link time.

>> Some things like optmizing addressing modes for far/short
>> destinations have to be done at link time instead of compile time,
>> but I don't see how that hurts anything.
>
> The linker messes with the addressing modes?

It can.

> That's really new to me.

>From the "ld" man page:

 --relax

    An option with machine dependent effects. This option is only
    supported on a few targets. See section ld and the H8/300. See
    section ld and the Intel 960 family. On some platforms, the
    --relax' option performs global optimizations that become possible
    when the linker resolves addressing in the program, such as
    relaxing address modes and synthesizing new instructions in the
    output object file. On platforms where this is not supported,
    --relax' is accepted, but ignored. 

I'm not sure if this option does anything for the '430 or not.  It's
possible that nobody has implimented it for the MSP430.  On other
targets I've used, it would change addressing modes to speed/shorten
code at link time.  I thought it worked for the '430, but it's
possible (probably even) that I'm remembering another target I was
using at the same time as the '430.
    
> Isn't it just placing the proper relocated addresses into the holes
> left by the compiler?

Sometimes.

> Well, I'm better safe than sorry and I guess someone else did too.
> Why else is this whole -ffunction-sections thing an option and
> disabled by default?

Because it's a somewhat new feature and it's not the way people are
used to having things work.  When a new feature gets added, it's
usually disabled by default in order to preserve as much
backwards-compatibilty as possible.

> Maybe I have been too suspicious and I'm sorry if I wasted your time.
> I'm not an information source for ongoing compiler/linker development
> anyway sicne I don't use the latest version. In a production
> environment, an old compiler with known bugs is better than a new one
> with perhaps unknown bugs (same for embedded OS versions). We made
> this mistake once and will never do again unless we're really forced
> to. Also, my boss pays me for working on the projects, not the
> compiler :) In his opinion, I'm making too many experiments already,
> wasting too much time (luckily he _needs_ me)

-- 
Grant Edwards               grant.b.edwards        Yow! Gibble, Gobble, we
                                  at               ACCEPT YOU ...
                              gmail.com            


Reply via email to