OSDN Git Service

Merge lto branch into trunk.
authordnovillo <dnovillo@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 3 Oct 2009 21:10:11 +0000 (21:10 +0000)
committerdnovillo <dnovillo@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 3 Oct 2009 21:10:11 +0000 (21:10 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@152434 138bc75d-0d04-0410-961f-82ee72b054a4

309 files changed:
ChangeLog
Makefile.def
Makefile.in
Makefile.tpl
configure
configure.ac
contrib/ChangeLog
contrib/gcc_update
gcc/ChangeLog
gcc/Makefile.in
gcc/builtins.c
gcc/c-common.c
gcc/c-common.h
gcc/c-opts.c
gcc/c.opt
gcc/cgraph.c
gcc/cgraph.h
gcc/cgraphbuild.c
gcc/cgraphunit.c
gcc/collect2.c
gcc/collect2.h
gcc/common.opt
gcc/config.in
gcc/config/rs6000/rs6000.c
gcc/configure
gcc/configure.ac
gcc/doc/install.texi
gcc/doc/invoke.texi
gcc/doc/sourcebuild.texi
gcc/except.c
gcc/flags.h
gcc/fortran/ChangeLog
gcc/fortran/options.c
gcc/gcc.c
gcc/gimple.c
gcc/gimple.h
gcc/ipa-cp.c
gcc/ipa-inline.c
gcc/ipa-prop.c
gcc/ipa-pure-const.c
gcc/ipa-reference.c
gcc/java/ChangeLog
gcc/java/config-lang.in
gcc/langhooks-def.h
gcc/langhooks.c
gcc/langhooks.h
gcc/lto-cgraph.c [new file with mode: 0644]
gcc/lto-compress.c [new file with mode: 0644]
gcc/lto-compress.h [new file with mode: 0644]
gcc/lto-opts.c [new file with mode: 0644]
gcc/lto-section-in.c [new file with mode: 0644]
gcc/lto-section-out.c [new file with mode: 0644]
gcc/lto-streamer-in.c [new file with mode: 0644]
gcc/lto-streamer-out.c [new file with mode: 0644]
gcc/lto-streamer.c [new file with mode: 0644]
gcc/lto-streamer.h [new file with mode: 0644]
gcc/lto-symtab.c [new file with mode: 0644]
gcc/lto-wpa-fixup.c [new file with mode: 0644]
gcc/lto-wrapper.c [new file with mode: 0644]
gcc/lto/ChangeLog [new file with mode: 0644]
gcc/lto/Make-lang.in [new file with mode: 0644]
gcc/lto/common.c [new file with mode: 0644]
gcc/lto/common.h [new file with mode: 0644]
gcc/lto/config-lang.in [new file with mode: 0644]
gcc/lto/lang-specs.h [new file with mode: 0644]
gcc/lto/lang.opt [new file with mode: 0644]
gcc/lto/lto-elf.c [new file with mode: 0644]
gcc/lto/lto-lang.c [new file with mode: 0644]
gcc/lto/lto-tree.h [new file with mode: 0644]
gcc/lto/lto.c [new file with mode: 0644]
gcc/lto/lto.h [new file with mode: 0644]
gcc/opts.c
gcc/passes.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/20090107-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/20090121-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/README
gcc/testsuite/g++.dg/dg.exp
gcc/testsuite/g++.dg/ipa/20090113-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20080709_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20080829_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20080904_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20080907_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20080908-1_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20080908-2_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20080908-3_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20080909-1_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20080910-1_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20080912-1_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20080912_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20080915_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20080916_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20080917_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20080924_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20080926_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20081008_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20081022.h [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20081022_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20081022_1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20081023_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20081109-1_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20081109-2_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20081109_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20081109_1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20081118-1_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20081118-1_1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20081118_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20081118_1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20081119-1.h [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20081119-1_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20081119-1_1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20081119_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20081119_1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20081120-1_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20081120-1_1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20081120-2_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20081120-2_1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20081123_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20081123_1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20081125.h [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20081125_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20081125_1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20081127_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20081127_1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20081203_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20081203_1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20081204-1_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20081204-1_1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20081204-2_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20081204-2_1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20081209_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20081209_1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20081211-1.h [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20081211-1_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20081211-1_1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20081217-1_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20081217-2_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20081219_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20081219_1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20090106_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20090112_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20090128_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20090221_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20090302_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20090302_1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20090303_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20090311-1.h [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20090311-1_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20090311-1_1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20090311_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20090311_1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20090312.h [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20090312_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20090312_1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20090313_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20090313_1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20090315_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20090315_1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20091002-1_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20091002-2_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/20091002-3_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/README [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/lto.exp [new file with mode: 0644]
gcc/testsuite/g++.dg/lto/pr40818_0.C [new file with mode: 0644]
gcc/testsuite/g++.dg/opt/thunk3-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/opt/thunk4.C [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/execute/builtins/builtins.exp
gcc/testsuite/gcc.c-torture/execute/builtins/lib/abs.c
gcc/testsuite/gcc.c-torture/execute/builtins/lib/bfill.c
gcc/testsuite/gcc.c-torture/execute/builtins/lib/bzero.c
gcc/testsuite/gcc.c-torture/execute/builtins/lib/fprintf.c
gcc/testsuite/gcc.c-torture/execute/builtins/lib/memchr.c
gcc/testsuite/gcc.c-torture/execute/builtins/lib/memcmp.c
gcc/testsuite/gcc.c-torture/execute/builtins/lib/memmove.c
gcc/testsuite/gcc.c-torture/execute/builtins/lib/mempcpy.c
gcc/testsuite/gcc.c-torture/execute/builtins/lib/memset.c
gcc/testsuite/gcc.c-torture/execute/builtins/lib/printf.c
gcc/testsuite/gcc.c-torture/execute/builtins/lib/sprintf.c
gcc/testsuite/gcc.c-torture/execute/builtins/lib/stpcpy.c
gcc/testsuite/gcc.c-torture/execute/builtins/lib/strcat.c
gcc/testsuite/gcc.c-torture/execute/builtins/lib/strchr.c
gcc/testsuite/gcc.c-torture/execute/builtins/lib/strcmp.c
gcc/testsuite/gcc.c-torture/execute/builtins/lib/strcpy.c
gcc/testsuite/gcc.c-torture/execute/builtins/lib/strcspn.c
gcc/testsuite/gcc.c-torture/execute/builtins/lib/strlen.c
gcc/testsuite/gcc.c-torture/execute/builtins/lib/strncat.c
gcc/testsuite/gcc.c-torture/execute/builtins/lib/strncmp.c
gcc/testsuite/gcc.c-torture/execute/builtins/lib/strncpy.c
gcc/testsuite/gcc.c-torture/execute/builtins/lib/strpbrk.c
gcc/testsuite/gcc.c-torture/execute/builtins/lib/strrchr.c
gcc/testsuite/gcc.c-torture/execute/builtins/lib/strspn.c
gcc/testsuite/gcc.c-torture/execute/builtins/lib/strstr.c
gcc/testsuite/gcc.c-torture/execute/execute.exp
gcc/testsuite/gcc.c-torture/execute/ieee/ieee.exp
gcc/testsuite/gcc.c-torture/unsorted/unsorted.exp
gcc/testsuite/gcc.dg/20081223-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20080908_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20080917_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20080924_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20081024_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20081109_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20081111_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20081111_1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20081112_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20081112_1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20081115_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20081115_1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20081115_2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20081118_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20081118_1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20081118_2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20081120-1_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20081120-1_1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20081120-2_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20081120-2_1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20081125_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20081125_1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20081126_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20081201-1_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20081201-1_1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20081201-1_2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20081201-2_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20081201-2_1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20081202-1_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20081202-1_1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20081202-2_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20081202-2_1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20081204-1_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20081204-1_1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20081204-2_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20081210-1_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20081212-1_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20081222_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20081222_0.h [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20081222_1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20081224_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20081224_0.h [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20081224_1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20090116_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20090120_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20090126-1_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20090126-2_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20090206-1_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20090206-2_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20090210_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20090210_1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20090213_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20090213_1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20090218-1_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20090218-1_1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20090218-2_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20090218-2_1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20090218_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20090218_1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20090218_2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20090218_3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20090219_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20090312_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20090312_1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20090313_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20090706-1_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20090706-2_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20090717_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20090717_1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20090729_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20090729_1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20090812_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20090812_1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/20090914-1_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/README [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/lto.exp [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/math-torture/math-torture.exp
gcc/testsuite/gfortran.dg/lto/lto.exp [new file with mode: 0644]
gcc/testsuite/gfortran.dg/lto/pr40724_0.f [new file with mode: 0644]
gcc/testsuite/gfortran.dg/lto/pr40724_1.f [new file with mode: 0644]
gcc/testsuite/gfortran.dg/lto/pr40725_0.f03 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/lto/pr40725_1.c [new file with mode: 0644]
gcc/testsuite/gfortran.dg/lto/pr41069_0.f90 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/lto/pr41069_1.f90 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/lto/pr41069_2.f90 [new file with mode: 0644]
gcc/testsuite/lib/c-torture.exp
gcc/testsuite/lib/gcc-dg.exp
gcc/testsuite/lib/lto.exp [new file with mode: 0644]
gcc/testsuite/lib/target-supports.exp
gcc/testsuite/lib/torture-options.exp
gcc/timevar.def
gcc/tlink.c
gcc/toplev.c
gcc/tree-cfg.c
gcc/tree-flow.h
gcc/tree-inline.c
gcc/tree-optimize.c
gcc/tree-pass.h
gcc/tree.c
gcc/tree.h
include/ChangeLog
include/lto-symtab.h [new file with mode: 0644]
include/plugin-api.h [new file with mode: 0644]
lto-plugin/ChangeLog [new file with mode: 0644]
lto-plugin/Makefile.am [new file with mode: 0644]
lto-plugin/Makefile.in [new file with mode: 0644]
lto-plugin/acinclude.m4 [new file with mode: 0644]
lto-plugin/aclocal.m4 [new file with mode: 0644]
lto-plugin/configure [new file with mode: 0755]
lto-plugin/configure.ac [new file with mode: 0644]
lto-plugin/lto-plugin.c [new file with mode: 0644]
lto-plugin/lto-symtab.c [new file with mode: 0644]
maintainer-scripts/ChangeLog
maintainer-scripts/gcc_release

index 3fc5305..a9de265 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,32 @@
+2009-10-03  2009-02-05  Rafael Avila de Espindola  <espindola@google.com>
+
+       * Makefile.def: all-lto-plugin depends on all-libiberty.
+       set bootstrap=true for lto-plugin.
+       Add lto-plugin.
+       * Makefile.in: Regenerate.
+       * configure.ac (host_libs): Add lto-plugin.
+       * configure: Regenerate.
+
+
+2009-10-03  Diego Novillo  <dnovillo@google.com>
+
+       * Makefile.tpl (HOST_EXPORTS): Add LIBELFLIBS and LIBELFINC.
+       (HOST_LIBELFLIBS): Define.
+       (HOST_LIBELFINC): Define.
+       * Makefile.in: Regenerate.
+       * configure.ac: Add --enable-lto.
+       Add --with-libelf, --with-libelf-include and --with-libelf-lib.
+       If --enable-lto is used, add 'lto' to new_enable_languages.
+       If --enable-lto is used and gold is enabled, add
+       lto-plugin to configdirs.
+       * configure: Regenerate.
+
+2009-10-03  Simon Baldwin  <simonb@google.com>
+
+       * configure.ac: If --with-system-zlib, suppress local zlib and
+       pass --with-system-zlib to subdir configure scripts.
+       * configure: Regenerate.
+
 2009-10-01  Loren J. Rittle <ljrittle@acm.org>
            Paolo Bonzini  <bonzini@gnu.org>
 
index 5834232..52d486f 100644 (file)
@@ -97,7 +97,8 @@ host_modules= { module= ld; bootstrap=true; };
 host_modules= { module= libcpp; bootstrap=true; };
 host_modules= { module= libdecnumber; bootstrap=true; };
 host_modules= { module= libgui; };
-host_modules= { module= libiberty; bootstrap=true; };
+host_modules= { module= libiberty; bootstrap=true;
+               extra_configure_flags='@extra_host_libiberty_configure_flags@';};
 // We abuse missing to avoid installing anything for libiconv.
 host_modules= { module= libiconv;
                extra_configure_flags='--disable-shared';
@@ -141,6 +142,7 @@ host_modules= { module= libtermcap; no_check=true;
                 missing=maintainer-clean; };
 host_modules= { module= utils; no_check=true; };
 host_modules= { module= gnattools; };
+host_modules= { module= lto-plugin; bootstrap=true; };
 
 target_modules = { module= libstdc++-v3;
                   bootstrap=true;
@@ -346,6 +348,8 @@ dependencies = { module=all-fixincludes; on=all-libiberty; };
 
 dependencies = { module=all-gnattools; on=all-target-libada; };
 
+dependencies = { module=all-lto-plugin; on=all-libiberty; };
+
 dependencies = { module=configure-mpfr; on=all-gmp; };
 dependencies = { module=configure-mpc; on=all-mpfr; };
 dependencies = { module=configure-ppl; on=all-gmp; };
index 4f86911..8738cd4 100644 (file)
@@ -219,6 +219,8 @@ HOST_EXPORTS = \
        PPLINC="$(HOST_PPLINC)"; export PPLINC; \
        CLOOGLIBS="$(HOST_CLOOGLIBS)"; export CLOOGLIBS; \
        CLOOGINC="$(HOST_CLOOGINC)"; export CLOOGINC; \
+       LIBELFLIBS="$(HOST_LIBELFLIBS)" ; export LIBELFLIBS; \
+       LIBELFINC="$(HOST_LIBELFINC)" ; export LIBELFINC; \
 @if gcc-bootstrap
        $(RPATH_ENVVAR)=`echo "$(TARGET_LIB_PATH)$$$(RPATH_ENVVAR)" | sed 's,::*,:,g;s,^:*,,;s,:*$$,,'`; export $(RPATH_ENVVAR); \
 @endif gcc-bootstrap
@@ -293,6 +295,10 @@ HOST_PPLINC = @pplinc@
 HOST_CLOOGLIBS = @clooglibs@
 HOST_CLOOGINC = @clooginc@
 
+# Where to find libelf
+HOST_LIBELFLIBS = @libelflibs@
+HOST_LIBELFINC = @libelfinc@
+
 # ----------------------------------------------
 # Programs producing files for the BUILD machine
 # ----------------------------------------------
@@ -854,7 +860,8 @@ configure-host:  \
     maybe-configure-tk \
     maybe-configure-libtermcap \
     maybe-configure-utils \
-    maybe-configure-gnattools
+    maybe-configure-gnattools \
+    maybe-configure-lto-plugin
 .PHONY: configure-target
 configure-target:  \
     maybe-configure-target-libstdc++-v3 \
@@ -1026,6 +1033,9 @@ all-host: maybe-all-tk
 all-host: maybe-all-libtermcap
 all-host: maybe-all-utils
 all-host: maybe-all-gnattools
+@if lto-plugin-no-bootstrap
+all-host: maybe-all-lto-plugin
+@endif lto-plugin-no-bootstrap
 
 .PHONY: all-target
 
@@ -1147,6 +1157,7 @@ info-host: maybe-info-tk
 info-host: maybe-info-libtermcap
 info-host: maybe-info-utils
 info-host: maybe-info-gnattools
+info-host: maybe-info-lto-plugin
 
 .PHONY: info-target
 
@@ -1259,6 +1270,7 @@ dvi-host: maybe-dvi-tk
 dvi-host: maybe-dvi-libtermcap
 dvi-host: maybe-dvi-utils
 dvi-host: maybe-dvi-gnattools
+dvi-host: maybe-dvi-lto-plugin
 
 .PHONY: dvi-target
 
@@ -1371,6 +1383,7 @@ pdf-host: maybe-pdf-tk
 pdf-host: maybe-pdf-libtermcap
 pdf-host: maybe-pdf-utils
 pdf-host: maybe-pdf-gnattools
+pdf-host: maybe-pdf-lto-plugin
 
 .PHONY: pdf-target
 
@@ -1483,6 +1496,7 @@ html-host: maybe-html-tk
 html-host: maybe-html-libtermcap
 html-host: maybe-html-utils
 html-host: maybe-html-gnattools
+html-host: maybe-html-lto-plugin
 
 .PHONY: html-target
 
@@ -1595,6 +1609,7 @@ TAGS-host: maybe-TAGS-tk
 TAGS-host: maybe-TAGS-libtermcap
 TAGS-host: maybe-TAGS-utils
 TAGS-host: maybe-TAGS-gnattools
+TAGS-host: maybe-TAGS-lto-plugin
 
 .PHONY: TAGS-target
 
@@ -1707,6 +1722,7 @@ install-info-host: maybe-install-info-tk
 install-info-host: maybe-install-info-libtermcap
 install-info-host: maybe-install-info-utils
 install-info-host: maybe-install-info-gnattools
+install-info-host: maybe-install-info-lto-plugin
 
 .PHONY: install-info-target
 
@@ -1819,6 +1835,7 @@ install-pdf-host: maybe-install-pdf-tk
 install-pdf-host: maybe-install-pdf-libtermcap
 install-pdf-host: maybe-install-pdf-utils
 install-pdf-host: maybe-install-pdf-gnattools
+install-pdf-host: maybe-install-pdf-lto-plugin
 
 .PHONY: install-pdf-target
 
@@ -1931,6 +1948,7 @@ install-html-host: maybe-install-html-tk
 install-html-host: maybe-install-html-libtermcap
 install-html-host: maybe-install-html-utils
 install-html-host: maybe-install-html-gnattools
+install-html-host: maybe-install-html-lto-plugin
 
 .PHONY: install-html-target
 
@@ -2043,6 +2061,7 @@ installcheck-host: maybe-installcheck-tk
 installcheck-host: maybe-installcheck-libtermcap
 installcheck-host: maybe-installcheck-utils
 installcheck-host: maybe-installcheck-gnattools
+installcheck-host: maybe-installcheck-lto-plugin
 
 .PHONY: installcheck-target
 
@@ -2155,6 +2174,7 @@ mostlyclean-host: maybe-mostlyclean-tk
 mostlyclean-host: maybe-mostlyclean-libtermcap
 mostlyclean-host: maybe-mostlyclean-utils
 mostlyclean-host: maybe-mostlyclean-gnattools
+mostlyclean-host: maybe-mostlyclean-lto-plugin
 
 .PHONY: mostlyclean-target
 
@@ -2267,6 +2287,7 @@ clean-host: maybe-clean-tk
 clean-host: maybe-clean-libtermcap
 clean-host: maybe-clean-utils
 clean-host: maybe-clean-gnattools
+clean-host: maybe-clean-lto-plugin
 
 .PHONY: clean-target
 
@@ -2379,6 +2400,7 @@ distclean-host: maybe-distclean-tk
 distclean-host: maybe-distclean-libtermcap
 distclean-host: maybe-distclean-utils
 distclean-host: maybe-distclean-gnattools
+distclean-host: maybe-distclean-lto-plugin
 
 .PHONY: distclean-target
 
@@ -2491,6 +2513,7 @@ maintainer-clean-host: maybe-maintainer-clean-tk
 maintainer-clean-host: maybe-maintainer-clean-libtermcap
 maintainer-clean-host: maybe-maintainer-clean-utils
 maintainer-clean-host: maybe-maintainer-clean-gnattools
+maintainer-clean-host: maybe-maintainer-clean-lto-plugin
 
 .PHONY: maintainer-clean-target
 
@@ -2656,7 +2679,8 @@ check-host:  \
     maybe-check-tk \
     maybe-check-libtermcap \
     maybe-check-utils \
-    maybe-check-gnattools
+    maybe-check-gnattools \
+    maybe-check-lto-plugin
 
 .PHONY: check-target
 check-target:  \
@@ -2794,7 +2818,8 @@ install-host-nogcc:  \
     maybe-install-tk \
     maybe-install-libtermcap \
     maybe-install-utils \
-    maybe-install-gnattools
+    maybe-install-gnattools \
+    maybe-install-lto-plugin
 
 .PHONY: install-host
 install-host:  \
@@ -2873,7 +2898,8 @@ install-host:  \
     maybe-install-tk \
     maybe-install-libtermcap \
     maybe-install-utils \
-    maybe-install-gnattools
+    maybe-install-gnattools \
+    maybe-install-lto-plugin
 
 .PHONY: install-target
 install-target:  \
@@ -28249,7 +28275,7 @@ configure-libiberty:
        libsrcdir="$$s/libiberty"; \
        $(SHELL) $${libsrcdir}/configure \
          $(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
-         --target=${target_alias} $${srcdiroption}  \
+         --target=${target_alias} $${srcdiroption} @extra_host_libiberty_configure_flags@ \
          || exit 1
 @endif libiberty
 
@@ -28283,7 +28309,8 @@ configure-stage1-libiberty:
        $(SHELL) $${libsrcdir}/configure \
          $(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
          --target=${target_alias} $${srcdiroption} \
-         $(STAGE1_CONFIGURE_FLAGS)
+         $(STAGE1_CONFIGURE_FLAGS) \
+         @extra_host_libiberty_configure_flags@
 @endif libiberty-bootstrap
 
 .PHONY: configure-stage2-libiberty maybe-configure-stage2-libiberty
@@ -28316,7 +28343,8 @@ configure-stage2-libiberty:
          $(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
          --target=${target_alias} $${srcdiroption} \
          --with-build-libsubdir=$(HOST_SUBDIR) \
-         $(STAGE2_CONFIGURE_FLAGS)
+         $(STAGE2_CONFIGURE_FLAGS) \
+         @extra_host_libiberty_configure_flags@
 @endif libiberty-bootstrap
 
 .PHONY: configure-stage3-libiberty maybe-configure-stage3-libiberty
@@ -28349,7 +28377,8 @@ configure-stage3-libiberty:
          $(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
          --target=${target_alias} $${srcdiroption} \
          --with-build-libsubdir=$(HOST_SUBDIR) \
-         $(STAGE3_CONFIGURE_FLAGS)
+         $(STAGE3_CONFIGURE_FLAGS) \
+         @extra_host_libiberty_configure_flags@
 @endif libiberty-bootstrap
 
 .PHONY: configure-stage4-libiberty maybe-configure-stage4-libiberty
@@ -28382,7 +28411,8 @@ configure-stage4-libiberty:
          $(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
          --target=${target_alias} $${srcdiroption} \
          --with-build-libsubdir=$(HOST_SUBDIR) \
-         $(STAGE4_CONFIGURE_FLAGS)
+         $(STAGE4_CONFIGURE_FLAGS) \
+         @extra_host_libiberty_configure_flags@
 @endif libiberty-bootstrap
 
 .PHONY: configure-stageprofile-libiberty maybe-configure-stageprofile-libiberty
@@ -28415,7 +28445,8 @@ configure-stageprofile-libiberty:
          $(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
          --target=${target_alias} $${srcdiroption} \
          --with-build-libsubdir=$(HOST_SUBDIR) \
-         $(STAGEprofile_CONFIGURE_FLAGS)
+         $(STAGEprofile_CONFIGURE_FLAGS) \
+         @extra_host_libiberty_configure_flags@
 @endif libiberty-bootstrap
 
 .PHONY: configure-stagefeedback-libiberty maybe-configure-stagefeedback-libiberty
@@ -28448,7 +28479,8 @@ configure-stagefeedback-libiberty:
          $(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
          --target=${target_alias} $${srcdiroption} \
          --with-build-libsubdir=$(HOST_SUBDIR) \
-         $(STAGEfeedback_CONFIGURE_FLAGS)
+         $(STAGEfeedback_CONFIGURE_FLAGS) \
+         @extra_host_libiberty_configure_flags@
 @endif libiberty-bootstrap
 
 
@@ -42970,6 +43002,872 @@ maintainer-clean-gnattools:
 
 
 
+.PHONY: configure-lto-plugin maybe-configure-lto-plugin
+maybe-configure-lto-plugin:
+@if gcc-bootstrap
+configure-lto-plugin: stage_current
+@endif gcc-bootstrap
+@if lto-plugin
+maybe-configure-lto-plugin: configure-lto-plugin
+configure-lto-plugin: 
+       @r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       test ! -f $(HOST_SUBDIR)/lto-plugin/Makefile || exit 0; \
+       $(SHELL) $(srcdir)/mkinstalldirs $(HOST_SUBDIR)/lto-plugin ; \
+       $(HOST_EXPORTS) \
+       echo Configuring in $(HOST_SUBDIR)/lto-plugin; \
+       cd "$(HOST_SUBDIR)/lto-plugin" || exit 1; \
+       case $(srcdir) in \
+         /* | [A-Za-z]:[\\/]*) topdir=$(srcdir) ;; \
+         *) topdir=`echo $(HOST_SUBDIR)/lto-plugin/ | \
+               sed -e 's,\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \
+       esac; \
+       srcdiroption="--srcdir=$${topdir}/lto-plugin"; \
+       libsrcdir="$$s/lto-plugin"; \
+       $(SHELL) $${libsrcdir}/configure \
+         $(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
+         --target=${target_alias} $${srcdiroption}  \
+         || exit 1
+@endif lto-plugin
+
+
+
+.PHONY: configure-stage1-lto-plugin maybe-configure-stage1-lto-plugin
+maybe-configure-stage1-lto-plugin:
+@if lto-plugin-bootstrap
+maybe-configure-stage1-lto-plugin: configure-stage1-lto-plugin
+configure-stage1-lto-plugin:
+       @[ $(current_stage) = stage1 ] || $(MAKE) stage1-start
+       @$(SHELL) $(srcdir)/mkinstalldirs $(HOST_SUBDIR)/lto-plugin
+       @r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       TFLAGS="$(STAGE1_TFLAGS)"; \
+       test ! -f $(HOST_SUBDIR)/lto-plugin/Makefile || exit 0; \
+       $(HOST_EXPORTS) \
+       CFLAGS="$(STAGE1_CFLAGS)"; export CFLAGS; \
+       CXXFLAGS="$(STAGE1_CFLAGS)"; export CXXFLAGS; \
+       LIBCFLAGS="$(LIBCFLAGS)"; export LIBCFLAGS; \
+       echo Configuring stage 1 in $(HOST_SUBDIR)/lto-plugin ; \
+       $(SHELL) $(srcdir)/mkinstalldirs $(HOST_SUBDIR)/lto-plugin ; \
+       cd $(HOST_SUBDIR)/lto-plugin || exit 1; \
+       case $(srcdir) in \
+         /* | [A-Za-z]:[\\/]*) topdir=$(srcdir) ;; \
+         *) topdir=`echo $(HOST_SUBDIR)/lto-plugin/ | \
+               sed -e 's,\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \
+       esac; \
+       srcdiroption="--srcdir=$${topdir}/lto-plugin"; \
+       libsrcdir="$$s/lto-plugin"; \
+       $(SHELL) $${libsrcdir}/configure \
+         $(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
+         --target=${target_alias} $${srcdiroption} \
+         $(STAGE1_CONFIGURE_FLAGS)
+@endif lto-plugin-bootstrap
+
+.PHONY: configure-stage2-lto-plugin maybe-configure-stage2-lto-plugin
+maybe-configure-stage2-lto-plugin:
+@if lto-plugin-bootstrap
+maybe-configure-stage2-lto-plugin: configure-stage2-lto-plugin
+configure-stage2-lto-plugin:
+       @[ $(current_stage) = stage2 ] || $(MAKE) stage2-start
+       @$(SHELL) $(srcdir)/mkinstalldirs $(HOST_SUBDIR)/lto-plugin
+       @r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       TFLAGS="$(STAGE2_TFLAGS)"; \
+       test ! -f $(HOST_SUBDIR)/lto-plugin/Makefile || exit 0; \
+       $(HOST_EXPORTS) \
+       $(POSTSTAGE1_HOST_EXPORTS) \
+       CFLAGS="$(STAGE2_CFLAGS)"; export CFLAGS; \
+       CXXFLAGS="$(STAGE2_CFLAGS)"; export CXXFLAGS; \
+       LIBCFLAGS="$(STAGE2_CFLAGS)"; export LIBCFLAGS; \
+       echo Configuring stage 2 in $(HOST_SUBDIR)/lto-plugin ; \
+       $(SHELL) $(srcdir)/mkinstalldirs $(HOST_SUBDIR)/lto-plugin ; \
+       cd $(HOST_SUBDIR)/lto-plugin || exit 1; \
+       case $(srcdir) in \
+         /* | [A-Za-z]:[\\/]*) topdir=$(srcdir) ;; \
+         *) topdir=`echo $(HOST_SUBDIR)/lto-plugin/ | \
+               sed -e 's,\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \
+       esac; \
+       srcdiroption="--srcdir=$${topdir}/lto-plugin"; \
+       libsrcdir="$$s/lto-plugin"; \
+       $(SHELL) $${libsrcdir}/configure \
+         $(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
+         --target=${target_alias} $${srcdiroption} \
+         --with-build-libsubdir=$(HOST_SUBDIR) \
+         $(STAGE2_CONFIGURE_FLAGS)
+@endif lto-plugin-bootstrap
+
+.PHONY: configure-stage3-lto-plugin maybe-configure-stage3-lto-plugin
+maybe-configure-stage3-lto-plugin:
+@if lto-plugin-bootstrap
+maybe-configure-stage3-lto-plugin: configure-stage3-lto-plugin
+configure-stage3-lto-plugin:
+       @[ $(current_stage) = stage3 ] || $(MAKE) stage3-start
+       @$(SHELL) $(srcdir)/mkinstalldirs $(HOST_SUBDIR)/lto-plugin
+       @r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       TFLAGS="$(STAGE3_TFLAGS)"; \
+       test ! -f $(HOST_SUBDIR)/lto-plugin/Makefile || exit 0; \
+       $(HOST_EXPORTS) \
+       $(POSTSTAGE1_HOST_EXPORTS) \
+       CFLAGS="$(STAGE3_CFLAGS)"; export CFLAGS; \
+       CXXFLAGS="$(STAGE3_CFLAGS)"; export CXXFLAGS; \
+       LIBCFLAGS="$(STAGE3_CFLAGS)"; export LIBCFLAGS; \
+       echo Configuring stage 3 in $(HOST_SUBDIR)/lto-plugin ; \
+       $(SHELL) $(srcdir)/mkinstalldirs $(HOST_SUBDIR)/lto-plugin ; \
+       cd $(HOST_SUBDIR)/lto-plugin || exit 1; \
+       case $(srcdir) in \
+         /* | [A-Za-z]:[\\/]*) topdir=$(srcdir) ;; \
+         *) topdir=`echo $(HOST_SUBDIR)/lto-plugin/ | \
+               sed -e 's,\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \
+       esac; \
+       srcdiroption="--srcdir=$${topdir}/lto-plugin"; \
+       libsrcdir="$$s/lto-plugin"; \
+       $(SHELL) $${libsrcdir}/configure \
+         $(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
+         --target=${target_alias} $${srcdiroption} \
+         --with-build-libsubdir=$(HOST_SUBDIR) \
+         $(STAGE3_CONFIGURE_FLAGS)
+@endif lto-plugin-bootstrap
+
+.PHONY: configure-stage4-lto-plugin maybe-configure-stage4-lto-plugin
+maybe-configure-stage4-lto-plugin:
+@if lto-plugin-bootstrap
+maybe-configure-stage4-lto-plugin: configure-stage4-lto-plugin
+configure-stage4-lto-plugin:
+       @[ $(current_stage) = stage4 ] || $(MAKE) stage4-start
+       @$(SHELL) $(srcdir)/mkinstalldirs $(HOST_SUBDIR)/lto-plugin
+       @r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       TFLAGS="$(STAGE4_TFLAGS)"; \
+       test ! -f $(HOST_SUBDIR)/lto-plugin/Makefile || exit 0; \
+       $(HOST_EXPORTS) \
+       $(POSTSTAGE1_HOST_EXPORTS) \
+       CFLAGS="$(STAGE4_CFLAGS)"; export CFLAGS; \
+       CXXFLAGS="$(STAGE4_CFLAGS)"; export CXXFLAGS; \
+       LIBCFLAGS="$(STAGE4_CFLAGS)"; export LIBCFLAGS; \
+       echo Configuring stage 4 in $(HOST_SUBDIR)/lto-plugin ; \
+       $(SHELL) $(srcdir)/mkinstalldirs $(HOST_SUBDIR)/lto-plugin ; \
+       cd $(HOST_SUBDIR)/lto-plugin || exit 1; \
+       case $(srcdir) in \
+         /* | [A-Za-z]:[\\/]*) topdir=$(srcdir) ;; \
+         *) topdir=`echo $(HOST_SUBDIR)/lto-plugin/ | \
+               sed -e 's,\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \
+       esac; \
+       srcdiroption="--srcdir=$${topdir}/lto-plugin"; \
+       libsrcdir="$$s/lto-plugin"; \
+       $(SHELL) $${libsrcdir}/configure \
+         $(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
+         --target=${target_alias} $${srcdiroption} \
+         --with-build-libsubdir=$(HOST_SUBDIR) \
+         $(STAGE4_CONFIGURE_FLAGS)
+@endif lto-plugin-bootstrap
+
+.PHONY: configure-stageprofile-lto-plugin maybe-configure-stageprofile-lto-plugin
+maybe-configure-stageprofile-lto-plugin:
+@if lto-plugin-bootstrap
+maybe-configure-stageprofile-lto-plugin: configure-stageprofile-lto-plugin
+configure-stageprofile-lto-plugin:
+       @[ $(current_stage) = stageprofile ] || $(MAKE) stageprofile-start
+       @$(SHELL) $(srcdir)/mkinstalldirs $(HOST_SUBDIR)/lto-plugin
+       @r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       TFLAGS="$(STAGEprofile_TFLAGS)"; \
+       test ! -f $(HOST_SUBDIR)/lto-plugin/Makefile || exit 0; \
+       $(HOST_EXPORTS) \
+       $(POSTSTAGE1_HOST_EXPORTS) \
+       CFLAGS="$(STAGEprofile_CFLAGS)"; export CFLAGS; \
+       CXXFLAGS="$(STAGEprofile_CFLAGS)"; export CXXFLAGS; \
+       LIBCFLAGS="$(STAGEprofile_CFLAGS)"; export LIBCFLAGS; \
+       echo Configuring stage profile in $(HOST_SUBDIR)/lto-plugin ; \
+       $(SHELL) $(srcdir)/mkinstalldirs $(HOST_SUBDIR)/lto-plugin ; \
+       cd $(HOST_SUBDIR)/lto-plugin || exit 1; \
+       case $(srcdir) in \
+         /* | [A-Za-z]:[\\/]*) topdir=$(srcdir) ;; \
+         *) topdir=`echo $(HOST_SUBDIR)/lto-plugin/ | \
+               sed -e 's,\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \
+       esac; \
+       srcdiroption="--srcdir=$${topdir}/lto-plugin"; \
+       libsrcdir="$$s/lto-plugin"; \
+       $(SHELL) $${libsrcdir}/configure \
+         $(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
+         --target=${target_alias} $${srcdiroption} \
+         --with-build-libsubdir=$(HOST_SUBDIR) \
+         $(STAGEprofile_CONFIGURE_FLAGS)
+@endif lto-plugin-bootstrap
+
+.PHONY: configure-stagefeedback-lto-plugin maybe-configure-stagefeedback-lto-plugin
+maybe-configure-stagefeedback-lto-plugin:
+@if lto-plugin-bootstrap
+maybe-configure-stagefeedback-lto-plugin: configure-stagefeedback-lto-plugin
+configure-stagefeedback-lto-plugin:
+       @[ $(current_stage) = stagefeedback ] || $(MAKE) stagefeedback-start
+       @$(SHELL) $(srcdir)/mkinstalldirs $(HOST_SUBDIR)/lto-plugin
+       @r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       TFLAGS="$(STAGEfeedback_TFLAGS)"; \
+       test ! -f $(HOST_SUBDIR)/lto-plugin/Makefile || exit 0; \
+       $(HOST_EXPORTS) \
+       $(POSTSTAGE1_HOST_EXPORTS) \
+       CFLAGS="$(STAGEfeedback_CFLAGS)"; export CFLAGS; \
+       CXXFLAGS="$(STAGEfeedback_CFLAGS)"; export CXXFLAGS; \
+       LIBCFLAGS="$(STAGEfeedback_CFLAGS)"; export LIBCFLAGS; \
+       echo Configuring stage feedback in $(HOST_SUBDIR)/lto-plugin ; \
+       $(SHELL) $(srcdir)/mkinstalldirs $(HOST_SUBDIR)/lto-plugin ; \
+       cd $(HOST_SUBDIR)/lto-plugin || exit 1; \
+       case $(srcdir) in \
+         /* | [A-Za-z]:[\\/]*) topdir=$(srcdir) ;; \
+         *) topdir=`echo $(HOST_SUBDIR)/lto-plugin/ | \
+               sed -e 's,\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \
+       esac; \
+       srcdiroption="--srcdir=$${topdir}/lto-plugin"; \
+       libsrcdir="$$s/lto-plugin"; \
+       $(SHELL) $${libsrcdir}/configure \
+         $(HOST_CONFIGARGS) --build=${build_alias} --host=${host_alias} \
+         --target=${target_alias} $${srcdiroption} \
+         --with-build-libsubdir=$(HOST_SUBDIR) \
+         $(STAGEfeedback_CONFIGURE_FLAGS)
+@endif lto-plugin-bootstrap
+
+
+
+
+
+.PHONY: all-lto-plugin maybe-all-lto-plugin
+maybe-all-lto-plugin:
+@if gcc-bootstrap
+all-lto-plugin: stage_current
+@endif gcc-bootstrap
+@if lto-plugin
+TARGET-lto-plugin=all
+maybe-all-lto-plugin: all-lto-plugin
+all-lto-plugin: configure-lto-plugin
+       @r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       $(HOST_EXPORTS) \
+       (cd $(HOST_SUBDIR)/lto-plugin && \
+         $(MAKE) $(BASE_FLAGS_TO_PASS) $(EXTRA_HOST_FLAGS)  \
+               $(TARGET-lto-plugin))
+@endif lto-plugin
+
+
+
+.PHONY: all-stage1-lto-plugin maybe-all-stage1-lto-plugin
+.PHONY: clean-stage1-lto-plugin maybe-clean-stage1-lto-plugin
+maybe-all-stage1-lto-plugin:
+maybe-clean-stage1-lto-plugin:
+@if lto-plugin-bootstrap
+maybe-all-stage1-lto-plugin: all-stage1-lto-plugin
+all-stage1: all-stage1-lto-plugin
+TARGET-stage1-lto-plugin = $(TARGET-lto-plugin)
+all-stage1-lto-plugin: configure-stage1-lto-plugin
+       @[ $(current_stage) = stage1 ] || $(MAKE) stage1-start
+       @r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       TFLAGS="$(STAGE1_TFLAGS)"; \
+       $(HOST_EXPORTS) \
+       cd $(HOST_SUBDIR)/lto-plugin && \
+       $(MAKE) $(BASE_FLAGS_TO_PASS) \
+               CFLAGS="$(STAGE1_CFLAGS)" \
+               CXXFLAGS="$(STAGE1_CFLAGS)" \
+               LIBCFLAGS="$(LIBCFLAGS)" \
+               CFLAGS_FOR_TARGET="$(CFLAGS_FOR_TARGET)" \
+               CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" \
+               LIBCFLAGS_FOR_TARGET="$(LIBCFLAGS_FOR_TARGET)" \
+               $(EXTRA_HOST_FLAGS)   \
+               TFLAGS="$(STAGE1_TFLAGS)" \
+               $(TARGET-stage1-lto-plugin)
+
+maybe-clean-stage1-lto-plugin: clean-stage1-lto-plugin
+clean-stage1: clean-stage1-lto-plugin
+clean-stage1-lto-plugin:
+       @if [ $(current_stage) = stage1 ]; then \
+         [ -f $(HOST_SUBDIR)/lto-plugin/Makefile ] || exit 0; \
+       else \
+         [ -f $(HOST_SUBDIR)/stage1-lto-plugin/Makefile ] || exit 0; \
+         $(MAKE) stage1-start; \
+       fi; \
+       cd $(HOST_SUBDIR)/lto-plugin && \
+       $(MAKE) $(EXTRA_HOST_FLAGS)  \
+                clean
+@endif lto-plugin-bootstrap
+
+
+.PHONY: all-stage2-lto-plugin maybe-all-stage2-lto-plugin
+.PHONY: clean-stage2-lto-plugin maybe-clean-stage2-lto-plugin
+maybe-all-stage2-lto-plugin:
+maybe-clean-stage2-lto-plugin:
+@if lto-plugin-bootstrap
+maybe-all-stage2-lto-plugin: all-stage2-lto-plugin
+all-stage2: all-stage2-lto-plugin
+TARGET-stage2-lto-plugin = $(TARGET-lto-plugin)
+all-stage2-lto-plugin: configure-stage2-lto-plugin
+       @[ $(current_stage) = stage2 ] || $(MAKE) stage2-start
+       @r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       TFLAGS="$(STAGE2_TFLAGS)"; \
+       $(HOST_EXPORTS) \
+       $(POSTSTAGE1_HOST_EXPORTS) \
+       cd $(HOST_SUBDIR)/lto-plugin && \
+       $(MAKE) $(BASE_FLAGS_TO_PASS) \
+               CFLAGS="$(STAGE2_CFLAGS)" \
+               CXXFLAGS="$(STAGE2_CFLAGS)" \
+               LIBCFLAGS="$(STAGE2_CFLAGS)" \
+               CFLAGS_FOR_TARGET="$(CFLAGS_FOR_TARGET)" \
+               CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" \
+               LIBCFLAGS_FOR_TARGET="$(LIBCFLAGS_FOR_TARGET)" \
+               $(EXTRA_HOST_FLAGS) $(POSTSTAGE1_FLAGS_TO_PASS)  \
+               TFLAGS="$(STAGE2_TFLAGS)" \
+               $(TARGET-stage2-lto-plugin)
+
+maybe-clean-stage2-lto-plugin: clean-stage2-lto-plugin
+clean-stage2: clean-stage2-lto-plugin
+clean-stage2-lto-plugin:
+       @if [ $(current_stage) = stage2 ]; then \
+         [ -f $(HOST_SUBDIR)/lto-plugin/Makefile ] || exit 0; \
+       else \
+         [ -f $(HOST_SUBDIR)/stage2-lto-plugin/Makefile ] || exit 0; \
+         $(MAKE) stage2-start; \
+       fi; \
+       cd $(HOST_SUBDIR)/lto-plugin && \
+       $(MAKE) $(EXTRA_HOST_FLAGS)  \
+               $(POSTSTAGE1_FLAGS_TO_PASS)  \
+                clean
+@endif lto-plugin-bootstrap
+
+
+.PHONY: all-stage3-lto-plugin maybe-all-stage3-lto-plugin
+.PHONY: clean-stage3-lto-plugin maybe-clean-stage3-lto-plugin
+maybe-all-stage3-lto-plugin:
+maybe-clean-stage3-lto-plugin:
+@if lto-plugin-bootstrap
+maybe-all-stage3-lto-plugin: all-stage3-lto-plugin
+all-stage3: all-stage3-lto-plugin
+TARGET-stage3-lto-plugin = $(TARGET-lto-plugin)
+all-stage3-lto-plugin: configure-stage3-lto-plugin
+       @[ $(current_stage) = stage3 ] || $(MAKE) stage3-start
+       @r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       TFLAGS="$(STAGE3_TFLAGS)"; \
+       $(HOST_EXPORTS) \
+       $(POSTSTAGE1_HOST_EXPORTS) \
+       cd $(HOST_SUBDIR)/lto-plugin && \
+       $(MAKE) $(BASE_FLAGS_TO_PASS) \
+               CFLAGS="$(STAGE3_CFLAGS)" \
+               CXXFLAGS="$(STAGE3_CFLAGS)" \
+               LIBCFLAGS="$(STAGE3_CFLAGS)" \
+               CFLAGS_FOR_TARGET="$(CFLAGS_FOR_TARGET)" \
+               CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" \
+               LIBCFLAGS_FOR_TARGET="$(LIBCFLAGS_FOR_TARGET)" \
+               $(EXTRA_HOST_FLAGS) $(POSTSTAGE1_FLAGS_TO_PASS)  \
+               TFLAGS="$(STAGE3_TFLAGS)" \
+               $(TARGET-stage3-lto-plugin)
+
+maybe-clean-stage3-lto-plugin: clean-stage3-lto-plugin
+clean-stage3: clean-stage3-lto-plugin
+clean-stage3-lto-plugin:
+       @if [ $(current_stage) = stage3 ]; then \
+         [ -f $(HOST_SUBDIR)/lto-plugin/Makefile ] || exit 0; \
+       else \
+         [ -f $(HOST_SUBDIR)/stage3-lto-plugin/Makefile ] || exit 0; \
+         $(MAKE) stage3-start; \
+       fi; \
+       cd $(HOST_SUBDIR)/lto-plugin && \
+       $(MAKE) $(EXTRA_HOST_FLAGS)  \
+               $(POSTSTAGE1_FLAGS_TO_PASS)  \
+                clean
+@endif lto-plugin-bootstrap
+
+
+.PHONY: all-stage4-lto-plugin maybe-all-stage4-lto-plugin
+.PHONY: clean-stage4-lto-plugin maybe-clean-stage4-lto-plugin
+maybe-all-stage4-lto-plugin:
+maybe-clean-stage4-lto-plugin:
+@if lto-plugin-bootstrap
+maybe-all-stage4-lto-plugin: all-stage4-lto-plugin
+all-stage4: all-stage4-lto-plugin
+TARGET-stage4-lto-plugin = $(TARGET-lto-plugin)
+all-stage4-lto-plugin: configure-stage4-lto-plugin
+       @[ $(current_stage) = stage4 ] || $(MAKE) stage4-start
+       @r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       TFLAGS="$(STAGE4_TFLAGS)"; \
+       $(HOST_EXPORTS) \
+       $(POSTSTAGE1_HOST_EXPORTS) \
+       cd $(HOST_SUBDIR)/lto-plugin && \
+       $(MAKE) $(BASE_FLAGS_TO_PASS) \
+               CFLAGS="$(STAGE4_CFLAGS)" \
+               CXXFLAGS="$(STAGE4_CFLAGS)" \
+               LIBCFLAGS="$(STAGE4_CFLAGS)" \
+               CFLAGS_FOR_TARGET="$(CFLAGS_FOR_TARGET)" \
+               CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" \
+               LIBCFLAGS_FOR_TARGET="$(LIBCFLAGS_FOR_TARGET)" \
+               $(EXTRA_HOST_FLAGS) $(POSTSTAGE1_FLAGS_TO_PASS)  \
+               TFLAGS="$(STAGE4_TFLAGS)" \
+               $(TARGET-stage4-lto-plugin)
+
+maybe-clean-stage4-lto-plugin: clean-stage4-lto-plugin
+clean-stage4: clean-stage4-lto-plugin
+clean-stage4-lto-plugin:
+       @if [ $(current_stage) = stage4 ]; then \
+         [ -f $(HOST_SUBDIR)/lto-plugin/Makefile ] || exit 0; \
+       else \
+         [ -f $(HOST_SUBDIR)/stage4-lto-plugin/Makefile ] || exit 0; \
+         $(MAKE) stage4-start; \
+       fi; \
+       cd $(HOST_SUBDIR)/lto-plugin && \
+       $(MAKE) $(EXTRA_HOST_FLAGS)  \
+               $(POSTSTAGE1_FLAGS_TO_PASS)  \
+                clean
+@endif lto-plugin-bootstrap
+
+
+.PHONY: all-stageprofile-lto-plugin maybe-all-stageprofile-lto-plugin
+.PHONY: clean-stageprofile-lto-plugin maybe-clean-stageprofile-lto-plugin
+maybe-all-stageprofile-lto-plugin:
+maybe-clean-stageprofile-lto-plugin:
+@if lto-plugin-bootstrap
+maybe-all-stageprofile-lto-plugin: all-stageprofile-lto-plugin
+all-stageprofile: all-stageprofile-lto-plugin
+TARGET-stageprofile-lto-plugin = $(TARGET-lto-plugin)
+all-stageprofile-lto-plugin: configure-stageprofile-lto-plugin
+       @[ $(current_stage) = stageprofile ] || $(MAKE) stageprofile-start
+       @r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       TFLAGS="$(STAGEprofile_TFLAGS)"; \
+       $(HOST_EXPORTS) \
+       $(POSTSTAGE1_HOST_EXPORTS) \
+       cd $(HOST_SUBDIR)/lto-plugin && \
+       $(MAKE) $(BASE_FLAGS_TO_PASS) \
+               CFLAGS="$(STAGEprofile_CFLAGS)" \
+               CXXFLAGS="$(STAGEprofile_CFLAGS)" \
+               LIBCFLAGS="$(STAGEprofile_CFLAGS)" \
+               CFLAGS_FOR_TARGET="$(CFLAGS_FOR_TARGET)" \
+               CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" \
+               LIBCFLAGS_FOR_TARGET="$(LIBCFLAGS_FOR_TARGET)" \
+               $(EXTRA_HOST_FLAGS) $(POSTSTAGE1_FLAGS_TO_PASS)  \
+               TFLAGS="$(STAGEprofile_TFLAGS)" \
+               $(TARGET-stageprofile-lto-plugin)
+
+maybe-clean-stageprofile-lto-plugin: clean-stageprofile-lto-plugin
+clean-stageprofile: clean-stageprofile-lto-plugin
+clean-stageprofile-lto-plugin:
+       @if [ $(current_stage) = stageprofile ]; then \
+         [ -f $(HOST_SUBDIR)/lto-plugin/Makefile ] || exit 0; \
+       else \
+         [ -f $(HOST_SUBDIR)/stageprofile-lto-plugin/Makefile ] || exit 0; \
+         $(MAKE) stageprofile-start; \
+       fi; \
+       cd $(HOST_SUBDIR)/lto-plugin && \
+       $(MAKE) $(EXTRA_HOST_FLAGS)  \
+               $(POSTSTAGE1_FLAGS_TO_PASS)  \
+                clean
+@endif lto-plugin-bootstrap
+
+
+.PHONY: all-stagefeedback-lto-plugin maybe-all-stagefeedback-lto-plugin
+.PHONY: clean-stagefeedback-lto-plugin maybe-clean-stagefeedback-lto-plugin
+maybe-all-stagefeedback-lto-plugin:
+maybe-clean-stagefeedback-lto-plugin:
+@if lto-plugin-bootstrap
+maybe-all-stagefeedback-lto-plugin: all-stagefeedback-lto-plugin
+all-stagefeedback: all-stagefeedback-lto-plugin
+TARGET-stagefeedback-lto-plugin = $(TARGET-lto-plugin)
+all-stagefeedback-lto-plugin: configure-stagefeedback-lto-plugin
+       @[ $(current_stage) = stagefeedback ] || $(MAKE) stagefeedback-start
+       @r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       TFLAGS="$(STAGEfeedback_TFLAGS)"; \
+       $(HOST_EXPORTS) \
+       $(POSTSTAGE1_HOST_EXPORTS) \
+       cd $(HOST_SUBDIR)/lto-plugin && \
+       $(MAKE) $(BASE_FLAGS_TO_PASS) \
+               CFLAGS="$(STAGEfeedback_CFLAGS)" \
+               CXXFLAGS="$(STAGEfeedback_CFLAGS)" \
+               LIBCFLAGS="$(STAGEfeedback_CFLAGS)" \
+               CFLAGS_FOR_TARGET="$(CFLAGS_FOR_TARGET)" \
+               CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" \
+               LIBCFLAGS_FOR_TARGET="$(LIBCFLAGS_FOR_TARGET)" \
+               $(EXTRA_HOST_FLAGS) $(POSTSTAGE1_FLAGS_TO_PASS)  \
+               TFLAGS="$(STAGEfeedback_TFLAGS)" \
+               $(TARGET-stagefeedback-lto-plugin)
+
+maybe-clean-stagefeedback-lto-plugin: clean-stagefeedback-lto-plugin
+clean-stagefeedback: clean-stagefeedback-lto-plugin
+clean-stagefeedback-lto-plugin:
+       @if [ $(current_stage) = stagefeedback ]; then \
+         [ -f $(HOST_SUBDIR)/lto-plugin/Makefile ] || exit 0; \
+       else \
+         [ -f $(HOST_SUBDIR)/stagefeedback-lto-plugin/Makefile ] || exit 0; \
+         $(MAKE) stagefeedback-start; \
+       fi; \
+       cd $(HOST_SUBDIR)/lto-plugin && \
+       $(MAKE) $(EXTRA_HOST_FLAGS)  \
+               $(POSTSTAGE1_FLAGS_TO_PASS)  \
+                clean
+@endif lto-plugin-bootstrap
+
+
+
+
+
+.PHONY: check-lto-plugin maybe-check-lto-plugin
+maybe-check-lto-plugin:
+@if lto-plugin
+maybe-check-lto-plugin: check-lto-plugin
+
+check-lto-plugin:
+       @: $(MAKE); $(unstage)
+       @r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       $(HOST_EXPORTS) \
+       (cd $(HOST_SUBDIR)/lto-plugin && \
+         $(MAKE) $(FLAGS_TO_PASS)  check)
+
+@endif lto-plugin
+
+.PHONY: install-lto-plugin maybe-install-lto-plugin
+maybe-install-lto-plugin:
+@if lto-plugin
+maybe-install-lto-plugin: install-lto-plugin
+
+install-lto-plugin: installdirs
+       @: $(MAKE); $(unstage)
+       @r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       $(HOST_EXPORTS) \
+       (cd $(HOST_SUBDIR)/lto-plugin && \
+         $(MAKE) $(FLAGS_TO_PASS)  install)
+
+@endif lto-plugin
+
+# Other targets (info, dvi, pdf, etc.)
+
+.PHONY: maybe-info-lto-plugin info-lto-plugin
+maybe-info-lto-plugin:
+@if lto-plugin
+maybe-info-lto-plugin: info-lto-plugin
+
+info-lto-plugin: \
+    configure-lto-plugin 
+       @[ -f ./lto-plugin/Makefile ] || exit 0; \
+       r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       $(HOST_EXPORTS) \
+       for flag in $(EXTRA_HOST_FLAGS) ; do \
+         eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+       done; \
+       echo "Doing info in lto-plugin" ; \
+       (cd $(HOST_SUBDIR)/lto-plugin && \
+         $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+                 "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+                 "RANLIB=$${RANLIB}" \
+                 "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+                 info) \
+         || exit 1
+
+@endif lto-plugin
+
+.PHONY: maybe-dvi-lto-plugin dvi-lto-plugin
+maybe-dvi-lto-plugin:
+@if lto-plugin
+maybe-dvi-lto-plugin: dvi-lto-plugin
+
+dvi-lto-plugin: \
+    configure-lto-plugin 
+       @[ -f ./lto-plugin/Makefile ] || exit 0; \
+       r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       $(HOST_EXPORTS) \
+       for flag in $(EXTRA_HOST_FLAGS) ; do \
+         eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+       done; \
+       echo "Doing dvi in lto-plugin" ; \
+       (cd $(HOST_SUBDIR)/lto-plugin && \
+         $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+                 "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+                 "RANLIB=$${RANLIB}" \
+                 "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+                 dvi) \
+         || exit 1
+
+@endif lto-plugin
+
+.PHONY: maybe-pdf-lto-plugin pdf-lto-plugin
+maybe-pdf-lto-plugin:
+@if lto-plugin
+maybe-pdf-lto-plugin: pdf-lto-plugin
+
+pdf-lto-plugin: \
+    configure-lto-plugin 
+       @[ -f ./lto-plugin/Makefile ] || exit 0; \
+       r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       $(HOST_EXPORTS) \
+       for flag in $(EXTRA_HOST_FLAGS) ; do \
+         eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+       done; \
+       echo "Doing pdf in lto-plugin" ; \
+       (cd $(HOST_SUBDIR)/lto-plugin && \
+         $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+                 "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+                 "RANLIB=$${RANLIB}" \
+                 "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+                 pdf) \
+         || exit 1
+
+@endif lto-plugin
+
+.PHONY: maybe-html-lto-plugin html-lto-plugin
+maybe-html-lto-plugin:
+@if lto-plugin
+maybe-html-lto-plugin: html-lto-plugin
+
+html-lto-plugin: \
+    configure-lto-plugin 
+       @[ -f ./lto-plugin/Makefile ] || exit 0; \
+       r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       $(HOST_EXPORTS) \
+       for flag in $(EXTRA_HOST_FLAGS) ; do \
+         eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+       done; \
+       echo "Doing html in lto-plugin" ; \
+       (cd $(HOST_SUBDIR)/lto-plugin && \
+         $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+                 "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+                 "RANLIB=$${RANLIB}" \
+                 "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+                 html) \
+         || exit 1
+
+@endif lto-plugin
+
+.PHONY: maybe-TAGS-lto-plugin TAGS-lto-plugin
+maybe-TAGS-lto-plugin:
+@if lto-plugin
+maybe-TAGS-lto-plugin: TAGS-lto-plugin
+
+TAGS-lto-plugin: \
+    configure-lto-plugin 
+       @[ -f ./lto-plugin/Makefile ] || exit 0; \
+       r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       $(HOST_EXPORTS) \
+       for flag in $(EXTRA_HOST_FLAGS) ; do \
+         eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+       done; \
+       echo "Doing TAGS in lto-plugin" ; \
+       (cd $(HOST_SUBDIR)/lto-plugin && \
+         $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+                 "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+                 "RANLIB=$${RANLIB}" \
+                 "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+                 TAGS) \
+         || exit 1
+
+@endif lto-plugin
+
+.PHONY: maybe-install-info-lto-plugin install-info-lto-plugin
+maybe-install-info-lto-plugin:
+@if lto-plugin
+maybe-install-info-lto-plugin: install-info-lto-plugin
+
+install-info-lto-plugin: \
+    configure-lto-plugin \
+    info-lto-plugin 
+       @[ -f ./lto-plugin/Makefile ] || exit 0; \
+       r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       $(HOST_EXPORTS) \
+       for flag in $(EXTRA_HOST_FLAGS) ; do \
+         eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+       done; \
+       echo "Doing install-info in lto-plugin" ; \
+       (cd $(HOST_SUBDIR)/lto-plugin && \
+         $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+                 "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+                 "RANLIB=$${RANLIB}" \
+                 "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+                 install-info) \
+         || exit 1
+
+@endif lto-plugin
+
+.PHONY: maybe-install-pdf-lto-plugin install-pdf-lto-plugin
+maybe-install-pdf-lto-plugin:
+@if lto-plugin
+maybe-install-pdf-lto-plugin: install-pdf-lto-plugin
+
+install-pdf-lto-plugin: \
+    configure-lto-plugin \
+    pdf-lto-plugin 
+       @[ -f ./lto-plugin/Makefile ] || exit 0; \
+       r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       $(HOST_EXPORTS) \
+       for flag in $(EXTRA_HOST_FLAGS) ; do \
+         eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+       done; \
+       echo "Doing install-pdf in lto-plugin" ; \
+       (cd $(HOST_SUBDIR)/lto-plugin && \
+         $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+                 "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+                 "RANLIB=$${RANLIB}" \
+                 "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+                 install-pdf) \
+         || exit 1
+
+@endif lto-plugin
+
+.PHONY: maybe-install-html-lto-plugin install-html-lto-plugin
+maybe-install-html-lto-plugin:
+@if lto-plugin
+maybe-install-html-lto-plugin: install-html-lto-plugin
+
+install-html-lto-plugin: \
+    configure-lto-plugin \
+    html-lto-plugin 
+       @[ -f ./lto-plugin/Makefile ] || exit 0; \
+       r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       $(HOST_EXPORTS) \
+       for flag in $(EXTRA_HOST_FLAGS) ; do \
+         eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+       done; \
+       echo "Doing install-html in lto-plugin" ; \
+       (cd $(HOST_SUBDIR)/lto-plugin && \
+         $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+                 "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+                 "RANLIB=$${RANLIB}" \
+                 "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+                 install-html) \
+         || exit 1
+
+@endif lto-plugin
+
+.PHONY: maybe-installcheck-lto-plugin installcheck-lto-plugin
+maybe-installcheck-lto-plugin:
+@if lto-plugin
+maybe-installcheck-lto-plugin: installcheck-lto-plugin
+
+installcheck-lto-plugin: \
+    configure-lto-plugin 
+       @[ -f ./lto-plugin/Makefile ] || exit 0; \
+       r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       $(HOST_EXPORTS) \
+       for flag in $(EXTRA_HOST_FLAGS) ; do \
+         eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+       done; \
+       echo "Doing installcheck in lto-plugin" ; \
+       (cd $(HOST_SUBDIR)/lto-plugin && \
+         $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+                 "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+                 "RANLIB=$${RANLIB}" \
+                 "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+                 installcheck) \
+         || exit 1
+
+@endif lto-plugin
+
+.PHONY: maybe-mostlyclean-lto-plugin mostlyclean-lto-plugin
+maybe-mostlyclean-lto-plugin:
+@if lto-plugin
+maybe-mostlyclean-lto-plugin: mostlyclean-lto-plugin
+
+mostlyclean-lto-plugin: 
+       @[ -f ./lto-plugin/Makefile ] || exit 0; \
+       r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       $(HOST_EXPORTS) \
+       for flag in $(EXTRA_HOST_FLAGS) ; do \
+         eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+       done; \
+       echo "Doing mostlyclean in lto-plugin" ; \
+       (cd $(HOST_SUBDIR)/lto-plugin && \
+         $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+                 "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+                 "RANLIB=$${RANLIB}" \
+                 "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+                 mostlyclean) \
+         || exit 1
+
+@endif lto-plugin
+
+.PHONY: maybe-clean-lto-plugin clean-lto-plugin
+maybe-clean-lto-plugin:
+@if lto-plugin
+maybe-clean-lto-plugin: clean-lto-plugin
+
+clean-lto-plugin: 
+       @[ -f ./lto-plugin/Makefile ] || exit 0; \
+       r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       $(HOST_EXPORTS) \
+       for flag in $(EXTRA_HOST_FLAGS) ; do \
+         eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+       done; \
+       echo "Doing clean in lto-plugin" ; \
+       (cd $(HOST_SUBDIR)/lto-plugin && \
+         $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+                 "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+                 "RANLIB=$${RANLIB}" \
+                 "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+                 clean) \
+         || exit 1
+
+@endif lto-plugin
+
+.PHONY: maybe-distclean-lto-plugin distclean-lto-plugin
+maybe-distclean-lto-plugin:
+@if lto-plugin
+maybe-distclean-lto-plugin: distclean-lto-plugin
+
+distclean-lto-plugin: 
+       @[ -f ./lto-plugin/Makefile ] || exit 0; \
+       r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       $(HOST_EXPORTS) \
+       for flag in $(EXTRA_HOST_FLAGS) ; do \
+         eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+       done; \
+       echo "Doing distclean in lto-plugin" ; \
+       (cd $(HOST_SUBDIR)/lto-plugin && \
+         $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+                 "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+                 "RANLIB=$${RANLIB}" \
+                 "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+                 distclean) \
+         || exit 1
+
+@endif lto-plugin
+
+.PHONY: maybe-maintainer-clean-lto-plugin maintainer-clean-lto-plugin
+maybe-maintainer-clean-lto-plugin:
+@if lto-plugin
+maybe-maintainer-clean-lto-plugin: maintainer-clean-lto-plugin
+
+maintainer-clean-lto-plugin: 
+       @[ -f ./lto-plugin/Makefile ] || exit 0; \
+       r=`${PWD_COMMAND}`; export r; \
+       s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+       $(HOST_EXPORTS) \
+       for flag in $(EXTRA_HOST_FLAGS) ; do \
+         eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+       done; \
+       echo "Doing maintainer-clean in lto-plugin" ; \
+       (cd $(HOST_SUBDIR)/lto-plugin && \
+         $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+                 "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+                 "RANLIB=$${RANLIB}" \
+                 "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+                 maintainer-clean) \
+         || exit 1
+
+@endif lto-plugin
+
+
+
 # ---------------------------------------
 # Modules which run on the target machine
 # ---------------------------------------
@@ -53466,6 +54364,11 @@ stage1-start::
          mkdir stage1-zlib; \
        mv stage1-zlib zlib 
 @endif zlib
+@if lto-plugin
+       @cd $(HOST_SUBDIR); [ -d stage1-lto-plugin ] || \
+         mkdir stage1-lto-plugin; \
+       mv stage1-lto-plugin lto-plugin 
+@endif lto-plugin
        @[ -d stage1-$(TARGET_SUBDIR) ] || \
          mkdir stage1-$(TARGET_SUBDIR); \
        mv stage1-$(TARGET_SUBDIR) $(TARGET_SUBDIR) 
@@ -53556,6 +54459,11 @@ stage1-end::
          cd $(HOST_SUBDIR); mv zlib stage1-zlib  ; \
        fi
 @endif zlib
+@if lto-plugin
+       @if test -d $(HOST_SUBDIR)/lto-plugin ; then \
+         cd $(HOST_SUBDIR); mv lto-plugin stage1-lto-plugin  ; \
+       fi
+@endif lto-plugin
        @if test -d $(TARGET_SUBDIR) ; then \
          mv $(TARGET_SUBDIR) stage1-$(TARGET_SUBDIR)  ; \
        fi
@@ -53706,6 +54614,12 @@ stage2-start::
        mv stage2-zlib zlib  ; \
        mv stage1-zlib prev-zlib || test -f stage1-lean 
 @endif zlib
+@if lto-plugin
+       @cd $(HOST_SUBDIR); [ -d stage2-lto-plugin ] || \
+         mkdir stage2-lto-plugin; \
+       mv stage2-lto-plugin lto-plugin  ; \
+       mv stage1-lto-plugin prev-lto-plugin || test -f stage1-lean 
+@endif lto-plugin
        @[ -d stage2-$(TARGET_SUBDIR) ] || \
          mkdir stage2-$(TARGET_SUBDIR); \
        mv stage2-$(TARGET_SUBDIR) $(TARGET_SUBDIR)  ; \
@@ -53814,6 +54728,12 @@ stage2-end::
          mv prev-zlib stage1-zlib ; :  ; \
        fi
 @endif zlib
+@if lto-plugin
+       @if test -d $(HOST_SUBDIR)/lto-plugin ; then \
+         cd $(HOST_SUBDIR); mv lto-plugin stage2-lto-plugin ; \
+         mv prev-lto-plugin stage1-lto-plugin ; :  ; \
+       fi
+@endif lto-plugin
        @if test -d $(TARGET_SUBDIR) ; then \
          mv $(TARGET_SUBDIR) stage2-$(TARGET_SUBDIR)  ; \
          mv prev-$(TARGET_SUBDIR) stage1-$(TARGET_SUBDIR) ; :  ; \
@@ -53988,6 +54908,12 @@ stage3-start::
        mv stage3-zlib zlib  ; \
        mv stage2-zlib prev-zlib || test -f stage2-lean 
 @endif zlib
+@if lto-plugin
+       @cd $(HOST_SUBDIR); [ -d stage3-lto-plugin ] || \
+         mkdir stage3-lto-plugin; \
+       mv stage3-lto-plugin lto-plugin  ; \
+       mv stage2-lto-plugin prev-lto-plugin || test -f stage2-lean 
+@endif lto-plugin
        @[ -d stage3-$(TARGET_SUBDIR) ] || \
          mkdir stage3-$(TARGET_SUBDIR); \
        mv stage3-$(TARGET_SUBDIR) $(TARGET_SUBDIR)  ; \
@@ -54096,6 +55022,12 @@ stage3-end::
          mv prev-zlib stage2-zlib ; :  ; \
        fi
 @endif zlib
+@if lto-plugin
+       @if test -d $(HOST_SUBDIR)/lto-plugin ; then \
+         cd $(HOST_SUBDIR); mv lto-plugin stage3-lto-plugin ; \
+         mv prev-lto-plugin stage2-lto-plugin ; :  ; \
+       fi
+@endif lto-plugin
        @if test -d $(TARGET_SUBDIR) ; then \
          mv $(TARGET_SUBDIR) stage3-$(TARGET_SUBDIR)  ; \
          mv prev-$(TARGET_SUBDIR) stage2-$(TARGET_SUBDIR) ; :  ; \
@@ -54326,6 +55258,12 @@ stage4-start::
        mv stage4-zlib zlib  ; \
        mv stage3-zlib prev-zlib || test -f stage3-lean 
 @endif zlib
+@if lto-plugin
+       @cd $(HOST_SUBDIR); [ -d stage4-lto-plugin ] || \
+         mkdir stage4-lto-plugin; \
+       mv stage4-lto-plugin lto-plugin  ; \
+       mv stage3-lto-plugin prev-lto-plugin || test -f stage3-lean 
+@endif lto-plugin
        @[ -d stage4-$(TARGET_SUBDIR) ] || \
          mkdir stage4-$(TARGET_SUBDIR); \
        mv stage4-$(TARGET_SUBDIR) $(TARGET_SUBDIR)  ; \
@@ -54434,6 +55372,12 @@ stage4-end::
          mv prev-zlib stage3-zlib ; :  ; \
        fi
 @endif zlib
+@if lto-plugin
+       @if test -d $(HOST_SUBDIR)/lto-plugin ; then \
+         cd $(HOST_SUBDIR); mv lto-plugin stage4-lto-plugin ; \
+         mv prev-lto-plugin stage3-lto-plugin ; :  ; \
+       fi
+@endif lto-plugin
        @if test -d $(TARGET_SUBDIR) ; then \
          mv $(TARGET_SUBDIR) stage4-$(TARGET_SUBDIR)  ; \
          mv prev-$(TARGET_SUBDIR) stage3-$(TARGET_SUBDIR) ; :  ; \
@@ -54652,6 +55596,12 @@ stageprofile-start::
        mv stageprofile-zlib zlib  ; \
        mv stage1-zlib prev-zlib || test -f stage1-lean 
 @endif zlib
+@if lto-plugin
+       @cd $(HOST_SUBDIR); [ -d stageprofile-lto-plugin ] || \
+         mkdir stageprofile-lto-plugin; \
+       mv stageprofile-lto-plugin lto-plugin  ; \
+       mv stage1-lto-plugin prev-lto-plugin || test -f stage1-lean 
+@endif lto-plugin
        @[ -d stageprofile-$(TARGET_SUBDIR) ] || \
          mkdir stageprofile-$(TARGET_SUBDIR); \
        mv stageprofile-$(TARGET_SUBDIR) $(TARGET_SUBDIR)  ; \
@@ -54760,6 +55710,12 @@ stageprofile-end::
          mv prev-zlib stage1-zlib ; :  ; \
        fi
 @endif zlib
+@if lto-plugin
+       @if test -d $(HOST_SUBDIR)/lto-plugin ; then \
+         cd $(HOST_SUBDIR); mv lto-plugin stageprofile-lto-plugin ; \
+         mv prev-lto-plugin stage1-lto-plugin ; :  ; \
+       fi
+@endif lto-plugin
        @if test -d $(TARGET_SUBDIR) ; then \
          mv $(TARGET_SUBDIR) stageprofile-$(TARGET_SUBDIR)  ; \
          mv prev-$(TARGET_SUBDIR) stage1-$(TARGET_SUBDIR) ; :  ; \
@@ -54911,6 +55867,12 @@ stagefeedback-start::
        mv stagefeedback-zlib zlib  ; \
        mv stageprofile-zlib prev-zlib || test -f stageprofile-lean 
 @endif zlib
+@if lto-plugin
+       @cd $(HOST_SUBDIR); [ -d stagefeedback-lto-plugin ] || \
+         mkdir stagefeedback-lto-plugin; \
+       mv stagefeedback-lto-plugin lto-plugin  ; \
+       mv stageprofile-lto-plugin prev-lto-plugin || test -f stageprofile-lean 
+@endif lto-plugin
        @[ -d stagefeedback-$(TARGET_SUBDIR) ] || \
          mkdir stagefeedback-$(TARGET_SUBDIR); \
        mv stagefeedback-$(TARGET_SUBDIR) $(TARGET_SUBDIR)  ; \
@@ -55019,6 +55981,12 @@ stagefeedback-end::
          mv prev-zlib stageprofile-zlib ; :  ; \
        fi
 @endif zlib
+@if lto-plugin
+       @if test -d $(HOST_SUBDIR)/lto-plugin ; then \
+         cd $(HOST_SUBDIR); mv lto-plugin stagefeedback-lto-plugin ; \
+         mv prev-lto-plugin stageprofile-lto-plugin ; :  ; \
+       fi
+@endif lto-plugin
        @if test -d $(TARGET_SUBDIR) ; then \
          mv $(TARGET_SUBDIR) stagefeedback-$(TARGET_SUBDIR)  ; \
          mv prev-$(TARGET_SUBDIR) stageprofile-$(TARGET_SUBDIR) ; :  ; \
@@ -55422,6 +56390,14 @@ all-stageprofile-libcpp: maybe-all-stageprofile-intl
 all-stagefeedback-libcpp: maybe-all-stagefeedback-intl
 all-fixincludes: maybe-all-libiberty
 all-gnattools: maybe-all-target-libada
+all-lto-plugin: maybe-all-libiberty
+
+all-stage1-lto-plugin: maybe-all-stage1-libiberty
+all-stage2-lto-plugin: maybe-all-stage2-libiberty
+all-stage3-lto-plugin: maybe-all-stage3-libiberty
+all-stage4-lto-plugin: maybe-all-stage4-libiberty
+all-stageprofile-lto-plugin: maybe-all-stageprofile-libiberty
+all-stagefeedback-lto-plugin: maybe-all-stagefeedback-libiberty
 configure-mpfr: maybe-all-gmp
 
 configure-stage1-mpfr: maybe-all-stage1-gmp
index 476cd5d..45a58c5 100644 (file)
@@ -222,6 +222,8 @@ HOST_EXPORTS = \
        PPLINC="$(HOST_PPLINC)"; export PPLINC; \
        CLOOGLIBS="$(HOST_CLOOGLIBS)"; export CLOOGLIBS; \
        CLOOGINC="$(HOST_CLOOGINC)"; export CLOOGINC; \
+       LIBELFLIBS="$(HOST_LIBELFLIBS)" ; export LIBELFLIBS; \
+       LIBELFINC="$(HOST_LIBELFINC)" ; export LIBELFINC; \
 @if gcc-bootstrap
        $(RPATH_ENVVAR)=`echo "$(TARGET_LIB_PATH)$$$(RPATH_ENVVAR)" | sed 's,::*,:,g;s,^:*,,;s,:*$$,,'`; export $(RPATH_ENVVAR); \
 @endif gcc-bootstrap
@@ -296,6 +298,10 @@ HOST_PPLINC = @pplinc@
 HOST_CLOOGLIBS = @clooglibs@
 HOST_CLOOGINC = @clooginc@
 
+# Where to find libelf
+HOST_LIBELFLIBS = @libelflibs@
+HOST_LIBELFINC = @libelfinc@
+
 # ----------------------------------------------
 # Programs producing files for the BUILD machine
 # ----------------------------------------------
index 263b934..76084ed 100755 (executable)
--- a/configure
+++ b/configure
@@ -553,6 +553,42 @@ PACKAGE_URL=
 
 ac_unique_file="move-if-change"
 enable_option_checking=no
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
 ac_subst_vars='LTLIBOBJS
 LIBOBJS
 compare_exclusions
@@ -637,6 +673,12 @@ CFLAGS_FOR_TARGET
 DEBUG_PREFIX_CFLAGS_FOR_TARGET
 SYSROOT_CFLAGS_FOR_TARGET
 stage1_languages
+extra_host_libiberty_configure_flags
+libelfinc
+libelflibs
+EGREP
+GREP
+CPP
 clooginc
 clooglibs
 pplinc
@@ -764,6 +806,10 @@ with_cloog
 with_cloog_include
 with_cloog_lib
 enable_cloog_version_check
+enable_lto
+with_libelf
+with_libelf_include
+with_libelf_lib
 enable_stage1_languages
 enable_objc_gc
 with_build_sysroot
@@ -787,6 +833,7 @@ CPPFLAGS
 CXX
 CXXFLAGS
 CCC
+CPP
 AR
 AS
 DLLTOOL
@@ -1441,6 +1488,7 @@ Optional Features:
   --enable-build-with-cxx build with C++ compiler instead of C compiler
   --disable-ppl-version-check    disable check for PPL version
   --disable-cloog-version-check  disable check for CLooG version
+  --enable-lto            enable link time optimization support
   --enable-stage1-languages[=all]   choose additional languages to build during
                           stage1.  Mostly useful for compiler development.
   --enable-objc-gc        enable use of Boehm's garbage collector with the
@@ -1495,6 +1543,11 @@ Optional Packages:
                           plus --with-cloog-lib=PATH/lib
   --with-cloog-include=PATH Specify directory for installed CLooG include files
   --with-cloog-lib=PATH   Specify the directory for the installed CLooG library
+  --with-libelf=PATH       Specify prefix directory for the installed libelf package
+                          Equivalent to --with-libelf-include=PATH/include
+                          plus --with-libelf-lib=PATH/lib
+  --with-libelf-include=PATH Specify directory for installed libelf include files
+  --with-libelf-lib=PATH   Specify the directory for the installed libelf library
   --with-build-sysroot=SYSROOT
                           use sysroot as the system root during the build
   --with-debug-prefix-map='A=B C=D ...'
@@ -1514,6 +1567,7 @@ Some influential environment variables:
               you have headers in a nonstandard directory <include dir>
   CXX         C++ compiler command
   CXXFLAGS    C++ compiler flags
+  CPP         C preprocessor
   AR          AR for the host
   AS          AS for the host
   DLLTOOL     DLLTOOL for the host
@@ -1760,6 +1814,203 @@ fi
   return $ac_retval
 
 } # ac_fn_c_try_link
+
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } >/dev/null && {
+        test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+    ac_retval=1
+fi
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  return $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_c_check_header_mongrel ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+  # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_header_compiler=yes
+else
+  ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  ac_header_preproc=yes
+else
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
+  yes:no: )
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+    ;;
+  no:yes:* )
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2:     check for missing prerequisite headers?" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+    ;;
+esac
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_header_mongrel
+
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_c_try_run ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: program exited with status $ac_status" >&5
+       $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_retval=$ac_status
+fi
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  return $ac_retval
+
+} # ac_fn_c_try_run
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_header_compile
 cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
@@ -2768,6 +3019,13 @@ if test x$with_gnu_as = xno ; then
   noconfigdirs="$noconfigdirs gas"
 fi
 
+use_included_zlib=
+# Make sure we don't let ZLIB be added if we didn't want it.
+if test x$with_system_zlib = xyes ; then
+  use_included_zlib=no
+  noconfigdirs="$noconfigdirs zlib"
+fi
+
 # some tools are so dependent upon X11 that if we're not building with X,
 # it's not even worth trying to configure, much less build, that tool.
 
@@ -5667,6 +5925,602 @@ fi
 
 
 
+# Check for LTO support.
+# Check whether --enable-lto was given.
+if test "${enable_lto+set}" = set; then :
+  enableval=$enable_lto; enable_lto=$enableval
+else
+  enable_lto=yes; default_enable_lto=yes
+fi
+
+
+if test x"$enable_lto" = x"yes" ; then
+  # Make sure that libelf.h and gelf.h are available.
+
+# Check whether --with-libelf was given.
+if test "${with_libelf+set}" = set; then :
+  withval=$with_libelf;
+fi
+
+
+
+# Check whether --with-libelf_include was given.
+if test "${with_libelf_include+set}" = set; then :
+  withval=$with_libelf_include;
+fi
+
+
+
+# Check whether --with-libelf_lib was given.
+if test "${with_libelf_lib+set}" = set; then :
+  withval=$with_libelf_lib;
+fi
+
+
+  case $with_libelf in
+    "")
+      libelflibs="-lelf"
+      libelfinc="-I/usr/include/libelf"
+      ;;
+    *)
+      libelflibs="-L$with_libelf/lib -lelf"
+      libelfinc="-I$with_libelf/include -I$with_libelf/include/libelf"
+      LIBS="$libelflibs $LIBS"
+      ;;
+  esac
+
+  if test "x$with_libelf_include" != x; then
+    libelfinc="-I$with_libelf_include"
+  fi
+
+  if test "x$with_libelf_lib" != x; then
+    libelflibs="-L$with_libelf_lib -lelf"
+    LIBS="$libelflibs $LIBS"
+  fi
+
+  if test "x$with_libelf$with_libelf_include$with_libelf_lib" = x \
+     && test -d ${srcdir}/libelf; then
+    libelflibs='-L$$r/$(HOST_SUBDIR)/libelf/.libs -L$$r/$(HOST_SUBDIR)/libelf/_libs -lelf '
+    libelfinc='-I$$r/$(HOST_SUBDIR)/libelf/include -I$$s/libelf/include'
+    LIBS="$libelflibs $LIBS"
+  fi
+
+  saved_CFLAGS="$CFLAGS"
+  saved_CPPFLAGS="$CPPFLAGS"
+  saved_LIBS="$LIBS"
+
+  CFLAGS="$CFLAGS $libelfinc"
+  CPPFLAGS="$CPPFLAGS $libelfinc"
+  LIBS="$LIBS $libelflibs"
+
+  ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if test "${ac_cv_prog_CPP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+                    Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+                    Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if test "${ac_cv_path_GREP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$GREP"; then
+  ac_path_GREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in grep ggrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+  # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'GREP' >> "conftest.nl"
+    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_GREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_GREP="$ac_path_GREP"
+      ac_path_GREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_GREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_GREP"; then
+    as_fn_error "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if test "${ac_cv_path_EGREP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+   then ac_cv_path_EGREP="$GREP -E"
+   else
+     if test -z "$EGREP"; then
+  ac_path_EGREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in egrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+  # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'EGREP' >> "conftest.nl"
+    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_EGREP="$ac_path_EGREP"
+      ac_path_EGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_EGREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_EGREP"; then
+    as_fn_error "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_EGREP=$EGREP
+fi
+
+   fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if test "${ac_cv_header_stdc+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_header_stdc=yes
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then :
+  :
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+                  (('a' <= (c) && (c) <= 'i') \
+                    || ('j' <= (c) && (c) <= 'r') \
+                    || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+       || toupper (i) != TOUPPER (i))
+      return 2;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+                 inttypes.h stdint.h unistd.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+eval as_val=\$$as_ac_Header
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+for ac_header in libelf.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "libelf.h" "ac_cv_header_libelf_h" "$ac_includes_default"
+if test "x$ac_cv_header_libelf_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBELF_H 1
+_ACEOF
+ have_libelf_h=yes
+fi
+
+done
+
+  for ac_header in gelf.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "gelf.h" "ac_cv_header_gelf_h" "$ac_includes_default"
+if test "x$ac_cv_header_gelf_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_GELF_H 1
+_ACEOF
+ have_gelf_h=yes
+fi
+
+done
+
+
+  for ac_header in libelf/libelf.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "libelf/libelf.h" "ac_cv_header_libelf_libelf_h" "$ac_includes_default"
+if test "x$ac_cv_header_libelf_libelf_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBELF_LIBELF_H 1
+_ACEOF
+ have_libelf_libelf_h=yes
+fi
+
+done
+
+  for ac_header in libelf/gelf.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "libelf/gelf.h" "ac_cv_header_libelf_gelf_h" "$ac_includes_default"
+if test "x$ac_cv_header_libelf_gelf_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBELF_GELF_H 1
+_ACEOF
+ have_libelf_gelf_h=yes
+fi
+
+done
+
+
+  # If we couldn't find libelf.h and the user forced it, emit an error.
+  if test x"$have_libelf_h" != x"yes" \
+     && test x"$have_libelf_libelf_h" != x"yes" ; then
+    if test x"$default_enable_lto" != x"yes" ; then
+      as_fn_error "LTO support requires libelf.h or libelf/libelf.h." "$LINENO" 5
+    else
+      enable_lto=no
+      libelflibs=
+      libelfinc=
+    fi
+  fi
+
+  # If we couldn't find gelf.h and the user forced it, emit an error.
+  if test x"$have_gelf_h" != x"yes" \
+     && test x"$have_libelf_gelf_h" != x"yes" ; then
+    if test x"$default_enable_lto" != x"yes" ; then
+      as_fn_error "LTO support requires gelf.h or libelf/gelf.h." "$LINENO" 5
+    else
+      enable_lto=no
+      libelflibs=
+      libelfinc=
+    fi
+  fi
+
+  # Check that the detected libelf has the functions we need.  We cannot
+  # rely on just detecting the headers since they do not include
+  # versioning information.  Add functions, if needed.
+  if test x"$enable_lto" = x"yes" ; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the correct version of libelf" >&5
+$as_echo_n "checking for the correct version of libelf... " >&6; }
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <libelf.h>
+int
+main ()
+{
+
+      elf_errmsg (0);
+      elf_getscn (0, 0);
+      elf_nextscn (0, 0);
+      elf_strptr (0, 0, 0);
+      elf_getident (0, 0);
+      elf_getshdrstrndx (0, 0);
+      elf_begin (0, 0, 0);
+      elf_ndxscn (0);
+      elf_end (0);
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; };
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }; enable_lto=no; libelflibs= ; libelfinc=
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
+    # If we couldn't enable LTO and the user forced it, emit an error.
+    if test x"$enable_lto" = x"no" \
+       && test x"$default_enable_lto" != x"yes" ; then
+      as_fn_error "To enable LTO, GCC requires libelf v0.8.12+.
+Try the --with-libelf, --with-libelf-include and --with-libelf-lib options
+to specify its location." "$LINENO" 5
+    fi
+  fi
+
+  CFLAGS="$saved_CFLAGS"
+  CPPFLAGS="$saved_CPPFLAGS"
+  LIBS="$saved_LIBS"
+
+  # Flags needed for libelf.
+
+
+fi
+
 
 # By default, C is the only stage 1 language.
 stage1_languages=,c,
@@ -5735,6 +6589,18 @@ if test -d ${srcdir}/gcc; then
   done
 
   new_enable_languages=,c,
+
+  # If LTO is enabled, add the LTO front end.
+  extra_host_libiberty_configure_flags=
+  if test "$enable_lto" = "yes" ; then
+    new_enable_languages="${new_enable_languages}lto,"
+    if test "${ENABLE_GOLD}" = "yes" ; then
+      configdirs="$configdirs lto-plugin"
+      extra_host_libiberty_configure_flags=--enable-shared
+    fi
+  fi
+
+
   missing_languages=`echo ",$enable_languages," | sed -e s/,all,/,/ -e s/,c,/,/ `
   potential_languages=,c,
 
@@ -6197,7 +7063,7 @@ if test x"${with_libs}" != x && test x"${with_libs}" != xno ; then
   fi
 fi
 
-# Set with_gnu_as and with_gnu_ld as appropriate.
+# Set with_gnu_as, with_gnu_ld, and with_system_zlib as appropriate.
 #
 # This is done by determining whether or not the appropriate directory
 # is available, and by checking whether or not specific configurations
@@ -6208,7 +7074,9 @@ fi
 #
 # If the default for a toolchain is to use GNU as and ld, and you don't
 # want to do that, then you should use the --without-gnu-as and
-# --without-gnu-ld options for the configure script.
+# --without-gnu-ld options for the configure script.  Similarly, if
+# the default is to use the included zlib and you don't want to do that,
+# you should use the --with-system-zlib option for the configure script.
 
 if test x${use_gnu_as} = x &&
    echo " ${configdirs} " | grep " gas " > /dev/null 2>&1 ; then
@@ -6222,6 +7090,14 @@ if test x${use_gnu_ld} = x &&
   extra_host_args="$extra_host_args --with-gnu-ld"
 fi
 
+if test x${use_included_zlib} = x &&
+   echo " ${configdirs} " | grep " zlib " > /dev/null 2>&1 ; then
+  :
+else
+  with_system_zlib=yes
+  extra_host_args="$extra_host_args --with-system-zlib"
+fi
+
 # If using newlib, add --with-newlib to the extra_host_args so that gcc/configure
 # can detect this case.
 
index 0e68f43..c961fe8 100644 (file)
@@ -260,6 +260,13 @@ if test x$with_gnu_as = xno ; then
   noconfigdirs="$noconfigdirs gas"
 fi
 
+use_included_zlib=
+# Make sure we don't let ZLIB be added if we didn't want it.
+if test x$with_system_zlib = xyes ; then
+  use_included_zlib=no
+  noconfigdirs="$noconfigdirs zlib"
+fi
+
 # some tools are so dependent upon X11 that if we're not building with X, 
 # it's not even worth trying to configure, much less build, that tool.
 
@@ -1611,6 +1618,127 @@ fi
 AC_SUBST(clooglibs)
 AC_SUBST(clooginc)
 
+# Check for LTO support.
+AC_ARG_ENABLE(lto,
+[  --enable-lto            enable link time optimization support],
+enable_lto=$enableval,
+enable_lto=yes; default_enable_lto=yes)
+
+if test x"$enable_lto" = x"yes" ; then
+  # Make sure that libelf.h and gelf.h are available.
+  AC_ARG_WITH(libelf, [  --with-libelf=PATH       Specify prefix directory for the installed libelf package
+                          Equivalent to --with-libelf-include=PATH/include
+                          plus --with-libelf-lib=PATH/lib])
+
+  AC_ARG_WITH(libelf_include, [  --with-libelf-include=PATH Specify directory for installed libelf include files])
+
+  AC_ARG_WITH(libelf_lib, [  --with-libelf-lib=PATH   Specify the directory for the installed libelf library])
+
+  case $with_libelf in 
+    "")
+      libelflibs="-lelf"
+      libelfinc="-I/usr/include/libelf"
+      ;;
+    *)
+      libelflibs="-L$with_libelf/lib -lelf"
+      libelfinc="-I$with_libelf/include -I$with_libelf/include/libelf"
+      LIBS="$libelflibs $LIBS"
+      ;;
+  esac
+
+  if test "x$with_libelf_include" != x; then
+    libelfinc="-I$with_libelf_include"
+  fi
+
+  if test "x$with_libelf_lib" != x; then
+    libelflibs="-L$with_libelf_lib -lelf"
+    LIBS="$libelflibs $LIBS"
+  fi
+
+  if test "x$with_libelf$with_libelf_include$with_libelf_lib" = x \
+     && test -d ${srcdir}/libelf; then
+    libelflibs='-L$$r/$(HOST_SUBDIR)/libelf/.libs -L$$r/$(HOST_SUBDIR)/libelf/_libs -lelf '
+    libelfinc='-I$$r/$(HOST_SUBDIR)/libelf/include -I$$s/libelf/include'
+    LIBS="$libelflibs $LIBS"
+  fi
+
+  saved_CFLAGS="$CFLAGS"
+  saved_CPPFLAGS="$CPPFLAGS"
+  saved_LIBS="$LIBS"
+
+  CFLAGS="$CFLAGS $libelfinc"
+  CPPFLAGS="$CPPFLAGS $libelfinc"
+  LIBS="$LIBS $libelflibs"
+
+  AC_CHECK_HEADERS(libelf.h, [have_libelf_h=yes])
+  AC_CHECK_HEADERS(gelf.h, [have_gelf_h=yes])
+
+  AC_CHECK_HEADERS(libelf/libelf.h, [have_libelf_libelf_h=yes])
+  AC_CHECK_HEADERS(libelf/gelf.h, [have_libelf_gelf_h=yes])
+
+  # If we couldn't find libelf.h and the user forced it, emit an error.
+  if test x"$have_libelf_h" != x"yes" \
+     && test x"$have_libelf_libelf_h" != x"yes" ; then
+    if test x"$default_enable_lto" != x"yes" ; then
+      AC_MSG_ERROR([LTO support requires libelf.h or libelf/libelf.h.])
+    else
+      enable_lto=no
+      libelflibs=
+      libelfinc=
+    fi
+  fi
+
+  # If we couldn't find gelf.h and the user forced it, emit an error.
+  if test x"$have_gelf_h" != x"yes" \
+     && test x"$have_libelf_gelf_h" != x"yes" ; then
+    if test x"$default_enable_lto" != x"yes" ; then
+      AC_MSG_ERROR([LTO support requires gelf.h or libelf/gelf.h.])
+    else
+      enable_lto=no
+      libelflibs=
+      libelfinc=
+    fi
+  fi
+
+  # Check that the detected libelf has the functions we need.  We cannot
+  # rely on just detecting the headers since they do not include 
+  # versioning information.  Add functions, if needed.
+  if test x"$enable_lto" = x"yes" ; then
+    AC_MSG_CHECKING([for the correct version of libelf])
+    AC_TRY_LINK(
+      [#include <libelf.h>],[
+      elf_errmsg (0);
+      elf_getscn (0, 0);
+      elf_nextscn (0, 0);
+      elf_strptr (0, 0, 0);
+      elf_getident (0, 0);
+      elf_getshdrstrndx (0, 0);
+      elf_begin (0, 0, 0);
+      elf_ndxscn (0);
+      elf_end (0);
+      ],
+      [AC_MSG_RESULT([yes]);],
+      [AC_MSG_RESULT([no]); enable_lto=no; libelflibs= ; libelfinc= ]
+    )
+
+    # If we couldn't enable LTO and the user forced it, emit an error.
+    if test x"$enable_lto" = x"no" \
+       && test x"$default_enable_lto" != x"yes" ; then
+      AC_MSG_ERROR([To enable LTO, GCC requires libelf v0.8.12+.
+Try the --with-libelf, --with-libelf-include and --with-libelf-lib options
+to specify its location.])
+    fi
+  fi
+
+  CFLAGS="$saved_CFLAGS"
+  CPPFLAGS="$saved_CPPFLAGS"
+  LIBS="$saved_LIBS"
+
+  # Flags needed for libelf.
+  AC_SUBST(libelflibs)
+  AC_SUBST(libelfinc)
+fi
+
 
 # By default, C is the only stage 1 language.
 stage1_languages=,c,
@@ -1679,6 +1807,18 @@ if test -d ${srcdir}/gcc; then
   done
 
   new_enable_languages=,c,
+
+  # If LTO is enabled, add the LTO front end.
+  extra_host_libiberty_configure_flags=
+  if test "$enable_lto" = "yes" ; then
+    new_enable_languages="${new_enable_languages}lto,"
+    if test "${ENABLE_GOLD}" = "yes" ; then
+      configdirs="$configdirs lto-plugin"
+      extra_host_libiberty_configure_flags=--enable-shared
+    fi
+  fi
+  AC_SUBST(extra_host_libiberty_configure_flags)
+
   missing_languages=`echo ",$enable_languages," | sed -e s/,all,/,/ -e s/,c,/,/ `
   potential_languages=,c,
 
@@ -2088,7 +2228,7 @@ if test x"${with_libs}" != x && test x"${with_libs}" != xno ; then
   fi
 fi
 
-# Set with_gnu_as and with_gnu_ld as appropriate.
+# Set with_gnu_as, with_gnu_ld, and with_system_zlib as appropriate.
 #
 # This is done by determining whether or not the appropriate directory
 # is available, and by checking whether or not specific configurations
@@ -2099,7 +2239,9 @@ fi
 #
 # If the default for a toolchain is to use GNU as and ld, and you don't 
 # want to do that, then you should use the --without-gnu-as and
-# --without-gnu-ld options for the configure script.
+# --without-gnu-ld options for the configure script.  Similarly, if
+# the default is to use the included zlib and you don't want to do that,
+# you should use the --with-system-zlib option for the configure script.
 
 if test x${use_gnu_as} = x &&
    echo " ${configdirs} " | grep " gas " > /dev/null 2>&1 ; then
@@ -2113,6 +2255,14 @@ if test x${use_gnu_ld} = x &&
   extra_host_args="$extra_host_args --with-gnu-ld"
 fi
 
+if test x${use_included_zlib} = x &&
+   echo " ${configdirs} " | grep " zlib " > /dev/null 2>&1 ; then
+  :
+else
+  with_system_zlib=yes
+  extra_host_args="$extra_host_args --with-system-zlib"
+fi
+
 # If using newlib, add --with-newlib to the extra_host_args so that gcc/configure
 # can detect this case.
 
index b4627d2..2dc5d3a 100644 (file)
@@ -1,3 +1,9 @@
+2009-10-03  H.J. Lu  <hongjiu.lu@intel.com>
+           Richard Guenther  <rguenther@suse.de>
+
+       PR lto/39216
+       * gcc_update: Adjust file timestamps for lto-plugin.
+
 2009-09-10  Iain Sandoe  <iain.sandoe@sandoe-acoustics.co.uk>
 
        PR bootstrap/41245
index f29dcb6..3e5a842 100755 (executable)
@@ -84,6 +84,9 @@ gcc/testsuite/gcc.dg/cpp/_Pragma3.c: gcc/testsuite/gcc.dg/cpp/mi1c.h
 # Similarly, without this, you will see:
 # direct2s.c:35: warning: current file is older than direct2.c
 gcc/testsuite/gcc.dg/cpp/direct2s.c: gcc/testsuite/gcc.dg/cpp/direct2.c
+# lto-plugin
+lto-plugin/configure: lto-plugin/configure.ac lto-plugin/aclocal.m4
+lto-plugin/Makefile.in: lto-plugin/Makefile.am lto-plugin/aclocal.m4
 # And libraries, at last
 libbanshee/configure: libbanshee/configure.ac
 libmudflap/configure: libmudflap/configure.ac
index 7263e90..62d725c 100644 (file)
@@ -1,3 +1,454 @@
+2009-10-03  Simon Baldwin  <simonb@google.com>
+           Cary Coutant  <ccoutant@google.com>
+           Rafael Espindola  <espindola@google.com>
+           Richard Guenther  <rguenther@suse.de>
+           Jan Hubicka  <jh@suse.cz>
+           Doug Kwan <dougkwan@google.com>
+           H.J. Lu  <hongjiu.lu@intel.com> 
+           Bill Maddox  <maddox@google.com>
+           Ryan Mansfield  <rmansfield@qnx.com>
+           Diego Novillo  <dnovillo@google.com>
+           Ollie Wild  <aaw@google.com>
+           Kenneth Zadeck <zadeck@naturalbridge.com>
+
+       * lto-cgraph.c: New file.
+       * lto-compress.c: New file.
+       * lto-compress.h: New file.
+       * lto-opts.c: New file.
+       * lto-section-in.c: New file.
+       * lto-section-out.c: New file.
+       * lto-streamer-in.c: New file.
+       * lto-streamer-out.c: New file.
+       * lto-streamer.c: New file.
+       * lto-streamer.h: New file.
+       * lto-symtab.c: New file.
+       * lto-wpa-fixup.c: New file.
+       * lto-wrapper.c: New file.
+
+2009-10-03  Simon Baldwin  <baldwin@google.com>
+           Ben Elliston  <bje@au.ibm.com>
+           Rafael Espindola  <espindola@google.com>
+           Nathan Froyd  <froydnj@codesourcery.com>
+           Jan Hubicka  <jh@suse.cz>
+           Doug Kwan  <dougkwan@google.com>
+           Diego Novillo  <dnovillo@google.com>
+           Kenneth Zadeck  <zadeck@naturalbridge.com>
+
+       * Makefile.in (enable_lto): New.
+       (site.exp): If @enable_lto@ is set to 'yes' define
+       ENABLE_LTO.
+       (LINKER_PLUGIN_API_H): Define.
+       (LTO_SYMTAB_H): Define.
+       (LTO_STREAMER_H): Define.
+       (TREE_VECTORIZER_H): Define.
+       (INCLUDES): Add LIBELFINC.
+       (OBJS-common): Add lto-cgraph.o, lto-streamer-in.o,
+       lto-streamer-out.o, lto-section-in.o, lto-section-out.o,
+       lto-symtab.o, lto-opts.o, lto-streamer.o, lto-wpa-fixup.o,
+       lto-compress.o.
+       (MOSTLYCLEANFILES): Add lto-wrapper$(exeext)
+       (native): Add lto-wrapper$(exeext)
+       (lto-compress.o, lto-cgraph.o, lto-streamer-in.o,
+       lto-streamer-out.o, lto-section-in.o, lto-section-out.o,
+       lto-symtab.o, lto-opts.o, lto-streamer.o,
+       lto-wpa-fixup.o): New rules.
+       (gimple.o): Add dependency on LTO_HEADER_H and
+       LTO_SECTION_OUT_H.
+       (varasm.o): Add dependency on tree-iterator.h.
+       (cgraph.o): Add dependency on cif-code.def.
+       (ipa-reference.o): Add dependency on LTO_STREAMER_H.
+       (ipa-pure-const.o): Likewise.
+       (GTFILES): Add lto-symtab.c.
+       (install-lto-wrapper): New.
+       * configure.ac: If 'lto' is in enable_languages, define
+       ENABLE_LTO and enable_lto.
+       If LIBELFLIBS is set, define HAVE_libelf.
+       * config.in: Regenerate.
+
+2009-10-03  Rafael Espindola  <espindola@google.com>
+           Diego Novillo  <dnovillo@google.com>
+
+       * cgraphunit.c (ipa_passes): Prevent lto1 from calling
+       ipa_write_summaries.
+       Call execute_ipa_summary_passes for all_regular_ipa_passes and
+       all_lto_gen_passes.
+       (cgraph_optimize): Make extern.
+
+2009-10-03  Nathan Froyd  <froydnj@codesourcery.com>
+           Kenneth Zadeck <zadeck@naturalbridge.com>
+
+       * toplev.c (in_lto_p): Declare.
+       * collect2.c (scan_prog_file): Read all the output when reading
+       information for LTO.
+       (enum lto_mode_d): Declare.
+
+2009-10-03  Richard Guenther  <rguenther@suse.de>
+           Diego Novillo  <dnovillo@google.com>
+
+       * gimple.c: Include target.h and alias.h.
+       (gimple_types): Declare.
+       (type_hash_cache): Declare.
+       (gimple_alloc_stat): Make extern.
+       (gimple_build_eh_must_not_throw): Call
+       gimple_eh_must_not_throw_set_fndecl.
+       (struct type_pair_d): Declare.
+       (type_pair_t): Declare.
+       (type_pair_hash): New.
+       (type_pair_eq): New.
+       (lookup_type_pair): New.
+       (gimple_force_type_merge): New.
+       (compare_type_names_p): New.
+       (compare_field_offset): New.
+       (gimple_types_compatible_p): New.
+       (struct sccs): Declare.
+       (next_dfs_num): Declare.
+       (iterative_hash_gimple_type): New.
+       (visit): New.
+       (iterative_hash_type_name): New.
+       (iterative_hash_gimple_type): New.
+       (gimple_type_hash): New.
+       (gimple_type_eq): New.
+       (gimple_register_type): New.
+       (print_gimple_types_stats): New.
+       (gimple_signed_or_unsigned_type): New.
+       (gimple_unsigned_type): New.
+       (gimple_signed_type): New.
+       (gimple_get_alias_set): New.
+       (gimple_decl_printable_name): Do not use DMGL_TYPES.
+       * gimple.h (gimple_alloc, gimple_alloc_stat): Declare.
+       (gimple_force_type_merge): Declare.
+       (gimple_types_compatible_p): Declare.
+       (gimple_register_type): Declare.
+       (print_gimple_types_stats): Declare.
+       (gimple_unsigned_type): Declare.
+       (gimple_signed_type): Declare.
+       (gimple_get_alias_set): Declare.
+       (gimple_eh_must_not_throw_set_fndecl): New.
+
+2009-10-03  Jan Hubicka  <jh@suse.cz>
+           Kenneth Zadeck <zadeck@naturalbridge.com>
+
+       * ipa-pure-const.c: Include lto-streamer.h.
+       (register_hooks): Factor out of ...
+       (generate_summary): ... here.
+       (pure_const_write_summary): New.
+       (pure_const_read_summary): New.
+       (pass_ipa_pure_const): Add pure_const_write_summary and
+       pure_const_read_summary.
+       * ipa-reference.c: Include lto-streamer.h.
+       (add_new_function): New.
+       (remove_node_data): New.
+       (duplicate_node_data): New.
+       (ipa_init): Guard against multiple calls.
+       Move hook setup from analyze_function.
+       (write_node_summary_p): New.
+       (ipa_reference_write_summary): New.
+       (ipa_reference_read_summary): New.
+       (pass_ipa_reference): Add ipa_reference_write_summary and
+       ipa_reference_read_summary.
+       * cgraph.h (cgraph_local_info): Add field lto_file_data.
+       (struct cgraph_edge): Add fields lto_stmt_uid and
+       call_stmt_cannot_inline_p.
+       (cgraph_optimize): Declare.
+       (cgraph_decide_is_function_needed): Declare.
+       (reset_inline_failed): Declare.
+       (enum LTO_cgraph_tags): Declare.
+       (LTO_cgraph_tag_names): Declare.
+       (LCC_NOT_FOUND): Define.
+
+2009-10-03  Doug Kwan  <dougkwan@google.com>
+           Rafael Espindola  <espindola@google.com>
+           Jan Hubicka  <jh@suse.cz>
+           Diego Novillo  <dnovillo@google.com>
+           Kenneth Zadeck  <zadeck@naturalbridge.com>
+
+       * passes.c (all_regular_ipa_passes): New.
+       (all_ipa_passes): Rename to all_small_ipa_passes.
+       (init_optimization_passes): Init all_regular_ipa_passes.
+       * tree-pass.h (all_regular_ipa_passes): New.
+       (all_ipa_passes): Rename to all_small_ipa_passes.
+       * passes.c (all_lto_gen_passes): New.
+       (init_optimization_passes): Initialize all_lto_gen_passes.
+       (execute_ipa_summary_passes): Make non-static.
+       (ipa_write_summaries_1): New.
+       (ipa_write_summaries_2): New.
+       (ipa_write_summaries): New.
+       (ipa_write_summaries_of_cgraph_node_set): New.
+       (ipa_read_summaries_1): New.
+       (ipa_read_summaries): New.
+       (execute_ipa_pass_list): Call cgraph_process_new_functions.
+       (execute_regular_ipa_pass_list): Remove.
+       (init_optimization_passes): Schedule
+       pass_rebuild_cgraph_edges and pass_early_inline outside
+       of pass_all_early_optimizations.  Document reason.
+       (pass_ipa_lto_gimple_out, pass_ipa_lto_wpa_fixup,
+       pass_ipa_lto_finish_out): New pass.
+       (pass_ipa_summary_passes): Start and stop timers if the pass
+       has them.
+       (execute_all_ipa_transforms): New.
+       (execute_one_pass): Don't call execute_one_ipa_transform_pass.
+       (dump_properties, debug_properties): New.
+       * tree-optimize.c (gate_all_early_local_passes): Return
+       false if we are in lto1.
+       (tree_rest_of_compilation): Call execute_all_ipa_transforms.
+       * tree-pass.h (execute_all_ipa_transforms): Declare.
+       (pass_ipa_function_and_variable_visibility): Declare.
+       (pass_ipa_early_inline): Declare.
+       (pass_ipa_lto_gimple_out): Declare.
+       (pass_ipa_lto_wpa_fixup): Declare.
+       (pass_ipa_lto_finish_out): Declare.
+       (all_small_ipa_passes, all_regular_ipa_passes,
+       all_lto_gen_passes): Declare.
+       (execute_ipa_summary_passes): Declare.
+       (execute_all_ipa_transforms): Declare.
+       (ipa_write_summaries): Declare
+       (ipa_write_summaries_of_cgraph_node_set): Declare.
+       (ipa_read_summaries): Declare.
+
+2009-10-03  Doug Kwan  <dougkwan@google.com>
+           Ollie Wild  <aaw@google.com>
+
+       * ipa-prop.c (ipa_propagate_indirect_call_infos): Do
+       nothing in WPA.
+
+       * collect2.c (LTO_MODE_NONE, LTO_MODE_LTO, LTO_MODE_WPA): New enums.
+       (lto_mode): New variable.
+       (maybe_run_lto_and_relink): Handle the -fwpa option.
+       (main): Handle the -fwpa option.
+       (maybe_unlink_list): New function.
+       * gcc.c (link_lto_options): Replace -flto with -fwpa.
+       * common.opt (flto): New flag.
+       * toplev.c (flag_generate_lto): Declare.
+
+2009-10-03  Simon Baldwin  <simonb@google.com>
+
+       * common.opt (flto-compression-level): New flag.
+
+       * opts.c: Include lto-opts.h.
+       (handle_option): Call lto_register_user_option for each
+       valid option handled.
+       * (decode_options): Clear registered options before the options
+       handling loop.
+
+2009-10-03  Cary Coutant  <ccoutant@google.com>
+
+       * collect2.c (is_elf): New function.
+       (scan_prog_file): Require LTO object to be in ELF format.
+
+2009-10-03  Rafael Espindola  <espindola@google.com>
+
+       * gcc.c (LINK_COMMAND_SPEC): Use the -pass-through option to pass
+       libgcc to the linker.
+
+       * ipa-cp.c (cgraph_gate_cp): Return false if LTRANS is
+       running.
+
+       * collect2.c (maybe_run_lto_and_relink): Execute lto-wrapper.
+       (collect_execute): Add flags argument. Pass flags to pex_run. Update
+       all callers.
+       * collect2.h (collect_execute): Add flags argument.
+       * tlink.c (tlink_execute): Update call to collect_execute.
+       * gcc.c (main): Set the COLLECT_LTO_WRAPPER environment variable.
+       (use_linker_plugin): New.
+       (use_linker_plugin_spec_function): New.
+       (LINK_COMMAND_SPEC): Pass plugin options to the linker.
+       (linker_plugin_file_spec): New.
+       (lto_wrapper_spec): New.
+       (lto_gcc_spec): New.
+       (static_specs): Add linker_plugin_file, lto_wrapper and lto_gcc.
+       (static_spec_functions): Add use-linker-plugin.
+       (process_command): Handle -use-linker-plugin.
+       (main): Use lto_wrapper_spec instead of lto_wrapper. Set
+       linker_plugin_file_spec and lto_gcc_spec.
+       (use_linker_plugin_spec_function): New.
+
+2009-10-03  Richard Guenther  <rguenther@suse.de>
+
+       PR lto/41547
+       PR lto/41548
+       * tree.h (is_lang_specific): Include LANG_TYPE.
+       * tree.c (find_decls_types_r): Manually add interesting parts
+       of TYPE_FIELDS.  Walk BINFO_VIRTUALS.  Do not walk TYPE_METHODS.
+
+       * gimple.c (type_pair_hash): Make symmetric.
+       (type_pair_eq): Likewise.
+       (lookup_type_pair): Increase initial hashtable size.
+       (gimple_force_type_merge): Rely on type-pair symmetry.
+       (visit): Remove excessive checking code.
+       (iterative_hash_type_name): Do not hash TYPE_NAME of
+       anonymous unions.
+       (gimple_register_type): Remove getenv calls, shrink initial
+       hashtable size.
+
+       PR middle-end/41502
+       * cgraphunit.c (ipa_passes): Do not remove bodies of extern
+       inline functions if not generating lto output.
+
+       PR lto/41379
+       * toplev.c (finalize): In WPA mode remove the asm file.
+
+2009-10-03  Doug Kwan  <dougkwan@google.com>
+
+       * ipa-inline.c (cgraph_mark_inline): Check
+       edge->call_stmt_cannot_inline_p instead of calling
+       gimple_call_cannot_inline_p.
+       (cgraph_decide_inlining): Do nothing in WPA and LTRANS.
+       (cgraph_gate_ipa_early_inlining): Return false if
+       in_lto_p is set.
+       (inline_generate_summary): Do nothing in LTRANS.
+       * cgraph.c (initialize_inline_failed): Make sure
+       e->call_stmt exists before calling
+       gimple_call_cannot_inline_p.
+       (cgraph_create_edge): Set edge->call_stmt_cannot_inline_p.
+       (cgraph_clone_edge): Add argument STMT_UID.  Modify all
+       callers.
+       Update new_edge->lto_stmt_uid.
+       * cgraphbuild.c (reset_inline_failed): New.
+
+       * common.opt (fwpa): New flag.
+       (fltrans): New option.
+       * gcc.c (gcc_lto_option_t): New type.
+       (current_lto_option): New variable.
+       (lto_single_spec_function): Remove and is replaced by ..
+       (lto_option_spec_function): New function.
+       (LINK_COMMAND_SPEC): Use link_lto_option spec instead of just
+       passing the -flto flag.
+       (cc1_options): Separate non-LTO related parts into ..
+       (cc1_non_lto_options): Non-LTO related options shared by all FEs.
+       (lto1_options): New spec for lto FE.
+       (link_lto_options): New spec for handling LTO flags in linker.
+       (invoke_lto_single): Re-format to fit in 80 column.  Replace
+       lto-single with lto-option.
+       (static_specs): Add cc1_non_lto_options, lto1_options and
+       link_lto_options.
+       (static_spec_function): Replace lto-single with lto-option.
+       (process_command): Handle -flto, -fwpa and -fltran
+       by setting current_lto_option and not passing it to subprocess
+       unconditionally.
+
+2009-10-03  Bill Maddox  <maddox@google.com>
+
+       Add `gcc' driver support for link-time code generation (LTO).
+
+       * collect2.c (enum pass): Add new literal PASS_LTOINFO.
+       (lto_flag, lto_objects, lto_o_file): New variables.
+       (struct lto_object, struct lto_object_list): New structures.
+       (collect_exit, handler): Remove LTO temporary output file on exit.
+       (add_lto_object): New function.
+       (maybe_run_lto_and_relink): New function. Perform link time code
+       generation and relinking for object files containing LTO information.
+       (main): Invoke maybe_run_lto_and_relink().
+       (dump_argv): New function.  For debugging, currently disabled.
+       (scan_prog_file): Add LTO information pass.
+       * gcc.c (LINK_COMMAND_SPEC): Pass `-flto' switch to linker, i.e.,
+       collect2.
+       * toplev.c (compile_file): Emit assembler directive to create
+       the `gnu_lto_v1' marker symbol when compiling with `-flto'.
+
+2009-10-03  Diego Novillo  <dnovillo@google.com>
+
+       * c.opt: Add LTO to warn_abi and warn_psabi.
+
+       * tree.c (fld_worklist_push): Rename from PUSH.
+       Convert to static inline function.
+       Ignore language-specific nodes.
+       Update all users.
+       (find_decls_types_r): Do not traverse the subtrees of
+       language-specific nodes.
+       Do not traverse DECL_INITIAL for TYPE_DECLs.
+       * tree.h (is_lang_specific): New.
+       * langhooks.h (struct lang_hooks_for_decls): Remove
+       may_need_assembler_name_p.  Update all users.
+
+       * c-common.c (set_builtin_user_assembler_name): Move ...
+       * builtins.c (set_builtin_user_assembler_name): ... here.
+       (is_builtin_name): Add comment
+       (is_builtin_fn): New.
+       * except.c (output_ttype): Only call
+       lookup_type_for_runtime if TYPE is not a runtime type.
+
+       * passes.c (register_pass): Call position_pass on
+       all_small_ipa_passes, all_regular_ipa_passes and
+       all_lto_gen_passes.
+       * timevar.def (TV_IPA_LTO_GIMPLE_IO): Define.
+       (TV_IPA_LTO_DECL_IO): Define.
+       (TV_IPA_LTO_CGRAPH_IO): Define.
+       (TV_LTO): Define.
+       (TV_WHOPR_WPA): Define.
+       (TV_WHOPR_WPA_IO): Define.
+       (TV_WHOPR_LTRANS): Define.
+       (TV_WHOPR_WPA_FIXUP): Define.
+       (TV_WHOPR_WPA_LTRANS_EXEC): Define.
+       * tree-cfg.c (tree_node_can_be_shared): Make extern.
+       * tree-flow.h (tree_node_can_be_shared): Declare.
+       * tree-inline.c (tree_can_inline_p): Check that E has a
+       statement associated with it.
+       * tree.c (free_lang_data_in_binf): Factor out of ...
+       (free_lang_data_in_type): ... here.
+       Call RECORD_OR_UNION_TYPE_P.
+       (need_assembler_name_p): Ignore DECL if it does not have
+       TREE_PUBLIC set.
+       Call lang_hooks.decls.may_need_assembler_name_p if set.
+       (free_lang_data_in_decl): Do not clear DECL_CONTEXT for
+       CONST_DECLs.
+       (free_lang_data): Set debug_info_level to
+       DINFO_LEVEL_NONE.
+       Set write_symbols to NO_DEBUG.
+       Set debug_hooks to do_nothing_debug_hooks.
+       (gate_free_lang_data): Return true if flag_generate_lto
+       is set.
+       (walk_tree_1): Call RECORD_OR_UNION_TYPE_P.
+       * c-common.h (set_builtin_user_assembler_name): Move ...
+       * tree.h (set_builtin_user_assembler_name): ... here.
+
+       * common.opt (flto-report): New flag.
+       * opts.c (complain_wrong_lang): Do not complain if
+       running lto1.
+       * collect2.c (scan_prog_file): Send the error output of
+       'nm' to HOST_BIT_BUCKET.
+
+2009-10-03  Ollie Wild  <aaw@google.com>
+
+       * langhooks-def.h (lhd_begin_section): New function declaration.
+       (lhd_write_section): New function declaration.
+       (lhd_end_section): New function declaration.
+       (LANG_HOOKS_BEGIN_SECTION): New macro.
+       (LANG_HOOKS_WRITE_SECTION_DATA): New macro.
+       (LANG_HOOKS_END_SECTION): New macro.
+       (LANG_HOOKS_LTO): New macro.
+       (LANG_HOOKS_INITIALIZER): Add LANG_HOOKS_LTO.
+       * langhooks.c (output.h): Add include.
+       (saved_section): New static variable.
+       (lhd_begin_section): New function.
+       (lhd_write_section_data): New function.
+       (lhd_end_section): New function.
+       * langhooks.h (struct lang_hooks_for_lto): New structure.
+       (struct lang_hooks): Add member lto.
+       * Makefile.in (langhooks.o): Add dependency on output.h.
+
+       * c-opts.c (c_common_post_options): Handle -flto and -fwhopr.
+
+2009-10-03  Richard Guenther  <rguenther@suse.de>
+
+       * config/rs6000/rs6000.c (rs6000_output_function_epilogue):
+       Handle LTO.
+
+2009-10-03  Simon Baldwin  <simonb@google.com>
+           Richard Guenther  <rguenther@suse.de>
+           Janis Johnson  <janis187@us.ibm.com>
+           Doug Kwan  <dougkwan@google.com>
+           Diego Novillo  <dnovillo@google.com>
+           Ramana Radhakrishnan  <ramana.r@gmail.com>
+           Ollie Wild  <aaw@google.com>
+
+       * doc/install.texi: Add documentation for libelf and --enable-lto.
+       * doc/invoke.texi: Document -fwpa, -flto, -fwhopr,
+       -fltrans, -flto-report, -flto-compression-level and
+       -use-linker-plugin.
+       * doc/sourcebuild.texi: Document use of zlib.
+       Document lto-plugin.
+       Add section for LTO Testing.
+
 2009-10-02  Cary Coutant  <ccoutant@google.com>
 
        Add support for comdat type sections for DWARF v4.  Merge from dwarf4
index 40fe3ba..490a8c4 100644 (file)
@@ -309,6 +309,13 @@ PPLINC = @PPLINC@
 CLOOGLIBS = @CLOOGLIBS@
 CLOOGINC = @CLOOGINC@
 
+# How to find libelf
+LIBELFLIBS = @LIBELFLIBS@
+LIBELFINC = @LIBELFINC@
+
+# Set to 'yes' if the LTO front end is enabled.
+enable_lto = @enable_lto@
+
 # Libs and linker option needed for plugin support
 PLUGINLIBS = @pluginlibs@
 
@@ -407,6 +414,10 @@ PARTITION_H = $(srcdir)/../include/partition.h
 MD5_H      = $(srcdir)/../include/md5.h
 DWARF2_H    = $(srcdir)/../include/dwarf2.h
 
+# Linker plugin API headers
+LINKER_PLUGIN_API_H = $(srcdir)/../include/plugin-api.h
+LTO_SYMTAB_H = $(srcdir)/../include/lto-symtab.h
+
 # Default native SYSTEM_HEADER_DIR, to be overridden by targets.
 NATIVE_SYSTEM_HEADER_DIR = /usr/include
 # Default cross SYSTEM_HEADER_DIR, to be overridden by targets.
@@ -917,6 +928,9 @@ REAL_H = real.h $(MACHMODE_H)
 IRA_INT_H = ira.h ira-int.h $(CFGLOOP_H) alloc-pool.h
 DBGCNT_H = dbgcnt.h dbgcnt.def
 EBITMAP_H = ebitmap.h sbitmap.h
+LTO_STREAMER_H = lto-streamer.h $(LINKER_PLUGIN_API_H) $(TARGET_H) \
+               $(CGRAPH_H) vec.h vecprim.h $(TREE_H) $(GIMPLE_H)
+TREE_VECTORIZER_H = tree-vectorizer.h $(TREE_DATA_REF_H)
 IPA_PROP_H = ipa-prop.h $(TREE_H) vec.h $(CGRAPH_H)
 GSTAB_H = gstab.h stab.def
 BITMAP_H = bitmap.h $(HASHTAB_H) statistics.h
@@ -976,7 +990,8 @@ BUILD_LIBDEPS= $(BUILD_LIBIBERTY)
 # and the system's installed libraries.
 LIBS = @LIBS@ $(CPPLIB) $(LIBINTL) $(LIBICONV) $(LIBIBERTY) $(LIBDECNUMBER) \
        $(HOST_LIBS)
-BACKENDLIBS = $(CLOOGLIBS) $(PPLLIBS) $(GMPLIBS) $(PLUGINLIBS) $(HOST_LIBS)
+BACKENDLIBS = $(CLOOGLIBS) $(PPLLIBS) $(GMPLIBS) $(PLUGINLIBS) $(HOST_LIBS) \
+       $(ZLIB) $(LIBELFLIBS)
 # Any system libraries needed just for GNAT.
 SYSLIBS = @GNAT_LIBEXC@
 
@@ -1005,7 +1020,7 @@ BUILD_ERRORS = build/errors.o
 INCLUDES = -I. -I$(@D) -I$(srcdir) -I$(srcdir)/$(@D) \
           -I$(srcdir)/../include @INCINTL@ \
           $(CPPINC) $(GMPINC) $(DECNUMINC) \
-          $(PPLINC) $(CLOOGINC)
+          $(PPLINC) $(CLOOGINC) $(LIBELFINC)
 
 .c.o:
        $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $< $(OUTPUT_OPTION)
@@ -1215,6 +1230,16 @@ OBJS-common = \
        loop-unroll.o \
        loop-unswitch.o \
        lower-subreg.o \
+       lto-cgraph.o \
+       lto-streamer-in.o \
+       lto-streamer-out.o \
+       lto-section-in.o \
+       lto-section-out.o \
+       lto-symtab.o \
+       lto-opts.o \
+       lto-streamer.o \
+       lto-wpa-fixup.o \
+       lto-compress.o \
        mcf.o \
        mode-switching.o \
        modulo-sched.o \
@@ -1411,7 +1436,7 @@ MOSTLYCLEANFILES = insn-flags.h insn-config.h insn-codes.h \
  genrtl.c genrtl.h gt-*.h gtype-*.h gtype-desc.c gtyp-input.list \
  xgcc$(exeext) cpp$(exeext) cc1$(exeext) cc1*-dummy$(exeext) $(EXTRA_PASSES) \
  $(EXTRA_PARTS) $(EXTRA_PROGRAMS) gcc-cross$(exeext) \
- $(SPECS) collect2$(exeext) \
+ $(SPECS) collect2$(exeext) lto-wrapper$(exeext) \
  gcov-iov$(build_exeext) gcov$(exeext) gcov-dump$(exeext) \
  *.[0-9][0-9].* *.[si] *-checksum.c libbackend.a libgcc.mk
 
@@ -1692,7 +1717,7 @@ rest.encap: lang.rest.encap
 # This is what is made with the host's compiler
 # whether making a cross compiler or not.
 native: config.status auto-host.h build-@POSUB@ $(LANGUAGES) \
-       $(EXTRA_PASSES) $(EXTRA_PROGRAMS) $(COLLECT2)
+       $(EXTRA_PASSES) $(EXTRA_PROGRAMS) $(COLLECT2) lto-wrapper$(exeext)
 
 # Define the names for selecting languages in LANGUAGES.
 c: cc1$(exeext)
@@ -1987,6 +2012,12 @@ collect2-aix.o : collect2-aix.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
 tlink.o: tlink.c $(DEMANGLE_H) $(HASHTAB_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
     $(OBSTACK_H) collect2.h intl.h
 
+lto-wrapper$(exeext): lto-wrapper.o intl.o $(LIBDEPS)
+       $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o T$@ lto-wrapper.o intl.o $(LIBS)
+       mv -f T$@ $@
+
+lto-wrapper.o: lto-wrapper.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) intl.h
+
 # A file used by all variants of C.
 
 c-common.o : c-common.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
@@ -2158,10 +2189,54 @@ convert.o: convert.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
 
 double-int.o: double-int.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H)
 
+# lto-compress.o needs $(ZLIBINC) added to the include flags.
+lto-compress.o: lto-compress.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+       $(TREE_H) langhooks.h $(LTO_HEADER_H) $(LTO_SECTION_H) \
+       lto-compress.h $(DIAGNOSTIC_H) errors.h
+       $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(ZLIBINC) $< $(OUTPUT_OPTION)
+
+lto-cgraph.o: lto-cgraph.c $(CONFIG_H) $(SYSTEM_H) coretypes.h   \
+   $(TM_H) $(TOPLEV_H) $(EXPR_H) $(FLAGS_H) $(PARAMS_H) input.h \
+   $(VARRAY_H) $(HASHTAB_H) langhooks.h $(BASIC_BLOCK_H) \
+   $(TREE_FLOW_H) $(CGRAPH_H) $(FUNCTION_H) $(GGC_H) $(DIAGNOSTIC_H) \
+   except.h $(TIMEVAR_H) output.h pointer-set.h $(LTO_STREAMER_H)
+lto-streamer-in.o: lto-streamer-in.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+   $(TM_H) $(TOPLEV_H) $(EXPR_H) $(FLAGS_H) $(PARAMS_H) input.h $(VARRAY_H) \
+   $(HASHTAB_H) $(BASIC_BLOCK_H) $(TREE_FLOW_H) $(TREE_PASS_H) $(CGRAPH_H) \
+   $(FUNCTION_H) $(GGC_H) $(DIAGNOSTIC_H) libfuncs.h $(EXCEPT_H) debug.h \
+   $(TIMEVAR_H) output.h $(IPA_UTILS_H) $(LTO_STREAMER_H)
+lto-streamer-out.o : lto-streamer-out.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+   $(TM_H) $(TOPLEV_H) $(TREE_H) $(EXPR_H) $(FLAGS_H) $(PARAMS_H) input.h \
+   $(VARRAY_H) $(HASHTAB_H) $(BASIC_BLOCK_H) tree-iterator.h \
+   $(TREE_FLOW_H) $(TREE_PASS_H) $(CGRAPH_H) $(FUNCTION_H) $(GGC_H) \
+   $(DIAGNOSTIC_H) except.h $(LTO_STREAMER_H) errors.h
+lto-section-in.o: lto-section-in.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
+   $(TOPLEV_H) $(EXPR_H) $(FLAGS_H) $(PARAMS_H) input.h $(VARRAY_H) \
+   $(HASHTAB_H) $(BASIC_BLOCK_H) $(TREE_FLOW_H) $(CGRAPH_H) $(FUNCTION_H) \
+   $(GGC_H) $(DIAGNOSTIC_H) except.h $(TIMEVAR_H) output.h \
+   $(LTO_STREAMER_H) lto-compress.h
+lto-section-out.o : lto-section-out.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+   $(TM_H) $(TOPLEV_H) $(TREE_H) $(EXPR_H) $(PARAMS_H) input.h \
+   $(VARRAY_H) $(HASHTAB_H) $(BASIC_BLOCK_H) $(TREE_FLOW_H) $(TREE_PASS_H) \
+   $(CGRAPH_H) $(FUNCTION_H) $(GGC_H) except.h pointer-set.h \
+   $(BITMAP_H) langhooks.h $(LTO_STREAMER_H) lto-compress.h
+lto-symtab.o: lto-symtab.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+   toplev.h $(TREE_H) $(GIMPLE_H) $(GGC_H) $(LAMBDA_H) $(HASHTAB_H) \
+   $(LTO_STREAMER_H) $(LINKER_PLUGIN_API_H) gt-lto-symtab.h
+lto-opts.o: lto-opts.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \
+   $(HASHTAB_H) $(GGC_H) $(BITMAP_H) $(FLAGS_H) opts.h options.h \
+   $(TARGET_H) $(TOPLEV_H) $(LTO_STREAMER_H)
+lto-streamer.o: lto-streamer.c $(CONFIG_H) $(SYSTEM_H) coretypes.h   \
+   $(TM_H) $(TREE_H) $(GIMPLE_H) $(BITMAP_H) $(LTO_STREAMER_H) $(FLAGS_H) \
+   $(TREE_FLOW_H) $(DIAGNOSTIC_H) $(LTO_SYMTAB_H) $(TOPLEV_H)
+lto-wpa-fixup.o: lto-wpa-fixup.c $(CONFIG_H) $(SYSTEM_H) coretypes.h   \
+   $(TM_H) $(TOPLEV_H) $(TREE_H) $(EXPR_H) $(FLAGS_H) $(CGRAPH_H) \
+   $(FUNCTION_H) $(DIAGNOSTIC_H) $(BITMAP_H) $(TIMEVAR_H) \
+   $(TREE_FLOW_H) $(TREE_PASS_H) $(LTO_STREAMER_H)
 langhooks.o : langhooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
    $(TREE_H) $(TOPLEV_H) $(TREE_INLINE_H) $(RTL_H) insn-config.h $(INTEGRATE_H) \
    langhooks.h $(TARGET_H) $(LANGHOOKS_DEF_H) $(FLAGS_H) $(GGC_H) $(DIAGNOSTIC_H) \
-   intl.h $(GIMPLE_H) $(CGRAPH_H)
+   intl.h $(GIMPLE_H) $(CGRAPH_H) output.h
 tree.o : tree.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
    all-tree.def $(FLAGS_H) $(FUNCTION_H) $(PARAMS_H) \
    $(TOPLEV_H) $(GGC_H) $(HASHTAB_H) $(TARGET_H) output.h $(TM_P_H) \
@@ -2572,7 +2647,8 @@ tree-object-size.o: tree-object-size.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
    $(TREE_PASS_H) tree-ssa-propagate.h
 gimple.o : gimple.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \
    $(GGC_H) $(GIMPLE_H) $(TOPLEV_H) $(DIAGNOSTIC_H) gt-gimple.h \
-   $(TREE_FLOW_H) value-prof.h $(FLAGS_H) $(DEMANGLE_H)
+   $(TREE_FLOW_H) value-prof.h $(FLAGS_H) $(DEMANGLE_H) \
+   $(TARGET_H) $(ALIAS_H)
 gimple-pretty-print.o : gimple-pretty-print.c $(CONFIG_H) $(SYSTEM_H) \
    $(TREE_H) $(DIAGNOSTIC_H) $(REAL_H) $(HASHTAB_H) $(TREE_FLOW_H) \
    $(TM_H) coretypes.h $(TREE_PASS_H) $(GIMPLE_H) value-prof.h
@@ -2640,7 +2716,7 @@ passes.o : passes.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
    langhooks.h insn-flags.h $(CFGLAYOUT_H) $(REAL_H) $(CFGLOOP_H) \
    hosthooks.h $(CGRAPH_H) $(COVERAGE_H) $(TREE_PASS_H) $(TREE_DUMP_H) \
    $(GGC_H) $(INTEGRATE_H) $(CPPLIB_H) opts.h $(TREE_FLOW_H) $(TREE_INLINE_H) \
-   gt-passes.h $(DF_H) $(PREDICT_H)
+   gt-passes.h $(DF_H) $(PREDICT_H) $(LTO_HEADER_H) $(LTO_SECTION_OUT_H)
 
 plugin.o : plugin.c $(PLUGIN_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h \
    $(TOPLEV_H) $(TREE_H) $(TREE_PASS_H) intl.h $(PLUGIN_VERSION_H) $(GGC_H)
@@ -2669,7 +2745,8 @@ varasm.o : varasm.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
    $(RTL_H) $(FLAGS_H) $(FUNCTION_H) $(EXPR_H) hard-reg-set.h $(REGS_H) \
    output.h $(TOPLEV_H) xcoffout.h debug.h $(GGC_H) $(TM_P_H) \
    $(HASHTAB_H) $(TARGET_H) langhooks.h gt-varasm.h $(BASIC_BLOCK_H) \
-   $(CFGLAYOUT_H) $(CGRAPH_H) targhooks.h tree-mudflap.h $(REAL_H) tree-iterator.h
+   $(CFGLAYOUT_H) $(CGRAPH_H) targhooks.h tree-mudflap.h $(REAL_H) \
+   tree-iterator.h
 function.o : function.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
    $(TREE_H) $(CFGLAYOUT_H) $(GIMPLE_H) $(FLAGS_H) $(FUNCTION_H) $(EXPR_H) \
    $(OPTABS_H) libfuncs.h $(REGS_H) hard-reg-set.h insn-config.h $(RECOG_H) \
@@ -2771,7 +2848,8 @@ simplify-rtx.o : simplify-rtx.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
 cgraph.o : cgraph.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
    langhooks.h $(TOPLEV_H) $(FLAGS_H) $(GGC_H) $(TARGET_H) $(CGRAPH_H) \
    gt-cgraph.h output.h intl.h $(BASIC_BLOCK_H) debug.h $(HASHTAB_H) \
-   $(TREE_INLINE_H) $(TREE_DUMP_H) $(TREE_FLOW_H) value-prof.h $(EXCEPT_H)
+   $(TREE_INLINE_H) $(TREE_DUMP_H) $(TREE_FLOW_H) cif-code.def \
+   value-prof.h $(EXCEPT_H)
 cgraphunit.o : cgraphunit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
    $(TREE_H) langhooks.h $(TREE_INLINE_H) $(TOPLEV_H) $(FLAGS_H) $(GGC_H) \
    $(TARGET_H) $(CGRAPH_H) intl.h pointer-set.h $(FUNCTION_H) $(GIMPLE_H) \
@@ -2813,12 +2891,13 @@ ipa-reference.o : ipa-reference.c $(CONFIG_H) $(SYSTEM_H) \
    coretypes.h $(TM_H) $(TREE_H) $(TREE_FLOW_H) $(TREE_INLINE_H) langhooks.h \
    pointer-set.h $(GGC_H) $(IPA_REFERENCE_H) $(IPA_UTILS_H) $(SPLAY_TREE_H) \
    $(GIMPLE_H) $(CGRAPH_H) output.h $(FLAGS_H) $(TREE_PASS_H) \
-   $(TIMEVAR_H) $(DIAGNOSTIC_H) $(FUNCTION_H) gt-ipa-reference.h
+   $(TIMEVAR_H) $(DIAGNOSTIC_H) $(FUNCTION_H) gt-ipa-reference.h \
+   $(LTO_STREAMER_H)
 ipa-pure-const.o : ipa-pure-const.c $(CONFIG_H) $(SYSTEM_H) \
    coretypes.h $(TM_H) $(TREE_H) $(TREE_FLOW_H) $(TREE_INLINE_H) langhooks.h \
    pointer-set.h $(GGC_H) $(IPA_UTILS_H) $(TARGET_H) \
    $(GIMPLE_H) $(CGRAPH_H) output.h $(FLAGS_H) $(TREE_PASS_H) $(TIMEVAR_H) \
-   $(DIAGNOSTIC_H) $(CFGLOOP_H) $(SCEV_H)
+   $(DIAGNOSTIC_H) $(CFGLOOP_H) $(SCEV_H) $(LTO_STREAMER_H)
 ipa-type-escape.o : ipa-type-escape.c $(CONFIG_H) $(SYSTEM_H) \
    coretypes.h $(TM_H) $(TREE_H) $(TREE_FLOW_H) $(TREE_INLINE_H) langhooks.h \
    pointer-set.h $(GGC_H) $(IPA_TYPE_ESCAPE_H) $(IPA_UTILS_H) $(SPLAY_TREE_H) \
@@ -3504,6 +3583,7 @@ GTFILES = $(CPP_ID_DATA_H) $(srcdir)/input.h $(srcdir)/coretypes.h \
   $(srcdir)/tree-phinodes.c \
   $(srcdir)/ipa-reference.c \
   $(srcdir)/tree-ssa-structalias.c \
+  $(srcdir)/lto-symtab.c \
   $(srcdir)/tree-ssa-alias.h \
   @all_gtfiles@
 
@@ -4145,7 +4225,7 @@ maintainer-clean:
 # broken is small.
 install: install-common $(INSTALL_HEADERS) \
     install-cpp install-man install-info install-@POSUB@ \
-    install-driver
+    install-driver install-lto-wrapper
 
 ifeq ($(enable_plugin),yes)
 install: install-plugin
@@ -4440,6 +4520,10 @@ install-collect2: collect2 installdirs
 # Install the driver program as $(libsubdir)/gcc for collect2.
        $(INSTALL_PROGRAM) xgcc$(exeext) $(DESTDIR)$(libexecsubdir)/gcc$(exeext)
 
+# Install lto-wrapper.
+install-lto-wrapper: lto-wrapper$(exeext)
+       $(INSTALL_PROGRAM) lto-wrapper$(exeext) $(DESTDIR)$(libexecsubdir)/lto-wrapper$(exeext)
+       
 # Cancel installation by deleting the installed files.
 uninstall: lang.uninstall
        -rm -rf $(DESTDIR)$(libsubdir)
@@ -4491,6 +4575,9 @@ site.exp: ./config.status Makefile
          echo "set ENABLE_PLUGIN 1" >> ./tmp0; \
          echo "set GMPINC \"$(GMPINC)\"" >> ./tmp0; \
        fi
+       @if test "@enable_lto@" = "yes" ; then \
+         echo "set ENABLE_LTO 1" >> ./tmp0; \
+       fi
 # If newlib has been configured, we need to pass -B to gcc so it can find
 # newlib's crt0.o if it exists.  This will cause a "path prefix not used"
 # message if it doesn't, but the testsuite is supposed to ignore the message -
index 64840e1..c9bc230 100644 (file)
@@ -230,6 +230,8 @@ static tree do_mpfr_bessel_n (tree, tree, tree,
 static tree do_mpfr_remquo (tree, tree, tree);
 static tree do_mpfr_lgamma_r (tree, tree, tree);
 
+/* Return true if NAME starts with __builtin_ or __sync_.  */
+
 bool
 is_builtin_name (const char *name)
 {
@@ -240,6 +242,16 @@ is_builtin_name (const char *name)
   return false;
 }
 
+
+/* Return true if DECL is a function symbol representing a built-in.  */
+
+bool
+is_builtin_fn (tree decl)
+{
+  return TREE_CODE (decl) == FUNCTION_DECL && DECL_BUILT_IN (decl);
+}
+
+
 /* Return true if NODE should be considered for inline expansion regardless
    of the optimization level.  This means whenever a function is invoked with
    its "internal" name, which normally contains the prefix "__builtin".  */
@@ -13856,3 +13868,41 @@ fold_call_stmt (gimple stmt, bool ignore)
     }
   return NULL_TREE;
 }
+
+/* Look up the function in built_in_decls that corresponds to DECL
+   and set ASMSPEC as its user assembler name.  DECL must be a
+   function decl that declares a builtin.  */
+
+void
+set_builtin_user_assembler_name (tree decl, const char *asmspec)
+{
+  tree builtin;
+  gcc_assert (TREE_CODE (decl) == FUNCTION_DECL
+             && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
+             && asmspec != 0);
+
+  builtin = built_in_decls [DECL_FUNCTION_CODE (decl)];
+  set_user_assembler_name (builtin, asmspec);
+  switch (DECL_FUNCTION_CODE (decl))
+    {
+    case BUILT_IN_MEMCPY:
+      init_block_move_fn (asmspec);
+      memcpy_libfunc = set_user_assembler_libfunc ("memcpy", asmspec);
+      break;
+    case BUILT_IN_MEMSET:
+      init_block_clear_fn (asmspec);
+      memset_libfunc = set_user_assembler_libfunc ("memset", asmspec);
+      break;
+    case BUILT_IN_MEMMOVE:
+      memmove_libfunc = set_user_assembler_libfunc ("memmove", asmspec);
+      break;
+    case BUILT_IN_MEMCMP:
+      memcmp_libfunc = set_user_assembler_libfunc ("memcmp", asmspec);
+      break;
+    case BUILT_IN_ABORT:
+      abort_libfunc = set_user_assembler_libfunc ("abort", asmspec);
+      break;
+    default:
+      break;
+    }
+}
index 4de92d0..bf57cb8 100644 (file)
@@ -5032,44 +5032,6 @@ c_common_nodes_and_builtins (void)
   memset (builtin_types, 0, sizeof (builtin_types));
 }
 
-/* Look up the function in built_in_decls that corresponds to DECL
-   and set ASMSPEC as its user assembler name.  DECL must be a
-   function decl that declares a builtin.  */
-
-void
-set_builtin_user_assembler_name (tree decl, const char *asmspec)
-{
-  tree builtin;
-  gcc_assert (TREE_CODE (decl) == FUNCTION_DECL
-             && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
-             && asmspec != 0);
-
-  builtin = built_in_decls [DECL_FUNCTION_CODE (decl)];
-  set_user_assembler_name (builtin, asmspec);
-  switch (DECL_FUNCTION_CODE (decl))
-    {
-    case BUILT_IN_MEMCPY:
-      init_block_move_fn (asmspec);
-      memcpy_libfunc = set_user_assembler_libfunc ("memcpy", asmspec);
-      break;
-    case BUILT_IN_MEMSET:
-      init_block_clear_fn (asmspec);
-      memset_libfunc = set_user_assembler_libfunc ("memset", asmspec);
-      break;
-    case BUILT_IN_MEMMOVE:
-      memmove_libfunc = set_user_assembler_libfunc ("memmove", asmspec);
-      break;
-    case BUILT_IN_MEMCMP:
-      memcmp_libfunc = set_user_assembler_libfunc ("memcmp", asmspec);
-      break;
-    case BUILT_IN_ABORT:
-      abort_libfunc = set_user_assembler_libfunc ("abort", asmspec);
-      break;
-    default:
-      break;
-    }
-}
-
 /* The number of named compound-literals generated thus far.  */
 static GTY(()) int compound_literal_number;
 
index c1655ae..db4f910 100644 (file)
@@ -839,8 +839,6 @@ extern tree c_build_qualified_type (tree, int);
    frontends.  */
 extern void c_common_nodes_and_builtins (void);
 
-extern void set_builtin_user_assembler_name (tree decl, const char *asmspec);
-
 extern void disable_builtin_function (const char *);
 
 extern void set_compound_literal_name (tree decl);
index e026fd9..6c2f5a5 100644 (file)
@@ -1033,6 +1033,29 @@ c_common_post_options (const char **pfilename)
   C_COMMON_OVERRIDE_OPTIONS;
 #endif
 
+  if (flag_lto || flag_whopr)
+    {
+#ifdef ENABLE_LTO
+      flag_generate_lto = 1;
+
+      /* When generating IL, do not operate in whole-program mode.
+        Otherwise, symbols will be privatized too early, causing link
+        errors later.  */
+      flag_whole_program = 0;
+
+      /* FIXME lto.  Disable var-tracking until debug information
+        is properly handled in free_lang_data.  */
+      flag_var_tracking = 0;
+#else
+      error ("LTO support has not been enabled in this configuration");
+#endif
+    }
+
+  /* Reconcile -flto and -fwhopr.  Set additional flags as appropriate and
+     check option consistency.  */
+  if (flag_lto && flag_whopr)
+    error ("-flto and -fwhopr are mutually exclusive");
+
   /* Excess precision other than "fast" requires front-end
      support.  */
   if (c_dialect_cxx ())
index 21f7ab7..006f9ae 100644 (file)
--- a/gcc/c.opt
+++ b/gcc/c.opt
@@ -113,11 +113,11 @@ C ObjC C++ ObjC++ Joined Separate
 -U<macro>      Undefine <macro>
 
 Wabi
-C ObjC C++ ObjC++ Var(warn_abi) Warning
+C ObjC C++ ObjC++ LTO Var(warn_abi) Warning
 Warn about things that will change when compiling with an ABI-compliant compiler
 
 Wpsabi
-C ObjC C++ ObjC++ Var(warn_psabi) Init(1) Undocumented
+C ObjC C++ ObjC++ LTO Var(warn_psabi) Init(1) Undocumented
 
 Waddress
 C ObjC C++ ObjC++ Var(warn_address) Warning
index 15dd60a..8dcf4e4 100644 (file)
@@ -802,7 +802,7 @@ initialize_inline_failed (struct cgraph_edge *e)
     e->inline_failed = CIF_REDEFINED_EXTERN_INLINE;
   else if (!callee->local.inlinable)
     e->inline_failed = CIF_FUNCTION_NOT_INLINABLE;
-  else if (gimple_call_cannot_inline_p (e->call_stmt))
+  else if (e->call_stmt && gimple_call_cannot_inline_p (e->call_stmt))
     e->inline_failed = CIF_MISMATCHED_ARGUMENTS;
   else
     e->inline_failed = CIF_FUNCTION_NOT_CONSIDERED;
@@ -816,13 +816,19 @@ cgraph_create_edge (struct cgraph_node *caller, struct cgraph_node *callee,
 {
   struct cgraph_edge *edge;
 
+
+  /* LTO does not actually have access to the call_stmt since these
+     have not been loaded yet.  */
+  if (call_stmt)
+    {
 #ifdef ENABLE_CHECKING
   /* This is rather pricely check possibly trigerring construction of call stmt
      hashtable.  */
   gcc_assert (!cgraph_edge (caller, call_stmt));
 #endif
 
-  gcc_assert (is_gimple_call (call_stmt));
+      gcc_assert (is_gimple_call (call_stmt));
+    }
 
   if (free_edges)
     {
@@ -860,7 +866,9 @@ cgraph_create_edge (struct cgraph_node *caller, struct cgraph_node *callee,
   gcc_assert (freq <= CGRAPH_FREQ_MAX);
   edge->loop_nest = nest;
   edge->indirect_call = 0;
-  if (caller->call_site_hash)
+  edge->call_stmt_cannot_inline_p =
+    (call_stmt ? gimple_call_cannot_inline_p (call_stmt) : false);
+  if (call_stmt && caller->call_site_hash)
     {
       void **slot;
       slot = htab_find_slot_with_hash (caller->call_site_hash,
@@ -1624,8 +1632,8 @@ cgraph_function_possibly_inlined_p (tree decl)
 /* Create clone of E in the node N represented by CALL_EXPR the callgraph.  */
 struct cgraph_edge *
 cgraph_clone_edge (struct cgraph_edge *e, struct cgraph_node *n,
-                  gimple call_stmt, gcov_type count_scale, int freq_scale,
-                  int loop_nest, bool update_original)
+                  gimple call_stmt, unsigned stmt_uid, gcov_type count_scale,
+                  int freq_scale, int loop_nest, bool update_original)
 {
   struct cgraph_edge *new_edge;
   gcov_type count = e->count * count_scale / REG_BR_PROB_BASE;
@@ -1638,6 +1646,7 @@ cgraph_clone_edge (struct cgraph_edge *e, struct cgraph_node *n,
 
   new_edge->inline_failed = e->inline_failed;
   new_edge->indirect_call = e->indirect_call;
+  new_edge->lto_stmt_uid = stmt_uid;
   if (update_original)
     {
       e->count -= new_edge->count;
@@ -1702,8 +1711,8 @@ cgraph_clone_node (struct cgraph_node *n, gcov_type count, int freq,
 
 
   for (e = n->callees;e; e=e->next_callee)
-    cgraph_clone_edge (e, new_node, e->call_stmt, count_scale, freq, loop_nest,
-                      update_original);
+    cgraph_clone_edge (e, new_node, e->call_stmt, e->lto_stmt_uid,
+                      count_scale, freq, loop_nest, update_original);
 
   new_node->next_sibling_clone = n->clones;
   if (n->clones)
index 292eccd..845897b 100644 (file)
@@ -46,6 +46,10 @@ enum availability
   AVAIL_LOCAL
 };
 
+/* This is the information that is put into the cgraph local structure
+   to recover a function.  */
+struct lto_file_decl_data;
+
 extern const char * const cgraph_availability_names[];
 
 /* Function inlining information.  */
@@ -69,6 +73,9 @@ struct GTY(()) inline_summary
    Available after function is analyzed.  */
 
 struct GTY(()) cgraph_local_info {
+  /* File stream where this node is being written to.  */
+  struct lto_file_decl_data * GTY ((skip)) lto_file_data;
+
   struct inline_summary inline_summary;
 
   /* Set when function function is visible in current compilation unit only
@@ -277,6 +284,9 @@ struct GTY((chain_next ("%h.next_caller"), chain_prev ("%h.prev_caller"))) cgrap
   struct cgraph_edge *prev_callee;
   struct cgraph_edge *next_callee;
   gimple call_stmt;
+  /* The stmt_uid of this call stmt.  This is used by LTO to recover
+     the call_stmt when the function is serialized in.  */
+  unsigned int lto_stmt_uid;
   PTR GTY ((skip (""))) aux;
   /* When equal to CIF_OK, inline this call.  Otherwise, points to the
      explanation why function was not inlined.  */
@@ -291,6 +301,8 @@ struct GTY((chain_next ("%h.next_caller"), chain_prev ("%h.prev_caller"))) cgrap
   unsigned int loop_nest : 30;
   /* Whether this edge describes a call that was originally indirect.  */
   unsigned int indirect_call : 1;
+  /* True if the corresponding CALL stmt cannot be inlined.  */
+  unsigned int call_stmt_cannot_inline_p : 1;
   /* Can this call throw externally?  */
   unsigned int can_throw_external : 1;
   /* Unique id of the edge.  */
@@ -406,8 +418,8 @@ struct cgraph_global_info *cgraph_global_info (tree);
 struct cgraph_rtl_info *cgraph_rtl_info (tree);
 const char * cgraph_node_name (struct cgraph_node *);
 struct cgraph_edge * cgraph_clone_edge (struct cgraph_edge *,
-                                       struct cgraph_node *,
-                                       gimple, gcov_type, int, int, bool);
+                                       struct cgraph_node *, gimple,
+                                       unsigned, gcov_type, int, int, bool);
 struct cgraph_node * cgraph_clone_node (struct cgraph_node *, gcov_type, int,
                                        int, bool, VEC(cgraph_edge_p,heap) *);
 
@@ -430,6 +442,7 @@ struct cgraph_node * cgraph_create_virtual_clone (struct cgraph_node *old_node,
 void cgraph_finalize_function (tree, bool);
 void cgraph_mark_if_needed (tree);
 void cgraph_finalize_compilation_unit (void);
+void cgraph_optimize (void);
 void cgraph_mark_needed_node (struct cgraph_node *);
 void cgraph_mark_address_taken_node (struct cgraph_node *);
 void cgraph_mark_reachable_node (struct cgraph_node *);
@@ -449,6 +462,8 @@ struct cgraph_node *save_inline_function_body (struct cgraph_node *);
 void record_references_in_initializer (tree);
 bool cgraph_process_new_functions (void);
 
+bool cgraph_decide_is_function_needed (struct cgraph_node *, tree);
+
 typedef void (*cgraph_edge_hook)(struct cgraph_edge *, void *);
 typedef void (*cgraph_node_hook)(struct cgraph_node *, void *);
 typedef void (*cgraph_2edge_hook)(struct cgraph_edge *, struct cgraph_edge *,
@@ -476,6 +491,7 @@ void cgraph_materialize_all_clones (void);
 
 /* In cgraphbuild.c  */
 unsigned int rebuild_cgraph_edges (void);
+void reset_inline_failed (struct cgraph_node *);
 int compute_call_stmt_bb_frequency (tree, basic_block bb);
 
 /* In ipa.c  */
@@ -560,6 +576,22 @@ unsigned int compute_inline_parameters (struct cgraph_node *);
 /* Create a new static variable of type TYPE.  */
 tree add_new_static_var (tree type);
 
+/* lto-cgraph.c */
+
+enum LTO_cgraph_tags
+{
+  /* Must leave 0 for the stopper.  */
+  LTO_cgraph_avail_node = 1,
+  LTO_cgraph_overwritable_node,
+  LTO_cgraph_unavail_node,
+  LTO_cgraph_edge,
+  LTO_cgraph_last_tag
+};
+
+extern const char * LTO_cgraph_tag_names[LTO_cgraph_last_tag];
+
+#define LCC_NOT_FOUND  (-1)
+
 
 /* Return true if iterator CSI points to nothing.  */
 static inline bool
index a7a8bd2..d61def2 100644 (file)
@@ -78,6 +78,29 @@ record_reference (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
   return NULL_TREE;
 }
 
+/* Reset inlining information of all incoming call edges of NODE.  */
+
+void
+reset_inline_failed (struct cgraph_node *node)
+{
+  struct cgraph_edge *e;
+
+  for (e = node->callers; e; e = e->next_caller)
+    {
+      e->callee->global.inlined_to = NULL;
+      if (!node->analyzed)
+       e->inline_failed = CIF_BODY_NOT_AVAILABLE;
+      else if (node->local.redefined_extern_inline)
+       e->inline_failed = CIF_REDEFINED_EXTERN_INLINE;
+      else if (!node->local.inlinable)
+       e->inline_failed = CIF_FUNCTION_NOT_INLINABLE;
+      else if (e->call_stmt_cannot_inline_p)
+       e->inline_failed = CIF_MISMATCHED_ARGUMENTS;
+      else
+       e->inline_failed = CIF_FUNCTION_NOT_CONSIDERED;
+    }
+}
+
 /* Computes the frequency of the call statement so that it can be stored in
    cgraph_edge.  BB is the basic block of the call statement.  */
 int
index 2ad0718..9a4f63d 100644 (file)
@@ -140,7 +140,6 @@ static void cgraph_expand_all_functions (void);
 static void cgraph_mark_functions_to_output (void);
 static void cgraph_expand_function (struct cgraph_node *);
 static void cgraph_output_pending_asms (void);
-static void cgraph_optimize (void);
 static void cgraph_analyze_function (struct cgraph_node *);
 
 static FILE *cgraph_dump_file;
@@ -314,8 +313,8 @@ cgraph_build_cdtor_fns (void)
    either outside this translation unit, something magic in the system
    configury.  */
 
-static bool
-decide_is_function_needed (struct cgraph_node *node, tree decl)
+bool
+cgraph_decide_is_function_needed (struct cgraph_node *node, tree decl)
 {
   if (MAIN_NAME_P (DECL_NAME (decl))
       && TREE_PUBLIC (decl))
@@ -522,7 +521,7 @@ cgraph_finalize_function (tree decl, bool nested)
   node->finalized_by_frontend = true;
   record_cdtor_fn (node->decl);
 
-  if (decide_is_function_needed (node, decl))
+  if (cgraph_decide_is_function_needed (node, decl))
     cgraph_mark_needed_node (node);
 
   /* Since we reclaim unreachable nodes at the end of every language
@@ -551,7 +550,7 @@ void
 cgraph_mark_if_needed (tree decl)
 {
   struct cgraph_node *node = cgraph_node (decl);
-  if (node->local.finalized && decide_is_function_needed (node, decl))
+  if (node->local.finalized && cgraph_decide_is_function_needed (node, decl))
     cgraph_mark_needed_node (node);
 }
 
@@ -692,7 +691,8 @@ verify_cgraph_node (struct cgraph_node *node)
 
   if (node->analyzed && gimple_has_body_p (node->decl)
       && !TREE_ASM_WRITTEN (node->decl)
-      && (!DECL_EXTERNAL (node->decl) || node->global.inlined_to))
+      && (!DECL_EXTERNAL (node->decl) || node->global.inlined_to)
+      && !flag_wpa)
     {
       if (this_cfun->cfg)
        {
@@ -949,8 +949,8 @@ cgraph_analyze_functions (void)
          continue;
        }
 
-      gcc_assert (!node->analyzed && node->reachable);
-      cgraph_analyze_function (node);
+      if (!node->analyzed)
+       cgraph_analyze_function (node);
 
       for (edge = node->callees; edge; edge = edge->next_callee)
        if (!edge->callee->reachable)
@@ -1355,15 +1355,31 @@ ipa_passes (void)
   current_function_decl = NULL;
   gimple_register_cfg_hooks ();
   bitmap_obstack_initialize (NULL);
-  execute_ipa_pass_list (all_ipa_passes);
+  execute_ipa_pass_list (all_small_ipa_passes);
 
-  /* Generate coverage variables and constructors.  */
-  coverage_finish ();
+  /* If pass_all_early_optimizations was not scheduled, the state of
+     the cgraph will not be properly updated.  Update it now.  */
+  if (cgraph_state < CGRAPH_STATE_IPA_SSA)
+    cgraph_state = CGRAPH_STATE_IPA_SSA;
 
-  /* Process new functions added.  */
-  set_cfun (NULL);
-  current_function_decl = NULL;
-  cgraph_process_new_functions ();
+  if (!in_lto_p)
+    {
+      /* Generate coverage variables and constructors.  */
+      coverage_finish ();
+
+      /* Process new functions added.  */
+      set_cfun (NULL);
+      current_function_decl = NULL;
+      cgraph_process_new_functions ();
+    }
+
+  execute_ipa_summary_passes ((struct ipa_opt_pass_d *) all_regular_ipa_passes);
+  execute_ipa_summary_passes ((struct ipa_opt_pass_d *) all_lto_gen_passes);
+
+  if (!in_lto_p)
+    ipa_write_summaries ();
+
+  execute_ipa_pass_list (all_regular_ipa_passes);
 
   bitmap_obstack_release (NULL);
 }
@@ -1371,7 +1387,7 @@ ipa_passes (void)
 
 /* Perform simple optimizations based on callgraph.  */
 
-static void
+void
 cgraph_optimize (void)
 {
   if (errorcount || sorrycount)
@@ -1598,7 +1614,8 @@ cgraph_copy_node_for_versioning (struct cgraph_node *old_version,
       also cloned.  */
    for (e = old_version->callees;e; e=e->next_callee)
      {
-       new_e = cgraph_clone_edge (e, new_version, e->call_stmt, 0, e->frequency,
+       new_e = cgraph_clone_edge (e, new_version, e->call_stmt,
+                                 e->lto_stmt_uid, 0, e->frequency,
                                  e->loop_nest, true);
        new_e->count = e->count;
      }
index 82c400b..20caa45 100644 (file)
@@ -184,6 +184,15 @@ static int aix64_flag;                     /* true if -b64 */
 static int aixrtl_flag;                        /* true if -brtl */
 #endif
 
+enum lto_mode_d {
+  LTO_MODE_NONE,                       /* Not doing LTO.  */
+  LTO_MODE_LTO,                                /* Normal LTO.  */
+  LTO_MODE_WHOPR                       /* WHOPR.  */
+};
+
+/* Current LTO mode.  */
+static enum lto_mode_d lto_mode = LTO_MODE_NONE;
+
 int debug;                             /* true if -debug */
 
 static int shared_obj;                 /* true if -shared */
@@ -193,6 +202,7 @@ static const char *o_file;          /* <xxx>.o for constructor/destructor list.  */
 #ifdef COLLECT_EXPORT_LIST
 static const char *export_file;                /* <xxx>.x for AIX export list.  */
 #endif
+static char **lto_o_files;             /* Output files for LTO.  */
 const char *ldout;                     /* File for ld stdout.  */
 const char *lderrout;                  /* File for ld stderr.  */
 static const char *output_file;                /* Output file for ld.  */
@@ -250,6 +260,25 @@ static struct path_prefix *libpaths[3] = {&cmdline_lib_dirs,
                                          &libpath_lib_dirs, NULL};
 #endif
 
+/* List of names of object files containing LTO information.
+   These are a subset of the object file names appearing on the
+   command line, and must be identical, in the sense of pointer
+   equality, with the names passed to maybe_run_lto_and_relink().  */
+
+struct lto_object
+{
+  const char *name;            /* Name of object file.  */
+  struct lto_object *next;     /* Next in linked list.  */
+};
+
+struct lto_object_list
+{
+  struct lto_object *first;    /* First list element.  */
+  struct lto_object *last;     /* Last list element.  */
+};
+
+static struct lto_object_list lto_objects;
+
 /* Special kinds of symbols that a name may denote.  */
 
 typedef enum {
@@ -272,6 +301,7 @@ static void prefix_from_string (const char *, struct path_prefix *);
 static void do_wait (const char *, struct pex_obj *);
 static void fork_execute (const char *, char **);
 static void maybe_unlink (const char *);
+static void maybe_unlink_list (char **);
 static void add_to_list (struct head *, const char *);
 static int extract_init_priority (const char *);
 static void sort_ids (struct head *);
@@ -310,7 +340,8 @@ typedef enum {
   PASS_FIRST,                          /* without constructors */
   PASS_OBJ,                            /* individual objects */
   PASS_LIB,                            /* looking for shared libraries */
-  PASS_SECOND                          /* with constructors linked in */
+  PASS_SECOND,                         /* with constructors linked in */
+  PASS_LTOINFO                         /* looking for objects with LTO info */
 } scanpass;
 
 /* ... and which kinds of symbols are to be considered.  */
@@ -363,6 +394,9 @@ collect_exit (int status)
     maybe_unlink (export_file);
 #endif
 
+  if (lto_o_files)
+    maybe_unlink_list (lto_o_files);
+
   if (ldout != 0 && ldout[0])
     {
       dump_file (ldout, stdout);
@@ -472,6 +506,9 @@ handler (int signo)
     maybe_unlink (export_file);
 #endif
 
+  if (lto_o_files)
+    maybe_unlink_list (lto_o_files);
+
   if (response_file)
     maybe_unlink (response_file);
 
@@ -815,6 +852,244 @@ prefix_from_string (const char *p, struct path_prefix *pprefix)
     }
   free (nstore);
 }
+
+/* Add an entry for the object file NAME to object file list LIST.
+   New entries are added at the end of the list. The original pointer
+   value of NAME is preserved, i.e., no string copy is performed.  */
+
+static void
+add_lto_object (struct lto_object_list *list, const char *name)
+{
+  struct lto_object *n = XNEW (struct lto_object);
+  n->name = name;
+  n->next = NULL;
+
+  if (list->last)
+    list->last->next = n;
+  else
+    list->first = n;
+
+  list->last = n;
+}
+
+
+/* Perform a link-time recompilation and relink if any of the object
+   files contain LTO info.  The linker command line LTO_LD_ARGV
+   represents the linker command that would produce a final executable
+   without the use of LTO. OBJECT_LST is a vector of object file names
+   appearing in LTO_LD_ARGV that are to be considerd for link-time
+   recompilation, where OBJECT is a pointer to the last valid element.
+   (This awkward convention avoids an impedance mismatch with the
+   usage of similarly-named variables in main().)  The elements of
+   OBJECT_LST must be identical, i.e., pointer equal, to the
+   corresponding arguments in LTO_LD_ARGV.
+
+   Upon entry, at least one linker run has been performed without the
+   use of any LTO info that might be present.  Any recompilations
+   necessary for template instantiations have been performed, and
+   initializer/finalizer tables have been created if needed and
+   included in the linker command line LTO_LD_ARGV. If any of the
+   object files contain LTO info, we run the LTO back end on all such
+   files, and perform the final link with the LTO back end output
+   substituted for the LTO-optimized files.  In some cases, a final
+   link with all link-time generated code has already been performed,
+   so there is no need to relink if no LTO info is found.  In other
+   cases, our caller has not produced the final executable, and is
+   relying on us to perform the required link whether LTO info is
+   present or not.  In that case, the FORCE argument should be true.
+   Note that the linker command line argument LTO_LD_ARGV passed into
+   this function may be modified in place.  */
+
+static void
+maybe_run_lto_and_relink (char **lto_ld_argv, char **object_lst,
+                         const char **object, bool force)
+{
+  const char **object_file = CONST_CAST2 (const char **, char **, object_lst);
+
+  int num_lto_c_args = 1;    /* Allow space for the terminating NULL.  */
+
+  while (object_file < object)
+  {
+    /* If file contains LTO info, add it to the list of LTO objects.  */
+    scan_prog_file (*object_file++, PASS_LTOINFO, SCAN_ALL);
+
+    /* Increment the argument count by the number of object file arguments
+       we will add.  An upper bound suffices, so just count all of the
+       object files regardless of whether they contain LTO info.  */
+    num_lto_c_args++;
+  }
+
+  if (lto_objects.first)
+    {
+      const char *opts;
+      char **lto_c_argv;
+      const char **lto_c_ptr;
+      const char *cp;
+      const char **p, **q, **r;
+      const char **lto_o_ptr;
+      struct lto_object *list;
+      char *lto_wrapper = getenv ("COLLECT_LTO_WRAPPER");
+      struct pex_obj *pex;
+      const char *prog = "lto-wrapper";
+
+      if (!lto_wrapper)
+       fatal ("COLLECT_LTO_WRAPPER must be set.");
+
+      /* There is at least one object file containing LTO info,
+         so we need to run the LTO back end and relink.  */
+
+      /* Get compiler options passed down from the parent `gcc' command.
+         These must be passed to the LTO back end.  */
+      opts = getenv ("COLLECT_GCC_OPTIONS");
+
+      /* Increment the argument count by the number of inherited options.
+         Some arguments may be filtered out later.  Again, an upper bound
+         suffices.  */
+
+      cp = opts;
+
+      while (cp && *cp)
+        {
+          extract_string (&cp);
+          num_lto_c_args++;
+        }
+      obstack_free (&temporary_obstack, temporary_firstobj);
+
+      if (debug)
+       num_lto_c_args++;
+
+      /* Increment the argument count by the number of initial
+        arguments added below.  */
+      num_lto_c_args += 9;
+
+      lto_c_argv = (char **) xcalloc (sizeof (char *), num_lto_c_args);
+      lto_c_ptr = CONST_CAST2 (const char **, char **, lto_c_argv);
+
+      *lto_c_ptr++ = lto_wrapper;
+      *lto_c_ptr++ = c_file_name;
+
+      cp = opts;
+
+      while (cp && *cp)
+        {
+          const char *s = extract_string (&cp);
+
+         /* Pass the option or argument to the wrapper.  */
+         *lto_c_ptr++ = xstrdup (s);
+        }
+      obstack_free (&temporary_obstack, temporary_firstobj);
+
+      if (debug)
+       *lto_c_ptr++ = xstrdup ("-debug");
+
+      /* Add LTO objects to the wrapper command line.  */
+      for (list = lto_objects.first; list; list = list->next)
+       *lto_c_ptr++ = list->name;
+
+      *lto_c_ptr = NULL;
+
+      /* Save intermediate WPA files in lto1 if debug.  */
+      if (debug)
+       putenv (xstrdup ("WPA_SAVE_LTRANS=1"));
+
+      /* Run the LTO back end.  */
+      pex = collect_execute (prog, lto_c_argv, NULL, NULL, PEX_SEARCH);
+      {
+       int c;
+       FILE *stream;
+       size_t i, num_files;
+       char *start, *end;
+
+       stream = pex_read_output (pex, 0);
+       gcc_assert (stream);
+
+       num_files = 0;
+       while ((c = getc (stream)) != EOF)
+         {
+           obstack_1grow (&temporary_obstack, c);
+           if (c == '\n')
+             ++num_files;
+         }
+
+       lto_o_files = XNEWVEC (char *, num_files + 1);
+       lto_o_files[num_files] = NULL;
+       start = XOBFINISH (&temporary_obstack, char *);
+       for (i = 0; i < num_files; ++i)
+         {
+           end = start;
+           while (*end != '\n')
+             ++end;
+           *end = '\0';
+
+           lto_o_files[i] = xstrdup (start);
+
+           start = end + 1;
+         }
+
+       obstack_free (&temporary_obstack, temporary_firstobj);
+      }
+      do_wait (prog, pex);
+      pex = NULL;
+
+      /* After running the LTO back end, we will relink, substituting
+        the LTO output for the object files that we submitted to the
+        LTO. Here, we modify the linker command line for the relink.  */
+      p = CONST_CAST2 (const char **, char **, lto_ld_argv);
+      lto_o_ptr = CONST_CAST2 (const char **, char **, lto_o_files);
+
+      while (*p != NULL)
+        {
+          for (list = lto_objects.first; list; list = list->next)
+            {
+              if (*p == list->name) /* Note test for pointer equality!  */
+                {
+                  /* Excise argument from linker command line.  */
+                  if (*lto_o_ptr)
+                    {
+                      /* Replace first argument with LTO output file.  */
+                      *p++ = *lto_o_ptr++;
+                    }
+                  else
+                    {
+                      /* Move following arguments one position earlier,
+                         overwriting the current argument.  */
+                      q = p;
+                      r = p + 1;
+                      while (*r != NULL)
+                        *q++ = *r++;
+                      *q = NULL;
+                    }
+
+                  /* No need to continue searching the LTO object list.  */
+                  break;
+                }
+            }
+
+          /* If we didn't find a match, move on to the next argument.
+             Otherwise, P has been set to the correct argument position
+             at which to continue.  */
+          if (!list) ++p;
+        }
+
+      /* The code above assumes we will never have more lto output files than
+        input files.  Otherwise, we need to resize lto_ld_argv.  Check this
+        assumption.  */
+      if (*lto_o_ptr)
+       fatal ("too many lto output files");
+
+      /* Run the linker again, this time replacing the object files
+         optimized by the LTO with the temporary file generated by the LTO.  */
+      fork_execute ("ld", lto_ld_argv);
+
+      maybe_unlink_list (lto_o_files);
+    }
+  else if (force)
+    {
+      /* Our caller is relying on us to do the link
+         even though there is no LTO back end work to be done.  */
+      fork_execute  ("ld", lto_ld_argv);
+    }
+}
 \f
 /* Main program.  */
 
@@ -935,14 +1210,25 @@ main (int argc, char **argv)
 
   /* Parse command line early for instances of -debug.  This allows
      the debug flag to be set before functions like find_a_file()
-     are called.  */
+     are called.  We also look for the -flto or -fwhopr flag to know
+     what LTO mode we are in.  */
   {
     int i;
+    bool use_plugin = false;
 
     for (i = 1; argv[i] != NULL; i ++)
       {
        if (! strcmp (argv[i], "-debug"))
          debug = 1;
+        else if (! strcmp (argv[i], "-flto") && ! use_plugin)
+          lto_mode = LTO_MODE_LTO;
+        else if (! strcmp (argv[i], "-fwhopr") && ! use_plugin)
+          lto_mode = LTO_MODE_WHOPR;
+        else if (! strcmp (argv[i], "-plugin"))
+         {
+           use_plugin = true;
+           lto_mode = LTO_MODE_NONE;
+         }
 #ifdef COLLECT_EXPORT_LIST
        /* since -brtl, -bexport, -b64 are not position dependent
           also check for them here */
@@ -1194,6 +1480,20 @@ main (int argc, char **argv)
                }
              break;
 
+            case 'f':
+             if (strcmp (arg, "-flto") == 0 || strcmp (arg, "-fwhopr") == 0)
+               {
+#ifdef ENABLE_LTO
+                 /* Do not pass LTO flag to the linker. */
+                 ld1--;
+                 ld2--;
+#else
+                 error ("LTO support has not been enabled in this "
+                        "configuration");
+#endif
+               }
+              break;
+
            case 'l':
              if (first_file)
                {
@@ -1456,6 +1756,9 @@ main (int argc, char **argv)
        if (export_file != 0 && export_file[0])
          maybe_unlink (export_file);
 #endif
+       if (lto_mode)
+         maybe_run_lto_and_relink (ld1_argv, object_lst, object, false);
+
        maybe_unlink (c_file);
        maybe_unlink (o_file);
        return 0;
@@ -1498,6 +1801,9 @@ main (int argc, char **argv)
       if (ld1_filter == SCAN_NOTHING)
        do_tlink (ld1_argv, object_lst);
 
+      if (lto_mode)
+        maybe_run_lto_and_relink (ld1_argv, object_lst, object, false);
+
       /* Strip now if it was requested on the command line.  */
       if (strip_flag)
        {
@@ -1591,9 +1897,15 @@ main (int argc, char **argv)
 #ifdef COLLECT_EXPORT_LIST
   /* On AIX we must call tlink because of possible templates resolution.  */
   do_tlink (ld2_argv, object_lst);
+
+  if (lto_mode)
+    maybe_run_lto_and_relink (ld2_argv, object_lst, object, false);
 #else
   /* Otherwise, simply call ld because tlink is already done.  */
-  fork_execute ("ld", ld2_argv);
+  if (lto_mode)
+    maybe_run_lto_and_relink (ld2_argv, object_lst, object, true);
+  else
+    fork_execute ("ld", ld2_argv);
 
   /* Let scan_prog_file do any final mods (OSF/rose needs this for
      constructors/destructors in shared libraries.  */
@@ -1661,7 +1973,7 @@ do_wait (const char *prog, struct pex_obj *pex)
 
 struct pex_obj *
 collect_execute (const char *prog, char **argv, const char *outname,
-                const char *errname)
+                const char *errname, int flags)
 {
   struct pex_obj *pex;
   const char *errmsg;
@@ -1737,7 +2049,7 @@ collect_execute (const char *prog, char **argv, const char *outname,
   if (pex == NULL)
     fatal_perror ("pex_init failed");
 
-  errmsg = pex_run (pex, PEX_LAST | PEX_SEARCH, argv[0], argv, outname,
+  errmsg = pex_run (pex, flags, argv[0], argv, outname,
                    errname, &err);
   if (errmsg != NULL)
     {
@@ -1761,7 +2073,7 @@ fork_execute (const char *prog, char **argv)
 {
   struct pex_obj *pex;
 
-  pex = collect_execute (prog, argv, NULL, NULL);
+  pex = collect_execute (prog, argv, NULL, NULL, PEX_LAST | PEX_SEARCH);
   do_wait (prog, pex);
 }
 \f
@@ -1776,6 +2088,17 @@ maybe_unlink (const char *file)
     notice ("[Leaving %s]\n", file);
 }
 
+/* Call maybe_unlink on the NULL-terminated list, FILE_LIST.  */
+
+static void
+maybe_unlink_list (char **file_list)
+{
+  char **tmp = file_list;
+
+  while (*tmp)
+    maybe_unlink (*(tmp++));
+}
+
 \f
 static long sequence_number = 0;
 
@@ -2170,6 +2493,25 @@ write_aix_file (FILE *stream, struct id *list)
 \f
 #ifdef OBJECT_FORMAT_NONE
 
+/* Check to make sure the file is an ELF file.  LTO objects must
+   be in ELF format.  */
+
+static bool
+is_elf (const char *prog_name)
+{
+  FILE *f;
+  char buf[4];
+  static char magic[4] = { 0x7f, 'E', 'L', 'F' };
+
+  f = fopen (prog_name, "r");
+  if (f == NULL)
+    return false;
+  if (fread (buf, sizeof (buf), 1, f) != 1)
+    buf[0] = 0;
+  fclose (f);
+  return memcmp (buf, magic, sizeof (magic)) == 0;
+}
+
 /* Generic version to scan the name list of the loaded program for
    the symbols g++ uses for static constructors and destructors.  */
 
@@ -2189,10 +2531,17 @@ scan_prog_file (const char *prog_name, scanpass which_pass,
   int err;
   char *p, buf[1024];
   FILE *inf;
+  int found_lto = 0;
 
   if (which_pass == PASS_SECOND)
     return;
 
+  /* LTO objects must be in ELF format.  This check prevents
+     us from accepting an archive containing LTO objects, which
+     gcc cannnot currently handle.  */
+  if (which_pass == PASS_LTOINFO && !is_elf (prog_name))
+    return;
+
   /* If we do not have an `nm', complain.  */
   if (nm_file_name == 0)
     fatal ("cannot find 'nm'");
@@ -2223,7 +2572,8 @@ scan_prog_file (const char *prog_name, scanpass which_pass,
   if (pex == NULL)
     fatal_perror ("pex_init failed");
 
-  errmsg = pex_run (pex, 0, nm_file_name, real_nm_argv, NULL, NULL, &err);
+  errmsg = pex_run (pex, 0, nm_file_name, real_nm_argv, NULL, HOST_BIT_BUCKET,
+                   &err);
   if (errmsg != NULL)
     {
       if (err != 0)
@@ -2245,7 +2595,12 @@ scan_prog_file (const char *prog_name, scanpass which_pass,
     fatal_perror ("can't open nm output");
 
   if (debug)
-    fprintf (stderr, "\nnm output with constructors/destructors.\n");
+    {
+      if (which_pass == PASS_LTOINFO)
+        fprintf (stderr, "\nnm output with LTO info marker symbol.\n");
+      else
+        fprintf (stderr, "\nnm output with constructors/destructors.\n");
+    }
 
   /* Read each line of nm output.  */
   while (fgets (buf, sizeof buf, inf) != (char *) 0)
@@ -2253,6 +2608,33 @@ scan_prog_file (const char *prog_name, scanpass which_pass,
       int ch, ch2;
       char *name, *end;
 
+      if (debug)
+        fprintf (stderr, "\t%s\n", buf);
+
+      if (which_pass == PASS_LTOINFO)
+        {
+          if (found_lto)
+            continue;
+
+          /* Look for the LTO info marker symbol, and add filename to
+             the LTO objects list if found.  */
+          for (p = buf; (ch = *p) != '\0' && ch != '\n'; p++)
+            if (ch == ' '
+               && (strncmp (p +1 , "gnu_lto_v1", 10) == 0)
+               && ISSPACE( p[11]))
+              {
+                add_lto_object (&lto_objects, prog_name);
+
+                /* We need to read all the input, so we can't just
+                   return here.  But we can avoid useless work.  */
+                found_lto = 1;
+
+                break;
+              }
+
+         continue;
+        }
+
       /* If it contains a constructor or destructor name, add the name
         to the appropriate list unless this is a kind of symbol we're
         not supposed to even consider.  */
@@ -2319,9 +2701,6 @@ scan_prog_file (const char *prog_name, scanpass which_pass,
        default:                /* not a constructor or destructor */
          continue;
        }
-
-      if (debug)
-       fprintf (stderr, "\t%s\n", buf);
     }
 
   if (debug)
index 3990b4f..81113cf 100644 (file)
@@ -23,7 +23,7 @@ along with GCC; see the file COPYING3.  If not see
 extern void do_tlink (char **, char **);
 
 extern struct pex_obj *collect_execute (const char *, char **, const char *,
-                                       const char *);
+                                       const char *, int flags);
 
 extern void collect_exit (int) ATTRIBUTE_NORETURN;
 
index 189f476..de43201 100644 (file)
@@ -749,6 +749,19 @@ floop-optimize
 Common
 Does nothing.  Preserved for backward compatibility.
 
+flto
+Common Var(flag_lto)
+Enable link-time optimization.
+
+; The initial value of -1 comes from Z_DEFAULT_COMPRESSION in zlib.h.
+flto-compression-level=
+Common Joined UInteger Var(flag_lto_compression_level) Init(-1)
+-flto-compression-level=<number> Use zlib compression level <number> for IL
+
+flto-report
+Common Report Var(flag_lto_report) Init(0) Optimization
+Report various link-time optimization statistics
+
 fmath-errno
 Common Report Var(flag_errno_math) Init(1) Optimization
 Set errno after built-in math functions
@@ -1432,6 +1445,10 @@ fweb
 Common Report Var(flag_web) Init(2) Optimization
 Construct webs and split unrelated uses of single variable
 
+fwhopr
+Common Var(flag_whopr)
+Enable partitioned link-time optimization.
+
 ftree-builtin-call-dce
 Common Report Var(flag_tree_builtin_call_dce) Init(0) Optimization
 Enable conditional dead code elimination for builtin calls
index 12573fd..220ff9f 100644 (file)
 #endif
 
 
+/* Define to enable LTO support. */
+#ifndef USED_FOR_TARGET
+#undef ENABLE_LTO
+#endif
+
+
 /* Define to 1 if translation of program messages to the user's native
    language is requested. */
 #ifndef USED_FOR_TARGET
 #endif
 
 
+/* Define if libelf is in use. */
+#ifndef USED_FOR_TARGET
+#undef HAVE_libelf
+#endif
+
+
 /* Define if mpc is in use. */
 #ifndef USED_FOR_TARGET
 #undef HAVE_mpc
index cafe2b3..f44bc99 100644 (file)
@@ -20052,8 +20052,10 @@ rs6000_output_function_epilogue (FILE *file,
         use language_string.
         C is 0.  Fortran is 1.  Pascal is 2.  Ada is 3.  C++ is 9.
         Java is 13.  Objective-C is 14.  Objective-C++ isn't assigned
-        a number, so for now use 9.  */
-      if (! strcmp (language_string, "GNU C"))
+        a number, so for now use 9.  LTO isn't assigned a number either,
+        so for now use 0.  */
+      if (! strcmp (language_string, "GNU C")
+         || ! strcmp (language_string, "GNU GIMPLE"))
        i = 0;
       else if (! strcmp (language_string, "GNU F77")
               || ! strcmp (language_string, "GNU Fortran"))
index a1e28a7..e4f3c2e 100755 (executable)
@@ -741,6 +741,8 @@ ac_subst_vars='LTLIBOBJS
 LIBOBJS
 enable_plugin
 pluginlibs
+LIBELFINC
+LIBELFLIBS
 CLOOGINC
 CLOOGLIBS
 PPLINC
@@ -808,6 +810,7 @@ subdirs
 slibdir
 dollar
 gcc_tooldir
+enable_lto
 MAINT
 zlibinc
 zlibdir
@@ -1061,7 +1064,9 @@ GMPINC
 PPLLIBS
 PPLINC
 CLOOGLIBS
-CLOOGINC'
+CLOOGINC
+LIBELFLIBS
+LIBELFINC'
 
 
 # Initialize some variables set by options.
@@ -1799,6 +1804,8 @@ Some influential environment variables:
   PPLINC      How to find PPL include files
   CLOOGLIBS   How to link CLOOG
   CLOOGINC    How to find CLOOG include files
+  LIBELFLIBS  How to link libelf
+  LIBELFINC   How to find libelf include files
 
 Use these variables to override the choices made by `configure' or to help
 it to find libraries and programs with nonstandard names/locations.
@@ -11565,13 +11572,13 @@ if test "${lt_cv_nm_interface+set}" = set; then :
 else
   lt_cv_nm_interface="BSD nm"
   echo "int some_variable = 0;" > conftest.$ac_ext
-  (eval echo "\"\$as_me:11568: $ac_compile\"" >&5)
+  (eval echo "\"\$as_me:11575: $ac_compile\"" >&5)
   (eval "$ac_compile" 2>conftest.err)
   cat conftest.err >&5
-  (eval echo "\"\$as_me:11571: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+  (eval echo "\"\$as_me:11578: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
   (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
   cat conftest.err >&5
-  (eval echo "\"\$as_me:11574: output\"" >&5)
+  (eval echo "\"\$as_me:11581: output\"" >&5)
   cat conftest.out >&5
   if $GREP 'External.*some_variable' conftest.out > /dev/null; then
     lt_cv_nm_interface="MS dumpbin"
@@ -12776,7 +12783,7 @@ ia64-*-hpux*)
   ;;
 *-*-irix6*)
   # Find out which ABI we are using.
-  echo '#line 12779 "configure"' > conftest.$ac_ext
+  echo '#line 12786 "configure"' > conftest.$ac_ext
   if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
@@ -14436,11 +14443,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:14439: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:14446: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:14443: \$? = $ac_status" >&5
+   echo "$as_me:14450: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -14775,11 +14782,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:14778: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:14785: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:14782: \$? = $ac_status" >&5
+   echo "$as_me:14789: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -14880,11 +14887,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:14883: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:14890: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:14887: \$? = $ac_status" >&5
+   echo "$as_me:14894: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -14935,11 +14942,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:14938: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:14945: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:14942: \$? = $ac_status" >&5
+   echo "$as_me:14949: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -17317,7 +17324,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 17320 "configure"
+#line 17327 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -17413,7 +17420,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 17416 "configure"
+#line 17423 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -19369,11 +19376,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:19372: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:19379: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:19376: \$? = $ac_status" >&5
+   echo "$as_me:19383: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -19468,11 +19475,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:19471: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:19478: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:19475: \$? = $ac_status" >&5
+   echo "$as_me:19482: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -19520,11 +19527,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:19523: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:19530: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:19527: \$? = $ac_status" >&5
+   echo "$as_me:19534: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
        all_compilers="$all_compilers $compilers"
        all_outputs="$all_outputs $outputs"
        all_gtfiles="$all_gtfiles [$subdir] $gtfiles"
+        case ",$enable_languages," in
+               *,lto,*)
+
+$as_echo "#define ENABLE_LTO 1" >>confdefs.h
+
+                   enable_lto=yes
+
+                   ;;
+               *) ;;
+       esac
 done
 
 # Pick up gtfiles for c
@@ -24941,6 +24958,14 @@ $as_echo "#define HAVE_cloog 1" >>confdefs.h
 
 fi
 
+
+
+if test "x${LIBELFLIBS}" != "x" ; then
+
+$as_echo "#define HAVE_libelf 1" >>confdefs.h
+
+fi
+
 # Check for plugin support
 # Check whether --enable-plugin was given.
 if test "${enable_plugin+set}" = set; then :
index d7597d2..79de6cd 100644 (file)
@@ -4041,6 +4041,14 @@ changequote([,])dnl
        all_compilers="$all_compilers $compilers"
        all_outputs="$all_outputs $outputs"
        all_gtfiles="$all_gtfiles [[$subdir]] $gtfiles"
+        case ",$enable_languages," in
+               *,lto,*)
+                   AC_DEFINE(ENABLE_LTO, 1, [Define to enable LTO support.])
+                   enable_lto=yes
+                   AC_SUBST(enable_lto)
+                   ;;
+               *) ;;
+       esac
 done
 
 # Pick up gtfiles for c
@@ -4213,6 +4221,12 @@ if test "x${CLOOGLIBS}" != "x" ; then
    AC_DEFINE(HAVE_cloog, 1, [Define if cloog is in use.])
 fi
 
+AC_ARG_VAR(LIBELFLIBS,[How to link libelf])
+AC_ARG_VAR(LIBELFINC,[How to find libelf include files])
+if test "x${LIBELFLIBS}" != "x" ; then 
+   AC_DEFINE(HAVE_libelf, 1, [Define if libelf is in use.])
+fi
+
 # Check for plugin support
 AC_ARG_ENABLE(plugin,
 [  --enable-plugin         enable plugin support],
index bfa336e..6bf446b 100644 (file)
@@ -356,6 +356,15 @@ Alternatively, if an MPC source distribution is found in a
 subdirectory of your GCC sources named @file{mpc}, it will be built
 together with GCC@.
 
+@item libelf version 0.8.12 (or later)
+
+Necessary to build link-time optimization (LTO) support.  It can be
+downloaded from @uref{http://www.mr511.de/software/libelf-0.8.12.tar.gz},
+though it is commonly available in several systems.
+
+The @option{--with-libelf} configure option should be used if libelf is
+not installed in your default library search patch.
+
 @end table
 
 @heading Tools/packages necessary for modifying GCC
@@ -1893,6 +1902,30 @@ Use the @code{WCHAR} and Win32 W functions natively.  Does @emph{not}
 add @code{-lunicows} to @file{libgcj.spec}.  The built executables will
 only run on Microsoft Windows NT and above.
 @end table
+
+@item --enable-lto
+Enable support for link-time optimization (LTO).  This is enabled by
+default if a working libelf implementation is found (see
+@option{--with-libelf}).
+
+@item --with-libelf=@var{pathname}
+@itemx --with-libelf-include=@var{pathname}
+@itemx --with-libelf-lib=@var{pathname}
+If you do not have libelf installed in a standard location and you
+want to enable support for link-time optimization (LTO), you can
+explicitly specify the directory where libelf is installed
+(@samp{--with-libelf=@var{libelfinstalldir}}).  The
+@option{--with-libelf=@var{libelfinstalldir}} option is shorthand for
+@option{--with-libelf-include=@var{libelfinstalldir}/include}
+@option{--with-libelf-lib=@var{libelfinstalldir}/lib}.
+
+@item --enable-gold
+Enable support for using @command{gold} as the linker.  If gold support is
+enabled together with @option{--enable-lto}, an additional directory
+@file{lto-plugin} will be built.  The code in this directory is a
+plugin for gold that allows the link-time optimizer to extract object
+files with LTO information out of library archives.  See
+@option{-flto} and @option{-fwhopr} for details.
 @end table
 
 @subsubheading AWT-Specific Options
index e12241c..9d39624 100644 (file)
@@ -349,8 +349,8 @@ Objective-C and Objective-C++ Dialects}.
 -fno-ira-share-spill-slots -fira-verbose=@var{n} @gol
 -fivopts -fkeep-inline-functions -fkeep-static-consts @gol
 -floop-block -floop-interchange -floop-strip-mine -fgraphite-identity @gol
--floop-parallelize-all @gol
--fmerge-all-constants -fmerge-constants -fmodulo-sched @gol
+-floop-parallelize-all -flto -flto-compression-level -flto-report -fltrans @gol
+-fltrans-output-list -fmerge-all-constants -fmerge-constants -fmodulo-sched @gol
 -fmodulo-sched-allow-regmoves -fmove-loop-invariants -fmudflap @gol
 -fmudflapir -fmudflapth -fno-branch-count-reg -fno-default-inline @gol
 -fno-defer-pop -fno-function-cse -fno-guess-branch-probability @gol
@@ -389,7 +389,7 @@ Objective-C and Objective-C++ Dialects}.
 -funit-at-a-time -funroll-all-loops -funroll-loops @gol
 -funsafe-loop-optimizations -funsafe-math-optimizations -funswitch-loops @gol
 -fvariable-expansion-in-unroller -fvect-cost-model -fvpt -fweb @gol
--fwhole-program @gol
+-fwhole-program -fwhopr -fwpa -use-linker-plugin @gol
 --param @var{name}=@var{value}
 -O  -O0  -O1  -O2  -O3  -Os}
 
@@ -7111,6 +7111,223 @@ compilation unit, not for the single source file itself.
 
 This option implies @option{-fwhole-file} for Fortran programs.
 
+@item -flto
+@opindex flto
+This option runs the standard link-time optimizer.  When invoked
+with source code, it generates GIMPLE (one of GCC's internal
+representations) and writes it to special ELF sections in the object
+file.  When the object files are linked together, all the function
+bodies are read from these ELF sections and instantiated as if they
+had been part of the same translation unit.
+
+To use the link-timer optimizer, @option{-flto} needs to be specified at
+compile time and during the final link.  For example,
+
+@smallexample
+gcc -c -O2 -flto foo.c
+gcc -c -O2 -flto bar.c
+gcc -o myprog -flto -O2 foo.o bar.o
+@end smallexample
+
+The first two invocations to GCC will save a bytecode representation
+of GIMPLE into special ELF sections inside @file{foo.o} and
+@file{bar.o}.  The final invocation will read the GIMPLE bytecode from
+@file{foo.o} and @file{bar.o}, merge the two files into a single
+internal image, and compile the result as usual.  Since both
+@file{foo.o} and @file{bar.o} are merged into a single image, this
+causes all the inter-procedural analyses and optimizations in GCC to
+work across the two files as if they were a single one.  This means,
+for example, that the inliner will be able to inline functions in
+@file{bar.o} into functions in @file{foo.o} and vice-versa.
+
+Another (simpler) way to enable link-time optimization is,
+
+@smallexample
+gcc -o myprog -flto -O2 foo.c bar.c
+@end smallexample
+
+The above will generate bytecode for @file{foo.c} and @file{bar.c},
+merge them together into a single GIMPLE representation and optimize
+them as usual to produce @file{myprog}.
+
+The only important thing to keep in mind is that to enable link-time
+optimizations the @option{-flto} flag needs to be passed to both the
+compile and the link commands.
+
+Note that when a file is compiled with @option{-flto}, the generated
+object file will be larger than a regular object file because it will
+contain GIMPLE bytecodes and the usual final code.  This means that
+object files with LTO information can be linked as a normal object
+file.  So, in the previous example, if the final link is done with
+
+@smallexample
+gcc -o myprog foo.o bar.o
+@end smallexample
+
+The only difference will be that no inter-procedural optimizations
+will be applied to produce @file{myprog}.  The two object files
+@file{foo.o} and @file{bar.o} will be simply sent to the regular
+linker.
+
+Additionally, the optimization flags used to compile individual files
+are not necessarily related to those used at link-time.  For instance,
+
+@smallexample
+gcc -c -O0 -flto foo.c
+gcc -c -O0 -flto bar.c
+gcc -o myprog -flto -O3 foo.o bar.o
+@end smallexample
+
+This will produce individual object files with unoptimized assembler
+code, but the resulting binary @file{myprog} will be optimized at
+@option{-O3}.  Now, if the final binary is generated without
+@option{-flto}, then @file{myprog} will not be optimized.
+
+When producing the final binary with @option{-flto}, GCC will only
+apply link-time optimizations to those files that contain bytecode.
+Therefore, you can mix and match object files and libraries with
+GIMPLE bytecodes and final object code.  GCC will automatically select
+which files to optimize in LTO mode and which files to link without
+further processing.
+
+There are some code generation flags that GCC will preserve when
+generating bytecodes, as they need to be used during the final link
+stage.  Currently, the following options are saved into the GIMPLE
+bytecode files: @option{-fPIC}, @option{-fcommon} and all the
+@option{-m} target flags.
+
+At link time, these options are read-in and reapplied.  Note that the
+current implementation makes no attempt at recognizing conflicting
+values for these options.  If two or more files have a conflicting
+value (e.g., one file is compiled with @option{-fPIC} and another
+isn't), the compiler will simply use the last value read from the
+bytecode files.  It is recommended, then, that all the files
+participating in the same link be compiled with the same options.
+
+Another feature of LTO is that it is possible to apply interprocedural
+optimizations on files written in different languages.  This requires
+some support in the language front end.  Currently, the C, C++ and
+Fortran front ends are capable of emitting GIMPLE bytecodes, so
+something like this should work
+
+@smallexample
+gcc -c -flto foo.c
+g++ -c -flto bar.cc
+gfortran -c -flto baz.f90
+g++ -o myprog -flto -O3 foo.o bar.o baz.o -lgfortran
+@end smallexample
+
+Notice that the final link is done with @command{g++} to get the C++
+runtime libraries and @option{-lgfortran} is added to get the Fortran
+runtime libraries.  In general, when mixing languages in LTO mode, you
+should use the same link command used when mixing languages in a
+regular (non-LTO) compilation.  This means that if your build process
+was mixing languages before, all you need to add is @option{-flto} to
+all the compile and link commands.
+
+If object files containing GIMPLE bytecode are stored in a library
+archive, say @file{libfoo.a}, it is possible to extract and use them
+in an LTO link if you are using @command{gold} as the linker (which,
+in turn requires GCC to be configured with @option{--enable-gold}).
+To enable this feature, use the flag @option{-use-linker-plugin} at
+link-time:
+
+@smallexample
+gcc -o myprog -O2 -flto -use-linker-plugin a.o b.o -lfoo
+@end smallexample
+
+With the linker plugin enabled, @command{gold} will extract the needed
+GIMPLE files from @file{libfoo.a} and pass them on to the running GCC
+to make them part of the aggregated GIMPLE image to be optimized.
+
+If you are not using @command{gold} and/or do not specify
+@option{-use-linker-plugin} then the objects inside @file{libfoo.a}
+will be extracted and linked as usual, but they will not participate
+in the LTO optimization process.
+
+Regarding portability: the current implementation of LTO makes no
+attempt at generating bytecode that can be ported between different
+types of hosts.  The bytecode files are versioned and there is a
+strict version check, so bytecode files generated in one version of
+GCC will not work with an older/newer version of GCC.
+
+This option is disabled by default.
+
+@item -fwhopr
+@opindex fwhopr
+This option is identical in functionality to @option{-flto} but it
+differs in how the final link stage is executed.  Instead of loading
+all the function bodies in memory, the callgraph is analyzed and
+optimization decisions are made (whole program analysis or WPA). Once
+optimization decisions are made, the callgraph is partitioned and the
+different sections are compiled separately (local transformations or
+LTRANS)@.  This process allows optimizations on very large programs
+that otherwise would not fit in memory.  This option enables
+@option{-fwpa} and @option{-fltrans} automatically.
+
+Disabled by default.
+
+@item -fwpa
+@opindex fwpa
+This is an internal option used by GCC when compiling with
+@option{-fwhopr}.  You should never need to use it.
+
+This option runs the link-time optimizer in the whole-program-analysis
+(WPA) mode, which reads in summary information from all inputs and
+performs a whole-program analysis based on summary information only.
+It generates object files for subsequent runs of the link-time
+optimizer where individual object files are optimized using both
+summary information from the WPA mode and the actual function bodies.
+It then drives the LTRANS phase.
+
+Disabled by default.
+
+@item -fltrans
+@opindex fltrans
+This is an internal option used by GCC when compiling with
+@option{-fwhopr}.  You should never need to use it.
+
+This option runs the link-time optimizer in the local-transformation (LTRANS)
+mode, which reads in output from a previous run of the LTO in WPA mode.
+In the LTRANS mode, LTO optimizes an object and produces the final assembly.
+
+Disabled by default.
+
+@item -fltrans-output-list=@var{file}
+@opindex fltrans-output-list
+This is an internal option used by GCC when compiling with
+@option{-fwhopr}.  You should never need to use it.
+
+This option specifies a file to which the names of LTRANS output files are
+written.  This option is only meaningful in conjunction with @option{-fwpa}.
+
+Disabled by default.
+
+@item -flto-compression-level=@var{n}
+This option specifies the level of compression used for intermediate
+language written to LTO object files, and is only meaningful in
+conjunction with LTO mode (@option{-fwhopr}, @option{-flto}).  Valid
+values are 0 (no compression) to 9 (maximum compression).  Values
+outside this range are clamped to either 0 or 9.  If the option is not
+given, a default balanced compression setting is used.
+
+@item -flto-report
+Prints a report with internal details on the workings of the link-time
+optimizer.  The contents of this report vary from version to version,
+it is meant to be useful to GCC developers when processing object
+files in LTO mode (via @option{-fwhopr} or @option{-flto}).
+
+Disabled by default.
+
+@item -use-linker-plugin
+Enables the extraction of objects with GIMPLE bytecode information
+from library archives.  This option relies on features available only
+in @command{gold}, so to use this you must configure GCC with
+@option{--enable-gold}.  See @option{-flto} for a description on the
+effect of this flag and how to use it.
+
+Disabled by default.
+
 @item -fcprop-registers
 @opindex fcprop-registers
 After register allocation and post-register allocation instruction splitting,
index 22b27e7..4cbc36f 100644 (file)
@@ -93,12 +93,16 @@ The Objective-C and Objective-C++ runtime library.
 @item libstdc++-v3
 The C++ runtime library.
 
+@item lto-plugin
+Plugin used by @command{gold} if link-time optimizations are enabled.
+
 @item maintainer-scripts
 Scripts used by the @code{gccadmin} account on @code{gcc.gnu.org}.
 
 @item zlib
-The @code{zlib} compression library, used by the Java front end and as
-part of the Java runtime library.
+The @code{zlib} compression library, used by the Java front end, as
+part of the Java runtime library, and for compressing and uncompressing
+GCC's intermediate language in LTO object files.
 @end table
 
 The build system in the top level directory, including how recursion
@@ -137,11 +141,12 @@ The @file{gcc} directory contains the following subdirectories:
 @item @var{language}
 Subdirectories for various languages.  Directories containing a file
 @file{config-lang.in} are language subdirectories.  The contents of
-the subdirectories @file{cp} (for C++), @file{objc} (for Objective-C)
-and @file{objcp} (for Objective-C++) are documented in this manual
-(@pxref{Passes, , Passes and Files of the Compiler}); those for other
-languages are not.  @xref{Front End, , Anatomy of a Language Front End},
-for details of the files in these directories.
+the subdirectories @file{cp} (for C++), @file{lto} (for LTO),
+@file{objc} (for Objective-C) and @file{objcp} (for Objective-C++) are
+documented in this manual (@pxref{Passes, , Passes and Files of the
+Compiler}); those for other languages are not.  @xref{Front End, ,
+Anatomy of a Language Front End}, for details of the files in these
+directories.
 
 @item config
 Configuration files for supported architectures and operating
@@ -821,6 +826,7 @@ here; FIXME: document the others.
 * Ada Tests::       The Ada language testsuites.
 * C Tests::         The C language testsuites.
 * libgcj Tests::    The Java library testsuites.
+* LTO Testing::     Support for testing link-time optimizations.
 * gcov Testing::    Support for testing gcov.
 * profopt Testing:: Support for testing profile-directed optimizations.
 * compat Testing::  Support for testing binary compatibility.
@@ -1347,6 +1353,42 @@ bugs in libgcj that had caused Mauve test failures.
 
 We encourage developers to contribute test cases to Mauve.
 
+@node LTO Testing
+@subsection Support for testing link-time optimizations
+
+Tests for link-time optimizations usually require multiple source files
+that are compiled separately, perhaps with different sets of options.
+There are several special-purpose test directives used for these tests.
+
+@table @code
+@item @{ dg-lto-do @var{do-what-keyword} @}
+@var{do-what-keyword} specifies how the test is compiled and whether
+it is executed.  It is one of:
+
+@table @code
+@item assemble
+Compile with @option{-c} to produce a relocatable object file.
+@item link
+Compile, assemble, and link to produce an executable file.
+@item run
+Produce and run an executable file, which is expected to return
+an exit code of 0.
+@end table
+
+The default is @code{assemble}.  That can be overridden for a set of
+tests by redefining @code{dg-do-what-default} within the @code{.exp}
+file for those tests.
+
+Unlike @code{dg-do}, @code{dg-lto-do} does not support an optional
+@samp{target} or @samp{xfail} list.  Use @code{dg-skip-if},
+@code{dg-xfail-if}, or @code{dg-xfail-run-if}.
+
+@item @{ dg-lto-options @{ @{ @var{options} @} [@{ @var{options} @}] @} [@{ target @var{selector} @}]@}
+This directive provides a list of one or more sets of compiler options
+to override @var{LTO_OPTIONS}.  Each test will be compiled and run with
+each of these sets of options.
+@end table
+
 @node gcov Testing
 @subsection Support for testing @command{gcov}
 
index bb26bf4..c00bcd3 100644 (file)
@@ -2886,7 +2886,14 @@ output_ttype (tree type, int tt_format, int tt_format_size)
     {
       struct varpool_node *node;
 
-      type = lookup_type_for_runtime (type);
+      /* FIXME lto.  pass_ipa_free_lang_data changes all types to
+        runtime types so TYPE should already be a runtime type
+        reference.  When pass_ipa_free_lang data is made a default
+        pass, we can then remove the call to lookup_type_for_runtime
+        below.  */
+      if (TYPE_P (type))
+       type = lookup_type_for_runtime (type);
+
       value = expand_expr (type, NULL_RTX, VOIDmode, EXPAND_INITIALIZER);
 
       /* Let cgraph know that the rtti decl is used.  Not all of the
index 8b71302..bd8b82d 100644 (file)
@@ -111,6 +111,17 @@ extern int optimize;
 
 extern int optimize_size;
 
+/* True if this is the LTO front end (lto1).  This is used to disable
+   gimple generation and lowering passes that are normally run on the
+   output of a front end.  These passes must be bypassed for lto since
+   they have already been done before the gimple was written.  */ 
+
+extern bool in_lto_p;
+
+/* Nonzero if we should write GIMPLE bytecode for link-time optimization.  */
+
+extern int flag_generate_lto;
+
 /* Used to set the level of -Wstrict-aliasing, when no level is specified.  
    The external way to set the default level is to use
    -Wstrict-aliasing=level.  
index c325d25..c3444d4 100644 (file)
@@ -1,3 +1,7 @@
+2009-10-03  Richard Guenther  <rguenther@suse.de>
+
+       * options.c (gfc_post_options): Handle -flto and -fwhopr.
+
 2009-10-02  Tobias Burnus  <burnus@net-b.de>
 
        PR fortran/41479
index 3e20f8e..d2c6d9b 100644 (file)
@@ -242,6 +242,28 @@ gfc_post_options (const char **pfilename)
   if (flag_whole_program)
     gfc_option.flag_whole_file = 1;
 
+  if (flag_lto || flag_whopr)
+    {
+#ifdef ENABLE_LTO
+      flag_generate_lto = 1;
+
+      /* When generating IL, do not operate in whole-program mode.
+        Otherwise, symbols will be privatized too early, causing link
+        errors later.  */
+      flag_whole_program = 0;
+
+      /* But do enable whole-file mode.  */
+      gfc_option.flag_whole_file = 1;
+#else
+      error ("LTO support has not been enabled in this configuration");
+#endif
+    }
+
+  /* Reconcile -flto and -fwhopr.  Set additional flags as appropriate and
+     check option consistency.  */
+  if (flag_lto && flag_whopr)
+    error ("-flto and -fwhopr are mutually exclusive");
+
   /* -fbounds-check is equivalent to -fcheck=bounds */
   if (flag_bounds_check)
     gfc_option.rtcheck |= GFC_RTCHECK_BOUNDS;
index a9ed7e2..9be56f2 100644 (file)
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -764,10 +764,23 @@ proper position among the other output files.  */
 /* We want %{T*} after %{L*} and %D so that it can be used to specify linker
    scripts which exist in user specified directories, or in standard
    directories.  */
+/* We pass any -flto and -fwhopr flags on to the linker, which is expected
+   to understand them.  In practice, this means it had better be collect2.  */
 #ifndef LINK_COMMAND_SPEC
 #define LINK_COMMAND_SPEC "\
 %{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S:\
-    %(linker) %l " LINK_PIE_SPEC "%X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} %{r}\
+    %(linker) \
+    %{use-linker-plugin: \
+    -plugin %(linker_plugin_file) \
+    -plugin-opt=%(lto_wrapper) \
+    -plugin-opt=%(lto_gcc) \
+    %{static|static-libgcc:-plugin-opt=-pass-through=%(lto_libgcc)}    \
+    %{O*:-plugin-opt=-O%*} \
+    %{w:-plugin-opt=-w} \
+    %{f*:-plugin-opt=-f%*} \
+    } \
+    %{flto} %{fwhopr} %l " LINK_PIE_SPEC \
+   "%X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} %{r}\
     %{s} %{t} %{u*} %{x} %{z} %{Z} %{!A:%{!nostdlib:%{!nostartfiles:%S}}}\
     %{static:} %{L*} %(mfwrap) %(link_libgcc) %o\
     %{fopenmp|ftree-parallelize-loops=*:%:include(libgomp.spec)%(link_gomp)} %(mflib)\
@@ -815,6 +828,10 @@ static const char *endfile_spec = ENDFILE_SPEC;
 static const char *startfile_spec = STARTFILE_SPEC;
 static const char *switches_need_spaces = SWITCHES_NEED_SPACES;
 static const char *linker_name_spec = LINKER_NAME;
+static const char *linker_plugin_file_spec = "";
+static const char *lto_wrapper_spec = "";
+static const char *lto_gcc_spec = "";
+static const char *lto_libgcc_spec = "";
 static const char *link_command_spec = LINK_COMMAND_SPEC;
 static const char *link_libgcc_spec = LINK_LIBGCC_SPEC;
 static const char *startfile_prefix_spec = STARTFILE_PREFIX_SPEC;
@@ -891,11 +908,15 @@ static const char *asm_options =
 
 static const char *invoke_as =
 #ifdef AS_NEEDS_DASH_FOR_PIPED_INPUT
-"%{fcompare-debug=*|fdump-final-insns=*:%:compare-debug-dump-opt()}\
- %{!S:-o %|.s |\n as %(asm_options) %|.s %A }";
+"%{!fwpa:\
+   %{fcompare-debug=*|fdump-final-insns=*:%:compare-debug-dump-opt()}\
+   %{!S:-o %|.s |\n as %(asm_options) %|.s %A }\
+  }";
 #else
-"%{fcompare-debug=*|fdump-final-insns=*:%:compare-debug-dump-opt()}\
- %{!S:-o %|.s |\n as %(asm_options) %m.s %A }";
+"%{!fwpa:\
+   %{fcompare-debug=*|fdump-final-insns=*:%:compare-debug-dump-opt()}\
+   %{!S:-o %|.s |\n as %(asm_options) %m.s %A }\
+  }";
 #endif
 
 /* Some compilers have limits on line lengths, and the multilib_select
@@ -1653,6 +1674,10 @@ static struct spec_list static_specs[] =
   INIT_STATIC_SPEC ("multilib_exclusions",     &multilib_exclusions),
   INIT_STATIC_SPEC ("multilib_options",                &multilib_options),
   INIT_STATIC_SPEC ("linker",                  &linker_name_spec),
+  INIT_STATIC_SPEC ("linker_plugin_file",      &linker_plugin_file_spec),
+  INIT_STATIC_SPEC ("lto_wrapper",             &lto_wrapper_spec),
+  INIT_STATIC_SPEC ("lto_gcc",                 &lto_gcc_spec),
+  INIT_STATIC_SPEC ("lto_libgcc",              &lto_libgcc_spec),
   INIT_STATIC_SPEC ("link_libgcc",             &link_libgcc_spec),
   INIT_STATIC_SPEC ("md_exec_prefix",          &md_exec_prefix),
   INIT_STATIC_SPEC ("md_startfile_prefix",     &md_startfile_prefix),
@@ -6834,14 +6859,6 @@ main (int argc, char **argv)
     multilib_defaults = XOBFINISH (&multilib_obstack, const char *);
   }
 
-  /* Set up to remember the pathname of gcc and any options
-     needed for collect.  We use argv[0] instead of programname because
-     we need the complete pathname.  */
-  obstack_init (&collect_obstack);
-  obstack_grow (&collect_obstack, "COLLECT_GCC=", sizeof ("COLLECT_GCC=") - 1);
-  obstack_grow (&collect_obstack, argv[0], strlen (argv[0]) + 1);
-  xputenv (XOBFINISH (&collect_obstack, char *));
-
 #ifdef INIT_ENVIRONMENT
   /* Set up any other necessary machine specific environment variables.  */
   xputenv (INIT_ENVIRONMENT);
@@ -7055,6 +7072,27 @@ main (int argc, char **argv)
      the subdirectory based on the options.  */
   set_multilib_dir ();
 
+  /* Set up to remember the pathname of gcc and any options
+     needed for collect.  We use argv[0] instead of programname because
+     we need the complete pathname.  */
+  obstack_init (&collect_obstack);
+  obstack_grow (&collect_obstack, "COLLECT_GCC=", sizeof ("COLLECT_GCC=") - 1);
+  obstack_grow (&collect_obstack, argv[0], strlen (argv[0]) + 1);
+  xputenv (XOBFINISH (&collect_obstack, char *));
+
+  /* Set up to remember the pathname of the lto wrapper. */
+
+  lto_wrapper_spec = find_a_file (&exec_prefixes, "lto-wrapper", X_OK, false);
+  if (lto_wrapper_spec)
+    {
+      obstack_init (&collect_obstack);
+      obstack_grow (&collect_obstack, "COLLECT_LTO_WRAPPER=",
+                   sizeof ("COLLECT_LTO_WRAPPER=") - 1);
+      obstack_grow (&collect_obstack, lto_wrapper_spec,
+                   strlen (lto_wrapper_spec) + 1);
+      xputenv (XOBFINISH (&collect_obstack, char *));
+    }
+
   /* Warn about any switches that no pass was interested in.  */
 
   for (i = 0; (int) i < n_switches; i++)
@@ -7475,6 +7513,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
   if (num_linker_inputs > 0 && error_count == 0 && print_subprocess_help < 2)
     {
       int tmp = execution_count;
+      const char *use_linker_plugin = "use-linker-plugin";
 
       /* We'll use ld if we can't find collect2.  */
       if (! strcmp (linker_name_spec, "collect2"))
@@ -7483,6 +7522,23 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
          if (s == NULL)
            linker_name_spec = "ld";
        }
+
+      if (switch_matches (use_linker_plugin,
+                         use_linker_plugin + strlen (use_linker_plugin), 0))
+       {
+         linker_plugin_file_spec = find_a_file (&exec_prefixes,
+                                                "liblto_plugin.so", X_OK,
+                                                false);
+         if (!linker_plugin_file_spec)
+           fatal ("-use-linker-plugin, but liblto_plugin.so not found.");
+
+         lto_libgcc_spec = find_a_file (&startfile_prefixes, "libgcc.a",
+                                        R_OK, true);
+         if (!lto_libgcc_spec)
+           fatal ("could not find libgcc.a.");
+       }
+      lto_gcc_spec = argv[0];
+
       /* Rebuild the COMPILER_PATH and LIBRARY_PATH environment variables
         for collect.  */
       putenv_from_prefixes (&exec_prefixes, "COMPILER_PATH", false);
index 425463c..af54306 100644 (file)
@@ -23,6 +23,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "system.h"
 #include "coretypes.h"
 #include "tm.h"
+#include "target.h"
 #include "tree.h"
 #include "ggc.h"
 #include "hard-reg-set.h"
@@ -33,8 +34,18 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-flow.h"
 #include "value-prof.h"
 #include "flags.h"
+#include "alias.h"
 #include "demangle.h"
 
+/* Global type table.  FIXME lto, it should be possible to re-use some
+   of the type hashing routines in tree.c (type_hash_canon, type_hash_lookup,
+   etc), but those assume that types were built with the various
+   build_*_type routines which is not the case with the streamer.  */
+static htab_t gimple_types;
+static struct pointer_map_t *type_hash_cache;
+
+/* Global type comparison cache.  */
+static htab_t gtc_visited;
 
 /* All the tuples have their operand vector (if present) at the very bottom
    of the structure.  Therefore, the offset required to find the
@@ -115,8 +126,7 @@ gimple_size (enum gimple_code code)
 /* Allocate memory for a GIMPLE statement with code CODE and NUM_OPS
    operands.  */
 
-#define gimple_alloc(c, n) gimple_alloc_stat (c, n MEM_STAT_INFO)
-static gimple
+gimple
 gimple_alloc_stat (enum gimple_code code, unsigned num_ops MEM_STAT_DECL)
 {
   size_t size;
@@ -613,7 +623,7 @@ gimple_build_eh_must_not_throw (tree decl)
 
   gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
   gcc_assert (flags_from_decl_or_type (decl) & ECF_NORETURN);
-  p->gimple_eh_mnt.fndecl = decl;
+  gimple_eh_must_not_throw_set_fndecl (p, decl);
 
   return p;
 }
@@ -3000,6 +3010,1162 @@ gimple_call_copy_skip_args (gimple stmt, bitmap args_to_skip)
 }
 
 
+static hashval_t gimple_type_hash (const void *);
+
+/* Structure used to maintain a cache of some type pairs compared by
+   gimple_types_compatible_p when comparing aggregate types.  There are
+   four possible values for SAME_P:
+
+       -2: The pair (T1, T2) has just been inserted in the table.
+       -1: The pair (T1, T2) is currently being compared.
+        0: T1 and T2 are different types.
+        1: T1 and T2 are the same type.
+
+   This table is only used when comparing aggregate types to avoid
+   infinite recursion due to self-referential types.  */
+struct type_pair_d
+{
+  tree t1;
+  tree t2;
+  int same_p;
+};
+typedef struct type_pair_d *type_pair_t;
+
+/* Return a hash value for the type pair pointed-to by P.  */
+
+static hashval_t
+type_pair_hash (const void *p)
+{
+  const struct type_pair_d *pair = (const struct type_pair_d *) p;
+  hashval_t val1 = iterative_hash_hashval_t (htab_hash_pointer (pair->t1), 0);
+  hashval_t val2 = iterative_hash_hashval_t (htab_hash_pointer (pair->t2), 0);
+  return (iterative_hash_hashval_t (val2, val1)
+         ^ iterative_hash_hashval_t (val1, val2));
+}
+
+/* Compare two type pairs pointed-to by P1 and P2.  */
+
+static int
+type_pair_eq (const void *p1, const void *p2)
+{
+  const struct type_pair_d *pair1 = (const struct type_pair_d *) p1;
+  const struct type_pair_d *pair2 = (const struct type_pair_d *) p2;
+  return ((pair1->t1 == pair2->t1 && pair1->t2 == pair2->t2)
+         || (pair1->t1 == pair2->t2 && pair1->t2 == pair2->t1));
+}
+
+/* Lookup the pair of types T1 and T2 in *VISITED_P.  Insert a new
+   entry if none existed.  */
+
+static type_pair_t
+lookup_type_pair (tree t1, tree t2, htab_t *visited_p)
+{
+  struct type_pair_d pair;
+  type_pair_t p;
+  void **slot;
+
+  if (*visited_p == NULL)
+    *visited_p = htab_create (251, type_pair_hash, type_pair_eq, free);
+
+  pair.t1 = t1;
+  pair.t2 = t2;
+  slot = htab_find_slot (*visited_p, &pair, INSERT);
+
+  if (*slot)
+    p = *((type_pair_t *) slot);
+  else
+    {
+      p = XNEW (struct type_pair_d);
+      p->t1 = t1;
+      p->t2 = t2;
+      p->same_p = -2;
+      *slot = (void *) p;
+    }
+
+  return p;
+}
+
+
+/* Force merging the type T2 into the type T1.  */
+
+void
+gimple_force_type_merge (tree t1, tree t2)
+{
+  void **slot;
+  type_pair_t p;
+
+  /* There's no other way than copying t2 to t1 in this case.
+     Yuck.  We'll just call this "completing" t1.  */
+  memcpy (t1, t2, tree_size (t1));
+
+  /* Adjust the hash value of T1 if it was computed already.  Otherwise
+     we would be forced to not hash fields of structs to match the
+     hash value of an incomplete struct.  */
+  if (type_hash_cache
+      && (slot = pointer_map_contains (type_hash_cache, t1)) != NULL)
+    {
+      gimple_type_hash (t2);
+      *slot = *pointer_map_contains (type_hash_cache, t2);
+    }
+
+  /* Adjust cached comparison results for T1 and T2 to make sure
+     they now compare compatible.  */
+  p = lookup_type_pair (t1, t2, &gtc_visited);
+  p->same_p = 1;
+}
+
+
+/* Return true if both types have the same name.  */
+
+static bool
+compare_type_names_p (tree t1, tree t2)
+{
+  tree name1 = TYPE_NAME (t1);
+  tree name2 = TYPE_NAME (t2);
+
+  /* Consider anonymous types all unique.  */
+  if (!name1 || !name2)
+    return false;
+
+  if (TREE_CODE (name1) == TYPE_DECL)
+    {
+      name1 = DECL_NAME (name1);
+      if (!name1)
+       return false;
+    }
+  gcc_assert (TREE_CODE (name1) == IDENTIFIER_NODE);
+
+  if (TREE_CODE (name2) == TYPE_DECL)
+    {
+      name2 = DECL_NAME (name2);
+      if (!name2)
+       return false;
+    }
+  gcc_assert (TREE_CODE (name2) == IDENTIFIER_NODE);
+
+  /* Identifiers can be compared with pointer equality rather
+     than a string comparison.  */
+  if (name1 == name2)
+    return true;
+
+  return false;
+}
+
+/* Return true if the field decls F1 and F2 are at the same offset.  */
+
+static bool
+compare_field_offset (tree f1, tree f2)
+{
+  if (DECL_OFFSET_ALIGN (f1) == DECL_OFFSET_ALIGN (f2))
+    return (operand_equal_p (DECL_FIELD_OFFSET (f1),
+                            DECL_FIELD_OFFSET (f2), 0)
+           && tree_int_cst_equal (DECL_FIELD_BIT_OFFSET (f1),
+                                  DECL_FIELD_BIT_OFFSET (f2)));
+
+  /* Fortran and C do not always agree on what DECL_OFFSET_ALIGN
+     should be, so handle differing ones specially by decomposing
+     the offset into a byte and bit offset manually.  */
+  if (host_integerp (DECL_FIELD_OFFSET (f1), 0)
+      && host_integerp (DECL_FIELD_OFFSET (f2), 0))
+    {
+      unsigned HOST_WIDE_INT byte_offset1, byte_offset2;
+      unsigned HOST_WIDE_INT bit_offset1, bit_offset2;
+      bit_offset1 = TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (f1));
+      byte_offset1 = (TREE_INT_CST_LOW (DECL_FIELD_OFFSET (f1))
+                     + bit_offset1 / BITS_PER_UNIT);
+      bit_offset2 = TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (f2));
+      byte_offset2 = (TREE_INT_CST_LOW (DECL_FIELD_OFFSET (f2))
+                     + bit_offset2 / BITS_PER_UNIT);
+      if (byte_offset1 != byte_offset2)
+       return false;
+      return bit_offset1 % BITS_PER_UNIT == bit_offset2 % BITS_PER_UNIT;
+    }
+
+  return false;
+}
+
+/* Return 1 iff T1 and T2 are structurally identical.
+   Otherwise, return 0.  */
+
+int
+gimple_types_compatible_p (tree t1, tree t2)
+{
+  type_pair_t p = NULL;
+
+  /* Check first for the obvious case of pointer identity.  */
+  if (t1 == t2)
+    goto same_types;
+
+  /* Check that we have two types to compare.  */
+  if (t1 == NULL_TREE || t2 == NULL_TREE)
+    goto different_types;
+
+  /* Can't be the same type if the types don't have the same code.  */
+  if (TREE_CODE (t1) != TREE_CODE (t2))
+    goto different_types;
+
+  /* Void types are always the same.  */
+  if (TREE_CODE (t1) == VOID_TYPE)
+    goto same_types;
+
+  /* Can't be the same type if they have different CV qualifiers.  */
+  if (TYPE_QUALS (t1) != TYPE_QUALS (t2))
+    goto different_types;
+
+  /* If the hash values of t1 and t2 are different the types can't
+     possibly be the same.  This helps keeping the type-pair hashtable
+     small, only tracking comparisons for hash collisions.  */
+  if (gimple_type_hash (t1) != gimple_type_hash (t2))
+    return 0;
+
+  /* If we've visited this type pair before (in the case of aggregates
+     with self-referential types), and we made a decision, return it.  */
+  p = lookup_type_pair (t1, t2, &gtc_visited);
+  if (p->same_p == 0 || p->same_p == 1)
+    {
+      /* We have already decided whether T1 and T2 are the
+        same, return the cached result.  */
+      return p->same_p == 1;
+    }
+  else if (p->same_p == -1)
+    {
+      /* We are currently comparing this pair of types, assume
+        that they are the same and let the caller decide.  */
+      return 1;
+    }
+
+  gcc_assert (p->same_p == -2);
+
+  /* Mark the (T1, T2) comparison in progress.  */
+  p->same_p = -1;
+
+  /* If their attributes are not the same they can't be the same type.  */
+  if (!attribute_list_equal (TYPE_ATTRIBUTES (t1), TYPE_ATTRIBUTES (t2)))
+    goto different_types;
+
+  /* For numerical types, the bounds must coincide.  */
+  if (INTEGRAL_TYPE_P (t1)
+      || SCALAR_FLOAT_TYPE_P (t1)
+      || FIXED_POINT_TYPE_P (t1))
+    {
+      /* Can't be the same type if they have different size, alignment,
+        sign, precision or mode.  Note that from now on, comparisons
+        between *_CST nodes must be done using tree_int_cst_equal because
+        we cannot assume that constants from T1 and T2 will be shared
+        since T1 and T2 are distinct pointers.  */
+      if (!tree_int_cst_equal (TYPE_SIZE (t1), TYPE_SIZE (t2))
+         || !tree_int_cst_equal (TYPE_SIZE_UNIT (t1), TYPE_SIZE_UNIT (t2))
+         || TYPE_ALIGN (t1) != TYPE_ALIGN (t2)
+         || TYPE_PRECISION (t1) != TYPE_PRECISION (t2)
+         || TYPE_MODE (t1) != TYPE_MODE (t2)
+         || TYPE_UNSIGNED (t1) != TYPE_UNSIGNED (t2))
+       goto different_types;
+
+      /* For non-enumeral types, check type bounds.  FIXME lto, we
+        cannot check bounds on enumeral types because different front
+        ends will produce different values.  In C, enumeral types are
+        integers, while in C++ each element will have its own
+        symbolic value.  We should decide how enums are to be
+        represented in GIMPLE and have each front end lower to that.  */
+      if (TREE_CODE (t1) != ENUMERAL_TYPE)
+       {
+         tree min1 = TYPE_MIN_VALUE (t1);
+         tree max1 = TYPE_MAX_VALUE (t1);
+         tree min2 = TYPE_MIN_VALUE (t2);
+         tree max2 = TYPE_MAX_VALUE (t2);
+         bool min_equal_p = false;
+         bool max_equal_p = false;
+
+         /* If either type has a minimum value, the other type must
+            have the same.  */
+         if (min1 == NULL_TREE && min2 == NULL_TREE)
+           min_equal_p = true;
+         else if (min1 && min2 && operand_equal_p (min1, min2, 0))
+           min_equal_p = true;
+
+         /* Likewise, if either type has a maximum value, the other
+            type must have the same.  */
+         if (max1 == NULL_TREE && max2 == NULL_TREE)
+           max_equal_p = true;
+         else if (max1 && max2 && operand_equal_p (max1, max2, 0))
+           max_equal_p = true;
+
+         if (!min_equal_p || !max_equal_p)
+           goto different_types;
+       }
+
+      if (TREE_CODE (t1) == INTEGER_TYPE)
+       {
+         if (TYPE_IS_SIZETYPE (t1) == TYPE_IS_SIZETYPE (t2)
+             && TYPE_STRING_FLAG (t1) == TYPE_STRING_FLAG (t2))
+           goto same_types;
+         else
+           goto different_types;
+       }
+      else if (TREE_CODE (t1) == BOOLEAN_TYPE)
+       goto same_types;
+      else if (TREE_CODE (t1) == REAL_TYPE)
+       goto same_types;
+    }
+
+  /* Do type-specific comparisons.  */
+  switch (TREE_CODE (t1))
+    {
+    case ARRAY_TYPE:
+      /* Array types are the same if the element types are the same and
+        the number of elements are the same.  */
+      if (!gimple_types_compatible_p (TREE_TYPE (t1), TREE_TYPE (t2))
+         || TYPE_STRING_FLAG (t1) != TYPE_STRING_FLAG (t2))
+       goto different_types;
+      else
+       {
+         tree i1 = TYPE_DOMAIN (t1);
+         tree i2 = TYPE_DOMAIN (t2);
+
+         /* For an incomplete external array, the type domain can be
+            NULL_TREE.  Check this condition also.  */
+         if (i1 == NULL_TREE && i2 == NULL_TREE)
+           goto same_types;
+         else if (i1 == NULL_TREE || i2 == NULL_TREE)
+           goto different_types;
+         /* If for a complete array type the possibly gimplified sizes
+            are different the types are different.  */
+         else if (((TYPE_SIZE (i1) != NULL) ^ (TYPE_SIZE (i2) != NULL))
+                  || (TYPE_SIZE (i1)
+                      && TYPE_SIZE (i2)
+                      && !operand_equal_p (TYPE_SIZE (i1), TYPE_SIZE (i2), 0)))
+           goto different_types;
+         else
+           {
+             tree min1 = TYPE_MIN_VALUE (i1);
+             tree min2 = TYPE_MIN_VALUE (i2);
+             tree max1 = TYPE_MAX_VALUE (i1);
+             tree max2 = TYPE_MAX_VALUE (i2);
+
+             /* The minimum/maximum values have to be the same.  */
+             if ((min1 == min2
+                  || (min1 && min2 && operand_equal_p (min1, min2, 0)))
+                 && (max1 == max2
+                     || (max1 && max2 && operand_equal_p (max1, max2, 0))))
+               goto same_types;
+             else
+               goto different_types;
+           }
+       }
+
+    case METHOD_TYPE:
+      /* Method types should belong to the same class.  */
+      if (!gimple_types_compatible_p (TYPE_METHOD_BASETYPE (t1),
+                                TYPE_METHOD_BASETYPE (t2)))
+       goto different_types;
+
+      /* Fallthru  */
+
+    case FUNCTION_TYPE:
+      /* Function types are the same if the return type and arguments types
+        are the same.  */
+      if (!gimple_types_compatible_p (TREE_TYPE (t1), TREE_TYPE (t2)))
+       goto different_types;
+      else
+       {
+         if (!targetm.comp_type_attributes (t1, t2))
+           goto different_types;
+
+         if (TYPE_ARG_TYPES (t1) == TYPE_ARG_TYPES (t2))
+           goto same_types;
+         else
+           {
+             tree parms1, parms2;
+
+             for (parms1 = TYPE_ARG_TYPES (t1), parms2 = TYPE_ARG_TYPES (t2);
+                  parms1 && parms2;
+                  parms1 = TREE_CHAIN (parms1), parms2 = TREE_CHAIN (parms2))
+               {
+                 if (!gimple_types_compatible_p (TREE_VALUE (parms1),
+                                            TREE_VALUE (parms2)))
+                   goto different_types;
+               }
+
+             if (parms1 || parms2)
+               goto different_types;
+
+             goto same_types;
+           }
+       }
+
+    case POINTER_TYPE:
+    case REFERENCE_TYPE:
+       {
+         /* If the two pointers have different ref-all attributes,
+            they can't be the same type.  */
+         if (TYPE_REF_CAN_ALIAS_ALL (t1) != TYPE_REF_CAN_ALIAS_ALL (t2))
+           goto different_types;
+
+         /* If one pointer points to an incomplete type variant of
+            the other pointed-to type they are the same.  */
+         if (TREE_CODE (TREE_TYPE (t1)) == TREE_CODE (TREE_TYPE (t2))
+             && (!COMPLETE_TYPE_P (TREE_TYPE (t1))
+                 || !COMPLETE_TYPE_P (TREE_TYPE (t2)))
+             && compare_type_names_p (TREE_TYPE (t1), TREE_TYPE (t2)))
+           {
+             /* If t2 is complete we want to choose it instead of t1.  */
+             if (COMPLETE_TYPE_P (TREE_TYPE (t2)))
+               gimple_force_type_merge (TREE_TYPE (t1), TREE_TYPE (t2));
+             goto same_types;
+           }
+
+         /* Otherwise, pointer and reference types are the same if the
+            pointed-to types are the same.  */
+         if (gimple_types_compatible_p (TREE_TYPE (t1), TREE_TYPE (t2)))
+           goto same_types;
+         
+         goto different_types;
+       }
+
+    case ENUMERAL_TYPE:
+       {
+         /* For enumeral types, all the values must be the same.  */
+         tree v1, v2;
+
+         if (TYPE_VALUES (t1) == TYPE_VALUES (t2))
+           goto same_types;
+
+         for (v1 = TYPE_VALUES (t1), v2 = TYPE_VALUES (t2);
+              v1 && v2;
+              v1 = TREE_CHAIN (v1), v2 = TREE_CHAIN (v2))
+           {
+             tree c1 = TREE_VALUE (v1);
+             tree c2 = TREE_VALUE (v2);
+
+             if (TREE_CODE (c1) == CONST_DECL)
+               c1 = DECL_INITIAL (c1);
+
+             if (TREE_CODE (c2) == CONST_DECL)
+               c2 = DECL_INITIAL (c2);
+
+             if (tree_int_cst_equal (c1, c2) != 1)
+               goto different_types;
+           }
+
+         /* If one enumeration has more values than the other, they
+            are not the same.  */
+         if (v1 || v2)
+           goto different_types;
+
+         goto same_types;
+       }
+
+    case RECORD_TYPE:
+    case UNION_TYPE:
+    case QUAL_UNION_TYPE:
+       {
+         /* For aggregate types, all the fields must be the same.  */
+         tree f1, f2;
+
+         /* Compare every field.  */
+         for (f1 = TYPE_FIELDS (t1), f2 = TYPE_FIELDS (t2);
+              f1 && f2;
+              f1 = TREE_CHAIN (f1), f2 = TREE_CHAIN (f2))
+           {
+             /* The fields must have the same name, offset and type.  */
+             if (DECL_NAME (f1) != DECL_NAME (f2)
+                 || !compare_field_offset (f1, f2)
+                 || !gimple_types_compatible_p (TREE_TYPE (f1),
+                                           TREE_TYPE (f2)))
+               goto different_types;
+           }
+
+         /* If one aggregate has more fields than the other, they
+            are not the same.  */
+         if (f1 || f2)
+           goto different_types;
+
+         goto same_types;
+       }
+
+    case VECTOR_TYPE:
+      if (TYPE_VECTOR_SUBPARTS (t1) != TYPE_VECTOR_SUBPARTS (t2))
+       goto different_types;
+
+      /* Fallthru  */
+    case COMPLEX_TYPE:
+      if (!gimple_types_compatible_p (TREE_TYPE (t1), TREE_TYPE (t2)))
+       goto different_types;
+      goto same_types;
+
+    default:
+      goto different_types;
+    }
+
+  /* Common exit path for types that are not compatible.  */
+different_types:
+  if (p)
+    p->same_p = 0;
+  return 0;
+
+  /* Common exit path for types that are compatible.  */
+same_types:
+  if (p)
+    p->same_p = 1;
+  return 1;
+}
+
+
+
+
+/* Per pointer state for the SCC finding.  The on_sccstack flag
+   is not strictly required, it is true when there is no hash value
+   recorded for the type and false otherwise.  But querying that
+   is slower.  */
+
+struct sccs
+{
+  unsigned int dfsnum;
+  unsigned int low;
+  bool on_sccstack;
+  hashval_t hash;
+};
+
+static unsigned int next_dfs_num;
+
+static hashval_t
+iterative_hash_gimple_type (tree, hashval_t, VEC(tree, heap) **,
+                           struct pointer_map_t *, struct obstack *);
+
+/* DFS visit the edge from the callers type with state *STATE to T.
+   Update the callers type hash V with the hash for T if it is not part
+   of the SCC containing the callers type and return it.
+   SCCSTACK, SCCSTATE and SCCSTATE_OBSTACK are state for the DFS walk done.  */
+
+static hashval_t
+visit (tree t, struct sccs *state, hashval_t v,
+       VEC (tree, heap) **sccstack,
+       struct pointer_map_t *sccstate,
+       struct obstack *sccstate_obstack)
+{
+  struct sccs *cstate = NULL;
+  void **slot;
+
+  /* If there is a hash value recorded for this type then it can't
+     possibly be part of our parent SCC.  Simply mix in its hash.  */
+  if ((slot = pointer_map_contains (type_hash_cache, t)))
+    return iterative_hash_hashval_t ((hashval_t) (size_t) *slot, v);
+
+  if ((slot = pointer_map_contains (sccstate, t)) != NULL)
+    cstate = (struct sccs *)*slot;
+  if (!cstate)
+    {
+      hashval_t tem;
+      /* Not yet visited.  DFS recurse.  */
+      tem = iterative_hash_gimple_type (t, v,
+                                       sccstack, sccstate, sccstate_obstack);
+      if (!cstate)
+       cstate = (struct sccs *)* pointer_map_contains (sccstate, t);
+      state->low = MIN (state->low, cstate->low);
+      /* If the type is no longer on the SCC stack and thus is not part
+         of the parents SCC mix in its hash value.  Otherwise we will
+        ignore the type for hashing purposes and return the unaltered
+        hash value.  */
+      if (!cstate->on_sccstack)
+       return tem;
+    }
+  if (cstate->dfsnum < state->dfsnum
+      && cstate->on_sccstack)
+    state->low = MIN (cstate->dfsnum, state->low);
+
+  /* We are part of our parents SCC, skip this type during hashing
+     and return the unaltered hash value.  */
+  return v;
+}
+
+/* Hash the name of TYPE with the previous hash value V and return it.  */
+
+static hashval_t
+iterative_hash_type_name (tree type, hashval_t v)
+{
+  tree name = TYPE_NAME (TYPE_MAIN_VARIANT (type));
+  if (!name)
+    return v;
+  if (TREE_CODE (name) == TYPE_DECL)
+    name = DECL_NAME (name);
+  if (!name)
+    return v;
+  gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
+  /* Do not hash names of anonymous unions.  At least the C++ FE insists
+     to have a non-NULL TYPE_NAME for them.  See cp/cp-tree.h for all
+     the glory.  */
+#ifndef NO_DOT_IN_LABEL
+  if (IDENTIFIER_POINTER (name)[0] == '.')
+    return v;
+#else
+#ifndef NO_DOLLAR_IN_LABEL
+  if (IDENTIFIER_POINTER (name)[0] == '$')
+    return v;
+#else
+  if (!strncmp (IDENTIFIER_POINTER (name), "__anon_", sizeof ("__anon_") - 1))
+    return v;
+#endif
+#endif
+  return iterative_hash_object (IDENTIFIER_HASH_VALUE (name), v);
+}
+
+/* Returning a hash value for gimple type TYPE combined with VAL.
+   SCCSTACK, SCCSTATE and SCCSTATE_OBSTACK are state for the DFS walk done.
+
+   To hash a type we end up hashing in types that are reachable.
+   Through pointers we can end up with cycles which messes up the
+   required property that we need to compute the same hash value
+   for structurally equivalent types.  To avoid this we have to
+   hash all types in a cycle (the SCC) in a commutative way.  The
+   easiest way is to not mix in the hashes of the SCC members at
+   all.  To make this work we have to delay setting the hash
+   values of the SCC until it is complete.  */
+
+static hashval_t
+iterative_hash_gimple_type (tree type, hashval_t val,
+                           VEC(tree, heap) **sccstack,
+                           struct pointer_map_t *sccstate,
+                           struct obstack *sccstate_obstack)
+{
+  hashval_t v;
+  void **slot;
+  struct sccs *state;
+
+#ifdef ENABLE_CHECKING
+  /* Not visited during this DFS walk nor during previous walks.  */
+  gcc_assert (!pointer_map_contains (type_hash_cache, type)
+             && !pointer_map_contains (sccstate, type));
+#endif
+  state = XOBNEW (sccstate_obstack, struct sccs);
+  *pointer_map_insert (sccstate, type) = state;
+
+  VEC_safe_push (tree, heap, *sccstack, type);
+  state->dfsnum = next_dfs_num++;
+  state->low = state->dfsnum;
+  state->on_sccstack = true;
+
+  /* Combine a few common features of types so that types are grouped into
+     smaller sets; when searching for existing matching types to merge,
+     only existing types having the same features as the new type will be
+     checked.  */
+  v = iterative_hash_hashval_t (TREE_CODE (type), 0);
+  v = iterative_hash_hashval_t (TYPE_QUALS (type), v);
+  v = iterative_hash_hashval_t (TREE_ADDRESSABLE (type), v);
+
+  /* Do not hash the types size as this will cause differences in
+     hash values for the complete vs. the incomplete type variant.  */
+
+  /* Incorporate common features of numerical types.  */
+  if (INTEGRAL_TYPE_P (type)
+      || SCALAR_FLOAT_TYPE_P (type)
+      || FIXED_POINT_TYPE_P (type))
+    {
+      v = iterative_hash_hashval_t (TYPE_PRECISION (type), v);
+      v = iterative_hash_hashval_t (TYPE_MODE (type), v);
+      v = iterative_hash_hashval_t (TYPE_UNSIGNED (type), v);
+    }
+
+  /* For pointer and reference types, fold in information about the type
+     pointed to but do not recurse into possibly incomplete types to
+     avoid hash differences for complete vs. incomplete types.  */
+  if (POINTER_TYPE_P (type))
+    {
+      if (AGGREGATE_TYPE_P (TREE_TYPE (type)))
+       {
+         v = iterative_hash_hashval_t (TREE_CODE (TREE_TYPE (type)), v);
+         v = iterative_hash_type_name (type, v);
+       }
+      else
+       v = visit (TREE_TYPE (type), state, v,
+                  sccstack, sccstate, sccstate_obstack);
+    }
+
+  /* Recurse for aggregates with a single element.  */
+  if (TREE_CODE (type) == ARRAY_TYPE
+      || TREE_CODE (type) == COMPLEX_TYPE
+      || TREE_CODE (type) == VECTOR_TYPE)
+    v = visit (TREE_TYPE (type), state, v,
+              sccstack, sccstate, sccstate_obstack);
+
+  /* Incorporate function return and argument types.  */
+  if (TREE_CODE (type) == FUNCTION_TYPE || TREE_CODE (type) == METHOD_TYPE)
+    {
+      unsigned na;
+      tree p;
+
+      /* For method types also incorporate their parent class.  */
+      if (TREE_CODE (type) == METHOD_TYPE)
+       v = visit (TYPE_METHOD_BASETYPE (type), state, v,
+                  sccstack, sccstate, sccstate_obstack);
+
+      v = visit (TREE_TYPE (type), state, v,
+                sccstack, sccstate, sccstate_obstack);
+
+      for (p = TYPE_ARG_TYPES (type), na = 0; p; p = TREE_CHAIN (p))
+       {
+         v = visit (TREE_VALUE (p), state, v,
+                    sccstack, sccstate, sccstate_obstack);
+         na++;
+       }
+
+      v = iterative_hash_hashval_t (na, v);
+    }
+
+  if (TREE_CODE (type) == RECORD_TYPE
+      || TREE_CODE (type) == UNION_TYPE
+      || TREE_CODE (type) == QUAL_UNION_TYPE)
+    {
+      unsigned nf;
+      tree f;
+
+      v = iterative_hash_type_name (type, v);
+
+      for (f = TYPE_FIELDS (type), nf = 0; f; f = TREE_CHAIN (f))
+       {
+         v = visit (TREE_TYPE (f), state, v,
+                    sccstack, sccstate, sccstate_obstack);
+         nf++;
+       }
+
+      v = iterative_hash_hashval_t (nf, v);
+    }
+
+  /* Record hash for us.  */
+  state->hash = v;
+
+  /* See if we found an SCC.  */
+  if (state->low == state->dfsnum)
+    {
+      tree x;
+
+      /* Pop off the SCC and set its hash values.  */
+      do
+       {
+         struct sccs *cstate;
+         x = VEC_pop (tree, *sccstack);
+         gcc_assert (!pointer_map_contains (type_hash_cache, x));
+         cstate = (struct sccs *)*pointer_map_contains (sccstate, x);
+         cstate->on_sccstack = false;
+         slot = pointer_map_insert (type_hash_cache, x);
+         *slot = (void *) (size_t) cstate->hash;
+       }
+      while (x != type);
+    }
+
+  return iterative_hash_hashval_t (v, val);
+}
+
+
+/* Returns a hash value for P (assumed to be a type).  The hash value
+   is computed using some distinguishing features of the type.  Note
+   that we cannot use pointer hashing here as we may be dealing with
+   two distinct instances of the same type.
+
+   This function should produce the same hash value for two compatible
+   types according to gimple_types_compatible_p.  */
+
+static hashval_t
+gimple_type_hash (const void *p)
+{
+  VEC(tree, heap) *sccstack = NULL;
+  struct pointer_map_t *sccstate;
+  struct obstack sccstate_obstack;
+  hashval_t val;
+  void **slot;
+
+  if (type_hash_cache == NULL)
+    type_hash_cache = pointer_map_create ();
+
+  if ((slot = pointer_map_contains (type_hash_cache, p)) != NULL)
+    return iterative_hash_hashval_t ((hashval_t) (size_t) *slot, 0);
+
+  /* Perform a DFS walk and pre-hash all reachable types.  */
+  next_dfs_num = 1;
+  sccstate = pointer_map_create ();
+  gcc_obstack_init (&sccstate_obstack);
+  val = iterative_hash_gimple_type (CONST_CAST2 (tree, const void *, p), 0,
+                                   &sccstack, sccstate, &sccstate_obstack);
+  VEC_free (tree, heap, sccstack);
+  pointer_map_destroy (sccstate);
+  obstack_free (&sccstate_obstack, NULL);
+
+  return val;
+}
+
+
+/* Returns nonzero if P1 and P2 are equal.  */
+
+static int
+gimple_type_eq (const void *p1, const void *p2)
+{
+  const_tree t1 = (const_tree) p1;
+  const_tree t2 = (const_tree) p2;
+  return gimple_types_compatible_p (CONST_CAST_TREE (t1), CONST_CAST_TREE (t2));
+}
+
+
+/* Register type T in the global type table gimple_types.
+   If another type T', compatible with T, already existed in
+   gimple_types then return T', otherwise return T.  This is used by
+   LTO to merge identical types read from different TUs.  */
+
+tree
+gimple_register_type (tree t)
+{
+  void **slot;
+
+  gcc_assert (TYPE_P (t));
+
+  if (gimple_types == NULL)
+    gimple_types = htab_create (16381, gimple_type_hash, gimple_type_eq, 0);
+
+  slot = htab_find_slot (gimple_types, t, INSERT);
+  if (*slot
+      && *(tree *)slot != t)
+    {
+      tree new_type = (tree) *((tree *) slot);
+
+      /* Do not merge types with different addressability.  */
+      gcc_assert (TREE_ADDRESSABLE (t) == TREE_ADDRESSABLE (new_type));
+
+      /* If t is not its main variant then make t unreachable from its
+        main variant list.  Otherwise we'd queue up a lot of duplicates
+        there.  */
+      if (t != TYPE_MAIN_VARIANT (t))
+       {
+         tree tem = TYPE_MAIN_VARIANT (t);
+         while (tem && TYPE_NEXT_VARIANT (tem) != t)
+           tem = TYPE_NEXT_VARIANT (tem);
+         if (tem)
+           TYPE_NEXT_VARIANT (tem) = TYPE_NEXT_VARIANT (t);
+         TYPE_NEXT_VARIANT (t) = NULL_TREE;
+       }
+
+      /* If we are a pointer then remove us from the pointer-to or
+        reference-to chain.  Otherwise we'd queue up a lot of duplicates
+        there.  */
+      if (TREE_CODE (t) == POINTER_TYPE)
+       {
+         if (TYPE_POINTER_TO (TREE_TYPE (t)) == t)
+           TYPE_POINTER_TO (TREE_TYPE (t)) = TYPE_NEXT_PTR_TO (t);
+         else
+           {
+             tree tem = TYPE_POINTER_TO (TREE_TYPE (t));
+             while (tem && TYPE_NEXT_PTR_TO (tem) != t)
+               tem = TYPE_NEXT_PTR_TO (tem);
+             if (tem)
+               TYPE_NEXT_PTR_TO (tem) = TYPE_NEXT_PTR_TO (t);
+           }
+         TYPE_NEXT_PTR_TO (t) = NULL_TREE;
+       }
+      else if (TREE_CODE (t) == REFERENCE_TYPE)
+       {
+         if (TYPE_REFERENCE_TO (TREE_TYPE (t)) == t)
+           TYPE_REFERENCE_TO (TREE_TYPE (t)) = TYPE_NEXT_REF_TO (t);
+         else
+           {
+             tree tem = TYPE_REFERENCE_TO (TREE_TYPE (t));
+             while (tem && TYPE_NEXT_REF_TO (tem) != t)
+               tem = TYPE_NEXT_REF_TO (tem);
+             if (tem)
+               TYPE_NEXT_REF_TO (tem) = TYPE_NEXT_REF_TO (t);
+           }
+         TYPE_NEXT_REF_TO (t) = NULL_TREE;
+       }
+
+      t = new_type;
+    }
+  else
+    *slot = (void *) t;
+
+  return t;
+}
+
+
+/* Show statistics on references to the global type table gimple_types.  */
+
+void
+print_gimple_types_stats (void)
+{
+  if (gimple_types)
+    fprintf (stderr, "GIMPLE type table: size %ld, %ld elements, "
+            "%ld searches, %ld collisions (ratio: %f)\n",
+            (long) htab_size (gimple_types),
+            (long) htab_elements (gimple_types),
+            (long) gimple_types->searches,
+            (long) gimple_types->collisions,
+            htab_collisions (gimple_types));
+  else
+    fprintf (stderr, "GIMPLE type table is empty\n");
+  if (gtc_visited)
+    fprintf (stderr, "GIMPLE type comparison table: size %ld, %ld elements, "
+            "%ld searches, %ld collisions (ratio: %f)\n",
+            (long) htab_size (gtc_visited),
+            (long) htab_elements (gtc_visited),
+            (long) gtc_visited->searches,
+            (long) gtc_visited->collisions,
+            htab_collisions (gtc_visited));
+  else
+    fprintf (stderr, "GIMPLE type comparison table is empty\n");
+}
+
+
+/* Return a type the same as TYPE except unsigned or
+   signed according to UNSIGNEDP.  */
+
+static tree
+gimple_signed_or_unsigned_type (bool unsignedp, tree type)
+{
+  tree type1;
+
+  type1 = TYPE_MAIN_VARIANT (type);
+  if (type1 == signed_char_type_node
+      || type1 == char_type_node
+      || type1 == unsigned_char_type_node)
+    return unsignedp ? unsigned_char_type_node : signed_char_type_node;
+  if (type1 == integer_type_node || type1 == unsigned_type_node)
+    return unsignedp ? unsigned_type_node : integer_type_node;
+  if (type1 == short_integer_type_node || type1 == short_unsigned_type_node)
+    return unsignedp ? short_unsigned_type_node : short_integer_type_node;
+  if (type1 == long_integer_type_node || type1 == long_unsigned_type_node)
+    return unsignedp ? long_unsigned_type_node : long_integer_type_node;
+  if (type1 == long_long_integer_type_node
+      || type1 == long_long_unsigned_type_node)
+    return unsignedp
+           ? long_long_unsigned_type_node
+          : long_long_integer_type_node;
+#if HOST_BITS_PER_WIDE_INT >= 64
+  if (type1 == intTI_type_node || type1 == unsigned_intTI_type_node)
+    return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
+#endif
+  if (type1 == intDI_type_node || type1 == unsigned_intDI_type_node)
+    return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
+  if (type1 == intSI_type_node || type1 == unsigned_intSI_type_node)
+    return unsignedp ? unsigned_intSI_type_node : intSI_type_node;
+  if (type1 == intHI_type_node || type1 == unsigned_intHI_type_node)
+    return unsignedp ? unsigned_intHI_type_node : intHI_type_node;
+  if (type1 == intQI_type_node || type1 == unsigned_intQI_type_node)
+    return unsignedp ? unsigned_intQI_type_node : intQI_type_node;
+
+#define GIMPLE_FIXED_TYPES(NAME)           \
+  if (type1 == short_ ## NAME ## _type_node \
+      || type1 == unsigned_short_ ## NAME ## _type_node) \
+    return unsignedp ? unsigned_short_ ## NAME ## _type_node \
+                    : short_ ## NAME ## _type_node; \
+  if (type1 == NAME ## _type_node \
+      || type1 == unsigned_ ## NAME ## _type_node) \
+    return unsignedp ? unsigned_ ## NAME ## _type_node \
+                    : NAME ## _type_node; \
+  if (type1 == long_ ## NAME ## _type_node \
+      || type1 == unsigned_long_ ## NAME ## _type_node) \
+    return unsignedp ? unsigned_long_ ## NAME ## _type_node \
+                    : long_ ## NAME ## _type_node; \
+  if (type1 == long_long_ ## NAME ## _type_node \
+      || type1 == unsigned_long_long_ ## NAME ## _type_node) \
+    return unsignedp ? unsigned_long_long_ ## NAME ## _type_node \
+                    : long_long_ ## NAME ## _type_node;
+
+#define GIMPLE_FIXED_MODE_TYPES(NAME) \
+  if (type1 == NAME ## _type_node \
+      || type1 == u ## NAME ## _type_node) \
+    return unsignedp ? u ## NAME ## _type_node \
+                    : NAME ## _type_node;
+
+#define GIMPLE_FIXED_TYPES_SAT(NAME) \
+  if (type1 == sat_ ## short_ ## NAME ## _type_node \
+      || type1 == sat_ ## unsigned_short_ ## NAME ## _type_node) \
+    return unsignedp ? sat_ ## unsigned_short_ ## NAME ## _type_node \
+                    : sat_ ## short_ ## NAME ## _type_node; \
+  if (type1 == sat_ ## NAME ## _type_node \
+      || type1 == sat_ ## unsigned_ ## NAME ## _type_node) \
+    return unsignedp ? sat_ ## unsigned_ ## NAME ## _type_node \
+                    : sat_ ## NAME ## _type_node; \
+  if (type1 == sat_ ## long_ ## NAME ## _type_node \
+      || type1 == sat_ ## unsigned_long_ ## NAME ## _type_node) \
+    return unsignedp ? sat_ ## unsigned_long_ ## NAME ## _type_node \
+                    : sat_ ## long_ ## NAME ## _type_node; \
+  if (type1 == sat_ ## long_long_ ## NAME ## _type_node \
+      || type1 == sat_ ## unsigned_long_long_ ## NAME ## _type_node) \
+    return unsignedp ? sat_ ## unsigned_long_long_ ## NAME ## _type_node \
+                    : sat_ ## long_long_ ## NAME ## _type_node;
+
+#define GIMPLE_FIXED_MODE_TYPES_SAT(NAME)      \
+  if (type1 == sat_ ## NAME ## _type_node \
+      || type1 == sat_ ## u ## NAME ## _type_node) \
+    return unsignedp ? sat_ ## u ## NAME ## _type_node \
+                    : sat_ ## NAME ## _type_node;
+
+  GIMPLE_FIXED_TYPES (fract);
+  GIMPLE_FIXED_TYPES_SAT (fract);
+  GIMPLE_FIXED_TYPES (accum);
+  GIMPLE_FIXED_TYPES_SAT (accum);
+
+  GIMPLE_FIXED_MODE_TYPES (qq);
+  GIMPLE_FIXED_MODE_TYPES (hq);
+  GIMPLE_FIXED_MODE_TYPES (sq);
+  GIMPLE_FIXED_MODE_TYPES (dq);
+  GIMPLE_FIXED_MODE_TYPES (tq);
+  GIMPLE_FIXED_MODE_TYPES_SAT (qq);
+  GIMPLE_FIXED_MODE_TYPES_SAT (hq);
+  GIMPLE_FIXED_MODE_TYPES_SAT (sq);
+  GIMPLE_FIXED_MODE_TYPES_SAT (dq);
+  GIMPLE_FIXED_MODE_TYPES_SAT (tq);
+  GIMPLE_FIXED_MODE_TYPES (ha);
+  GIMPLE_FIXED_MODE_TYPES (sa);
+  GIMPLE_FIXED_MODE_TYPES (da);
+  GIMPLE_FIXED_MODE_TYPES (ta);
+  GIMPLE_FIXED_MODE_TYPES_SAT (ha);
+  GIMPLE_FIXED_MODE_TYPES_SAT (sa);
+  GIMPLE_FIXED_MODE_TYPES_SAT (da);
+  GIMPLE_FIXED_MODE_TYPES_SAT (ta);
+
+  /* For ENUMERAL_TYPEs in C++, must check the mode of the types, not
+     the precision; they have precision set to match their range, but
+     may use a wider mode to match an ABI.  If we change modes, we may
+     wind up with bad conversions.  For INTEGER_TYPEs in C, must check
+     the precision as well, so as to yield correct results for
+     bit-field types.  C++ does not have these separate bit-field
+     types, and producing a signed or unsigned variant of an
+     ENUMERAL_TYPE may cause other problems as well.  */
+  if (!INTEGRAL_TYPE_P (type)
+      || TYPE_UNSIGNED (type) == unsignedp)
+    return type;
+
+#define TYPE_OK(node)                                                      \
+  (TYPE_MODE (type) == TYPE_MODE (node)                                            \
+   && TYPE_PRECISION (type) == TYPE_PRECISION (node))
+  if (TYPE_OK (signed_char_type_node))
+    return unsignedp ? unsigned_char_type_node : signed_char_type_node;
+  if (TYPE_OK (integer_type_node))
+    return unsignedp ? unsigned_type_node : integer_type_node;
+  if (TYPE_OK (short_integer_type_node))
+    return unsignedp ? short_unsigned_type_node : short_integer_type_node;
+  if (TYPE_OK (long_integer_type_node))
+    return unsignedp ? long_unsigned_type_node : long_integer_type_node;
+  if (TYPE_OK (long_long_integer_type_node))
+    return (unsignedp
+           ? long_long_unsigned_type_node
+           : long_long_integer_type_node);
+
+#if HOST_BITS_PER_WIDE_INT >= 64
+  if (TYPE_OK (intTI_type_node))
+    return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
+#endif
+  if (TYPE_OK (intDI_type_node))
+    return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
+  if (TYPE_OK (intSI_type_node))
+    return unsignedp ? unsigned_intSI_type_node : intSI_type_node;
+  if (TYPE_OK (intHI_type_node))
+    return unsignedp ? unsigned_intHI_type_node : intHI_type_node;
+  if (TYPE_OK (intQI_type_node))
+    return unsignedp ? unsigned_intQI_type_node : intQI_type_node;
+
+#undef GIMPLE_FIXED_TYPES
+#undef GIMPLE_FIXED_MODE_TYPES
+#undef GIMPLE_FIXED_TYPES_SAT
+#undef GIMPLE_FIXED_MODE_TYPES_SAT
+#undef TYPE_OK
+
+  return build_nonstandard_integer_type (TYPE_PRECISION (type), unsignedp);
+}
+
+
+/* Return an unsigned type the same as TYPE in other respects.  */
+
+tree
+gimple_unsigned_type (tree type)
+{
+  return gimple_signed_or_unsigned_type (true, type);
+}
+
+
+/* Return a signed type the same as TYPE in other respects.  */
+
+tree
+gimple_signed_type (tree type)
+{
+  return gimple_signed_or_unsigned_type (false, type);
+}
+
+
+/* Return the typed-based alias set for T, which may be an expression
+   or a type.  Return -1 if we don't do anything special.  */
+
+alias_set_type
+gimple_get_alias_set (tree t)
+{
+  tree u;
+
+  /* Permit type-punning when accessing a union, provided the access
+     is directly through the union.  For example, this code does not
+     permit taking the address of a union member and then storing
+     through it.  Even the type-punning allowed here is a GCC
+     extension, albeit a common and useful one; the C standard says
+     that such accesses have implementation-defined behavior.  */
+  for (u = t;
+       TREE_CODE (u) == COMPONENT_REF || TREE_CODE (u) == ARRAY_REF;
+       u = TREE_OPERAND (u, 0))
+    if (TREE_CODE (u) == COMPONENT_REF
+       && TREE_CODE (TREE_TYPE (TREE_OPERAND (u, 0))) == UNION_TYPE)
+      return 0;
+
+  /* That's all the expressions we handle specially.  */
+  if (!TYPE_P (t))
+    return -1;
+
+  /* For convenience, follow the C standard when dealing with
+     character types.  Any object may be accessed via an lvalue that
+     has character type.  */
+  if (t == char_type_node
+      || t == signed_char_type_node
+      || t == unsigned_char_type_node)
+    return 0;
+
+  /* Allow aliasing between signed and unsigned variants of the same
+     type.  We treat the signed variant as canonical.  */
+  if (TREE_CODE (t) == INTEGER_TYPE && TYPE_UNSIGNED (t))
+    {
+      tree t1 = gimple_signed_type (t);
+
+      /* t1 == t can happen for boolean nodes which are always unsigned.  */
+      if (t1 != t)
+       return get_alias_set (t1);
+    }
+  else if (POINTER_TYPE_P (t))
+    {
+      tree t1;
+
+      /* Unfortunately, there is no canonical form of a pointer type.
+        In particular, if we have `typedef int I', then `int *', and
+        `I *' are different types.  So, we have to pick a canonical
+        representative.  We do this below.
+
+        Technically, this approach is actually more conservative that
+        it needs to be.  In particular, `const int *' and `int *'
+        should be in different alias sets, according to the C and C++
+        standard, since their types are not the same, and so,
+        technically, an `int **' and `const int **' cannot point at
+        the same thing.
+
+        But, the standard is wrong.  In particular, this code is
+        legal C++:
+
+        int *ip;
+        int **ipp = &ip;
+        const int* const* cipp = ipp;
+        And, it doesn't make sense for that to be legal unless you
+        can dereference IPP and CIPP.  So, we ignore cv-qualifiers on
+        the pointed-to types.  This issue has been reported to the
+        C++ committee.  */
+      t1 = build_type_no_quals (t);
+      if (t1 != t)
+       return get_alias_set (t1);
+    }
+
+  return -1;
+}
+
+
 /* Data structure used to count the number of dereferences to PTR
    inside an expression.  */
 struct count_ptr_d
@@ -3344,7 +4510,6 @@ gimple_decl_printable_name (tree decl, int verbosity)
       if (verbosity >= 2)
        {
          dmgl_opts = DMGL_VERBOSE
-                     | DMGL_TYPES
                      | DMGL_ANSI
                      | DMGL_GNU_V3
                      | DMGL_RET_POSTFIX;
index e1e3b65..e21d53f 100644 (file)
@@ -855,6 +855,8 @@ bool gimple_assign_rhs_could_trap_p (gimple);
 void gimple_regimplify_operands (gimple, gimple_stmt_iterator *);
 bool empty_body_p (gimple_seq);
 unsigned get_gimple_rhs_num_ops (enum tree_code);
+#define gimple_alloc(c, n) gimple_alloc_stat (c, n MEM_STAT_INFO)
+gimple gimple_alloc_stat (enum gimple_code, unsigned MEM_STAT_DECL);
 const char *gimple_decl_printable_name (tree, int);
 tree gimple_fold_obj_type_ref (tree, tree);
 
@@ -913,6 +915,13 @@ extern bool is_gimple_call_addr (tree);
 extern tree get_call_expr_in (tree t);
 
 extern void recalculate_side_effects (tree);
+extern void gimple_force_type_merge (tree, tree);
+extern int gimple_types_compatible_p (tree, tree);
+extern tree gimple_register_type (tree);
+extern void print_gimple_types_stats (void);
+extern tree gimple_unsigned_type (tree);
+extern tree gimple_signed_type (tree);
+extern alias_set_type gimple_get_alias_set (tree);
 extern void count_uses_and_derefs (tree, gimple, unsigned *, unsigned *,
                                   unsigned *);
 extern bool walk_stmt_load_store_addr_ops (gimple, void *,
@@ -2912,6 +2921,16 @@ gimple_eh_must_not_throw_fndecl (gimple gs)
   return gs->gimple_eh_mnt.fndecl;
 }
 
+/* Set the function decl to be called by GS to DECL.  */
+
+static inline void
+gimple_eh_must_not_throw_set_fndecl (gimple gs, tree decl)
+{
+  GIMPLE_CHECK (gs, GIMPLE_EH_MUST_NOT_THROW);
+  gs->gimple_eh_mnt.fndecl = decl;
+}
+
+
 /* GIMPLE_TRY accessors. */
 
 /* Return the kind of try block represented by GIMPLE_TRY GS.  This is
index f7782cb..a974dd0 100644 (file)
@@ -1273,7 +1273,13 @@ ipcp_generate_summary (void)
 static bool
 cgraph_gate_cp (void)
 {
-  return flag_ipa_cp;
+  /* FIXME lto.  IPA-CP does not tolerate running when the inlining decisions
+     have not been applied.  This happens when WPA modifies the callgraph.
+     Since those decisions are not applied until after all the IPA passes
+     have been run in LTRANS, this means that IPA passes may see partially
+     modified callgraphs.  The solution to this is to apply WPA decisions
+     early during LTRANS.  */
+  return flag_ipa_cp && !flag_ltrans;
 }
 
 struct ipa_opt_pass_d pass_ipa_cp =
index 8851d60..0a02ae1 100644 (file)
@@ -326,7 +326,7 @@ cgraph_mark_inline (struct cgraph_edge *edge)
   struct cgraph_node *what = edge->callee;
   struct cgraph_edge *e, *next;
 
-  gcc_assert (!gimple_call_cannot_inline_p (edge->call_stmt));
+  gcc_assert (!edge->call_stmt_cannot_inline_p);
   /* Look for all calls, mark them inline and clone recursively
      all inlined functions.  */
   for (e = what->callers; e; e = next)
@@ -1031,7 +1031,7 @@ cgraph_decide_inlining_of_small_functions (void)
       else
        {
          struct cgraph_node *callee;
-         if (gimple_call_cannot_inline_p (edge->call_stmt)
+         if (edge->call_stmt_cannot_inline_p
              || !cgraph_check_inline_limits (edge->caller, edge->callee,
                                              &edge->inline_failed, true))
            {
@@ -1111,7 +1111,13 @@ cgraph_decide_inlining (void)
   bool redo_always_inline = true;
   int initial_size = 0;
 
-  cgraph_remove_function_insertion_hook (function_insertion_hook_holder);
+  /* FIXME lto.  We need to rethink how to coordinate different passes. */
+  if (flag_ltrans)
+    return 0;
+
+  /* FIXME lto.  We need to re-think about how the passes get invoked. */
+  if (!flag_wpa)
+    cgraph_remove_function_insertion_hook (function_insertion_hook_holder);
 
   max_count = 0;
   max_benefit = 0;
@@ -1121,7 +1127,6 @@ cgraph_decide_inlining (void)
        struct cgraph_edge *e;
 
        gcc_assert (inline_summary (node)->self_size == node->global.size);
-       gcc_assert (node->needed || node->reachable);
        initial_size += node->global.size;
        for (e = node->callees; e; e = e->next_callee)
          if (max_count < e->count)
@@ -1129,7 +1134,9 @@ cgraph_decide_inlining (void)
        if (max_benefit < inline_summary (node)->time_inlining_benefit)
          max_benefit = inline_summary (node)->time_inlining_benefit;
       }
-  gcc_assert (!max_count || (profile_info && flag_branch_probabilities));
+  gcc_assert (in_lto_p
+             || !max_count
+             || (profile_info && flag_branch_probabilities));
   overall_size = initial_size;
 
   nnodes = cgraph_postorder (order);
@@ -1177,8 +1184,7 @@ cgraph_decide_inlining (void)
          for (e = node->callers; e; e = next)
            {
              next = e->next_caller;
-             if (!e->inline_failed
-                 || gimple_call_cannot_inline_p (e->call_stmt))
+             if (!e->inline_failed || e->call_stmt_cannot_inline_p)
                continue;
              if (cgraph_recursive_inlining_p (e->caller, e->callee,
                                               &e->inline_failed))
@@ -1225,7 +1231,7 @@ cgraph_decide_inlining (void)
              && node->callers->inline_failed
              && node->callers->caller != node
              && node->callers->caller->global.inlined_to != node
-             && !gimple_call_cannot_inline_p (node->callers->call_stmt)
+             && !node->callers->call_stmt_cannot_inline_p
              && !DECL_EXTERNAL (node->decl)
              && !DECL_COMDAT (node->decl))
            {
@@ -1411,7 +1417,7 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node,
        if (!e->callee->local.disregard_inline_limits
            && (mode != INLINE_ALL || !e->callee->local.inlinable))
          continue;
-       if (gimple_call_cannot_inline_p (e->call_stmt))
+       if (e->call_stmt_cannot_inline_p)
          continue;
        /* When the edge is already inlined, we just need to recurse into
           it in order to fully flatten the leaves.  */
@@ -1529,7 +1535,7 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node,
          }
        if (!cgraph_check_inline_limits (node, e->callee, &e->inline_failed,
                                         false)
-           || gimple_call_cannot_inline_p (e->call_stmt))
+           || e->call_stmt_cannot_inline_p)
          {
            if (dump_file)
              {
@@ -1632,6 +1638,7 @@ static bool
 cgraph_gate_ipa_early_inlining (void)
 {
   return (flag_early_inlining
+         && !in_lto_p
          && (flag_branch_probabilities || flag_test_coverage
              || profile_arc_flag));
 }
@@ -1919,6 +1926,10 @@ inline_generate_summary (void)
 {
   struct cgraph_node *node;
 
+  /* FIXME lto.  We should not run any IPA-summary pass in LTRANS mode.  */
+  if (flag_ltrans)
+    return;
+
   function_insertion_hook_holder =
       cgraph_add_function_insertion_hook (&add_new_function, NULL);
 
index 2371006..7ffb676 100644 (file)
@@ -1150,6 +1150,10 @@ bool
 ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
                                   VEC (cgraph_edge_p, heap) **new_edges)
 {
+  /* FIXME lto: We do not stream out indirect call information.  */
+  if (flag_wpa)
+    return false;
+
   /* Do nothing if the preparation phase has not been carried out yet
      (i.e. during early inlining).  */
   if (!ipa_node_params_vector)
index 04d4e11..ea1d81e 100644 (file)
@@ -51,6 +51,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "diagnostic.h"
 #include "langhooks.h"
 #include "target.h"
+#include "lto-streamer.h"
 #include "cfgloop.h"
 #include "tree-scalar-evolution.h"
 
@@ -648,13 +649,15 @@ remove_node_data (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
 }
 
 \f
-/* Analyze each function in the cgraph to see if it is locally PURE or
-   CONST.  */
-
-static void 
-generate_summary (void)
+static void
+register_hooks (void)
 {
-  struct cgraph_node *node;
+  static bool init_p = false;
+
+  if (init_p)
+    return;
+
+  init_p = true;
 
   node_removal_hook_holder =
       cgraph_add_node_removal_hook (&remove_node_data, NULL);
@@ -662,6 +665,19 @@ generate_summary (void)
       cgraph_add_node_duplication_hook (&duplicate_node_data, NULL);
   function_insertion_hook_holder =
       cgraph_add_function_insertion_hook (&add_new_function, NULL);
+}
+
+
+/* Analyze each function in the cgraph to see if it is locally PURE or
+   CONST.  */
+
+static void 
+generate_summary (void)
+{
+  struct cgraph_node *node;
+
+  register_hooks ();
+
   /* There are some shared nodes, in particular the initializers on
      static declarations.  We do not need to scan them more than once
      since all we would be interested in are the addressof
@@ -682,6 +698,120 @@ generate_summary (void)
   visited_nodes = NULL;
 }
 
+
+/* Serialize the ipa info for lto.  */
+
+static void
+pure_const_write_summary (cgraph_node_set set)
+{
+  struct cgraph_node *node;
+  struct lto_simple_output_block *ob
+    = lto_create_simple_output_block (LTO_section_ipa_pure_const);
+  unsigned int count = 0;
+  cgraph_node_set_iterator csi;
+
+  for (csi = csi_start (set); !csi_end_p (csi); csi_next (&csi))
+    {
+      node = csi_node (csi);
+      if (node->analyzed && get_function_state (node) != NULL)
+       count++;
+    }
+  
+  lto_output_uleb128_stream (ob->main_stream, count);
+  
+  /* Process all of the functions.  */
+  for (csi = csi_start (set); !csi_end_p (csi); csi_next (&csi))
+    {
+      node = csi_node (csi);
+      if (node->analyzed && get_function_state (node) != NULL)
+       {
+         struct bitpack_d *bp;
+         funct_state fs;
+         int node_ref;
+         lto_cgraph_encoder_t encoder;
+         
+         fs = get_function_state (node);
+
+         encoder = ob->decl_state->cgraph_node_encoder;
+         node_ref = lto_cgraph_encoder_encode (encoder, node);
+         lto_output_uleb128_stream (ob->main_stream, node_ref);
+       
+         /* Note that flags will need to be read in the opposite
+            order as we are pushing the bitflags into FLAGS.  */
+         bp = bitpack_create ();
+         bp_pack_value (bp, fs->pure_const_state, 2);
+         bp_pack_value (bp, fs->state_previously_known, 2);
+         bp_pack_value (bp, fs->looping_previously_known, 1);
+         bp_pack_value (bp, fs->looping, 1);
+         bp_pack_value (bp, fs->can_throw, 1);
+         lto_output_bitpack (ob->main_stream, bp);
+         bitpack_delete (bp);
+       }
+    }
+
+  lto_destroy_simple_output_block (ob);
+}
+
+
+/* Deserialize the ipa info for lto.  */
+
+static void 
+pure_const_read_summary (void)
+{
+  struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
+  struct lto_file_decl_data *file_data;
+  unsigned int j = 0;
+
+  register_hooks ();
+  while ((file_data = file_data_vec[j++]))
+    {
+      const char *data;
+      size_t len;
+      struct lto_input_block *ib
+       = lto_create_simple_input_block (file_data, 
+                                        LTO_section_ipa_pure_const, 
+                                        &data, &len);
+      if (ib)
+       {
+         unsigned int i;
+         unsigned int count = lto_input_uleb128 (ib);
+
+         for (i = 0; i < count; i++)
+           {
+             unsigned int index;
+             struct cgraph_node *node;
+             struct bitpack_d *bp;
+             funct_state fs;
+             lto_cgraph_encoder_t encoder;
+
+             fs = XCNEW (struct funct_state_d);
+             index = lto_input_uleb128 (ib);
+             encoder = file_data->cgraph_node_encoder;
+             node = lto_cgraph_encoder_deref (encoder, index);
+             set_function_state (node, fs);
+
+             /* Note that the flags must be read in the opposite
+                order in which they were written (the bitflags were
+                pushed into FLAGS).  */
+             bp = lto_input_bitpack (ib);
+             fs->pure_const_state
+                       = (enum pure_const_state_e) bp_unpack_value (bp, 2);
+             fs->state_previously_known
+                       = (enum pure_const_state_e) bp_unpack_value (bp, 2);
+             fs->looping_previously_known = bp_unpack_value (bp, 1);
+             fs->looping = bp_unpack_value (bp, 1);
+             fs->can_throw = bp_unpack_value (bp, 1);
+             bitpack_delete (bp);
+           }
+
+         lto_destroy_simple_input_block (file_data, 
+                                         LTO_section_ipa_pure_const, 
+                                         ib, data, len);
+       }
+    }
+}
+
+
 static bool
 ignore_edge (struct cgraph_edge *e)
 {
@@ -952,8 +1082,8 @@ struct ipa_opt_pass_d pass_ipa_pure_const =
   0