[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [avr-gcc-list] binutils 2.22 blow up program size with -flto
From: |
Georg-Johann Lay |
Subject: |
Re: [avr-gcc-list] binutils 2.22 blow up program size with -flto |
Date: |
Fri, 24 Aug 2012 18:38:47 +0200 |
User-agent: |
Thunderbird 2.0.0.24 (X11/20100302) |
Georg-Johann Lay wrote:
>
> [...]
>
> One known problem is the way AVR-Libc "supplies" basic single float (SF)
> routines: It "overrides" the routines from libgcc for some reasons.
>
> This relies on a specific -library sequence during the final link.
>
> Suppose the following small program:
>
> /* foo.c */
> float volatile f;
>
> int main (void)
> {
> return f;
> }
>
> And compile it to foo.o with, say
>
> $ avr-gcc -mmcu=atmega8 foo.c -Os -flto -c
>
> Then link with
>
> $ avr-gcc -mmcu=atmega8 foo.o -Os -o foo.elf -lm -v
>
> and with by setup (avr-gcc 4.7.1, binutils ~2.23, AVR-Libc 1.8.0)
> the elf has a size of 278 bytes.
>
> $ avr-gcc -mmcu=atmega8 foo.o -Os -o foo.elf -lm -v -flto
>
> gives a size of 582 bytes because the SF routines from libgcc are
> linked:
>
>>> COLLECT_GCC_OPTIONS='-mmcu=atmega8' '-Os' '-o' 'foo.elf' '-v' '-flto'
>>> .../collect2.exe ... -plugin-opt=-pass-through=-lgcc
>>> -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -flto
>>> -m avr4 -o foo.elf ... -lm -lgcc -lc -lgcc
>
> The -v options does not show how the final link is actually performed,
> but the result indicates that it's similar to
>
> $ ld ... -lgcc -lc -lgcc -m avr4 -o foo.elf ... -lm -lgcc -lc -lgcc
>
> For the test case a hack around is to link with
>
> $ avr-gcc ... -nodefaultlibs -lm -lgcc -lc -lgcc
>
> instead of with -lm. Thus we have just another déjà-vu of PR28718...
>
> One proposed hack was to add a configure option to GCC:
>
> From 2011-11-10 [off-list] PR28718 Infos?
>
>> As Georg-Johann Lay wrote:
>>
>> >> Dazu habe ich folgende Fragen:
>> >> >> o Ist sowas überhaupt sinnvoll (per extra configure-Option)?
>>
>> Sinnvoller würde ich es finden, die avr-libc-Teile stattdessen in die
>> libgcc zu packen, aber ich fürchte, dass das mit all dem copyright
>> assignment Krams für die beteiligten Leute zumindest ein jahrelanger
>> Prozess wäre, einschließlich des Umschreibens der Lizenz. Teilweise
>> stammt der Code noch von Michael Stumpf (2002 geschrieben), und ihn
>> hatten wir damals extra noch um die Genehmigung gebeten, seinen Code
>> unter BSD-Lizenz zu stellen (ursprünglich war er unter GPL), damit er
>> zur Lizenz der übrigen avr-libc passt.
>>
>> >> o Falls ja: Welche libgcc-Funktionen werden auch von der
>> >> avr-libc dargestellt und können über den geplanten Mechanismus
>> >> rausgekickt werden?
>>
>> Gute Frage. ;-)
>> % nm /usr/local/avr/lib/libm.a | grep 'T __'
>>
>> 00000002 T __addsf3
>> 00000000 T __subsf3
>> 00000000 T __cmpsf2
>> 00000000 T __eqsf2
>> 00000000 T __lesf2
>> 00000000 T __ltsf2
>> 00000000 T __nesf2
>> 00000000 T __divsf3
>> 00000000 T __fixsfdi
>> 0000000a T __fixunssfdi
>> 00000000 T __fixsfsi
>> 00000000 T __fixunssfsi
>> 00000000 T __floatdisf
>> 00000004 T __floatsisf
>> 00000000 T __floatunsisf
>> 00000000 T __floatundisf
>> 00000000 T __gesf2
>> 00000000 T __gtsf2
>> 00000000 T __mulsf3
>> 00000000 T __negsf2
>> 00000000 T __unordsf2
>
> I cut down that list to possible candidates (__fp_* are not).
>
>> Das müssten sie sein, oder?
>
> Maybe there are some missing like ffs, parity, popcount, etc.
>
>> Disclaimer: das oben ist erstmal nur für avr3 direkt aus den binären
>> Bibliotheken gezogen. Wir sollten dafür in der avr-libc noch eine
>> Methode finden, eine solche Liste explizit zu pflegen und dann auch zu
>> testen, dass genau die in dieser Liste genannten Symbole auch
>> tatsächlich vorhanden sind.
>>
>> Schwierig wird das natürlich mit der relativen Unabhängigkeit von
>> Compiler und Bibliothek bei irgendwelchen Änderungen.
>
> Or instead of --with-avrlibc=yes or --with-avrlibc=1.8.0 there could
> be --with-lib2funcs-exclude=<list> append to LIB2FUNCS_EXCLUDE.
Attached is a patch that supports --with-avrlibc=yes as
GCC configure option.
> avr.h currently has no macro to define LINK_GCC_C_SEQUENCE_SPEC which
> defaults to "%G %L %G".
Maybe this has to be adjusted, too, i.e. something like
"%G %L %G %L"
which covers the case when AVR-Libc uses fixed-point support from
libgcc which use float-functions in AVR-Libc.
Johann
--
libgcc/
* config.host (tmake_file && avr-*-*): Add avr/t-avrlibc if
configured --with-avrlibc=yes
* Makefile.in (FPBIT_FUNCS): filter-out LIB2FUNCS_EXCLUDE.
(DPBIT_FUNCS): Ditto.
(TPBIT_FUNCS): Ditto.
* config/avr/t-avrlibc: New.
Index: libgcc/config.host
===================================================================
--- libgcc/config.host (revision 190644)
+++ libgcc/config.host (working copy)
@@ -380,6 +380,9 @@ avr-*-rtems*)
avr-*-*)
# Make HImode functions for AVR
tmake_file="${cpu_type}/t-avr t-fpbit"
+ if test x$with_avrlibc = xyes; then
+ tmake_file="$tmake_file ${cpu_type}/t-avrlibc"
+ fi
tm_file="$tm_file avr/avr-lib.h"
;;
bfin*-elf*)
Index: libgcc/Makefile.in
===================================================================
--- libgcc/Makefile.in (revision 190644)
+++ libgcc/Makefile.in (working copy)
@@ -516,6 +516,10 @@ FPBIT_FUNCS := $(filter-out _sf_to_tf,$(
DPBIT_FUNCS := $(filter-out _df_to_tf,$(DPBIT_FUNCS))
endif
+FPBIT_FUNCS := $(filter-out $(LIB2FUNCS_EXCLUDE),$(FPBIT_FUNCS))
+DPBIT_FUNCS := $(filter-out $(LIB2FUNCS_EXCLUDE),$(DPBIT_FUNCS))
+TPBIT_FUNCS := $(filter-out $(LIB2FUNCS_EXCLUDE),$(TPBIT_FUNCS))
+
fpbit-src := $(srcdir)/fp-bit.c
# Build FPBIT.
Index: libgcc/config/avr/t-avrlibc
===================================================================
--- libgcc/config/avr/t-avrlibc (revision 0)
+++ libgcc/config/avr/t-avrlibc (revision 0)
@@ -0,0 +1,36 @@
+LIB2FUNCS_EXCLUDE += \
+ _compare_sf \
+ _eq_sf \
+ _ne_sf \
+ _gt_sf \
+ _ge_sf \
+ _lt_sf \
+ _le_sf \
+ _unord_sf \
+ \
+ _negate_sf \
+ _addsub_sf \
+ _mul_sf \
+ _div_sf \
+ \
+ _si_to_sf _sf_to_si \
+ _usi_to_sf _sf_to_usi
+
+# DF
+LIB2FUNCS_EXCLUDE += \
+ _sf_to_df
+
+LIB2FUNCS_EXCLUDE += \
+ _fixunssfsi \
+ _fixsfdi \
+ _fixunssfdi \
+ _floatdisf \
+ _floatundisf
+
+# DF
+LIB2FUNCS_EXCLUDE += \
+ _fixdfdi \
+ _fixunsdfsi \
+ _fixunsdfdi \
+ _floatdidf \
+ _floatundidf