Re: Removing unused code/variables

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 18/04/2021 00:47, Alexander Shpilkin via Gcc-help wrote:
> Hi,
> 
> On Fri, 2021-04-16 at 13:47 +0000, David Sherman wrote:
>> We are using NXP's MCUXpresso to target ARM, and it uses gcc.  We have
>> a large project with several different configurations.  The underlying
>> library code gets compiled into libs and linked into the main
>> application, and the main application has all the switches to enable or
>> disable features.  Despite using -Os, many chunks of code are still
>> present, as are static variables, even though they never get used.  We
>> have tried turning on link time optimization, but it appears to have no
>> effect.  Some static variables are optimized away, but many remain.  We
>> have even tried making them part of their own section and using
>> different linker directives that don't have that section specified, but
>> they get linked in anyway.
> 
> I don’t know anything about MCUXpresso specifically, but let me expand
> a bit on David Brown’s general remarks.
> 
> First of all, it’s not the job of -Os to remove unused code.  Unless
> the source explicitly checks for the __OPTIMIZE_SIZE__ macro (rare, but
> not unheard of), the compiler will compile more or less the same code
> at any optimization level.  More optimization might enable it to
> eliminate more code (e.g. if a C function declared 'static inline' ends
> up inlined everywhere), but the dependency analysis is very
> conservative and AFAIK setting -Os does not change anything about it. 
> I don’t actually know if GCC is capable of dropping unused static
> variables at all, by the way.  (This requires, for example, proving
> that a pointer to the variable is never taken.)

There is little difference (IME) about what is dropped or not between
different variations on optimisation levels (-Os, -O2, -Og).  But there
is a huge difference between -O0 (no optimisation) and -O1.  Once the
compiler can do inter-procedural analysis, inlining and constant
propagation, it can definitely start removing unused /static/ code and
data.  Static variables that are not used (or only written to), whose
address is not taken or does not escape, are removed.  Static functions
that are called only once are inlined, those that are never called are
never generated (unless you take pointers to them).


Static libraries with each function in its own source file is certainly
traditional for many uses, but it is not efficient in code space unless
you expect that the solid majority of the code will not be needed in a
given application.  That applies to general-purpose libraries, but not
to most embedded systems (like the OP has).  In particular, having
separate files for each function (or small group of functions) greatly
reduces the scope for inter-procedural optimisations (unless you go all
the way and use LTO), and severely limits the use of "static".

For embedded systems, -fdata-sections -ffunction-sections
-Wl,--gc-sections is standard practice.

(Remember also to include "-fno-common" - it can sometimes have a
surprisingly large effect on code size, and certainly on code speed, as
well as being important to catch duplicate definition errors.  And of
course make everything static where possible.)





[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux