aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2005-06-04 13:54:48 +0000
committerJan Hubicka <jh@suse.cz>2005-06-04 13:54:48 +0000
commitf02ebad6e149ca06650b09a2bb88921ee86d651a (patch)
treed0964adef6a41f0707fc09b2e71e4c716c302552
parentf8a262d3463a8787af1353714a0d4747987eabb6 (diff)
* Merge from mainline (tree-profiling-merge-20050603)tree-profiling-branch
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/tree-profiling-branch@100586 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--ChangeLog33
-rw-r--r--MAINTAINERS6
-rwxr-xr-xconfig.sub5
-rwxr-xr-xconfigure3
-rw-r--r--configure.in3
-rw-r--r--gcc/ChangeLog1262
-rw-r--r--gcc/ChangeLog.profiling4
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/Makefile.in125
-rw-r--r--gcc/ada/ChangeLog20
-rw-r--r--gcc/ada/cal.c4
-rw-r--r--gcc/ada/decl.c6
-rw-r--r--gcc/ada/gnat_rm.texi4
-rw-r--r--gcc/ada/gnat_ugn.texi10
-rw-r--r--gcc/ada/init.c10
-rw-r--r--gcc/ada/misc.c1
-rw-r--r--gcc/ada/raise.c12
-rw-r--r--gcc/ada/trans.c7
-rw-r--r--gcc/ada/utils2.c2
-rw-r--r--gcc/basic-block.h13
-rw-r--r--gcc/bb-reorder.c2
-rw-r--r--gcc/builtins.def8
-rw-r--r--gcc/c-common.c2
-rw-r--r--gcc/c-common.h8
-rw-r--r--gcc/c-decl.c35
-rw-r--r--gcc/c-gimplify.c1
-rw-r--r--gcc/c-objc-common.c2
-rw-r--r--gcc/c-parser.c6
-rw-r--r--gcc/c-pch.c2
-rw-r--r--gcc/c-pragma.c24
-rw-r--r--gcc/c-semantics.c27
-rw-r--r--gcc/c-typeck.c5
-rw-r--r--gcc/cfgbuild.c3
-rw-r--r--gcc/cfgexpand.c29
-rw-r--r--gcc/cfghooks.c2
-rw-r--r--gcc/cfghooks.h2
-rw-r--r--gcc/cfgloop.h1
-rw-r--r--gcc/cfgrtl.c2
-rw-r--r--gcc/cgraph.c81
-rw-r--r--gcc/cgraph.h18
-rw-r--r--gcc/cgraphunit.c268
-rw-r--r--gcc/collect2.c2
-rw-r--r--gcc/common.opt4
-rw-r--r--gcc/config.gcc6
-rw-r--r--gcc/config.in12
-rw-r--r--gcc/config/alpha/alpha.c59
-rw-r--r--gcc/config/alpha/alpha.h1
-rw-r--r--gcc/config/alpha/alpha.md8
-rw-r--r--gcc/config/alpha/alpha.opt14
-rw-r--r--gcc/config/arc/arc.c26
-rw-r--r--gcc/config/arc/arc.opt8
-rw-r--r--gcc/config/arm/arm.c45
-rw-r--r--gcc/config/arm/arm.md56
-rw-r--r--gcc/config/arm/arm.opt14
-rw-r--r--gcc/config/arm/semi.h2
-rw-r--r--gcc/config/arm/t-arm1
-rw-r--r--gcc/config/arm/vfp.md66
-rw-r--r--gcc/config/avr/avr.c29
-rw-r--r--gcc/config/avr/avr.opt4
-rw-r--r--gcc/config/bfin/bfin.c6
-rw-r--r--gcc/config/bfin/bfin.opt2
-rw-r--r--gcc/config/c4x/c4x.c5
-rw-r--r--gcc/config/c4x/c4x.h1
-rw-r--r--gcc/config/c4x/c4x.opt2
-rw-r--r--gcc/config/cris/aout.h4
-rw-r--r--gcc/config/cris/aout.opt4
-rw-r--r--gcc/config/cris/cris.c26
-rw-r--r--gcc/config/cris/cris.h14
-rw-r--r--gcc/config/cris/cris.opt10
-rw-r--r--gcc/config/darwin.c2
-rw-r--r--gcc/config/darwin.h2
-rw-r--r--gcc/config/frv/frv.c6
-rw-r--r--gcc/config/frv/frv.md2
-rw-r--r--gcc/config/i386/cygming.h4
-rw-r--r--gcc/config/i386/emmintrin.h35
-rw-r--r--gcc/config/i386/i386.c85
-rw-r--r--gcc/config/i386/i386.h3
-rw-r--r--gcc/config/i386/i386.opt24
-rw-r--r--gcc/config/i386/sse.md2
-rw-r--r--gcc/config/i386/xmmintrin.h10
-rw-r--r--gcc/config/ia64/ia64.c20
-rw-r--r--gcc/config/ia64/ia64.h1
-rw-r--r--gcc/config/ia64/ia64.opt2
-rw-r--r--gcc/config/m32r/m32r.c19
-rw-r--r--gcc/config/m32r/m32r.h4
-rw-r--r--gcc/config/m32r/m32r.opt4
-rw-r--r--gcc/config/m68hc11/m68hc11.c2
-rw-r--r--gcc/config/m68hc11/m68hc11.h2
-rw-r--r--gcc/config/m68k/m68k-none.h4
-rw-r--r--gcc/config/mcore/mcore.c2
-rw-r--r--gcc/config/mips/mips-protos.h3
-rw-r--r--gcc/config/mips/mips.c567
-rw-r--r--gcc/config/mips/mips.h40
-rw-r--r--gcc/config/mips/mips.md53
-rw-r--r--gcc/config/mips/mips.opt6
-rw-r--r--gcc/config/mmix/mmix.h2
-rw-r--r--gcc/config/rs6000/darwin-ldouble.c2
-rw-r--r--gcc/config/rs6000/eabispe.h2
-rw-r--r--gcc/config/rs6000/lynx.h2
-rw-r--r--gcc/config/rs6000/rs6000-c.c2
-rw-r--r--gcc/config/rs6000/rs6000.c101
-rw-r--r--gcc/config/rs6000/rs6000.h6
-rw-r--r--gcc/config/rs6000/rs6000.md161
-rw-r--r--gcc/config/rs6000/rs6000.opt2
-rw-r--r--gcc/config/rs6000/sysv4.h17
-rw-r--r--gcc/config/rs6000/sysv4.opt8
-rw-r--r--gcc/config/rs6000/t-rtems35
-rw-r--r--gcc/config/rs6000/tramp.asm10
-rw-r--r--gcc/config/s390/s390.c66
-rw-r--r--gcc/config/s390/s390.opt2
-rw-r--r--gcc/config/sh/elf.h2
-rw-r--r--gcc/config/sh/predicates.md880
-rw-r--r--gcc/config/sh/sh-protos.h1
-rw-r--r--gcc/config/sh/sh.c846
-rw-r--r--gcc/config/sh/sh.h96
-rw-r--r--gcc/config/sh/sh.md2
-rw-r--r--gcc/config/sh/sh.opt20
-rw-r--r--gcc/config/sh/symbian-pre.h2
-rw-r--r--gcc/config/sh/ushmedia.h4
-rw-r--r--gcc/config/sparc/sparc-protos.h2
-rw-r--r--gcc/config/sparc/sparc.c9
-rw-r--r--gcc/config/sparc/sparc.h2
-rw-r--r--gcc/config/sparc/sparc.md4
-rw-r--r--gcc/config/sparc/sparc.opt2
-rw-r--r--gcc/config/stormy16/stormy-abi2
-rwxr-xr-xgcc/configure97
-rw-r--r--gcc/configure.ac30
-rw-r--r--gcc/convert.c31
-rw-r--r--gcc/cp/ChangeLog133
-rw-r--r--gcc/cp/call.c6
-rw-r--r--gcc/cp/cp-gimplify.c10
-rw-r--r--gcc/cp/cp-tree.def4
-rw-r--r--gcc/cp/cp-tree.h10
-rw-r--r--gcc/cp/cxx-pretty-print.c6
-rw-r--r--gcc/cp/decl.c130
-rw-r--r--gcc/cp/decl2.c67
-rw-r--r--gcc/cp/dump.c2
-rw-r--r--gcc/cp/error.c2
-rw-r--r--gcc/cp/init.c2
-rw-r--r--gcc/cp/lex.c2
-rw-r--r--gcc/cp/mangle.c17
-rw-r--r--gcc/cp/method.c64
-rw-r--r--gcc/cp/name-lookup.c20
-rw-r--r--gcc/cp/operators.def4
-rw-r--r--gcc/cp/optimize.c2
-rw-r--r--gcc/cp/parser.c12
-rw-r--r--gcc/cp/pt.c14
-rw-r--r--gcc/cp/semantics.c26
-rw-r--r--gcc/cp/tree.c9
-rw-r--r--gcc/cp/typeck.c83
-rw-r--r--gcc/ddg.c2
-rw-r--r--gcc/df.c61
-rw-r--r--gcc/df.h11
-rw-r--r--gcc/doc/extend.texi33
-rw-r--r--gcc/doc/install.texi54
-rw-r--r--gcc/doc/invoke.texi50
-rw-r--r--gcc/doc/options.texi29
-rw-r--r--gcc/doc/rtl.texi8
-rw-r--r--gcc/doc/tm.texi195
-rw-r--r--gcc/doc/tree-ssa.texi4
-rw-r--r--gcc/dominance.c2
-rw-r--r--gcc/domwalk.c33
-rw-r--r--gcc/domwalk.h8
-rw-r--r--gcc/dwarf2out.c2
-rw-r--r--gcc/errors.h8
-rw-r--r--gcc/except.c38
-rw-r--r--gcc/except.h4
-rw-r--r--gcc/expmed.c2
-rw-r--r--gcc/expr.c16
-rw-r--r--gcc/expr.h2
-rw-r--r--gcc/fold-const.c183
-rw-r--r--gcc/fortran/ChangeLog131
-rw-r--r--gcc/fortran/Make-lang.in2
-rw-r--r--gcc/fortran/arith.c62
-rw-r--r--gcc/fortran/arith.h2
-rw-r--r--gcc/fortran/data.c4
-rw-r--r--gcc/fortran/gfortran.h13
-rw-r--r--gcc/fortran/gfortran.texi26
-rw-r--r--gcc/fortran/intrinsic.c44
-rw-r--r--gcc/fortran/intrinsic.texi429
-rw-r--r--gcc/fortran/invoke.texi2
-rw-r--r--gcc/fortran/io.c28
-rw-r--r--gcc/fortran/lang.opt4
-rw-r--r--gcc/fortran/options.c20
-rw-r--r--gcc/fortran/parse.c2
-rw-r--r--gcc/fortran/resolve.c64
-rw-r--r--gcc/fortran/simplify.c17
-rw-r--r--gcc/fortran/trans-array.c33
-rw-r--r--gcc/fortran/trans-decl.c3
-rw-r--r--gcc/fortran/trans-expr.c136
-rw-r--r--gcc/fortran/trans-intrinsic.c2
-rw-r--r--gcc/fortran/trans-stmt.c2
-rw-r--r--gcc/fortran/trans-types.c2
-rw-r--r--gcc/fortran/trans.c2
-rw-r--r--gcc/fortran/trans.h4
-rw-r--r--gcc/gcse.c87
-rw-r--r--gcc/genmodes.c39
-rw-r--r--gcc/ggc-page.c2
-rw-r--r--gcc/ggc-zone.c2
-rw-r--r--gcc/gimple-low.c1
-rw-r--r--gcc/gimplify.c197
-rw-r--r--gcc/global.c4
-rw-r--r--gcc/ifcvt.c176
-rw-r--r--gcc/ipa-inline.c23
-rw-r--r--gcc/ipa-prop.c2
-rw-r--r--gcc/ipcp.c2
-rw-r--r--gcc/java/ChangeLog96
-rw-r--r--gcc/java/Make-lang.in4
-rw-r--r--gcc/java/class.c60
-rw-r--r--gcc/java/decl.c87
-rw-r--r--gcc/java/java-tree.h36
-rw-r--r--gcc/java/jcf-write.c2
-rw-r--r--gcc/java/lang.c3
-rw-r--r--gcc/java/mangle.c124
-rw-r--r--gcc/java/parse.y399
-rw-r--r--gcc/java/verify-glue.c2
-rw-r--r--gcc/lambda-code.c5
-rw-r--r--gcc/lambda-trans.c1
-rw-r--r--gcc/local-alloc.c7
-rw-r--r--gcc/longlong.h4
-rw-r--r--gcc/loop-doloop.c47
-rw-r--r--gcc/loop-iv.c6
-rw-r--r--gcc/loop.c2
-rw-r--r--gcc/machmode.h3
-rw-r--r--gcc/modulo-sched.c90
-rw-r--r--gcc/opt-functions.awk15
-rw-r--r--gcc/optabs.c1
-rw-r--r--gcc/optc-gen.awk6
-rw-r--r--gcc/opth-gen.awk9
-rw-r--r--gcc/opts.c109
-rw-r--r--gcc/opts.h22
-rw-r--r--gcc/po/ChangeLog4
-rw-r--r--gcc/po/sv.po37
-rw-r--r--gcc/postreload-gcse.c2
-rw-r--r--gcc/predict.c16
-rw-r--r--gcc/reg-stack.c505
-rw-r--r--gcc/reload1.c21
-rw-r--r--gcc/rtl.c6
-rw-r--r--gcc/rtl.h3
-rw-r--r--gcc/simplify-rtx.c43
-rw-r--r--gcc/stmt.c11
-rw-r--r--gcc/system.h3
-rw-r--r--gcc/target-def.h2
-rw-r--r--gcc/target.h5
-rw-r--r--gcc/targhooks.c2
-rw-r--r--gcc/testsuite/ChangeLog545
-rw-r--r--gcc/testsuite/g++.dg/abi/bitfield3.C4
-rw-r--r--gcc/testsuite/g++.dg/abi/bitfield8.C5
-rw-r--r--gcc/testsuite/g++.dg/abi/bitfield9.C3
-rw-r--r--gcc/testsuite/g++.dg/abi/dtor1.C4
-rw-r--r--gcc/testsuite/g++.dg/abi/empty10.C4
-rw-r--r--gcc/testsuite/g++.dg/abi/empty7.C4
-rw-r--r--gcc/testsuite/g++.dg/abi/empty9.C4
-rw-r--r--gcc/testsuite/g++.dg/abi/layout3.C4
-rw-r--r--gcc/testsuite/g++.dg/abi/layout4.C4
-rw-r--r--gcc/testsuite/g++.dg/abi/thunk1.C5
-rw-r--r--gcc/testsuite/g++.dg/abi/thunk2.C4
-rw-r--r--gcc/testsuite/g++.dg/abi/vbase11.C4
-rw-r--r--gcc/testsuite/g++.dg/abi/vthunk2.C4
-rw-r--r--gcc/testsuite/g++.dg/abi/vthunk3.C4
-rw-r--r--gcc/testsuite/g++.dg/charset/asm2.c2
-rw-r--r--gcc/testsuite/g++.dg/eh/simd-1.C1
-rw-r--r--gcc/testsuite/g++.dg/eh/simd-2.C1
-rw-r--r--gcc/testsuite/g++.dg/ext/attrib8.C4
-rw-r--r--gcc/testsuite/g++.dg/init/ctor4.C4
-rw-r--r--gcc/testsuite/g++.dg/opt/cse2.C2
-rw-r--r--gcc/testsuite/g++.dg/opt/longbranch2.C5
-rw-r--r--gcc/testsuite/g++.dg/opt/mmx1.C3
-rw-r--r--gcc/testsuite/g++.dg/opt/reg-stack4.C4
-rw-r--r--gcc/testsuite/g++.dg/other/big-struct.C3
-rw-r--r--gcc/testsuite/g++.dg/warn/register-var-1.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.bob/inherit2.C6
-rw-r--r--gcc/testsuite/g++.old-deja/g++.bugs/900205_04.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.eh/badalloc1.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.ext/asmspec1.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.ext/attrib1.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.ext/attrib2.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.ext/attrib3.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/opeq3.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/regstack.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/store-expr1.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/store-expr2.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/assign1.C6
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/crash20.C13
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/ieee/ieee.exp5
-rw-r--r--gcc/testsuite/gcc.dg/20000609-1.c5
-rw-r--r--gcc/testsuite/gcc.dg/20000614-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/20000720-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/20000807-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/20000904-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/20001127-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/20010202-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/20010520-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/20011009-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/20011029-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/20011107-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/20011119-1.c5
-rw-r--r--gcc/testsuite/gcc.dg/20020108-1.c5
-rw-r--r--gcc/testsuite/gcc.dg/20020122-2.c4
-rw-r--r--gcc/testsuite/gcc.dg/20020122-3.c4
-rw-r--r--gcc/testsuite/gcc.dg/20020201-3.c4
-rw-r--r--gcc/testsuite/gcc.dg/20020206-1.c5
-rw-r--r--gcc/testsuite/gcc.dg/20020218-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/20020224-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/20020310-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/20020411-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/20020418-2.c4
-rw-r--r--gcc/testsuite/gcc.dg/20020426-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/20020426-2.c4
-rw-r--r--gcc/testsuite/gcc.dg/20020517-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/20020523-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/20020523-2.c4
-rw-r--r--gcc/testsuite/gcc.dg/20020531-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/20020616-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/20020729-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/20030204-1.c5
-rw-r--r--gcc/testsuite/gcc.dg/20030826-2.c4
-rw-r--r--gcc/testsuite/gcc.dg/20030926-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/20031202-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/980226-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/980312-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/980313-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/980414-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/980520-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/980709-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/990117-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/990130-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/990213-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/990214-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/990424-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/990524-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/991129-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/991209-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/991214-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/991230-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/asm-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/attr-returns_twice-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/builtins-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/c99-math-double-1.c36
-rw-r--r--gcc/testsuite/gcc.dg/c99-math-float-1.c36
-rw-r--r--gcc/testsuite/gcc.dg/c99-math-long-double-1.c36
-rw-r--r--gcc/testsuite/gcc.dg/c99-math.h222
-rw-r--r--gcc/testsuite/gcc.dg/charset/asm3.c2
-rw-r--r--gcc/testsuite/gcc.dg/clobbers.c2
-rw-r--r--gcc/testsuite/gcc.dg/cpp/trad/num-sign.c2
-rw-r--r--gcc/testsuite/gcc.dg/i386-387-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/i386-387-2.c4
-rw-r--r--gcc/testsuite/gcc.dg/i386-387-3.c4
-rw-r--r--gcc/testsuite/gcc.dg/i386-387-4.c4
-rw-r--r--gcc/testsuite/gcc.dg/i386-387-5.c4
-rw-r--r--gcc/testsuite/gcc.dg/i386-387-6.c4
-rw-r--r--gcc/testsuite/gcc.dg/i386-387-7.c2
-rw-r--r--gcc/testsuite/gcc.dg/i386-387-8.c3
-rw-r--r--gcc/testsuite/gcc.dg/i386-3dnowA-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/i386-3dnowA-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/i386-asm-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/i386-asm-2.c3
-rw-r--r--gcc/testsuite/gcc.dg/i386-asm-3.c2
-rw-r--r--gcc/testsuite/gcc.dg/i386-bitfield1.c4
-rw-r--r--gcc/testsuite/gcc.dg/i386-bitfield2.c4
-rw-r--r--gcc/testsuite/gcc.dg/i386-bitfield3.c2
-rw-r--r--gcc/testsuite/gcc.dg/i386-call-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/i386-loop-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/i386-loop-2.c4
-rw-r--r--gcc/testsuite/gcc.dg/i386-loop-3.c4
-rw-r--r--gcc/testsuite/gcc.dg/i386-memset-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/i386-pentium4-not-mull.c5
-rw-r--r--gcc/testsuite/gcc.dg/i386-pic-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/i386-regparm.c4
-rw-r--r--gcc/testsuite/gcc.dg/i386-signbit-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/i386-signbit-2.c4
-rw-r--r--gcc/testsuite/gcc.dg/i386-signbit-3.c4
-rw-r--r--gcc/testsuite/gcc.dg/i386-sse-5.c5
-rw-r--r--gcc/testsuite/gcc.dg/i386-sse-8.c5
-rw-r--r--gcc/testsuite/gcc.dg/i386-ssefn-1.c3
-rw-r--r--gcc/testsuite/gcc.dg/i386-ssefn-2.c3
-rw-r--r--gcc/testsuite/gcc.dg/i386-ssefn-3.c2
-rw-r--r--gcc/testsuite/gcc.dg/i386-ssefn-4.c2
-rw-r--r--gcc/testsuite/gcc.dg/i386-unroll-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/i386-volatile-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/i386-xorps.c2
-rw-r--r--gcc/testsuite/gcc.dg/ppc-vector-memcpy.c2
-rw-r--r--gcc/testsuite/gcc.dg/pr12092-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/pr14289-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/pr19236-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/pr20204.c2
-rw-r--r--gcc/testsuite/gcc.dg/pr9771-1.c3
-rw-r--r--gcc/testsuite/gcc.dg/register-var-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/setjmp-2.c5
-rw-r--r--gcc/testsuite/gcc.dg/short-compare-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/short-compare-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/sibcall-5.c3
-rw-r--r--gcc/testsuite/gcc.dg/tls/opt-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/tls/opt-2.c4
-rw-r--r--gcc/testsuite/gcc.dg/torture/builtin-attr-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/tree-prof.exp2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11a.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11b.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11c.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/gen-vect-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/gen-vect-25.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/gen-vect-26.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/gen-vect-28.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/gen-vect-32.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr14841.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-14.c6
-rw-r--r--gcc/testsuite/gcc.dg/unroll-1.c5
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-7.c4
-rw-r--r--gcc/testsuite/gcc.misc-tests/i386-pf-3dnow-1.c4
-rw-r--r--gcc/testsuite/gcc.misc-tests/i386-pf-athlon-1.c4
-rw-r--r--gcc/testsuite/gcc.misc-tests/i386-pf-none-1.c4
-rw-r--r--gcc/testsuite/gcc.misc-tests/i386-pf-sse-1.c4
-rw-r--r--gcc/testsuite/gfortran.dg/assign_2.f902
-rw-r--r--gcc/testsuite/gfortran.dg/promotion.f903
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_unpack.f904
-rw-r--r--gcc/testsuite/lib/obj-c++.exp7
-rw-r--r--gcc/testsuite/lib/target-supports.exp45
-rw-r--r--gcc/testsuite/objc.dg/selector-2.m5
-rw-r--r--gcc/testsuite/objc/execute/next_mapping.h25
-rw-r--r--gcc/testsuite/treelang/compile/unsigned.tree6
-rw-r--r--gcc/timevar.c2
-rw-r--r--gcc/timevar.h2
-rw-r--r--gcc/toplev.c341
-rw-r--r--gcc/toplev.h2
-rw-r--r--gcc/tree-browser.c1
-rw-r--r--gcc/tree-browser.def2
-rw-r--r--gcc/tree-cfg.c876
-rw-r--r--gcc/tree-cfgcleanup.c2
-rw-r--r--gcc/tree-chrec.c5
-rw-r--r--gcc/tree-complex.c493
-rw-r--r--gcc/tree-data-ref.c1
-rw-r--r--gcc/tree-dfa.c1
-rw-r--r--gcc/tree-eh.c13
-rw-r--r--gcc/tree-flow-inline.h15
-rw-r--r--gcc/tree-flow.h64
-rw-r--r--gcc/tree-if-conv.c3
-rw-r--r--gcc/tree-inline.c166
-rw-r--r--gcc/tree-into-ssa.c9
-rw-r--r--gcc/tree-loop-linear.c1
-rw-r--r--gcc/tree-mudflap.c2
-rw-r--r--gcc/tree-nested.c10
-rw-r--r--gcc/tree-nomudflap.c2
-rw-r--r--gcc/tree-optimize.c6
-rw-r--r--gcc/tree-outof-ssa.c44
-rw-r--r--gcc/tree-pass.h5
-rw-r--r--gcc/tree-phinodes.c6
-rw-r--r--gcc/tree-pretty-print.c4
-rw-r--r--gcc/tree-scalar-evolution.c1
-rw-r--r--gcc/tree-sra.c5
-rw-r--r--gcc/tree-ssa-alias.c33
-rw-r--r--gcc/tree-ssa-ccp.c51
-rw-r--r--gcc/tree-ssa-copy.c18
-rw-r--r--gcc/tree-ssa-copyrename.c2
-rw-r--r--gcc/tree-ssa-dce.c1
-rw-r--r--gcc/tree-ssa-dom.c85
-rw-r--r--gcc/tree-ssa-dse.c11
-rw-r--r--gcc/tree-ssa-forwprop.c11
-rw-r--r--gcc/tree-ssa-live.c6
-rw-r--r--gcc/tree-ssa-loop-im.c5
-rw-r--r--gcc/tree-ssa-loop-ivopts.c43
-rw-r--r--gcc/tree-ssa-operands.c4
-rw-r--r--gcc/tree-ssa-phiopt.c1
-rw-r--r--gcc/tree-ssa-pre.c1
-rw-r--r--gcc/tree-ssa-propagate.c147
-rw-r--r--gcc/tree-ssa-propagate.h35
-rw-r--r--gcc/tree-ssa-sink.c1
-rw-r--r--gcc/tree-ssa-threadupdate.c22
-rw-r--r--gcc/tree-ssa-uncprop.c1
-rw-r--r--gcc/tree-ssa.c2
-rw-r--r--gcc/tree-vect-analyze.c7
-rw-r--r--gcc/tree-vect-generic.c4
-rw-r--r--gcc/tree-vect-transform.c49
-rw-r--r--gcc/tree-vectorizer.c17
-rw-r--r--gcc/tree-vrp.c2375
-rw-r--r--gcc/tree.c98
-rw-r--r--gcc/tree.h22
-rw-r--r--gcc/treelang/ChangeLog6
-rw-r--r--gcc/treelang/Make-lang.in5
-rw-r--r--gcc/treelang/lex.l2
-rw-r--r--gcc/treelang/parse.y2
-rw-r--r--gcc/unwind-compat.c2
-rw-r--r--gcc/unwind-dw2-fde-compat.c2
-rw-r--r--gcc/unwind-dw2-fde.c2
-rw-r--r--gcc/value-prof.c37
-rw-r--r--gcc/var-tracking.c3
-rw-r--r--gcc/varray.c6
-rw-r--r--gcc/vec.c2
-rw-r--r--gcc/vec.h152
-rw-r--r--include/ChangeLog26
-rw-r--r--include/ansidecl.h16
-rw-r--r--include/demangle.h3
-rw-r--r--include/libiberty.h13
-rw-r--r--libcpp/ChangeLog87
-rw-r--r--libcpp/charset.c24
-rw-r--r--libcpp/config.in8
-rwxr-xr-xlibcpp/configure140
-rw-r--r--libcpp/configure.ac3
-rw-r--r--libcpp/directives.c69
-rw-r--r--libcpp/expr.c8
-rw-r--r--libcpp/files.c60
-rw-r--r--libcpp/identifiers.c2
-rw-r--r--libcpp/include/cpplib.h25
-rw-r--r--libcpp/init.c6
-rw-r--r--libcpp/lex.c10
-rw-r--r--libcpp/line-map.c2
-rw-r--r--libcpp/macro.c29
-rw-r--r--libcpp/makedepend.c4
-rw-r--r--libcpp/mkdeps.c23
-rw-r--r--libcpp/pch.c34
-rw-r--r--libcpp/symtab.c9
-rw-r--r--libcpp/system.h10
-rw-r--r--libcpp/traditional.c4
-rw-r--r--libffi/ChangeLog6
-rw-r--r--libffi/src/powerpc/ppc_closure.S2
-rw-r--r--libffi/src/powerpc/sysv.S2
-rw-r--r--libgfortran/ChangeLog34
-rw-r--r--libgfortran/intrinsics/unpack_generic.c51
-rw-r--r--libgfortran/io/format.c1
-rw-r--r--libgfortran/io/transfer.c7
-rw-r--r--libgfortran/io/unix.c7
-rw-r--r--libgfortran/runtime/in_pack_generic.c8
-rw-r--r--libgfortran/runtime/in_unpack_generic.c8
-rw-r--r--libiberty/ChangeLog18
-rw-r--r--libiberty/config.in8
-rwxr-xr-xlibiberty/configure280
-rw-r--r--libiberty/configure.ac4
-rw-r--r--libiberty/cp-demangle.c14
-rw-r--r--libiberty/testsuite/demangle-expected4
-rw-r--r--libjava/ChangeLog113
-rwxr-xr-xlibjava/configure3
-rw-r--r--libjava/configure.ac11
-rw-r--r--libjava/configure.host22
-rw-r--r--libjava/gnu/java/nio/channels/natFileChannelPosix.cc11
-rw-r--r--libjava/gnu/regexp/RE.java36
-rw-r--r--libjava/gnu/regexp/RESyntax.java8
-rw-r--r--libjava/gnu/regexp/RETokenRepeated.java13
-rw-r--r--libjava/include/jvm.h47
-rw-r--r--libjava/java/io/ObjectInputStream.java34
-rw-r--r--libjava/java/io/natObjectInputStream.cc13
-rw-r--r--libjava/java/lang/natString.cc5
-rw-r--r--libjava/java/util/LinkedHashMap.java3
-rw-r--r--libjava/java/util/regex/Pattern.java3
-rw-r--r--libjava/jawt.c1
-rw-r--r--libjava/mauve-libgcj8
-rw-r--r--libjava/stacktrace.cc9
-rw-r--r--libjava/testsuite/libjava.jacks/jacks.xfail2
-rw-r--r--libjava/testsuite/libjava.jni/jni.exp2
-rw-r--r--libstdc++-v3/ChangeLog154
-rw-r--r--libstdc++-v3/acinclude.m412
-rw-r--r--libstdc++-v3/config/linker-map.gnu14
-rwxr-xr-xlibstdc++-v3/configure6
-rw-r--r--libstdc++-v3/configure.ac2
-rw-r--r--libstdc++-v3/docs/html/abi.html9
-rw-r--r--libstdc++-v3/docs/html/test.html4
-rw-r--r--libstdc++-v3/include/Makefile.am2
-rw-r--r--libstdc++-v3/include/Makefile.in2
-rw-r--r--libstdc++-v3/include/bits/basic_string.h16
-rw-r--r--libstdc++-v3/include/bits/basic_string.tcc20
-rw-r--r--libstdc++-v3/include/bits/c++config51
-rw-r--r--libstdc++-v3/include/bits/deque.tcc48
-rw-r--r--libstdc++-v3/include/bits/list.tcc2
-rw-r--r--libstdc++-v3/include/bits/stl_deque.h59
-rw-r--r--libstdc++-v3/include/bits/stl_list.h44
-rw-r--r--libstdc++-v3/include/bits/stl_map.h73
-rw-r--r--libstdc++-v3/include/bits/stl_multimap.h81
-rw-r--r--libstdc++-v3/include/bits/stl_multiset.h88
-rw-r--r--libstdc++-v3/include/bits/stl_set.h78
-rw-r--r--libstdc++-v3/include/bits/stl_vector.h48
-rw-r--r--libstdc++-v3/include/bits/vector.tcc60
-rw-r--r--libstdc++-v3/include/c_std/std_cstdlib.h13
-rw-r--r--libstdc++-v3/include/debug/debug.h453
-rw-r--r--libstdc++-v3/include/debug/hash_map8
-rw-r--r--libstdc++-v3/include/debug/hash_set8
-rw-r--r--libstdc++-v3/include/debug/safe_iterator.h7
-rw-r--r--libstdc++-v3/include/debug/safe_sequence.h4
-rw-r--r--libstdc++-v3/include/debug/vector4
-rw-r--r--libstdc++-v3/include/ext/array_allocator.h5
-rw-r--r--libstdc++-v3/include/ext/hash_map7
-rw-r--r--libstdc++-v3/include/ext/hash_set7
-rw-r--r--libstdc++-v3/include/std/std_complex.h12
-rw-r--r--libstdc++-v3/src/bitmap_allocator.cc4
-rw-r--r--libstdc++-v3/src/debug.cc9
-rw-r--r--libstdc++-v3/src/misc-inst.cc5
-rw-r--r--libstdc++-v3/src/mt_allocator.cc5
-rw-r--r--libstdc++-v3/src/pool_allocator.cc1
-rw-r--r--libstdc++-v3/testsuite/23_containers/deque/explicit_instantiation.cc34
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/explicit_instantiation.cc34
-rw-r--r--libstdc++-v3/testsuite/23_containers/map/explicit_instantiation.cc34
-rw-r--r--libstdc++-v3/testsuite/23_containers/multimap/explicit_instantiation.cc34
-rw-r--r--libstdc++-v3/testsuite/23_containers/multiset/explicit_instantiation.cc34
-rw-r--r--libstdc++-v3/testsuite/23_containers/set/explicit_instantiation.cc34
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/explicit_instantiation.cc34
-rw-r--r--libstdc++-v3/testsuite/27_io/ios_base/cons/assign_neg.cc3
-rw-r--r--libstdc++-v3/testsuite/27_io/ios_base/cons/copy_neg.cc3
-rw-r--r--libstdc++-v3/testsuite/ext/array_allocator/2.cc12
-rw-r--r--libstdc++-v3/testsuite/lib/libstdc++.exp31
-rw-r--r--libstdc++-v3/testsuite/libstdc++-dg/normal.exp3
-rw-r--r--libstdc++-v3/testsuite/testsuite_abi.cc1
599 files changed, 12392 insertions, 8192 deletions
diff --git a/ChangeLog b/ChangeLog
index 897a621ad1c..da4c57d9db4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,36 @@
+2005-06-02 Jim Blandy <jimb@redhat.com>
+
+ * config.sub: Add cases for the Renesas m32c. (This patch has been
+ accepted into the master sources.)
+
+2005-06-02 Aldy Hernandez <aldyh@redhat.com>
+ Michael Snyder <msnyder@redhat.com>
+ Stan Cox <scox@redhat.com>
+
+ * configure.in: Set noconfigdirs for ms1.
+
+ * configure: Regenerate.
+
+2005-06-01 Jerry DeLisle <jvdelisle@verizon.net>
+
+ * MAINTAINERS (Write After Approval): Add self.
+
+2005-06-01 Josh Conner <jconner@apple.com>
+
+ * MAINTAINERS (Write After Approval): Add self.
+
+2005-06-01 Kazu Hirata <kazu@codesourcery.com>
+
+ * MAINTAINERS: Update my email address.
+
+2005-05-27 Ziga Mahkovec <ziga.mahkovec@klika.si>
+
+ * MAINTAINERS (Write After Approval): Add self.
+
+2005-05-26 Chris Demetriou <cgd@broadcom.com>
+
+ * MAINTAINERS (Write After Approval): Remove self.
+
2005-05-25 Paolo Bonzini <bonzini@gnu.org>
* Makefile.tpl (stage[+id+]-start): Iterate over target module as well.
diff --git a/MAINTAINERS b/MAINTAINERS
index 5c0811fd1e7..a2e7307bf3e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -49,7 +49,7 @@ fr30 port Nick Clifton nickc@redhat.com
frv port Aldy Hernandez aldyh@redhat.com
frv port Alexandre Oliva aoliva@redhat.com
h8 port Jeff Law law@redhat.com
-h8 port Kazu Hirata kazu@cs.umass.edu
+h8 port Kazu Hirata kazu@codesourcery.com
hppa port Jeff Law law@redhat.com
hppa port Dave Anglin dave.anglin@nrc.ca
i386 port Richard Henderson rth@redhat.com
@@ -223,12 +223,13 @@ Steve Chamberlain sac@transmeta.com
Michael Chastain mec.gnu@mindspring.com
Chandra Chavva cchavva@redhat.com
William Cohen wcohen@redhat.com
+Josh Conner jconner@apple.com
R. Kelley Cook kcook@gcc.gnu.org
Christian Cornelssen ccorn@cs.tu-berlin.de
François-Xavier Coudert coudert@clipper.ens.fr
David Daney ddaney@avtrex.com
Bud Davis bdavis9659@comcast.net
-Chris Demetriou cgd@broadcom.com
+Jerry DeLisle jvdelisle@verizon.net
Zdenek Dvorak dvorakz@suse.cz
Steve Ellcey sje@cup.hp.com
Mohan Embar gnustuff@thisiscool.com
@@ -277,6 +278,7 @@ Gabor Loki loki@inf.u-szeged.hu
Dave Love d.love@dl.ac.uk
Martin v. Löwis loewis@informatik.hu-berlin.de
HJ Lu hjl@lucon.org
+Ziga Mahkovec ziga.mahkovec@klika.si
Ranjit Mathew rmathew@hotmail.com
Michael Matz matz@suse.de
Greg McGary gkm@gnu.org
diff --git a/config.sub b/config.sub
index 87a1ee49e67..c2262a72984 100755
--- a/config.sub
+++ b/config.sub
@@ -273,6 +273,9 @@ case $basic_machine in
| z8k)
basic_machine=$basic_machine-unknown
;;
+ m32c)
+ basic_machine=$basic_machine-unknown
+ ;;
m6811 | m68hc11 | m6812 | m68hc12)
# Motorola 68HC11/12.
basic_machine=$basic_machine-unknown
@@ -351,6 +354,8 @@ case $basic_machine in
| ymp-* \
| z8k-*)
;;
+ m32c-*)
+ ;;
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
386bsd)
diff --git a/configure b/configure
index be814518b79..1e25b8e1b1d 100755
--- a/configure
+++ b/configure
@@ -1430,6 +1430,9 @@ case "${target}" in
mn10300-*-*)
noconfigdirs="$noconfigdirs ${libgcj}"
;;
+ ms1-*-*)
+ noconfigdirs="$noconfigdirs sim"
+ ;;
powerpc-*-aix*)
# copied from rs6000-*-* entry
noconfigdirs="$noconfigdirs gprof target-libgloss ${libgcj}"
diff --git a/configure.in b/configure.in
index c2ced9168a7..7e2f52aa7a3 100644
--- a/configure.in
+++ b/configure.in
@@ -647,6 +647,9 @@ case "${target}" in
mn10300-*-*)
noconfigdirs="$noconfigdirs ${libgcj}"
;;
+ ms1-*-*)
+ noconfigdirs="$noconfigdirs sim"
+ ;;
powerpc-*-aix*)
# copied from rs6000-*-* entry
noconfigdirs="$noconfigdirs gprof target-libgloss ${libgcj}"
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 02d90470820..22136dd307b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,1261 @@
+2005-06-03 Pat Haugen <pthaugen@us.ibm.com>
+
+ * config/rs6000/rs6000.c (rs6000_conditional_register_usage):
+ Clear call_realy_used_regs[r2] when ABI_AIX.
+
+2005-06-03 Richard Guenther <rguenth@gcc.gnu.org>
+
+ PR middle-end/21858
+ * fold-const.c (fold_binary): Fix type mismatches in folding
+ of comparisons.
+
+2005-06-03 Kazu Hirata <kazu@codesourcery.com>
+
+ * cgraph.c, cgraphunit.c, config/mips/mips.c: Fix comment
+ typos.
+
+2005-06-03 Joseph S. Myers <joseph@codesourcery.com>
+
+ * collect2.c (maybe_unlink): Use unlink_if_ordinary.
+
+2005-06-02 Bernd Schmidt <bernd.schmidt@analog.com>
+
+ * reload1.c (reload): Revert my previous patch.
+
+2005-06-03 Nick Clifton <nickc@redhat.com>
+
+ * config/arm/semi.h (ASM_SPEC): Fix typo passing -mfloat-abi to
+ assembler.
+
+2005-06-03 Kazu Hirata <kazu@codesourcery.com>
+
+ PR tree-optimization/21849
+ * tree-ssa-copy.c (dump_copy_of): Call sbitmap_zero.
+
+2005-06-02 Richard Henderson <rth@redhat.com>
+
+ * Makefile.in (tree-vect-generic.o): New.
+ (OBJS-common, GTFILES, s-gtype): Add it.
+ * tree-complex.c (build_replicated_const, vector_inner_type,
+ vector_last_type, vector_last_nunits, build_word_mode_vector_type,
+ elem_op_func, tree_vec_extract, do_unop, do_binop, do_plus_minus,
+ do_negate, expand_vector_piecewise, expand_vector_parallel,
+ expand_vector_addition, expand_vector_operation,
+ type_for_widest_vector_mode, expand_vector_operations_1,
+ gate_expand_vector_operations, expand_vector_operations,
+ pass_lower_vector_ssa): Move to tree-vect-generic.c.
+ (tree_lower_complex): Rename from tree_lower_operations.
+ (pass_lower_complex): Rename from pass_pre_expand.
+ * tree-vect-generic.c: New file.
+ * tree-pass.h (pass_lower_complex): Rename from pass_pre_expand.
+ (pass_lower_vector): New.
+ * tree-optimize.c (init_tree_optimization_passes): Update to match.
+
+2005-06-02 Richard Henderson <rth@redhat.com>
+
+ * modulo-sched.c (doloop_register_get): Protect against
+ doloop_end not defined.
+
+2005-06-02 Kazu Hirata <kazu@codesourcery.com>
+
+ * config/sh/sh.c (general_movsrc_operand,
+ general_movdst_operand, arith_reg_operand, arith_reg_dest,
+ logical_reg_operand, int_gpr_dest, fp_arith_reg_operand,
+ fp_arith_reg_dest, arith_operand, arith_reg_or_0_operand,
+ xor_operand, cmp_operand, logical_operand, and_operand,
+ fpscr_operand, fpul_operand, symbol_ref_operand,
+ commutative_float_operator, noncommutative_float_operator,
+ unary_float_operator, binary_float_operator,
+ binary_logical_operator, equality_comparison_operator,
+ greater_comparison_operator, less_comparison_operator,
+ shift_operator, logical_operator, target_reg_operand,
+ target_operand, mextr_bit_offset, extend_reg_operand,
+ trunc_hi_operand, extend_reg_or_0_operand, minuend_operand,
+ general_extend_operand, ua_address_operand,
+ cache_address_operand, inqhi_operand, sh_rep_vec, sh_1el_vec,
+ sh_const_vec, ua_offset, sh_register_operand, cmpsi_operand,
+ shift_count_reg_operand, shift_count_operand,
+ unaligned_load_operand): Move to ...
+ * config/sh/predicates.md: ... here.
+ * config/sh/sh.h (PREDICATE_CODES, SPECIAL_MODE_PREDICATES):
+ Remove.
+
+2005-06-02 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * tree.c (build_common_builtin_nodes): Fix the return type on
+ __builtin_memcmp.
+
+2005-06-02 Richard Guenther <rguenth@gcc.gnu.org>
+
+ * tree-ssa-loop-ivopts.c (build_addr_strip_iref): Remove.
+ (find_interesting_uses_address): Use build_fold_addr_expr instead.
+ (strip_offset_1): Likewise.
+ (tree_to_aff_combination): Likewise.
+
+2005-06-02 DJ Delorie <dj@redhat.com>
+
+ * convert.c (convert_to_pointer): Avoid recursion if no conversion
+ is needed.
+
+2005-06-02 Richard Guenther <rguenth@gcc.gnu.org>
+
+ * tree-chrec.c (chrec_fold_plus_1): Ensure we build
+ binary operations with the correct types.
+ * tree-ssa-loo-ivopts.c (idx_find_step): Use sizetype
+ for all computation.
+
+2005-06-02 Kazu Hirata <kazu@codesourcery.com>
+
+ * tree-vrp.c, config/arm/arm.md, config/arm/arm1020e.md,
+ config/rs6000/rs6000.md: Fix comment typos. Follow splling
+ conventions.
+ * doc/install.texi: Fix a typo.
+
+2005-06-02 Jan Hubicka <jh@suse.cz>
+
+ * cgraphunit.c (cgraph_function_and_variable_visibility): Extern
+ inline functions are not local.
+
+2005-06-02 Kazu Hirata <kazu@codesourcery.com>
+
+ * gimplify.c (gimplify_ctx): Change the type of case_labels to
+ VEC from VARRAY.
+ (gimplify_switch_expr, gimplify_case_label_expr): Adjust uses
+ of case_labels.
+
+2005-06-02 Richard Guenther <rguenth@gcc.gnu.org>
+
+ * c-typeck.c (build_indirect_ref): Build INDIRECT_REF
+ with correct type.
+
+2005-06-02 Ulrich Weigand <uweigand@de.ibm.com>
+
+ * config/s390/s390.c (s390_add_execute): Do not handle out-of-pool
+ execute templates.
+ (s390_dump_pool): Likewise.
+ (s390_mainpool_start, s390_mainpool_finish): Likewise.
+ (s390_chunkify_start): Likewise.
+ (s390_dump_execute): Remove.
+ (s390_reorg): Handle out-of-pool execute templates.
+
+2005-06-02 Adrian Straetling <straetling@de.ibm.com>
+
+ * optabs.c: (expand_bool_compare_and_swap): Emit barrier after
+ unconditional jump.
+
+2005-06-02 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (cgraph_node): Maintain master clones.
+ (cgraph_remove_node): Likewise.
+ (availability_names): New static variable.
+ (dump_cgraph_node): Dump availability.
+ (dump_cgraph_varpool_node): Likewise.
+ (cgraph_is_master_clone, cgraph_master_clone,
+ cgraph_function_body_availability,
+ cgraph_variable_initializer_availability): New functions.
+ * cgraph.h (availability): New enum.
+ (struct cgraph_node): Add master_clone.
+ (cgraph_is_master_clone, cgraph_master_clone,
+ cgraph_function_body_availability,
+ cgraph_variable_initializer_availability): Declare.
+ * cgraphunit.c (cgraph_expand_function): Setcgraph_function_flags_ready.
+ (cgraph_remove_unreachable_nodes): Remove unreachable nodes.
+ * ipa-inline.c (cgraph_decide_inlining): Do not call
+ cgraph_remove_unreachable_nodes.
+
+ * cgraphunit.c (cgraph_function_and_variable_visibility): Fix typo in
+ previous patch.
+
+2005-06-02 Diego Novillo <dnovillo@redhat.com>
+
+ PR 21582
+ * tree-vrp.c (nonnull_arg_p): New.
+ (get_value_range): Call it.
+
+2005-06-02 Eric Christopher <echristo@redhat.com>
+
+ * config/mips/mips.h (processor_type): Remove PROCESSOR_DEFAULT,
+ add PROCESSOR_MAX.
+ (mips_rtx_cost_data): New datatype.
+ (MEMORY_MOVE_COST): Use data from structure.
+ (BRANCH_COST): Ditto.
+ (LOGICAL_OP_NON_SHORT_CIRCUIT): Define to zero.
+ * config/mips/mips.md (cpu): Rework for processor_type changes.
+ * config/mips/mips.c (mips_cost): New variable.
+ (DEFAULT_COSTS): Define.
+ (mips_rtx_cost_data): New.
+ (mips_rtx_costs): Use. Minor formatting changes. Use COSTS_N_INSNS
+ for NEG cost. Add support for FLOAT, UNSIGNED_FLOAT, FIX,
+ FLOAT_EXTEND, FLOAT_TRUNCATE, and SQRT.
+ (override_options): Set cost data.
+ (mips_register_move_cost): Formatting changes.
+ (bdesc_arrays): Use PROCESSOR_MAX.
+ (mips_init_builtins): Ditto.
+
+2005-06-02 Diego Novillo <dnovillo@redhat.com>
+
+ PR 21765
+ * doc/invoke.texi: Document -ftree-vrp.
+
+2005-06-02 Dorit Nuzman <dorit@il.ibm.com>
+
+ PR tree-optimization/21734
+ * tree-vectorizer.c (slpeel_update_phis_for_duplicate_loop): Use the
+ phi_result when current_def is not available.
+ (slpeel_update_phi_nodes_for_guard1): Don't fail if current_def is not
+ available.
+
+2005-06-02 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.c (rs6000_insn_valid_within_doloop): New.
+ (TARGET_INSN_VALID_WITHIN_DOLOOP): Define.
+
+2005-06-02 Diego Novillo <dnovillo@redhat.com>
+
+ * tree-vrp.c (has_assert_expr, maybe_add_assert_expr): Remove.
+
+2005-06-02 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (dump_cgraph_node): Print new flags.
+ (dump_cgraph_varpool_node): Likewise.
+ (decide_variable_is_needed): Initialize externally_visible flag.
+ * cgraph.h (cgraph_local_info): Add externally_visible flag.
+ (cgraph_varpool_node): Likewise.
+ (cgraph_function_flags_ready): Declare.
+ * cgraph.c (cgraph_mark_local_functions): Rename to ...
+ (cgraph_function_and_variable_visibility) ... this one; handle
+ externally_visible flags.
+ (decide_is_function_needed): Set externally_visible flag.
+ (cgraph_finalize_function): Deal properly with early cleanups.
+ (cgraph_optimize): Update call of
+ cgraph_function_and_variable_visibility.
+
+2005-06-02 Steven Bosscher <stevenb@suse.de>
+ Mostafa Hagog <mustafa@il.ibm.com>
+
+ * cfgloop.h (doloop_condition_get): Make external.
+ * loop-doloop.c (doloop_condition_get): Generalize to make it
+ usable in modulo-sched.c.
+ * modulo-sched.c (doloop_register_get): Use
+ doloop_condition_get instead of duplicating it.
+
+2005-06-02 Bernd Schmidt <bernd.schmidt@analog.com>
+
+ * reload1.c (reload): Undo 2005-04-20 change. Make sure we detect
+ the correct set of init_insns that need deletion.
+ * local-alloc.c (update_equiv_regs): When substituting sole definition
+ into sole use of a reg, delete it from liveness information.
+
+2005-06-02 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * config/sh/sh.h (TARGET_FPU_DOUBLE): Use MASK_SH4.
+
+2005-06-01 Diego Novillo <dnovillo@redhat.com>
+
+ PR 14341, PR 21332, PR 20701, PR 21029, PR 21086, PR 21090
+ PR 21289, PR 21348, PR 21367, PR 21368, PR 21458.
+ * fold-const.c (invert_tree_comparison): Make extern.
+ * tree-flow.h (enum value_range_type): Move to tree-ssa-propagate.
+ (struct value_range_def): Limewise.
+ (get_value_range): Remove.
+ (dump_value_range): Remove.
+ (dump_all_value_ranges): Remove.
+ (debug_all_value_ranges): Remove.
+ (vrp_evaluate_conditional): Declare.
+ * tree-ssa-propagate.c (struct prop_stats_d): Add field
+ num_pred_folded.
+ (substitute_and_fold): Add argument use_ranges_p.
+ Update all callers.
+ If use_ranges_p is true, call fold_predicate_in to fold
+ predicates using range information.
+ Ignore ASSERT_EXPRs.
+ Change debugging output to only show statements that have been
+ folded.
+ (replace_phi_args_in): Move debugging output code from
+ substitute and fold.
+ (fold_predicate_in): New local function.
+ * tree-ssa-propagate.h (enum value_range_type): Move from
+ tree-flow.h.
+ (struct value_range_d): Likewise.
+ Add field 'equiv'.
+ (value_range_t): Rename from value_range.
+ * tree-vrp.c (found_in_subgraph): Rename from found.
+ (get_opposite_operand): Remove.
+ (struct assert_locus_d): Declare.
+ (assert_locus_t): Declare.
+ (need_assert_for): Declare.
+ (asserts_for): Declare.
+ (blocks_visited): Declare.
+ (vr_value): Declare.
+ (set_value_range): Add argument 'equiv'.
+ Don't drop to VARYING ranges that cover all values in the
+ type.
+ Make deep copy of equivalence set 'equiv'.
+ (copy_value_range): New local function.
+ (set_value_range_to_undefined): New local function.
+ (compare_values): Return -2 if either value has overflowed.
+ (range_includes_zero_p): New local function.
+ (extract_range_from_assert): Flip the predicate code if the
+ name being asserted is on the RHS of the predicate.
+ Avoid creating unnecessary symbolic ranges if the comparison
+ includes another name with a known numeric range.
+ Update the equivalnce set of the new range when asserting
+ EQ_EXPR predicates.
+ (extract_range_from_ssa_name): Update the equivalence set of
+ the new range with VAR.
+ (extract_range_from_binary_expr): Also handle TRUTH_*_EXPR.
+ If -fwrapv is used, set the resulting range to VARYING if the
+ operation overflows. Otherwise, use TYPE_MIN_VALUE and
+ TYPE_MAX_VALUE to represent -INF and +INF.
+ Fix handling of *_DIV_EXPR.
+ (extract_range_from_unary_expr): Handle MINUS_EXPR and
+ ABS_EXPR properly by switching the range around if necessary.
+ (extract_range_from_comparison): New local function.
+ (extract_range_from_expr): Call it.
+ (adjust_range_with_scev): Do not adjust the range if using
+ wrapping arithmetic (-fwrapv).
+ (dump_value_range): Also show equivalence set.
+ Show -INF and +INF for TYPE_MIN_VALUE and TYPE_MAX_VALUE.
+ (build_assert_expr_for): Also build ASSERT_EXPR for EQ_EXPR.
+ (infer_value_range): Change return value to bool.
+ Add arguments 'comp_code_p' and 'val_p'.
+ Do not attempt to infer ranges from statements that may throw.
+ Store the comparison code in comp_code_p.
+ Store the other operand to be used in the predicate in val_p.
+ (dump_asserts_for): New.
+ (debug_asserts_for): New.
+ (dump_all_asserts): New.
+ (debug_all_asserts): New.
+ (register_new_assert_for): New.
+ (register_edge_assert_for): New.
+ (find_conditional_asserts): New.
+ (find_assert_locations): New.
+ (process_assert_insertions_for): New.
+ (process_assert_insertions): New.
+ (insert_range_assertions): Initialize found_in_subgraph,
+ blocks_visited, need_assert_for and asserts_for.
+ Call find_assert_locations and process_assert_insertions.
+ (remove_range_assertions): Add more documentation.
+ (vrp_initialize): Change return type to void.
+ Do not try to guess if running VRP is worth it.
+ (compare_name_with_value): New.
+ (compare_names): New.
+ (vrp_evaluate_conditional): Add argument 'use_equiv_p'. If
+ use_equiv_p is true, call compare_names and
+ compare_name_with_value to compare all the ranges for every
+ name in the equivalence set of the predicate operands.
+ Update all callers.
+ (vrp_meet): Try harder not to derive a VARYING range.
+ If two values meet, the resulting equivalence set is the
+ intersection of the two equivalence sets.
+ (vrp_visit_phi_node): Call copy_value_range to get the current
+ range information of the LHS.
+ (vrp_finalize): Create a value vector representing all the
+ names that ended up with exactly one value in their range.
+ Call substitute_and_fold.
+ (execute_vrp): Document equivalence sets in ranges.
+ * tree.h (SSA_NAME_VALUE_RANGE): Remove.
+ (struct tree_ssa_name): Remove field value_range.
+ (invert_tree_comparison): Declare.
+
+2005-06-01 Daniel Berlin <dberlin@dberlin.org>
+
+ Fix PR tree-optimization/21839
+
+ * gimplify.c (zero_sized_field_decl): New function.
+ (gimplify_init_ctor_eval): Use it.
+
+2005-06-01 Josh Conner <jconner@apple.com>
+
+ PR 21478
+ * gimplify.c (gimplify_init_constructor): Don't spill initializer
+ to read-only memory if it's sparse.
+
+2005-06-01 Ramana Radhakrishnan <ramana@codito.com>
+
+ * doc/rtl.texi: Remove references to NOTE_INSN_SETJMP.
+ Add documentation for REG_SETJMP
+
+2005-06-01 Richard Guenther <rguenth@gcc.gnu.org>
+
+ * stmt.c (expand_case): Use build_int_cst.
+ (node_has_low_bound): Likewise, and correct type mismatch.
+ (node_has_high_bound): Likewise.
+ * fold-const.c (fold_binary): Ensure we build trees
+ with the correct types - undo what STRIP_NOPS possibly did.
+
+2005-06-01 Richard Guenther <rguenth@gcc.gnu.org>
+
+ * tree.h (fold_indirect_ref_1): Export from fold-const.c.
+ * fold-const.c (fold_indirect_ref_1): No longer static.
+ * tree-inline.c (copy_body_r): Use fold_indirect_ref_1 for
+ folding, if possible.
+
+2005-06-01 Joseph S. Myers <joseph@codesourcery.com>
+
+ * common.opt (fjump-tables): New.
+ * doc/invoke.texi (-fno-jump-tables): Document.
+ * stmt.c (expand_end_case_type): Do not emit jump tables unless
+ flag_jump_tables.
+
+2005-06-01 Richard Earnshaw <richard.earnshaw@arm.com>
+
+ * arm.md (bunordered, bordered, bungt, bunlt, bunge, bunle, buneq)
+ (bltgt, arm_buneq, arm_bltgt, sunordered, sordered, sungt, sunge)
+ (sunlt, sunle): Enable patterns on VFP.
+
+ * arm.md (attribute 'type'): Add new types - f_loads floadd, f_stores,
+ f_stored, f_flag, f_cvt.
+ (generic_sched): No-longer used for the arm1020e and arm1022e cores.
+ Include arm1020e.md.
+ * vfp.md (fmstat): New cpu unit. Add an exclusion set between it and
+ the ds and fmac pipelines. Re-work all load and store patterns and
+ all conversion patterns to use new attributes. Adjust reservation
+ descriptions accordingly.
+ * arm1020e.md: New file.
+ * t-arm: Add dependency.
+
+2005-06-01 Jan Hubicka <jh@suse.cz>
+
+ * except.c (struct eh_region): Kill unused fields.
+ * basic-block.h (struct basic_block_def): Likewise.
+
+2005-06-01 J"orn Rennecke <joern.rennecke@st.com>
+
+ PR rtl-optimization/21767
+ * rtl.h (function_invariant_p): Re-add declaration.
+ * reload1.c (function_invariant_p): No longer static.
+ * ifcvt.c (dead_or_predicable): Remove REG_EQUAL notes that
+ might have become invalid.
+
+2005-06-01 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/21536
+ PR c/20760
+ * gimplify.c (gimplify_decl_expr): Call gimplify_type_sizes
+ on variable sizes types if a decl is a pointer to a VLA.
+ (gimplify_type_sizes): Handle POINTER_TYPE and REFERENCE_TYPE.
+ Call gimplify_type_sizes on aggregate fields. Prevent infinite
+ recursion.
+
+ * fold-const.c (fold_ternary): Optimize BIT_FIELD_REF of VECTOR_CST.
+
+ * config/i386/xmmintrin.h (_mm_setzero_ps, _mm_set_ss, _mm_set1_ps,
+ _mm_set_ps, _mm_setr_ps): Add __extension__.
+ * config/i386/emmintrin.h (_mm_set_sd, _mm_set1_pd, _mm_set_pd,
+ _mm_setr_pd, _mm_setzero_pd, _mm_set_epi64x, _mm_set_epi64x,
+ _mm_set_epi32, _mm_set_epi16, _mm_set_epi8, _mm_setzero_si128):
+ Likewise.
+ (_mm_clflush): Don't use return in void function.
+
+ * config/i386/emmintrin.h (_mm_castpd_ps, _mm_castpd_si128,
+ _mm_castps_pd, _mm_castps_si128, _mm_castsi128_ps, _mm_castsi128_pd):
+ Use __inline instead of inline.
+
+2005-06-01 Richard Guenther <rguenth@gcc.gnu.org>
+
+ * fold-const.c (fold_binary): Fix types in strlen vs.
+ zero comparison folding.
+
+2005-06-01 Richard Henderson <rth@redhat.com>
+
+ * configure.ac (HAVE_AS_JSRDIRECT_RELOCS): New.
+ * config.in, configure: Rebuild.
+ * config/alpha/alpha.c (print_operand): Add 'j'.
+ * alpha.md (divmodsi_internal_er_1): Use it.
+ (divmoddi_internal_er_1): Likewise.
+
+2005-06-01 Richard Sandiford <rsandifo@redhat.com>
+
+ * system.h (TARGET_OPTIONS, TARGET_SWITCHES): Poison.
+ * opts.h (print_filtered_help): Delete.
+ * opts.c (handle_option, decode_options): Remove calls to
+ set_target_switch.
+ (print_target_help): New function.
+ (common_option, print_help): Call print_target_help instead of
+ display_target_options.
+ (print_filtered_help): Make static.
+ * toplev.h (display_target_options, set_target_switch): Delete.
+ * toplev.c (target_switches, target_options, display_target_options)
+ (set_target_switch): Delete.
+ (print_switch_values): Remove handling of TARGET_SWITCHES and
+ TARGET_OPTIONS.
+ (default_get_pch_validity): Likewise. Only treat target_flags
+ specially if targetm.check_pch_target_flags is nonnull.
+ (pch_option_mismatch): New function.
+ (default_pch_valid_p): Use it. Remove handling of TARGET_SWITCHES
+ and TARGET_OPTIONS. Only treat target_flags specially if
+ targetm.check_pch_target_flags is nonnull.
+ * config/ia64/ia64.c (ia64_override_options): Don't mention
+ TARGET_OPTIONS in comment.
+ * config/m68k/m68k-none.h (CC1_SPEC): Likewise.
+ * doc/invoke.texi: Remove a reference to TARGET_SWITCHES.
+ * doc/tm.texi (TARGET_DEFAULT_TARGET_FLAGS): Don't mention the
+ interaction with TARGET_SWITCHES.
+ (TARGET_@var{featurename}, TARGET_SWITCHES, TARGET_OPTIONS): Delete.
+
+2005-06-01 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/sh/sh.c (multcosts): Check sh_multcost rather than
+ sh_multcost_str.
+ (sh_register_move_cost): Likewise sh_gettrcost and sh_gettrcost_str.
+ (sh_multcost_str, sh_gettrcost_str, sh_div_str, sh_divsi3_libfunc)
+ (cut2_workaround_str): Delete.
+ * config/sh/sh.h (SUBTARGET_OPTIONS, TARGET_OPTIONS)
+ (TARGET_SH5_CUT2_WORKAROUND, sh_multcost_str, sh_gettrcost_str)
+ (sh_div_str, sh_divsi3_libfunc, cut2_workaround_str): Delete.
+ * config/sh/sh.opt (mcut2-workaround, mdiv=, mdivsi3_libfunc=)
+ (mgettrcost=, multcost=): New options.
+
+2005-06-01 Richard Sandiford <rsandifo@redhat.com>
+
+ * opts.h (cl_option_state): New structure.
+ (get_option_state): Declare.
+ * opts.c (get_option_state): New function.
+ * toplev.c (option_affects_pch_p): New function.
+ (default_get_pch_validity): Store the state of all options for which
+ option_affects_pch_p returns true.
+ (default_pch_valid_p): Check the state of those options here.
+ Only check target_flags separately if targetm.check_pch_target_Flags
+ is nonnull or if TARGET_SWITCHES is defined.
+
+2005-06-01 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/mips/mips-protos.h (mips_use_ins_ext_p): Remove parameter
+ names.
+
+2005-06-01 Mostafa Hagog <mustafa@il.ibm.com>
+
+ * modulo-sched.c (undo_generate_reg_moves ): Fix PR 21138.
+
+2005-06-01 Mostafa Hagog <mustafa@il.ibm.com>
+
+ * gcse.c (compute_transp, load_killed_in_block): Use
+ MEM_READONLY_P.
+
+2005-06-01 David.Billinghurst <David.Billinghurst@riotinto.com>
+
+ PR target/21854
+ * config/mips/mips-protos.h: Declare mips_use_ins_ext_p
+
+2005-05-31 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * errors.h (warning, error, fatal, internal_error): Add printf
+ attribute.
+ * genmodes.c (make_vector_mode): Fix format arguments.
+
+2005-05-31 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * basic-block.h, bb-reorder.c, c-gimplify.c, config/darwin.c,
+ config/rs6000/rs6000-c.c, dominance.c, gimple-low.c, gimplify.c,
+ lambda-code.c, lambda-trans.c, tree-browser.c, tree-cfg.c,
+ tree-chrec.c, tree-data-ref.c, tree-dfa.c, tree-eh.c,
+ tree-if-conv.c, tree-into-ssa.c, tree-loop-linear.c,
+ tree-mudflap.c, tree-nomudflap.c, tree-outof-ssa.c,
+ tree-pretty-print.c, tree-scalar-evolution.c, tree-sra.c,
+ tree-ssa-ccp.c, tree-ssa-copy.c, tree-ssa-dce.c, tree-ssa-dom.c,
+ tree-ssa-dse.c, tree-ssa-forwprop.c, tree-ssa-live.c,
+ tree-ssa-operands.c, tree-ssa-phiopt.c, tree-ssa-pre.c,
+ tree-ssa-propagate.c, tree-ssa-sink.c, tree-ssa-threadupdate.c,
+ tree-ssa-uncprop.c, tree-ssa.c, tree-vect-analyze.c,
+ tree-vect-transform.c, tree-vectorizer.c, vec.c: Don't include
+ errors.h and include toplev.h if necessary.
+
+ * rtl.c, varray.c: If we're compiling as a GENERATOR_FILE, include
+ errors.h otherwise include toplev.h.
+
+ * Makefile.in: Update dependencies.
+
+2005-06-01 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * config/i386/cygming.h (NO_PROFILE_COUNTERS): Define.
+
+2005-05-31 Geoffrey Keating <geoffk@geoffk.org>
+
+ * config/rs6000/rs6000.md (sync_boolcshort_internal): New.
+ * config/rs6000/rs6000.c (rs6000_emit_sync): Shift count must
+ be complemented for big-endian. Mask for AND must be rotated,
+ not shifted. Handle short operands with NOT on the memory
+ operation.
+
+2005-05-30 Daniel Berlin <dberlin@dberlin.org>
+
+ * c-objc-common.c (c_tree_printer): Check flag before hashtable.
+ Use DECL_DEBUG_EXPR and SET_DECL_DEBUG_EXPR.
+ * dwarf2out.c (dwarf2out_var_location): Ditto.
+ * toplev.c (default_tree_printer): Ditto.
+ * tree-outof-ssa.c (create_temp): Ditto.
+ * tree-sra.c (instantiate_element): Ditto.
+ * var-tracking.c (track_expr_p): Ditto.
+ * tree.c (struct tree_map): New structure.
+ (debug_expr_for_decl): New.
+ (tree_map_eq): New function.
+ (tree_map_hash): Ditto.
+ (tree_map_marked_p): Ditto.
+ (print_debug_expr_statistics): Ditto.
+ (decl_debug_expr_lookup): Ditto.
+ (decl_debug_expr_insert): Ditto.
+ (dump_tree_statistics): Dump debug_expr hashtable stats.
+ * tree.h (DECL_DEBUG_EXPR): Change
+ (SET_DECL_DEBUG_EXPR): Add.
+
+2005-06-01 Alan Modra <amodra@bigpond.net.au>
+
+ * configure.ac: Add --enable-secureplt.
+ (HAVE_AS_REL16): Test for R_PPC_REL16 relocs.
+ * config.in: Regenerate.
+ * configure: Regenerate.
+ * config.gcc (powerpc64-*-linux*, powerpc-*-linux*): Add
+ rs6000/secureplt.h to tm_file when enable_secureplt.
+ * doc/invoke.texi (msecure-plt, mbss-plt): Document.
+ * doc/install.texi: Document --enable-targets and --enable-secureplt.
+ Correct xrefs to "Using the GNU Compiler Collection (GCC)".
+ * config/rs6000/secureplt.h: New file.
+ * config/rs6000/sysv4.h (TARGET_SECURE_PLT): Define.
+ (SUBTARGET_OVERRIDE_OPTIONS): Error if -msecure-plt given without
+ assembler support.
+ (CC1_SECURE_PLT_DEFAULT_SPEC): Define.
+ (CC1_SPEC): Delete duplicate mno-sdata. Invoke cc1_secure_plt_default.
+ (SUBTARGET_EXTRA_SPECS): Add cc1_secure_plt_default.
+ * config/rs6000/sysv4.opt (msecure-plt, bss-plt): Add options.
+ * config/rs6000/rs6000.h (TARGET_SECURE_PLT): Define.
+ * config/rs6000/rs6000.c (rs6000_emit_load_toc_table): Handle
+ TARGET_SECURE_PLT got register load sequence.
+ (rs6000_emit_prologue): Call rs6000_emit_load_toc_table when
+ TARGET_SECURE_PLT.
+ (rs6000_elf_declare_function_name): Don't emit toc address offset
+ word when TARGET_SECURE_PLT.
+ * config/rs6000/rs6000.md (elf_high, elf_low): Move past load_toc_*.
+ (load_toc_v4_PIC_1) Enable for TARGET_SECURE_PLT.
+ (load_toc_v4_PIC_3b, load_toc_v4_PIC_3c): New insns.
+ (call, call_value): Mark pic_offset_table_rtx used for sysv pic and
+ TARGET_SECURE_PLT.
+ (call_nonlocal_sysv, call_value_nonlocal_sysv, sibcall_nonlocal_sysv,
+ sibcall_value_nonlocal_sysv): Add 32768 offset when TARGET_SECURE_PLT
+ and -fPIC.
+ * config/rs6000/tramp.asm (trampoline_initial): Use "bcl 20,31".
+ (__trampoline_setup): Likewise. Init r30 before plt call.
+
+2005-05-31 DJ Delorie <dj@redhat.com>
+
+ * expr.c (convert_move): When a partial_int requires multiple
+ conversion steps, make sure successive steps convert the
+ intermediate value, not the original value.
+
+ * expmed.c (expand_mult): Convert partial_int multiplies to
+ shift/add combinations too.
+
+ * genmodes.c (mode_data): Add wider_2x.
+ (calc_wider_mode): Calculate twice-wider mode too.
+ (emit_mode_wider): Emit twice-wider mode too.
+ * machmode.h (mode_2xwider, GET_MODE_2XWIDER_MODE): New.
+ * expr.c (expand_expr_real_1): Use it for expanding
+ multiplies.
+
+2005-05-31 Zdenek Dvorak <dvorakz@suse.cz>
+
+ PR tree-optimization/21817
+ * tree-ssa-loop-im.c (for_each_index): Handle VECTOR_CST.
+
+2005-05-31 Pat Haugen <pthaugen@us.ibm.com>
+
+ * loop.c (loop_invariant_p, valid_initial_value_p): Revert last
+ change.
+
+2005-05-31 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR middle-end/20931
+ PR middle-end/20946
+ * fold-const.c (fold_checksum_tree): Copy types also if
+ TYPE_CONTAINS_PLACEHOLDER_INTERNAL is set.
+ Don't call fold_checksum_tree for TREE_LIST's TREE_CHAIN
+ first.
+ Tail recurse TREE_LIST's TREE_CHAIN.
+
+2005-05-31 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR tree-opt/21732
+ * tree-ssa-copy.c (dump_copy_of): Create a bitmap and don't visit a
+ SSA_NAME twice and cause the loop to become finite. Remove the test
+ for val.
+
+2005-05-31 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * tree-cfg.c (verify_expr): Add checking for COND_EXPR's conditional
+ expression.
+
+2005-05-31 Richard Sandiford <rsandifo@redhat.com>
+
+ * doc/tm.texi (TARGET_GET_PCH_VALIDITY, TARGET_PCH_VALID_P): Tweak
+ the documentation to make it more future-proof.
+ (TARGET_CHECK_PCH_TARGET_FLAGS): Document this new hook.
+ * target.h (gcc_target): Add check_pch_target_flags.
+ * target-def.h (TARGET_CHECK_PCH_TARGET_FLAGS): New macro.
+ (TARGET_INITIALIZER): Include it.
+ * toplev.c (default_pch_valid_p): Use targetm.check_pch_target_flags.
+ * config/sh/sh-protos.h (sh_pch_valid_p): Delete.
+ * config/sh/sh.c (TARGET_PCH_VALID_P, sh_pch_valid_p): Delete.
+ (sh_check_pch_target_flags): New function.
+ (TARGET_CHECK_PCH_TARGET_FLAGS): Override default.
+
+2005-05-31 Richard Guenther <rguenth@gcc.gnu.org>
+
+ * fold-const.c (extract_array_ref): Handle more cases,
+ do some useful canonicalization of the base.
+ (fold_binary): Explicitly deal with arrays of zero-sized
+ structures during folding of &a[i] == &a[j].
+
+2005-05-31 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * doc/install.texi (sparc-sun-solaris2*): Update note
+ about Sun bug 4910101.
+ (sparc-sun-solaris2.7): Document bootstrap
+ failure with Sun WorkShop 6 99/08/18 as.
+
+2005-05-30 Pat Haugen <pthaugen@us.ibm.com>
+
+ * loop.c (loop_invariant_p, valid_initial_value_p): Use
+ regs_invalidated_by_call instead of call_used_regs.
+
+2005-05-30 Paolo Carlini <pcarlini@suse.de>
+
+ PR middle-end/21743
+ * builtins.def (BUILT_IN_CLOG, BUILT_IN_CLOGF, BUILT_IN_CLOGL):
+ Enable.
+ * doc/extend.texi: Add clog, clogf, clogl.
+
+2005-05-30 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR middle-end/20303
+ * c-pragma.c: Include "vec.h".
+ (handle_pragma_visibility): Use VEC.
+
+ * doc/invoke.texi: Remove the nested visibility push limit.
+
+2005-05-30 Roger Sayle <roger@eyesopen.com>
+
+ PR rtl-optimization/15422
+ * reg-stack.c (starting_stack_p): New static global.
+ (straighten_stack): Delete prototype. Change to update the stack
+ before the current insn.
+ (subst_stack_regs): Update call to straighten stack.
+ (emit_swap_insn): Delete prototype. For the first insn in a
+ basic block, update stack_in instead of emitting a real swap.
+ (change_stack): When changing the stack before the first insn
+ in a basic block, update stack_in instead of emitting real code.
+ (compensate_edges): Clear starting_stack_p during compensation.
+ (convert_regs_1): Keep track of starting_stack_p whilst processing
+ a basic block.
+
+2005-05-30 Kazu Hirata <kazu@cs.umass.edu>
+
+ * tree-ssa-ccp.c (const_val): Make it static.
+
+2005-05-29 Geoffrey Keating <geoffk@apple.com>
+
+ PR target/21761
+ * config/rs6000/rs6000.md: Remove stray TARGET_32BIT from
+ pattern involving `:P'.
+
+ * Makefile.in (install-cpp): Depend on installdirs.
+
+2005-05-30 Kazu Hirata <kazu@cs.umass.edu>
+
+ * tree-outof-ssa.c (_elim_graph): Change the type of edge_list
+ to VEC(int,heap)*.
+ (new_elim_graph, clear_elim_graph, delete_elim_graph,
+ elim_graph_add_edge, elim_graph_remove_succ_edge,
+ FOR_EACH_ELIM_GRAPH_SUCC, FOR_EACH_ELIM_GRAPH_PRED): Use VEC
+ instead of VARRAY.
+
+2005-05-29 Kazu Hirata <kazu@cs.umass.edu>
+
+ * cgraphunit.c, ipa-inline.c, loop-iv.c, modulo-sched.c,
+ opts.c, postreload-gcse.c, tree-browser.def, tree-eh.c,
+ tree-ssa-copyrename.c, tree-vect-analyze.c: Fix typos and
+ follow spelling conventions in error/dump messages.
+
+2005-05-29 Roger Sayle <roger@eyesopen.com>
+ Richard Henderson <rth@redhat.com>
+
+ * ifcvt.c (noce_emit_move_insn): Construct a SET pattern directly
+ if the RHS isn't suitable for calling emit_move_insn.
+
+2005-05-29 Kazu Hirata <kazu@cs.umass.edu>
+
+ * tree-ssa-ccp.c (ccp_fold): Return immediately after calling
+ fold_unary and fold_binary.
+
+2005-05-29 Roger Sayle <roger@eyesopen.com>
+
+ * reg-stack.c (propagate_stack): Always copy the source stack to
+ the destination. This routine is now only called when this is safe.
+ (better_edge): New function split out from convert_regs_1 to
+ determine which of two edges is better to propagate across.
+ (convert_regs_1): We need only search for a best edge if the
+ stack layout hasn't been defined yet. Use better_edge to help
+ find beste. No longer traverse unnecessary edges.
+
+2005-05-29 Keith Besaw <kbesaw@us.ibm.com>
+
+ * tree-ssa-alias.c (new_type_alias): New procedure to
+ create a type memory tag for a pointer with a may-alias
+ set determined from a variable declaration.
+ * tree-flow.h: export declaration of new_type_alias
+ * tree-optimize.c (init_tree_optimization_passes): document
+ that pass_may_alias cannot be called after pass_vectorize.
+ * tree-vect-transform (vect_create_data_ref_ptr): Call
+ new_type_alias when an type memory tag isn't available
+ for a reference.
+ (vectorizable_store): Use copy_virtual_operands to update
+ virtual defs in place (so that loop_version can be called).
+ Call mark_for_renaming for the virtual defs in case peeling
+ is done and virtual uses outside the loop need to be updated.
+
+2005-05-29 Dorit Naishlos <dorit@il.ibm.com>
+
+ PR tree-optimization/21639
+ * tree-complex.c (pass_lower_vector_s): Remove TODO_ggc_collect.
+
+2005-05-29 Jan Hubicka <jh@suse.cz>
+
+ PR tree-optimization/21562
+ * cfgexpand.c (construct_init_block): Deal properly with the case
+ of entry edge not pointing to very first basic block.
+
+2005-05-28 Kazu Hirata <kazu@cs.umass.edu>
+
+ * tree-ssa-ccp.c (ccp_fold): Remove code that produces
+ non-gimple min invariant.
+
+ * Makefile.in (OBJS-common): Add tree-cfgcleanup.o.
+ * tree-flow.h: Add prototypes for start_recording_case_labels
+ and end_recording_case_labels.
+ * tree-cfg.c (start_recording_case_labels,
+ end_recording_case_labels): Export.
+ (cleanup_tree_cfg_loop, modified_noreturn_calls,
+ cleanup_control_flow, cleanup_control_expr_graph,
+ remove_fallthru_edge, phi_alternatives_equal,
+ tree_forwarder_block_p, has_abnormal_incoming_edge_p,
+ remove_forwarder_block, cleanup_forwarder_blocks,
+ remove_forwarder_block_with_phi, merge_phi_nodes,
+ gate_merge_phi, pass_merge_phi): Move to ...
+ * tree-cfgcleanup.c: ... here.
+
+ * basic-block.h: Remove forward declaration of bb_ann_d.
+
+2005-05-28 Jan Hubicka <jh@suse.cz>
+
+ * tree-ssa-threadupdate.c: (create_edge_and_update_destination_phis):
+ Update profile.
+ * value-prof.c (tree_divmod_fixed_value_transform): Be more verbose in
+ debug output.
+ (tree_mod_subtract): Fix profile updating code.
+ (tree_divmod_values_to_profile): Do not produce useless value profilers
+ for divisions.
+
+2005-05-28 Kazu Hirata <kazu@cs.umass.edu>
+
+ * tree-ssa-dom.c (vrp_element_p): Define.
+ (vrp_hash_elt): Change the type of records to
+ VEC(vrp_element_p,heap).
+ (vrp_free): New.
+ (tree_ssa_dominator_optimize): Pass vrp_free to htab_create.
+ Update uses of VRP records.
+ (simplify_cond_and_lookup_avail_expr, record_range): Update
+ uses of VRP records.
+
+ * tree-inline.c (cfun_stack): Change the type to
+ VEC(function_p,heap).
+ (push_cfun, pop_cfun): Use VEC instead of VARRAY.
+
+2005-05-27 Ian Lance Taylor <ian@airs.com>
+
+ * c-decl.c (add_stmt): Add C frontend specific version.
+ (stmts_are_full_exprs_p): Remove.
+ * c-common.h (STMT_IS_FULL_EXPR_P): Remove.
+ (stmts_are_full_exprs_p): Don't declare.
+ * c-semantics.c (add_stmt): Remove.
+
+2005-05-27 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * config/mips/mips-protos.h (mips_declare_object): Add printf
+ attribute.
+ * config/mips/mips.c (mips_declare_object_name): Fix format
+ argument.
+
+2005-05-27 Roger Sayle <roger@eyesopen.com>
+
+ * reg-stack.c (compensate_edge): Remove original prototype.
+ (propagate_stack): New function to copy the stack layout
+ at the start of a basic block from the layout at the end of
+ one of its predecessors.
+ (compensate_edge): Assume that both source and destination
+ blocks have already had their stack layouts defined.
+ (compensate_edges): Traverse all non-entry edges in the CFG
+ and call compensate_edge on each in turn.
+ (convert_regs_1): Change return type to void. Call
+ propagate_stack instead of compensate_edge.
+ (convert_regs_2): Change return type to void. Update call
+ to convert_regs_1 to ignore the (now void) return value.
+ (convert_regs): Update calls to convert_regs_2 to ignore
+ the (now void) return value. After all the basic blocks have
+ been processed, call compensate_edges to actually emit new
+ insns.
+ (reg_to_stack): Initialize the aux info for each basic block
+ with FOR_EACH_BB instead of which FOR_EACH_BB_REVERSE.
+
+2005-05-28 Jan Hubicka <jh@suse.cz>
+
+ * except.c (can_throw_internal_1, can_throw_external_1): Add
+ "is_resx" argument.
+ (can_throw_external, can_throw_internal): Bring into sync wrt
+ dealing resx.
+ * except.h (can_throw_internal_1, can_throw_external_1): Update
+ prototype.
+ * tree-eh.c (tree_can_throw_internal, tree_can_throw_external):
+ Deal properly with resx.
+
+2005-05-27 Kazu Hirata <kazu@cs.umass.edu>
+
+ * basic-block.h (basic_block_def): Add phi_nodes and
+ predictions. Remove tree_annotations.
+ * predict.c (tree_predicted_by_p, tree_predict_edge,
+ combine_predictions_for_bb): Adjust references to predictions.
+ * tree-cfg.c (init_empty_tree_cfg, create_bb): Don't call
+ create_block_annotation.
+ (create_block_annotation, free_blocks_annotatios,
+ clear_blocks_annotations): Remove.
+ (dump_cfg_stats): Don't print out the memory spent on
+ bb_ann_d.
+ (delete_tree_cfg_annotations): Don't call free_blocks_annotations.
+ * tree-flow-inline.h (bb_ann): Remove.
+ (phi_nodes, set_phi_nodes): Update references to phi_nodes.
+ * tree-flow.h (bb_ann_d): Remove.
+ * tree-if-conv.c (process_phi_nodes): Update a reference to
+ phi_nodes.
+ * tree-phinodes.c (reserve_phi_args_for_new_edge,
+ create_phi_node, remove_phi_node): Likewise.
+ * tree-pretty-print.c (dump_generic_bb_buff): Don't call bb_ann.
+ * tree-ssa-dom.c (threaded_blocks): New.
+ (tree_ssa_dominator_optimize): Initialize, clear, and free
+ threaded_blocks. Update a call to thread_through_all_blocks.
+ (thread_across_edge): Use threaded_blocks instead of setting
+ incoming_edge_threaded.
+ * tree-ssa-threadupdate.c (threaded_through_all_blocks): Take
+ a bitmap of blocks that are threaded through.
+ * tree.h: Move the prototype of threaded_through_blocks to
+ tree-flow.h.
+
+ * domwalk.c (walk_dominator_tree, init_walk_dominator_tree,
+ fini_walk_dominator_tree): Use VEC instead of VARRAY.
+ * domwalk.h (dom_walk_data): Change the type of
+ block_data_stack and free_block_data to VEC(void_p,heap)*.
+ * tree-ssa-dse.c (dse_initialize_block_local_data,
+ dse_optimize_stmt, dse_record_phis, dse_finalize_block): Use
+ VEC instead of VARRAY.
+
+2005-05-27 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c: Include tree-gimple.h
+ (cgraph_edge): Rename expr to stmt.
+ (cgraph_create_edge): Likewise.
+ (cgraph_clone_node): Likewise.
+ * cgraph.h (cgraph_node): Use call_stmt instead of call_expr.
+ * cgraphunit.c (record_call_1): Rename to ...
+ (record_reference): ... this one; do not build edges.
+ (cgraph_varpool_analyze_pending_decls): Call record_reference directly.
+ (current_basic_block): Kill.
+ (cgraph_create_edges): Rewrite to work on gimple statements nicely.
+ (verify_cgraph_node): Likewise.
+ * tree-inline.c (copy_body_r): Do not mess up with cgraph edges.
+ (copy_bb): Mess up with cgraph edges here; simplify EH handling.
+ (copy_edges_for_bb): Simplify EH handling.
+ (expand_call_inline): Pass statement to cgraph_edge and
+ cgraph_create_edge.
+
+2005-05-27 Richard Guenther <rguenth@gcc.gnu.org>
+
+ * tree-inline.c (copy_body_r): Manually fold *& to deal
+ with ADDR_EXPRs with mismatched types for now.
+
+ * gimplify.c (fold_indirect_ref_rhs): New function.
+ (gimplify_modify_expr_rhs): Use it instead of pessimistic
+ fold_indirect_ref.
+
+ * fold-const.c (fold_indirect_ref_1): Add type argument;
+ make sure the resulting expression is of this type.
+ (build_fold_indirect_ref, fold_indirect_ref): Adjust callers.
+
+2005-05-27 Kazu Hirata <kazu@cs.umass.edu>
+
+ PR tree-optimization/21658
+ * tree-ssa-ccp.c (ccp_fold): Call fold_binary instead of
+ fold_binary_to_constant. Likewise, call fold_unary instead of
+ fold_unary_to_constant.
+
+2005-05-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ * vec.h: Implement integral type vector specialization.
+ (VEC_T): Define a non-GTY structure.
+ (VEC_T_GTY): Define a GTY structure.
+ (VEC_TA): Rename to ...
+ (VEC_TA_GTY): ... here.
+ (DEF_VEC_I, DEF_VEC_ALLOC_I): New.
+ (DEF_VEC_P, DEF_VEC_ALLOC_P): Adjust.
+ (DEF_VEC_FUNC_P, DEF_VEC_ALLOC_FUNC_P): New, broken out of
+ DEF_VEC_P and DEF_VEC_ALLOC_P.
+ (DEF_VEC_O, DEF_VEC_ALLOC_O): Adjust.
+ (DEF_VEC_FUNC_O, DEF_VEC_ALLOC_FUNC_O): New, broken out of
+ DEF_VEC_O and DEF_VEC_ALLOC_O.
+ * global.c: Use DEF_VEC_I, DEF_VEC_ALLOC_I.
+ * lambda-code.c: Likewise.
+ * tree-into-ssa.c: Likewise.
+ * tree-ssa-live.c: Likewise.
+
+2005-05-27 Kazu Hirata <kazu@cs.umass.edu>
+
+ * tree-into-ssa.c (update_ssa): Ensure that the operand cache
+ is up-to-date.
+ * tree-ssa-dom.c (tree_ssa_dominator_optimize): Call
+ update_stmt_if_modified before calling update_ssa.
+
+2005-05-27 Ralf Corsepius <ralf.corsepius@rtems.org>
+
+ * config/rs6000/t-rtems: Remove roe multilib variant.
+
+2005-05-26 Roger Sayle <roger@eyesopen.com>
+
+ PR tree-optimization/9814
+ * ifcvt.c (noce_emit_move_insn): If we fail to recognize the move
+ instruction, add the necessary clobbers by re-expanding the RTL
+ for arithmetic operations via optab.c's expand_unop/expand_binop.
+ (noce_try_bitop): New function to optimize bit manipulation idioms
+ of the form "if (x & C) x = x op C" and "if (!(x & C) x = x op C".
+ (noce_process_if_block): Call noce_try_bitop.
+
+2005-05-26 Roger Sayle <roger@eyesopen.com>
+
+ * reg-stack.c (convert_regs_entry, convert_regs_exit,
+ convert_regs_1, convert_regs_2, convert_regs): Delete prototypes.
+ (reg_to_stack): Move to end of the file. Initialize the per
+ basic block information here, instead of...
+ (convert_regs_entry): Here.
+ (convert_regs): Change unused return type to void.
+
+2005-05-27 Kazu Hirata <kazu@cs.umass.edu>
+
+ * c-pch.c, timevar.c, timevar.h, unwind-compat.c,
+ unwind-dw2-fde-compat.c, unwind-dw2-fde.c, config/mmix/mmix.h,
+ config/rs6000/eabispe.h, config/rs6000/lynx.h,
+ config/sh/elf.h, config/sh/symbian-pre.h,
+ config/sparc/sparc-protos.h: Update copyright.
+
+2005-05-26 Mike Stump <mrs@apple.com>
+
+ * darwin.h (ASM_OUTPUT_LABELREF): Handle quoted non-lazy pointers
+ for Objective-C++.
+
+2005-05-26 Richard Guenther <rguenth@gcc.gnu.org>
+
+ * tree-ssa-forwprop.c (forward_propagate_addr_expr):
+ See through ADDR_EXPR in finding place to propagate into.
+
+2005-05-26 Kazu Hirata <kazu@cs.umass.edu>
+
+ * c-common.c, c-parser.c, cfgbuild.c, cfghooks.c, cfghooks.h,
+ cfgrtl.c, cgraphunit.c, ddg.c, expr.h, gcse.c, ggc-page.c,
+ ggc-zone.c, gimplify.c, ipa-inline.c, longlong.h, targhooks.c,
+ tree-flow-inline.h, tree-pass.h, tree-ssa-dse.c,
+ tree-ssa-loop-im.c, tree-ssa-loop-ivopts.c,
+ tree-ssa-operands.c, tree-vect-analyze.c,
+ tree-vect-transform.c, tree-vectorizer.c, tree.c,
+ config/arm/arm.c, config/bfin/bfin.c, config/frv/frv.c,
+ config/frv/frv.md, config/i386/i386.c, config/i386/sse.md,
+ config/m68hc11/m68hc11.c, config/m68hc11/m68hc11.h,
+ config/mcore/mcore.c, config/mips/mips.c, config/mips/mips.md,
+ config/rs6000/darwin-ldouble.c, config/rs6000/rs6000.c,
+ config/rs6000/rs6000.h, config/sh/sh.c, config/sh/sh.md,
+ config/sh/ushmedia.h, config/sparc/sparc.c,
+ config/sparc/sparc.md, config/stormy16/stormy-abi: Fix comment
+ typos. Follow spelling conventions.
+ * doc/invoke.texi, doc/tm.texi, doc/tree-ssa.texi: Fix typos.
+ Follow spelling conventions.
+
+2005-05-26 David Ung <davidu@mips.com>
+
+ * config/mips/mips.c (mips_use_ins_ext_p): New helper function
+ that determines whether the MIPS32/64 R2 ext/ins should be used.
+ * config/mips/mips.h (ISA_HAS_EXT_INS): New macro.
+ * config/mips/mips.md (extzv): Changed predicate for operand to
+ nonimmediate_operand. Add code to generate insn patterns for
+ extzvsi and extzvdi.
+ (extzv<mode>): New pattern to match mips32/64 r2 ext insn.
+ (insv): Similarly for insertion.
+ (insv<mode>): Similarly.
+
+2005-05-26 Paolo Bonzini <bonzini@gnu.org>
+
+ * simplify-rtx.c (avoid_constant_pool_reference): Support
+ offsetted addresses in the constant pool.
+
+2005-05-26 Paolo Bonzini <bonzini@gnu.org>
+
+ * df.h (DF_SUBREGS, df_local_def_available_p, df_insn_modified_p): New.
+ * df.c (DF_SUBREGS, df_local_def_available_p, df_insn_modified_p): New.
+
+2005-05-26 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/21716
+ * reg-stack.c (swap_rtx_condition): Don't crash if %ax user was not
+ found in the basic block and last insn in the basic block is not
+ INSN_P. Remove explicit unspec numbers that are no longer valid
+ from comments.
+
+2005-05-26 Paolo Bonzini <bonzini@gnu.org>
+
+ * tree-vect-transform.c (vectorizable_operation): Try word_mode
+ vectorization if UNITS_PER_WORD == UNITS_PER_SIMD_WORD, even
+ if a vector mode is available.
+
+2005-05-25 Roger Sayle <roger@eyesopen.com>
+
+ PR middle-end/21709
+ * fold-const.c (const_binop): Check for division by zero during
+ complex division.
+
+2005-05-26 Ian Lance Taylor <ian@airs.com>
+
+ * reload1.c (verify_initial_elim_offsets): Add braces to avoid
+ having a declaration after a statement.
+
+2005-05-26 Richard Sandiford <rsandifo@redhat.com>
+
+ * opt-functions.awk (var_type): New function.
+ (var_set): Use CLVC_STRING if var_type returns "const char *".
+ * opth-gen.awk: Use var_type to find out the types of variables.
+ Don't print comments above each "extern" definition.
+ * optc-gen.awk: Use var_type in the same way.
+ * opts.h (cl_var_cond): Rename to...
+ (cl_var_type): ...this. Add CLVC_STRING.
+ (cl_option): Make "flag_var" a "void *" pointer. Replace "var_cond"
+ with "var_type".
+ * opts.c (handle_option, option_enabled): Update after above name
+ change. Cast flag_var before using it. Handle CLVC_STRING.
+
+ * config/alpha/alpha.h (alpha_tls_size): Delete.
+ * config/alpha/alpha.c (alpha_tls_size, alpha_cpu_string)
+ (alpha_tune_string, alpha_tp_string, alpha_fprm_string)
+ (alpha_fptm_string, alpha_mlat_string): Delete.
+ (alpha_handle_option): Don't set the above variables here. Use the
+ integer argument to check the validity of -mtls-size=.
+ * config/alpha/alpha.opt (mcpu=, mtune=, mfp-rounding-mode=)
+ (mfp-trap-mode=, mtrap-precision=, mmemory-latency=): Add Var()s.
+ (mtls-size=): Likewise. Convert to a UInteger and initialize the
+ variable to 32.
+
+ * config/arc/arc.c (arc_cpu_string, arc_text_string)
+ (arc_data_string, arc_rodata_string): Delete.
+ (arc_handle_option): Don't set the above variables here.
+ * config/arc/arc.opt (mcpu=, mtext=, mdata=, mrodata=): Add Var()s
+ and initialize them.
+
+ * config/arm/arm.c (target_fpu_name, target_fpe_name)
+ (target_float_abi_name, target_abi_name, structure_size_string)
+ (arm_pic_register_string): Delete.
+ (arm_handle_option): Don't set the above variables here, except
+ in the handling of -mhard-float and -msoft-float.
+ * config/arm/arm.opt (mabi=, mfloat-abi=, mfp=, mfpe=, mfpu=)
+ (mpic-register=, mstructure-size-boundary=): Add Var()s.
+
+ * config/avr/avr.c (avr_init_stack, avr_mcu_name, TARGET_HANDLE_OPTION)
+ (avr_handle_option): Delete.
+ * config/avr/avr.opt (mmcu=, minit-stack=): Add Var()s and initialize
+ them.
+
+ * config/bfin/bfin.c (bfin_library_id): Delete.
+ (bfin_handle_option): Don't set it.
+ * config/bfin/bfin.opt (mshared-library-id=): Add Var().
+
+ * config/c4x/c4x.h (c4x_rpts_cycles): Delete.
+ * config/c4x/c4x.c (c4x_rpts_cycles): Delete.
+ (c4x_handle_option): Don't set c4x_rpts_cycles here.
+ * config/c4x/c4x.opt (mrpts=): Add Var().
+
+ * config/cris/aout.h (CRIS_SUBTARGET_HANDLE_OPTION): Don't set
+ cris_elinux_stacksize_str here.
+ * config/cris/aout.opt (melinux-stacksize=): Add Var().
+ * config/cris/cris.h (cris_max_stackframe_str, cris_cpu_str)
+ (cris_tune_str, cris_elinux_stacksize_str): Delete.
+ * config/cris/cris.c (cris_max_stackframe_str, cris_cpu_str)
+ (cris_tune_str, cris_elinux_stacksize_str): Delete.
+ (cris_handle_option): Don't set the above variables here.
+ * config/cris/cris.opt (mcpu=, march=, mtune=, mmax-stackframe=)
+ (max-stackframe=): Add Var()s.
+
+ * config/i386/i386.h (ix86_tune_string, ix86_arch_string): Delete.
+ * config/i386/i386.c (ix86_cmodel_string, ix86_asm_string)
+ (ix86_tls_dialect_string, ix86_tune_string, ix86_arch_string)
+ (ix86_fpmath_string, ix86_regparm_string, ix86_align_loops_string)
+ (ix86_align_jumps_string, ix86_preferred_stack_boundary_string)
+ (ix86_branch_cost_string, ix86_align_funcs_string): Delete.
+ (ix86_handle_option): Don't set the above variables here.
+ * config/i386/i386.opt (malign-functions=, malign-jumps=)
+ (malign-loops=, march=, masm=, mbranch-cost=, mcmodel=, mfpmath=)
+ (mpreferred-stack-boundary=, mregparm=, mtls-dialect=, mtune=): Add
+ Var()s.
+
+ * config/ia64/ia64.h (ia64_tls_size): Delete.
+ * config/ia64/ia64.c (ia64_tls_size): Delete.
+ (ia64_handle_option): Treat -mtls-size= as a UInteger option,
+ reading the integer argument from the "value" parameter. Don't
+ set ia64_tls_size here.
+ * config/ia64/ia64.opt (mtls-size=): Turn into a UInteger option.
+ Add Var() and Init().
+
+ * config/m32r/m32r.h (m32r_cache_flush_func): Delete.
+ (m32r_cache_flush_trap): Delete.
+ * config/m32r/m32r.c (m32r_cache_flush_func): Delete.
+ (m32r_cache_flush_trap): Delete.
+ (m32r_handle_option): Don't set the above variables when handling
+ -mflush-func= and -mflush-trap=.
+ * config/m32r/m32r.opt (-mflush-func=, -mflush-trap=): Add Var()s
+ and Init()s.
+
+ * config/mips/mips.h (mips_cache_flush_func): Delete.
+ * config/mips/mips.c (mips_arch_string, mips_tune_string)
+ (mips_cache_flush_func): Delete.
+ (mips_handle_option): Don't set the above variables when handling
+ -march=, -mtune= and -mflush-func=.
+ * config/mips/mips.opt (march=, mflush-func=, mtune=): Add Var()s.
+
+ * config/s390/s390.c (s390_arch_string): Delete.
+ (s390_handle_option): Don't set it here.
+ * config/s390/s390.opt (march=): Add Var().
+
+ * config/sparc/sparc.h (sparc_cmodel_string): Delete.
+ * config/sparc/sparc.c (sparc_cmodel_string): Delete.
+ (sparc_handle_option): Don't set it here.
+ * config/sparc/sparc.opt (mcmodel=): Add Var().
+
+2005-05-25 Roger Sayle <roger@eyesopen.com>
+
+ * convert.c (convert_to_integer) <POINTER_TYPE>: Avoid recursive
+ call to convert_to_integer by building the NOP_EXPR directly.
+
+2005-05-25 Richard Sandiford <rsandifo@redhat.com>
+
+ * config/rs6000/rs6000.opt (mprioritize-restricted-insns=): Fix typo.
+
+2005-05-25 Daniel Berlin <dberlin@dberlin.org>
+ Jeff Law <law@redhat.com>
+
+ * tree-cfg.c (verify_expr, case ADDR_EXPR): Verify invariant,
+ constant and side_effects of the ADDR_EXPR are consistent.
+
+ * tree-nested.c (convert_local_reference): Set CURRENT_FUNCTION_DECL
+ appropriately around calls to recompute_tree_invarant_for_addr_expr.
+
2005-05-25 Ulrich Weigand <uweigand@de.ibm.com>
* config/s390/s390.c (GP_ARG_NUM_REG, FP_ARG_NUM_REG): New defines.
@@ -906,6 +2164,10 @@
2005-05-17 Paolo Bonzini <bonzini@gnu.org>
+ * tree-ssa-math-opts.c: New file.
+
+2005-05-17 Paolo Bonzini <bonzini@gnu.org>
+
* Makefile.in: Add tree-ssa-math-opts.c.
* expr.c (expand_expr_real_1) <case RDIV_EXPR>: Never emit as a*(1/b).
* fold-const.c (distribute_real_division): New.
diff --git a/gcc/ChangeLog.profiling b/gcc/ChangeLog.profiling
index 94187628ac5..cfef67a1f3b 100644
--- a/gcc/ChangeLog.profiling
+++ b/gcc/ChangeLog.profiling
@@ -1,3 +1,7 @@
+2005-06-03 Jan Hubicka <jh@suse.cz>
+
+ * Merge from mainline (tree-profiling-merge-20050603)
+
2005-05-31 Razya Ladelsky <razya@il.ibm.com>
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index b3781051483..21cad460a67 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20050525
+20050603
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 6ae9c5e3b7e..4a4f03bc2dd 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -926,14 +926,15 @@ C_OBJS = c-lang.o stub-objc.o $(C_AND_OBJC_OBJS)
OBJS-common = \
tree-chrec.o tree-scalar-evolution.o tree-data-ref.o \
tree-cfg.o tree-dfa.o tree-eh.o tree-ssa.o tree-optimize.o tree-gimple.o \
- gimplify.o tree-pretty-print.o tree-into-ssa.o \
+ gimplify.o tree-pretty-print.o tree-into-ssa.o \
tree-outof-ssa.o tree-ssa-ccp.o tree-vn.o tree-ssa-uncprop.o \
- tree-ssa-dce.o tree-ssa-copy.o tree-nrv.o tree-ssa-copyrename.o \
+ tree-ssa-dce.o tree-ssa-copy.o tree-nrv.o tree-ssa-copyrename.o \
tree-ssa-pre.o tree-ssa-live.o tree-ssa-operands.o tree-ssa-alias.o \
tree-ssa-phiopt.o tree-ssa-forwprop.o tree-nested.o tree-ssa-dse.o \
tree-ssa-dom.o domwalk.o tree-tailcall.o gimple-low.o tree-iterator.o \
- tree-phinodes.o tree-ssanames.o tree-sra.o tree-complex.o tree-ssa-loop.o \
- tree-ssa-loop-niter.o tree-ssa-loop-manip.o tree-ssa-threadupdate.o \
+ tree-phinodes.o tree-ssanames.o tree-sra.o tree-complex.o \
+ tree-vect-generic.o tree-ssa-loop.o tree-ssa-loop-niter.o \
+ tree-ssa-loop-manip.o tree-ssa-threadupdate.o \
tree-vectorizer.o tree-vect-analyze.o tree-vect-transform.o \
tree-ssa-loop-ivcanon.o tree-ssa-propagate.o tree-ssa-math-opts.o \
tree-ssa-loop-ivopts.o tree-if-conv.o tree-ssa-loop-unswitch.o \
@@ -962,7 +963,7 @@ OBJS-common = \
et-forest.o cfghooks.o bt-load.o pretty-print.o $(GGC) web.o passes.o \
rtl-profile.o tree-profile.o rtlhooks.o cfgexpand.o lambda-mat.o \
lambda-trans.o lambda-code.o tree-loop-linear.o tree-ssa-sink.o \
- tree-vrp.o tree-stdarg.o
+ tree-vrp.o tree-stdarg.o tree-cfgcleanup.o
OBJS-md = $(out_object_file)
OBJS-archive = $(EXTRA_OBJS) $(host_hook_obj) tree-inline.o ipa-inline.o \
@@ -1663,32 +1664,32 @@ stor-layout.o : stor-layout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
toplev.h
tree-ssa.o : tree-ssa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) output.h $(DIAGNOSTIC_H) \
- errors.h toplev.h function.h $(TIMEVAR_H) $(TM_H) coretypes.h \
+ toplev.h function.h $(TIMEVAR_H) $(TM_H) coretypes.h \
$(TREE_DUMP_H) langhooks.h tree-pass.h $(BASIC_BLOCK_H) bitmap.h \
$(FLAGS_H) $(GGC_H) hard-reg-set.h $(HASHTAB_H) pointer-set.h \
$(TREE_GIMPLE_H) tree-inline.h $(VARRAY_H)
tree-into-ssa.o : tree-into-ssa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) output.h $(DIAGNOSTIC_H) \
- errors.h function.h $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
+ function.h $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
langhooks.h domwalk.h tree-pass.h $(GGC_H) $(PARAMS_H) $(BASIC_BLOCK_H) \
bitmap.h $(CFGLOOP_H) $(FLAGS_H) hard-reg-set.h $(HASHTAB_H) \
$(TREE_GIMPLE_H) tree-inline.h $(VARRAY_H)
tree-outof-ssa.o : tree-outof-ssa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) output.h $(DIAGNOSTIC_H) \
- errors.h function.h $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
+ function.h $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
langhooks.h tree-pass.h $(TREE_SSA_LIVE_H) $(BASIC_BLOCK_H) bitmap.h \
$(FLAGS_H) $(GGC_H) hard-reg-set.h $(HASHTAB_H) $(TREE_GIMPLE_H) \
- tree-inline.h $(VARRAY_H)
+ tree-inline.h $(VARRAY_H) toplev.h
tree-ssa-dse.o : tree-ssa-dse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
- $(TM_H) errors.h $(GGC_H) $(TREE_H) $(RTL_H) $(TM_P_H) $(BASIC_BLOCK_H) \
+ $(TM_H) $(GGC_H) $(TREE_H) $(RTL_H) $(TM_P_H) $(BASIC_BLOCK_H) \
$(TREE_FLOW_H) tree-pass.h $(TREE_DUMP_H) domwalk.h $(FLAGS_H) \
$(DIAGNOSTIC_H) $(TIMEVAR_H)
tree-ssa-forwprop.o : tree-ssa-forwprop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
- $(TM_H) errors.h $(GGC_H) $(TREE_H) $(RTL_H) $(TM_P_H) $(BASIC_BLOCK_H) \
+ $(TM_H) $(GGC_H) $(TREE_H) $(RTL_H) $(TM_P_H) $(BASIC_BLOCK_H) \
$(TREE_FLOW_H) tree-pass.h $(TREE_DUMP_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) \
langhooks.h
tree-ssa-phiopt.o : tree-ssa-phiopt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
- $(TM_H) errors.h $(GGC_H) $(TREE_H) $(RTL_H) $(TM_P_H) $(BASIC_BLOCK_H) \
+ $(TM_H) $(GGC_H) $(TREE_H) $(RTL_H) $(TM_P_H) $(BASIC_BLOCK_H) \
$(TREE_FLOW_H) tree-pass.h $(TREE_DUMP_H) langhooks.h $(FLAGS_H) \
$(DIAGNOSTIC_H) $(TIMEVAR_H)
tree-nrv.o : tree-nrv.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
@@ -1697,26 +1698,26 @@ tree-nrv.o : tree-nrv.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
langhooks.h
tree-ssa-copy.o : tree-ssa-copy.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) output.h $(DIAGNOSTIC_H) \
- errors.h function.h $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
+ function.h $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
$(BASIC_BLOCK_H) tree-pass.h langhooks.h tree-ssa-propagate.h $(FLAGS_H)
tree-ssa-propagate.o : tree-ssa-propagate.c $(TREE_FLOW_H) $(CONFIG_H) \
$(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) output.h \
- $(DIAGNOSTIC_H) errors.h function.h $(TIMEVAR_H) $(TM_H) coretypes.h \
+ $(DIAGNOSTIC_H) function.h $(TIMEVAR_H) $(TM_H) coretypes.h \
$(TREE_DUMP_H) $(BASIC_BLOCK_H) tree-pass.h langhooks.h \
tree-ssa-propagate.h vec.h gt-tree-ssa-propagate.h $(FLAGS_H) $(VARRAY_H)
tree-ssa-dom.o : tree-ssa-dom.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) output.h $(DIAGNOSTIC_H) \
- errors.h function.h $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
+ function.h $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
$(BASIC_BLOCK_H) domwalk.h real.h tree-pass.h $(FLAGS_H) langhooks.h \
tree-ssa-propagate.h $(CFGLOOP_H)
tree-ssa-uncprop.o : tree-ssa-uncprop.c $(TREE_FLOW_H) $(CONFIG_H) \
$(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) output.h \
- $(DIAGNOSTIC_H) errors.h function.h $(TIMEVAR_H) $(TM_H) coretypes.h \
+ $(DIAGNOSTIC_H) function.h $(TIMEVAR_H) $(TM_H) coretypes.h \
$(TREE_DUMP_H) $(BASIC_BLOCK_H) domwalk.h real.h tree-pass.h $(FLAGS_H) \
langhooks.h tree-ssa-propagate.h
tree-ssa-threadupdate.o : tree-ssa-threadupdate.c $(TREE_FLOW_H) $(CONFIG_H) \
$(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) output.h \
- $(DIAGNOSTIC_H) errors.h function.h $(TM_H) coretypes.h $(TREE_DUMP_H) \
+ $(DIAGNOSTIC_H) function.h $(TM_H) coretypes.h $(TREE_DUMP_H) \
$(BASIC_BLOCK_H) $(FLAGS_H) tree-pass.h $(CFGLOOP_H)
tree-ssanames.o : tree-ssanames.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(TREE_H) $(VARRAY_H) $(GGC_H) gt-tree-ssanames.h $(TREE_FLOW_H)
@@ -1726,17 +1727,17 @@ tree-phinodes.o : tree-phinodes.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
domwalk.o : domwalk.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) $(BASIC_BLOCK_H) $(TREE_FLOW_H) domwalk.h $(GGC_H)
tree-ssa-live.o : tree-ssa-live.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
- $(TREE_H) $(DIAGNOSTIC_H) errors.h function.h $(TIMEVAR_H) \
+ $(TREE_H) $(DIAGNOSTIC_H) function.h $(TIMEVAR_H) \
$(TM_H) coretypes.h $(TREE_DUMP_H) $(TREE_SSA_LIVE_H) $(BASIC_BLOCK_H) \
bitmap.h $(FLAGS_H) $(HASHTAB_H) $(TREE_GIMPLE_H) tree-inline.h \
- $(VARRAY_H)
+ $(VARRAY_H) toplev.h
tree-ssa-copyrename.o : tree-ssa-copyrename.c $(TREE_FLOW_H) $(CONFIG_H) \
$(SYSTEM_H) $(TREE_H) $(DIAGNOSTIC_H) function.h $(TIMEVAR_H) tree-pass.h \
$(TM_H) coretypes.h $(TREE_DUMP_H) $(TREE_SSA_LIVE_H) $(BASIC_BLOCK_H) \
bitmap.h $(FLAGS_H) $(HASHTAB_H) langhooks.h $(TREE_GIMPLE_H) \
tree-inline.h
tree-ssa-pre.o : tree-ssa-pre.c $(TREE_FLOW_H) $(CONFIG_H) \
- $(SYSTEM_H) $(TREE_H) $(GGC_H) $(DIAGNOSTIC_H) errors.h $(TIMEVAR_H) \
+ $(SYSTEM_H) $(TREE_H) $(GGC_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) \
$(TM_H) coretypes.h $(TREE_DUMP_H) tree-pass.h $(FLAGS_H) $(CFGLOOP_H) \
alloc-pool.h $(BASIC_BLOCK_H) bitmap.h $(FIBHEAP_H) $(HASHTAB_H) \
langhooks.h real.h $(TREE_GIMPLE_H) tree-inline.h tree-iterator.h
@@ -1749,6 +1750,12 @@ tree-vrp.o : tree-vrp.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
$(CFGLOOP_H) $(SCEV_H) tree-chrec.h $(TIMEVAR_H)
tree-cfg.o : tree-cfg.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) $(FLAGS_H) output.h \
+ $(DIAGNOSTIC_H) function.h $(TIMEVAR_H) $(TM_H) coretypes.h \
+ $(TREE_DUMP_H) except.h langhooks.h $(CFGLOOP_H) tree-pass.h \
+ $(CFGLAYOUT_H) $(BASIC_BLOCK_H) hard-reg-set.h $(HASHTAB_H) toplev.h \
+ tree-ssa-propagate.h
+tree-cfgcleanup.o : tree-cfg.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
+ $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) $(FLAGS_H) output.h \
$(DIAGNOSTIC_H) errors.h function.h $(TIMEVAR_H) $(TM_H) coretypes.h \
$(TREE_DUMP_H) except.h langhooks.h $(CFGLOOP_H) tree-pass.h \
$(CFGLAYOUT_H) $(BASIC_BLOCK_H) hard-reg-set.h $(HASHTAB_H) toplev.h \
@@ -1758,7 +1765,7 @@ tree-tailcall.o : tree-tailcall.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(TREE_DUMP_H) $(DIAGNOSTIC_H) except.h tree-pass.h $(FLAGS_H) langhooks.h \
$(BASIC_BLOCK_H) hard-reg-set.h
tree-ssa-sink.o : tree-ssa-sink.c $(TREE_FLOW_H) $(CONFIG_H) \
- $(SYSTEM_H) $(TREE_H) $(GGC_H) $(DIAGNOSTIC_H) errors.h $(TIMEVAR_H) \
+ $(SYSTEM_H) $(TREE_H) $(GGC_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) \
$(TM_H) coretypes.h $(TREE_DUMP_H) tree-pass.h $(FLAGS_H) alloc-pool.h \
$(BASIC_BLOCK_H) bitmap.h $(CFGLOOP_H) $(FIBHEAP_H) $(HASHTAB_H) \
langhooks.h real.h $(TREE_GIMPLE_H) tree-inline.h tree-iterator.h
@@ -1769,13 +1776,13 @@ tree-nested.o: tree-nested.c $(CONFIG_H) $(SYSTEM_H) $(TM_H) $(TREE_H) \
tree-if-conv.o: tree-if-conv.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) $(FLAGS_H) $(TIMEVAR_H) $(BASIC_BLOCK_H) $(TREE_FLOW_H) \
$(CFGLOOP_H) $(RTL_H) $(C_COMMON_H) tree-chrec.h $(TREE_DATA_REF_H) \
- $(SCEV_H) tree-pass.h $(DIAGNOSTIC_H) errors.h $(TARGET_H) $(TREE_DUMP_H) \
+ $(SCEV_H) tree-pass.h $(DIAGNOSTIC_H) $(TARGET_H) $(TREE_DUMP_H) \
$(VARRAY_H)
tree-iterator.o : tree-iterator.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \
coretypes.h $(GGC_H) tree-iterator.h $(TREE_GIMPLE_H) gt-tree-iterator.h
tree-dfa.o : tree-dfa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) output.h $(DIAGNOSTIC_H) \
- errors.h tree-inline.h $(HASHTAB_H) pointer-set.h $(FLAGS_H) function.h \
+ tree-inline.h $(HASHTAB_H) pointer-set.h $(FLAGS_H) function.h \
$(TIMEVAR_H) convert.h $(TM_H) coretypes.h langhooks.h $(TREE_DUMP_H) \
tree-pass.h $(PARAMS_H) $(CGRAPH_H) $(BASIC_BLOCK_H) hard-reg-set.h \
$(TREE_GIMPLE_H)
@@ -1785,7 +1792,8 @@ tree-ssa-operands.o : tree-ssa-operands.c $(TREE_FLOW_H) $(CONFIG_H) \
gt-tree-ssa-operands.h coretypes.h langhooks.h tree-ssa-opfinalize.h
tree-eh.o : tree-eh.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(RTL_H) $(TREE_H) $(TM_H) $(FLAGS_H) function.h except.h langhooks.h \
- $(GGC_H) tree-pass.h
+ $(GGC_H) tree-pass.h coretypes.h $(TIMEVAR_H) $(TM_P_H) \
+ $(TREE_DUMP_H) tree-inline.h tree-iterator.h toplev.h
tree-ssa-loop.o : tree-ssa-loop.c $(TREE_FLOW_H) $(CONFIG_H) \
$(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) \
output.h $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
@@ -1837,12 +1845,12 @@ tree-optimize.o : tree-optimize.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
function.h langhooks.h $(FLAGS_H) $(CGRAPH_H) tree-inline.h \
tree-mudflap.h $(GGC_H) $(CGRAPH_H) tree-pass.h $(CFGLOOP_H) \
$(BASIC_BLOCK_H) graph.h hard-reg-set.h
-c-gimplify.o : c-gimplify.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) errors.h \
+c-gimplify.o : c-gimplify.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \
$(C_TREE_H) $(C_COMMON_H) $(DIAGNOSTIC_H) $(TREE_GIMPLE_H) $(VARRAY_H) \
$(FLAGS_H) langhooks.h toplev.h $(RTL_H) $(TREE_FLOW_H) $(LANGHOOKS_DEF_H) \
$(TM_H) coretypes.h $(C_PRETTY_PRINT_H) $(CGRAPH_H) $(BASIC_BLOCK_H) \
hard-reg-set.h $(TREE_DUMP_H) tree-inline.h
-gimplify.o : gimplify.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) errors.h \
+gimplify.o : gimplify.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \
$(DIAGNOSTIC_H) $(TREE_GIMPLE_H) tree-inline.h $(VARRAY_H) langhooks.h \
$(LANGHOOKS_DEF_H) $(TREE_FLOW_H) $(CGRAPH_H) $(TIMEVAR_H) $(TM_H) \
coretypes.h except.h $(FLAGS_H) $(RTL_H) function.h $(EXPR_H) output.h \
@@ -1852,36 +1860,36 @@ gimple-low.o : gimple-low.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) errors.h \
langhooks-def.h $(TREE_FLOW_H) $(TIMEVAR_H) $(TM_H) coretypes.h except.h \
$(FLAGS_H) $(RTL_H) function.h $(EXPR_H) tree-pass.h pointer-set.h
tree-browser.o : tree-browser.c tree-browser.def $(CONFIG_H) $(SYSTEM_H) \
- $(TREE_H) errors.h tree-inline.h $(DIAGNOSTIC_H) $(HASHTAB_H) \
+ $(TREE_H) tree-inline.h $(DIAGNOSTIC_H) $(HASHTAB_H) \
$(TM_H) coretypes.h
tree-chrec.o: tree-chrec.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
- errors.h $(GGC_H) $(TREE_H) tree-chrec.h tree-pass.h $(PARAMS_H) \
+ $(GGC_H) $(TREE_H) tree-chrec.h tree-pass.h $(PARAMS_H) \
$(DIAGNOSTIC_H) $(VARRAY_H)
tree-scalar-evolution.o: tree-scalar-evolution.c $(CONFIG_H) $(SYSTEM_H) \
- coretypes.h $(TM_H) errors.h $(GGC_H) $(TREE_H) $(RTL_H) \
+ coretypes.h $(TM_H) $(GGC_H) $(TREE_H) $(RTL_H) \
$(BASIC_BLOCK_H) $(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_DUMP_H) \
$(TIMEVAR_H) $(CFGLOOP_H) $(SCEV_H) tree-pass.h $(FLAGS_H) tree-chrec.h
tree-data-ref.o: tree-data-ref.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
- errors.h $(GGC_H) $(TREE_H) $(RTL_H) $(BASIC_BLOCK_H) $(DIAGNOSTIC_H) \
+ $(GGC_H) $(TREE_H) $(RTL_H) $(BASIC_BLOCK_H) $(DIAGNOSTIC_H) \
$(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(CFGLOOP_H) \
$(TREE_DATA_REF_H) $(SCEV_H) tree-pass.h tree-chrec.h
tree-vect-analyze.o: tree-vect-analyze.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
- $(TM_H) errors.h $(GGC_H) $(OPTABS_H) $(TREE_H) $(BASIC_BLOCK_H) \
+ $(TM_H) $(GGC_H) $(OPTABS_H) $(TREE_H) $(BASIC_BLOCK_H) \
$(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(CFGLOOP_H) \
tree-vectorizer.h $(TREE_DATA_REF_H) $(SCEV_H) $(EXPR_H) tree-chrec.h
tree-vect-transform.o: tree-vect-transform.c $(CONFIG_H) $(SYSTEM_H) \
- coretypes.h $(TM_H) errors.h $(GGC_H) $(OPTABS_H) $(TREE_H) $(RTL_H) \
+ coretypes.h $(TM_H) $(GGC_H) $(OPTABS_H) $(TREE_H) $(RTL_H) \
$(BASIC_BLOCK_H) $(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_DUMP_H) \
$(TIMEVAR_H) $(CFGLOOP_H) $(TARGET_H) tree-pass.h $(EXPR_H) \
tree-vectorizer.h $(TREE_DATA_REF_H) $(SCEV_H) langhooks.h toplev.h \
tree-chrec.h
tree-vectorizer.o: tree-vectorizer.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
- $(TM_H) errors.h $(GGC_H) $(OPTABS_H) $(TREE_H) $(RTL_H) $(BASIC_BLOCK_H) \
+ $(TM_H) $(GGC_H) $(OPTABS_H) $(TREE_H) $(RTL_H) $(BASIC_BLOCK_H) \
$(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(CFGLOOP_H) \
tree-pass.h $(EXPR_H) tree-vectorizer.h $(TREE_DATA_REF_H) $(SCEV_H) \
input.h $(TARGET_H) $(CFGLAYOUT_H) toplev.h tree-chrec.h
tree-loop-linear.o: tree-loop-linear.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
- $(TM_H) errors.h $(GGC_H) $(OPTABS_H) $(TREE_H) $(RTL_H) $(BASIC_BLOCK_H) \
+ $(TM_H) $(GGC_H) $(OPTABS_H) $(TREE_H) $(RTL_H) $(BASIC_BLOCK_H) \
$(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(CFGLOOP_H) \
tree-pass.h $(TREE_DATA_REF_H) $(SCEV_H) $(EXPR_H) $(LAMBDA_H) \
$(TARGET_H) tree-chrec.h $(VARRAY_H)
@@ -1891,17 +1899,17 @@ tree-stdarg.o: tree-stdarg.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
tree-gimple.o : tree-gimple.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(EXPR_H) \
$(RTL_H) $(TREE_GIMPLE_H) $(TM_H) coretypes.h bitmap.h $(GGC_H) \
output.h $(TREE_FLOW_H)
-tree-mudflap.o : $(CONFIG_H) errors.h $(SYSTEM_H) $(TREE_H) tree-inline.h \
+tree-mudflap.o : $(CONFIG_H) $(SYSTEM_H) $(TREE_H) tree-inline.h \
$(TREE_GIMPLE_H) $(DIAGNOSTIC_H) $(HASHTAB_H) langhooks.h tree-mudflap.h \
$(TM_H) coretypes.h $(TREE_DUMP_H) tree-pass.h $(CGRAPH_H) $(GGC_H) \
gt-tree-mudflap.h $(BASIC_BLOCK_H) $(FLAGS_H) function.h hard-reg-set.h \
- $(RTL_H) $(TM_P_H) $(TREE_FLOW_H)
-tree-nomudflap.o : $(CONFIG_H) errors.h $(SYSTEM_H) $(TREE_H) tree-inline.h \
+ $(RTL_H) $(TM_P_H) $(TREE_FLOW_H) toplev.h
+tree-nomudflap.o : $(CONFIG_H) $(SYSTEM_H) $(TREE_H) tree-inline.h \
$(C_TREE_H) $(C_COMMON_H) $(TREE_GIMPLE_H) $(DIAGNOSTIC_H) $(HASHTAB_H) \
output.h $(VARRAY_H) langhooks.h tree-mudflap.h $(TM_H) coretypes.h \
- $(GGC_H) gt-tree-mudflap.h tree-pass.h
+ $(GGC_H) gt-tree-mudflap.h tree-pass.h toplev.h
tree-pretty-print.o : tree-pretty-print.c $(CONFIG_H) $(SYSTEM_H) \
- errors.h $(TREE_H) $(DIAGNOSTIC_H) real.h $(HASHTAB_H) $(TREE_FLOW_H) \
+ $(TREE_H) $(DIAGNOSTIC_H) real.h $(HASHTAB_H) $(TREE_FLOW_H) \
$(TM_H) coretypes.h tree-iterator.h tree-chrec.h langhooks.h
fold-const.o : fold-const.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) $(FLAGS_H) real.h toplev.h $(HASHTAB_H) $(EXPR_H) $(RTL_H) \
@@ -1950,7 +1958,7 @@ rtl-error.o: rtl-error.c $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(CONFIG_H)
rtl.o : rtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) real.h \
- $(GGC_H) errors.h $(BCONFIG_H) insn-notes.def reg-notes.def
+ $(GGC_H) $(BCONFIG_H) insn-notes.def reg-notes.def toplev.h
print-rtl.o : print-rtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) $(TREE_H) hard-reg-set.h $(BASIC_BLOCK_H) real.h $(FLAGS_H) \
@@ -2103,16 +2111,16 @@ resource.o : resource.c $(CONFIG_H) $(RTL_H) hard-reg-set.h $(SYSTEM_H) \
lcm.o : lcm.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(REGS_H) \
hard-reg-set.h $(FLAGS_H) real.h insn-config.h $(INSN_ATTR_H) $(RECOG_H) \
$(BASIC_BLOCK_H) $(TM_P_H) function.h output.h
-tree-ssa-dce.o : tree-ssa-dce.c $(CONFIG_H) $(SYSTEM_H) errors.h $(TREE_H) \
+tree-ssa-dce.o : tree-ssa-dce.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \
$(RTL_H) $(TM_P_H) $(TREE_FLOW_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) \
coretypes.h $(TREE_DUMP_H) tree-pass.h $(FLAGS_H) $(BASIC_BLOCK_H) \
$(GGC_H) hard-reg-set.h $(OBSTACK_H) $(TREE_GIMPLE_H)
tree-ssa-ccp.o : tree-ssa-ccp.c $(TREE_FLOW_H) $(CONFIG_H) \
$(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) output.h \
- $(DIAGNOSTIC_H) errors.h function.h $(TIMEVAR_H) $(TM_H) coretypes.h \
+ $(DIAGNOSTIC_H) function.h $(TIMEVAR_H) $(TM_H) coretypes.h \
$(TREE_DUMP_H) $(BASIC_BLOCK_H) tree-pass.h langhooks.h \
tree-ssa-propagate.h $(FLAGS_H) $(TARGET_H)
-tree-sra.o : tree-sra.c $(CONFIG_H) $(SYSTEM_H) errors.h $(TREE_H) $(RTL_H) \
+tree-sra.o : tree-sra.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) \
$(TM_P_H) $(TREE_FLOW_H) $(DIAGNOSTIC_H) tree-inline.h \
$(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) $(TREE_GIMPLE_H) \
langhooks.h tree-pass.h $(FLAGS_H) $(EXPR_H) $(BASIC_BLOCK_H) \
@@ -2120,10 +2128,13 @@ tree-sra.o : tree-sra.c $(CONFIG_H) $(SYSTEM_H) errors.h $(TREE_H) $(RTL_H) \
tree-complex.o : tree-complex.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \
$(TM_H) $(TREE_FLOW_H) $(TREE_GIMPLE_H) tree-iterator.h tree-pass.h \
$(FLAGS_H) $(OPTABS_H) $(RTL_H) $(MACHMODE_H) $(EXPR_H) \
- langhooks.h $(FLAGS_H) $(DIAGNOSTIC_H) gt-tree-complex.h $(GGC_H)
-tree-promote-statics.o : tree-promote-statics.c $(CONFIG_H) system.h \
- $(TREE_H) $(TM_H) $(BASIC_BLOCK_H) $(TREE_FLOW_H) $(IPA_STATIC_H) \
- bitmap.h tree-pass.h $(FLAGS_H)
+ langhooks.h $(FLAGS_H) $(DIAGNOSTIC_H) $(GGC_H) \
+ coretypes.h insn-codes.h
+tree-vect-generic.o : tree-vect-generic.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \
+ $(TM_H) $(TREE_FLOW_H) $(TREE_GIMPLE_H) tree-iterator.h tree-pass.h \
+ $(FLAGS_H) $(OPTABS_H) $(RTL_H) $(MACHMODE_H) $(EXPR_H) \
+ langhooks.h $(FLAGS_H) $(DIAGNOSTIC_H) gt-tree-vect-generic.h $(GGC_H) \
+ coretypes.h insn-codes.h
df.o : df.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
insn-config.h $(RECOG_H) function.h $(REGS_H) alloc-pool.h hard-reg-set.h \
$(BASIC_BLOCK_H) $(DF_H) bitmap.h sbitmap.h $(TM_P_H)
@@ -2208,7 +2219,7 @@ loop-unroll.o: loop-unroll.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TM_H) \
output.h $(EXPR_H) coretypes.h $(TM_H) $(HASHTAB_H) $(RECOG_H) $(VARRAY_H) \
$(OBSTACK_H)
dominance.o : dominance.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
- hard-reg-set.h $(BASIC_BLOCK_H) et-forest.h errors.h $(OBSTACK_H)
+ hard-reg-set.h $(BASIC_BLOCK_H) et-forest.h $(OBSTACK_H) toplev.h
et-forest.o : et-forest.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
et-forest.h alloc-pool.h $(BASIC_BLOCK_H)
combine.o : combine.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
@@ -2230,9 +2241,9 @@ global.o : global.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(FLAGS_H) reload.h function.h $(RECOG_H) $(REGS_H) hard-reg-set.h \
insn-config.h output.h toplev.h $(TM_P_H) $(MACHMODE_H)
varray.o : varray.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(GGC_H) \
- errors.h $(HASHTAB_H) $(BCONFIG_H) $(VARRAY_H)
+ $(HASHTAB_H) $(BCONFIG_H) $(VARRAY_H) toplev.h
vec.o : vec.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) coretypes.h vec.h $(GGC_H) \
- errors.h
+ toplev.h
reload.o : reload.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(FLAGS_H) output.h $(EXPR_H) $(OPTABS_H) reload.h $(RECOG_H) \
hard-reg-set.h insn-config.h $(REGS_H) function.h real.h toplev.h \
@@ -2322,7 +2333,7 @@ lists.o: lists.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) toplev.h \
bb-reorder.o : bb-reorder.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) $(FLAGS_H) $(TIMEVAR_H) output.h $(CFGLAYOUT_H) $(FIBHEAP_H) \
$(TARGET_H) function.h $(TM_P_H) $(OBSTACK_H) $(EXPR_H) $(REGS_H) \
- errors.h $(PARAMS_H)
+ $(PARAMS_H) toplev.h
tracer.o : tracer.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(TREE_H) $(BASIC_BLOCK_H) hard-reg-set.h output.h $(CFGLAYOUT_H) \
$(FLAGS_H) $(TIMEVAR_H) $(PARAMS_H) $(COVERAGE_H) $(FIBHEAP_H)
@@ -2343,9 +2354,9 @@ ifcvt.o : ifcvt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
lambda-mat.o : lambda-mat.c $(LAMBDA_H) $(GGC_H) $(SYSTEM_H) $(CONFIG_H) \
$(TM_H) coretypes.h $(TREE_H) $(VARRAY_H)
lambda-trans.o: lambda-trans.c $(LAMBDA_H) $(GGC_H) $(SYSTEM_H) $(CONFIG_H) \
- $(TM_H) coretypes.h errors.h $(TARGET_H) $(TREE_H) $(VARRAY_H)
+ $(TM_H) coretypes.h $(TARGET_H) $(TREE_H) $(VARRAY_H)
lambda-code.o: lambda-code.c $(LAMBDA_H) $(GGC_H) $(SYSTEM_H) $(CONFIG_H) \
- errors.h $(TM_H) $(OPTABS_H) $(TREE_H) $(RTL_H) $(BASIC_BLOCK_H) \
+ $(TM_H) $(OPTABS_H) $(TREE_H) $(RTL_H) $(BASIC_BLOCK_H) \
$(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) $(CFGLOOP_H) \
$(TREE_DATA_REF_H) $(SCEV_H) $(EXPR_H) coretypes.h $(TARGET_H) \
tree-chrec.h tree-pass.h vec.h
@@ -2618,8 +2629,7 @@ GTFILES = $(srcdir)/input.h $(srcdir)/coretypes.h \
$(srcdir)/tree-phinodes.c $(srcdir)/tree-cfg.c \
$(srcdir)/tree-dfa.c $(srcdir)/tree-ssa-propagate.c \
$(srcdir)/tree-iterator.c $(srcdir)/gimplify.c \
- $(srcdir)/tree-chrec.h $(srcdir)/tree-complex.c \
- $(srcdir)/tree-inline.c $(srcdir)/except.h \
+ $(srcdir)/tree-chrec.h $(srcdir)/tree-vect-generic.c \
$(srcdir)/tree-ssa-operands.h $(srcdir)/tree-ssa-operands.c \
$(srcdir)/tree-profile.c $(srcdir)/rtl-profile.c $(srcdir)/tree-nested.c \
$(srcdir)/ipa-static-vars-anal.c \
@@ -2639,8 +2649,7 @@ gt-expr.h gt-sdbout.h gt-optabs.h gt-bitmap.h gt-dojump.h \
gt-dwarf2out.h gt-reg-stack.h gt-dwarf2asm.h \
gt-dbxout.h gt-c-common.h gt-c-decl.h gt-c-parser.h \
gt-c-pragma.h gtype-c.h gt-cfglayout.h \
-gt-tree-mudflap.h gt-tree-complex.h \
-gt-tree-profile.h \
+gt-tree-mudflap.h gt-tree-vect-generic.h gt-tree-profile.h \
gt-tree-ssanames.h gt-tree-iterator.h gt-gimplify.h \
gt-tree-phinodes.h gt-tree-nested.h \
gt-tree-ssa-operands.h gt-tree-ssa-propagate.h \
@@ -3410,7 +3419,7 @@ install: install-common $(INSTALL_HEADERS) $(INSTALL_LIBGCC) \
lang.install-normal install-driver
# Handle cpp installation.
-install-cpp: cpp$(exeext)
+install-cpp: installdirs cpp$(exeext)
-rm -f $(DESTDIR)$(bindir)/$(CPP_INSTALL_NAME)$(exeext)
-$(INSTALL_PROGRAM) -m 755 cpp$(exeext) $(DESTDIR)$(bindir)/$(CPP_INSTALL_NAME)$(exeext)
-if [ x$(cpp_install_dir) != x ]; then \
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index a08251e21b0..68779b1483a 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,23 @@
+2005-06-03 Andrew Pinski <pinskia@physics.uc.edu>
+
+ * trans.c (gnat_gimplify_expr): Call
+ recompute_tree_invarant_for_addr_expr when we change
+ the operand of the ADDR_EXPR.
+
+2005-05-31 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * misc.c: Don't include errors.h.
+
+2005-05-29 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * raise.c (db): Add ATTRIBUTE_PRINTF_2.
+
+2005-05-29 Kazu Hirata <kazu@cs.umass.edu>
+
+ * cal.c, decl.c, init.c, raise.c, trans.c, utils2.c: Fix
+ comment typos.
+ * gnat_rm.texi, gnat_ugn.texi: Fix typos.
+
2005-05-16 Nathanael Nerode <neroden@gcc.gnu.org>
PR ada/20270
diff --git a/gcc/ada/cal.c b/gcc/ada/cal.c
index 20a631634bb..283a0e6856e 100644
--- a/gcc/ada/cal.c
+++ b/gcc/ada/cal.c
@@ -32,8 +32,8 @@
/* This file contains those routines named by Import pragmas in package */
/* GNAT.Calendar. It is used to do Duration to timeval conversion. */
-/* These are simple wrappers function to abstarct the fact that the C */
-/* struct timeval fields type are not normalized (they are generaly */
+/* These are simple wrappers function to abstract the fact that the C */
+/* struct timeval fields type are not normalized (they are generally */
/* defined as int or long values). */
#if defined(VMS)
diff --git a/gcc/ada/decl.c b/gcc/ada/decl.c
index c881d55b41f..bd9f26017b5 100644
--- a/gcc/ada/decl.c
+++ b/gcc/ada/decl.c
@@ -839,7 +839,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
}
/* If this is a pointer and it does not have an initializing
- expression, initialize it to NULL, unless the obect is
+ expression, initialize it to NULL, unless the object is
imported. */
if (definition
&& (POINTER_TYPE_P (gnu_type) || TYPE_FAT_POINTER_P (gnu_type))
@@ -4223,7 +4223,7 @@ elaborate_entity (Entity_Id gnat_entity)
Node_Id gnat_lb = Type_Low_Bound (gnat_entity);
Node_Id gnat_hb = Type_High_Bound (gnat_entity);
- /* ??? Tests for avoiding static constaint error expression
+ /* ??? Tests for avoiding static constraint error expression
is needed until the front stops generating bogus conversions
on bounds of real types. */
@@ -6322,7 +6322,7 @@ static int
compatible_signatures_p (tree ftype1, tree ftype2)
{
/* As of now, we only perform very trivial tests and consider it's the
- programmer's responsability to ensure the type correctness in the Ada
+ programmer's responsibility to ensure the type correctness in the Ada
declaration, as in the regular Import cases.
Mismatches typically result in either error messages from the builtin
diff --git a/gcc/ada/gnat_rm.texi b/gcc/ada/gnat_rm.texi
index 6471f36a7a1..a985edc42d8 100644
--- a/gcc/ada/gnat_rm.texi
+++ b/gcc/ada/gnat_rm.texi
@@ -4818,7 +4818,7 @@ subprogram yields a value that can be called as long as the subprogram
is in scope (normal Ada 95 accessibility rules restrict this usage).
It is possible to use @code{Unrestricted_Access} for any type, but care
-must be excercised if it is used to create pointers to unconstrained
+must be exercised if it is used to create pointers to unconstrained
objects. In this case, the resulting pointer has the same scope as the
context of the attribute, and may not be returned to some enclosing
scope. For instance, a function cannot use @code{Unrestricted_Access}
@@ -12522,7 +12522,7 @@ collisions occur and each item can be retrieved from the table in one
probe (perfect property). The hash table size corresponds to the exact
size of the key set and no larger (minimal property). The key set has to
be know in advance (static property). The hash functions are also order
-preservering. If w2 is inserted after w1 in the generator, their
+preserving. If w2 is inserted after w1 in the generator, their
hashcode are in the same order. These hashing functions are very
convenient for use with realtime applications.
diff --git a/gcc/ada/gnat_ugn.texi b/gcc/ada/gnat_ugn.texi
index 7f4e0671f87..e27ed3de73c 100644
--- a/gcc/ada/gnat_ugn.texi
+++ b/gcc/ada/gnat_ugn.texi
@@ -12582,7 +12582,7 @@ Additionally, you may define the library-related attributes
@code{Library_Auto_Init}, @code{Library_Options} and @code{Library_GCC}.
The @code{Library_Name} attribute has a string value. There is no restriction
-on the name of a library. It is the responsability of the developer to
+on the name of a library. It is the responsibility of the developer to
choose a name that will be accepted by the platform. It is recommended to
choose names that could be Ada identifiers; such names are almost guaranteed
to be acceptable on all platforms.
@@ -12664,7 +12664,7 @@ if @file{a1.ads}, @file{a2.ads} or @file{a2.adb} includes a statement
@code{"with L1;"}.
To be sure that all the sources in the library associated with @code{L} are
-up to date, and that all the sources of parject @code{A} are also up to date,
+up to date, and that all the sources of project @code{A} are also up to date,
the following two commands needs to be used:
@smallexample
@@ -15221,7 +15221,7 @@ affected cases include:
@noindent
In compact mode (when GNAT style layout or compact layout is set),
the pretty printer uses one level of indentation instead
-of two. This is achived in the record definition and record representation
+of two. This is achieved in the record definition and record representation
clause cases by putting the @code{record} keyword on the same line as the
start of the declaration or representation clause, and in the block and loop
case by putting the block or loop header on the same line as the statement
@@ -16106,7 +16106,7 @@ all upper case). Characters of the other case are folded as required.
@var{length} represents the length of the krunched name. The default
when no argument is given is ^8^39^ characters. A length of zero stands for
unlimited, in other words do not chop except for system files where the
-impled crunching length is always eight characters.
+implied crunching length is always eight characters.
@noindent
The output is the krunched name. The output has an extension only if the
@@ -27062,7 +27062,7 @@ There is nothing specific to Windows in this area. @pxref{Library Projects}.
@end menu
@noindent
-Note that it is prefered to use the built-in GNAT DLL support
+Note that it is preferred to use the built-in GNAT DLL support
(@pxref{Building DLLs with GNAT}) or GNAT Project files
(@pxref{Building DLLs with GNAT Project files}) to build DLLs.
diff --git a/gcc/ada/init.c b/gcc/ada/init.c
index 12a9badafc2..7ca680040bd 100644
--- a/gcc/ada/init.c
+++ b/gcc/ada/init.c
@@ -277,10 +277,10 @@ __gnat_set_globals (int main_priority,
call chain. To evaluate if a handler applies at some point in this chain,
the propagation engine needs to determine what region the corresponding
call instruction pertains to. The return address may not be attached to the
- same region as the call, so the unwinder unconditionally substracts "some"
+ same region as the call, so the unwinder unconditionally subtracts "some"
amount to the return addresses it gets to search the region tables. The
exact amount is computed to ensure that the resulting address is inside the
- call instruction, and is thus target dependant (think about delay slots for
+ call instruction, and is thus target dependent (think about delay slots for
instance).
When we raise an exception from a signal handler, e.g. to transform a
@@ -1794,10 +1794,10 @@ __gnat_initialize (void *eh ATTRIBUTE_UNUSED)
constructor fashion, typically triggered by the VxWorks loader. This is
achieved by way of a special variable declaration in the crt object, the
name of which has been deduced by analyzing the output of the "munching"
- step documented for C++. The de-registration is handled symetrically,
+ step documented for C++. The de-registration is handled symmetrically,
a-la C++ destructor fashion and typically triggered by the dynamic
unloader. Note that since the tables shall be registered against a
- common datastructure, libgcc should be one of the modules (vs beeing
+ common datastructure, libgcc should be one of the modules (vs being
partially linked against all the others at build time) and shall be
loaded first.
@@ -1991,7 +1991,7 @@ __gnat_adjust_context_for_raise (int signo ATTRIBUTE_UNUSED,
{
/* The point is that the interrupted context PC typically is the address
that we should search an EH region for, which is different from the call
- return address case. The target independant part of the GCC unwinder
+ return address case. The target independent part of the GCC unwinder
don't differentiate the two situations, so we compensate here for the
adjustments it will blindly make.
diff --git a/gcc/ada/misc.c b/gcc/ada/misc.c
index b8a3299ef49..8d59496fd17 100644
--- a/gcc/ada/misc.c
+++ b/gcc/ada/misc.c
@@ -41,7 +41,6 @@
#include "tree.h"
#include "real.h"
#include "rtl.h"
-#include "errors.h"
#include "diagnostic.h"
#include "expr.h"
#include "libfuncs.h"
diff --git a/gcc/ada/raise.c b/gcc/ada/raise.c
index d0abc8a79c0..05d19baf218 100644
--- a/gcc/ada/raise.c
+++ b/gcc/ada/raise.c
@@ -204,7 +204,7 @@ db_indent (int requests)
}
-static void
+static void ATTRIBUTE_PRINTF_2
db (int db_code, char * msg_format, ...)
{
if (db_accepted_codes () & db_code)
@@ -264,7 +264,7 @@ db_phases (int phases)
table which heads a list of possible actions to be taken (see below).
If it is determined that indeed an action should be taken, that
- is, if one action filter matches the exception beeing propagated,
+ is, if one action filter matches the exception being propagated,
then control should be transfered to landing-pad.
A null first-action-index indicates that there are only cleanups
@@ -283,7 +283,7 @@ db_phases (int phases)
Non null action-filters provide an index into the ttypes [] table
(see below), from which information may be retrieved to check if it
- matches the exception beeing propagated.
+ matches the exception being propagated.
action-filter > 0 means there is a regular handler to be run,
@@ -302,7 +302,7 @@ db_phases (int phases)
A null value indicates a catch-all handler in C++, and an "others"
handler in Ada.
- Non null values are used to match the exception beeing propagated:
+ Non null values are used to match the exception being propagated:
In C++ this is a pointer to some rtti data, while in Ada this is an
exception id.
@@ -611,7 +611,7 @@ get_region_description_for (_Unwind_Context *uw_context,
typedef enum
{
/* Found some call site base data, but need to analyze further
- before beeing able to decide. */
+ before being able to decide. */
unknown,
/* There is nothing relevant in the context at hand. */
@@ -761,7 +761,7 @@ get_call_site_action_for (_Unwind_Context *uw_context,
{
_Unwind_Ptr ip
= _Unwind_GetIP (uw_context) - 1;
- /* Substract 1 because GetIP yields a call return address while we are
+ /* Subtract 1 because GetIP yields a call return address while we are
interested in information for the call point. This does not always yield
the exact call instruction address but always brings the ip back within
the corresponding region.
diff --git a/gcc/ada/trans.c b/gcc/ada/trans.c
index 869ce3f5603..36b5ba2d3bc 100644
--- a/gcc/ada/trans.c
+++ b/gcc/ada/trans.c
@@ -2316,7 +2316,7 @@ Exception_Handler_to_gnu_zcx (Node_Id gnat_node)
is integer_zero_node. It would not work, however, because GCC's
notion of "catch all" is stronger than our notion of "others". Until
we correctly use the cleanup interface as well, doing that would
- prevent the "all others" handlers from beeing seen, because nothing
+ prevent the "all others" handlers from being seen, because nothing
can be caught beyond a catch all from GCC's point of view. */
gnu_etypes_list = tree_cons (NULL_TREE, gnu_etype, gnu_etypes_list);
}
@@ -2431,7 +2431,7 @@ Compilation_Unit_to_gnu (Node_Id gnat_node)
If this is an expression, return the GCC equivalent of the expression. If
it is a statement, return the statement. In the case when called for a
statement, it may also add statements to the current statement group, in
- which case anything it returns is to be interpreted as occuring after
+ which case anything it returns is to be interpreted as occurring after
anything `it already added. */
tree
@@ -4261,7 +4261,7 @@ add_decl_expr (tree gnu_decl, Entity_Id gnat_entity)
}
}
- /* If this is a DECL_EXPR for a variable with DECL_INITIAl set,
+ /* If this is a DECL_EXPR for a variable with DECL_INITIAL set,
there are two cases we need to handle here. */
if (TREE_CODE (gnu_decl) == VAR_DECL && DECL_INITIAL (gnu_decl))
{
@@ -4526,6 +4526,7 @@ gnat_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p ATTRIBUTE_UNUSED)
DECL_INITIAL (new_var) = TREE_OPERAND (expr, 0);
TREE_OPERAND (expr, 0) = new_var;
+ recompute_tree_invarant_for_addr_expr (expr);
return GS_ALL_DONE;
}
return GS_UNHANDLED;
diff --git a/gcc/ada/utils2.c b/gcc/ada/utils2.c
index 6ca8b99e50a..ae56b421a32 100644
--- a/gcc/ada/utils2.c
+++ b/gcc/ada/utils2.c
@@ -176,7 +176,7 @@ known_alignment (tree exp)
case PLUS_EXPR:
case MINUS_EXPR:
/* If two address are added, the alignment of the result is the
- minimum of the two aligments. */
+ minimum of the two alignments. */
lhs = known_alignment (TREE_OPERAND (exp, 0));
rhs = known_alignment (TREE_OPERAND (exp, 1));
this_alignment = MIN (lhs, rhs);
diff --git a/gcc/basic-block.h b/gcc/basic-block.h
index 4deeb899755..ad89fa5b69e 100644
--- a/gcc/basic-block.h
+++ b/gcc/basic-block.h
@@ -29,7 +29,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "hard-reg-set.h"
#include "predict.h"
#include "vec.h"
-#include "errors.h"
#include "function.h"
/* Head of register set linked list. */
@@ -183,7 +182,7 @@ struct loop;
struct loops;
/* Declared in tree-flow.h. */
-struct bb_ann_d;
+struct edge_prediction;
/* A basic block is a sequence of instructions with only entry and
only one exit. If any one of the instructions are executed, they
@@ -246,8 +245,11 @@ struct basic_block_def GTY((chain_next ("%h.next_bb"), chain_prev ("%h.prev_bb")
/* The data used by basic block copying and reordering functions. */
struct reorder_block_def * rbi;
- /* Annotations used at the tree level. */
- struct bb_ann_d *tree_annotations;
+ /* Chain of PHI nodes for this block. */
+ tree phi_nodes;
+
+ /* A list of predictions. */
+ struct edge_prediction *predictions;
/* Expected number of executions: calculated in profile.c. */
gcov_type count;
@@ -263,9 +265,6 @@ struct basic_block_def GTY((chain_next ("%h.next_bb"), chain_prev ("%h.prev_bb")
/* Various flags. See BB_* below. */
int flags;
-
- /* Which section block belongs in, when partitioning basic blocks. */
- int partition;
};
typedef struct basic_block_def *basic_block;
diff --git a/gcc/bb-reorder.c b/gcc/bb-reorder.c
index 547296714ce..e0cba445c67 100644
--- a/gcc/bb-reorder.c
+++ b/gcc/bb-reorder.c
@@ -81,8 +81,8 @@
#include "tm_p.h"
#include "obstack.h"
#include "expr.h"
-#include "errors.h"
#include "params.h"
+#include "toplev.h"
/* The number of rounds. In most cases there will only be 4 rounds, but
when partitioning hot and cold basic blocks into separate sections of
diff --git a/gcc/builtins.def b/gcc/builtins.def
index 61f2c3e4d5c..7d3353898af 100644
--- a/gcc/builtins.def
+++ b/gcc/builtins.def
@@ -397,8 +397,6 @@ DEF_EXT_LIB_BUILTIN (BUILT_IN_YNF, "ynf", BT_FN_FLOAT_INT_FLOAT, ATTR_MATHFN_
DEF_EXT_LIB_BUILTIN (BUILT_IN_YNL, "ynl", BT_FN_LONGDOUBLE_INT_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
/* Category: _Complex math builtins. */
-/* The C99 clog function conflicts with C++ iostreams clog, see
- http://gcc.gnu.org/ml/gcc-patches/2003-09/msg00510.html */
DEF_C99_BUILTIN (BUILT_IN_CABS, "cabs", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
DEF_C99_BUILTIN (BUILT_IN_CABSF, "cabsf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
DEF_C99_BUILTIN (BUILT_IN_CABSL, "cabsl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
@@ -435,9 +433,9 @@ DEF_C99_BUILTIN (BUILT_IN_CEXPL, "cexpl", BT_FN_COMPLEX_LONGDOUBLE_COMPLE
DEF_C99_BUILTIN (BUILT_IN_CIMAG, "cimag", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LIST)
DEF_C99_BUILTIN (BUILT_IN_CIMAGF, "cimagf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LIST)
DEF_C99_BUILTIN (BUILT_IN_CIMAGL, "cimagl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST)
-/*DEF_C99_BUILTIN (BUILT_IN_CLOG, "clog", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)*/
-/*DEF_C99_BUILTIN (BUILT_IN_CLOGF, "clogf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)*/
-/*DEF_C99_BUILTIN (BUILT_IN_CLOGL, "clogl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)*/
+DEF_C99_BUILTIN (BUILT_IN_CLOG, "clog", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CLOGF, "clogf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_BUILTIN (BUILT_IN_CLOGL, "clogl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
DEF_C99_BUILTIN (BUILT_IN_CONJ, "conj", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LIST)
DEF_C99_BUILTIN (BUILT_IN_CONJF, "conjf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LIST)
DEF_C99_BUILTIN (BUILT_IN_CONJL, "conjl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LIST)
diff --git a/gcc/c-common.c b/gcc/c-common.c
index 177ca826b99..50cc7ad486e 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -1448,7 +1448,7 @@ check_case_value (tree value)
if the case is not a case range.
The caller has to make sure that we are not called with NULL for
CASE_LOW_P (i.e. the default case).
- Returns true if the case label is in range of ORIG_TYPE (satured or
+ Returns true if the case label is in range of ORIG_TYPE (saturated or
untouched) or false if the label is out of range. */
static bool
diff --git a/gcc/c-common.h b/gcc/c-common.h
index 4b860e2aded..04b434616b2 100644
--- a/gcc/c-common.h
+++ b/gcc/c-common.h
@@ -31,7 +31,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
IDENTIFIER_MARKED (used by search routines).
DECL_PRETTY_FUNCTION_P (in VAR_DECL)
1: C_DECLARED_LABEL_FLAG (in LABEL_DECL)
- STMT_IS_FULL_EXPR_P (in _STMT)
STATEMENT_LIST_STMT_EXPR (in STATEMENT_LIST)
2: unused
3: STATEMENT_LIST_HAS_LABEL (in STATEMENT_LIST)
@@ -704,12 +703,6 @@ extern void finish_file (void);
/* These macros provide convenient access to the various _STMT nodes. */
-/* Nonzero if this statement should be considered a full-expression,
- i.e., if temporaries created during this statement should have
- their destructors run at the end of this statement. (In C, this
- will always be false, since there are no destructors.) */
-#define STMT_IS_FULL_EXPR_P(NODE) TREE_LANG_FLAG_1 ((NODE))
-
/* Nonzero if a given STATEMENT_LIST represents the outermost binding
if a statement expression. */
#define STATEMENT_LIST_STMT_EXPR(NODE) \
@@ -735,7 +728,6 @@ enum c_tree_code {
#undef DEFTREECODE
-extern int stmts_are_full_exprs_p (void);
extern int anon_aggr_type_p (tree);
/* For a VAR_DECL that is an anonymous union, these are the various
diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index ebd93986583..606c0d8a4ac 100644
--- a/gcc/c-decl.c
+++ b/gcc/c-decl.c
@@ -418,6 +418,31 @@ static tree grokdeclarator (const struct c_declarator *,
static tree grokparms (struct c_arg_info *, bool);
static void layout_array_type (tree);
+/* T is a statement. Add it to the statement-tree. This is the
+ C/ObjC version--C++ has a slightly different version of this
+ function. */
+
+tree
+add_stmt (tree t)
+{
+ enum tree_code code = TREE_CODE (t);
+
+ if (EXPR_P (t) && code != LABEL_EXPR)
+ {
+ if (!EXPR_HAS_LOCATION (t))
+ SET_EXPR_LOCATION (t, input_location);
+ }
+
+ if (code == LABEL_EXPR || code == CASE_LABEL_EXPR)
+ STATEMENT_LIST_HAS_LABEL (cur_stmt_list) = 1;
+
+ /* Add T to the statement-tree. Non-side-effect statements need to be
+ recorded during statement expressions. */
+ append_to_statement_list_force (t, &cur_stmt_list);
+
+ return t;
+}
+
/* States indicating how grokdeclarator() should handle declspecs marked
with __attribute__((deprecated)). An object declared as
__attribute__((deprecated)) suppresses warnings of uses of other
@@ -6718,16 +6743,6 @@ c_dup_lang_specific_decl (tree decl)
functions are not called from anywhere in the C front end, but as
these changes continue, that will change. */
-/* Returns nonzero if the current statement is a full expression,
- i.e. temporaries created during that statement should be destroyed
- at the end of the statement. */
-
-int
-stmts_are_full_exprs_p (void)
-{
- return 0;
-}
-
/* Returns the stmt_tree (if any) to which statements are currently
being added. If there is no active statement-tree, NULL is
returned. */
diff --git a/gcc/c-gimplify.c b/gcc/c-gimplify.c
index a82c4a6562b..f7e87bf489e 100644
--- a/gcc/c-gimplify.c
+++ b/gcc/c-gimplify.c
@@ -29,7 +29,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
-#include "errors.h"
#include "varray.h"
#include "c-tree.h"
#include "c-common.h"
diff --git a/gcc/c-objc-common.c b/gcc/c-objc-common.c
index 0dc8f55ddfc..95a0a3a7130 100644
--- a/gcc/c-objc-common.c
+++ b/gcc/c-objc-common.c
@@ -171,7 +171,7 @@ c_tree_printer (pretty_printer *pp, text_info *text)
switch (*text->format_spec)
{
case 'D':
- if (DECL_DEBUG_EXPR (t) && DECL_DEBUG_EXPR_IS_FROM (t))
+ if (DECL_DEBUG_EXPR_IS_FROM (t) && DECL_DEBUG_EXPR (t))
{
t = DECL_DEBUG_EXPR (t);
if (!DECL_P (t))
diff --git a/gcc/c-parser.c b/gcc/c-parser.c
index 04fffd1a23f..d0eec8db17d 100644
--- a/gcc/c-parser.c
+++ b/gcc/c-parser.c
@@ -2145,7 +2145,7 @@ c_parser_direct_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
which is resolved in the direction of treating it as a typedef
name. If a close parenthesis follows, it is also an empty
parameter list, as the syntax does not permit empty abstract
- declarators. Otherwise, it is a parenthesised declarator (in
+ declarators. Otherwise, it is a parenthesized declarator (in
which case the analysis may be repeated inside it, recursively).
??? There is an ambiguity in a parameter declaration "int
@@ -2155,7 +2155,7 @@ c_parser_direct_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
documenting. At present we follow an accident of the old
parser's implementation, whereby the first parameter must have
some declaration specifiers other than just attributes. Thus as
- a parameter declaration it is treated as a parenthesised
+ a parameter declaration it is treated as a parenthesized
parameter named x, and as an abstract declarator it is
rejected.
@@ -5325,7 +5325,7 @@ c_parser_expr_list (c_parser *parser)
"@interface identifier (" must start "@interface identifier (
identifier ) ...": objc-methodprotolist in the first production may
- not start with a parenthesised identifier as a declarator of a data
+ not start with a parenthesized identifier as a declarator of a data
definition with no declaration specifiers if the objc-superclass,
objc-protocol-refs and objc-class-instance-variables are omitted. */
diff --git a/gcc/c-pch.c b/gcc/c-pch.c
index a1513418578..39cf42c1082 100644
--- a/gcc/c-pch.c
+++ b/gcc/c-pch.c
@@ -1,5 +1,5 @@
/* Precompiled header implementation for the C languages.
- Copyright (C) 2000, 2002, 2003, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
This file is part of GCC.
diff --git a/gcc/c-pragma.c b/gcc/c-pragma.c
index f4801e87c06..bf1c4581a1d 100644
--- a/gcc/c-pragma.c
+++ b/gcc/c-pragma.c
@@ -34,6 +34,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "c-common.h"
#include "output.h"
#include "tm_p.h"
+#include "vec.h"
#include "target.h"
#define GCC_BAD(msgid) do { warning (0, msgid); return; } while (0)
@@ -585,15 +586,20 @@ maybe_apply_renaming_pragma (tree decl, tree asmname)
#ifdef HANDLE_PRAGMA_VISIBILITY
static void handle_pragma_visibility (cpp_reader *);
+typedef enum symbol_visibility visibility;
+DEF_VEC_I (visibility);
+DEF_VEC_ALLOC_I (visibility, heap);
+
/* Sets the default visibility for symbols to something other than that
specified on the command line. */
static void
handle_pragma_visibility (cpp_reader *dummy ATTRIBUTE_UNUSED)
-{ /* Form is #pragma GCC visibility push(hidden)|pop */
- static int visstack [16], visidx;
+{
+ /* Form is #pragma GCC visibility push(hidden)|pop */
tree x;
enum cpp_ttype token;
enum { bad, push, pop } action = bad;
+ static VEC (visibility, heap) *visstack;
token = c_lex (&x);
if (token == CPP_NAME)
@@ -610,14 +616,15 @@ handle_pragma_visibility (cpp_reader *dummy ATTRIBUTE_UNUSED)
{
if (pop == action)
{
- if (!visidx)
+ if (!VEC_length (visibility, visstack))
{
GCC_BAD ("No matching push for %<#pragma GCC visibility pop%>");
}
else
{
- default_visibility = visstack[--visidx];
- visibility_options.inpragma = (visidx>0);
+ default_visibility = VEC_pop (visibility, visstack);
+ visibility_options.inpragma
+ = VEC_length (visibility, visstack) != 0;
}
}
else
@@ -629,14 +636,11 @@ handle_pragma_visibility (cpp_reader *dummy ATTRIBUTE_UNUSED)
{
GCC_BAD ("malformed #pragma GCC visibility push");
}
- else if (visidx >= 16)
- {
- GCC_BAD ("No more than sixteen #pragma GCC visibility pushes allowed at once");
- }
else
{
const char *str = IDENTIFIER_POINTER (x);
- visstack[visidx++] = default_visibility;
+ VEC_safe_push (visibility, heap, visstack,
+ default_visibility);
if (!strcmp (str, "default"))
default_visibility = VISIBILITY_DEFAULT;
else if (!strcmp (str, "internal"))
diff --git a/gcc/c-semantics.c b/gcc/c-semantics.c
index f7757c6ff82..d2f9650a957 100644
--- a/gcc/c-semantics.c
+++ b/gcc/c-semantics.c
@@ -101,33 +101,6 @@ pop_stmt_list (tree t)
return t;
}
-/* T is a statement. Add it to the statement-tree. */
-
-tree
-add_stmt (tree t)
-{
- enum tree_code code = TREE_CODE (t);
-
- if (EXPR_P (t) && code != LABEL_EXPR)
- {
- if (!EXPR_HAS_LOCATION (t))
- SET_EXPR_LOCATION (t, input_location);
-
- /* When we expand a statement-tree, we must know whether or not the
- statements are full-expressions. We record that fact here. */
- STMT_IS_FULL_EXPR_P (t) = stmts_are_full_exprs_p ();
- }
-
- if (code == LABEL_EXPR || code == CASE_LABEL_EXPR)
- STATEMENT_LIST_HAS_LABEL (cur_stmt_list) = 1;
-
- /* Add T to the statement-tree. Non-side-effect statements need to be
- recorded during statement expressions. */
- append_to_statement_list_force (t, &cur_stmt_list);
-
- return t;
-}
-
/* Build a generic statement based on the given type of node and
arguments. Similar to `build_nt', except that we set
EXPR_LOCATION to be the current source location. */
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index e1580b3417a..dc945bf243e 100644
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -1742,12 +1742,9 @@ build_indirect_ref (tree ptr, const char *errorstring)
else
{
tree t = TREE_TYPE (type);
- tree mvt = t;
tree ref;
- if (TREE_CODE (mvt) != ARRAY_TYPE)
- mvt = TYPE_MAIN_VARIANT (mvt);
- ref = build1 (INDIRECT_REF, mvt, pointer);
+ ref = build1 (INDIRECT_REF, t, pointer);
if (!COMPLETE_OR_VOID_TYPE_P (t) && TREE_CODE (t) != ARRAY_TYPE)
{
diff --git a/gcc/cfgbuild.c b/gcc/cfgbuild.c
index 98910232b5c..d87d6d35de5 100644
--- a/gcc/cfgbuild.c
+++ b/gcc/cfgbuild.c
@@ -225,8 +225,7 @@ enum state {
/* Basic blocks that may need splitting (due to a label appearing in
the middle, etc) belong to this state. After splitting them,
- make_edges will create create edges going out of them as
- needed. */
+ make_edges will create edges going out of them as needed. */
BLOCK_TO_SPLIT
};
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 2bba7416a4e..cbbffb6c36d 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -1157,22 +1157,25 @@ static basic_block
construct_init_block (void)
{
basic_block init_block, first_block;
- edge e = NULL, e2;
- edge_iterator ei;
+ edge e = NULL;
+ int flags;
- FOR_EACH_EDGE (e2, ei, ENTRY_BLOCK_PTR->succs)
- {
- /* Clear EDGE_EXECUTABLE. This flag is never used in the backend.
+ /* Multiple entry points not supported yet. */
+ gcc_assert (EDGE_COUNT (ENTRY_BLOCK_PTR->succs) == 1);
- For all other blocks this edge flag is cleared while expanding
- a basic block in expand_gimple_basic_block, but there we never
- looked at the successors of the entry block.
- This caused PR17513. */
- e2->flags &= ~EDGE_EXECUTABLE;
+ e = EDGE_SUCC (ENTRY_BLOCK_PTR, 0);
- if (e2->dest == ENTRY_BLOCK_PTR->next_bb)
- e = e2;
+ /* When entry edge points to first basic block, we don't need jump,
+ otherwise we have to jump into proper target. */
+ if (e && e->dest != ENTRY_BLOCK_PTR->next_bb)
+ {
+ tree label = tree_block_label (e->dest);
+
+ emit_jump (label_rtx (label));
+ flags = 0;
}
+ else
+ flags = EDGE_FALLTHRU;
init_block = create_basic_block (NEXT_INSN (get_insns ()),
get_last_insn (),
@@ -1183,7 +1186,7 @@ construct_init_block (void)
{
first_block = e->dest;
redirect_edge_succ (e, init_block);
- e = make_edge (init_block, first_block, EDGE_FALLTHRU);
+ e = make_edge (init_block, first_block, flags);
}
else
e = make_edge (init_block, EXIT_BLOCK_PTR, EDGE_FALLTHRU);
diff --git a/gcc/cfghooks.c b/gcc/cfghooks.c
index bf7921806b2..35e65a31c31 100644
--- a/gcc/cfghooks.c
+++ b/gcc/cfghooks.c
@@ -825,7 +825,7 @@ execute_on_shrinking_pred (edge e)
}
/* This is used inside loop versioning when we want to insert
- stmts/insns on the edges, which have a different behaviour
+ stmts/insns on the edges, which have a different behavior
in tree's and in RTL, so we made a CFG hook. */
void
lv_flush_pending_stmts (edge e)
diff --git a/gcc/cfghooks.h b/gcc/cfghooks.h
index 480c197b597..5867d972774 100644
--- a/gcc/cfghooks.h
+++ b/gcc/cfghooks.h
@@ -119,7 +119,7 @@ struct cfg_hooks
unsigned int *n_to_remove,
int flags);
- /* Add conition to new basic block and update CFG used in loop
+ /* Add condition to new basic block and update CFG used in loop
versioning. */
void (*lv_add_condition_to_bb) (basic_block, basic_block, basic_block,
void *);
diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h
index f96bf81c9eb..048802bb85a 100644
--- a/gcc/cfgloop.h
+++ b/gcc/cfgloop.h
@@ -289,6 +289,7 @@ extern void verify_loop_structure (struct loops *);
/* Loop analysis. */
extern bool just_once_each_iteration_p (const struct loop *, basic_block);
extern unsigned expected_loop_iterations (const struct loop *);
+extern rtx doloop_condition_get (rtx);
/* Loop manipulation. */
extern bool can_duplicate_loop_p (struct loop *loop);
diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c
index 42761cad745..86b2435c30a 100644
--- a/gcc/cfgrtl.c
+++ b/gcc/cfgrtl.c
@@ -1190,7 +1190,7 @@ rtl_tidy_fallthru_edge (edge e)
/* ??? In a late-running flow pass, other folks may have deleted basic
blocks by nopping out blocks, leaving multiple BARRIERs between here
- and the target label. They ought to be chastized and fixed.
+ and the target label. They ought to be chastised and fixed.
We can also wind up with a sequence of undeletable labels between
one block and the next.
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index b58b89af3e8..a447fabc134 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -97,6 +97,7 @@ The varpool data structure:
#include "varray.h"
#include "output.h"
#include "intl.h"
+#include "tree-gimple.h"
static void cgraph_node_remove_callers (struct cgraph_node *node);
static inline void cgraph_edge_remove_caller (struct cgraph_edge *e);
@@ -262,9 +263,9 @@ cgraph_node_for_asm (tree asmname)
return NULL;
}
-/* Return callgraph edge representing CALL_EXPR. */
+/* Return callgraph edge representing CALL_EXPR statement. */
struct cgraph_edge *
-cgraph_edge (struct cgraph_node *node, tree call_expr)
+cgraph_edge (struct cgraph_node *node, tree call_stmt)
{
struct cgraph_edge *e;
@@ -274,7 +275,7 @@ cgraph_edge (struct cgraph_node *node, tree call_expr)
because we want to make possible having multiple cgraph nodes representing
different clones of the same body before the body is actually cloned. */
for (e = node->callees; e; e= e->next_callee)
- if (e->call_expr == call_expr)
+ if (e->call_stmt == call_stmt)
break;
return e;
}
@@ -283,17 +284,17 @@ cgraph_edge (struct cgraph_node *node, tree call_expr)
struct cgraph_edge *
cgraph_create_edge (struct cgraph_node *caller, struct cgraph_node *callee,
- tree call_expr, gcov_type count, int nest)
+ tree call_stmt, gcov_type count, int nest)
{
struct cgraph_edge *edge = ggc_alloc (sizeof (struct cgraph_edge));
#ifdef ENABLE_CHECKING
struct cgraph_edge *e;
for (e = caller->callees; e; e = e->next_callee)
- gcc_assert (e->call_expr != call_expr);
+ gcc_assert (e->call_stmt != call_stmt);
#endif
- gcc_assert (TREE_CODE (call_expr) == CALL_EXPR);
+ gcc_assert (get_call_expr_in (call_stmt));
if (!DECL_SAVED_TREE (callee->decl))
edge->inline_failed = N_("function body not available");
@@ -309,7 +310,7 @@ cgraph_create_edge (struct cgraph_node *caller, struct cgraph_node *callee,
edge->caller = caller;
edge->callee = callee;
- edge->call_expr = call_expr;
+ edge->call_stmt = call_stmt;
edge->prev_caller = NULL;
edge->next_caller = callee->callers;
if (callee->callers)
@@ -601,8 +602,11 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node)
if (cgraph_function_flags_ready)
fprintf (f, " availability:%s",
availability_names [cgraph_function_body_availability (node)]);
- if (node->local.self_insns)
- fprintf (f, " %i insns", node->local.self_insns);
+ if (node->master_clone && node->master_clone->uid != node->uid)
+ fprintf (f, "(%i)", node->master_clone->uid);
+ if (node->count)
+ fprintf (f, " executed "HOST_WIDEST_INT_PRINT_DEC"x",
+ (HOST_WIDEST_INT)node->count);
if (node->local.self_insns)
fprintf (f, " %i insns", node->local.self_insns);
if (node->global.insns && node->global.insns != node->local.self_insns)
@@ -856,8 +860,8 @@ decide_is_variable_needed (struct cgraph_varpool_node *node, tree decl)
if (node->needed)
return true;
- /* Externally visible functions must be output. The exception is
- COMDAT functions that must be output only when they are needed. */
+ /* Externally visible variables must be output. The exception is
+ COMDAT variables that must be output only when they are needed. */
if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
return true;
@@ -895,6 +899,11 @@ cgraph_varpool_finalize_decl (tree decl)
if (decide_is_variable_needed (node, decl))
cgraph_varpool_mark_needed_node (node);
+ /* Since we reclaim unreachable nodes at the end of every language
+ level unit, we need to be conservative about possible entry points
+ there. */
+ if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
+ cgraph_varpool_mark_needed_node (node);
if (cgraph_global_info_ready || !flag_unit_at_a_time)
cgraph_varpool_assemble_pending_decls ();
}
@@ -911,11 +920,11 @@ 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,
- tree call_expr, int count_scale, int loop_nest)
+ tree call_stmt, int count_scale, int loop_nest)
{
struct cgraph_edge *new;
- new = cgraph_create_edge (n, e->callee, call_expr,
+ new = cgraph_create_edge (n, e->callee, call_stmt,
e->count * count_scale / REG_BR_PROB_BASE,
e->loop_nest + loop_nest);
@@ -954,7 +963,7 @@ cgraph_clone_node (struct cgraph_node *n, gcov_type count, int loop_nest)
n->count -= count;
for (e = n->callees;e; e=e->next_callee)
- cgraph_clone_edge (e, new, e->call_expr, count_scale, loop_nest);
+ cgraph_clone_edge (e, new, e->call_stmt, count_scale, loop_nest);
new->next_clone = n->next_clone;
new->prev_clone = n;
@@ -1039,36 +1048,39 @@ cgraph_unnest_node (struct cgraph_node *node)
node->origin = NULL;
}
+/* Return true when CALLER_DECL should be inlined into CALLEE_DECL. */
+
+bool
+cgraph_inline_p (struct cgraph_edge *e, const char **reason)
+{
+ *reason = e->inline_failed;
+ return !e->inline_failed;
+}
+
/* Return function availability. See cgraph.h for description of individual
return values. */
enum availability
cgraph_function_body_availability (struct cgraph_node *node)
{
- enum availability avail = node->local.avail;
- enum availability old_avail = avail;
-
+ enum availability avail;
gcc_assert (cgraph_function_flags_ready);
-#if 0
- if (avail != AVAIL_UNSET)
- return avail;
-#endif
if (!node->local.finalized)
avail = AVAIL_NOT_AVAILABLE;
else if (node->local.local)
avail = AVAIL_LOCAL;
- else if (!node->local.externally_visible)
+ else if (node->local.externally_visible)
avail = AVAIL_AVAILABLE;
/* If the function can be overwritten, return OVERWRITABLE. Take
care at least of two notable extensions - the COMDAT functions
used to share template instantiations in C++ (this is symmetric
to code cp_cannot_inline_tree_fn and probably shall be shared and
- the inlinability hooks completelly elliminated).
+ the inlinability hooks completely eliminated).
??? Does the C++ one definition rule allow us to always return
AVAIL_AVAILABLE here? That would be good reason to preserve this
hook Similarly deal with extern inline functions - this is again
- neccesary to get C++ shared functions having keyed templates
+ necessary to get C++ shared functions having keyed templates
right and in the C extension documentation we probably should
document the requirement of both versions of function (extern
inline and offline) having same side effect characteristics as
@@ -1076,17 +1088,9 @@ cgraph_function_body_availability (struct cgraph_node *node)
else if (!(*targetm.binds_local_p) (node->decl)
&& !DECL_COMDAT (node->decl) && !DECL_EXTERNAL (node->decl))
- if (DECL_DECLARED_INLINE_P (node->decl))
- avail = AVAIL_OVERWRITABLE_BUT_INLINABLE;
- else
- avail = AVAIL_OVERWRITABLE;
+ avail = AVAIL_OVERWRITABLE;
else avail = AVAIL_AVAILABLE;
- if ((old_avail != AVAIL_UNSET) && (avail != old_avail)
- && (avail != AVAIL_LOCAL || old_avail != AVAIL_AVAILABLE))
- abort ();
-
- node->local.avail = avail;
return avail;
}
@@ -1100,7 +1104,7 @@ cgraph_variable_initializer_availability (struct cgraph_varpool_node *node)
return AVAIL_NOT_AVAILABLE;
if (!TREE_PUBLIC (node->decl))
return AVAIL_AVAILABLE;
- /* If the variable can be overwritted, return OVERWRITABLE. Takes
+ /* If the variable can be overwritten, return OVERWRITABLE. Takes
care of at least two notable extensions - the COMDAT variables
used to share template instantiations in C++. */
if (!(*targetm.binds_local_p) (node->decl) && !DECL_COMDAT (node->decl))
@@ -1108,13 +1112,4 @@ cgraph_variable_initializer_availability (struct cgraph_varpool_node *node)
return AVAIL_AVAILABLE;
}
-/* Return true when CALLER_DECL should be inlined into CALLEE_DECL. */
-
-bool
-cgraph_inline_p (struct cgraph_edge *e, const char **reason)
-{
- *reason = e->inline_failed;
- return !e->inline_failed;
-}
-
#include "gt-cgraph.h"
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 6a4e89c77ba..89f9a6c5c06 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -33,12 +33,11 @@ enum availability
/* Function body/variable initializer is unknown. */
AVAIL_NOT_AVAILABLE,
/* Function body/variable initializer is known but might be replaced
- by a different one from other compilation unit and thus can be
- dealt with only as a hint. */
+ by a different one from other compilation unit and thus needs to
+ be dealt with a care. Like AVAIL_NOT_AVAILABLE it can have
+ arbitrary side effects on escaping variables and functions, while
+ like AVAILABLE it might access static variables. */
AVAIL_OVERWRITABLE,
- /* Same as AVAIL_OVERWRITABLE except the front end has said that
- this instance is stable enough to analyze or even inline. */
- AVAIL_OVERWRITABLE_BUT_INLINABLE,
/* Function body/variable initializer is known and will be used in final
program. */
AVAIL_AVAILABLE,
@@ -181,7 +180,7 @@ struct cgraph_edge GTY((chain_next ("%h.next_caller"), chain_prev ("%h.prev_call
struct cgraph_edge *next_caller;
struct cgraph_edge *prev_callee;
struct cgraph_edge *next_callee;
- tree call_expr;
+ tree call_stmt;
PTR GTY ((skip (""))) aux;
/* When NULL, inline this call. When non-NULL, points to the explanation
why function was not inlined. */
@@ -214,7 +213,7 @@ struct cgraph_varpool_node GTY(())
bool analyzed;
/* Set once it has been finalized so we consider it to be output. */
bool finalized;
- /* Set when function is scheduled to be assembled. */
+ /* Set when variable is scheduled to be assembled. */
bool output;
/* Set when function is visible by other units. */
bool externally_visible;
@@ -279,6 +278,11 @@ void cgraph_mark_reachable_node (struct cgraph_node *);
bool cgraph_inline_p (struct cgraph_edge *, const char **);
bool decide_is_variable_needed (struct cgraph_varpool_node *, tree);
+enum availability cgraph_function_body_availability (struct cgraph_node *);
+enum availability cgraph_variable_initializer_availability (struct cgraph_varpool_node *);
+bool cgraph_is_master_clone (struct cgraph_node *);
+struct cgraph_node *cgraph_master_clone (struct cgraph_node *);
+
/* In cgraphunit.c */
bool cgraph_assemble_pending_functions (void);
bool cgraph_varpool_assemble_pending_decls (void);
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 443840893fd..d3952ff49f4 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -172,14 +172,13 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
static void cgraph_expand_all_functions (void);
static void cgraph_mark_functions_to_output (void);
static void cgraph_expand_function (struct cgraph_node *);
-static tree record_call_1 (tree *, int *, void *);
+static tree record_reference (tree *, int *, void *);
static void cgraph_analyze_function (struct cgraph_node *node);
-static void cgraph_create_edges (struct cgraph_node *node, tree body);
-/* Records tree nodes seen in cgraph_create_edges. Simply using
+/* Records tree nodes seen in record_reference. Simply using
walk_tree_without_duplicates doesn't guarantee each node is visited
once because it gets a new htab upon each recursive call from
- record_calls_1. */
+ record_reference itself. */
static struct pointer_set_t *visited_nodes;
static FILE *cgraph_dump_file;
@@ -219,6 +218,17 @@ decide_is_function_needed (struct cgraph_node *node, tree decl)
return true;
}
+ /* If the user told us it is used, then it must be so. */
+ if (lookup_attribute ("used", DECL_ATTRIBUTES (decl)))
+ return true;
+
+ /* ??? If the assembler name is set by hand, it is possible to assemble
+ the name later after finalizing the function and the fact is noticed
+ in assemble_name then. This is arguably a bug. */
+ if (DECL_ASSEMBLER_NAME_SET_P (decl)
+ && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
+ return true;
+
/* If we decided it was needed before, but at the time we didn't have
the body of the function available, then it's still needed. We have
to go back and re-check its dependencies now. */
@@ -282,7 +292,12 @@ cgraph_varpool_analyze_pending_decls (void)
cgraph_varpool_first_unanalyzed_node = cgraph_varpool_first_unanalyzed_node->next_needed;
if (DECL_INITIAL (decl))
- cgraph_create_edges (NULL, DECL_INITIAL (decl));
+ {
+ visited_nodes = pointer_set_create ();
+ walk_tree (&DECL_INITIAL (decl), record_reference, NULL, visited_nodes);
+ pointer_set_destroy (visited_nodes);
+ visited_nodes = NULL;
+ }
changed = true;
}
timevar_pop (TV_CGRAPH);
@@ -292,7 +307,7 @@ cgraph_varpool_analyze_pending_decls (void)
/* Optimization of function bodies might've rendered some variables as
unnecessary so we want to avoid these from being compiled.
- This is done by prunning the queue and keeping only the variables that
+ This is done by pruning the queue and keeping only the variables that
really appear needed (ie they are either externally visible or referenced
by compiled function). Re-doing the reachability analysis on variables
brings back the remaining variables referenced by these. */
@@ -447,11 +462,10 @@ cgraph_finalize_function (tree decl, bool nested)
if (decide_is_function_needed (node, decl))
cgraph_mark_needed_node (node);
- /* Since we reclaim unrechable nodes at the end of every language
+ /* Since we reclaim unreachable nodes at the end of every language
level unit, we need to be conservative about possible entry points
there. */
- if (flag_whole_program
- && (TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl)))
+ if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
cgraph_mark_reachable_node (node);
/* If not unit at a time, go ahead and emit everything we've found
@@ -471,9 +485,6 @@ cgraph_finalize_function (tree decl, bool nested)
do_warn_unused_parameter (decl);
}
-/* Used only while constructing the callgraph. */
-static basic_block current_basic_block;
-
void
cgraph_lower_function (struct cgraph_node *node)
{
@@ -485,7 +496,7 @@ cgraph_lower_function (struct cgraph_node *node)
/* Walk tree and record all calls. Called via walk_tree. */
static tree
-record_call_1 (tree *tp, int *walk_subtrees, void *data)
+record_reference (tree *tp, int *walk_subtrees, void *data)
{
tree t = *tp;
@@ -516,41 +527,6 @@ record_call_1 (tree *tp, int *walk_subtrees, void *data)
}
break;
- case CALL_EXPR:
- {
- tree decl = get_callee_fndecl (*tp);
- if (decl && TREE_CODE (decl) == FUNCTION_DECL)
- {
- cgraph_create_edge (data, cgraph_node (decl), *tp,
- current_basic_block->count,
- current_basic_block->loop_depth);
-
- /* When we see a function call, we don't want to look at the
- function reference in the ADDR_EXPR that is hanging from
- the CALL_EXPR we're examining here, because we would
- conclude incorrectly that the function's address could be
- taken by something that is not a function call. So only
- walk the function parameter list, skip the other subtrees. */
-
- walk_tree (&TREE_OPERAND (*tp, 1), record_call_1, data,
- visited_nodes);
- *walk_subtrees = 0;
- }
- break;
- }
-
- case STATEMENT_LIST:
- {
- tree_stmt_iterator tsi;
- /* Track current statement while finding CALL_EXPRs. */
- for (tsi = tsi_start (*tp); !tsi_end_p (tsi); tsi_next (&tsi))
- {
- walk_tree (tsi_stmt_ptr (tsi), record_call_1, data,
- visited_nodes);
- }
- }
- break;
-
default:
/* Save some cycles by not walking types and declaration as we
won't find anything useful there anyway. */
@@ -573,98 +549,62 @@ record_call_1 (tree *tp, int *walk_subtrees, void *data)
static void
cgraph_create_edges (struct cgraph_node *node, tree body)
{
+ basic_block bb;
- /* The nodes we're interested in are never shared, so walk
- the tree ignoring duplicates. */
+ struct function *this_cfun = DECL_STRUCT_FUNCTION (body);
+ block_stmt_iterator bsi;
+ tree step;
visited_nodes = pointer_set_create ();
- gcc_assert (current_basic_block == NULL);
- if (TREE_CODE (body) == FUNCTION_DECL)
- {
- struct function *this_cfun = DECL_STRUCT_FUNCTION (body);
- block_stmt_iterator bsi;
- tree step;
-
- /* Reach the trees by walking over the CFG, and note the
- enclosing basic-blocks in the call edges. */
- FOR_EACH_BB_FN (current_basic_block, this_cfun)
- for (bsi = bsi_start (current_basic_block); !bsi_end_p (bsi); bsi_next (&bsi))
- walk_tree (bsi_stmt_ptr (bsi), record_call_1, node, visited_nodes);
- current_basic_block = NULL;
-
- /* Walk over any private statics that may take addresses of functions. */
- if (TREE_CODE (DECL_INITIAL (body)) == BLOCK)
- {
- for (step = BLOCK_VARS (DECL_INITIAL (body));
- step;
- step = TREE_CHAIN (step))
- if (DECL_INITIAL (step))
- walk_tree (&DECL_INITIAL (step), record_call_1, node, visited_nodes);
- }
- /* Also look here for private statics. */
- if (DECL_STRUCT_FUNCTION (body))
- for (step = DECL_STRUCT_FUNCTION (body)->unexpanded_var_list;
- step;
- step = TREE_CHAIN (step))
+ /* Reach the trees by walking over the CFG, and note the
+ enclosing basic-blocks in the call edges. */
+ FOR_EACH_BB_FN (bb, this_cfun)
+ for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ {
+ tree stmt = bsi_stmt (bsi);
+ tree call = get_call_expr_in (stmt);
+ tree decl;
+
+ if (call && (decl = get_callee_fndecl (call)))
{
- tree decl = TREE_VALUE (step);
- if (DECL_INITIAL (decl) && TREE_STATIC (decl))
- walk_tree (&DECL_INITIAL (decl), record_call_1, node, visited_nodes);
+ cgraph_create_edge (node, cgraph_node (decl), stmt,
+ bb->count,
+ bb->loop_depth);
+ walk_tree (&TREE_OPERAND (call, 1),
+ record_reference, node, visited_nodes);
+ if (TREE_CODE (stmt) == MODIFY_EXPR)
+ walk_tree (&TREE_OPERAND (stmt, 0),
+ record_reference, node, visited_nodes);
}
+ else
+ walk_tree (bsi_stmt_ptr (bsi), record_reference, node, visited_nodes);
+ }
+
+ /* Walk over any private statics that may take addresses of functions. */
+ if (TREE_CODE (DECL_INITIAL (body)) == BLOCK)
+ {
+ for (step = BLOCK_VARS (DECL_INITIAL (body));
+ step;
+ step = TREE_CHAIN (step))
+ if (DECL_INITIAL (step))
+ walk_tree (&DECL_INITIAL (step), record_reference, node, visited_nodes);
}
- else
- walk_tree (&body, record_call_1, node, visited_nodes);
+
+ /* Also look here for private statics. */
+ if (DECL_STRUCT_FUNCTION (body))
+ for (step = DECL_STRUCT_FUNCTION (body)->unexpanded_var_list;
+ step;
+ step = TREE_CHAIN (step))
+ {
+ tree decl = TREE_VALUE (step);
+ if (DECL_INITIAL (decl) && TREE_STATIC (decl))
+ walk_tree (&DECL_INITIAL (decl), record_reference, node, visited_nodes);
+ }
pointer_set_destroy (visited_nodes);
visited_nodes = NULL;
}
-static bool error_found;
-
-/* Callback of verify_cgraph_node. Check that all call_exprs have
- cgraph nodes. */
-
-static tree
-verify_cgraph_node_1 (tree *tp, int *walk_subtrees, void *data)
-{
- tree t = *tp;
- tree decl;
-
- if (TREE_CODE (t) == CALL_EXPR && (decl = get_callee_fndecl (t)))
- {
- struct cgraph_edge *e = cgraph_edge (data, t);
- if (e)
- {
- if (e->aux)
- {
- error ("Shared call_expr:");
- debug_tree (t);
- error_found = true;
- }
- if (e->callee->decl != cgraph_node (decl)->decl)
- {
- error ("Edge points to wrong declaration:");
- debug_tree (e->callee->decl);
- fprintf (stderr," Instead of:");
- debug_tree (decl);
- }
- e->aux = (void *)1;
- }
- else
- {
- error ("Missing callgraph edge for call expr:");
- debug_tree (t);
- error_found = true;
- }
- }
-
- /* Save some cycles by not walking types and declaration as we
- won't find anything useful there anyway. */
- if (IS_TYPE_OR_DECL_P (*tp))
- *walk_subtrees = 0;
-
- return NULL_TREE;
-}
/* Verify cgraph nodes of given cgraph node. */
void
@@ -675,9 +615,9 @@ verify_cgraph_node (struct cgraph_node *node)
struct function *this_cfun = DECL_STRUCT_FUNCTION (node->decl);
basic_block this_block;
block_stmt_iterator bsi;
+ bool error_found = false;
timevar_push (TV_CGRAPH_VERIFY);
- error_found = false;
for (e = node->callees; e; e = e->next_callee)
if (e->aux)
{
@@ -716,7 +656,7 @@ verify_cgraph_node (struct cgraph_node *node)
}
if (node->global.inlined_to == node)
{
- error ("Inlined_to pointer reffers to itself");
+ error ("Inlined_to pointer refers to itself");
error_found = true;
}
@@ -743,7 +683,38 @@ verify_cgraph_node (struct cgraph_node *node)
enclosing basic-blocks in the call edges. */
FOR_EACH_BB_FN (this_block, this_cfun)
for (bsi = bsi_start (this_block); !bsi_end_p (bsi); bsi_next (&bsi))
- walk_tree (bsi_stmt_ptr (bsi), verify_cgraph_node_1, node, visited_nodes);
+ {
+ tree stmt = bsi_stmt (bsi);
+ tree call = get_call_expr_in (stmt);
+ tree decl;
+ if (call && (decl = get_callee_fndecl (call)))
+ {
+ struct cgraph_edge *e = cgraph_edge (node, stmt);
+ if (e)
+ {
+ if (e->aux)
+ {
+ error ("Shared call_stmt:");
+ debug_generic_stmt (stmt);
+ error_found = true;
+ }
+ if (e->callee->decl != cgraph_node (decl)->decl)
+ {
+ error ("Edge points to wrong declaration:");
+ debug_tree (e->callee->decl);
+ fprintf (stderr," Instead of:");
+ debug_tree (decl);
+ }
+ e->aux = (void *)1;
+ }
+ else
+ {
+ error ("Missing callgraph edge for call stmt:");
+ debug_generic_stmt (stmt);
+ error_found = true;
+ }
+ }
+ }
pointer_set_destroy (visited_nodes);
visited_nodes = NULL;
}
@@ -755,9 +726,10 @@ verify_cgraph_node (struct cgraph_node *node)
{
if (!e->aux)
{
- error ("Edge %s->%s has no corresponding call_expr",
+ error ("Edge %s->%s has no corresponding call_stmt",
cgraph_node_name (e->caller),
cgraph_node_name (e->callee));
+ debug_generic_stmt (e->call_stmt);
error_found = true;
}
e->aux = 0;
@@ -1045,6 +1017,8 @@ cgraph_expand_function (struct cgraph_node *node)
points to the dead function body. */
cgraph_node_remove_callees (node);
}
+
+ cgraph_function_flags_ready = true;
}
/* Expand all functions that must be output.
@@ -1097,7 +1071,7 @@ cgraph_expand_all_functions (void)
We also change the TREE_PUBLIC flag of all declarations that are public
in language point of view but we want to overwrite this default
- via -fwhole-program for the backend point of view. */
+ via visibilities for the backend point of view. */
static void
cgraph_function_and_variable_visibility (void)
@@ -1109,8 +1083,7 @@ cgraph_function_and_variable_visibility (void)
{
if (node->reachable
&& (DECL_COMDAT (node->decl)
- || (TREE_PUBLIC (node->decl) && !DECL_EXTERNAL (node->decl)
- && !flag_whole_program)))
+ || (TREE_PUBLIC (node->decl) && !DECL_EXTERNAL (node->decl))))
node->local.externally_visible = 1;
if (!node->local.externally_visible && node->analyzed
&& !DECL_EXTERNAL (node->decl))
@@ -1120,19 +1093,14 @@ cgraph_function_and_variable_visibility (void)
}
node->local.local = (!node->needed
&& node->analyzed
- && !TREE_PUBLIC (node->decl));
+ && !DECL_EXTERNAL (node->decl)
+ && !node->local.externally_visible);
}
for (vnode = cgraph_varpool_nodes_queue; vnode; vnode = vnode->next_needed)
{
if (vnode->needed
- && (DECL_COMDAT (vnode->decl)
- || (TREE_PUBLIC (vnode->decl) && !flag_whole_program)))
+ && (DECL_COMDAT (vnode->decl) || TREE_PUBLIC (vnode->decl)))
vnode->externally_visible = 1;
- if (!vnode->externally_visible)
- {
- gcc_assert (flag_whole_program || !TREE_PUBLIC (vnode->decl));
- TREE_PUBLIC (vnode->decl) = 0;
- }
gcc_assert (TREE_STATIC (vnode->decl));
}
@@ -1141,8 +1109,7 @@ cgraph_function_and_variable_visibility (void)
reachable just because they might be used later via external
linkage, but after making them local they are really unreachable
now. */
- if (flag_whole_program)
- cgraph_remove_unreachable_nodes (true, cgraph_dump_file);
+ cgraph_remove_unreachable_nodes (true, cgraph_dump_file);
if (cgraph_dump_file)
{
@@ -1225,6 +1192,7 @@ cgraph_optimize (void)
if (!vnode->non_ipa)
ipa_analyze_variable (vnode);
+ cgraph_function_and_variable_visibility ();
if (cgraph_dump_file)
{
fprintf (cgraph_dump_file, "Marked ");
@@ -1235,8 +1203,8 @@ cgraph_optimize (void)
bitmap_obstack_initialize (NULL);
ipa_passes ();
bitmap_obstack_release (NULL);
- /* FIXME: this should be unnecesary if inliner took care of removing dead
- functions. */
+ /* This pass remove bodies of extern inline functions we never inlined.
+ Do this later so other IPA passes see what is really going on. */
cgraph_remove_unreachable_nodes (false, dump_file);
cgraph_global_info_ready = true;
if (cgraph_dump_file)
@@ -1383,7 +1351,7 @@ update_call_expr (struct cgraph_node *new_version)
for (e = new_version->callers; e; e = e->next_caller)
/* Update the call expr on the edges
to be calling the new version. */
- TREE_OPERAND (TREE_OPERAND (e->call_expr, 0), 0) = new_version->decl;
+ TREE_OPERAND (TREE_OPERAND (get_call_expr_in (e->call_stmt), 0), 0) = new_version->decl;
}
@@ -1420,7 +1388,7 @@ 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_expr, 0, e->loop_nest);
+ new_e = cgraph_clone_edge (e, new_version, get_call_expr_in (e->call_stmt), 0, e->loop_nest);
new_e->count = e->count;
}
/* Fix recursive calls.
diff --git a/gcc/collect2.c b/gcc/collect2.c
index 7c8fde6a4c0..cc1ac32802d 100644
--- a/gcc/collect2.c
+++ b/gcc/collect2.c
@@ -1606,7 +1606,7 @@ static void
maybe_unlink (const char *file)
{
if (!debug)
- unlink (file);
+ unlink_if_ordinary (file);
else
notice ("[Leaving %s]\n", file);
}
diff --git a/gcc/common.opt b/gcc/common.opt
index 29251db3572..2a8665d29a7 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -492,6 +492,10 @@ fivopts
Common Report Var(flag_ivopts) Init(1)
Optimize induction variables on trees
+fjump-tables
+Common Var(flag_jump_tables) Init(1)
+Use jump tables for sufficiently large switch statements
+
fkeep-inline-functions
Common Report Var(flag_keep_inline_functions)
Generate code for functions even if they are fully inlined
diff --git a/gcc/config.gcc b/gcc/config.gcc
index ea3a49c871c..a379fca6042 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -1581,6 +1581,9 @@ powerpc64-*-linux*)
test x$with_cpu != x || cpu_is_64bit=yes
test x$cpu_is_64bit != xyes || tm_file="${tm_file} rs6000/default64.h"
tm_file="rs6000/biarch64.h ${tm_file} rs6000/linux64.h"
+ if test x${enable_secureplt} = xyes; then
+ tm_file="rs6000/secureplt.h ${tm_file}"
+ fi
extra_options="${extra_options} rs6000/sysv4.opt rs6000/linux64.opt"
tmake_file="rs6000/t-fprules ${tmake_file} rs6000/t-ppccomm rs6000/t-linux64"
;;
@@ -1690,6 +1693,9 @@ powerpc-*-linux*)
tm_file="${tm_file} rs6000/linux.h"
;;
esac
+ if test x${enable_secureplt} = xyes; then
+ tm_file="rs6000/secureplt.h ${tm_file}"
+ fi
;;
powerpc-*-gnu-gnualtivec*)
tm_file="${cpu_type}/${cpu_type}.h elfos.h svr4.h freebsd-spec.h gnu.h rs6000/sysv4.h rs6000/linux.h rs6000/linuxaltivec.h rs6000/gnu.h"
diff --git a/gcc/config.in b/gcc/config.in
index 44158812b6e..6221762435f 100644
--- a/gcc/config.in
+++ b/gcc/config.in
@@ -185,6 +185,12 @@
#endif
+/* Define if your assembler supports the lituse_jsrdirect relocation. */
+#ifndef USED_FOR_TARGET
+#undef HAVE_AS_JSRDIRECT_RELOCS
+#endif
+
+
/* Define if your assembler supports .sleb128 and .uleb128. */
#ifndef USED_FOR_TARGET
#undef HAVE_AS_LEB128
@@ -227,6 +233,12 @@
#endif
+/* Define if your assembler supports R_PPC_REL16 relocs. */
+#ifndef USED_FOR_TARGET
+#undef HAVE_AS_REL16
+#endif
+
+
/* Define if your assembler supports -relax option. */
#ifndef USED_FOR_TARGET
#undef HAVE_AS_RELAX_OPTION
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
index 56e08c5339a..908165a7523 100644
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -79,19 +79,6 @@ enum alpha_fp_rounding_mode alpha_fprm;
enum alpha_fp_trap_mode alpha_fptm;
-/* Specify bit size of immediate TLS offsets. */
-
-int alpha_tls_size = 32;
-
-/* Strings decoded into the above options. */
-
-static const char *alpha_cpu_string; /* -mcpu= */
-static const char *alpha_tune_string; /* -mtune= */
-static const char *alpha_tp_string; /* -mtrap-precision=[p|s|i] */
-static const char *alpha_fprm_string; /* -mfp-rounding-mode=[n|m|c|d] */
-static const char *alpha_fptm_string; /* -mfp-trap-mode=[n|u|su|sui] */
-static const char *alpha_mlat_string; /* -mmemory-latency= */
-
/* Save information from a "cmpxx" operation until the branch or scc is
emitted. */
@@ -239,38 +226,8 @@ alpha_handle_option (size_t code, const char *arg, int value)
target_flags |= MASK_IEEE_CONFORMANT;
break;
- case OPT_mcpu_:
- alpha_cpu_string = arg;
- break;
-
- case OPT_mtune_:
- alpha_tune_string = arg;
- break;
-
- case OPT_mfp_rounding_mode_:
- alpha_fprm_string = arg;
- break;
-
- case OPT_mfp_trap_mode_:
- alpha_fptm_string = arg;
- break;
-
- case OPT_mtrap_precision_:
- alpha_tp_string = arg;
- break;
-
- case OPT_mmemory_latency_:
- alpha_mlat_string = arg;
- break;
-
case OPT_mtls_size_:
- if (strcmp (arg, "16") == 0)
- alpha_tls_size = 16;
- else if (strcmp (arg, "32") == 0)
- alpha_tls_size = 32;
- else if (strcmp (arg, "64") == 0)
- alpha_tls_size = 64;
- else
+ if (value != 16 && value != 32 && value != 64)
error ("bad value %qs for -mtls-size switch", arg);
break;
}
@@ -4964,6 +4921,20 @@ print_operand (FILE *file, rtx x, int code)
}
break;
+ case 'j':
+ {
+ const char *lituse;
+
+#ifdef HAVE_AS_JSRDIRECT_RELOCS
+ lituse = "lituse_jsrdirect";
+#else
+ lituse = "lituse_jsr";
+#endif
+
+ gcc_assert (INTVAL (x) != 0);
+ fprintf (file, "\t\t!%s!%d", lituse, (int) INTVAL (x));
+ }
+ break;
case 'r':
/* If this operand is the constant zero, write it as "$31". */
if (GET_CODE (x) == REG)
diff --git a/gcc/config/alpha/alpha.h b/gcc/config/alpha/alpha.h
index 8d2974574a1..68508220658 100644
--- a/gcc/config/alpha/alpha.h
+++ b/gcc/config/alpha/alpha.h
@@ -152,7 +152,6 @@ extern int target_flags;
extern enum alpha_trap_precision alpha_tp;
extern enum alpha_fp_rounding_mode alpha_fprm;
extern enum alpha_fp_trap_mode alpha_fptm;
-extern int alpha_tls_size;
/* Invert the easy way to make options work. */
#define TARGET_FP (!TARGET_SOFT_FP)
diff --git a/gcc/config/alpha/alpha.md b/gcc/config/alpha/alpha.md
index def77b4efee..efb6d02f8e4 100644
--- a/gcc/config/alpha/alpha.md
+++ b/gcc/config/alpha/alpha.md
@@ -978,7 +978,7 @@
(clobber (reg:DI 23))
(clobber (reg:DI 28))]
"TARGET_EXPLICIT_RELOCS && ! TARGET_ABI_OPEN_VMS"
- "ldq $27,__%E3($29)\t\t!literal!%#\;jsr $23,($27),__%E3\t\t!lituse_jsr!%#"
+ "#"
"&& reload_completed"
[(parallel [(set (match_dup 0)
(sign_extend:DI (match_dup 3)))
@@ -1023,7 +1023,7 @@
(clobber (reg:DI 23))
(clobber (reg:DI 28))]
"TARGET_EXPLICIT_RELOCS && ! TARGET_ABI_OPEN_VMS"
- "jsr $23,($27),__%E3%J5"
+ "jsr $23,($27),__%E3%j5"
[(set_attr "type" "jsr")
(set_attr "length" "4")])
@@ -1047,7 +1047,7 @@
(clobber (reg:DI 23))
(clobber (reg:DI 28))]
"TARGET_EXPLICIT_RELOCS && ! TARGET_ABI_OPEN_VMS"
- "ldq $27,__%E3($29)\t\t!literal!%#\;jsr $23,($27),__%E3\t\t!lituse_jsr!%#"
+ "#"
"&& reload_completed"
[(parallel [(set (match_dup 0) (match_dup 3))
(use (match_dup 0))
@@ -1091,7 +1091,7 @@
(clobber (reg:DI 23))
(clobber (reg:DI 28))]
"TARGET_EXPLICIT_RELOCS && ! TARGET_ABI_OPEN_VMS"
- "jsr $23,($27),__%E3%J5"
+ "jsr $23,($27),__%E3%j5"
[(set_attr "type" "jsr")
(set_attr "length" "4")])
diff --git a/gcc/config/alpha/alpha.opt b/gcc/config/alpha/alpha.opt
index 0c6ca3c302e..d3bc9044461 100644
--- a/gcc/config/alpha/alpha.opt
+++ b/gcc/config/alpha/alpha.opt
@@ -107,29 +107,29 @@ Target Report RejectNegative InverseMask(LONG_DOUBLE_128)
Use 64-bit long double
mcpu=
-Target RejectNegative Joined
+Target RejectNegative Joined Var(alpha_cpu_string)
Use features of and schedule given CPU
mtune=
-Target RejectNegative Joined
+Target RejectNegative Joined Var(alpha_tune_string)
Schedule given CPU
mfp-rounding-mode=
-Target RejectNegative Joined
+Target RejectNegative Joined Var(alpha_fprm_string)
Control the generated fp rounding mode
mfp-trap-mode=
-Target RejectNegative Joined
+Target RejectNegative Joined Var(alpha_fptm_string)
Control the IEEE trap mode
mtrap-precision=
-Target RejectNegative Joined
+Target RejectNegative Joined Var(alpha_tp_string)
Control the precision given to fp exceptions
mmemory-latency=
-Target RejectNegative Joined
+Target RejectNegative Joined Var(alpha_mlat_string)
Tune expected memory latency
mtls-size=
-Target RejectNegative Joined
+Target RejectNegative Joined UInteger Var(alpha_tls_size) Init(32)
Specify bit size of immediate TLS offsets
diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index 2161817ca95..1a7024530a3 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -45,7 +45,6 @@ Boston, MA 02111-1307, USA. */
#include "target-def.h"
/* Which cpu we're compiling for. */
-static const char *arc_cpu_string = "base";
int arc_cpu_type;
/* Name of mangle string to add to symbols to separate code compiled for each
@@ -56,12 +55,6 @@ const char *arc_mangle_cpu;
generate a scc or bcc insn. */
rtx arc_compare_op0, arc_compare_op1;
-/* Name of text, data, and rodata sections, as specified on command line.
- Selected by -m{text,data,rodata} flags. */
-static const char *arc_text_string = ARC_DEFAULT_TEXT_SECTION;
-static const char *arc_data_string = ARC_DEFAULT_DATA_SECTION;
-static const char *arc_rodata_string = ARC_DEFAULT_RODATA_SECTION;
-
/* Name of text, data, and rodata sections used in varasm.c. */
const char *arc_text_section;
const char *arc_data_section;
@@ -163,24 +156,7 @@ arc_handle_option (size_t code, const char *arg, int value ATTRIBUTE_UNUSED)
switch (code)
{
case OPT_mcpu_:
- if (strcmp (arg, "base") == 0 || ARC_EXTENSION_CPU (arg))
- {
- arc_cpu_string = arg;
- return true;
- }
- return false;
-
- case OPT_mtext_:
- arc_text_string = arg;
- return true;
-
- case OPT_mdata_:
- arc_data_string = arg;
- return true;
-
- case OPT_mrodata_:
- arc_rodata_string = arg;
- return true;
+ return strcmp (arg, "base") == 0 || ARC_EXTENSION_CPU (arg);
default:
return true;
diff --git a/gcc/config/arc/arc.opt b/gcc/config/arc/arc.opt
index ffb6b010b7b..919550a2878 100644
--- a/gcc/config/arc/arc.opt
+++ b/gcc/config/arc/arc.opt
@@ -39,17 +39,17 @@ mno-cond-exec
Target Undocumented Report RejectNegative Mask(NO_COND_EXEC)
mcpu=
-Target RejectNegative Joined
+Target RejectNegative Joined Var(arc_cpu_string) Init("base")
-mcpu=CPU Compile code for ARC variant CPU
mtext=
-Target RejectNegative Joined
+Target RejectNegative Joined Var(arc_text_string) Init(ARC_DEFAULT_TEXT_SECTION)
-mtext=SECTION Put functions in SECTION
mdata=
-Target RejectNegative Joined
+Target RejectNegative Joined Var(arc_data_string) Init(ARC_DEFAULT_DATA_SECTION)
-mdata=SECTION Put data in SECTION
mrodata=
-Target RejectNegative Joined
+Target RejectNegative Joined Var(arc_rodata_string) Init(ARC_DEFAULT_RODATA_SECTION)
-mrodata=SECTION Put read-only data in SECTION
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index f2266c7c991..8924a490ff4 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -374,20 +374,7 @@ enum float_abi_type arm_float_abi;
/* Which ABI to use. */
enum arm_abi_type arm_abi;
-/* Set by the -mfpu=... option. */
-static const char * target_fpu_name = NULL;
-
-/* Set by the -mfpe=... option. */
-static const char * target_fpe_name = NULL;
-
-/* Set by the -mfloat-abi=... option. */
-static const char * target_float_abi_name = NULL;
-
-/* Set by the -mabi=... option. */
-static const char * target_abi_name = NULL;
-
/* Used to parse -mstructure_size_boundary command line option. */
-static const char * structure_size_string = NULL;
int arm_structure_size_boundary = DEFAULT_STRUCTURE_SIZE_BOUNDARY;
/* Used for Thumb call_via trampolines. */
@@ -498,7 +485,6 @@ int arm_cpp_interwork = 0;
enum machine_mode output_memory_reference_mode;
/* The register number to be used for the PIC offset register. */
-static const char * arm_pic_register_string = NULL;
int arm_pic_register = INVALID_REGNUM;
/* Set to 1 when a return insn is output, this means that the epilogue
@@ -801,10 +787,6 @@ arm_handle_option (size_t code, const char *arg, int value ATTRIBUTE_UNUSED)
{
switch (code)
{
- case OPT_mabi_:
- target_abi_name = arg;
- return true;
-
case OPT_march_:
arm_select[1].string = arg;
return true;
@@ -813,35 +795,14 @@ arm_handle_option (size_t code, const char *arg, int value ATTRIBUTE_UNUSED)
arm_select[0].string = arg;
return true;
- case OPT_mfloat_abi_:
- target_float_abi_name = arg;
- return true;
-
- case OPT_mfp_:
- case OPT_mfpe_:
- target_fpe_name = arg;
- return true;
-
- case OPT_mfpu_:
- target_fpu_name = arg;
- return true;
-
case OPT_mhard_float:
target_float_abi_name = "hard";
return true;
- case OPT_mpic_register_:
- arm_pic_register_string = arg;
- return true;
-
case OPT_msoft_float:
target_float_abi_name = "soft";
return true;
- case OPT_mstructure_size_boundary_:
- structure_size_string = arg;
- return true;
-
case OPT_mtune_:
arm_select[2].string = arg;
return true;
@@ -7015,7 +6976,7 @@ add_minipool_forward_ref (Mfix *fix)
/* If this fix's address is greater than the address of the first
entry, then we can't put the fix in this pool. We subtract the
size of the current fix to ensure that if the table is fully
- packed we still have enough room to insert this value by suffling
+ packed we still have enough room to insert this value by shuffling
the other fixes forwards. */
if (minipool_vector_head &&
fix->address >= minipool_vector_head->max_address - fix->fix_size)
@@ -13531,7 +13492,7 @@ thumb_output_function_prologue (FILE *f, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
asm_fprintf (f, "\tmov\t%r, %r\t\t%@ Backtrace structure created\n",
ARM_HARD_FRAME_POINTER_REGNUM, work_register);
}
- /* Optimisation: If we are not pushing any low registers but we are going
+ /* Optimization: If we are not pushing any low registers but we are going
to push some high registers then delay our first push. This will just
be a push of LR and we can combine it with the push of the first high
register. */
@@ -14475,7 +14436,7 @@ arm_cxx_guard_type (void)
}
-/* The EABI says test the least significan bit of a guard variable. */
+/* The EABI says test the least significant bit of a guard variable. */
static bool
arm_cxx_guard_mask_bit (void)
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 5c7da904a88..2aadfea671b 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -202,10 +202,14 @@
; even on a machine with an fpa.
; f_load a floating point load from memory
; f_store a floating point store to memory
+; f_load[sd] single/double load from memory
+; f_store[sd] single/double store to memory
+; f_flag a transfer of co-processor flags to the CPSR
; f_mem_r a transfer of a floating point register to a real reg via mem
; r_mem_f the reverse of f_mem_r
; f_2_r fast transfer float to arm (no memory needed)
; r_2_f fast transfer arm to float
+; f_cvt convert floating<->integral
; branch a branch
; call a subroutine call
; load_byte load byte(s) from memory to arm registers
@@ -222,7 +226,7 @@
; mav_dmult Double multiplies (7 cycle)
;
(define_attr "type"
- "alu,alu_shift,alu_shift_reg,mult,block,float,fdivx,fdivd,fdivs,fmul,ffmul,farith,ffarith,float_em,f_load,f_store,f_mem_r,r_mem_f,f_2_r,r_2_f,branch,call,load_byte,load1,load2,load3,load4,store1,store2,store3,store4,mav_farith,mav_dmult"
+ "alu,alu_shift,alu_shift_reg,mult,block,float,fdivx,fdivd,fdivs,fmul,ffmul,farith,ffarith,f_flag,float_em,f_load,f_store,f_loads,f_loadd,f_stores,f_stored,f_mem_r,r_mem_f,f_2_r,r_2_f,f_cvt,branch,call,load_byte,load1,load2,load3,load4,store1,store2,store3,store4,mav_farith,mav_dmult"
(if_then_else
(eq_attr "insn" "smulxy,smlaxy,smlalxy,smulwy,smlawx,mul,muls,mla,mlas,umull,umulls,umlal,umlals,smull,smulls,smlal,smlals")
(const_string "mult")
@@ -313,12 +317,20 @@
(define_attr "generic_sched" "yes,no"
(const (if_then_else
- (eq_attr "tune" "arm926ejs,arm1026ejs,arm1136js,arm1136jfs")
+ (eq_attr "tune" "arm926ejs,arm1020e,arm1026ejs,arm1136js,arm1136jfs")
(const_string "no")
(const_string "yes"))))
+(define_attr "generic_vfp" "yes,no"
+ (const (if_then_else
+ (and (eq_attr "fpu" "vfp")
+ (eq_attr "tune" "!arm1020e,arm1022e"))
+ (const_string "yes")
+ (const_string "no"))))
+
(include "arm-generic.md")
(include "arm926ejs.md")
+(include "arm1020e.md")
(include "arm1026ejs.md")
(include "arm1136jfs.md")
@@ -6963,7 +6975,7 @@
(if_then_else (unordered (match_dup 1) (const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))]
- "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
+ "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
"operands[1] = arm_gen_compare_reg (UNORDERED, arm_compare_op0,
arm_compare_op1);"
)
@@ -6973,7 +6985,7 @@
(if_then_else (ordered (match_dup 1) (const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))]
- "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
+ "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
"operands[1] = arm_gen_compare_reg (ORDERED, arm_compare_op0,
arm_compare_op1);"
)
@@ -6983,7 +6995,7 @@
(if_then_else (ungt (match_dup 1) (const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))]
- "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
+ "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
"operands[1] = arm_gen_compare_reg (UNGT, arm_compare_op0, arm_compare_op1);"
)
@@ -6992,7 +7004,7 @@
(if_then_else (unlt (match_dup 1) (const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))]
- "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
+ "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
"operands[1] = arm_gen_compare_reg (UNLT, arm_compare_op0, arm_compare_op1);"
)
@@ -7001,7 +7013,7 @@
(if_then_else (unge (match_dup 1) (const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))]
- "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
+ "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
"operands[1] = arm_gen_compare_reg (UNGE, arm_compare_op0, arm_compare_op1);"
)
@@ -7010,7 +7022,7 @@
(if_then_else (unle (match_dup 1) (const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))]
- "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
+ "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
"operands[1] = arm_gen_compare_reg (UNLE, arm_compare_op0, arm_compare_op1);"
)
@@ -7021,7 +7033,7 @@
(if_then_else (uneq (match_dup 1) (const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))]
- "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
+ "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
"operands[1] = arm_gen_compare_reg (UNEQ, arm_compare_op0, arm_compare_op1);"
)
@@ -7030,7 +7042,7 @@
(if_then_else (ltgt (match_dup 1) (const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))]
- "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
+ "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
"operands[1] = arm_gen_compare_reg (LTGT, arm_compare_op0, arm_compare_op1);"
)
@@ -7044,7 +7056,7 @@
(if_then_else (uneq (match_operand 1 "cc_register" "") (const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))]
- "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
+ "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
"*
gcc_assert (!arm_ccfsm_state);
@@ -7060,7 +7072,7 @@
(if_then_else (ltgt (match_operand 1 "cc_register" "") (const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))]
- "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
+ "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
"*
gcc_assert (!arm_ccfsm_state);
@@ -7095,7 +7107,7 @@
(if_then_else (uneq (match_operand 1 "cc_register" "") (const_int 0))
(pc)
(label_ref (match_operand 0 "" ""))))]
- "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
+ "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
"*
gcc_assert (!arm_ccfsm_state);
@@ -7111,7 +7123,7 @@
(if_then_else (ltgt (match_operand 1 "cc_register" "") (const_int 0))
(pc)
(label_ref (match_operand 0 "" ""))))]
- "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
+ "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
"*
gcc_assert (!arm_ccfsm_state);
@@ -7217,7 +7229,7 @@
(define_expand "sunordered"
[(set (match_operand:SI 0 "s_register_operand" "")
(unordered:SI (match_dup 1) (const_int 0)))]
- "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
+ "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
"operands[1] = arm_gen_compare_reg (UNORDERED, arm_compare_op0,
arm_compare_op1);"
)
@@ -7225,7 +7237,7 @@
(define_expand "sordered"
[(set (match_operand:SI 0 "s_register_operand" "")
(ordered:SI (match_dup 1) (const_int 0)))]
- "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
+ "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
"operands[1] = arm_gen_compare_reg (ORDERED, arm_compare_op0,
arm_compare_op1);"
)
@@ -7233,7 +7245,7 @@
(define_expand "sungt"
[(set (match_operand:SI 0 "s_register_operand" "")
(ungt:SI (match_dup 1) (const_int 0)))]
- "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
+ "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
"operands[1] = arm_gen_compare_reg (UNGT, arm_compare_op0,
arm_compare_op1);"
)
@@ -7241,7 +7253,7 @@
(define_expand "sunge"
[(set (match_operand:SI 0 "s_register_operand" "")
(unge:SI (match_dup 1) (const_int 0)))]
- "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
+ "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
"operands[1] = arm_gen_compare_reg (UNGE, arm_compare_op0,
arm_compare_op1);"
)
@@ -7249,7 +7261,7 @@
(define_expand "sunlt"
[(set (match_operand:SI 0 "s_register_operand" "")
(unlt:SI (match_dup 1) (const_int 0)))]
- "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
+ "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
"operands[1] = arm_gen_compare_reg (UNLT, arm_compare_op0,
arm_compare_op1);"
)
@@ -7257,7 +7269,7 @@
(define_expand "sunle"
[(set (match_operand:SI 0 "s_register_operand" "")
(unle:SI (match_dup 1) (const_int 0)))]
- "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
+ "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
"operands[1] = arm_gen_compare_reg (UNLE, arm_compare_op0,
arm_compare_op1);"
)
@@ -7268,14 +7280,14 @@
; (define_expand "suneq"
; [(set (match_operand:SI 0 "s_register_operand" "")
; (uneq:SI (match_dup 1) (const_int 0)))]
-; "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
+; "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
; "gcc_unreachable ();"
; )
;
; (define_expand "sltgt"
; [(set (match_operand:SI 0 "s_register_operand" "")
; (ltgt:SI (match_dup 1) (const_int 0)))]
-; "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
+; "TARGET_ARM && TARGET_HARD_FLOAT && (TARGET_FPA || TARGET_VFP)"
; "gcc_unreachable ();"
; )
diff --git a/gcc/config/arm/arm.opt b/gcc/config/arm/arm.opt
index 28bec490e38..d03679a2d66 100644
--- a/gcc/config/arm/arm.opt
+++ b/gcc/config/arm/arm.opt
@@ -20,7 +20,7 @@
; 02111-1307, USA.
mabi=
-Target RejectNegative Joined
+Target RejectNegative Joined Var(target_abi_name)
Specify an ABI
mabort-on-noreturn
@@ -73,21 +73,21 @@ Target RejectNegative Joined
Specify the name of the target CPU
mfloat-abi=
-Target RejectNegative Joined
+Target RejectNegative Joined Var(target_float_abi_name)
Specify if floating point hardware should be used
mfp=
-Target RejectNegative Joined Undocumented
+Target RejectNegative Joined Undocumented Var(target_fpe_name) VarExists
;; Now ignored.
mfpe
Target RejectNegative Mask(FPE) Undocumented
mfpe=
-Target RejectNegative Joined Undocumented
+Target RejectNegative Joined Undocumented Var(target_fpe_name)
mfpu=
-Target RejectNegative Joined
+Target RejectNegative Joined Var(target_fpu_name)
Specify the name of the target floating point hardware/format
mhard-float
@@ -103,7 +103,7 @@ Target Report Mask(LONG_CALLS)
Generate call insns as indirect calls, if necessary
mpic-register=
-Target RejectNegative Joined
+Target RejectNegative Joined Var(arm_pic_register_string)
Specify the register to be used for PIC addressing
mpoke-function-name
@@ -123,7 +123,7 @@ Target RejectNegative
Alias for -mfloat-abi=soft
mstructure-size-boundary=
-Target RejectNegative Joined
+Target RejectNegative Joined Var(structure_size_string)
Specify the minimum bit alignment of structures
mthumb
diff --git a/gcc/config/arm/semi.h b/gcc/config/arm/semi.h
index 8a3587c91dd..840195f48a7 100644
--- a/gcc/config/arm/semi.h
+++ b/gcc/config/arm/semi.h
@@ -69,7 +69,7 @@
%{mcpu=*:-mcpu=%*} \
%{march=*:-march=%*} \
%{mapcs-float:-mfloat} \
-%{msoft-float:-mfloat-abi=soft} %{mhard-float:mfloat-abi=hard} \
+%{msoft-float:-mfloat-abi=soft} %{mhard-float:-mfloat-abi=hard} \
%{mfloat-abi=*} %{mfpu=*} \
%{mthumb-interwork:-mthumb-interwork} \
%(subtarget_extra_asm_spec)"
diff --git a/gcc/config/arm/t-arm b/gcc/config/arm/t-arm
index 21cab03cf6e..9fcd187865a 100644
--- a/gcc/config/arm/t-arm
+++ b/gcc/config/arm/t-arm
@@ -3,6 +3,7 @@
MD_INCLUDES= $(srcdir)/config/arm/arm-tune.md \
$(srcdir)/config/arm/predicates.md \
$(srcdir)/config/arm/arm-generic.md \
+ $(srcdir)/config/arm/arm1020e.md \
$(srcdir)/config/arm/arm1026ejs.md \
$(srcdir)/config/arm/arm1136jfs.md \
$(srcdir)/config/arm/arm926ejs.md \
diff --git a/gcc/config/arm/vfp.md b/gcc/config/arm/vfp.md
index c6ace731e66..443562b629e 100644
--- a/gcc/config/arm/vfp.md
+++ b/gcc/config/arm/vfp.md
@@ -55,53 +55,63 @@
(define_cpu_unit "vfp_ls" "vfp11")
+(define_cpu_unit "fmstat" "vfp11")
+
+(exclusion_set "fmac,ds" "fmstat")
+
;; The VFP "type" attributes differ from those used in the FPA model.
;; ffarith Fast floating point insns, e.g. abs, neg, cpy, cmp.
;; farith Most arithmetic insns.
;; fmul Double precision multiply.
;; fdivs Single precision sqrt or division.
;; fdivd Double precision sqrt or division.
-;; f_load Floating point load from memory.
-;; f_store Floating point store to memory.
+;; f_flag fmstat operation
+;; f_load[sd] Floating point load from memory.
+;; f_store[sd] Floating point store to memory.
;; f_2_r Transfer vfp to arm reg.
;; r_2_f Transfer arm to vfp reg.
+;; f_cvt Convert floating<->integral
(define_insn_reservation "vfp_ffarith" 4
- (and (eq_attr "fpu" "vfp")
+ (and (eq_attr "generic_vfp" "yes")
(eq_attr "type" "ffarith"))
"fmac")
(define_insn_reservation "vfp_farith" 8
- (and (eq_attr "fpu" "vfp")
- (eq_attr "type" "farith"))
+ (and (eq_attr "generic_vfp" "yes")
+ (eq_attr "type" "farith,f_cvt"))
"fmac")
(define_insn_reservation "vfp_fmul" 9
- (and (eq_attr "fpu" "vfp")
+ (and (eq_attr "generic_vfp" "yes")
(eq_attr "type" "fmul"))
"fmac*2")
(define_insn_reservation "vfp_fdivs" 19
- (and (eq_attr "fpu" "vfp")
+ (and (eq_attr "generic_vfp" "yes")
(eq_attr "type" "fdivs"))
"ds*15")
(define_insn_reservation "vfp_fdivd" 33
- (and (eq_attr "fpu" "vfp")
+ (and (eq_attr "generic_vfp" "yes")
(eq_attr "type" "fdivd"))
"fmac+ds*29")
;; Moves to/from arm regs also use the load/store pipeline.
(define_insn_reservation "vfp_fload" 4
- (and (eq_attr "fpu" "vfp")
- (eq_attr "type" "f_load,r_2_f"))
+ (and (eq_attr "generic_vfp" "yes")
+ (eq_attr "type" "f_loads,f_loadd,r_2_f"))
"vfp_ls")
(define_insn_reservation "vfp_fstore" 4
- (and (eq_attr "fpu" "vfp")
- (eq_attr "type" "f_load,f_2_r"))
+ (and (eq_attr "generic_vfp" "yes")
+ (eq_attr "type" "f_stores,f_stored,f_2_r"))
"vfp_ls")
+(define_insn_reservation "vfp_to_cpsr" 4
+ (and (eq_attr "generic_vfp" "yes")
+ (eq_attr "type" "f_flag"))
+ "fmstat,vfp_ls*3")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Insn pattern
@@ -127,7 +137,7 @@
flds%?\\t%0, %1\\t%@ int
fsts%?\\t%1, %0\\t%@ int"
[(set_attr "predicable" "yes")
- (set_attr "type" "*,*,load1,store1,r_2_f,f_2_r,ffarith,f_load,f_store")
+ (set_attr "type" "*,*,load1,store1,r_2_f,f_2_r,ffarith,f_loads,f_stores")
(set_attr "pool_range" "*,*,4096,*,*,*,*,1020,*")
(set_attr "neg_pool_range" "*,*,4084,*,*,*,*,1008,*")]
)
@@ -161,7 +171,7 @@
gcc_unreachable ();
}
"
- [(set_attr "type" "*,load2,store2,r_2_f,f_2_r,ffarith,f_load,f_store")
+ [(set_attr "type" "*,load2,store2,r_2_f,f_2_r,ffarith,f_loadd,f_stored")
(set_attr "length" "8,8,8,4,4,4,4,4")
(set_attr "pool_range" "*,1020,*,*,*,*,1020,*")
(set_attr "neg_pool_range" "*,1008,*,*,*,*,1008,*")]
@@ -186,7 +196,7 @@
fcpys%?\\t%0, %1
mov%?\\t%0, %1\\t%@ float"
[(set_attr "predicable" "yes")
- (set_attr "type" "r_2_f,f_2_r,ffarith,*,f_load,f_store,load1,store1")
+ (set_attr "type" "r_2_f,f_2_r,ffarith,*,f_loads,f_stores,load1,store1")
(set_attr "pool_range" "*,*,1020,*,4096,*,*,*")
(set_attr "neg_pool_range" "*,*,1008,*,4080,*,*,*")]
)
@@ -221,7 +231,7 @@
}
}
"
- [(set_attr "type" "r_2_f,f_2_r,ffarith,*,load2,store2,f_load,f_store")
+ [(set_attr "type" "r_2_f,f_2_r,ffarith,*,load2,store2,f_loadd,f_stored")
(set_attr "length" "4,4,8,8,4,4,4,8")
(set_attr "pool_range" "*,*,1020,*,1020,*,*,*")
(set_attr "neg_pool_range" "*,*,1008,*,1008,*,*,*")]
@@ -572,7 +582,7 @@
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
"fcvtds%?\\t%P0, %1"
[(set_attr "predicable" "yes")
- (set_attr "type" "farith")]
+ (set_attr "type" "f_cvt")]
)
(define_insn "*truncdfsf2_vfp"
@@ -581,7 +591,7 @@
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
"fcvtsd%?\\t%0, %P1"
[(set_attr "predicable" "yes")
- (set_attr "type" "farith")]
+ (set_attr "type" "f_cvt")]
)
(define_insn "*truncsisf2_vfp"
@@ -590,7 +600,7 @@
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
"ftosizs%?\\t%0, %1"
[(set_attr "predicable" "yes")
- (set_attr "type" "farith")]
+ (set_attr "type" "f_cvt")]
)
(define_insn "*truncsidf2_vfp"
@@ -599,7 +609,7 @@
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
"ftosizd%?\\t%0, %P1"
[(set_attr "predicable" "yes")
- (set_attr "type" "farith")]
+ (set_attr "type" "f_cvt")]
)
@@ -609,7 +619,7 @@
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
"ftouizs%?\\t%0, %1"
[(set_attr "predicable" "yes")
- (set_attr "type" "farith")]
+ (set_attr "type" "f_cvt")]
)
(define_insn "fixuns_truncdfsi2"
@@ -618,7 +628,7 @@
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
"ftouizd%?\\t%0, %P1"
[(set_attr "predicable" "yes")
- (set_attr "type" "farith")]
+ (set_attr "type" "f_cvt")]
)
@@ -628,7 +638,7 @@
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
"fsitos%?\\t%0, %1"
[(set_attr "predicable" "yes")
- (set_attr "type" "farith")]
+ (set_attr "type" "f_cvt")]
)
(define_insn "*floatsidf2_vfp"
@@ -637,7 +647,7 @@
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
"fsitod%?\\t%P0, %1"
[(set_attr "predicable" "yes")
- (set_attr "type" "farith")]
+ (set_attr "type" "f_cvt")]
)
@@ -647,7 +657,7 @@
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
"fuitos%?\\t%0, %1"
[(set_attr "predicable" "yes")
- (set_attr "type" "farith")]
+ (set_attr "type" "f_cvt")]
)
(define_insn "floatunssidf2"
@@ -656,7 +666,7 @@
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
"fuitod%?\\t%P0, %1"
[(set_attr "predicable" "yes")
- (set_attr "type" "farith")]
+ (set_attr "type" "f_cvt")]
)
@@ -689,7 +699,7 @@
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
"fmstat%?"
[(set_attr "conds" "set")
- (set_attr "type" "ffarith")]
+ (set_attr "type" "f_flag")]
)
(define_insn_and_split "*cmpsf_split_vfp"
@@ -813,7 +823,7 @@
UNSPEC_PUSH_MULT))])]
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
"* return vfp_output_fstmx (operands);"
- [(set_attr "type" "f_store")]
+ [(set_attr "type" "f_stored")]
)
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
index 45b51f24fb5..3de646b025d 100644
--- a/gcc/config/avr/avr.c
+++ b/gcc/config/avr/avr.c
@@ -48,7 +48,6 @@
/* Maximal allowed offset for an address in the LD command */
#define MAX_LD_OFFSET(MODE) (64 - (signed)GET_MODE_SIZE (MODE))
-static bool avr_handle_option (size_t, const char *, int);
static int avr_naked_function_p (tree);
static int interrupt_function_p (tree);
static int signal_function_p (tree);
@@ -111,12 +110,6 @@ static int epilogue_size;
/* Size of all jump tables in the current function, in words. */
static int jump_tables_size;
-/* Initial stack value specified by the `-minit-stack=' option */
-static const char *avr_init_stack = "__stack";
-
-/* Default MCU name */
-static const char *avr_mcu_name = "avr2";
-
/* Preprocessor macros to define depending on MCU type. */
const char *avr_base_arch_macro;
const char *avr_extra_arch_macro;
@@ -245,8 +238,6 @@ int avr_case_values_threshold = 30000;
#define TARGET_ATTRIBUTE_TABLE avr_attribute_table
#undef TARGET_ASM_FUNCTION_RODATA_SECTION
#define TARGET_ASM_FUNCTION_RODATA_SECTION default_no_function_rodata_section
-#undef TARGET_HANDLE_OPTION
-#define TARGET_HANDLE_OPTION avr_handle_option
#undef TARGET_INSERT_ATTRIBUTES
#define TARGET_INSERT_ATTRIBUTES avr_insert_attributes
#undef TARGET_SECTION_TYPE_FLAGS
@@ -266,26 +257,6 @@ int avr_case_values_threshold = 30000;
struct gcc_target targetm = TARGET_INITIALIZER;
-/* Implement TARGET_HANDLE_OPTION. */
-
-static bool
-avr_handle_option (size_t code, const char *arg, int value ATTRIBUTE_UNUSED)
-{
- switch (code)
- {
- case OPT_minit_stack_:
- avr_init_stack = arg;
- return true;
-
- case OPT_mmcu_:
- avr_mcu_name = arg;
- return true;
-
- default:
- return true;
- }
-}
-
void
avr_override_options (void)
{
diff --git a/gcc/config/avr/avr.opt b/gcc/config/avr/avr.opt
index 8d40f926907..303816a24e9 100644
--- a/gcc/config/avr/avr.opt
+++ b/gcc/config/avr/avr.opt
@@ -24,14 +24,14 @@ Target Report Mask(CALL_PROLOGUES)
Use subroutines for function prologues and epilogues
mmcu=
-Target RejectNegative Joined
+Target RejectNegative Joined Var(avr_mcu_name) Init("avr2")
-mmcu=MCU Select the target MCU
mdeb
Target Report Undocumented Mask(ALL_DEBUG)
minit-stack=
-Target RejectNegative Joined
+Target RejectNegative Joined Var(avr_init_stack) Init("__stack")
-minit-stack=STACK Use STACK as the initial value of the stack pointer
mint8
diff --git a/gcc/config/bfin/bfin.c b/gcc/config/bfin/bfin.c
index 8f3e0547457..da31338e4ba 100644
--- a/gcc/config/bfin/bfin.c
+++ b/gcc/config/bfin/bfin.c
@@ -67,8 +67,6 @@ const char *byte_reg_names[] = BYTE_REGISTER_NAMES;
static int arg_regs[] = FUNCTION_ARG_REGISTERS;
-/* The value passed to -mshared-library-id=. */
-static int bfin_library_id;
/* Nonzero if -mshared-library-id was given. */
static int bfin_lib_id_given;
@@ -1722,8 +1720,6 @@ bfin_handle_option (size_t code, const char *arg, int value)
if (value > MAX_LIBRARY_ID)
error ("-mshared-library-id=%s is not between 0 and %d",
arg, MAX_LIBRARY_ID);
- else
- bfin_library_id = value;
bfin_lib_id_given = 1;
return true;
@@ -2470,7 +2466,7 @@ bfin_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
which perform the memory reference, are allowed to execute before the
jump condition is evaluated.
Therefore, we must insert additional instructions in all places where this
- could lead to incorrect behaviour. The manual recommends CSYNC, while
+ could lead to incorrect behavior. The manual recommends CSYNC, while
VDSP seems to use NOPs (even though its corresponding compiler option is
named CSYNC).
diff --git a/gcc/config/bfin/bfin.opt b/gcc/config/bfin/bfin.opt
index 827947d5e6a..4aace2f7182 100644
--- a/gcc/config/bfin/bfin.opt
+++ b/gcc/config/bfin/bfin.opt
@@ -36,5 +36,5 @@ Target Report Mask(ID_SHARED_LIBRARY)
Enabled ID based shared library
mshared-library-id=
-Target RejectNegative Joined UInteger
+Target RejectNegative Joined UInteger Var(bfin_library_id)
ID of shared library to build
diff --git a/gcc/config/c4x/c4x.c b/gcc/config/c4x/c4x.c
index 119c7be80d8..110dfcc00aa 100644
--- a/gcc/config/c4x/c4x.c
+++ b/gcc/config/c4x/c4x.c
@@ -153,7 +153,6 @@ enum machine_mode c4x_caller_save_map[FIRST_PSEUDO_REGISTER] =
rtx c4x_compare_op0;
rtx c4x_compare_op1;
-int c4x_rpts_cycles = 0; /* Max. cycles for RPTS. */
int c4x_cpu_version = 40; /* CPU version C30/31/32/33/40/44. */
/* Pragma definitions. */
@@ -291,10 +290,6 @@ c4x_handle_option (size_t code, const char *arg, int value)
}
return false;
- case OPT_mrpts_:
- c4x_rpts_cycles = value;
- return true;
-
default:
return true;
}
diff --git a/gcc/config/c4x/c4x.h b/gcc/config/c4x/c4x.h
index 832ed8e4609..b9fd452b4ac 100644
--- a/gcc/config/c4x/c4x.h
+++ b/gcc/config/c4x/c4x.h
@@ -121,7 +121,6 @@
RPTS blocks interrupts. */
-extern int c4x_rpts_cycles; /* Max cycles for RPTS. */
extern int c4x_cpu_version; /* Cpu version C30/31/32/33/40/44. */
#define TARGET_INLINE (! optimize_size) /* Inline MPYI. */
diff --git a/gcc/config/c4x/c4x.opt b/gcc/config/c4x/c4x.opt
index a135e632fe4..43288463575 100644
--- a/gcc/config/c4x/c4x.opt
+++ b/gcc/config/c4x/c4x.opt
@@ -128,7 +128,7 @@ Target Report Mask(RPTS)
Enable use of RTPS instruction
mrpts=
-Target RejectNegative Joined UInteger
+Target RejectNegative Joined UInteger Var(c4x_rpts_cycles)
-mrpts=N Set the maximum number of iterations for RPTS to N
msmall
diff --git a/gcc/config/cris/aout.h b/gcc/config/cris/aout.h
index 0b6e61e3cf1..f39676cdaa5 100644
--- a/gcc/config/cris/aout.h
+++ b/gcc/config/cris/aout.h
@@ -94,10 +94,6 @@ Boston, MA 02111-1307, USA. */
+ MASK_ALIGN_BY_32); \
break; \
\
- case OPT_melinux_stacksize_: \
- cris_elinux_stacksize_str = (ARG); \
- break; \
- \
default: \
break; \
} \
diff --git a/gcc/config/cris/aout.opt b/gcc/config/cris/aout.opt
index f51dc2e68fc..b821d576fa0 100644
--- a/gcc/config/cris/aout.opt
+++ b/gcc/config/cris/aout.opt
@@ -27,6 +27,8 @@ melinux
Target Report RejectNegative
Compile for the MMU-less Etrax 100-based elinux system
+;; We don't parse it currently; it's just passed on to the linker.
+;; We might want to do something here someday.
melinux-stacksize=
-Target Report RejectNegative Joined
+Target Report RejectNegative Joined Var(cris_elinux_stacksize_str)
-melinux-stacksize=SIZE For elinux, request a specified stack-size for this program
diff --git a/gcc/config/cris/cris.c b/gcc/config/cris/cris.c
index 81e3ce6fb39..0bc8b8cf8aa 100644
--- a/gcc/config/cris/cris.c
+++ b/gcc/config/cris/cris.c
@@ -132,18 +132,6 @@ static tree cris_md_asm_clobbers (tree, tree, tree);
static bool cris_handle_option (size_t, const char *, int);
-/* This is the argument from the "-max-stack-stackframe=" option. */
-const char *cris_max_stackframe_str;
-
-/* This is the argument from the "-march=" option. */
-const char *cris_cpu_str;
-
-/* This is the argument from the "-mtune=" option. */
-const char *cris_tune_str;
-
-/* This is the argument from the "-melinux-stacksize=" option. */
-const char *cris_elinux_stacksize_str;
-
/* This is the parsed result of the "-max-stack-stackframe=" option. If
it (still) is zero, then there was no such option given. */
int cris_max_stackframe = 0;
@@ -2073,20 +2061,6 @@ cris_handle_option (size_t code, const char *arg, int value ATTRIBUTE_UNUSED)
+ MASK_DATA_ALIGN);
break;
- case OPT_max_stackframe_:
- case OPT_mmax_stackframe_:
- cris_max_stackframe_str = arg;
- break;
-
- case OPT_march_:
- case OPT_mcpu_:
- cris_cpu_str = arg;
- break;
-
- case OPT_mtune_:
- cris_tune_str = arg;
- break;
-
default:
break;
}
diff --git a/gcc/config/cris/cris.h b/gcc/config/cris/cris.h
index bdf48238016..4f998d05fa7 100644
--- a/gcc/config/cris/cris.h
+++ b/gcc/config/cris/cris.h
@@ -75,23 +75,9 @@ Boston, MA 02111-1307, USA. */
((MODE) != BLKmode ? GET_MODE_SIZE (MODE) \
: (unsigned) int_size_in_bytes (TYPE))
-/* Check for max allowed stackframe. A "const char *" to be parsed. */
-extern const char *cris_max_stackframe_str;
-
-/* Which CPU version this is. A "const char *" to be parsed. */
-extern const char *cris_cpu_str;
-
/* Which CPU version this is. The parsed and adjusted cris_cpu_str. */
extern int cris_cpu_version;
-/* Which CPU version to tune for. A "const char *" to be parsed. */
-extern const char *cris_tune_str;
-
-/* The argument to "-melinux-stacksize=". We don't parse it currently;
- it's just passed on to the linker. We might want to do something
- here someday. */
-extern const char *cris_elinux_stacksize_str;
-
/* Changing the order used to be necessary to put the fourth __make_dp
argument (a DImode parameter) in registers, to fit with the libfunc
parameter passing scheme used for intrinsic functions. FIXME: Check
diff --git a/gcc/config/cris/cris.opt b/gcc/config/cris/cris.opt
index 0aad8e7d14c..c828f61f3b0 100644
--- a/gcc/config/cris/cris.opt
+++ b/gcc/config/cris/cris.opt
@@ -159,22 +159,22 @@ Target Report RejectNegative
Override -mbest-lib-options
mcpu=
-Target Report RejectNegative Joined Undocumented
+Target Report RejectNegative Joined Undocumented Var(cris_cpu_str)
march=
-Target Report RejectNegative Joined
+Target Report RejectNegative Joined Var(cris_cpu_str) VarExists
-march=ARCH Generate code for the specified chip or CPU version
mtune=
-Target Report RejectNegative Joined
+Target Report RejectNegative Joined Var(cris_tune_str)
-mtune=ARCH Tune alignment for the specified chip or CPU version
mmax-stackframe=
-Target Report RejectNegative Joined
+Target Report RejectNegative Joined Var(cris_max_stackframe_str)
-mmax-stackframe=SIZE Warn when a stackframe is larger than the specified size
max-stackframe=
-Target Report RejectNegative Joined Undocumented
+Target Report RejectNegative Joined Undocumented Var(cris_max_stackframe_str) VarExists
; TARGET_SVINTO: Currently this just affects alignment. FIXME:
; Redundant with TARGET_ALIGN_BY_32, or put machine stuff here?
diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c
index 7b3289ffe49..c82c77b0047 100644
--- a/gcc/config/darwin.c
+++ b/gcc/config/darwin.c
@@ -43,7 +43,7 @@ Boston, MA 02111-1307, USA. */
#include "langhooks.h"
#include "target.h"
#include "tm_p.h"
-#include "errors.h"
+#include "toplev.h"
#include "hashtab.h"
/* Darwin supports a feature called fix-and-continue, which is used
diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h
index c2a53d0b45e..96a501a1e79 100644
--- a/gcc/config/darwin.h
+++ b/gcc/config/darwin.h
@@ -533,6 +533,8 @@ Boston, MA 02111-1307, USA. */
machopic_validate_stub_or_non_lazy_ptr (xname); \
else if (len > 14 && !strcmp ("$non_lazy_ptr", xname + len - 13)) \
machopic_validate_stub_or_non_lazy_ptr (xname); \
+ else if (len > 15 && !strcmp ("$non_lazy_ptr\"", xname + len - 14)) \
+ machopic_validate_stub_or_non_lazy_ptr (xname); \
if (xname[1] != '"' && name_needs_quotes (&xname[1])) \
fprintf (FILE, "\"%s\"", &xname[1]); \
else \
diff --git a/gcc/config/frv/frv.c b/gcc/config/frv/frv.c
index 679b0b433c8..cc9270c88bb 100644
--- a/gcc/config/frv/frv.c
+++ b/gcc/config/frv/frv.c
@@ -8197,7 +8197,7 @@ frv_int_to_acc (enum insn_code icode, int opnum, rtx opval)
rtx reg;
int i;
- /* ACCs and ACCGs are implicity global registers if media intrinsics
+ /* ACCs and ACCGs are implicit global registers if media intrinsics
are being used. We set up this lazily to avoid creating lots of
unnecessary call_insn rtl in non-media code. */
for (i = 0; i <= ACC_MASK; i++)
@@ -8292,7 +8292,7 @@ frv_read_iacc_argument (enum machine_mode mode, tree *arglistptr)
op = const0_rtx;
}
- /* IACCs are implicity global registers. We set up this lazily to
+ /* IACCs are implicit global registers. We set up this lazily to
avoid creating lots of unnecessary call_insn rtl when IACCs aren't
being used. */
regno = INTVAL (op) + IACC_FIRST;
@@ -8622,7 +8622,7 @@ frv_expand_mdpackh_builtin (tree arglist, rtx target)
op0 = gen_reg_rtx (DImode);
op1 = gen_reg_rtx (DImode);
- /* The high half of each word is not explicitly initialised, so indicate
+ /* The high half of each word is not explicitly initialized, so indicate
that the input operands are not live before this point. */
emit_insn (gen_rtx_CLOBBER (DImode, op0));
emit_insn (gen_rtx_CLOBBER (DImode, op1));
diff --git a/gcc/config/frv/frv.md b/gcc/config/frv/frv.md
index 2feb6c6a7b9..8514da2221a 100644
--- a/gcc/config/frv/frv.md
+++ b/gcc/config/frv/frv.md
@@ -1669,7 +1669,7 @@
;; Note - it is best to only have one movsi pattern and to handle
;; all the various contingencies by the use of alternatives. This
;; allows reload the greatest amount of flexibility (since reload will
-;; only choose amoungst alternatives for a selected insn, it will not
+;; only choose amongst alternatives for a selected insn, it will not
;; replace the insn with another one).
;; Unfortunately, we do have to separate out load-type moves from the rest,
diff --git a/gcc/config/i386/cygming.h b/gcc/config/i386/cygming.h
index 6b78909b5e3..4c63729cf10 100644
--- a/gcc/config/i386/cygming.h
+++ b/gcc/config/i386/cygming.h
@@ -403,6 +403,10 @@ extern int i386_pe_dllimport_name_p (const char *);
/* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */ \
{ "selectany", 0, 0, true, false, false, ix86_handle_selectany_attribute }
+/* mcount() does not need a counter variable. */
+#undef NO_PROFILE_COUNTERS
+#define NO_PROFILE_COUNTERS 1
+
#undef TREE
#ifndef BUFSIZ
diff --git a/gcc/config/i386/emmintrin.h b/gcc/config/i386/emmintrin.h
index 45624d20190..81a9b151134 100644
--- a/gcc/config/i386/emmintrin.h
+++ b/gcc/config/i386/emmintrin.h
@@ -51,14 +51,14 @@ typedef __v2df __m128d;
static __inline __m128d
_mm_set_sd (double __F)
{
- return (__m128d){ __F, 0 };
+ return __extension__ (__m128d){ __F, 0 };
}
/* Create a vector with both elements equal to F. */
static __inline __m128d
_mm_set1_pd (double __F)
{
- return (__m128d){ __F, __F };
+ return __extension__ (__m128d){ __F, __F };
}
static __inline __m128d
@@ -71,21 +71,21 @@ _mm_set_pd1 (double __F)
static __inline __m128d
_mm_set_pd (double __W, double __X)
{
- return (__m128d){ __X, __W };
+ return __extension__ (__m128d){ __X, __W };
}
/* Create a vector with the lower value W and upper value X. */
static __inline __m128d
_mm_setr_pd (double __W, double __X)
{
- return (__m128d){ __W, __X };
+ return __extension__ (__m128d){ __W, __X };
}
/* Create a vector of zeros. */
static __inline __m128d
_mm_setzero_pd (void)
{
- return (__m128d){ 0.0, 0.0 };
+ return __extension__ (__m128d){ 0.0, 0.0 };
}
/* Sets the low DPFP value of A from the low value of B. */
@@ -553,7 +553,7 @@ _mm_ucomineq_sd (__m128d __A, __m128d __B)
static __inline __m128i
_mm_set_epi64x (long long __q1, long long __q0)
{
- return (__m128i)(__v2di){ __q0, __q1 };
+ return __extension__ (__m128i)(__v2di){ __q0, __q1 };
}
static __inline __m128i
@@ -565,14 +565,15 @@ _mm_set_epi64 (__m64 __q1, __m64 __q0)
static __inline __m128i
_mm_set_epi32 (int __q3, int __q2, int __q1, int __q0)
{
- return (__m128i)(__v4si){ __q0, __q1, __q2, __q3 };
+ return __extension__ (__m128i)(__v4si){ __q0, __q1, __q2, __q3 };
}
static __inline __m128i
_mm_set_epi16 (short __q7, short __q6, short __q5, short __q4,
short __q3, short __q2, short __q1, short __q0)
{
- return (__m128i)(__v8hi){ __q0, __q1, __q2, __q3, __q4, __q5, __q6, __q7 };
+ return __extension__ (__m128i)(__v8hi){
+ __q0, __q1, __q2, __q3, __q4, __q5, __q6, __q7 };
}
static __inline __m128i
@@ -581,7 +582,7 @@ _mm_set_epi8 (char __q15, char __q14, char __q13, char __q12,
char __q07, char __q06, char __q05, char __q04,
char __q03, char __q02, char __q01, char __q00)
{
- return (__m128i)(__v16qi){
+ return __extension__ (__m128i)(__v16qi){
__q00, __q01, __q02, __q03, __q04, __q05, __q06, __q07,
__q08, __q09, __q10, __q11, __q12, __q13, __q14, __q15
};
@@ -712,7 +713,7 @@ _mm_move_epi64 (__m128i __A)
static __inline __m128i
_mm_setzero_si128 (void)
{
- return (__m128i)(__v4si){ 0, 0, 0, 0 };
+ return __extension__ (__m128i)(__v4si){ 0, 0, 0, 0 };
}
static __inline __m128d
@@ -1356,7 +1357,7 @@ _mm_stream_pd (double *__A, __m128d __B)
static __inline void
_mm_clflush (void const *__A)
{
- return __builtin_ia32_clflush (__A);
+ __builtin_ia32_clflush (__A);
}
static __inline void
@@ -1387,37 +1388,37 @@ _mm_cvtsi64x_si128 (long long __A)
/* Casts between various SP, DP, INT vector types. Note that these do no
conversion of values, they just change the type. */
-static inline __m128
+static __inline __m128
_mm_castpd_ps(__m128d __A)
{
return (__m128) __A;
}
-static inline __m128i
+static __inline __m128i
_mm_castpd_si128(__m128d __A)
{
return (__m128i) __A;
}
-static inline __m128d
+static __inline __m128d
_mm_castps_pd(__m128 __A)
{
return (__m128d) __A;
}
-static inline __m128i
+static __inline __m128i
_mm_castps_si128(__m128 __A)
{
return (__m128i) __A;
}
-static inline __m128
+static __inline __m128
_mm_castsi128_ps(__m128i __A)
{
return (__m128) __A;
}
-static inline __m128d
+static __inline __m128d
_mm_castsi128_pd(__m128i __A)
{
return (__m128d) __A;
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 43fcd2ef4e4..c63913b9e9d 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -787,15 +787,11 @@ struct ix86_frame
bool save_regs_using_mov;
};
-/* Code model option as passed by user. */
-static const char *ix86_cmodel_string;
-/* Parsed value. */
+/* Code model option. */
enum cmodel ix86_cmodel;
/* Asm dialect. */
-static const char *ix86_asm_string;
enum asm_dialect ix86_asm_dialect = ASM_ATT;
/* TLS dialext. */
-static const char *ix86_tls_dialect_string;
enum tls_dialect ix86_tls_dialect = TLS_DIALECT_GNU;
/* Which unit we are generating floating point math for. */
@@ -806,40 +802,17 @@ enum processor_type ix86_tune;
/* Which instruction set architecture to use. */
enum processor_type ix86_arch;
-/* Strings to hold which cpu and instruction set architecture to use. */
-const char *ix86_tune_string; /* for -mtune=<xxx> */
-const char *ix86_arch_string; /* for -march=<xxx> */
-static const char *ix86_fpmath_string; /* for -mfpmath=<xxx> */
-
-/* # of registers to use to pass arguments. */
-static const char *ix86_regparm_string;
-
/* true if sse prefetch instruction is not NOOP. */
int x86_prefetch_sse;
/* ix86_regparm_string as a number */
static int ix86_regparm;
-/* Alignment to use for loops and jumps: */
-
-/* Power of two alignment for loops. */
-static const char *ix86_align_loops_string;
-
-/* Power of two alignment for non-loop jumps. */
-static const char *ix86_align_jumps_string;
-
-/* Power of two alignment for stack boundary in bytes. */
-static const char *ix86_preferred_stack_boundary_string;
-
/* Preferred alignment for stack boundary in bits. */
unsigned int ix86_preferred_stack_boundary;
/* Values 1-5: see jump.c */
int ix86_branch_cost;
-static const char *ix86_branch_cost_string;
-
-/* Power of two alignment for functions. */
-static const char *ix86_align_funcs_string;
/* Prefix built by ASM_GENERATE_INTERNAL_LABEL. */
char internal_label_prefix[16];
@@ -1107,7 +1080,7 @@ struct gcc_target targetm = TARGET_INITIALIZER;
/* Implement TARGET_HANDLE_OPTION. */
static bool
-ix86_handle_option (size_t code, const char *arg, int value)
+ix86_handle_option (size_t code, const char *arg ATTRIBUTE_UNUSED, int value)
{
switch (code)
{
@@ -1119,38 +1092,6 @@ ix86_handle_option (size_t code, const char *arg, int value)
}
return true;
- case OPT_malign_functions_:
- ix86_align_funcs_string = arg;
- return true;
-
- case OPT_malign_jumps_:
- ix86_align_jumps_string = arg;
- return true;
-
- case OPT_malign_loops_:
- ix86_align_loops_string = arg;
- return true;
-
- case OPT_march_:
- ix86_arch_string = arg;
- return true;
-
- case OPT_masm_:
- ix86_asm_string = arg;
- return true;
-
- case OPT_mbranch_cost_:
- ix86_branch_cost_string = arg;
- return true;
-
- case OPT_mcmodel_:
- ix86_cmodel_string = arg;
- return true;
-
- case OPT_mfpmath_:
- ix86_fpmath_string = arg;
- return true;
-
case OPT_mmmx:
if (!value)
{
@@ -1159,14 +1100,6 @@ ix86_handle_option (size_t code, const char *arg, int value)
}
return true;
- case OPT_mpreferred_stack_boundary_:
- ix86_preferred_stack_boundary_string = arg;
- return true;
-
- case OPT_mregparm_:
- ix86_regparm_string = arg;
- return true;
-
case OPT_msse:
if (!value)
{
@@ -1183,14 +1116,6 @@ ix86_handle_option (size_t code, const char *arg, int value)
}
return true;
- case OPT_mtls_dialect_:
- ix86_tls_dialect_string = arg;
- return true;
-
- case OPT_mtune_:
- ix86_tune_string = arg;
- return true;
-
default:
return true;
}
@@ -1586,7 +1511,7 @@ override_options (void)
target_flags &= ~MASK_NO_FANCY_MATH_387;
/* Likewise, if the target doesn't have a 387, or we've specified
- software floating point, don't use 387 inline instrinsics. */
+ software floating point, don't use 387 inline intrinsics. */
if (!TARGET_80387)
target_flags |= MASK_NO_FANCY_MATH_387;
@@ -1922,7 +1847,7 @@ ix86_comp_type_attributes (tree type1, tree type2)
return 1;
}
-/* Return the regparm value for a fuctio with the indicated TYPE and DECL.
+/* Return the regparm value for a function with the indicated TYPE and DECL.
DECL may be NULL when calling function indirectly
or considering a libcall. */
@@ -15340,7 +15265,7 @@ ix86_cannot_change_mode_class (enum machine_mode from, enum machine_mode to,
if (from == to)
return false;
- /* x87 registers can't do subreg at all, as all values are reformated
+ /* x87 registers can't do subreg at all, as all values are reformatted
to extended precision. */
if (MAYBE_FLOAT_CLASS_P (class))
return true;
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index d65ce49a4c5..0a9df5a9ec4 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -2132,10 +2132,7 @@ enum processor_type
};
extern enum processor_type ix86_tune;
-extern const char *ix86_tune_string;
-
extern enum processor_type ix86_arch;
-extern const char *ix86_arch_string;
enum fpmath_unit
{
diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt
index 5571deebe4e..64337d49e46 100644
--- a/gcc/config/i386/i386.opt
+++ b/gcc/config/i386/i386.opt
@@ -60,15 +60,15 @@ Target Report Mask(ALIGN_DOUBLE)
Align some doubles on dword boundary
malign-functions=
-Target RejectNegative Joined
+Target RejectNegative Joined Var(ix86_align_funcs_string)
Function starts are aligned to this power of 2
malign-jumps=
-Target RejectNegative Joined
+Target RejectNegative Joined Var(ix86_align_jumps_string)
Jump targets are aligned to this power of 2
malign-loops=
-Target RejectNegative Joined
+Target RejectNegative Joined Var(ix86_align_loops_string)
Loop code aligned to this power of 2
malign-stringops
@@ -76,19 +76,19 @@ Target RejectNegative Report InverseMask(NO_ALIGN_STRINGOPS, ALIGN_STRINGOPS)
Align destination of the string operations
march=
-Target RejectNegative Joined
+Target RejectNegative Joined Var(ix86_arch_string)
Generate code for given CPU
masm=
-Target RejectNegative Joined
+Target RejectNegative Joined Var(ix86_asm_string)
Use given assembler dialect
mbranch-cost=
-Target RejectNegative Joined
+Target RejectNegative Joined Var(ix86_branch_cost_string)
Branches are this expensive (1-5, arbitrary units)
mcmodel=
-Target RejectNegative Joined
+Target RejectNegative Joined Var(ix86_cmodel_string)
Use given x86-64 code model
mdebug-addr
@@ -106,7 +106,7 @@ Target Report Mask(FLOAT_RETURNS)
Return values of functions in FPU registers
mfpmath=
-Target RejectNegative Joined
+Target RejectNegative Joined Var(ix86_fpmath_string)
Generate floating point mathematics using given instruction set
mhard-float
@@ -158,7 +158,7 @@ Target RejectNegative Undocumented
;; Deprecated
mpreferred-stack-boundary=
-Target RejectNegative Joined
+Target RejectNegative Joined Var(ix86_preferred_stack_boundary_string)
Attempt to keep stack aligned to this power of 2
mpush-args
@@ -170,7 +170,7 @@ Target RejectNegative Report InverseMask(NO_RED_ZONE, RED_ZONE)
Use red-zone in the x86-64 code
mregparm=
-Target RejectNegative Joined
+Target RejectNegative Joined Var(ix86_regparm_string)
Number of registers used to pass integer arguments
mrtd
@@ -202,7 +202,7 @@ Target Report Mask(STACK_PROBE)
Enable stack probing
mtls-dialect=
-Target RejectNegative Joined
+Target RejectNegative Joined Var(ix86_tls_dialect_string)
Use given thread-local storage dialect
mtls-direct-seg-refs
@@ -210,7 +210,7 @@ Target Report Mask(TLS_DIRECT_SEG_REFS)
Use direct references against %gs when accessing tls data
mtune=
-Target RejectNegative Joined
+Target RejectNegative Joined Var(ix86_tune_string)
Schedule code for given CPU
;; Support Athlon 3Dnow builtins
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index 4d664cec10b..48b6cde1692 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -1744,7 +1744,7 @@
(set_attr "mode" "V2DF")])
;; Also define scalar versions. These are used for abs, neg, and
-;; conditional move. Using subregs into vector modes causes regiser
+;; conditional move. Using subregs into vector modes causes register
;; allocation lossage. These patterns do not allow memory operands
;; because the native instructions read the full 128-bits.
diff --git a/gcc/config/i386/xmmintrin.h b/gcc/config/i386/xmmintrin.h
index a22b809085e..311ecba581f 100644
--- a/gcc/config/i386/xmmintrin.h
+++ b/gcc/config/i386/xmmintrin.h
@@ -90,7 +90,7 @@ enum _mm_hint
static __inline __m128
_mm_setzero_ps (void)
{
- return (__m128){ 0.0f, 0.0f, 0.0f, 0.0f };
+ return __extension__ (__m128){ 0.0f, 0.0f, 0.0f, 0.0f };
}
/* Perform the respective operation on the lower SPFP (single-precision
@@ -832,14 +832,14 @@ _MM_SET_FLUSH_ZERO_MODE (unsigned int __mode)
static __inline __m128
_mm_set_ss (float __F)
{
- return (__m128)(__v4sf){ __F, 0, 0, 0 };
+ return __extension__ (__m128)(__v4sf){ __F, 0, 0, 0 };
}
/* Create a vector with all four elements equal to F. */
static __inline __m128
_mm_set1_ps (float __F)
{
- return (__m128)(__v4sf){ __F, __F, __F, __F };
+ return __extension__ (__m128)(__v4sf){ __F, __F, __F, __F };
}
static __inline __m128
@@ -894,14 +894,14 @@ _mm_loadr_ps (float const *__P)
static __inline __m128
_mm_set_ps (const float __Z, const float __Y, const float __X, const float __W)
{
- return (__m128)(__v4sf){ __W, __X, __Y, __Z };
+ return __extension__ (__m128)(__v4sf){ __W, __X, __Y, __Z };
}
/* Create the vector [W X Y Z]. */
static __inline __m128
_mm_setr_ps (float __Z, float __Y, float __X, float __W)
{
- return (__m128)(__v4sf){ __Z, __Y, __X, __W };
+ return __extension__ (__m128)(__v4sf){ __Z, __Y, __X, __W };
}
/* Stores the lower SPFP value. */
diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c
index a52b7d850d4..7b20280b746 100644
--- a/gcc/config/ia64/ia64.c
+++ b/gcc/config/ia64/ia64.c
@@ -98,10 +98,6 @@ static const char * const ia64_local_reg_names[80] =
static const char * const ia64_output_reg_names[8] =
{ "out0", "out1", "out2", "out3", "out4", "out5", "out6", "out7" };
-/* Determines whether we use adds, addl, or movl to generate our
- TLS immediate offsets. */
-int ia64_tls_size = 22;
-
/* Which cpu are we scheduling for. */
enum processor_type ia64_tune = PROCESSOR_ITANIUM2;
@@ -4822,7 +4818,7 @@ fix_range (const char *const_str)
/* Implement TARGET_HANDLE_OPTION. */
static bool
-ia64_handle_option (size_t code, const char *arg, int value ATTRIBUTE_UNUSED)
+ia64_handle_option (size_t code, const char *arg, int value)
{
switch (code)
{
@@ -4831,15 +4827,9 @@ ia64_handle_option (size_t code, const char *arg, int value ATTRIBUTE_UNUSED)
return true;
case OPT_mtls_size_:
- {
- char *end;
- unsigned long tmp = strtoul (arg, &end, 10);
- if (*end || (tmp != 14 && tmp != 22 && tmp != 64))
- error ("bad value %<%s%> for -mtls-size= switch", arg);
- else
- ia64_tls_size = tmp;
- return true;
- }
+ if (value != 14 && value != 22 && value != 64)
+ error ("bad value %<%s%> for -mtls-size= switch", arg);
+ return true;
case OPT_mtune_:
{
@@ -4875,7 +4865,7 @@ ia64_handle_option (size_t code, const char *arg, int value ATTRIBUTE_UNUSED)
}
}
-/* Handle TARGET_OPTIONS switches. */
+/* Implement OVERRIDE_OPTIONS. */
void
ia64_override_options (void)
diff --git a/gcc/config/ia64/ia64.h b/gcc/config/ia64/ia64.h
index bd32069b171..28a8637defd 100644
--- a/gcc/config/ia64/ia64.h
+++ b/gcc/config/ia64/ia64.h
@@ -67,7 +67,6 @@ extern unsigned int ia64_section_threshold;
#define TARGET_HAVE_TLS true
#endif
-extern int ia64_tls_size;
#define TARGET_TLS14 (ia64_tls_size == 14)
#define TARGET_TLS22 (ia64_tls_size == 22)
#define TARGET_TLS64 (ia64_tls_size == 64)
diff --git a/gcc/config/ia64/ia64.opt b/gcc/config/ia64/ia64.opt
index f3790ad1012..25a2cc6a91b 100644
--- a/gcc/config/ia64/ia64.opt
+++ b/gcc/config/ia64/ia64.opt
@@ -89,7 +89,7 @@ Target RejectNegative Joined
Specify range of registers to make fixed
mtls-size=
-Target RejectNegative Joined
+Target RejectNegative Joined UInteger Var(ia64_tls_size) Init(22)
Specify bit size of immediate TLS offsets
mtune=
diff --git a/gcc/config/m32r/m32r.c b/gcc/config/m32r/m32r.c
index c27b2441127..c6c682de97a 100644
--- a/gcc/config/m32r/m32r.c
+++ b/gcc/config/m32r/m32r.c
@@ -64,18 +64,6 @@ enum m32r_sdata m32r_sdata = M32R_SDATA_DEFAULT;
/* For string literals, etc. */
#define LIT_NAME_P(NAME) ((NAME)[0] == '*' && (NAME)[1] == '.')
-/* Cache-flush support. Cache-flush is used at trampoline.
- Default cache-flush is "trap 12".
- default cache-flush function is "_flush_cache" (CACHE_FLUSH_FUNC)
- default cache-flush trap-interrupt number is 12 (CACHE_FLUSH_TRAP)
- You can change how to generate code of cache-flush with following options.
- -mflush-func=FLUSH-FUNC-NAME
- -mno-flush-func (sets m32r_cache_flush_func to NULL)
- -mfluch-trap=TRAP-NUMBER
- -mno-flush-trap. (sets m32r_cache_flush_trap to -1). */
-const char *m32r_cache_flush_func = CACHE_FLUSH_FUNC;
-int m32r_cache_flush_trap = CACHE_FLUSH_TRAP;
-
/* Forward declaration. */
static bool m32r_handle_option (size_t, const char *, int);
static void init_reg_tables (void);
@@ -188,17 +176,12 @@ m32r_handle_option (size_t code, const char *arg, int value)
return false;
return true;
- case OPT_mflush_func_:
- m32r_cache_flush_func = arg;
- return true;
-
case OPT_mno_flush_func:
m32r_cache_flush_func = NULL;
return true;
case OPT_mflush_trap_:
- m32r_cache_flush_trap = value;
- return m32r_cache_flush_trap <= 15;
+ return value <= 15;
case OPT_mno_flush_trap:
m32r_cache_flush_trap = -1;
diff --git a/gcc/config/m32r/m32r.h b/gcc/config/m32r/m32r.h
index a83886f3cef..5747c4491e2 100644
--- a/gcc/config/m32r/m32r.h
+++ b/gcc/config/m32r/m32r.h
@@ -209,10 +209,6 @@
#define TARGET_CPU_DEFAULT 0
#endif
-/* Cache-flush support. */
-extern const char * m32r_cache_flush_func;
-extern int m32r_cache_flush_trap;
-
/* Code Models
Code models are used to select between two choices of two separate
diff --git a/gcc/config/m32r/m32r.opt b/gcc/config/m32r/m32r.opt
index 73287852bb5..85fb8ede1da 100644
--- a/gcc/config/m32r/m32r.opt
+++ b/gcc/config/m32r/m32r.opt
@@ -48,11 +48,11 @@ Target Mask(DEBUG)
Display compile time statistics
mflush-func=
-Target RejectNegative Joined
+Target RejectNegative Joined Var(m32r_cache_flush_func) Init(CACHE_FLUSH_FUNC)
Specify cache flush function
mflush-trap=
-Target RejectNegative Joined UInteger
+Target RejectNegative Joined UInteger Var(m32r_cache_flush_trap) Init(CACHE_FLUSH_TRAP)
Specify cache flush trap number
missue-rate=1
diff --git a/gcc/config/m68hc11/m68hc11.c b/gcc/config/m68hc11/m68hc11.c
index fca34d27e2f..30f2ff9e740 100644
--- a/gcc/config/m68hc11/m68hc11.c
+++ b/gcc/config/m68hc11/m68hc11.c
@@ -5018,7 +5018,7 @@ m68hc11_reorg (void)
replacement, unshare everything. */
unshare_all_rtl_again (first);
- /* Force a split of all splitable insn. This is necessary for the
+ /* Force a split of all splittable insn. This is necessary for the
Z register replacement mechanism because we end up with basic insns. */
split_all_insns_noflow ();
split_done = 1;
diff --git a/gcc/config/m68hc11/m68hc11.h b/gcc/config/m68hc11/m68hc11.h
index bdbe31ef66f..7ec76bf7cbd 100644
--- a/gcc/config/m68hc11/m68hc11.h
+++ b/gcc/config/m68hc11/m68hc11.h
@@ -450,7 +450,7 @@ SOFT_REG_FIRST+28, SOFT_REG_FIRST+29,SOFT_REG_FIRST+30,SOFT_REG_FIRST+31
For any two classes, it is very desirable that there be another
class that represents their union. */
-/* The M68hc11 has so fiew registers that it's not possible for GCC to
+/* The M68hc11 has so few registers that it's not possible for GCC to
do any register allocation without breaking. We extend the processor
registers by having soft registers. These registers are treated as
hard registers by GCC but they are located in memory and accessed by page0
diff --git a/gcc/config/m68k/m68k-none.h b/gcc/config/m68k/m68k-none.h
index 79463b84abc..378197d8308 100644
--- a/gcc/config/m68k/m68k-none.h
+++ b/gcc/config/m68k/m68k-none.h
@@ -86,8 +86,8 @@ Unrecognized value in TARGET_CPU_DEFAULT.
"
/* cc1/cc1plus always receives all the -m flags. If the specs strings above
- are consistent with the TARGET_OPTIONS flags in m68k.h, there should be no
- need for any further cc1/cc1plus specs. */
+ are consistent with the flags in m68k.opt, there should be no need for
+ any further cc1/cc1plus specs. */
#undef CC1_SPEC
#define CC1_SPEC ""
diff --git a/gcc/config/mcore/mcore.c b/gcc/config/mcore/mcore.c
index e07f2470b1a..a2c963aac8a 100644
--- a/gcc/config/mcore/mcore.c
+++ b/gcc/config/mcore/mcore.c
@@ -2117,7 +2117,7 @@ mcore_expand_epilog (void)
/* The MCORE cannot load a large constant into a register, constants have to
come from a pc relative load. The reference of a pc relative load
- instruction must be less than 1k infront of the instruction. This
+ instruction must be less than 1k in front of the instruction. This
means that we often have to dump a constant inside a function, and
generate code to branch around it.
diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h
index 8fa82a72e3b..89afa25f242 100644
--- a/gcc/config/mips/mips-protos.h
+++ b/gcc/config/mips/mips-protos.h
@@ -184,7 +184,7 @@ extern void mips_declare_common_object (FILE *, const char *,
const char *, unsigned HOST_WIDE_INT,
unsigned int, bool);
extern void mips_declare_object (FILE *, const char *, const char *,
- const char *, ...);
+ const char *, ...) ATTRIBUTE_PRINTF_4;
extern void mips_declare_object_name (FILE *, const char *, tree);
extern void mips_finish_declare_object (FILE *, tree, int, int);
@@ -222,5 +222,6 @@ extern rtx mips_prefetch_cookie (rtx, rtx);
extern void irix_asm_output_align (FILE *, unsigned);
extern const char *current_section_name (void);
extern unsigned int current_section_flags (void);
+extern bool mips_use_ins_ext_p (rtx, rtx, rtx);
#endif /* ! GCC_MIPS_PROTOS_H */
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 9faddde503d..155682aa624 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -549,21 +549,18 @@ int mips_isa;
/* Which ABI to use. */
int mips_abi = MIPS_ABI_DEFAULT;
+/* Cost information to use. */
+const struct mips_rtx_cost_data *mips_cost;
+
/* Whether we are generating mips16 hard float code. In mips16 mode
we always set TARGET_SOFT_FLOAT; this variable is nonzero if
-msoft-float was not specified by the user, which means that we
should arrange to call mips32 hard floating point code. */
int mips16_hard_float;
-/* The arguments passed to -march and -mtune. */
-static const char *mips_arch_string;
-static const char *mips_tune_string;
-
/* The architecture selected by -mipsN. */
static const struct mips_cpu_info *mips_isa_info;
-const char *mips_cache_flush_func = CACHE_FLUSH_FUNC;
-
/* If TRUE, we split addresses into their high and low parts in the RTL. */
int mips_split_addresses;
@@ -714,6 +711,224 @@ const struct mips_cpu_info mips_cpu_info_table[] = {
/* End marker */
{ 0, 0, 0 }
};
+
+/* Default costs. If these are used for a processor we should look
+ up the actual costs. */
+#define DEFAULT_COSTS COSTS_N_INSNS (6), /* fp_add */ \
+ COSTS_N_INSNS (7), /* fp_mult_sf */ \
+ COSTS_N_INSNS (8), /* fp_mult_df */ \
+ COSTS_N_INSNS (23), /* fp_div_sf */ \
+ COSTS_N_INSNS (36), /* fp_div_df */ \
+ COSTS_N_INSNS (10), /* int_mult_si */ \
+ COSTS_N_INSNS (10), /* int_mult_di */ \
+ COSTS_N_INSNS (69), /* int_div_si */ \
+ COSTS_N_INSNS (69), /* int_div_di */ \
+ 2, /* branch_cost */ \
+ 4 /* memory_latency */
+
+/* Need to replace these with the costs of calling the appropriate
+ libgcc routine. */
+#define SOFT_FP_COSTS COSTS_N_INSNS (256), /* fp_add */ \
+ COSTS_N_INSNS (256), /* fp_mult_sf */ \
+ COSTS_N_INSNS (256), /* fp_mult_df */ \
+ COSTS_N_INSNS (256), /* fp_div_sf */ \
+ COSTS_N_INSNS (256) /* fp_div_df */
+
+static struct mips_rtx_cost_data const mips_rtx_cost_data[PROCESSOR_MAX] =
+ {
+ { /* R3000 */
+ COSTS_N_INSNS (2), /* fp_add */
+ COSTS_N_INSNS (4), /* fp_mult_sf */
+ COSTS_N_INSNS (5), /* fp_mult_df */
+ COSTS_N_INSNS (12), /* fp_div_sf */
+ COSTS_N_INSNS (19), /* fp_div_df */
+ COSTS_N_INSNS (12), /* int_mult_si */
+ COSTS_N_INSNS (12), /* int_mult_di */
+ COSTS_N_INSNS (35), /* int_div_si */
+ COSTS_N_INSNS (35), /* int_div_di */
+ 1, /* branch_cost */
+ 4 /* memory_latency */
+
+ },
+ { /* 4KC */
+ DEFAULT_COSTS
+ },
+ { /* 4KP */
+ DEFAULT_COSTS
+ },
+ { /* 5KC */
+ DEFAULT_COSTS
+ },
+ { /* 20KC */
+ DEFAULT_COSTS
+ },
+ { /* 24k */
+ DEFAULT_COSTS
+ },
+ { /* 24kx */
+ DEFAULT_COSTS
+ },
+ { /* M4k */
+ DEFAULT_COSTS
+ },
+ { /* R3900 */
+ COSTS_N_INSNS (2), /* fp_add */
+ COSTS_N_INSNS (4), /* fp_mult_sf */
+ COSTS_N_INSNS (5), /* fp_mult_df */
+ COSTS_N_INSNS (12), /* fp_div_sf */
+ COSTS_N_INSNS (19), /* fp_div_df */
+ COSTS_N_INSNS (2), /* int_mult_si */
+ COSTS_N_INSNS (2), /* int_mult_di */
+ COSTS_N_INSNS (35), /* int_div_si */
+ COSTS_N_INSNS (35), /* int_div_di */
+ 1, /* branch_cost */
+ 4 /* memory_latency */
+ },
+ { /* R6000 */
+ COSTS_N_INSNS (3), /* fp_add */
+ COSTS_N_INSNS (5), /* fp_mult_sf */
+ COSTS_N_INSNS (6), /* fp_mult_df */
+ COSTS_N_INSNS (15), /* fp_div_sf */
+ COSTS_N_INSNS (16), /* fp_div_df */
+ COSTS_N_INSNS (17), /* int_mult_si */
+ COSTS_N_INSNS (17), /* int_mult_di */
+ COSTS_N_INSNS (38), /* int_div_si */
+ COSTS_N_INSNS (38), /* int_div_di */
+ 2, /* branch_cost */
+ 6 /* memory_latency */
+ },
+ { /* R4000 */
+ COSTS_N_INSNS (6), /* fp_add */
+ COSTS_N_INSNS (7), /* fp_mult_sf */
+ COSTS_N_INSNS (8), /* fp_mult_df */
+ COSTS_N_INSNS (23), /* fp_div_sf */
+ COSTS_N_INSNS (36), /* fp_div_df */
+ COSTS_N_INSNS (10), /* int_mult_si */
+ COSTS_N_INSNS (10), /* int_mult_di */
+ COSTS_N_INSNS (69), /* int_div_si */
+ COSTS_N_INSNS (69), /* int_div_di */
+ 2, /* branch_cost */
+ 6 /* memory_latency */
+ },
+ { /* R4100 */
+ DEFAULT_COSTS
+ },
+ { /* R4111 */
+ DEFAULT_COSTS
+ },
+ { /* R4120 */
+ DEFAULT_COSTS
+ },
+ { /* R4130 */
+ /* The only costs that appear to be updated here are
+ integer multiplication. */
+ SOFT_FP_COSTS,
+ COSTS_N_INSNS (4), /* int_mult_si */
+ COSTS_N_INSNS (6), /* int_mult_di */
+ COSTS_N_INSNS (69), /* int_div_si */
+ COSTS_N_INSNS (69), /* int_div_di */
+ 1, /* branch_cost */
+ 4 /* memory_latency */
+ },
+ { /* R4300 */
+ DEFAULT_COSTS
+ },
+ { /* R4600 */
+ DEFAULT_COSTS
+ },
+ { /* R4650 */
+ DEFAULT_COSTS
+ },
+ { /* R5000 */
+ COSTS_N_INSNS (6), /* fp_add */
+ COSTS_N_INSNS (4), /* fp_mult_sf */
+ COSTS_N_INSNS (5), /* fp_mult_df */
+ COSTS_N_INSNS (23), /* fp_div_sf */
+ COSTS_N_INSNS (36), /* fp_div_df */
+ COSTS_N_INSNS (5), /* int_mult_si */
+ COSTS_N_INSNS (5), /* int_mult_di */
+ COSTS_N_INSNS (36), /* int_div_si */
+ COSTS_N_INSNS (36), /* int_div_di */
+ 1, /* branch_cost */
+ 4 /* memory_latency */
+ },
+ { /* R5400 */
+ COSTS_N_INSNS (6), /* fp_add */
+ COSTS_N_INSNS (5), /* fp_mult_sf */
+ COSTS_N_INSNS (6), /* fp_mult_df */
+ COSTS_N_INSNS (30), /* fp_div_sf */
+ COSTS_N_INSNS (59), /* fp_div_df */
+ COSTS_N_INSNS (3), /* int_mult_si */
+ COSTS_N_INSNS (4), /* int_mult_di */
+ COSTS_N_INSNS (42), /* int_div_si */
+ COSTS_N_INSNS (74), /* int_div_di */
+ 1, /* branch_cost */
+ 4 /* memory_latency */
+ },
+ { /* R5500 */
+ COSTS_N_INSNS (6), /* fp_add */
+ COSTS_N_INSNS (5), /* fp_mult_sf */
+ COSTS_N_INSNS (6), /* fp_mult_df */
+ COSTS_N_INSNS (30), /* fp_div_sf */
+ COSTS_N_INSNS (59), /* fp_div_df */
+ COSTS_N_INSNS (5), /* int_mult_si */
+ COSTS_N_INSNS (9), /* int_mult_di */
+ COSTS_N_INSNS (42), /* int_div_si */
+ COSTS_N_INSNS (74), /* int_div_di */
+ 1, /* branch_cost */
+ 4 /* memory_latency */
+ },
+ { /* R7000 */
+ /* The only costs that are changed here are
+ integer multiplication. */
+ COSTS_N_INSNS (6), /* fp_add */
+ COSTS_N_INSNS (7), /* fp_mult_sf */
+ COSTS_N_INSNS (8), /* fp_mult_df */
+ COSTS_N_INSNS (23), /* fp_div_sf */
+ COSTS_N_INSNS (36), /* fp_div_df */
+ COSTS_N_INSNS (5), /* int_mult_si */
+ COSTS_N_INSNS (9), /* int_mult_di */
+ COSTS_N_INSNS (69), /* int_div_si */
+ COSTS_N_INSNS (69), /* int_div_di */
+ 1, /* branch_cost */
+ 4 /* memory_latency */
+ },
+ { /* R8000 */
+ DEFAULT_COSTS
+ },
+ { /* R9000 */
+ /* The only costs that are changed here are
+ integer multiplication. */
+ COSTS_N_INSNS (6), /* fp_add */
+ COSTS_N_INSNS (7), /* fp_mult_sf */
+ COSTS_N_INSNS (8), /* fp_mult_df */
+ COSTS_N_INSNS (23), /* fp_div_sf */
+ COSTS_N_INSNS (36), /* fp_div_df */
+ COSTS_N_INSNS (3), /* int_mult_si */
+ COSTS_N_INSNS (8), /* int_mult_di */
+ COSTS_N_INSNS (69), /* int_div_si */
+ COSTS_N_INSNS (69), /* int_div_di */
+ 1, /* branch_cost */
+ 4 /* memory_latency */
+ },
+ { /* SB1 */
+ COSTS_N_INSNS (4), /* fp_add */
+ COSTS_N_INSNS (4), /* fp_mult_sf */
+ COSTS_N_INSNS (4), /* fp_mult_df */
+ COSTS_N_INSNS (24), /* fp_div_sf */
+ COSTS_N_INSNS (32), /* fp_div_df */
+ COSTS_N_INSNS (3), /* int_mult_si */
+ COSTS_N_INSNS (4), /* int_mult_di */
+ COSTS_N_INSNS (36), /* int_div_si */
+ COSTS_N_INSNS (68), /* int_div_di */
+ 1, /* branch_cost */
+ 4 /* memory_latency */
+ },
+ { /* SR71000 */
+ DEFAULT_COSTS
+ },
+ };
+
/* Nonzero if -march should decide the default value of MASK_SOFT_FLOAT. */
#ifndef MIPS_MARCH_CONTROLS_SOFT_FLOAT
@@ -2090,75 +2305,81 @@ static bool
mips_rtx_costs (rtx x, int code, int outer_code, int *total)
{
enum machine_mode mode = GET_MODE (x);
+ bool float_mode_p = FLOAT_MODE_P (mode);
+
+ /* To be used for soft-float costs. */
+ int max_cost = COSTS_N_INSNS (256);
switch (code)
{
case CONST_INT:
- if (!TARGET_MIPS16)
- {
- /* Always return 0, since we don't have different sized
- instructions, hence different costs according to Richard
- Kenner */
- *total = 0;
- return true;
- }
-
- /* A number between 1 and 8 inclusive is efficient for a shift.
- Otherwise, we will need an extended instruction. */
- if ((outer_code) == ASHIFT || (outer_code) == ASHIFTRT
- || (outer_code) == LSHIFTRT)
+ if (TARGET_MIPS16)
{
- if (INTVAL (x) >= 1 && INTVAL (x) <= 8)
- *total = 0;
- else
- *total = COSTS_N_INSNS (1);
- return true;
- }
+ /* A number between 1 and 8 inclusive is efficient for a shift.
+ Otherwise, we will need an extended instruction. */
+ if ((outer_code) == ASHIFT || (outer_code) == ASHIFTRT
+ || (outer_code) == LSHIFTRT)
+ {
+ if (INTVAL (x) >= 1 && INTVAL (x) <= 8)
+ *total = 0;
+ else
+ *total = COSTS_N_INSNS (1);
+ return true;
+ }
- /* We can use cmpi for an xor with an unsigned 16 bit value. */
- if ((outer_code) == XOR
- && INTVAL (x) >= 0 && INTVAL (x) < 0x10000)
- {
- *total = 0;
- return true;
- }
+ /* We can use cmpi for an xor with an unsigned 16 bit value. */
+ if ((outer_code) == XOR
+ && INTVAL (x) >= 0 && INTVAL (x) < 0x10000)
+ {
+ *total = 0;
+ return true;
+ }
- /* We may be able to use slt or sltu for a comparison with a
- signed 16 bit value. (The boundary conditions aren't quite
- right, but this is just a heuristic anyhow.) */
- if (((outer_code) == LT || (outer_code) == LE
- || (outer_code) == GE || (outer_code) == GT
- || (outer_code) == LTU || (outer_code) == LEU
- || (outer_code) == GEU || (outer_code) == GTU)
- && INTVAL (x) >= -0x8000 && INTVAL (x) < 0x8000)
- {
- *total = 0;
- return true;
- }
+ /* We may be able to use slt or sltu for a comparison with a
+ signed 16 bit value. (The boundary conditions aren't quite
+ right, but this is just a heuristic anyhow.) */
+ if (((outer_code) == LT || (outer_code) == LE
+ || (outer_code) == GE || (outer_code) == GT
+ || (outer_code) == LTU || (outer_code) == LEU
+ || (outer_code) == GEU || (outer_code) == GTU)
+ && INTVAL (x) >= -0x8000 && INTVAL (x) < 0x8000)
+ {
+ *total = 0;
+ return true;
+ }
- /* Equality comparisons with 0 are cheap. */
- if (((outer_code) == EQ || (outer_code) == NE)
- && INTVAL (x) == 0)
- {
- *total = 0;
- return true;
- }
+ /* Equality comparisons with 0 are cheap. */
+ if (((outer_code) == EQ || (outer_code) == NE)
+ && INTVAL (x) == 0)
+ {
+ *total = 0;
+ return true;
+ }
- /* Constants in the range 0...255 can be loaded with an unextended
- instruction. They are therefore as cheap as a register move.
+ /* Constants in the range 0...255 can be loaded with an unextended
+ instruction. They are therefore as cheap as a register move.
- Given the choice between "li R1,0...255" and "move R1,R2"
- (where R2 is a known constant), it is usually better to use "li",
- since we do not want to unnecessarily extend the lifetime of R2. */
- if (outer_code == SET
- && INTVAL (x) >= 0
- && INTVAL (x) < 256)
+ Given the choice between "li R1,0...255" and "move R1,R2"
+ (where R2 is a known constant), it is usually better to use "li",
+ since we do not want to unnecessarily extend the lifetime
+ of R2. */
+ if (outer_code == SET
+ && INTVAL (x) >= 0
+ && INTVAL (x) < 256)
+ {
+ *total = 0;
+ return true;
+ }
+ }
+ else
{
+ /* These can be used anywhere. */
*total = 0;
return true;
}
- /* Otherwise fall through to the handling below. */
+ /* Otherwise fall through to the handling below because
+ we'll need to construct the constant. */
case CONST:
case SYMBOL_REF:
@@ -2178,15 +2399,15 @@ mips_rtx_costs (rtx x, int code, int outer_code, int *total)
case MEM:
{
- /* If the address is legitimate, return the number of
- instructions it needs, otherwise use the default handling. */
- int n = mips_address_insns (XEXP (x, 0), GET_MODE (x));
- if (n > 0)
- {
- *total = COSTS_N_INSNS (1 + n);
- return true;
- }
- return false;
+ /* If the address is legitimate, return the number of
+ instructions it needs, otherwise use the default handling. */
+ int n = mips_address_insns (XEXP (x, 0), GET_MODE (x));
+ if (n > 0)
+ {
+ *total = COSTS_N_INSNS (n + 1);
+ return true;
+ }
+ return false;
}
case FFS:
@@ -2219,7 +2440,7 @@ mips_rtx_costs (rtx x, int code, int outer_code, int *total)
return false;
case ABS:
- if (mode == SFmode || mode == DFmode)
+ if (float_mode_p)
*total = COSTS_N_INSNS (1);
else
*total = COSTS_N_INSNS (4);
@@ -2231,19 +2452,13 @@ mips_rtx_costs (rtx x, int code, int outer_code, int *total)
case PLUS:
case MINUS:
- if (mode == SFmode || mode == DFmode)
- {
- if (TUNE_MIPS3000 || TUNE_MIPS3900)
- *total = COSTS_N_INSNS (2);
- else if (TUNE_MIPS6000)
- *total = COSTS_N_INSNS (3);
- else if (TUNE_SB1)
- *total = COSTS_N_INSNS (4);
- else
- *total = COSTS_N_INSNS (6);
- return true;
- }
- if (mode == DImode && !TARGET_64BIT)
+ if (float_mode_p)
+ {
+ *total = mips_cost->fp_add;
+ return true;
+ }
+
+ else if (mode == DImode && !TARGET_64BIT)
{
*total = COSTS_N_INSNS (4);
return true;
@@ -2253,115 +2468,46 @@ mips_rtx_costs (rtx x, int code, int outer_code, int *total)
case NEG:
if (mode == DImode && !TARGET_64BIT)
{
- *total = 4;
+ *total = COSTS_N_INSNS (4);
return true;
}
return false;
case MULT:
if (mode == SFmode)
- {
- if (TUNE_MIPS3000
- || TUNE_MIPS3900
- || TUNE_MIPS5000
- || TUNE_SB1)
- *total = COSTS_N_INSNS (4);
- else if (TUNE_MIPS6000
- || TUNE_MIPS5400
- || TUNE_MIPS5500)
- *total = COSTS_N_INSNS (5);
- else
- *total = COSTS_N_INSNS (7);
- return true;
- }
+ *total = mips_cost->fp_mult_sf;
- if (mode == DFmode)
- {
- if (TUNE_SB1)
- *total = COSTS_N_INSNS (4);
- else if (TUNE_MIPS3000
- || TUNE_MIPS3900
- || TUNE_MIPS5000)
- *total = COSTS_N_INSNS (5);
- else if (TUNE_MIPS6000
- || TUNE_MIPS5400
- || TUNE_MIPS5500)
- *total = COSTS_N_INSNS (6);
- else
- *total = COSTS_N_INSNS (8);
- return true;
- }
+ else if (mode == DFmode)
+ *total = mips_cost->fp_mult_df;
+
+ else if (mode == SImode)
+ *total = mips_cost->int_mult_si;
- if (TUNE_MIPS3000)
- *total = COSTS_N_INSNS (12);
- else if (TUNE_MIPS3900)
- *total = COSTS_N_INSNS (2);
- else if (TUNE_MIPS4130)
- *total = COSTS_N_INSNS (mode == DImode ? 6 : 4);
- else if (TUNE_MIPS5400 || TUNE_SB1)
- *total = COSTS_N_INSNS (mode == DImode ? 4 : 3);
- else if (TUNE_MIPS5500 || TUNE_MIPS7000)
- *total = COSTS_N_INSNS (mode == DImode ? 9 : 5);
- else if (TUNE_MIPS9000)
- *total = COSTS_N_INSNS (mode == DImode ? 8 : 3);
- else if (TUNE_MIPS6000)
- *total = COSTS_N_INSNS (17);
- else if (TUNE_MIPS5000)
- *total = COSTS_N_INSNS (5);
else
- *total = COSTS_N_INSNS (10);
+ *total = mips_cost->int_mult_di;
+
return true;
case DIV:
case MOD:
- if (mode == SFmode)
- {
- if (TUNE_MIPS3000
- || TUNE_MIPS3900)
- *total = COSTS_N_INSNS (12);
- else if (TUNE_MIPS6000)
- *total = COSTS_N_INSNS (15);
- else if (TUNE_SB1)
- *total = COSTS_N_INSNS (24);
- else if (TUNE_MIPS5400 || TUNE_MIPS5500)
- *total = COSTS_N_INSNS (30);
- else
- *total = COSTS_N_INSNS (23);
- return true;
- }
+ if (float_mode_p)
+ {
+ if (mode == SFmode)
+ *total = mips_cost->fp_div_sf;
+ else
+ *total = mips_cost->fp_div_df;
- if (mode == DFmode)
- {
- if (TUNE_MIPS3000
- || TUNE_MIPS3900)
- *total = COSTS_N_INSNS (19);
- else if (TUNE_MIPS5400 || TUNE_MIPS5500)
- *total = COSTS_N_INSNS (59);
- else if (TUNE_MIPS6000)
- *total = COSTS_N_INSNS (16);
- else if (TUNE_SB1)
- *total = COSTS_N_INSNS (32);
- else
- *total = COSTS_N_INSNS (36);
- return true;
- }
+ return true;
+ }
/* Fall through. */
case UDIV:
case UMOD:
- if (TUNE_MIPS3000
- || TUNE_MIPS3900)
- *total = COSTS_N_INSNS (35);
- else if (TUNE_MIPS6000)
- *total = COSTS_N_INSNS (38);
- else if (TUNE_MIPS5000)
- *total = COSTS_N_INSNS (36);
- else if (TUNE_SB1)
- *total = COSTS_N_INSNS ((mode == SImode) ? 36 : 68);
- else if (TUNE_MIPS5400 || TUNE_MIPS5500)
- *total = COSTS_N_INSNS ((mode == SImode) ? 42 : 74);
+ if (mode == DImode)
+ *total = mips_cost->int_div_di;
else
- *total = COSTS_N_INSNS (69);
+ *total = mips_cost->int_div_si;
+
return true;
case SIGN_EXTEND:
@@ -2383,6 +2529,15 @@ mips_rtx_costs (rtx x, int code, int outer_code, int *total)
*total = COSTS_N_INSNS (1);
return true;
+ case FLOAT:
+ case UNSIGNED_FLOAT:
+ case FIX:
+ case FLOAT_EXTEND:
+ case FLOAT_TRUNCATE:
+ case SQRT:
+ *total = mips_cost->fp_add;
+ return true;
+
default:
return false;
}
@@ -4048,7 +4203,7 @@ mips_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
left-side instructions (lwl, swl, ldl, sdl).
*RIGHT is a QImode reference to the opposite end of the field and
- can be used in the parterning right-side instruction. */
+ can be used in the patterning right-side instruction. */
static bool
mips_get_unaligned_mem (rtx *op, unsigned int width, int bitpos,
@@ -4164,7 +4319,39 @@ mips_expand_unaligned_store (rtx dest, rtx src, unsigned int width, int bitpos)
}
return true;
}
-
+
+/* Return true if (zero_extract OP SIZE POSITION) can be used as the
+ source of an "ext" instruction or the destination of an "ins"
+ instruction. OP must be a register operand and the following
+ conditions must hold:
+
+ 0 <= POSITION < GET_MODE_BITSIZE (GET_MODE (op))
+ 0 < SIZE <= GET_MODE_BITSIZE (GET_MODE (op))
+ 0 < POSITION + SIZE <= GET_MODE_BITSIZE (GET_MODE (op))
+
+ Also reject lengths equal to a word as they are better handled
+ by the move patterns. */
+
+bool
+mips_use_ins_ext_p (rtx op, rtx size, rtx position)
+{
+ HOST_WIDE_INT len, pos;
+
+ if (!ISA_HAS_EXT_INS
+ || !register_operand (op, VOIDmode)
+ || GET_MODE_BITSIZE (GET_MODE (op)) > BITS_PER_WORD)
+ return false;
+
+ len = INTVAL (size);
+ pos = INTVAL (position);
+
+ if (len <= 0 || len >= GET_MODE_BITSIZE (GET_MODE (op))
+ || pos < 0 || pos + len > GET_MODE_BITSIZE (GET_MODE (op)))
+ return false;
+
+ return true;
+}
+
/* Set up globals to generate code for the ISA or processor
described by INFO. */
@@ -4215,21 +4402,13 @@ mips_handle_option (size_t code, const char *arg, int value ATTRIBUTE_UNUSED)
return true;
case OPT_march_:
- mips_arch_string = arg;
- return mips_parse_cpu (arg) != 0;
-
case OPT_mtune_:
- mips_tune_string = arg;
return mips_parse_cpu (arg) != 0;
case OPT_mips:
mips_isa_info = mips_parse_cpu (ACONCAT (("mips", arg, NULL)));
return mips_isa_info != 0;
- case OPT_mflush_func_:
- mips_cache_flush_func = arg;
- return true;
-
case OPT_mno_flush_func:
mips_cache_flush_func = NULL;
return true;
@@ -4288,6 +4467,9 @@ override_options (void)
if (mips_tune_info == 0)
mips_set_tune (mips_arch_info);
+ /* Set cost structure for the processor. */
+ mips_cost = &mips_rtx_cost_data[mips_tune];
+
if ((target_flags_explicit & MASK_64BIT) != 0)
{
/* The user specified the size of the integer registers. Make sure
@@ -5609,7 +5791,7 @@ mips_declare_object_name (FILE *stream, const char *name,
ASM_OUTPUT_SIZE_DIRECTIVE (stream, name, size);
}
- mips_declare_object (stream, name, "", ":\n", 0);
+ mips_declare_object (stream, name, "", ":\n");
}
/* Implement ASM_FINISH_DECLARE_OBJECT. This is generic ELF stuff. */
@@ -8668,7 +8850,7 @@ mips_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
{
return 5;
}
- } /* GR_REG_CLASS_P (from) */
+ }
else if (from == FP_REGS)
{
if (GR_REG_CLASS_P (to))
@@ -8677,7 +8859,7 @@ mips_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
return 2;
else if (to == ST_REGS)
return 8;
- } /* from == FP_REGS */
+ }
else if (from == HI_REG || from == LO_REG || from == MD_REGS)
{
if (GR_REG_CLASS_P (to))
@@ -8687,15 +8869,16 @@ mips_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
else
return 6;
}
- } /* from == HI_REG, etc. */
+ }
else if (from == ST_REGS && GR_REG_CLASS_P (to))
return 4;
else if (COP_REG_CLASS_P (from))
{
return 5;
- } /* COP_REG_CLASS_P (from) */
+ }
- /* Fall through. */
+ /* Fall through.
+ ??? What cases are these? Shouldn't we return 2 here? */
return 12;
}
@@ -9691,13 +9874,13 @@ struct bdesc_map
unsigned int size;
/* The target processor that supports these builtin functions.
- PROCESSOR_DEFAULT means we enable them for all processors. */
+ PROCESSOR_MAX means we enable them for all processors. */
enum processor_type proc;
};
static const struct bdesc_map bdesc_arrays[] =
{
- { mips_bdesc, ARRAY_SIZE (mips_bdesc), PROCESSOR_DEFAULT },
+ { mips_bdesc, ARRAY_SIZE (mips_bdesc), PROCESSOR_MAX },
{ sb1_bdesc, ARRAY_SIZE (sb1_bdesc), PROCESSOR_SB1 }
};
@@ -9872,7 +10055,7 @@ mips_init_builtins (void)
offset = 0;
for (m = bdesc_arrays; m < &bdesc_arrays[ARRAY_SIZE (bdesc_arrays)]; m++)
{
- if (m->proc == PROCESSOR_DEFAULT || (m->proc == mips_arch))
+ if (m->proc == PROCESSOR_MAX || (m->proc == mips_arch))
for (d = m->bdesc; d < &m->bdesc[m->size]; d++)
if ((d->target_flags & target_flags) == d->target_flags)
lang_hooks.builtin_function (d->name, types[d->function_type],
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index aeadac30fa8..6c9d343b530 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -32,7 +32,7 @@ Boston, MA 02111-1307, USA. */
the cpu attribute in the mips.md machine description. */
enum processor_type {
- PROCESSOR_DEFAULT,
+ PROCESSOR_R3000,
PROCESSOR_4KC,
PROCESSOR_4KP,
PROCESSOR_5KC,
@@ -40,7 +40,6 @@ enum processor_type {
PROCESSOR_24K,
PROCESSOR_24KX,
PROCESSOR_M4K,
- PROCESSOR_R3000,
PROCESSOR_R3900,
PROCESSOR_R6000,
PROCESSOR_R4000,
@@ -58,7 +57,25 @@ enum processor_type {
PROCESSOR_R8000,
PROCESSOR_R9000,
PROCESSOR_SB1,
- PROCESSOR_SR71000
+ PROCESSOR_SR71000,
+ PROCESSOR_MAX
+};
+
+/* Costs of various operations on the different architectures. */
+
+struct mips_rtx_cost_data
+{
+ unsigned short fp_add;
+ unsigned short fp_mult_sf;
+ unsigned short fp_mult_df;
+ unsigned short fp_div_sf;
+ unsigned short fp_div_df;
+ unsigned short int_mult_si;
+ unsigned short int_mult_di;
+ unsigned short int_div_si;
+ unsigned short int_div_di;
+ unsigned short branch_cost;
+ unsigned short memory_latency;
};
/* Which ABI to use. ABI_32 (original 32, or o32), ABI_N32 (n32),
@@ -105,10 +122,10 @@ extern enum processor_type mips_tune; /* which cpu to schedule for */
extern int mips_isa; /* architectural level */
extern int mips_abi; /* which ABI to use */
extern int mips16_hard_float; /* mips16 without -msoft-float */
-extern const char *mips_cache_flush_func;/* for -mflush-func= and -mno-flush-func */
extern const struct mips_cpu_info mips_cpu_info_table[];
extern const struct mips_cpu_info *mips_arch_info;
extern const struct mips_cpu_info *mips_tune_info;
+extern const struct mips_rtx_cost_data *mips_cost;
/* Macros to silence warnings about numbers being signed in traditional
C and unsigned in ISO C when compiled on 32-bit hosts. */
@@ -671,6 +688,11 @@ extern const struct mips_cpu_info *mips_tune_info;
&& (ISA_MIPS32R2 \
))
+/* ISA includes the MIPS32/64 rev 2 ext and ins instructions. */
+#define ISA_HAS_EXT_INS (!TARGET_MIPS16 \
+ && (ISA_MIPS32R2 \
+ ))
+
/* True if the result of a load is not available to the next instruction.
A nop will then be needed between instructions like "lw $4,..."
and "addiu $4,$4,1". */
@@ -2295,9 +2317,8 @@ typedef struct mips_args {
#define REGISTER_MOVE_COST(MODE, FROM, TO) \
mips_register_move_cost (MODE, FROM, TO)
-/* ??? Fix this to be right for the R8000. */
#define MEMORY_MOVE_COST(MODE,CLASS,TO_P) \
- (((TUNE_MIPS4000 || TUNE_MIPS6000) ? 6 : 4) \
+ (mips_cost->memory_latency \
+ memory_move_secondary_cost ((MODE), (CLASS), (TO_P)))
/* Define if copies to/from condition code registers should be avoided.
@@ -2310,11 +2331,8 @@ typedef struct mips_args {
/* A C expression for the cost of a branch instruction. A value of
1 is the default; other values are interpreted relative to that. */
-/* ??? Fix this to be right for the R8000. */
-#define BRANCH_COST \
- ((! TARGET_MIPS16 \
- && (TUNE_MIPS4000 || TUNE_MIPS6000)) \
- ? 2 : 1)
+#define BRANCH_COST mips_cost->branch_cost
+#define LOGICAL_OP_NON_SHORT_CIRCUIT 0
/* If defined, modifies the length assigned to instruction INSN as a
function of the context in which it is used. LENGTH is an lvalue
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index 5d58b735503..e8a6b2a8576 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -266,7 +266,7 @@
;; Attribute describing the processor. This attribute must match exactly
;; with the processor_type enumeration in mips.h.
(define_attr "cpu"
- "default,4kc,4kp,5kc,20kc,24k,24kx,m4k,r3000,r3900,r6000,r4000,r4100,r4111,r4120,r4130,r4300,r4600,r4650,r5000,r5400,r5500,r7000,r8000,r9000,sb1,sr71000"
+ "r3000,4kc,4kp,5kc,20kc,24k,24kx,m4k,r3900,r6000,r4000,r4100,r4111,r4120,r4130,r4300,r4600,r4650,r5000,r5400,r5500,r7000,r8000,r9000,sb1,sr71000"
(const (symbol_ref "mips_tune")))
;; The type of hardware hazard associated with this instruction.
@@ -2818,7 +2818,7 @@ beq\t%2,%.,1b\;\
(define_expand "extzv"
[(set (match_operand 0 "register_operand")
- (zero_extract (match_operand:QI 1 "memory_operand")
+ (zero_extract (match_operand 1 "nonimmediate_operand")
(match_operand 2 "immediate_operand")
(match_operand 3 "immediate_operand")))]
"!TARGET_MIPS16"
@@ -2827,12 +2827,33 @@ beq\t%2,%.,1b\;\
INTVAL (operands[2]),
INTVAL (operands[3])))
DONE;
+ else if (mips_use_ins_ext_p (operands[1], operands[2], operands[3]))
+ {
+ if (GET_MODE (operands[0]) == DImode)
+ emit_insn (gen_extzvdi (operands[0], operands[1], operands[2],
+ operands[3]));
+ else
+ emit_insn (gen_extzvsi (operands[0], operands[1], operands[2],
+ operands[3]));
+ DONE;
+ }
else
FAIL;
})
+(define_insn "extzv<mode>"
+ [(set (match_operand:GPR 0 "register_operand" "=d")
+ (zero_extract:GPR (match_operand:GPR 1 "register_operand" "d")
+ (match_operand:SI 2 "immediate_operand" "I")
+ (match_operand:SI 3 "immediate_operand" "I")))]
+ "mips_use_ins_ext_p (operands[1], operands[2], operands[3])"
+ "<d>ext\t%0,%1,%3,%2"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "<MODE>")])
+
+
(define_expand "insv"
- [(set (zero_extract (match_operand:QI 0 "memory_operand")
+ [(set (zero_extract (match_operand 0 "nonimmediate_operand")
(match_operand 1 "immediate_operand")
(match_operand 2 "immediate_operand"))
(match_operand 3 "reg_or_0_operand"))]
@@ -2842,10 +2863,30 @@ beq\t%2,%.,1b\;\
INTVAL (operands[1]),
INTVAL (operands[2])))
DONE;
- else
- FAIL;
+ else if (mips_use_ins_ext_p (operands[0], operands[1], operands[2]))
+ {
+ if (GET_MODE (operands[0]) == DImode)
+ emit_insn (gen_insvdi (operands[0], operands[1], operands[2],
+ operands[3]));
+ else
+ emit_insn (gen_insvsi (operands[0], operands[1], operands[2],
+ operands[3]));
+ DONE;
+ }
+ else
+ FAIL;
})
+(define_insn "insv<mode>"
+ [(set (zero_extract:GPR (match_operand:GPR 0 "register_operand" "+d")
+ (match_operand:SI 1 "immediate_operand" "I")
+ (match_operand:SI 2 "immediate_operand" "I"))
+ (match_operand:GPR 3 "reg_or_0_operand" "dJ"))]
+ "mips_use_ins_ext_p (operands[0], operands[1], operands[2])"
+ "<d>ins\t%0,%z3,%2,%1"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "<MODE>")])
+
;; Unaligned word moves generated by the bit field patterns.
;;
;; As far as the rtl is concerned, both the left-part and right-part
@@ -5326,7 +5367,7 @@ beq\t%2,%.,1b\;\
; Thread-Local Storage
-; The TLS base pointer is acessed via "rdhwr $v1, $29". No current
+; The TLS base pointer is accessed via "rdhwr $v1, $29". No current
; MIPS architecture defines this register, and no current
; implementation provides it; instead, any OS which supports TLS is
; expected to trap and emulate this instruction. rdhwr is part of the
diff --git a/gcc/config/mips/mips.opt b/gcc/config/mips/mips.opt
index cb78b8e7b40..3e028962973 100644
--- a/gcc/config/mips/mips.opt
+++ b/gcc/config/mips/mips.opt
@@ -32,7 +32,7 @@ Target Report Var(TARGET_MAD)
Use PMC-style 'mad' instructions
march=
-Target RejectNegative Joined
+Target RejectNegative Joined Var(mips_arch_string)
-march=ISA Generate code for the given ISA
mbranch-likely
@@ -114,7 +114,7 @@ Target Report RejectNegative Mask(FLOAT64)
Use 64-bit floating-point registers
mflush-func=
-Target RejectNegative Joined
+Target RejectNegative Joined Var(mips_cache_flush_func) Init(CACHE_FLUSH_FUNC)
-mflush-func=FUNC Use FUNC to flush the cache before calling stack trampolines
mfused-madd
@@ -198,7 +198,7 @@ Target Report Var(TARGET_SYM32)
Assume all symbols have 32-bit values
mtune=
-Target RejectNegative Joined
+Target RejectNegative Joined Var(mips_tune_string)
-mtune=PROCESSOR Optimize the output for PROCESSOR
muninit-const-in-rodata
diff --git a/gcc/config/mmix/mmix.h b/gcc/config/mmix/mmix.h
index a5feb38fc7a..92f2d3a66bb 100644
--- a/gcc/config/mmix/mmix.h
+++ b/gcc/config/mmix/mmix.h
@@ -1,5 +1,5 @@
/* Definitions of target machine for GNU compiler, for MMIX.
- Copyright (C) 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2002, 2004, 2005 Free Software Foundation, Inc.
Contributed by Hans-Peter Nilsson (hp@bitrange.com)
This file is part of GCC.
diff --git a/gcc/config/rs6000/darwin-ldouble.c b/gcc/config/rs6000/darwin-ldouble.c
index b394d5d99bf..9ac9a8a0e8f 100644
--- a/gcc/config/rs6000/darwin-ldouble.c
+++ b/gcc/config/rs6000/darwin-ldouble.c
@@ -68,7 +68,7 @@ extern long double __gcc_qmul (double, double, double, double);
extern long double __gcc_qdiv (double, double, double, double);
#if defined __ELF__ && defined SHARED
-/* Provide definitions of the old symbol names to statisfy apps and
+/* Provide definitions of the old symbol names to satisfy apps and
shared libs built against an older libgcc. To access the _xlq
symbols an explicit version reference is needed, so these won't
satisfy an unadorned reference like _xlqadd. If dot symbols are
diff --git a/gcc/config/rs6000/eabispe.h b/gcc/config/rs6000/eabispe.h
index 54d8ce4f2c7..9afb3df5cfb 100644
--- a/gcc/config/rs6000/eabispe.h
+++ b/gcc/config/rs6000/eabispe.h
@@ -1,6 +1,6 @@
/* Core target definitions for GNU compiler
for PowerPC embedded targeted systems with SPE support.
- Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
Contributed by Aldy Hernandez (aldyh@redhat.com).
This file is part of GCC.
diff --git a/gcc/config/rs6000/lynx.h b/gcc/config/rs6000/lynx.h
index f928eefa078..a7f6f6f6578 100644
--- a/gcc/config/rs6000/lynx.h
+++ b/gcc/config/rs6000/lynx.h
@@ -1,5 +1,5 @@
/* Definitions for Rs6000 running LynxOS.
- Copyright (C) 1995, 1996, 2000, 2002, 2003, 2004
+ Copyright (C) 1995, 1996, 2000, 2002, 2003, 2004, 2005
Free Software Foundation, Inc.
Contributed by David Henkel-Wallace, Cygnus Support (gumby@cygnus.com)
Rewritten by Adam Nemet, LynuxWorks Inc.
diff --git a/gcc/config/rs6000/rs6000-c.c b/gcc/config/rs6000/rs6000-c.c
index 41a4d296452..4fa46b4eed0 100644
--- a/gcc/config/rs6000/rs6000-c.c
+++ b/gcc/config/rs6000/rs6000-c.c
@@ -31,7 +31,7 @@
#include "c-common.h"
#include "c-pragma.h"
#include "c-tree.h"
-#include "errors.h"
+#include "toplev.h"
#include "tm_p.h"
#include "target.h"
#include "langhooks.h"
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 228af5d3aa1..ce9164c66d5 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -552,6 +552,7 @@ struct processor_costs power4_cost = {
static bool rs6000_function_ok_for_sibcall (tree, tree);
+static bool rs6000_insn_valid_within_doloop (rtx);
static rtx rs6000_generate_compare (enum rtx_code);
static void rs6000_maybe_dead (rtx);
static void rs6000_emit_stack_tie (void);
@@ -906,6 +907,9 @@ static const char alt_reg_names[][8] =
#undef TARGET_FUNCTION_OK_FOR_SIBCALL
#define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
+#undef TARGET_INSN_VALID_WITHIN_DOLOOP
+#define TARGET_INSN_VALID_WITHIN_DOLOOP rs6000_insn_valid_within_doloop
+
#undef TARGET_RTX_COSTS
#define TARGET_RTX_COSTS rs6000_rtx_costs
#undef TARGET_ADDRESS_COST
@@ -3283,7 +3287,7 @@ rs6000_conditional_register_usage (void)
if (! TARGET_POWER)
fixed_regs[64] = 1;
- /* 64-bit AIX reserves GPR13 for thread-private data. */
+ /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
if (TARGET_64BIT)
fixed_regs[13] = call_used_regs[13]
= call_really_used_regs[13] = 1;
@@ -3294,6 +3298,11 @@ rs6000_conditional_register_usage (void)
fixed_regs[i] = call_used_regs[i]
= call_really_used_regs[i] = 1;
+ /* The TOC register is not killed across calls in a way that is
+ visible to the compiler. */
+ if (DEFAULT_ABI == ABI_AIX)
+ call_really_used_regs[2] = 0;
+
if (DEFAULT_ABI == ABI_V4
&& PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
&& flag_pic == 2)
@@ -11409,13 +11418,15 @@ rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
else
{
rtx addrSI, aligned_addr;
+ int shift_mask = mode == QImode ? 0x18 : 0x10;
addrSI = force_reg (SImode, gen_lowpart_common (SImode,
XEXP (used_m, 0)));
shift = gen_reg_rtx (SImode);
emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
- GEN_INT (0x18)));
+ GEN_INT (shift_mask)));
+ emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
aligned_addr = expand_binop (Pmode, and_optab,
XEXP (used_m, 0),
@@ -11453,7 +11464,7 @@ rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
newop = expand_binop (SImode, ior_optab,
oldop, GEN_INT (~imask), NULL_RTX,
1, OPTAB_LIB_WIDEN);
- emit_insn (gen_ashlsi3 (newop, newop, shift));
+ emit_insn (gen_rotlsi3 (newop, newop, shift));
break;
case PLUS:
@@ -11482,6 +11493,19 @@ rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
gcc_unreachable ();
}
+ if (GET_CODE (m) == NOT)
+ {
+ rtx mask, xorm;
+
+ mask = gen_reg_rtx (SImode);
+ emit_move_insn (mask, GEN_INT (imask));
+ emit_insn (gen_ashlsi3 (mask, mask, shift));
+
+ xorm = gen_rtx_XOR (SImode, used_m, mask);
+ /* Depending on the value of 'op', the XOR or the operation might
+ be able to be simplified away. */
+ newop = simplify_gen_binary (code, SImode, xorm, newop);
+ }
op = newop;
used_mode = SImode;
before = gen_reg_rtx (used_mode);
@@ -11499,7 +11523,7 @@ rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
after = gen_reg_rtx (used_mode);
}
- if (code == PLUS && used_mode != mode)
+ if ((code == PLUS || GET_CODE (m) == NOT) && used_mode != mode)
the_op = op; /* Computed above. */
else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
@@ -12505,6 +12529,23 @@ rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
return false;
}
+/* TRUE if INSN insn is valid within a low-overhead loop.
+ PowerPC uses the COUNT register for branch on table instructions. */
+
+static bool
+rs6000_insn_valid_within_doloop (rtx insn)
+{
+ if (CALL_P (insn))
+ return false;
+
+ if (JUMP_P (insn)
+ && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
+ || GET_CODE (PATTERN (insn)) == ADDR_VEC))
+ return false;
+
+ return true;
+}
+
static int
rs6000_ra_ever_killed (void)
{
@@ -12572,15 +12613,49 @@ rs6000_emit_load_toc_table (int fromprolog)
rtx dest, insn;
dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
- if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
+ if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
{
- rtx temp = (fromprolog
- ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
- : gen_reg_rtx (Pmode));
- insn = emit_insn (gen_load_toc_v4_pic_si (temp));
+ char buf[30];
+ rtx lab, tmp1, tmp2, got, tempLR;
+
+ ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
+ lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
+ if (flag_pic == 2)
+ got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
+ else
+ got = rs6000_got_sym ();
+ tmp1 = tmp2 = dest;
+ if (!fromprolog)
+ {
+ tmp1 = gen_reg_rtx (Pmode);
+ tmp2 = gen_reg_rtx (Pmode);
+ }
+ tempLR = (fromprolog
+ ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
+ : gen_reg_rtx (Pmode));
+ insn = emit_insn (gen_load_toc_v4_PIC_1 (tempLR, lab));
+ if (fromprolog)
+ rs6000_maybe_dead (insn);
+ insn = emit_move_insn (tmp1, tempLR);
+ if (fromprolog)
+ rs6000_maybe_dead (insn);
+ insn = emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
+ if (fromprolog)
+ rs6000_maybe_dead (insn);
+ insn = emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
+ if (fromprolog)
+ rs6000_maybe_dead (insn);
+ }
+ else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
+ {
+ rtx tempLR = (fromprolog
+ ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
+ : gen_reg_rtx (Pmode));
+
+ insn = emit_insn (gen_load_toc_v4_pic_si (tempLR));
if (fromprolog)
rs6000_maybe_dead (insn);
- insn = emit_move_insn (dest, temp);
+ insn = emit_move_insn (dest, tempLR);
if (fromprolog)
rs6000_maybe_dead (insn);
}
@@ -13674,7 +13749,8 @@ rs6000_emit_prologue (void)
/* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
- || (DEFAULT_ABI == ABI_V4 && flag_pic == 1
+ || (DEFAULT_ABI == ABI_V4
+ && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
&& regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM]))
{
/* If emit_load_toc_table will use the link register, we need to save
@@ -16120,7 +16196,7 @@ force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
between the insns.
The function estimates the group boundaries that the processor will form as
- folllows: It keeps track of how many vacant issue slots are available after
+ follows: It keeps track of how many vacant issue slots are available after
each insn. A subsequent insn will start a new group if one of the following
4 cases applies:
- no more vacant issue slots remain in the current dispatch group.
@@ -17204,6 +17280,7 @@ rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
}
if (TARGET_RELOCATABLE
+ && !TARGET_SECURE_PLT
&& (get_pool_size () != 0 || current_function_profile)
&& uses_TOC ())
{
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 25e48498f2d..2710dad4dae 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -136,7 +136,7 @@
#define TARGET_MFCRF 0
#endif
-/* Define TARGET_POPCNTB if the target assembler does not suppport the
+/* Define TARGET_POPCNTB if the target assembler does not support the
popcount byte instruction. */
#ifndef HAVE_AS_POPCNTB
@@ -144,6 +144,10 @@
#define TARGET_POPCNTB 0
#endif
+#ifndef TARGET_SECURE_PLT
+#define TARGET_SECURE_PLT 0
+#endif
+
#define TARGET_32BIT (! TARGET_64BIT)
/* Emit a dtp-relative reference to a TLS variable. */
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 2c0b0491abe..15426d96f63 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -1672,7 +1672,7 @@
(const_int 0)))
(set (match_operand:P 0 "gpc_reg_operand" "")
(neg:P (match_dup 1)))]
- "TARGET_32BIT && reload_completed"
+ "reload_completed"
[(set (match_dup 0)
(neg:P (match_dup 1)))
(set (match_dup 2)
@@ -7360,26 +7360,6 @@
;; Now define ways of moving data around.
-;; Elf specific ways of loading addresses for non-PIC code.
-;; The output of this could be r0, but we make a very strong
-;; preference for a base register because it will usually
-;; be needed there.
-(define_insn "elf_high"
- [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
- (high:SI (match_operand 1 "" "")))]
- "TARGET_ELF && ! TARGET_64BIT"
- "{liu|lis} %0,%1@ha")
-
-(define_insn "elf_low"
- [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
- (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b,!*r")
- (match_operand 2 "" "")))]
- "TARGET_ELF && ! TARGET_64BIT"
- "@
- {cal|la} %0,%2@l(%1)
- {ai|addic} %0,%1,%K2")
-
-
;; Set up a register with a value from the GOT table
(define_expand "movsi_got"
@@ -9810,7 +9790,8 @@
[(set (match_operand:SI 0 "register_operand" "=l")
(match_operand:SI 1 "immediate_operand" "s"))
(use (unspec [(match_dup 1)] UNSPEC_TOC))]
- "TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2"
+ "TARGET_ELF && DEFAULT_ABI != ABI_AIX
+ && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
"bcl 20,31,%1\\n%1:"
[(set_attr "type" "branch")
(set_attr "length" "4")])
@@ -9833,6 +9814,22 @@
"{l|lwz} %0,%2-%3(%1)"
[(set_attr "type" "load")])
+(define_insn "load_toc_v4_PIC_3b"
+ [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
+ (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r")
+ (high:SI
+ (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
+ (match_operand:SI 3 "symbol_ref_operand" "s")))))]
+ "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic"
+ "{cau|addis} %0,%1,%2-%3@ha")
+
+(define_insn "load_toc_v4_PIC_3c"
+ [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
+ (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
+ (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
+ (match_operand:SI 3 "symbol_ref_operand" "s"))))]
+ "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic"
+ "{cal|addi} %0,%1,%2-%3@l")
;; If the TOC is shared over a translation unit, as happens with all
;; the kinds of PIC that we support, we need to restore the TOC
@@ -9867,6 +9864,25 @@
rs6000_emit_load_toc_table (FALSE);
DONE;
}")
+
+;; Elf specific ways of loading addresses for non-PIC code.
+;; The output of this could be r0, but we make a very strong
+;; preference for a base register because it will usually
+;; be needed there.
+(define_insn "elf_high"
+ [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
+ (high:SI (match_operand 1 "" "")))]
+ "TARGET_ELF && ! TARGET_64BIT"
+ "{liu|lis} %0,%1@ha")
+
+(define_insn "elf_low"
+ [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
+ (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b,!*r")
+ (match_operand 2 "" "")))]
+ "TARGET_ELF && ! TARGET_64BIT"
+ "@
+ {cal|la} %0,%2@l(%1)
+ {ai|addic} %0,%1,%K2")
;; A function pointer under AIX is a pointer to a data area whose first word
;; contains the actual address of the function, whose second word contains a
@@ -9983,6 +9999,25 @@
operands[0] = XEXP (operands[0], 0);
+ if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT
+ && flag_pic
+ && GET_CODE (operands[0]) == SYMBOL_REF
+ && !SYMBOL_REF_LOCAL_P (operands[0]))
+ {
+ rtx call;
+ rtvec tmp;
+
+ tmp = gen_rtvec (3,
+ gen_rtx_CALL (VOIDmode,
+ gen_rtx_MEM (SImode, operands[0]),
+ operands[1]),
+ gen_rtx_USE (VOIDmode, operands[2]),
+ gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
+ call = emit_call_insn (gen_rtx_PARALLEL (VOIDmode, tmp));
+ use_reg (&CALL_INSN_FUNCTION_USAGE (call), pic_offset_table_rtx);
+ DONE;
+ }
+
if (GET_CODE (operands[0]) != SYMBOL_REF
|| (DEFAULT_ABI == ABI_AIX && !SYMBOL_REF_FUNCTION_P (operands[0]))
|| (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
@@ -10034,6 +10069,28 @@
operands[1] = XEXP (operands[1], 0);
+ if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT
+ && flag_pic
+ && GET_CODE (operands[1]) == SYMBOL_REF
+ && !SYMBOL_REF_LOCAL_P (operands[1]))
+ {
+ rtx call;
+ rtvec tmp;
+
+ tmp = gen_rtvec (3,
+ gen_rtx_SET (VOIDmode,
+ operands[0],
+ gen_rtx_CALL (VOIDmode,
+ gen_rtx_MEM (SImode,
+ operands[1]),
+ operands[2])),
+ gen_rtx_USE (VOIDmode, operands[3]),
+ gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
+ call = emit_call_insn (gen_rtx_PARALLEL (VOIDmode, tmp));
+ use_reg (&CALL_INSN_FUNCTION_USAGE (call), pic_offset_table_rtx);
+ DONE;
+ }
+
if (GET_CODE (operands[1]) != SYMBOL_REF
|| (DEFAULT_ABI == ABI_AIX && !SYMBOL_REF_FUNCTION_P (operands[1]))
|| (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
@@ -10307,7 +10364,18 @@
#if TARGET_MACHO
return output_call(insn, operands, 0, 2);
#else
- return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@plt" : "bl %z0";
+ if (DEFAULT_ABI == ABI_V4 && flag_pic)
+ {
+ if (TARGET_SECURE_PLT && flag_pic == 2)
+ /* The magic 32768 offset here and in the other sysv call insns
+ corresponds to the offset of r30 in .got2, as given by LCTOC1.
+ See sysv4.h:toc_section. */
+ return "bl %z0+32768@plt";
+ else
+ return "bl %z0@plt";
+ }
+ else
+ return "bl %z0";
#endif
}
[(set_attr "type" "branch,branch")
@@ -10352,7 +10420,15 @@
#if TARGET_MACHO
return output_call(insn, operands, 1, 3);
#else
- return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@plt" : "bl %z1";
+ if (DEFAULT_ABI == ABI_V4 && flag_pic)
+ {
+ if (TARGET_SECURE_PLT && flag_pic == 2)
+ return "bl %z1+32768@plt";
+ else
+ return "bl %z1@plt";
+ }
+ else
+ return "bl %z1";
#endif
}
[(set_attr "type" "branch,branch")
@@ -10567,7 +10643,15 @@
else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
output_asm_insn (\"creqv 6,6,6\", operands);
- return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@plt\" : \"b %z0\";
+ if (DEFAULT_ABI == ABI_V4 && flag_pic)
+ {
+ if (TARGET_SECURE_PLT && flag_pic == 2)
+ return \"b %z0+32768@plt\";
+ else
+ return \"b %z0@plt\";
+ }
+ else
+ return \"b %z0\";
}"
[(set_attr "type" "branch,branch")
(set_attr "length" "4,8")])
@@ -10613,7 +10697,15 @@
else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
output_asm_insn (\"creqv 6,6,6\", operands);
- return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@plt\" : \"b %z1\";
+ if (DEFAULT_ABI == ABI_V4 && flag_pic)
+ {
+ if (TARGET_SECURE_PLT && flag_pic == 2)
+ return \"b %z1+32768@plt\";
+ else
+ return \"b %z1@plt\";
+ }
+ else
+ return \"b %z1\";
}"
[(set_attr "type" "branch,branch")
(set_attr "length" "4,8")])
@@ -14776,6 +14868,23 @@
"<larx> %3,%y0\n\t%q4 %2,%1,%3\n\t<stcx> %2,%y0\n\tbne- $-12"
[(set_attr "length" "16")])
+; This pattern could also take immediate values of operand 1,
+; since the non-NOT version of the operator is used; but this is not
+; very useful, since in practice operand 1 is a full 32-bit value.
+; Likewise, operand 5 is in practice either <= 2^16 or it is a register.
+(define_insn "*sync_boolcshort_internal"
+ [(set (match_operand:SI 2 "gpc_reg_operand" "=&r")
+ (match_operator:SI 4 "boolean_operator"
+ [(xor:SI (match_operand:SI 0 "memory_operand" "+Z")
+ (match_operand:SI 5 "logical_operand" "rK"))
+ (match_operand:SI 1 "gpc_reg_operand" "r")]))
+ (set (match_operand:SI 3 "gpc_reg_operand" "=&b") (match_dup 0))
+ (set (match_dup 0) (unspec:SI [(match_dup 4)] UNSPEC_SYNC_OP))
+ (clobber (match_scratch:CC 6 "=&x"))]
+ "TARGET_POWERPC"
+ "lwarx %3,%y0\n\txor%I2 %2,%3,%5\n\t%q4 %2,%2,%1\n\tstwcx. %2,%y0\n\tbne- $-16"
+ [(set_attr "length" "20")])
+
(define_insn "*sync_boolc<mode>_internal2"
[(set (match_operand:GPR 2 "gpc_reg_operand" "=&r")
(match_operator:GPR 4 "boolean_operator"
diff --git a/gcc/config/rs6000/rs6000.opt b/gcc/config/rs6000/rs6000.opt
index 84ceba07012..fd5d3b09338 100644
--- a/gcc/config/rs6000/rs6000.opt
+++ b/gcc/config/rs6000/rs6000.opt
@@ -227,5 +227,5 @@ Target RejectNegative Joined
Specify alignment of structure fields default/natural
mprioritize-restricted-insns=
-Target RejectNegative Joined Uinteger Var(rs6000_sched_restricted_insns_priority)
+Target RejectNegative Joined UInteger Var(rs6000_sched_restricted_insns_priority)
Specify scheduling priority for dispatch slot restricted insns
diff --git a/gcc/config/rs6000/sysv4.h b/gcc/config/rs6000/sysv4.h
index a8b06aedb16..ed5deb1a55e 100644
--- a/gcc/config/rs6000/sysv4.h
+++ b/gcc/config/rs6000/sysv4.h
@@ -59,6 +59,11 @@ extern enum rs6000_sdata_type rs6000_sdata;
#define TARGET_NO_TOC (! TARGET_TOC)
#define TARGET_NO_EABI (! TARGET_EABI)
+#ifdef HAVE_AS_REL16
+#undef TARGET_SECURE_PLT
+#define TARGET_SECURE_PLT secure_plt
+#endif
+
extern const char *rs6000_abi_name;
extern const char *rs6000_sdata_name;
extern const char *rs6000_tls_size_string; /* For -mtls-size= */
@@ -205,6 +210,11 @@ do { \
error ("-mcall-aixdesc must be big endian"); \
} \
\
+ if (TARGET_SECURE_PLT != secure_plt) \
+ { \
+ error ("-msecure-plt not supported by your assembler"); \
+ } \
+ \
/* Treat -fPIC the same as -mrelocatable. */ \
if (flag_pic > 1 && DEFAULT_ABI != ABI_AIX) \
target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC | MASK_NO_FP_IN_TOC; \
@@ -750,6 +760,10 @@ extern int fixuplabelno;
#define CC1_ENDIAN_DEFAULT_SPEC "%(cc1_endian_big)"
+#ifndef CC1_SECURE_PLT_DEFAULT_SPEC
+#define CC1_SECURE_PLT_DEFAULT_SPEC ""
+#endif
+
/* Pass -G xxx to the compiler and set correct endian mode. */
#define CC1_SPEC "%{G*} \
%{mlittle|mlittle-endian: %(cc1_endian_little); \
@@ -762,7 +776,6 @@ extern int fixuplabelno;
mcall-gnu : -mbig %(cc1_endian_big); \
mcall-i960-old : -mlittle %(cc1_endian_little); \
: %(cc1_endian_default)} \
-%{mno-sdata: -msdata=none } \
%{meabi: %{!mcall-*: -mcall-sysv }} \
%{!meabi: %{!mno-eabi: \
%{mrelocatable: -meabi } \
@@ -774,6 +787,7 @@ extern int fixuplabelno;
%{mcall-openbsd: -mno-eabi }}} \
%{msdata: -msdata=default} \
%{mno-sdata: -msdata=none} \
+%{!mbss-plt: %{!msecure-plt: %(cc1_secure_plt_default)}} \
%{profile: -p}"
/* Don't put -Y P,<path> for cross compilers. */
@@ -1214,6 +1228,7 @@ ncrtn.o%s"
{ "cc1_endian_big", CC1_ENDIAN_BIG_SPEC }, \
{ "cc1_endian_little", CC1_ENDIAN_LITTLE_SPEC }, \
{ "cc1_endian_default", CC1_ENDIAN_DEFAULT_SPEC }, \
+ { "cc1_secure_plt_default", CC1_SECURE_PLT_DEFAULT_SPEC }, \
{ "cpp_os_ads", CPP_OS_ADS_SPEC }, \
{ "cpp_os_yellowknife", CPP_OS_YELLOWKNIFE_SPEC }, \
{ "cpp_os_mvme", CPP_OS_MVME_SPEC }, \
diff --git a/gcc/config/rs6000/sysv4.opt b/gcc/config/rs6000/sysv4.opt
index d826c55dd72..289c6e19e21 100644
--- a/gcc/config/rs6000/sysv4.opt
+++ b/gcc/config/rs6000/sysv4.opt
@@ -139,3 +139,11 @@ Generate 32-bit code
mnewlib
Target RejectNegative
no description yet
+
+msecure-plt
+Target Report RejectNegative Var(secure_plt, 1)
+Generate code to use a non-exec PLT and GOT
+
+mbss-plt
+Target Report RejectNegative Var(secure_plt, 0)
+Generate code for old exec BSS PLT
diff --git a/gcc/config/rs6000/t-rtems b/gcc/config/rs6000/t-rtems
index fe266272a5e..b3db9498a23 100644
--- a/gcc/config/rs6000/t-rtems
+++ b/gcc/config/rs6000/t-rtems
@@ -1,13 +1,11 @@
# Multilibs for powerpc RTEMS targets.
MULTILIB_OPTIONS = \
-D_OLD_EXCEPTIONS \
mcpu=403/mcpu=505/mcpu=601/mcpu=603e/mcpu=604/mcpu=860/mcpu=7400 \
Dmpc8260 \
msoft-float
MULTILIB_DIRNAMES = \
-roe \
m403 m505 m601 m603e m604 m860 m7400 \
mpc8260 \
nof
@@ -33,38 +31,6 @@ MULTILIB_MATCHES += mcpu?7400=mcpu?7450
# Map 750 to .
MULTILIB_MATCHES += mcpu?750=
-
-#
-# RTEMS old/new-exceptions handling
-#
-# old-exception processing is depredicated, therefore
-#
-# * Cpu-variants supporting new exception processing are build
-# with new exception processing only
-# * Cpu-variants not having been ported to new exception processing are
-# build with old and new exception processing
-#
-
-# Cpu-variants supporting new exception processing only
-MULTILIB_NEW_EXCEPTIONS_ONLY = \
-D_OLD_EXCEPTIONS \
-D_OLD_EXCEPTIONS/msoft-float \
-D_OLD_EXCEPTIONS/mcpu=505 \
-D_OLD_EXCEPTIONS/mcpu=505/* \
-D_OLD_EXCEPTIONS/mcpu=601 \
-D_OLD_EXCEPTIONS/mcpu=601/* \
-D_OLD_EXCEPTIONS/mcpu=603e \
-D_OLD_EXCEPTIONS/mcpu=603e/* \
-D_OLD_EXCEPTIONS/mcpu=604 \
-D_OLD_EXCEPTIONS/mcpu=604/* \
-D_OLD_EXCEPTIONS/mcpu=750 \
-D_OLD_EXCEPTIONS/mcpu=750/* \
-D_OLD_EXCEPTIONS/mcpu=860 \
-D_OLD_EXCEPTIONS/mcpu=860/* \
-D_OLD_EXCEPTIONS/mcpu=7400 \
-D_OLD_EXCEPTIONS/mcpu=7400/* \
-D_OLD_EXCEPTIONS/*Dmpc*
-
# Soft-float only, default implies msoft-float
# NOTE: Must match with MULTILIB_MATCHES_FLOAT and MULTILIB_MATCHES
MULTILIB_SOFTFLOAT_ONLY = \
@@ -86,7 +52,6 @@ MULTILIB_EXCEPTIONS =
MULTILIB_EXCEPTIONS += Dppc* Dmpc*
MULTILIB_EXCEPTIONS += \
-${MULTILIB_NEW_EXCEPTIONS_ONLY} \
${MULTILIB_SOFTFLOAT_ONLY} \
${MULTILIB_HARDFLOAT_ONLY}
diff --git a/gcc/config/rs6000/tramp.asm b/gcc/config/rs6000/tramp.asm
index 284f9386074..0c6127d567b 100644
--- a/gcc/config/rs6000/tramp.asm
+++ b/gcc/config/rs6000/tramp.asm
@@ -44,7 +44,7 @@
.align 2
trampoline_initial:
mflr r0
- bl 1f
+ bcl 20,31,1f
.Lfunc = .-trampoline_initial
.long 0 /* will be replaced with function address */
.Lchain = .-trampoline_initial
@@ -67,7 +67,7 @@ trampoline_size = .-trampoline_initial
FUNC_START(__trampoline_setup)
mflr r0 /* save return address */
- bl .LCF0 /* load up __trampoline_initial into r7 */
+ bcl 20,31,.LCF0 /* load up __trampoline_initial into r7 */
.LCF0:
mflr r11
addi r7,r11,trampoline_initial-4-.LCF0 /* trampoline address -4 */
@@ -105,6 +105,12 @@ FUNC_START(__trampoline_setup)
blr
.Labort:
+#if defined SHARED && defined HAVE_AS_REL16
+ bcl 20,31,1f
+1: mflr r30
+ addis r30,r30,_GLOBAL_OFFSET_TABLE_-1b@ha
+ addi r30,r30,_GLOBAL_OFFSET_TABLE_-1b@l
+#endif
bl JUMP_TARGET(abort)
FUNC_END(__trampoline_setup)
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index 2c860e7da1b..354f55e26fb 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -186,7 +186,6 @@ enum processor_flags s390_tune_flags;
/* Which instruction set architecture to use. */
enum processor_type s390_arch;
enum processor_flags s390_arch_flags;
-static const char *s390_arch_string;
HOST_WIDE_INT s390_warn_framesize = 0;
HOST_WIDE_INT s390_stack_size = 0;
@@ -1128,7 +1127,6 @@ s390_handle_option (size_t code, const char *arg, int value ATTRIBUTE_UNUSED)
switch (code)
{
case OPT_march_:
- s390_arch_string = arg;
return s390_handle_arch_option (arg, &s390_arch, &s390_arch_flags);
case OPT_mstack_guard_:
@@ -4674,15 +4672,12 @@ s390_add_execute (struct constant_pool *pool, rtx insn)
if (c == NULL)
{
- rtx label = s390_execute_label (insn);
- gcc_assert (label);
-
c = (struct constant *) xmalloc (sizeof *c);
c->value = insn;
- c->label = label == const0_rtx ? gen_label_rtx () : XEXP (label, 0);
+ c->label = gen_label_rtx ();
c->next = pool->execute;
pool->execute = c;
- pool->size += label == const0_rtx ? 6 : 0;
+ pool->size += 6;
}
}
@@ -4734,28 +4729,6 @@ s390_execute_target (rtx insn)
return pattern;
}
-/* Dump out the out-of-pool execute template insns in POOL
- at the end of the instruction stream. */
-
-static void
-s390_dump_execute (struct constant_pool *pool)
-{
- struct constant *c;
- rtx insn;
-
- for (c = pool->execute; c; c = c->next)
- {
- if (s390_execute_label (c->value) == const0_rtx)
- continue;
-
- insn = emit_label (c->label);
- INSN_ADDRESSES_NEW (insn, -1);
-
- insn = emit_insn (s390_execute_target (c->value));
- INSN_ADDRESSES_NEW (insn, -1);
- }
-}
-
/* Indicate that INSN cannot be duplicated. This is the case for
execute insns that carry a unique label. */
@@ -4831,9 +4804,6 @@ s390_dump_pool (struct constant_pool *pool, bool remote_label)
/* Output in-pool execute template insns. */
for (c = pool->execute; c; c = c->next)
{
- if (s390_execute_label (c->value) != const0_rtx)
- continue;
-
insn = emit_label_after (c->label, insn);
INSN_ADDRESSES_NEW (insn, -1);
@@ -4853,9 +4823,6 @@ s390_dump_pool (struct constant_pool *pool, bool remote_label)
/* Remove placeholder insn. */
remove_insn (pool->pool_insn);
-
- /* Output out-of-pool execute template isns. */
- s390_dump_execute (pool);
}
/* Free all memory used by POOL. */
@@ -4905,7 +4872,7 @@ s390_mainpool_start (void)
pool->pool_insn = insn;
}
- if (s390_execute_label (insn))
+ if (!TARGET_CPU_ZARCH && s390_execute_label (insn))
{
s390_add_execute (pool, insn);
}
@@ -4950,9 +4917,6 @@ s390_mainpool_finish (struct constant_pool *pool)
/* If the pool is empty, we're done. */
if (pool->size == 0)
{
- /* However, we may have out-of-pool execute templates. */
- s390_dump_execute (pool);
-
/* We don't actually need a base register after all. */
cfun->machine->base_reg = NULL_RTX;
@@ -5105,7 +5069,7 @@ s390_chunkify_start (void)
}
}
- if (s390_execute_label (insn))
+ if (!TARGET_CPU_ZARCH && s390_execute_label (insn))
{
if (!curr_pool)
curr_pool = s390_start_pool (&pool_list, insn);
@@ -8190,6 +8154,28 @@ s390_reorg (void)
break;
}
+ /* Generate out-of-pool execute target insns. */
+ if (TARGET_CPU_ZARCH)
+ {
+ rtx insn, label, target;
+
+ for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+ {
+ label = s390_execute_label (insn);
+ if (!label)
+ continue;
+
+ gcc_assert (label != const0_rtx);
+
+ target = emit_label (XEXP (label, 0));
+ INSN_ADDRESSES_NEW (target, -1);
+
+ target = emit_insn (s390_execute_target (insn));
+ INSN_ADDRESSES_NEW (target, -1);
+ }
+ }
+
+ /* Try to optimize prologue and epilogue further. */
s390_optimize_prologue ();
}
diff --git a/gcc/config/s390/s390.opt b/gcc/config/s390/s390.opt
index 9ece6f13a3c..e020e63f221 100644
--- a/gcc/config/s390/s390.opt
+++ b/gcc/config/s390/s390.opt
@@ -28,7 +28,7 @@ Target Report RejectNegative Mask(64BIT)
64 bit ABI
march=
-Target RejectNegative Joined
+Target RejectNegative Joined Var(s390_arch_string)
Generate code for given CPU
mbackchain
diff --git a/gcc/config/sh/elf.h b/gcc/config/sh/elf.h
index 52d0727eb64..c53c4be54ff 100644
--- a/gcc/config/sh/elf.h
+++ b/gcc/config/sh/elf.h
@@ -1,5 +1,5 @@
/* Definitions of target machine for gcc for Renesas / SuperH SH using ELF.
- Copyright (C) 1996, 1997, 2000, 2001, 2002, 2004
+ Copyright (C) 1996, 1997, 2000, 2001, 2002, 2004, 2005
Free Software Foundation, Inc.
Contributed by Ian Lance Taylor <ian@cygnus.com>.
diff --git a/gcc/config/sh/predicates.md b/gcc/config/sh/predicates.md
index 981cc8f10f5..324d30da802 100644
--- a/gcc/config/sh/predicates.md
+++ b/gcc/config/sh/predicates.md
@@ -1,3 +1,25 @@
+;; Predicate definitions for Renesas / SuperH SH.
+;; Copyright (C) 2005 Free Software Foundation, Inc.
+;;
+;; This file is part of GCC.
+;;
+;; GCC is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+;;
+;; GCC is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GCC; see the file COPYING. If not, write to
+;; the Free Software Foundation, 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;; TODO: Add a comment here.
+
(define_predicate "trapping_target_operand"
(match_code "if_then_else")
{
@@ -36,3 +58,861 @@
&& INTVAL (XEXP (and, 1)) == 3
&& INTVAL (XEXP (cond, 1)) == 3);
})
+
+;; TODO: Add a comment here.
+
+(define_predicate "and_operand"
+ (match_code "subreg,reg,const_int")
+{
+ if (logical_operand (op, mode))
+ return 1;
+
+ /* Check mshflo.l / mshflhi.l opportunities. */
+ if (TARGET_SHMEDIA
+ && mode == DImode
+ && GET_CODE (op) == CONST_INT
+ && CONST_OK_FOR_J16 (INTVAL (op)))
+ return 1;
+
+ return 0;
+})
+
+;; Like arith_reg_dest, but this predicate belongs to
+;; SPECIAL_MODE_PREDICATES.
+
+(define_special_predicate "any_arith_reg_dest"
+ (match_code "subreg,reg")
+{
+ return arith_reg_dest (op, mode);
+})
+
+;; Like register_operand, but this predicate belongs to
+;; SPECIAL_MODE_PREDICATES.
+
+(define_special_predicate "any_register_operand"
+ (match_code "subreg,reg")
+{
+ return register_operand (op, mode);
+})
+
+;; Returns 1 if OP is a valid source operand for an arithmetic insn.
+
+(define_predicate "arith_operand"
+ (match_code "subreg,reg,const_int,truncate")
+{
+ if (arith_reg_operand (op, mode))
+ return 1;
+
+ if (TARGET_SHMEDIA)
+ {
+ /* FIXME: We should be checking whether the CONST_INT fits in a
+ CONST_OK_FOR_I16 here, but this causes reload_cse to crash when
+ attempting to transform a sequence of two 64-bit sets of the
+ same register from literal constants into a set and an add,
+ when the difference is too wide for an add. */
+ if (GET_CODE (op) == CONST_INT
+ || EXTRA_CONSTRAINT_C16 (op))
+ return 1;
+ else if (GET_CODE (op) == TRUNCATE
+ && ! system_reg_operand (XEXP (op, 0), VOIDmode)
+ && (mode == VOIDmode || mode == GET_MODE (op))
+ && (GET_MODE_SIZE (GET_MODE (op))
+ < GET_MODE_SIZE (GET_MODE (XEXP (op, 0))))
+ && (! FP_REGISTER_P (REGNO (XEXP (op, 0)))
+ || GET_MODE_SIZE (GET_MODE (op)) == 4))
+ return register_operand (XEXP (op, 0), VOIDmode);
+ else
+ return 0;
+ }
+ else if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_I08 (INTVAL (op)))
+ return 1;
+
+ return 0;
+})
+
+;; Like above, but for DImode destinations: forbid paradoxical DImode
+;; subregs, because this would lead to missing sign extensions when
+;; truncating from DImode to SImode.
+
+(define_predicate "arith_reg_dest"
+ (match_code "subreg,reg")
+{
+ if (mode == DImode && GET_CODE (op) == SUBREG
+ && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) < 8
+ && TARGET_SHMEDIA)
+ return 0;
+ return arith_reg_operand (op, mode);
+})
+
+;; Returns 1 if OP is a normal arithmetic register.
+
+(define_predicate "arith_reg_operand"
+ (match_code "subreg,reg,sign_extend")
+{
+ if (register_operand (op, mode))
+ {
+ int regno;
+
+ if (GET_CODE (op) == REG)
+ regno = REGNO (op);
+ else if (GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == REG)
+ regno = REGNO (SUBREG_REG (op));
+ else
+ return 1;
+
+ return (regno != T_REG && regno != PR_REG
+ && ! TARGET_REGISTER_P (regno)
+ && (regno != FPUL_REG || TARGET_SH4)
+ && regno != MACH_REG && regno != MACL_REG);
+ }
+ /* Allow a no-op sign extension - compare LOAD_EXTEND_OP.
+ We allow SImode here, as not using an FP register is just a matter of
+ proper register allocation. */
+ if (TARGET_SHMEDIA
+ && GET_MODE (op) == DImode && GET_CODE (op) == SIGN_EXTEND
+ && GET_MODE (XEXP (op, 0)) == SImode
+ && GET_CODE (XEXP (op, 0)) != SUBREG)
+ return register_operand (XEXP (op, 0), VOIDmode);
+#if 0 /* Can't do this because of PROMOTE_MODE for unsigned vars. */
+ if (GET_MODE (op) == SImode && GET_CODE (op) == SIGN_EXTEND
+ && GET_MODE (XEXP (op, 0)) == HImode
+ && GET_CODE (XEXP (op, 0)) == REG
+ && REGNO (XEXP (op, 0)) <= LAST_GENERAL_REG)
+ return register_operand (XEXP (op, 0), VOIDmode);
+#endif
+ if (GET_MODE_CLASS (GET_MODE (op)) == MODE_VECTOR_INT
+ && GET_CODE (op) == SUBREG
+ && GET_MODE (SUBREG_REG (op)) == DImode
+ && GET_CODE (SUBREG_REG (op)) == SIGN_EXTEND
+ && GET_MODE (XEXP (SUBREG_REG (op), 0)) == SImode
+ && GET_CODE (XEXP (SUBREG_REG (op), 0)) != SUBREG)
+ return register_operand (XEXP (SUBREG_REG (op), 0), VOIDmode);
+ return 0;
+})
+
+;; Returns 1 if OP is a valid source operand for a compare insn.
+
+(define_predicate "arith_reg_or_0_operand"
+ (match_code "subreg,reg,const_int,const_vector")
+{
+ if (arith_reg_operand (op, mode))
+ return 1;
+
+ if (EXTRA_CONSTRAINT_Z (op))
+ return 1;
+
+ return 0;
+})
+
+;; TODO: Add a comment here.
+
+(define_predicate "binary_float_operator"
+ (match_code "plus,minus,mult,div")
+{
+ if (GET_MODE (op) != mode)
+ return 0;
+ switch (GET_CODE (op))
+ {
+ case PLUS:
+ case MINUS:
+ case MULT:
+ case DIV:
+ return 1;
+ default:
+ break;
+ }
+ return 0;
+})
+
+;; TODO: Add a comment here.
+
+(define_predicate "binary_logical_operator"
+ (match_code "and,ior,xor")
+{
+ if (GET_MODE (op) != mode)
+ return 0;
+ switch (GET_CODE (op))
+ {
+ case IOR:
+ case AND:
+ case XOR:
+ return 1;
+ default:
+ break;
+ }
+ return 0;
+})
+
+;; TODO: Add a comment here.
+
+(define_predicate "cache_address_operand"
+ (match_code "plus,reg")
+{
+ if (GET_CODE (op) == PLUS)
+ {
+ if (GET_CODE (XEXP (op, 0)) != REG)
+ return 0;
+ if (GET_CODE (XEXP (op, 1)) != CONST_INT
+ || (INTVAL (XEXP (op, 1)) & 31))
+ return 0;
+ }
+ else if (GET_CODE (op) != REG)
+ return 0;
+ return address_operand (op, mode);
+})
+
+;; Return 1 if OP is a valid source operand for shmedia cmpgt / cmpgtu.
+
+(define_predicate "cmp_operand"
+ (match_code "subreg,reg,const_int")
+{
+ if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_N (INTVAL (op)))
+ return 1;
+ if (TARGET_SHMEDIA
+ && mode != DImode && GET_CODE (op) == SUBREG
+ && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) > 4)
+ return 0;
+ return arith_reg_operand (op, mode);
+})
+
+;; TODO: Add a comment here.
+
+(define_predicate "cmpsi_operand"
+ (match_code "subreg,reg,const_int")
+{
+ if (GET_CODE (op) == REG && REGNO (op) == T_REG
+ && GET_MODE (op) == SImode
+ && TARGET_SH1)
+ return 1;
+ return arith_operand (op, mode);
+})
+
+;; TODO: Add a comment here.
+
+(define_predicate "commutative_float_operator"
+ (match_code "plus,mult")
+{
+ if (GET_MODE (op) != mode)
+ return 0;
+ switch (GET_CODE (op))
+ {
+ case PLUS:
+ case MULT:
+ return 1;
+ default:
+ break;
+ }
+ return 0;
+})
+
+;; TODO: Add a comment here.
+
+(define_predicate "equality_comparison_operator"
+ (match_code "eq,ne")
+{
+ return ((mode == VOIDmode || GET_MODE (op) == mode)
+ && (GET_CODE (op) == EQ || GET_CODE (op) == NE));
+})
+
+;; TODO: Add a comment here.
+
+(define_predicate "extend_reg_operand"
+ (match_code "subreg,reg,truncate")
+{
+ return (GET_CODE (op) == TRUNCATE
+ ? arith_operand
+ : arith_reg_operand) (op, mode);
+})
+
+;; TODO: Add a comment here.
+
+(define_predicate "extend_reg_or_0_operand"
+ (match_code "subreg,reg,truncate,const_int")
+{
+ return (GET_CODE (op) == TRUNCATE
+ ? arith_operand
+ : arith_reg_or_0_operand) (op, mode);
+})
+
+;; Like arith_reg_operand, but this predicate does not accept SIGN_EXTEND.
+
+(define_predicate "ext_dest_operand"
+ (match_code "subreg,reg")
+{
+ return arith_reg_operand (op, mode);
+})
+
+;; TODO: Add a comment here.
+
+(define_predicate "fp_arith_reg_dest"
+ (match_code "subreg,reg")
+{
+ if (mode == DImode && GET_CODE (op) == SUBREG
+ && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) < 8)
+ return 0;
+ return fp_arith_reg_operand (op, mode);
+})
+
+;; TODO: Add a comment here.
+
+(define_predicate "fp_arith_reg_operand"
+ (match_code "subreg,reg")
+{
+ if (register_operand (op, mode))
+ {
+ int regno;
+
+ if (GET_CODE (op) == REG)
+ regno = REGNO (op);
+ else if (GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == REG)
+ regno = REGNO (SUBREG_REG (op));
+ else
+ return 1;
+
+ return (regno >= FIRST_PSEUDO_REGISTER
+ || FP_REGISTER_P (regno));
+ }
+ return 0;
+})
+
+;; TODO: Add a comment here.
+
+(define_predicate "fpscr_operand"
+ (match_code "reg")
+{
+ return (GET_CODE (op) == REG
+ && (REGNO (op) == FPSCR_REG
+ || (REGNO (op) >= FIRST_PSEUDO_REGISTER
+ && !(reload_in_progress || reload_completed)))
+ && GET_MODE (op) == PSImode);
+})
+
+;; TODO: Add a comment here.
+
+(define_predicate "fpul_operand"
+ (match_code "reg")
+{
+ if (TARGET_SHMEDIA)
+ return fp_arith_reg_operand (op, mode);
+
+ return (GET_CODE (op) == REG
+ && (REGNO (op) == FPUL_REG || REGNO (op) >= FIRST_PSEUDO_REGISTER)
+ && GET_MODE (op) == mode);
+})
+
+;; TODO: Add a comment here.
+
+(define_predicate "general_extend_operand"
+ (match_code "subreg,reg,mem,truncate")
+{
+ return (GET_CODE (op) == TRUNCATE
+ ? arith_operand
+ : nonimmediate_operand) (op, mode);
+})
+
+;; Returns 1 if OP can be source of a simple move operation. Same as
+;; general_operand, but a LABEL_REF is valid, PRE_DEC is invalid as
+;; are subregs of system registers.
+
+(define_predicate "general_movsrc_operand"
+ (match_code "subreg,reg,const_int,const_double,mem,symbol_ref,label_ref,const,const_vector")
+{
+ if (GET_CODE (op) == MEM)
+ {
+ rtx inside = XEXP (op, 0);
+ if (GET_CODE (inside) == CONST)
+ inside = XEXP (inside, 0);
+
+ if (GET_CODE (inside) == LABEL_REF)
+ return 1;
+
+ if (GET_CODE (inside) == PLUS
+ && GET_CODE (XEXP (inside, 0)) == LABEL_REF
+ && GET_CODE (XEXP (inside, 1)) == CONST_INT)
+ return 1;
+
+ /* Only post inc allowed. */
+ if (GET_CODE (inside) == PRE_DEC)
+ return 0;
+ }
+
+ if ((mode == QImode || mode == HImode)
+ && (GET_CODE (op) == SUBREG
+ && GET_CODE (XEXP (op, 0)) == REG
+ && system_reg_operand (XEXP (op, 0), mode)))
+ return 0;
+
+ if (TARGET_SHMEDIA
+ && (GET_CODE (op) == PARALLEL || GET_CODE (op) == CONST_VECTOR)
+ && sh_rep_vec (op, mode))
+ return 1;
+ if (TARGET_SHMEDIA && 1
+ && GET_CODE (op) == SUBREG && GET_MODE (op) == mode
+ && SUBREG_REG (op) == const0_rtx && subreg_lowpart_p (op))
+ /* FIXME */ abort (); /* return 1; */
+ return general_operand (op, mode);
+})
+
+;; Returns 1 if OP can be a destination of a move. Same as
+;; general_operand, but no preinc allowed.
+
+(define_predicate "general_movdst_operand"
+ (match_code "subreg,reg,mem")
+{
+ /* Only pre dec allowed. */
+ if (GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) == POST_INC)
+ return 0;
+ if (mode == DImode && TARGET_SHMEDIA && GET_CODE (op) == SUBREG
+ && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) < 8
+ && ! (high_life_started || reload_completed))
+ return 0;
+
+ return general_operand (op, mode);
+})
+
+;; Returns 1 if OP is a MEM that can be source of a simple move operation.
+
+(define_predicate "unaligned_load_operand"
+ (match_code "mem")
+{
+ rtx inside;
+
+ if (GET_CODE (op) != MEM || GET_MODE (op) != mode)
+ return 0;
+
+ inside = XEXP (op, 0);
+
+ if (GET_CODE (inside) == POST_INC)
+ inside = XEXP (inside, 0);
+
+ if (GET_CODE (inside) == REG)
+ return 1;
+
+ return 0;
+})
+
+;; TODO: Add a comment here.
+
+(define_predicate "greater_comparison_operator"
+ (match_code "gt,ge,gtu,geu")
+{
+ if (mode != VOIDmode && GET_MODE (op) != mode)
+ return 0;
+ switch (GET_CODE (op))
+ {
+ case GT:
+ case GE:
+ case GTU:
+ case GEU:
+ return 1;
+ default:
+ return 0;
+ }
+})
+
+;; TODO: Add a comment here.
+
+(define_predicate "inqhi_operand"
+ (match_code "truncate")
+{
+ if (GET_CODE (op) != TRUNCATE || mode != GET_MODE (op))
+ return 0;
+ op = XEXP (op, 0);
+ /* Can't use true_regnum here because copy_cost wants to know about
+ SECONDARY_INPUT_RELOAD_CLASS. */
+ return GET_CODE (op) == REG && FP_REGISTER_P (REGNO (op));
+})
+
+;; TODO: Add a comment here.
+
+(define_special_predicate "int_gpr_dest"
+ (match_code "subreg,reg")
+{
+ enum machine_mode op_mode = GET_MODE (op);
+
+ if (GET_MODE_CLASS (op_mode) != MODE_INT
+ || GET_MODE_SIZE (op_mode) >= UNITS_PER_WORD)
+ return 0;
+ if (! reload_completed)
+ return 0;
+ return true_regnum (op) <= LAST_GENERAL_REG;
+})
+
+;; TODO: Add a comment here.
+
+(define_predicate "less_comparison_operator"
+ (match_code "lt,le,ltu,leu")
+{
+ if (mode != VOIDmode && GET_MODE (op) != mode)
+ return 0;
+ switch (GET_CODE (op))
+ {
+ case LT:
+ case LE:
+ case LTU:
+ case LEU:
+ return 1;
+ default:
+ return 0;
+ }
+})
+
+;; Returns 1 if OP is a valid source operand for a logical operation.
+
+(define_predicate "logical_operand"
+ (match_code "subreg,reg,const_int")
+{
+ if (TARGET_SHMEDIA
+ && mode != DImode && GET_CODE (op) == SUBREG
+ && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) > 4)
+ return 0;
+
+ if (arith_reg_operand (op, mode))
+ return 1;
+
+ if (TARGET_SHMEDIA)
+ {
+ if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_I10 (INTVAL (op)))
+ return 1;
+ else
+ return 0;
+ }
+ else if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_K08 (INTVAL (op)))
+ return 1;
+
+ return 0;
+})
+
+;; TODO: Add a comment here.
+
+(define_predicate "logical_operator"
+ (match_code "and,ior,xor")
+{
+ if (mode != VOIDmode && GET_MODE (op) != mode)
+ return 0;
+ switch (GET_CODE (op))
+ {
+ case AND:
+ case IOR:
+ case XOR:
+ return 1;
+ default:
+ return 0;
+ }
+})
+
+;; Like arith_reg_operand, but for register source operands of narrow
+;; logical SHMEDIA operations: forbid subregs of DImode / TImode regs.
+
+(define_predicate "logical_reg_operand"
+ (match_code "subreg,reg")
+{
+ if (TARGET_SHMEDIA
+ && GET_CODE (op) == SUBREG
+ && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) > 4
+ && mode != DImode)
+ return 0;
+ return arith_reg_operand (op, mode);
+})
+
+;; TODO: Add a comment here.
+
+(define_predicate "mextr_bit_offset"
+ (match_code "const_int")
+{
+ HOST_WIDE_INT i;
+
+ if (GET_CODE (op) != CONST_INT)
+ return 0;
+ i = INTVAL (op);
+ return i >= 1 * 8 && i <= 7 * 8 && (i & 7) == 0;
+})
+
+;; TODO: Add a comment here.
+
+(define_predicate "minuend_operand"
+ (match_code "subreg,reg,truncate,const_int")
+{
+ return op == constm1_rtx || extend_reg_or_0_operand (op, mode);
+})
+
+;; TODO: Add a comment here.
+
+(define_predicate "noncommutative_float_operator"
+ (match_code "minus,div")
+{
+ if (GET_MODE (op) != mode)
+ return 0;
+ switch (GET_CODE (op))
+ {
+ case MINUS:
+ case DIV:
+ return 1;
+ default:
+ break;
+ }
+ return 0;
+})
+
+;; TODO: Add a comment here.
+
+(define_predicate "sh_const_vec"
+ (match_code "const_vector")
+{
+ int i;
+
+ if (GET_CODE (op) != CONST_VECTOR
+ || (GET_MODE (op) != mode && mode != VOIDmode))
+ return 0;
+ i = XVECLEN (op, 0) - 1;
+ for (; i >= 0; i--)
+ if (GET_CODE (XVECEXP (op, 0, i)) != CONST_INT)
+ return 0;
+ return 1;
+})
+
+;; Determine if OP is a constant vector matching MODE with only one
+;; element that is not a sign extension. Two byte-sized elements
+;; count as one.
+
+(define_predicate "sh_1el_vec"
+ (match_code "const_vector")
+{
+ int unit_size;
+ int i, last, least, sign_ix;
+ rtx sign;
+
+ if (GET_CODE (op) != CONST_VECTOR
+ || (GET_MODE (op) != mode && mode != VOIDmode))
+ return 0;
+ /* Determine numbers of last and of least significant elements. */
+ last = XVECLEN (op, 0) - 1;
+ least = TARGET_LITTLE_ENDIAN ? 0 : last;
+ if (GET_CODE (XVECEXP (op, 0, least)) != CONST_INT)
+ return 0;
+ sign_ix = least;
+ if (GET_MODE_UNIT_SIZE (mode) == 1)
+ sign_ix = TARGET_LITTLE_ENDIAN ? 1 : last - 1;
+ if (GET_CODE (XVECEXP (op, 0, sign_ix)) != CONST_INT)
+ return 0;
+ unit_size = GET_MODE_UNIT_SIZE (GET_MODE (op));
+ sign = (INTVAL (XVECEXP (op, 0, sign_ix)) >> (unit_size * BITS_PER_UNIT - 1)
+ ? constm1_rtx : const0_rtx);
+ i = XVECLEN (op, 0) - 1;
+ do
+ if (i != least && i != sign_ix && XVECEXP (op, 0, i) != sign)
+ return 0;
+ while (--i);
+ return 1;
+})
+
+;; Like register_operand, but take into account that SHMEDIA can use
+;; the constant zero like a general register.
+
+(define_predicate "sh_register_operand"
+ (match_code "reg,subreg,const_int")
+{
+ if (op == CONST0_RTX (mode) && TARGET_SHMEDIA)
+ return 1;
+ return register_operand (op, mode);
+})
+
+;; TODO: Add a comment here.
+
+(define_predicate "sh_rep_vec"
+ (match_code "const_vector")
+{
+ int i;
+ rtx x, y;
+
+ if ((GET_CODE (op) != CONST_VECTOR && GET_CODE (op) != PARALLEL)
+ || (GET_MODE (op) != mode && mode != VOIDmode))
+ return 0;
+ i = XVECLEN (op, 0) - 2;
+ x = XVECEXP (op, 0, i + 1);
+ if (GET_MODE_UNIT_SIZE (mode) == 1)
+ {
+ y = XVECEXP (op, 0, i);
+ for (i -= 2; i >= 0; i -= 2)
+ if (! rtx_equal_p (XVECEXP (op, 0, i + 1), x)
+ || ! rtx_equal_p (XVECEXP (op, 0, i), y))
+ return 0;
+ }
+ else
+ for (; i >= 0; i--)
+ if (XVECEXP (op, 0, i) != x)
+ return 0;
+ return 1;
+})
+
+;; TODO: Add a comment here.
+
+(define_predicate "shift_count_operand"
+ (match_code "const_int,const_double,const,symbol_ref,label_ref,subreg,reg,zero_extend,sign_extend")
+{
+ return (CONSTANT_P (op)
+ ? (GET_CODE (op) == CONST_INT
+ ? (unsigned) INTVAL (op) < GET_MODE_BITSIZE (mode)
+ : nonmemory_operand (op, mode))
+ : shift_count_reg_operand (op, mode));
+})
+
+;; TODO: Add a comment here.
+
+(define_predicate "shift_count_reg_operand"
+ (match_code "subreg,reg,zero_extend,sign_extend")
+{
+ if ((GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == SIGN_EXTEND
+ || (GET_CODE (op) == SUBREG && SUBREG_BYTE (op) == 0))
+ && (mode == VOIDmode || mode == GET_MODE (op))
+ && GET_MODE_BITSIZE (GET_MODE (XEXP (op, 0))) >= 6
+ && GET_MODE_CLASS (GET_MODE (XEXP (op, 0))) == MODE_INT)
+ {
+ mode = VOIDmode;
+ do
+ op = XEXP (op, 0);
+ while ((GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == SIGN_EXTEND
+ || GET_CODE (op) == TRUNCATE)
+ && GET_MODE_BITSIZE (GET_MODE (XEXP (op, 0))) >= 6
+ && GET_MODE_CLASS (GET_MODE (XEXP (op, 0))) == MODE_INT);
+
+ }
+ return arith_reg_operand (op, mode);
+})
+
+;; TODO: Add a comment here.
+
+(define_predicate "shift_operator"
+ (match_code "ashift,ashiftrt,lshiftrt")
+{
+ if (mode != VOIDmode && GET_MODE (op) != mode)
+ return 0;
+ switch (GET_CODE (op))
+ {
+ case ASHIFT:
+ case ASHIFTRT:
+ case LSHIFTRT:
+ return 1;
+ default:
+ return 0;
+ }
+})
+
+;; TODO: Add a comment here.
+
+(define_predicate "symbol_ref_operand"
+ (match_code "symbol_ref")
+{
+ return (GET_CODE (op) == SYMBOL_REF);
+})
+
+;; Same as target_reg_operand, except that label_refs and symbol_refs
+;; are accepted before reload.
+
+(define_special_predicate "target_operand"
+ (match_code "subreg,reg,label_ref,symbol_ref,const,unspec")
+{
+ if (mode != VOIDmode && mode != Pmode)
+ return 0;
+
+ if ((GET_MODE (op) == Pmode || GET_MODE (op) == VOIDmode)
+ && EXTRA_CONSTRAINT_Csy (op))
+ return ! reload_completed;
+
+ return target_reg_operand (op, mode);
+})
+
+;; Accept pseudos and branch target registers.
+
+(define_special_predicate "target_reg_operand"
+ (match_code "subreg,reg")
+{
+ if (mode == VOIDmode
+ ? GET_MODE (op) != Pmode && GET_MODE (op) != PDImode
+ : mode != GET_MODE (op))
+ return 0;
+
+ if (GET_CODE (op) == SUBREG)
+ op = XEXP (op, 0);
+
+ if (GET_CODE (op) != REG)
+ return 0;
+
+ /* We must protect ourselves from matching pseudos that are virtual
+ register, because they will eventually be replaced with hardware
+ registers that aren't branch-target registers. */
+ if (REGNO (op) > LAST_VIRTUAL_REGISTER
+ || TARGET_REGISTER_P (REGNO (op)))
+ return 1;
+
+ return 0;
+})
+
+;; TODO: Add a comment here.
+
+(define_special_predicate "trunc_hi_operand"
+ (match_code "subreg,reg,truncate")
+{
+ enum machine_mode op_mode = GET_MODE (op);
+
+ if (op_mode != SImode && op_mode != DImode
+ && op_mode != V4HImode && op_mode != V2SImode)
+ return 0;
+ return extend_reg_operand (op, mode);
+})
+
+;; TODO: Add a comment here.
+
+(define_predicate "ua_address_operand"
+ (match_code "subreg,reg,plus")
+{
+ if (GET_CODE (op) == PLUS
+ && (GET_CODE (XEXP (op, 1)) != CONST_INT
+ || ! CONST_OK_FOR_I06 (INTVAL (XEXP (op, 1)))))
+ return 0;
+ return address_operand (op, QImode);
+})
+
+;; TODO: Add a comment here.
+
+(define_predicate "ua_offset"
+ (match_code "const_int")
+{
+ return GET_CODE (op) == CONST_INT && CONST_OK_FOR_I06 (INTVAL (op));
+})
+
+;; TODO: Add a comment here.
+
+(define_predicate "unary_float_operator"
+ (match_code "abs,neg,sqrt")
+{
+ if (GET_MODE (op) != mode)
+ return 0;
+ switch (GET_CODE (op))
+ {
+ case ABS:
+ case NEG:
+ case SQRT:
+ return 1;
+ default:
+ break;
+ }
+ return 0;
+})
+
+;; Return 1 if OP is a valid source operand for xor.
+
+(define_predicate "xor_operand"
+ (match_code "subreg,reg,const_int")
+{
+ if (GET_CODE (op) == CONST_INT)
+ return (TARGET_SHMEDIA
+ ? (CONST_OK_FOR_I06 (INTVAL (op))
+ || (no_new_pseudos && INTVAL (op) == 0xff))
+ : CONST_OK_FOR_K08 (INTVAL (op)));
+ if (TARGET_SHMEDIA
+ && mode != DImode && GET_CODE (op) == SUBREG
+ && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) > 4)
+ return 0;
+ return arith_reg_operand (op, mode);
+})
diff --git a/gcc/config/sh/sh-protos.h b/gcc/config/sh/sh-protos.h
index d3644d87805..dd9d5c29540 100644
--- a/gcc/config/sh/sh-protos.h
+++ b/gcc/config/sh/sh-protos.h
@@ -159,7 +159,6 @@ extern rtx sh_function_arg (CUMULATIVE_ARGS *, enum machine_mode, tree, int);
extern void sh_function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, tree, int);
extern int sh_pass_in_reg_p (CUMULATIVE_ARGS *, enum machine_mode, tree);
extern void sh_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree, signed int, enum machine_mode);
-extern const char *sh_pch_valid_p (const void *data_p, size_t sz);
extern bool sh_promote_prototypes (tree);
extern rtx replace_n_hard_rtx (rtx, rtx *, int , int);
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index 9da837e4aa1..91fa5e9ce52 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -228,6 +228,7 @@ static tree sh_handle_trap_exit_attribute (tree *, tree, tree, int, bool *);
static tree sh_handle_renesas_attribute (tree *, tree, tree, int, bool *);
static void sh_output_function_epilogue (FILE *, HOST_WIDE_INT);
static void sh_insert_attributes (tree, tree *);
+static const char *sh_check_pch_target_flags (int);
static int sh_adjust_cost (rtx, rtx, rtx, int);
static int sh_issue_rate (void);
static int sh_dfa_new_cycle (FILE *, int, rtx, int, int, int *sort_p);
@@ -467,8 +468,8 @@ static int hard_regs_intersect_p (HARD_REG_SET *, HARD_REG_SET *);
#undef TARGET_VECTOR_MODE_SUPPORTED_P
#define TARGET_VECTOR_MODE_SUPPORTED_P sh_vector_mode_supported_p
-#undef TARGET_PCH_VALID_P
-#define TARGET_PCH_VALID_P sh_pch_valid_p
+#undef TARGET_CHECK_PCH_TARGET_FLAGS
+#define TARGET_CHECK_PCH_TARGET_FLAGS sh_check_pch_target_flags
#undef TARGET_DWARF_CALLING_CONVENTION
#define TARGET_DWARF_CALLING_CONVENTION sh_dwarf_calling_convention
@@ -1964,8 +1965,8 @@ addsubcosts (rtx x)
static inline int
multcosts (rtx x ATTRIBUTE_UNUSED)
{
- if (*sh_multcost_str)
- return atoi (sh_multcost_str);
+ if (sh_multcost >= 0)
+ return sh_multcost;
if (TARGET_SHMEDIA)
/* ??? We have a mul insn, but it has a latency of three, and doesn't
accept constants. Ideally, we would use a cost of one or two and
@@ -2909,7 +2910,7 @@ gen_datalabel_ref (rtx sym)
/* The SH cannot load a large constant into a register, constants have to
come from a pc relative load. The reference of a pc relative load
- instruction must be less than 1k infront of the instruction. This
+ instruction must be less than 1k in front of the instruction. This
means that we often have to dump a constant inside a function, and
generate code to branch around it.
@@ -7515,36 +7516,11 @@ sh_cfun_interrupt_handler_p (void)
!= NULL_TREE);
}
-/* Like default_pch_valid_p, but only check certain target_flags. */
-const char *
-sh_pch_valid_p (const void *data_p, size_t len)
-{
-#ifdef TARGET_OPTIONS
- /* ??? We have a copy of this in toplev.c, but it is static. */
- static const struct
- {
- const char *const prefix;
- const char **const variable;
- const char *const description;
- const char *const value;
- }
- target_options[] = TARGET_OPTIONS;
-#endif
-
- const char *data = (const char *)data_p;
- const char *flag_that_differs = NULL;
- size_t i;
- int old_flags;
-
- /* -fpic and -fpie also usually make a PCH invalid. */
- if (data[0] != flag_pic)
- return _("created and used with different settings of -fpic");
- if (data[1] != flag_pie)
- return _("created and used with different settings of -fpie");
- data += 2;
+/* Implement TARGET_CHECK_PCH_TARGET_FLAGS. */
- /* Check target_flags. */
- memcpy (&old_flags, data, sizeof (target_flags));
+static const char *
+sh_check_pch_target_flags (int old_flags)
+{
if ((old_flags ^ target_flags) & (MASK_SH1 | MASK_SH2 | MASK_SH3
| MASK_SH_E | MASK_HARD_SH4
| MASK_FPU_SINGLE | MASK_SH4))
@@ -7553,40 +7529,7 @@ sh_pch_valid_p (const void *data_p, size_t len)
return _("created and used with different ABIs");
if ((old_flags ^ target_flags) & MASK_LITTLE_ENDIAN)
return _("created and used with different endianness");
-
- data += sizeof (target_flags);
- len -= sizeof (target_flags);
-
- /* Check string options. */
-#ifdef TARGET_OPTIONS
- for (i = 0; i < ARRAY_SIZE (target_options); i++)
- {
- const char *str = *target_options[i].variable;
- size_t l;
- if (! str)
- str = "";
- l = strlen (str) + 1;
- if (len < l || memcmp (data, str, l) != 0)
- {
- flag_that_differs = target_options[i].prefix;
- goto make_message;
- }
- data += l;
- len -= l;
- }
-#endif
-
return NULL;
-
- make_message:
- {
- char *r;
- asprintf (&r, _("created and used with differing settings of '-m%s'"),
- flag_that_differs);
- if (r == NULL)
- return _("out of memory");
- return r;
- }
}
/* Predicates used by the templates. */
@@ -7607,301 +7550,6 @@ system_reg_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
return 0;
}
-/* Returns 1 if OP can be source of a simple move operation.
- Same as general_operand, but a LABEL_REF is valid, PRE_DEC is
- invalid as are subregs of system registers. */
-
-int
-general_movsrc_operand (rtx op, enum machine_mode mode)
-{
- if (GET_CODE (op) == MEM)
- {
- rtx inside = XEXP (op, 0);
- if (GET_CODE (inside) == CONST)
- inside = XEXP (inside, 0);
-
- if (GET_CODE (inside) == LABEL_REF)
- return 1;
-
- if (GET_CODE (inside) == PLUS
- && GET_CODE (XEXP (inside, 0)) == LABEL_REF
- && GET_CODE (XEXP (inside, 1)) == CONST_INT)
- return 1;
-
- /* Only post inc allowed. */
- if (GET_CODE (inside) == PRE_DEC)
- return 0;
- }
-
- if ((mode == QImode || mode == HImode)
- && (GET_CODE (op) == SUBREG
- && GET_CODE (XEXP (op, 0)) == REG
- && system_reg_operand (XEXP (op, 0), mode)))
- return 0;
-
- if (TARGET_SHMEDIA
- && (GET_CODE (op) == PARALLEL || GET_CODE (op) == CONST_VECTOR)
- && sh_rep_vec (op, mode))
- return 1;
- if (TARGET_SHMEDIA && 1
- && GET_CODE (op) == SUBREG && GET_MODE (op) == mode
- && SUBREG_REG (op) == const0_rtx && subreg_lowpart_p (op))
- /* FIXME */ abort (); /* return 1; */
- return general_operand (op, mode);
-}
-
-/* Returns 1 if OP can be a destination of a move.
- Same as general_operand, but no preinc allowed. */
-
-int
-general_movdst_operand (rtx op, enum machine_mode mode)
-{
- /* Only pre dec allowed. */
- if (GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) == POST_INC)
- return 0;
- if (mode == DImode && TARGET_SHMEDIA && GET_CODE (op) == SUBREG
- && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) < 8
- && ! (high_life_started || reload_completed))
- return 0;
-
- return general_operand (op, mode);
-}
-
-/* Returns 1 if OP is a normal arithmetic register. */
-
-int
-arith_reg_operand (rtx op, enum machine_mode mode)
-{
- if (register_operand (op, mode))
- {
- int regno;
-
- if (GET_CODE (op) == REG)
- regno = REGNO (op);
- else if (GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == REG)
- regno = REGNO (SUBREG_REG (op));
- else
- return 1;
-
- return (regno != T_REG && regno != PR_REG
- && ! TARGET_REGISTER_P (regno)
- && (regno != FPUL_REG || TARGET_SH4)
- && regno != MACH_REG && regno != MACL_REG);
- }
- /* Allow a no-op sign extension - compare LOAD_EXTEND_OP.
- We allow SImode here, as not using an FP register is just a matter of
- proper register allocation. */
- if (TARGET_SHMEDIA
- && GET_MODE (op) == DImode && GET_CODE (op) == SIGN_EXTEND
- && GET_MODE (XEXP (op, 0)) == SImode
- && GET_CODE (XEXP (op, 0)) != SUBREG)
- return register_operand (XEXP (op, 0), VOIDmode);
-#if 0 /* Can't do this because of PROMOTE_MODE for unsigned vars. */
- if (GET_MODE (op) == SImode && GET_CODE (op) == SIGN_EXTEND
- && GET_MODE (XEXP (op, 0)) == HImode
- && GET_CODE (XEXP (op, 0)) == REG
- && REGNO (XEXP (op, 0)) <= LAST_GENERAL_REG)
- return register_operand (XEXP (op, 0), VOIDmode);
-#endif
- if (GET_MODE_CLASS (GET_MODE (op)) == MODE_VECTOR_INT
- && GET_CODE (op) == SUBREG
- && GET_MODE (SUBREG_REG (op)) == DImode
- && GET_CODE (SUBREG_REG (op)) == SIGN_EXTEND
- && GET_MODE (XEXP (SUBREG_REG (op), 0)) == SImode
- && GET_CODE (XEXP (SUBREG_REG (op), 0)) != SUBREG)
- return register_operand (XEXP (SUBREG_REG (op), 0), VOIDmode);
- return 0;
-}
-
-/* Like above, but for DImode destinations: forbid paradoxical DImode subregs,
- because this would lead to missing sign extensions when truncating from
- DImode to SImode. */
-int
-arith_reg_dest (rtx op, enum machine_mode mode)
-{
- if (mode == DImode && GET_CODE (op) == SUBREG
- && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) < 8
- && TARGET_SHMEDIA)
- return 0;
- return arith_reg_operand (op, mode);
-}
-
-/* Like arith_reg_operand, but for register source operands of narrow
- logical SHMEDIA operations: forbid subregs of DImode / TImode regs. */
-int
-logical_reg_operand (rtx op, enum machine_mode mode)
-{
- if (TARGET_SHMEDIA
- && GET_CODE (op) == SUBREG
- && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) > 4
- && mode != DImode)
- return 0;
- return arith_reg_operand (op, mode);
-}
-
-int
-int_gpr_dest (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
- enum machine_mode op_mode = GET_MODE (op);
-
- if (GET_MODE_CLASS (op_mode) != MODE_INT
- || GET_MODE_SIZE (op_mode) >= UNITS_PER_WORD)
- return 0;
- if (! reload_completed)
- return 0;
- return true_regnum (op) <= LAST_GENERAL_REG;
-}
-
-int
-fp_arith_reg_operand (rtx op, enum machine_mode mode)
-{
- if (register_operand (op, mode))
- {
- int regno;
-
- if (GET_CODE (op) == REG)
- regno = REGNO (op);
- else if (GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == REG)
- regno = REGNO (SUBREG_REG (op));
- else
- return 1;
-
- return (regno >= FIRST_PSEUDO_REGISTER
- || FP_REGISTER_P (regno));
- }
- return 0;
-}
-
-int
-fp_arith_reg_dest (rtx op, enum machine_mode mode)
-{
- if (mode == DImode && GET_CODE (op) == SUBREG
- && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) < 8)
- return 0;
- return fp_arith_reg_operand (op, mode);
-}
-
-/* Returns 1 if OP is a valid source operand for an arithmetic insn. */
-
-int
-arith_operand (rtx op, enum machine_mode mode)
-{
- if (arith_reg_operand (op, mode))
- return 1;
-
- if (TARGET_SHMEDIA)
- {
- /* FIXME: We should be checking whether the CONST_INT fits in a
- CONST_OK_FOR_I16 here, but this causes reload_cse to crash when
- attempting to transform a sequence of two 64-bit sets of the
- same register from literal constants into a set and an add,
- when the difference is too wide for an add. */
- if (GET_CODE (op) == CONST_INT
- || EXTRA_CONSTRAINT_C16 (op))
- return 1;
- else if (GET_CODE (op) == TRUNCATE
- && ! system_reg_operand (XEXP (op, 0), VOIDmode)
- && (mode == VOIDmode || mode == GET_MODE (op))
- && (GET_MODE_SIZE (GET_MODE (op))
- < GET_MODE_SIZE (GET_MODE (XEXP (op, 0))))
- && (! FP_REGISTER_P (REGNO (XEXP (op, 0)))
- || GET_MODE_SIZE (GET_MODE (op)) == 4))
- return register_operand (XEXP (op, 0), VOIDmode);
- else
- return 0;
- }
- else if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_I08 (INTVAL (op)))
- return 1;
-
- return 0;
-}
-
-/* Returns 1 if OP is a valid source operand for a compare insn. */
-
-int
-arith_reg_or_0_operand (rtx op, enum machine_mode mode)
-{
- if (arith_reg_operand (op, mode))
- return 1;
-
- if (EXTRA_CONSTRAINT_Z (op))
- return 1;
-
- return 0;
-}
-
-/* Return 1 if OP is a valid source operand for xor. */
-
-int
-xor_operand (rtx op, enum machine_mode mode)
-{
- if (GET_CODE (op) == CONST_INT)
- return (TARGET_SHMEDIA
- ? (CONST_OK_FOR_I06 (INTVAL (op))
- || (no_new_pseudos && INTVAL (op) == 0xff))
- : CONST_OK_FOR_K08 (INTVAL (op)));
- if (TARGET_SHMEDIA
- && mode != DImode && GET_CODE (op) == SUBREG
- && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) > 4)
- return 0;
- return arith_reg_operand (op, mode);
-}
-
-/* Return 1 if OP is a valid source operand for shmedia cmpgt / cmpgtu. */
-int
-cmp_operand (rtx op, enum machine_mode mode)
-{
- if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_N (INTVAL (op)))
- return 1;
- if (TARGET_SHMEDIA
- && mode != DImode && GET_CODE (op) == SUBREG
- && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) > 4)
- return 0;
- return arith_reg_operand (op, mode);
-}
-
-/* Returns 1 if OP is a valid source operand for a logical operation. */
-
-int
-logical_operand (rtx op, enum machine_mode mode)
-{
- if (TARGET_SHMEDIA
- && mode != DImode && GET_CODE (op) == SUBREG
- && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) > 4)
- return 0;
-
- if (arith_reg_operand (op, mode))
- return 1;
-
- if (TARGET_SHMEDIA)
- {
- if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_I10 (INTVAL (op)))
- return 1;
- else
- return 0;
- }
- else if (GET_CODE (op) == CONST_INT && CONST_OK_FOR_K08 (INTVAL (op)))
- return 1;
-
- return 0;
-}
-
-int
-and_operand (rtx op, enum machine_mode mode)
-{
- if (logical_operand (op, mode))
- return 1;
-
- /* Check mshflo.l / mshflhi.l opportunities. */
- if (TARGET_SHMEDIA
- && mode == DImode
- && GET_CODE (op) == CONST_INT
- && CONST_OK_FOR_J16 (INTVAL (op)))
- return 1;
-
- return 0;
-}
-
/* Nonzero if OP is a floating point value with value 0.0. */
int
@@ -7950,33 +7598,6 @@ tertiary_reload_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
return code == MEM || (TARGET_SH4 && code == CONST_DOUBLE);
}
-int
-fpscr_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
- return (GET_CODE (op) == REG
- && (REGNO (op) == FPSCR_REG
- || (REGNO (op) >= FIRST_PSEUDO_REGISTER
- && !(reload_in_progress || reload_completed)))
- && GET_MODE (op) == PSImode);
-}
-
-int
-fpul_operand (rtx op, enum machine_mode mode)
-{
- if (TARGET_SHMEDIA)
- return fp_arith_reg_operand (op, mode);
-
- return (GET_CODE (op) == REG
- && (REGNO (op) == FPUL_REG || REGNO (op) >= FIRST_PSEUDO_REGISTER)
- && GET_MODE (op) == mode);
-}
-
-int
-symbol_ref_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
- return (GET_CODE (op) == SYMBOL_REF);
-}
-
/* Return the TLS type for TLS symbols, 0 for otherwise. */
int
tls_symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
@@ -7985,366 +7606,6 @@ tls_symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
return 0;
return SYMBOL_REF_TLS_MODEL (op);
}
-
-int
-commutative_float_operator (rtx op, enum machine_mode mode)
-{
- if (GET_MODE (op) != mode)
- return 0;
- switch (GET_CODE (op))
- {
- case PLUS:
- case MULT:
- return 1;
- default:
- break;
- }
- return 0;
-}
-
-int
-noncommutative_float_operator (rtx op, enum machine_mode mode)
-{
- if (GET_MODE (op) != mode)
- return 0;
- switch (GET_CODE (op))
- {
- case MINUS:
- case DIV:
- return 1;
- default:
- break;
- }
- return 0;
-}
-
-int
-unary_float_operator (rtx op, enum machine_mode mode)
-{
- if (GET_MODE (op) != mode)
- return 0;
- switch (GET_CODE (op))
- {
- case ABS:
- case NEG:
- case SQRT:
- return 1;
- default:
- break;
- }
- return 0;
-}
-
-int
-binary_float_operator (rtx op, enum machine_mode mode)
-{
- if (GET_MODE (op) != mode)
- return 0;
- switch (GET_CODE (op))
- {
- case PLUS:
- case MINUS:
- case MULT:
- case DIV:
- return 1;
- default:
- break;
- }
- return 0;
-}
-
-int
-binary_logical_operator (rtx op, enum machine_mode mode)
-{
- if (GET_MODE (op) != mode)
- return 0;
- switch (GET_CODE (op))
- {
- case IOR:
- case AND:
- case XOR:
- return 1;
- default:
- break;
- }
- return 0;
-}
-
-int
-equality_comparison_operator (rtx op, enum machine_mode mode)
-{
- return ((mode == VOIDmode || GET_MODE (op) == mode)
- && (GET_CODE (op) == EQ || GET_CODE (op) == NE));
-}
-
-int
-greater_comparison_operator (rtx op, enum machine_mode mode)
-{
- if (mode != VOIDmode && GET_MODE (op) != mode)
- return 0;
- switch (GET_CODE (op))
- {
- case GT:
- case GE:
- case GTU:
- case GEU:
- return 1;
- default:
- return 0;
- }
-}
-
-int
-less_comparison_operator (rtx op, enum machine_mode mode)
-{
- if (mode != VOIDmode && GET_MODE (op) != mode)
- return 0;
- switch (GET_CODE (op))
- {
- case LT:
- case LE:
- case LTU:
- case LEU:
- return 1;
- default:
- return 0;
- }
-}
-
-int
-shift_operator (rtx op, enum machine_mode mode)
-{
- if (mode != VOIDmode && GET_MODE (op) != mode)
- return 0;
- switch (GET_CODE (op))
- {
- case ASHIFT:
- case ASHIFTRT:
- case LSHIFTRT:
- return 1;
- default:
- return 0;
- }
-}
-
-int
-logical_operator (rtx op, enum machine_mode mode)
-{
- if (mode != VOIDmode && GET_MODE (op) != mode)
- return 0;
- switch (GET_CODE (op))
- {
- case AND:
- case IOR:
- case XOR:
- return 1;
- default:
- return 0;
- }
-}
-
-/* Accept pseudos and branch target registers. */
-int
-target_reg_operand (rtx op, enum machine_mode mode)
-{
- if (mode == VOIDmode
- ? GET_MODE (op) != Pmode && GET_MODE (op) != PDImode
- : mode != GET_MODE (op))
- return 0;
-
- if (GET_CODE (op) == SUBREG)
- op = XEXP (op, 0);
-
- if (GET_CODE (op) != REG)
- return 0;
-
- /* We must protect ourselves from matching pseudos that are virtual
- register, because they will eventually be replaced with hardware
- registers that aren't branch-target registers. */
- if (REGNO (op) > LAST_VIRTUAL_REGISTER
- || TARGET_REGISTER_P (REGNO (op)))
- return 1;
-
- return 0;
-}
-
-/* Same as target_reg_operand, except that label_refs and symbol_refs
- are accepted before reload. */
-int
-target_operand (rtx op, enum machine_mode mode)
-{
- if (mode != VOIDmode && mode != Pmode)
- return 0;
-
- if ((GET_MODE (op) == Pmode || GET_MODE (op) == VOIDmode)
- && EXTRA_CONSTRAINT_Csy (op))
- return ! reload_completed;
-
- return target_reg_operand (op, mode);
-}
-
-int
-mextr_bit_offset (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
- HOST_WIDE_INT i;
-
- if (GET_CODE (op) != CONST_INT)
- return 0;
- i = INTVAL (op);
- return i >= 1 * 8 && i <= 7 * 8 && (i & 7) == 0;
-}
-
-int
-extend_reg_operand (rtx op, enum machine_mode mode)
-{
- return (GET_CODE (op) == TRUNCATE
- ? arith_operand
- : arith_reg_operand) (op, mode);
-}
-
-int
-trunc_hi_operand (rtx op, enum machine_mode mode)
-{
- enum machine_mode op_mode = GET_MODE (op);
-
- if (op_mode != SImode && op_mode != DImode
- && op_mode != V4HImode && op_mode != V2SImode)
- return 0;
- return extend_reg_operand (op, mode);
-}
-
-int
-extend_reg_or_0_operand (rtx op, enum machine_mode mode)
-{
- return (GET_CODE (op) == TRUNCATE
- ? arith_operand
- : arith_reg_or_0_operand) (op, mode);
-}
-
-int
-minuend_operand (rtx op, enum machine_mode mode)
-{
- return op == constm1_rtx || extend_reg_or_0_operand (op, mode);
-}
-
-int
-general_extend_operand (rtx op, enum machine_mode mode)
-{
- return (GET_CODE (op) == TRUNCATE
- ? arith_operand
- : nonimmediate_operand) (op, mode);
-}
-
-int
-ua_address_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
- if (GET_CODE (op) == PLUS
- && (GET_CODE (XEXP (op, 1)) != CONST_INT
- || ! CONST_OK_FOR_I06 (INTVAL (XEXP (op, 1)))))
- return 0;
- return address_operand (op, QImode);
-}
-
-int
-cache_address_operand (rtx op, enum machine_mode mode)
-{
- if (GET_CODE (op) == PLUS)
- {
- if (GET_CODE (XEXP (op, 0)) != REG)
- return 0;
- if (GET_CODE (XEXP (op, 1)) != CONST_INT
- || (INTVAL (XEXP (op, 1)) & 31))
- return 0;
- }
- else if (GET_CODE (op) != REG)
- return 0;
- return address_operand (op, mode);
-}
-
-int
-inqhi_operand (rtx op, enum machine_mode mode)
-{
- if (GET_CODE (op) != TRUNCATE || mode != GET_MODE (op))
- return 0;
- op = XEXP (op, 0);
- /* Can't use true_regnum here because copy_cost wants to know about
- SECONDARY_INPUT_RELOAD_CLASS. */
- return GET_CODE (op) == REG && FP_REGISTER_P (REGNO (op));
-}
-
-int
-sh_rep_vec (rtx v, enum machine_mode mode)
-{
- int i;
- rtx x, y;
-
- if ((GET_CODE (v) != CONST_VECTOR && GET_CODE (v) != PARALLEL)
- || (GET_MODE (v) != mode && mode != VOIDmode))
- return 0;
- i = XVECLEN (v, 0) - 2;
- x = XVECEXP (v, 0, i + 1);
- if (GET_MODE_UNIT_SIZE (mode) == 1)
- {
- y = XVECEXP (v, 0, i);
- for (i -= 2; i >= 0; i -= 2)
- if (! rtx_equal_p (XVECEXP (v, 0, i + 1), x)
- || ! rtx_equal_p (XVECEXP (v, 0, i), y))
- return 0;
- }
- else
- for (; i >= 0; i--)
- if (XVECEXP (v, 0, i) != x)
- return 0;
- return 1;
-}
-
-/* Determine if V is a constant vector matching MODE with only one element
- that is not a sign extension. Two byte-sized elements count as one. */
-int
-sh_1el_vec (rtx v, enum machine_mode mode)
-{
- int unit_size;
- int i, last, least, sign_ix;
- rtx sign;
-
- if (GET_CODE (v) != CONST_VECTOR
- || (GET_MODE (v) != mode && mode != VOIDmode))
- return 0;
- /* Determine numbers of last and of least significant elements. */
- last = XVECLEN (v, 0) - 1;
- least = TARGET_LITTLE_ENDIAN ? 0 : last;
- if (GET_CODE (XVECEXP (v, 0, least)) != CONST_INT)
- return 0;
- sign_ix = least;
- if (GET_MODE_UNIT_SIZE (mode) == 1)
- sign_ix = TARGET_LITTLE_ENDIAN ? 1 : last - 1;
- if (GET_CODE (XVECEXP (v, 0, sign_ix)) != CONST_INT)
- return 0;
- unit_size = GET_MODE_UNIT_SIZE (GET_MODE (v));
- sign = (INTVAL (XVECEXP (v, 0, sign_ix)) >> (unit_size * BITS_PER_UNIT - 1)
- ? constm1_rtx : const0_rtx);
- i = XVECLEN (v, 0) - 1;
- do
- if (i != least && i != sign_ix && XVECEXP (v, 0, i) != sign)
- return 0;
- while (--i);
- return 1;
-}
-
-int
-sh_const_vec (rtx v, enum machine_mode mode)
-{
- int i;
-
- if (GET_CODE (v) != CONST_VECTOR
- || (GET_MODE (v) != mode && mode != VOIDmode))
- return 0;
- i = XVECLEN (v, 0) - 1;
- for (; i >= 0; i--)
- if (GET_CODE (XVECEXP (v, 0, i)) != CONST_INT)
- return 0;
- return 1;
-}
/* Return the destination address of a branch. */
@@ -8856,12 +8117,6 @@ mark_constant_pool_use (rtx x)
return lab;
}
-
-int
-ua_offset (rtx c, enum machine_mode mode ATTRIBUTE_UNUSED)
-{
- return GET_CODE (c) == CONST_INT && CONST_OK_FOR_I06 (INTVAL (c));
-}
/* Return true if it's possible to redirect BRANCH1 to the destination
of an unconditional jump BRANCH2. We only want to do this if the
@@ -10126,8 +9381,8 @@ sh_register_move_cost (enum machine_mode mode,
if (TARGET_SHMEDIA
&& ((srcclass) == TARGET_REGS || (srcclass) == SIBCALL_REGS))
{
- if (*sh_gettrcost_str)
- return atoi (sh_gettrcost_str);
+ if (sh_gettrcost >= 0)
+ return sh_gettrcost;
else if (!TARGET_PT_FIXED)
return 100;
}
@@ -10145,57 +9400,6 @@ sh_register_move_cost (enum machine_mode mode,
return 2 * ((GET_MODE_SIZE (mode) + 3) / 4U);
}
-/* Like register_operand, but take into account that SHMEDIA can use
- the constant zero like a general register. */
-int
-sh_register_operand (rtx op, enum machine_mode mode)
-{
- if (op == CONST0_RTX (mode) && TARGET_SHMEDIA)
- return 1;
- return register_operand (op, mode);
-}
-
-int
-cmpsi_operand (rtx op, enum machine_mode mode)
-{
- if (GET_CODE (op) == REG && REGNO (op) == T_REG
- && GET_MODE (op) == SImode
- && TARGET_SH1)
- return 1;
- return arith_operand (op, mode);
-}
-
-int
-shift_count_reg_operand (rtx op, enum machine_mode mode)
-{
- if ((GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == SIGN_EXTEND
- || (GET_CODE (op) == SUBREG && SUBREG_BYTE (op) == 0))
- && (mode == VOIDmode || mode == GET_MODE (op))
- && GET_MODE_BITSIZE (GET_MODE (XEXP (op, 0))) >= 6
- && GET_MODE_CLASS (GET_MODE (XEXP (op, 0))) == MODE_INT)
- {
- mode = VOIDmode;
- do
- op = XEXP (op, 0);
- while ((GET_CODE (op) == ZERO_EXTEND || GET_CODE (op) == SIGN_EXTEND
- || GET_CODE (op) == TRUNCATE)
- && GET_MODE_BITSIZE (GET_MODE (XEXP (op, 0))) >= 6
- && GET_MODE_CLASS (GET_MODE (XEXP (op, 0))) == MODE_INT);
-
- }
- return arith_reg_operand (op, mode);
-}
-
-int
-shift_count_operand (rtx op, enum machine_mode mode)
-{
- return (CONSTANT_P (op)
- ? (GET_CODE (op) == CONST_INT
- ? (unsigned) INTVAL (op) < GET_MODE_BITSIZE (mode)
- : nonmemory_operand (op, mode))
- : shift_count_reg_operand (op, mode));
-}
-
static rtx emit_load_ptr (rtx, rtx);
static rtx
@@ -10598,27 +9802,6 @@ check_use_sfunc_addr (rtx insn, rtx reg)
gcc_unreachable ();
}
-/* Returns 1 if OP is a MEM that can be source of a simple move operation. */
-
-int
-unaligned_load_operand (rtx op, enum machine_mode mode)
-{
- rtx inside;
-
- if (GET_CODE (op) != MEM || GET_MODE (op) != mode)
- return 0;
-
- inside = XEXP (op, 0);
-
- if (GET_CODE (inside) == POST_INC)
- inside = XEXP (inside, 0);
-
- if (GET_CODE (inside) == REG)
- return 1;
-
- return 0;
-}
-
/* This function returns a constant rtx that represents pi / 2**15 in
SFmode. it's used to scale SFmode angles, in radians, to a
fixed-point signed 16.16-bit fraction of a full circle, i.e., 2*pi
@@ -11290,11 +10473,6 @@ shmedia_prepare_call_address (rtx fnaddr, int is_sibcall)
return fnaddr;
}
-const char *sh_multcost_str = "";
-const char *sh_gettrcost_str = "";
-const char *sh_div_str = "";
-const char *sh_divsi3_libfunc = "";
-const char *cut2_workaround_str = "";
enum sh_divide_strategy_e sh_div_strategy = SH_DIV_STRATEGY_DEFAULT;
/* This defines the storage for the variable part of a -mboard= option.
diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h
index 92d8ce00696..e194759d388 100644
--- a/gcc/config/sh/sh.h
+++ b/gcc/config/sh/sh.h
@@ -174,7 +174,8 @@ do { \
#define TARGET_HARVARD (TARGET_HARD_SH4 || TARGET_SH5)
/* Nonzero if a double-precision FPU is available. */
-#define TARGET_FPU_DOUBLE (TARGET_SH4 || TARGET_SH2A_DOUBLE)
+#define TARGET_FPU_DOUBLE \
+ ((target_flags & MASK_SH4) != 0 || TARGET_SH2A_DOUBLE)
/* Nonzero if an FPU is available. */
#define TARGET_FPU_ANY (TARGET_SH2E || TARGET_FPU_DOUBLE)
@@ -334,26 +335,6 @@ do { \
#define TARGET_DEFAULT \
(TARGET_CPU_DEFAULT | TARGET_ENDIAN_DEFAULT | TARGET_OPT_DEFAULT)
-#ifndef SUBTARGET_OPTIONS
-#define SUBTARGET_OPTIONS
-#endif
-
-#define TARGET_OPTIONS \
-{ { "ultcost=", &sh_multcost_str, \
- N_("Cost to assume for a multiply insn"), 0 }, \
- { "gettrcost=", &sh_gettrcost_str, \
- N_("Cost to assume for gettr insn"), 0 }, \
- { "div=", &sh_div_str, \
- N_("division strategy, one of: call, call2, fp, inv, inv:minlat, inv20u, inv20l, inv:call, inv:call2, inv:fp"), 0 }, \
- { "divsi3_libfunc=", &sh_divsi3_libfunc, \
- N_("Specify name for 32 bit signed division function"), 0 }, \
- { "cut2-workaround", &cut2_workaround_str, \
- N_("Enable SH5 cut2 workaround"), "\1" }, \
- SUBTARGET_OPTIONS \
-}
-
-#define TARGET_SH5_CUT2_WORKAROUND (*cut2_workaround_str)
-
#ifndef SH_MULTILIB_CPU_DEFAULT
#define SH_MULTILIB_CPU_DEFAULT "m1"
#endif
@@ -3265,73 +3246,6 @@ extern struct rtx_def *sp_switch;
#define ADJUST_INSN_LENGTH(X, LENGTH) \
(LENGTH) += sh_insn_length_adjustment (X);
-/* Define the codes that are matched by predicates in sh.c. */
-#define PREDICATE_CODES \
- {"and_operand", {SUBREG, REG, CONST_INT}}, \
- {"any_arith_reg_dest", {SUBREG, REG}}, \
- {"any_register_operand", {SUBREG, REG}}, \
- {"arith_operand", {SUBREG, REG, CONST_INT}}, \
- {"arith_reg_dest", {SUBREG, REG}}, \
- {"arith_reg_operand", {SUBREG, REG, SIGN_EXTEND}}, \
- {"arith_reg_or_0_operand", {SUBREG, REG, CONST_INT, CONST_VECTOR}}, \
- {"binary_float_operator", {PLUS, MINUS, MULT, DIV}}, \
- {"binary_logical_operator", {AND, IOR, XOR}}, \
- {"cache_address_operand", {PLUS, REG}}, \
- {"cmp_operand", {SUBREG, REG, CONST_INT}}, \
- {"cmpsi_operand", {SUBREG, REG, CONST_INT}}, \
- {"commutative_float_operator", {PLUS, MULT}}, \
- {"equality_comparison_operator", {EQ,NE}}, \
- {"extend_reg_operand", {SUBREG, REG, TRUNCATE}}, \
- {"extend_reg_or_0_operand", {SUBREG, REG, TRUNCATE, CONST_INT}}, \
- {"ext_dest_operand", {SUBREG, REG}}, \
- {"fp_arith_reg_dest", {SUBREG, REG}}, \
- {"fp_arith_reg_operand", {SUBREG, REG}}, \
- {"fpscr_operand", {REG}}, \
- {"fpul_operand", {REG}}, \
- {"general_extend_operand", {SUBREG, REG, MEM, TRUNCATE}}, \
- {"general_movsrc_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE, MEM, CONST }}, \
- {"general_movdst_operand", {SUBREG, REG, MEM}}, \
- {"unaligned_load_operand", {MEM}}, \
- {"greater_comparison_operator", {GT,GE,GTU,GEU}}, \
- {"inqhi_operand", {TRUNCATE}}, \
- {"int_gpr_dest", {SUBREG, REG}}, \
- {"less_comparison_operator", {LT,LE,LTU,LEU}}, \
- {"logical_operand", {SUBREG, REG, CONST_INT}}, \
- {"logical_operator", {AND,IOR,XOR}}, \
- {"logical_reg_operand", {SUBREG, REG}}, \
- {"mextr_bit_offset", {CONST_INT}}, \
- {"minuend_operand", {SUBREG, REG, TRUNCATE, CONST_INT}}, \
- {"noncommutative_float_operator", {MINUS, DIV}}, \
- {"sh_const_vec", {CONST_VECTOR}}, \
- {"sh_1el_vec", {CONST_VECTOR}}, \
- {"sh_register_operand", {REG, SUBREG, CONST_INT}}, \
- {"sh_rep_vec", {CONST_VECTOR}}, \
- {"shift_count_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF, \
- LABEL_REF, SUBREG, REG, ZERO_EXTEND, SIGN_EXTEND}},\
- {"shift_count_reg_operand", {SUBREG, REG, ZERO_EXTEND, SIGN_EXTEND}}, \
- {"shift_operator", {ASHIFT, ASHIFTRT, LSHIFTRT}}, \
- {"symbol_ref_operand", {SYMBOL_REF}}, \
- {"target_operand", {SUBREG, REG, LABEL_REF, SYMBOL_REF, CONST, UNSPEC}},\
- {"target_reg_operand", {SUBREG, REG}}, \
- {"trunc_hi_operand", {SUBREG, REG, TRUNCATE}}, \
- {"ua_address_operand", {SUBREG, REG, PLUS}}, \
- {"ua_offset", {CONST_INT}}, \
- {"unary_float_operator", {ABS, NEG, SQRT}}, \
- {"xor_operand", {SUBREG, REG, CONST_INT}}, \
-
-#define SPECIAL_MODE_PREDICATES \
- "any_arith_reg_dest", \
- "any_register_operand", \
- "int_gpr_dest", \
- "target_operand", \
- "target_reg_operand", \
- "trunc_hi_operand", \
- /* This line intentionally left blank. */
-
-#define any_register_operand register_operand
-#define any_arith_reg_dest arith_reg_dest
-#define ext_dest_operand arith_reg_operand
-
/* Define this macro if it is advisable to hold scalars in registers
in a wider mode than that declared by the program. In such cases,
the value is constrained to be within the bounds of the declared
@@ -3460,12 +3374,6 @@ extern struct rtx_def *sp_switch;
#define SIMULTANEOUS_PREFETCHES 2
-extern const char *sh_multcost_str;
-extern const char *sh_gettrcost_str;
-extern const char *sh_div_str;
-extern const char *sh_divsi3_libfunc;
-extern const char *cut2_workaround_str;
-
/* FIXME: middle-end support for highpart optimizations is missing. */
#define high_life_started reload_in_progress
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
index f05be16d92d..de46e08c82d 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -1106,7 +1106,7 @@
rtx set1, set2;
rtx replacements[4];
- /* We want to replace occurences of operands[0] with operands[1] and
+ /* We want to replace occurrences of operands[0] with operands[1] and
operands[2] with operands[0] in operands[4]/operands[5].
Doing just two replace_rtx calls naively would result in the second
replacement undoing all that the first did if operands[1] and operands[2]
diff --git a/gcc/config/sh/sh.opt b/gcc/config/sh/sh.opt
index c3c659f95d2..553a5576eb0 100644
--- a/gcc/config/sh/sh.opt
+++ b/gcc/config/sh/sh.opt
@@ -148,13 +148,29 @@ mbigtable
Target Report RejectNegative Mask(BIGTABLE)
Generate 32-bit offsets in switch tables
+mcut2-workaround
+Target RejectNegative Var(TARGET_SH5_CUT2_WORKAROUND)
+Enable SH5 cut2 workaround
+
mdalign
Target Report RejectNegative Mask(ALIGN_DOUBLE)
Align doubles at 64-bit boundaries
+mdiv=
+Target RejectNegative Joined Var(sh_div_str) Init("")
+Division strategy, one of: call, call2, fp, inv, inv:minlat, inv20u, inv20l, inv:call, inv:call2, inv:fp
+
+mdivsi3_libfunc=
+Target RejectNegative Joined Var(sh_divsi3_libfunc) Init("")
+Specify name for 32 bit signed division function
+
mfmovd
Target RejectNegative Mask(FMOVD) Undocumented
+mgettrcost=
+Target RejectNegative Joined UInteger Var(sh_gettrcost) Init(-1)
+Cost to assume for gettr insn
+
mhitachi
Target Report RejectNegative Mask(HITACHI)
Follow Renesas (formerly Hitachi) / SuperH calling conventions
@@ -209,6 +225,10 @@ mspace
Target Report RejectNegative Mask(SMALLCODE)
Deprecated. Use -Os instead
+multcost=
+Target RejectNegative Joined UInteger Var(sh_multcost) Init(-1)
+Cost to assume for a multiply insn
+
musermode
Target Report RejectNegative Mask(USERMODE)
Generate library function call to invalidate instruction cache entries after fixing trampoline
diff --git a/gcc/config/sh/symbian-pre.h b/gcc/config/sh/symbian-pre.h
index 1d882bec0c3..b1f7ab69061 100644
--- a/gcc/config/sh/symbian-pre.h
+++ b/gcc/config/sh/symbian-pre.h
@@ -1,7 +1,7 @@
/* Definitions for the Symbian OS running on an SH part.
This file is included before any other target specific headers.
- Copyright (C) 2004 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
Contributed by Red Hat.
This file is part of GCC.
diff --git a/gcc/config/sh/ushmedia.h b/gcc/config/sh/ushmedia.h
index 514ddff35b5..98e9a5bd365 100644
--- a/gcc/config/sh/ushmedia.h
+++ b/gcc/config/sh/ushmedia.h
@@ -720,14 +720,14 @@ sh_media_ADDZ_L (unsigned int mm, unsigned int mn)
return mm + mn;
}
-/* NOP and Synchronization instrinsics not implemented here. */
+/* NOP and Synchronization intrinsics not implemented here. */
static __inline__ void sh_media_PREFO(void *mm, int s)
{
__builtin_sh_media_PREFO (mm + s, 0, 0);
}
-/* Event Handling instrinsics not implemented here. */
+/* Event Handling intrinsics not implemented here. */
/* Old asm stuff */
diff --git a/gcc/config/sparc/sparc-protos.h b/gcc/config/sparc/sparc-protos.h
index 9c1e3721b72..9c6e822cc76 100644
--- a/gcc/config/sparc/sparc-protos.h
+++ b/gcc/config/sparc/sparc-protos.h
@@ -1,5 +1,5 @@
/* Prototypes of target machine for SPARC.
- Copyright (C) 1999, 2000, 2003, 2004 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com).
64-bit SPARC-V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
at Cygnus Support.
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 1958f3f3982..9d5edd18391 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -370,9 +370,6 @@ const struct attribute_spec sparc_attribute_table[];
/* Option handling. */
-/* Code model option as passed by user. */
-const char *sparc_cmodel_string;
-
/* Parsed value. */
enum cmodel sparc_cmodel;
@@ -540,10 +537,6 @@ sparc_handle_option (size_t code, const char *arg, int value ATTRIBUTE_UNUSED)
case OPT_mtune_:
sparc_select[2].string = arg;
break;
-
- case OPT_mcmodel_:
- sparc_cmodel_string = arg;
- break;
}
return true;
@@ -7846,7 +7839,7 @@ sparc_vis_init_builtins (void)
}
/* Handle TARGET_EXPAND_BUILTIN target hook.
- Expand builtin functions for sparc instrinsics. */
+ Expand builtin functions for sparc intrinsics. */
static rtx
sparc_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h
index 9fcee127385..aa3752c9d6f 100644
--- a/gcc/config/sparc/sparc.h
+++ b/gcc/config/sparc/sparc.h
@@ -191,8 +191,6 @@ enum cmodel {
CM_EMBMEDANY
};
-/* Value of -mcmodel specified by user. */
-extern const char *sparc_cmodel_string;
/* One of CM_FOO. */
extern enum cmodel sparc_cmodel;
diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md
index 589edb612a4..cea956624df 100644
--- a/gcc/config/sparc/sparc.md
+++ b/gcc/config/sparc/sparc.md
@@ -854,7 +854,7 @@
;; The SEQ and SNE patterns are special because they can be done
;; without any branching and do not involve a COMPARE. We want
-;; them to always use the splitz below so the results can be
+;; them to always use the splits below so the results can be
;; scheduled.
(define_insn_and_split "*snesi_zero"
@@ -8363,7 +8363,7 @@
(set_attr "fptype" "double")])
;; Using faligndata only makes sense after an alignaddr since the choice of
-;; bytes to take out of each operand is dependant on the results of the last
+;; bytes to take out of each operand is dependent on the results of the last
;; alignaddr.
(define_insn "faligndata<V64I:mode>_vis"
[(set (match_operand:V64I 0 "register_operand" "=e")
diff --git a/gcc/config/sparc/sparc.opt b/gcc/config/sparc/sparc.opt
index 88a603c6f56..6bee67d8d25 100644
--- a/gcc/config/sparc/sparc.opt
+++ b/gcc/config/sparc/sparc.opt
@@ -96,7 +96,7 @@ Target RejectNegative Joined
Schedule code for given CPU
mcmodel=
-Target RejectNegative Joined
+Target RejectNegative Joined Var(sparc_cmodel_string)
Use given SPARC-V9 code model
diff --git a/gcc/config/stormy16/stormy-abi b/gcc/config/stormy16/stormy-abi
index 01d15796f4e..8c6d590d4ec 100644
--- a/gcc/config/stormy16/stormy-abi
+++ b/gcc/config/stormy16/stormy-abi
@@ -159,7 +159,7 @@ the reloc refers, 'A' is the addend, and 'P' represents the place of
the storage unit being relocated.
In the 'Overflow' column, 'none' means that any overflow of the
-computation perfomed in the 'Calculation' column is ignored.
+computation performed in the 'Calculation' column is ignored.
'signed' means that the overflow is only reported if it happens when
the values are treated as signed quantities. 'unsigned' is the same,
except that the values are treated as unsigned quantities. 'either'
diff --git a/gcc/configure b/gcc/configure
index 9f7dba7c491..b4b41b97782 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -891,6 +891,7 @@ Optional Features:
--enable-initfini-array use .init_array/.fini_array sections
--enable-sjlj-exceptions
arrange to use setjmp/longjmp exception handling
+ --enable-secureplt enable -msecure-plt by default for PowerPC
--disable-win32-registry
disable lookup of installation paths in the
Registry on Windows hosts
@@ -7402,7 +7403,7 @@ if test "${gcc_cv_prog_makeinfo_modern+set}" = set; then
else
ac_prog_version=`$MAKEINFO --version 2>&1 |
sed -n 's/^.*GNU texinfo.* \([0-9][0-9.]*\).*$/\1/p'`
- echo "configure:7405: version of makeinfo is $ac_prog_version" >&5
+ echo "configure:7406: version of makeinfo is $ac_prog_version" >&5
case $ac_prog_version in
'') gcc_cv_prog_makeinfo_modern=no;;
4.[2-9]*)
@@ -12361,6 +12362,12 @@ case "$LIBINTL" in *$LIBICONV*)
LIBICONV= ;;
esac
+# Check whether --enable-secureplt or --disable-secureplt was given.
+if test "${enable_secureplt+set}" = set; then
+ enableval="$enable_secureplt"
+
+fi;
+
# Windows32 Registry support for specifying GCC installation paths.
# Check whether --enable-win32-registry or --disable-win32-registry was given.
if test "${enable_win32_registry+set}" = set; then
@@ -14152,6 +14159,45 @@ cat >>confdefs.h <<\_ACEOF
_ACEOF
fi
+ echo "$as_me:$LINENO: checking assembler for jsrdirect relocation support" >&5
+echo $ECHO_N "checking assembler for jsrdirect relocation support... $ECHO_C" >&6
+if test "${gcc_cv_as_alpha_jsrdirect_relocs+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ gcc_cv_as_alpha_jsrdirect_relocs=no
+ if test $in_tree_gas = yes; then
+ if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 16 \) \* 1000 + 90`
+ then gcc_cv_as_alpha_jsrdirect_relocs=yes
+fi
+ elif test x$gcc_cv_as != x; then
+ echo ' .set nomacro
+ .text
+ ldq $27, a($29) !literal!1
+ jsr $26, ($27), a !lituse_jsrdirect!1' > conftest.s
+ if { ac_try='$gcc_cv_as -o conftest.o conftest.s >&5'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }
+ then
+ gcc_cv_as_alpha_jsrdirect_relocs=yes
+ else
+ echo "configure: failed program was" >&5
+ cat conftest.s >&5
+ fi
+ rm -f conftest.o conftest.s
+ fi
+fi
+echo "$as_me:$LINENO: result: $gcc_cv_as_alpha_jsrdirect_relocs" >&5
+echo "${ECHO_T}$gcc_cv_as_alpha_jsrdirect_relocs" >&6
+if test $gcc_cv_as_alpha_jsrdirect_relocs = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_AS_JSRDIRECT_RELOCS 1
+_ACEOF
+
+fi
;;
cris-*-*)
@@ -14729,6 +14775,55 @@ _ACEOF
fi
+ case $target in
+ *-*-aix*) conftest_s=' .csect .text[PR]
+LCF..0:
+ addis 11,30,_GLOBAL_OFFSET_TABLE_-LCF..0@ha';;
+ *-*-darwin*)
+ conftest_s=' .text
+LCF0:
+ addis r11,r30,_GLOBAL_OFFSET_TABLE_-LCF0@ha';;
+ *) conftest_s=' .text
+.LCF0:
+ addis 11,30,_GLOBAL_OFFSET_TABLE_-.LCF0@ha';;
+ esac
+
+ echo "$as_me:$LINENO: checking assembler for rel16 relocs" >&5
+echo $ECHO_N "checking assembler for rel16 relocs... $ECHO_C" >&6
+if test "${gcc_cv_as_powerpc_rel16+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ gcc_cv_as_powerpc_rel16=no
+ if test $in_tree_gas = yes; then
+ if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 17 \) \* 1000 + 0`
+ then gcc_cv_as_powerpc_rel16=yes
+fi
+ elif test x$gcc_cv_as != x; then
+ echo "$conftest_s" > conftest.s
+ if { ac_try='$gcc_cv_as -a32 -o conftest.o conftest.s >&5'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }
+ then
+ gcc_cv_as_powerpc_rel16=yes
+ else
+ echo "configure: failed program was" >&5
+ cat conftest.s >&5
+ fi
+ rm -f conftest.o conftest.s
+ fi
+fi
+echo "$as_me:$LINENO: result: $gcc_cv_as_powerpc_rel16" >&5
+echo "${ECHO_T}$gcc_cv_as_powerpc_rel16" >&6
+if test $gcc_cv_as_powerpc_rel16 = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_AS_REL16 1
+_ACEOF
+
+fi
;;
mips*-*-*)
diff --git a/gcc/configure.ac b/gcc/configure.ac
index b853c142483..7c6bfceea72 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -1441,6 +1441,10 @@ case "$LIBINTL" in *$LIBICONV*)
LIBICONV= ;;
esac
+AC_ARG_ENABLE(secureplt,
+[ --enable-secureplt enable -msecure-plt by default for PowerPC],
+[], [])
+
# Windows32 Registry support for specifying GCC installation paths.
AC_ARG_ENABLE(win32-registry,
[ --disable-win32-registry
@@ -2637,6 +2641,14 @@ case "$target" in
lda $29, 0($29) !gpdisp!3],,
[AC_DEFINE(HAVE_AS_EXPLICIT_RELOCS, 1,
[Define if your assembler supports explicit relocations.])])
+ gcc_GAS_CHECK_FEATURE([jsrdirect relocation support],
+ gcc_cv_as_alpha_jsrdirect_relocs, [2,16,90],,
+[ .set nomacro
+ .text
+ ldq $27, a($29) !literal!1
+ jsr $26, ($27), a !lituse_jsrdirect!1],,
+ [AC_DEFINE(HAVE_AS_JSRDIRECT_RELOCS, 1,
+ [Define if your assembler supports the lituse_jsrdirect relocation.])])
;;
cris-*-*)
@@ -2822,6 +2834,24 @@ foo: nop
[AC_DEFINE(HAVE_AS_POPCNTB, 1,
[Define if your assembler supports popcntb field.])])
+ case $target in
+ *-*-aix*) conftest_s=' .csect .text[[PR]]
+LCF..0:
+ addis 11,30,_GLOBAL_OFFSET_TABLE_-LCF..0@ha';;
+ *-*-darwin*)
+ conftest_s=' .text
+LCF0:
+ addis r11,r30,_GLOBAL_OFFSET_TABLE_-LCF0@ha';;
+ *) conftest_s=' .text
+.LCF0:
+ addis 11,30,_GLOBAL_OFFSET_TABLE_-.LCF0@ha';;
+ esac
+
+ gcc_GAS_CHECK_FEATURE([rel16 relocs],
+ gcc_cv_as_powerpc_rel16, [2,17,0], -a32,
+ [$conftest_s],,
+ [AC_DEFINE(HAVE_AS_REL16, 1,
+ [Define if your assembler supports R_PPC_REL16 relocs.])])
;;
mips*-*-*)
diff --git a/gcc/convert.c b/gcc/convert.c
index 97705a2926a..dc9f41f648a 100644
--- a/gcc/convert.c
+++ b/gcc/convert.c
@@ -42,10 +42,7 @@ tree
convert_to_pointer (tree type, tree expr)
{
if (integer_zerop (expr))
- {
- expr = build_int_cst (type, 0);
- return expr;
- }
+ return build_int_cst (type, 0);
switch (TREE_CODE (TREE_TYPE (expr)))
{
@@ -57,13 +54,12 @@ convert_to_pointer (tree type, tree expr)
case ENUMERAL_TYPE:
case BOOLEAN_TYPE:
case CHAR_TYPE:
- if (TYPE_PRECISION (TREE_TYPE (expr)) == POINTER_SIZE)
- return build1 (CONVERT_EXPR, type, expr);
+ if (TYPE_PRECISION (TREE_TYPE (expr)) != POINTER_SIZE)
+ expr = fold_build1 (NOP_EXPR,
+ lang_hooks.types.type_for_size (POINTER_SIZE, 0),
+ expr);
+ return fold_build1 (CONVERT_EXPR, type, expr);
- return
- convert_to_pointer (type,
- convert (lang_hooks.types.type_for_size
- (POINTER_SIZE, 0), expr));
default:
error ("cannot convert to a pointer type");
@@ -411,13 +407,14 @@ convert_to_integer (tree type, tree expr)
case POINTER_TYPE:
case REFERENCE_TYPE:
if (integer_zerop (expr))
- expr = integer_zero_node;
- else
- expr = fold (build1 (CONVERT_EXPR,
- lang_hooks.types.type_for_size (POINTER_SIZE, 0),
- expr));
-
- return convert_to_integer (type, expr);
+ return build_int_cst (type, 0);
+
+ /* Convert to an unsigned integer of the correct width first,
+ and from there widen/truncate to the required type. */
+ expr = fold_build1 (CONVERT_EXPR,
+ lang_hooks.types.type_for_size (POINTER_SIZE, 0),
+ expr);
+ return fold_build1 (NOP_EXPR, type, expr);
case INTEGER_TYPE:
case ENUMERAL_TYPE:
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index a54ca60803e..28dc483398b 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,130 @@
+2005-06-03 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/21336
+ * cp-tree.h (grok_op_properties): Remove friendp parameter.
+ * decl.c (grokfndecl): Adjust call.
+ (grok_op_properties): Determine the class of which the function is
+ a member by looking at its DECL_CONTEXT, not current_class_type.
+ * pt.c (tsubst_decl): Adjust call to grok_op_properties.
+
+2005-06-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ * method.c (synthesize_method): Add addtional arg to warning call.
+
+ PR c++/21280
+ * Make-lang.in (method.o): Add diagnostic.h
+ * decl.c (start_preparsed_function): Use decl's location for file
+ info.
+ * decl2.c (cp_finish_file): Set input_location before synthesizing
+ a function.
+ (mark_used): When deferring a synthesized function, save current
+ location. Do not set function's location when actually
+ synthesizing it.
+ * method.c: #include diagnostic.h.
+ (synthesize_method): Set the functions source location. Show
+ needed location if errors are emitted.
+
+ * decl.c (start_decl): Simplify specialization handling. Remove
+ unneeded CLASSTYPE_TEMPLATE_INSTANTIATION check.
+ * mangle.c (discriminator_for_local_entity): Use VEC_index.
+
+ PR c++/20350
+ * decl.c (duplicate_decls): Copy all of DECL_USE_TEMPLATE.
+
+ PR c++/21151
+ * name-lookup.c (pushtag): Push local class even in a template.
+
+2005-05-31 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/21165
+ * init.c (integral_constant_value): Check the type of the
+ initializer, not the decl.
+
+2005-05-30 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/21784
+ * name-lookup.c (do_nonmember_using_decl): Ignore builtin
+ functions, even when the used name is not a function.
+
+2005-05-30 Kazu Hirata <kazu@cs.umass.edu>
+
+ * operators.def, optimize.c: Update copyright.
+
+2005-05-28 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/21210
+ * call.c (standard_conversion): Permit conversions to complex
+ types if conversion to the corresponding scalar type would be
+ permitted.
+
+ PR c++/21340
+ * method.c (implicitly_declare_fn): Clear processing_template_decl
+ when generating implicit declaration.
+
+2005-05-27 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/21614
+ * typeck.c (get_member_function_from_ptrfunc): Do not attempt
+ conversions to base classes of incomplete types.
+
+2005-05-27 Ian Lance Taylor <ian@airs.com>
+
+ * semantics.c (add_stmt): Add C++ frontend specific version.
+ * cp-tree.h (STMT_IS_FULL_EXPR_P): Define.
+ (stmts_are_full_exprs_p): Declare.
+
+2005-05-27 Roger Sayle <roger@eyesopen.com>
+ Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ * cp-tree.def (UNARY_PLUS_EXPR): New C++ unary tree code.
+ * parser.c (cp_parser_unary_expression): Use UNARY_PLUS_EXPR instead
+ of CONVERT_EXPR.
+ (cp_parser_unary_expression): Likewise.
+ * typeck.c (build_unary_op): Likewise.
+ * call.c (add_builtin_candidate, build_new_op): Likewise.
+ * error.c (dump_expr): Likewise.
+ * pt.c (tsubst_copy, tsubst_copy_and_build): Likewise.
+ * decl.c (ambi_op_p, grok_op_properties): Likewise.
+ * dump.c (dump_op): Likewise.
+ * lex.c (init_operators): Likewise.
+ * operators.def ("+"): Likewise.
+ * cp-gimplify.c (cp_gimplify_expr): Handle UNARY_PLUS_EXPR like a
+ conversion, if the result and argument types differ.
+ * tree.c (fold_if_not_in_template): Fold UNARY_PLUS_EXPR much
+ like a NOP_EXPR when !processing_template_decl.
+
+ * cxx-pretty-print.c (pp_cxx_cast_expression): Prototype.
+ (pp_cxx_unary_expression): Handle new UNARY_PLUS_EXPR tree code.
+
+2005-05-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/21455
+ * typeck.c (get_delta_difference): Cope with incomplete but equal
+ classes. Reorder if.
+
+ PR c++/21681
+ * parser.c (cp_parser_late_parsing_for_member): Disable access
+ checking for template functions.
+
+2005-05-26 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ PR c++/21768
+ * pt.c (redeclare_class_template): Change error message according
+ to coding conventions.
+
+2005-05-26 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
+
+ * call.c (build_op_delete_call): Fix quoting in error message.
+
+2005-05-25 Richard Henderson <rth@redhat.com>
+
+ PR libgcj/21692
+ * cp-tree.h (make_alias_for): Declare.
+ * decl2.c (build_java_method_aliases): New.
+ (cp_finish_file): Call it.
+ * method.c (make_alias_for): Split out from ...
+ (make_alias_for_thunk): ... here.
+
2005-05-25 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
PR c++/21686
@@ -248,8 +375,8 @@
2005-05-02 Paolo Bonzini <bonzini@gnu.org>
- * semantics.c (finish_call_expr): Call resolve_overloaded_builtin
- for BUILT_IN_MD built-ins.
+ * semantics.c (finish_call_expr): Call resolve_overloaded_builtin
+ for BUILT_IN_MD built-ins.
2005-05-02 Michael Matz <matz@suse.de>
@@ -310,7 +437,7 @@
2005-04-22 Per Bothner <per@bothner.com>
* decl.c (make_rtl_for_nonlocal_decl): Don't try get_fileinfo if
- input_filename is NULL, as it is for (say) __PRETTY_FUNCTION__.
+ input_filename is NULL, as it is for (say) __PRETTY_FUNCTION__.
2005-04-22 Alexandre Oliva <aoliva@redhat.com>
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index e40e61f0aae..01d4046e0bf 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -1652,7 +1652,7 @@ add_builtin_candidate (struct z_candidate **candidates, enum tree_code code,
T operator+(T);
T operator-(T); */
- case CONVERT_EXPR: /* unary + */
+ case UNARY_PLUS_EXPR: /* unary + */
if (TREE_CODE (type1) == POINTER_TYPE)
break;
case NEGATE_EXPR:
@@ -3848,7 +3848,7 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
case TRUTH_ORIF_EXPR:
return cp_build_binary_op (code, arg1, arg2);
- case CONVERT_EXPR:
+ case UNARY_PLUS_EXPR:
case NEGATE_EXPR:
case BIT_NOT_EXPR:
case TRUTH_NOT_EXPR:
@@ -4035,7 +4035,7 @@ build_op_delete_call (enum tree_code code, tree addr, tree size,
if (placement)
return NULL_TREE;
- error ("no suitable %<operator %s> for %qT",
+ error ("no suitable %<operator %s%> for %qT",
operator_name_info[(int)code].name, type);
return error_mark_node;
}
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index fc8c1af2d21..4ad30b98008 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -557,6 +557,16 @@ cp_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p)
ret = GS_OK;
break;
+ case UNARY_PLUS_EXPR:
+ {
+ tree arg = TREE_OPERAND (*expr_p, 0);
+ tree type = TREE_TYPE (*expr_p);
+ *expr_p = (TREE_TYPE (arg) != type) ? fold_convert (type, arg)
+ : arg;
+ ret = GS_OK;
+ }
+ break;
+
default:
ret = c_gimplify_expr (expr_p, pre_p, post_p);
break;
diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def
index 705517a2e4a..c42dbfbf7c0 100644
--- a/gcc/cp/cp-tree.def
+++ b/gcc/cp/cp-tree.def
@@ -340,6 +340,10 @@ DEFTREECODE (ALIGNOF_EXPR, "alignof_expr", tcc_unary, 1)
STMT_EXPR_STMT is the statement given by the expression. */
DEFTREECODE (STMT_EXPR, "stmt_expr", tcc_expression, 1)
+/* Unary plus. Operand 0 is the expression to which the unary plus
+ is applied. */
+DEFTREECODE (UNARY_PLUS_EXPR, "unary_plus_expr", tcc_unary, 1)
+
/*
Local variables:
mode:c
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 4d956a7ea01..65f9d507800 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -59,6 +59,7 @@ struct diagnostic_context;
ICS_ELLIPSIS_FLAG (in _CONV)
DECL_INITIALIZED_P (in VAR_DECL)
TYPENAME_IS_CLASS_P (in TYPENAME_TYPE)
+ STMT_IS_FULL_EXPR_P (in _STMT)
2: IDENTIFIER_OPNAME_P (in IDENTIFIER_NODE)
ICS_THIS_FLAG (in _CONV)
DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (in VAR_DECL)
@@ -259,6 +260,11 @@ typedef struct ptrmem_cst * ptrmem_cst_t;
#define STATEMENT_LIST_TRY_BLOCK(NODE) \
TREE_LANG_FLAG_2 (STATEMENT_LIST_CHECK (NODE))
+/* Nonzero if this statement should be considered a full-expression,
+ i.e., if temporaries created during this statement should have
+ their destructors run at the end of this statement. */
+#define STMT_IS_FULL_EXPR_P(NODE) TREE_LANG_FLAG_1 ((NODE))
+
/* Marks the result of a statement expression. */
#define EXPR_STMT_STMT_EXPR_RESULT(NODE) \
TREE_LANG_FLAG_0 (EXPR_STMT_CHECK (NODE))
@@ -3760,7 +3766,7 @@ extern int copy_fn_p (tree);
extern tree get_scope_of_declarator (const cp_declarator *);
extern void grok_special_member_properties (tree);
extern int grok_ctor_properties (tree, tree);
-extern void grok_op_properties (tree, int, bool);
+extern void grok_op_properties (tree, bool);
extern tree xref_tag (enum tag_types, tree, tag_scope, bool);
extern tree xref_tag_from_type (tree, tree, tag_scope);
extern void xref_basetypes (tree, tree);
@@ -3923,6 +3929,7 @@ extern void synthesize_method (tree);
extern tree implicitly_declare_fn (special_function_kind, tree, bool);
extern tree lazily_declare_fn (special_function_kind, tree);
extern tree skip_artificial_parms_for (tree, tree);
+extern tree make_alias_for (tree, tree);
/* In optimize.c */
extern bool maybe_clone_body (tree);
@@ -4062,6 +4069,7 @@ extern tree get_deferred_access_checks (void);
extern void pop_to_parent_deferring_access_checks (void);
extern void perform_deferred_access_checks (void);
extern void perform_or_defer_access_check (tree, tree);
+extern int stmts_are_full_exprs_p (void);
extern void init_cp_semantics (void);
extern tree do_poplevel (tree);
extern void add_decl_expr (tree);
diff --git a/gcc/cp/cxx-pretty-print.c b/gcc/cp/cxx-pretty-print.c
index 0ad1e9a4025..afa969f9f71 100644
--- a/gcc/cp/cxx-pretty-print.c
+++ b/gcc/cp/cxx-pretty-print.c
@@ -43,6 +43,7 @@ static void pp_cxx_parameter_declaration_clause (cxx_pretty_printer *, tree);
static void pp_cxx_abstract_declarator (cxx_pretty_printer *, tree);
static void pp_cxx_statement (cxx_pretty_printer *, tree);
static void pp_cxx_template_parameter (cxx_pretty_printer *, tree);
+static void pp_cxx_cast_expression (cxx_pretty_printer *, tree);
static inline void
@@ -640,6 +641,11 @@ pp_cxx_unary_expression (cxx_pretty_printer *pp, tree t)
pp_unary_expression (pp, TREE_OPERAND (t, 0));
break;
+ case UNARY_PLUS_EXPR:
+ pp_plus (pp);
+ pp_cxx_cast_expression (pp, TREE_OPERAND (t, 0));
+ break;
+
default:
pp_c_unary_expression (pp_c_base (pp), t);
break;
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index d3544172bc4..6b278ae2878 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -1672,13 +1672,14 @@ duplicate_decls (tree newdecl, tree olddecl)
DECL_COMDAT (newdecl) |= DECL_COMDAT (olddecl);
DECL_TEMPLATE_INSTANTIATED (newdecl)
|= DECL_TEMPLATE_INSTANTIATED (olddecl);
- /* If the OLDDECL is an implicit instantiation, then the NEWDECL
- must be too. But, it may not yet be marked as such if the
- caller has created NEWDECL, but has not yet figured out that
- it is a redeclaration. */
- if (DECL_IMPLICIT_INSTANTIATION (olddecl)
- && !DECL_USE_TEMPLATE (newdecl))
- SET_DECL_IMPLICIT_INSTANTIATION (newdecl);
+
+ /* If the OLDDECL is an instantiation and/or specialization,
+ then the NEWDECL must be too. But, it may not yet be marked
+ as such if the caller has created NEWDECL, but has not yet
+ figured out that it is a redeclaration. */
+ if (!DECL_USE_TEMPLATE (newdecl))
+ DECL_USE_TEMPLATE (newdecl) = DECL_USE_TEMPLATE (olddecl);
+
/* Don't really know how much of the language-specific
values we should copy from old to new. */
DECL_IN_AGGR_P (newdecl) = DECL_IN_AGGR_P (olddecl);
@@ -3715,22 +3716,22 @@ start_decl (const cp_declarator *declarator,
/* cp_finish_decl sets DECL_EXTERNAL if DECL_IN_AGGR_P is set. */
DECL_IN_AGGR_P (decl) = 0;
- if ((DECL_LANG_SPECIFIC (decl) && DECL_USE_TEMPLATE (decl))
- || CLASSTYPE_TEMPLATE_INSTANTIATION (context))
- {
- /* Do not mark DECL as an explicit specialization if it was
- not already marked as an instantiation; a declaration
- should never be marked as a specialization unless we know
- what template is being specialized. */
- if (DECL_LANG_SPECIFIC (decl) && DECL_USE_TEMPLATE (decl))
- SET_DECL_TEMPLATE_SPECIALIZATION (decl);
+ /* Do not mark DECL as an explicit specialization if it was not
+ already marked as an instantiation; a declaration should
+ never be marked as a specialization unless we know what
+ template is being specialized. */
+ if (DECL_LANG_SPECIFIC (decl) && DECL_USE_TEMPLATE (decl))
+ {
+ SET_DECL_TEMPLATE_SPECIALIZATION (decl);
+
/* [temp.expl.spec] An explicit specialization of a static data
member of a template is a definition if the declaration
includes an initializer; otherwise, it is a declaration.
-
+
We check for processing_specialization so this only applies
to the new specialization syntax. */
- if (DECL_INITIAL (decl) == NULL_TREE && processing_specialization)
+ if (!DECL_INITIAL (decl)
+ && processing_specialization)
DECL_EXTERNAL (decl) = 1;
}
@@ -5609,7 +5610,7 @@ grokfndecl (tree ctype,
}
if (IDENTIFIER_OPNAME_P (DECL_NAME (decl)))
- grok_op_properties (decl, friendp, /*complain=*/true);
+ grok_op_properties (decl, /*complain=*/true);
if (ctype && decl_function_context (decl))
DECL_NO_STATIC_CHAIN (decl) = 1;
@@ -8586,7 +8587,7 @@ ambi_op_p (enum tree_code code)
{
return (code == INDIRECT_REF
|| code == ADDR_EXPR
- || code == CONVERT_EXPR
+ || code == UNARY_PLUS_EXPR
|| code == NEGATE_EXPR
|| code == PREINCREMENT_EXPR
|| code == PREDECREMENT_EXPR);
@@ -8607,7 +8608,7 @@ unary_op_p (enum tree_code code)
errors are issued for invalid declarations. */
void
-grok_op_properties (tree decl, int friendp, bool complain)
+grok_op_properties (tree decl, bool complain)
{
tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (decl));
tree argtype;
@@ -8615,6 +8616,7 @@ grok_op_properties (tree decl, int friendp, bool complain)
tree name = DECL_NAME (decl);
enum tree_code operator_code;
int arity;
+ tree class_type;
/* Count the number of arguments. */
for (argtype = argtypes, arity = 0;
@@ -8622,8 +8624,9 @@ grok_op_properties (tree decl, int friendp, bool complain)
argtype = TREE_CHAIN (argtype))
++arity;
- if (current_class_type == NULL_TREE)
- friendp = 1;
+ class_type = DECL_CONTEXT (decl);
+ if (class_type && !CLASS_TYPE_P (class_type))
+ class_type = NULL_TREE;
if (DECL_CONV_FN_P (decl))
operator_code = TYPE_EXPR;
@@ -8652,30 +8655,28 @@ grok_op_properties (tree decl, int friendp, bool complain)
gcc_assert (operator_code != LAST_CPLUS_TREE_CODE);
SET_OVERLOADED_OPERATOR_CODE (decl, operator_code);
- if (! friendp)
- {
- switch (operator_code)
- {
- case NEW_EXPR:
- TYPE_HAS_NEW_OPERATOR (current_class_type) = 1;
- break;
+ if (class_type)
+ switch (operator_code)
+ {
+ case NEW_EXPR:
+ TYPE_HAS_NEW_OPERATOR (class_type) = 1;
+ break;
- case DELETE_EXPR:
- TYPE_GETS_DELETE (current_class_type) |= 1;
- break;
+ case DELETE_EXPR:
+ TYPE_GETS_DELETE (class_type) |= 1;
+ break;
- case VEC_NEW_EXPR:
- TYPE_HAS_ARRAY_NEW_OPERATOR (current_class_type) = 1;
- break;
+ case VEC_NEW_EXPR:
+ TYPE_HAS_ARRAY_NEW_OPERATOR (class_type) = 1;
+ break;
- case VEC_DELETE_EXPR:
- TYPE_GETS_DELETE (current_class_type) |= 2;
- break;
+ case VEC_DELETE_EXPR:
+ TYPE_GETS_DELETE (class_type) |= 2;
+ break;
- default:
- break;
- }
- }
+ default:
+ break;
+ }
/* [basic.std.dynamic.allocation]/1:
@@ -8754,32 +8755,38 @@ grok_op_properties (tree decl, int friendp, bool complain)
if (operator_code == CALL_EXPR)
return;
- if (IDENTIFIER_TYPENAME_P (name) && ! DECL_TEMPLATE_INFO (decl))
+ /* Warn about conversion operators that will never be used. */
+ if (IDENTIFIER_TYPENAME_P (name)
+ && ! DECL_TEMPLATE_INFO (decl)
+ && warn_conversion
+ /* Warn only declaring the function; there is no need to
+ warn again about out-of-class definitions. */
+ && class_type == current_class_type)
{
tree t = TREE_TYPE (name);
- if (! friendp)
- {
- int ref = (TREE_CODE (t) == REFERENCE_TYPE);
- const char *what = 0;
+ int ref = (TREE_CODE (t) == REFERENCE_TYPE);
+ const char *what = 0;
- if (ref)
- t = TYPE_MAIN_VARIANT (TREE_TYPE (t));
+ if (ref)
+ t = TYPE_MAIN_VARIANT (TREE_TYPE (t));
- if (TREE_CODE (t) == VOID_TYPE)
- what = "void";
- else if (t == current_class_type)
+ if (TREE_CODE (t) == VOID_TYPE)
+ what = "void";
+ else if (class_type)
+ {
+ if (t == class_type)
what = "the same type";
/* Don't force t to be complete here. */
else if (IS_AGGR_TYPE (t)
&& COMPLETE_TYPE_P (t)
- && DERIVED_FROM_P (t, current_class_type))
+ && DERIVED_FROM_P (t, class_type))
what = "a base class";
-
- if (what && warn_conversion)
- warning (0, "conversion to %s%s will never use a type "
- "conversion operator",
- ref ? "a reference to " : "", what);
}
+
+ if (what)
+ warning (0, "conversion to %s%s will never use a type "
+ "conversion operator",
+ ref ? "a reference to " : "", what);
}
if (operator_code == COND_EXPR)
{
@@ -8806,7 +8813,7 @@ grok_op_properties (tree decl, int friendp, bool complain)
operator_code = BIT_AND_EXPR;
break;
- case CONVERT_EXPR:
+ case UNARY_PLUS_EXPR:
operator_code = PLUS_EXPR;
break;
@@ -9878,7 +9885,8 @@ start_preparsed_function (tree decl1, tree attrs, int flags)
int doing_friend = 0;
struct cp_binding_level *bl;
tree current_function_parms;
- struct c_fileinfo *finfo = get_fileinfo (lbasename (input_filename));
+ struct c_fileinfo *finfo
+ = get_fileinfo (lbasename (LOCATION_FILE (DECL_SOURCE_LOCATION (decl1))));
/* Sanity check. */
gcc_assert (TREE_CODE (TREE_VALUE (void_list_node)) == VOID_TYPE);
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 970c6381cc6..48febf714d0 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -2731,6 +2731,50 @@ cxx_callgraph_analyze_expr (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
return NULL;
}
+/* Java requires that we be able to reference a local address for a
+ method, and not be confused by PLT entries. If hidden aliases are
+ supported, emit one for each java function that we've emitted. */
+
+static void
+build_java_method_aliases (void)
+{
+ struct cgraph_node *node;
+
+#ifndef HAVE_GAS_HIDDEN
+ return;
+#endif
+
+ for (node = cgraph_nodes; node ; node = node->next)
+ {
+ tree fndecl = node->decl;
+
+ if (TREE_ASM_WRITTEN (fndecl)
+ && DECL_CONTEXT (fndecl)
+ && TYPE_P (DECL_CONTEXT (fndecl))
+ && TYPE_FOR_JAVA (DECL_CONTEXT (fndecl))
+ && TARGET_USE_LOCAL_THUNK_ALIAS_P (fndecl))
+ {
+ /* Mangle the name in a predictable way; we need to reference
+ this from a java compiled object file. */
+ tree oid, nid, alias;
+ const char *oname;
+ char *nname;
+
+ oid = DECL_ASSEMBLER_NAME (fndecl);
+ oname = IDENTIFIER_POINTER (oid);
+ gcc_assert (oname[0] == '_' && oname[1] == 'Z');
+ nname = ACONCAT (("_ZGA", oname+2, NULL));
+ nid = get_identifier (nname);
+
+ alias = make_alias_for (fndecl, nid);
+ TREE_PUBLIC (alias) = 1;
+ DECL_VISIBILITY (alias) = VISIBILITY_HIDDEN;
+
+ assemble_alias (alias, oid);
+ }
+ }
+}
+
/* This routine is called from the last rule in yyparse ().
Its job is to create all the code needed to initialize and
destroy the global aggregates. We do the destruction
@@ -2922,6 +2966,10 @@ cp_finish_file (void)
finish_function doesn't clean things up, and we end
up with CURRENT_FUNCTION_DECL set. */
push_to_top_level ();
+ /* The decl's location will mark where it was first
+ needed. Save that so synthesize method can indicate
+ where it was needed from, in case of error */
+ input_location = DECL_SOURCE_LOCATION (decl);
synthesize_method (decl);
pop_from_top_level ();
reconsider = true;
@@ -3062,6 +3110,9 @@ cp_finish_file (void)
check_global_declarations (VEC_address (tree, pending_statics),
VEC_length (tree, pending_statics));
+ /* Generate hidden aliases for Java. */
+ build_java_method_aliases ();
+
finish_repo ();
/* The entire file is now complete. If requested, dump everything
@@ -3181,6 +3232,14 @@ mark_used (tree decl)
{
if (DECL_DEFERRED_FN (decl))
return;
+
+ /* Remember the current location for a function we will end up
+ synthesizing. Then we can inform the user where it was
+ required in the case of error. */
+ if (DECL_ARTIFICIAL (decl) && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)
+ && !DECL_THUNK_P (decl))
+ DECL_SOURCE_LOCATION (decl) = input_location;
+
note_vague_linkage_fn (decl);
}
@@ -3198,14 +3257,6 @@ mark_used (tree decl)
pointing to the class location. */
&& current_function_decl)
{
- /* Put the function definition at the position where it is needed,
- rather than within the body of the class. That way, an error
- during the generation of the implicit body points at the place
- where the attempt to generate the function occurs, giving the
- user a hint as to why we are attempting to generate the
- function. */
- DECL_SOURCE_LOCATION (decl) = input_location;
-
synthesize_method (decl);
/* If we've already synthesized the method we don't need to
instantiate it, so we can return right away. */
diff --git a/gcc/cp/dump.c b/gcc/cp/dump.c
index 6b93045e02f..daf55952c53 100644
--- a/gcc/cp/dump.c
+++ b/gcc/cp/dump.c
@@ -65,7 +65,7 @@ dump_op (dump_info_p di, tree t)
case VEC_DELETE_EXPR:
dump_string (di, "vecdelete");
break;
- case CONVERT_EXPR:
+ case UNARY_PLUS_EXPR:
dump_string (di, "pos");
break;
case NEGATE_EXPR:
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 4e634efcdff..9f24276a514 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -1518,7 +1518,7 @@ dump_expr (tree t, int flags)
pp_cxx_right_bracket (cxx_pp);
break;
- case CONVERT_EXPR:
+ case UNARY_PLUS_EXPR:
if (TREE_TYPE (t) && VOID_TYPE_P (TREE_TYPE (t)))
{
pp_cxx_left_paren (cxx_pp);
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 99891cb2922..7c8d9c6a800 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -1573,7 +1573,7 @@ integral_constant_value (tree decl)
&& DECL_INITIAL (decl)
&& DECL_INITIAL (decl) != error_mark_node
&& TREE_TYPE (DECL_INITIAL (decl))
- && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (decl)))
+ && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (DECL_INITIAL (decl))))
decl = DECL_INITIAL (decl);
return decl;
}
diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c
index 21fe2a13581..7e891860306 100644
--- a/gcc/cp/lex.c
+++ b/gcc/cp/lex.c
@@ -145,7 +145,7 @@ init_operators (void)
operator_name_info [(int) TRUTH_AND_EXPR].name = "strict &&";
operator_name_info [(int) TRUTH_OR_EXPR].name = "strict ||";
operator_name_info [(int) RANGE_EXPR].name = "...";
- operator_name_info [(int) CONVERT_EXPR].name = "+";
+ operator_name_info [(int) UNARY_PLUS_EXPR].name = "+";
assignment_operator_name_info [(int) EXACT_DIV_EXPR].name
= "(exact /=)";
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index a2fefd0c238..8c276b586ae 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -1426,8 +1426,6 @@ write_special_name_destructor (const tree dtor)
static int
discriminator_for_local_entity (tree entity)
{
- tree *type;
-
/* Assume this is the only local entity with this name. */
int discriminator = 0;
@@ -1435,12 +1433,19 @@ discriminator_for_local_entity (tree entity)
discriminator = DECL_DISCRIMINATOR (entity);
else if (TREE_CODE (entity) == TYPE_DECL)
{
+ int ix;
+
/* Scan the list of local classes. */
entity = TREE_TYPE (entity);
- for (type = VEC_address (tree, local_classes); *type != entity; ++type)
- if (TYPE_IDENTIFIER (*type) == TYPE_IDENTIFIER (entity)
- && TYPE_CONTEXT (*type) == TYPE_CONTEXT (entity))
- ++discriminator;
+ for (ix = 0; ; ix++)
+ {
+ tree type = VEC_index (tree, local_classes, ix);
+ if (type == entity)
+ break;
+ if (TYPE_IDENTIFIER (type) == TYPE_IDENTIFIER (entity)
+ && TYPE_CONTEXT (type) == TYPE_CONTEXT (entity))
+ ++discriminator;
+ }
}
return discriminator;
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index f606c7014c8..0621fe2b140 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -38,6 +38,7 @@ Boston, MA 02111-1307, USA. */
#include "target.h"
#include "cgraph.h"
#include "tree-pass.h"
+#include "diagnostic.h"
/* Various flags to control the mangling process. */
@@ -259,16 +260,10 @@ static GTY (()) int thunk_labelno;
/* Create a static alias to function. */
-static tree
-make_alias_for_thunk (tree function)
+tree
+make_alias_for (tree function, tree newid)
{
- tree alias;
- char buf[256];
-
- ASM_GENERATE_INTERNAL_LABEL (buf, "LTHUNK", thunk_labelno);
- thunk_labelno++;
- alias = build_decl (FUNCTION_DECL, get_identifier (buf),
- TREE_TYPE (function));
+ tree alias = build_decl (FUNCTION_DECL, newid, TREE_TYPE (function));
DECL_LANG_SPECIFIC (alias) = DECL_LANG_SPECIFIC (function);
cxx_dup_lang_specific_decl (alias);
DECL_CONTEXT (alias) = NULL;
@@ -297,8 +292,23 @@ make_alias_for_thunk (tree function)
TREE_USED (alias) = 1;
SET_DECL_ASSEMBLER_NAME (alias, DECL_NAME (alias));
TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (alias)) = 1;
+ return alias;
+}
+
+static tree
+make_alias_for_thunk (tree function)
+{
+ tree alias;
+ char buf[256];
+
+ ASM_GENERATE_INTERNAL_LABEL (buf, "LTHUNK", thunk_labelno);
+ thunk_labelno++;
+
+ alias = make_alias_for (function, get_identifier (buf));
+
if (!flag_syntax_only)
assemble_alias (alias, DECL_ASSEMBLER_NAME (function));
+
return alias;
}
@@ -725,6 +735,8 @@ do_build_assign_ref (tree fndecl)
finish_compound_stmt (compound_stmt);
}
+/* Synthesize FNDECL, a non-static member function. */
+
void
synthesize_method (tree fndecl)
{
@@ -733,17 +745,19 @@ synthesize_method (tree fndecl)
bool need_body = true;
tree stmt;
location_t save_input_location = input_location;
+ int error_count = errorcount;
+ int warning_count = warningcount;
+ /* Reset the source location, we might have been previously
+ deferred, and thus have saved where we were first needed. */
+ DECL_SOURCE_LOCATION (fndecl)
+ = DECL_SOURCE_LOCATION (TYPE_NAME (DECL_CONTEXT (fndecl)));
+
/* If we've been asked to synthesize a clone, just synthesize the
cloned function instead. Doing so will automatically fill in the
body for the clone. */
if (DECL_CLONED_FUNCTION_P (fndecl))
- {
- DECL_SOURCE_LOCATION (DECL_CLONED_FUNCTION (fndecl)) =
- DECL_SOURCE_LOCATION (fndecl);
- synthesize_method (DECL_CLONED_FUNCTION (fndecl));
- return;
- }
+ fndecl = DECL_CLONED_FUNCTION (fndecl);
/* We may be in the middle of deferred access check. Disable
it now. */
@@ -793,6 +807,10 @@ synthesize_method (tree fndecl)
pop_function_context_from (context);
pop_deferring_access_checks ();
+
+ if (error_count != errorcount || warning_count != warningcount)
+ warning (0, "%Hsynthesized method %qD first required here ",
+ &input_location, fndecl);
}
/* Use EXTRACTOR to locate the relevant function called for each base &
@@ -962,6 +980,19 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
tree raises = empty_except_spec;
tree rhs_parm_type = NULL_TREE;
tree name;
+ HOST_WIDE_INT saved_processing_template_decl;
+
+ /* Because we create declarations for implictly declared functions
+ lazily, we may be creating the declaration for a member of TYPE
+ while in some completely different context. However, TYPE will
+ never be a dependent class (because we never want to do lookups
+ for implicitly defined functions in a dependent class).
+ Furthermore, we must set PROCESSING_TEMPLATE_DECL to zero here
+ because we only create clones for constructors and destructors
+ when not in a template. */
+ gcc_assert (!dependent_type_p (type));
+ saved_processing_template_decl = processing_template_decl;
+ processing_template_decl = 0;
type = TYPE_MAIN_VARIANT (type);
@@ -1060,6 +1091,9 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
DECL_INLINE (fn) = 1;
gcc_assert (!TREE_USED (fn));
+ /* Restore PROCESSING_TEMPLATE_DECL. */
+ processing_template_decl = saved_processing_template_decl;
+
return fn;
}
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index bd83695cd0a..3197a41077d 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -2032,6 +2032,14 @@ do_nonmember_using_decl (tree scope, tree name, tree oldval, tree oldtype,
return;
}
+ /* It is impossible to overload a built-in function; any explicit
+ declaration eliminates the built-in declaration. So, if OLDVAL
+ is a built-in, then we can just pretend it isn't there. */
+ if (oldval
+ && TREE_CODE (oldval) == FUNCTION_DECL
+ && DECL_ANTICIPATED (oldval))
+ oldval = NULL_TREE;
+
/* Check for using functions. */
if (decls.value && is_overloaded_fn (decls.value))
{
@@ -2044,15 +2052,6 @@ do_nonmember_using_decl (tree scope, tree name, tree oldval, tree oldtype,
oldval = NULL_TREE;
}
- /* It is impossible to overload a built-in function; any
- explicit declaration eliminates the built-in declaration.
- So, if OLDVAL is a built-in, then we can just pretend it
- isn't there. */
- if (oldval
- && TREE_CODE (oldval) == FUNCTION_DECL
- && DECL_ANTICIPATED (oldval))
- oldval = NULL_TREE;
-
*newval = oldval;
for (tmp = decls.value; tmp; tmp = OVL_NEXT (tmp))
{
@@ -4699,8 +4698,7 @@ pushtag (tree name, tree type, tag_scope scope)
way. (It's otherwise tricky to find a member function definition
it's only pointed to from within a local class.) */
if (TYPE_CONTEXT (type)
- && TREE_CODE (TYPE_CONTEXT (type)) == FUNCTION_DECL
- && !processing_template_decl)
+ && TREE_CODE (TYPE_CONTEXT (type)) == FUNCTION_DECL)
VEC_safe_push (tree, gc, local_classes, type);
}
if (b->kind == sk_class
diff --git a/gcc/cp/operators.def b/gcc/cp/operators.def
index 16e603d31bf..e35144b29e3 100644
--- a/gcc/cp/operators.def
+++ b/gcc/cp/operators.def
@@ -5,7 +5,7 @@
non-overloadable operators (like the `?:' ternary operator).
Written by Mark Mitchell <mark@codesourcery.com>
- Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
This file is part of GCC.
@@ -84,7 +84,7 @@ DEF_SIMPLE_OPERATOR ("delete", DELETE_EXPR, "dl", -1)
DEF_SIMPLE_OPERATOR ("delete []", VEC_DELETE_EXPR, "da", -1)
/* Unary operators. */
-DEF_SIMPLE_OPERATOR ("+", CONVERT_EXPR, "ps", 1)
+DEF_SIMPLE_OPERATOR ("+", UNARY_PLUS_EXPR, "ps", 1)
DEF_SIMPLE_OPERATOR ("-", NEGATE_EXPR, "ng", 1)
DEF_SIMPLE_OPERATOR ("&", ADDR_EXPR, "ad", 1)
DEF_SIMPLE_OPERATOR ("*", INDIRECT_REF, "de", 1)
diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c
index bf9b22b63e9..e779b54ad22 100644
--- a/gcc/cp/optimize.c
+++ b/gcc/cp/optimize.c
@@ -1,5 +1,5 @@
/* Perform optimizations on tree structure.
- Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005
Free Software Foundation, Inc.
Written by Mark Michell (mark@codesourcery.com).
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index a0d71b3141f..27c1751cb02 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -4873,7 +4873,7 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p)
non_constant_p = (unary_operator == PREINCREMENT_EXPR
? "`++'" : "`--'");
/* Fall through. */
- case CONVERT_EXPR:
+ case UNARY_PLUS_EXPR:
case NEGATE_EXPR:
case TRUTH_NOT_EXPR:
expression = finish_unary_op_expr (unary_operator, cast_expression);
@@ -4909,7 +4909,7 @@ cp_parser_unary_operator (cp_token* token)
return ADDR_EXPR;
case CPP_PLUS:
- return CONVERT_EXPR;
+ return UNARY_PLUS_EXPR;
case CPP_MINUS:
return NEGATE_EXPR;
@@ -15486,6 +15486,7 @@ cp_parser_late_parsing_for_member (cp_parser* parser, tree member_function)
if (function_scope)
push_function_context_to (function_scope);
+
/* Push the body of the function onto the lexer stack. */
cp_parser_push_lexer_for_tokens (parser, tokens);
@@ -15494,10 +15495,17 @@ cp_parser_late_parsing_for_member (cp_parser* parser, tree member_function)
start_preparsed_function (member_function, NULL_TREE,
SF_PRE_PARSED | SF_INCLASS_INLINE);
+ /* Don't do access checking if it is a templated function. */
+ if (processing_template_decl)
+ push_deferring_access_checks (dk_no_check);
+
/* Now, parse the body of the function. */
cp_parser_function_definition_after_declarator (parser,
/*inline_p=*/true);
+ if (processing_template_decl)
+ pop_deferring_access_checks ();
+
/* Leave the scope of the containing function. */
if (function_scope)
pop_function_context_from (function_scope);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 1a1d5c0f237..ad1e5f33bfd 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -3225,10 +3225,9 @@ redeclare_class_template (tree type, tree parms)
if (TREE_VEC_LENGTH (parms) != TREE_VEC_LENGTH (tmpl_parms))
{
cp_error_at ("previous declaration %qD", tmpl);
- error ("used %d template parameter%s instead of %d",
- TREE_VEC_LENGTH (tmpl_parms),
- TREE_VEC_LENGTH (tmpl_parms) == 1 ? "" : "s",
- TREE_VEC_LENGTH (parms));
+ error ("used %d template parameter(s) instead of %d",
+ TREE_VEC_LENGTH (tmpl_parms),
+ TREE_VEC_LENGTH (parms));
return;
}
@@ -6495,8 +6494,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
clone_function_decl (r, /*update_method_vec_p=*/0);
}
else if (IDENTIFIER_OPNAME_P (DECL_NAME (r)))
- grok_op_properties (r, DECL_FRIEND_P (r),
- (complain & tf_error) != 0);
+ grok_op_properties (r, (complain & tf_error) != 0);
if (DECL_FRIEND_P (t) && DECL_FRIEND_CONTEXT (t))
SET_DECL_FRIEND_CONTEXT (r,
@@ -7785,7 +7783,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
case TRUTH_NOT_EXPR:
case BIT_NOT_EXPR:
case ADDR_EXPR:
- case CONVERT_EXPR: /* Unary + */
+ case UNARY_PLUS_EXPR: /* Unary + */
case SIZEOF_EXPR:
case ALIGNOF_EXPR:
case ARROW_EXPR:
@@ -8466,7 +8464,7 @@ tsubst_copy_and_build (tree t,
case BIT_NOT_EXPR:
case ABS_EXPR:
case TRUTH_NOT_EXPR:
- case CONVERT_EXPR: /* Unary + */
+ case UNARY_PLUS_EXPR: /* Unary + */
case REALPART_EXPR:
case IMAGPART_EXPR:
return build_x_unary_op (TREE_CODE (t), RECUR (TREE_OPERAND (t, 0)));
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 1316ef34888..d969a246379 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -340,6 +340,32 @@ stmts_are_full_exprs_p (void)
return current_stmt_tree ()->stmts_are_full_exprs_p;
}
+/* T is a statement. Add it to the statement-tree. This is the C++
+ version. The C/ObjC frontends have a slightly different version of
+ this function. */
+
+tree
+add_stmt (tree t)
+{
+ enum tree_code code = TREE_CODE (t);
+
+ if (EXPR_P (t) && code != LABEL_EXPR)
+ {
+ if (!EXPR_HAS_LOCATION (t))
+ SET_EXPR_LOCATION (t, input_location);
+
+ /* When we expand a statement-tree, we must know whether or not the
+ statements are full-expressions. We record that fact here. */
+ STMT_IS_FULL_EXPR_P (t) = stmts_are_full_exprs_p ();
+ }
+
+ /* Add T to the statement-tree. Non-side-effect statements need to be
+ recorded during statement expressions. */
+ append_to_statement_list_force (t, &cur_stmt_list);
+
+ return t;
+}
+
/* Returns the stmt_tree (if any) to which statements are currently
being added. If there is no active statement-tree, NULL is
returned. */
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 64a5aa5bd25..8ef383c30ee 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -2268,7 +2268,14 @@ fold_if_not_in_template (tree expr)
"fold". We will call fold later when actually instantiating the
template. Integral constant expressions in templates will be
evaluated via fold_non_dependent_expr, as necessary. */
- return (processing_template_decl ? expr : fold (expr));
+ if (processing_template_decl)
+ return expr;
+
+ /* Fold C++ front-end specific tree codes. */
+ if (TREE_CODE (expr) == UNARY_PLUS_EXPR)
+ return fold_convert (TREE_TYPE (expr), TREE_OPERAND (expr, 0));
+
+ return fold (expr);
}
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 8bd101295fd..73bb514f499 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -2346,14 +2346,23 @@ get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function)
gcc_unreachable ();
}
- /* Convert down to the right base before using the instance. First
- use the type... */
+ /* Convert down to the right base before using the instance. A
+ special case is that in a pointer to member of class C, C may
+ be incomplete. In that case, the function will of course be
+ a member of C, and no conversion is required. In fact,
+ lookup_base will fail in that case, because incomplete
+ classes do not have BINFOs. */
basetype = TYPE_METHOD_BASETYPE (TREE_TYPE (fntype));
- basetype = lookup_base (TREE_TYPE (TREE_TYPE (instance_ptr)),
- basetype, ba_check, NULL);
- instance_ptr = build_base_path (PLUS_EXPR, instance_ptr, basetype, 1);
- if (instance_ptr == error_mark_node)
- return error_mark_node;
+ if (!same_type_ignoring_top_level_qualifiers_p
+ (basetype, TREE_TYPE (TREE_TYPE (instance_ptr))))
+ {
+ basetype = lookup_base (TREE_TYPE (TREE_TYPE (instance_ptr)),
+ basetype, ba_check, NULL);
+ instance_ptr = build_base_path (PLUS_EXPR, instance_ptr, basetype,
+ 1);
+ if (instance_ptr == error_mark_node)
+ return error_mark_node;
+ }
/* ...and then the delta in the PMF. */
instance_ptr = build2 (PLUS_EXPR, TREE_TYPE (instance_ptr),
instance_ptr, delta);
@@ -3692,13 +3701,12 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert)
switch (code)
{
- /* CONVERT_EXPR stands for unary plus in this context. */
- case CONVERT_EXPR:
+ case UNARY_PLUS_EXPR:
case NEGATE_EXPR:
{
int flags = WANT_ARITH | WANT_ENUM;
/* Unary plus (but not unary minus) is allowed on pointers. */
- if (code == CONVERT_EXPR)
+ if (code == UNARY_PLUS_EXPR)
flags |= WANT_POINTER;
arg = build_expr_type_conversion (flags, arg, true);
if (!arg)
@@ -5523,7 +5531,6 @@ get_delta_difference (tree from, tree to,
bool c_cast_p)
{
tree binfo;
- tree virt_binfo;
base_kind kind;
tree result;
@@ -5532,36 +5539,14 @@ get_delta_difference (tree from, tree to,
binfo = lookup_base (to, from, c_cast_p ? ba_unique : ba_check, &kind);
if (kind == bk_inaccessible || kind == bk_ambig)
error (" in pointer to member function conversion");
- else if (!binfo)
- {
- if (!allow_inverse_p)
- {
- error_not_base_type (from, to);
- error (" in pointer to member conversion");
- }
- else
- {
- binfo = lookup_base (from, to, c_cast_p ? ba_unique : ba_check,
- &kind);
- if (binfo)
- {
- virt_binfo = binfo_from_vbase (binfo);
- if (virt_binfo)
- /* This is a reinterpret cast, we choose to do nothing. */
- warning (0, "pointer to member cast via virtual base %qT",
- BINFO_TYPE (virt_binfo));
- else
- result = size_diffop (size_zero_node, BINFO_OFFSET (binfo));
- }
- }
- }
- else
+ else if (binfo)
{
- virt_binfo = binfo_from_vbase (binfo);
- if (!virt_binfo)
+ if (kind != bk_via_virtual)
result = BINFO_OFFSET (binfo);
else
{
+ tree virt_binfo = binfo_from_vbase (binfo);
+
/* This is a reinterpret cast, we choose to do nothing. */
if (allow_inverse_p)
warning (0, "pointer to member cast via virtual base %qT",
@@ -5571,6 +5556,30 @@ get_delta_difference (tree from, tree to,
BINFO_TYPE (virt_binfo));
}
}
+ else if (same_type_ignoring_top_level_qualifiers_p (from, to))
+ /* Pointer to member of incomplete class is permitted*/;
+ else if (!allow_inverse_p)
+ {
+ error_not_base_type (from, to);
+ error (" in pointer to member conversion");
+ }
+ else
+ {
+ binfo = lookup_base (from, to, c_cast_p ? ba_unique : ba_check, &kind);
+ if (binfo)
+ {
+ if (kind != bk_via_virtual)
+ result = size_diffop (size_zero_node, BINFO_OFFSET (binfo));
+ else
+ {
+ /* This is a reinterpret cast, we choose to do nothing. */
+ tree virt_binfo = binfo_from_vbase (binfo);
+
+ warning (0, "pointer to member cast via virtual base %qT",
+ BINFO_TYPE (virt_binfo));
+ }
+ }
+ }
return fold_if_not_in_template (convert_to_integer (ptrdiff_type_node,
result));
diff --git a/gcc/ddg.c b/gcc/ddg.c
index ea65835a324..cbdb18e72bc 100644
--- a/gcc/ddg.c
+++ b/gcc/ddg.c
@@ -302,7 +302,7 @@ add_deps_for_use (ddg_ptr g, struct df *df, struct ref *use)
if (df_find_def (df, g->nodes[i].insn, use->reg))
return;
/* We must not add ANTI dep when there is an intra-loop TRUE dep in
- the opozite direction. If the first_def reaches the USE then there is
+ the opposite direction. If the first_def reaches the USE then there is
such a dep. */
if (! bitmap_bit_p (bb_info->rd_gen, first_def->id))
create_ddg_dep_no_link (g, use_node, def_node, ANTI_DEP, REG_DEP, 1);
diff --git a/gcc/df.c b/gcc/df.c
index ad7852cb4d4..339f2c9ac4f 100644
--- a/gcc/df.c
+++ b/gcc/df.c
@@ -820,7 +820,8 @@ df_ref_record (struct df *df, rtx reg, rtx *loc, rtx insn,
reg. As written in the docu those should have the form
(subreg:SI (reg:M A) N), with size(SImode) > size(Mmode).
XXX Is that true? We could also use the global word_mode variable. */
- if (GET_CODE (reg) == SUBREG
+ if ((df->flags & DF_SUBREGS) == 0
+ && GET_CODE (reg) == SUBREG
&& (GET_MODE_SIZE (GET_MODE (reg)) < GET_MODE_SIZE (word_mode)
|| GET_MODE_SIZE (GET_MODE (reg))
>= GET_MODE_SIZE (GET_MODE (SUBREG_REG (reg)))))
@@ -2675,6 +2676,20 @@ df_insn_modify (struct df *df, basic_block bb, rtx insn)
will just get ignored. */
}
+/* Check if INSN was marked as changed. Of course the correctness of
+ the information depends on whether the instruction was really modified
+ at the time df_insn_modify was called. */
+bool
+df_insn_modified_p (struct df *df, rtx insn)
+{
+ unsigned int uid;
+
+ uid = INSN_UID (insn);
+ return (df->insns_modified
+ && uid < df->insn_size
+ && bitmap_bit_p (df->insns_modified, uid));
+}
+
typedef struct replace_args
{
rtx match;
@@ -3237,6 +3252,48 @@ df_bb_regs_lives_compare (struct df *df, basic_block bb, rtx reg1, rtx reg2)
}
+/* Return true if the definition DEF, which is in the same basic
+ block as USE, is available at USE. So DEF may as well be
+ dead, in which case using it will extend its live range. */
+bool
+df_local_def_available_p (struct df *df, struct ref *def, struct ref *use)
+{
+ struct df_link *link;
+ int def_luid = DF_INSN_LUID (df, DF_REF_INSN (def));
+ int in_bb = 0;
+ unsigned int regno = REGNO (def->reg);
+ basic_block bb;
+
+ /* The regs must be local to BB. */
+ gcc_assert (DF_REF_BB (def) == DF_REF_BB (use));
+ bb = DF_REF_BB (def);
+
+ /* This assumes that the reg-def list is ordered such that for any
+ BB, the first def is found first. However, since the BBs are not
+ ordered, the first def in the chain is not necessarily the first
+ def in the function. */
+ for (link = df->regs[regno].defs; link; link = link->next)
+ {
+ struct ref *this_def = link->ref;
+ if (DF_REF_BB (this_def) == bb)
+ {
+ int this_luid = DF_INSN_LUID (df, DF_REF_INSN (this_def));
+ /* Do nothing with defs coming before DEF. */
+ if (this_luid > def_luid)
+ return this_luid > DF_INSN_LUID (df, DF_REF_INSN (use));
+
+ in_bb = 1;
+ }
+ else if (in_bb)
+ /* DEF was the last in its basic block. */
+ return 1;
+ }
+
+ /* DEF was the last in the function. */
+ return 1;
+}
+
+
/* Return last use of REGNO within BB. */
struct ref *
df_bb_regno_last_use_find (struct df *df, basic_block bb, unsigned int regno)
@@ -3304,7 +3361,7 @@ df_bb_regno_last_def_find (struct df *df, basic_block bb, unsigned int regno)
return last_def;
}
-/* Return first use of REGNO inside INSN within BB. */
+/* Return last use of REGNO inside INSN within BB. */
static struct ref *
df_bb_insn_regno_last_use_find (struct df *df,
basic_block bb ATTRIBUTE_UNUSED, rtx insn,
diff --git a/gcc/df.h b/gcc/df.h
index 60f6030fae1..43820819025 100644
--- a/gcc/df.h
+++ b/gcc/df.h
@@ -38,6 +38,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#define DF_ALL 255
#define DF_HARD_REGS 1024 /* Mark hard registers. */
#define DF_EQUIV_NOTES 2048 /* Mark uses present in EQUIV/EQUAL notes. */
+#define DF_SUBREGS 4096 /* Return subregs rather than the inner reg. */
enum df_ref_type {DF_REF_REG_DEF, DF_REF_REG_USE, DF_REF_REG_MEM_LOAD,
DF_REF_REG_MEM_STORE};
@@ -207,11 +208,9 @@ struct df_map
((DF)->regs[REGNUM].uses ? (DF)->regs[REGNUM].uses->ref : 0)
#define DF_REGNO_FIRST_BB(DF, REGNUM) \
-(DF_REGNO_FIRST_DEF (DF, REGNUM) \
-? DF_REF_BB (DF_REGNO_FIRST_DEF (DF, REGNUM)) : 0)
+((DF)->regs[REGNUM].defs ? DF_REF_BB ((DF)->regs[REGNUM].defs->ref) : 0)
#define DF_REGNO_LAST_BB(DF, REGNUM) \
-(DF_REGNO_LAST_USE (DF, REGNUM) \
-? DF_REF_BB (DF_REGNO_LAST_USE (DF, REGNUM)) : 0)
+((DF)->regs[REGNUM].uses ? DF_REF_BB ((DF)->regs[REGNUM].uses->ref) : 0)
/* Macros to access the elements within the insn_info structure table. */
@@ -235,6 +234,8 @@ extern void df_dump (struct df *, int, FILE *);
/* Functions to modify insns. */
+extern bool df_insn_modified_p (struct df *, rtx);
+
extern void df_insn_modify (struct df *, basic_block, rtx);
extern rtx df_insn_delete (struct df *, basic_block, rtx);
@@ -280,6 +281,8 @@ extern int df_bb_reg_live_end_p (struct df *, basic_block, rtx);
extern int df_bb_regs_lives_compare (struct df *, basic_block, rtx, rtx);
+extern bool df_local_def_available_p (struct df *, struct ref *, struct ref *);
+
extern rtx df_bb_single_def_use_insn_find (struct df *, basic_block, rtx,
rtx);
extern struct ref *df_bb_regno_last_use_find (struct df *, basic_block, unsigned int);
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index c714c54b495..7d83c2bded7 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -4791,6 +4791,9 @@ are not prevented from being speculated to before the barrier.
@findex cimag
@findex cimagf
@findex cimagl
+@findex clog
+@findex clogf
+@findex clogl
@findex conj
@findex conjf
@findex conjl
@@ -5140,21 +5143,21 @@ The ISO C99 functions
@code{catanl}, @code{catan}, @code{cbrtf}, @code{cbrtl}, @code{cbrt},
@code{ccosf}, @code{ccoshf}, @code{ccoshl}, @code{ccosh}, @code{ccosl},
@code{ccos}, @code{cexpf}, @code{cexpl}, @code{cexp}, @code{cimagf},
-@code{cimagl}, @code{cimag}, @code{conjf}, @code{conjl}, @code{conj},
-@code{copysignf}, @code{copysignl}, @code{copysign}, @code{cpowf},
-@code{cpowl}, @code{cpow}, @code{cprojf}, @code{cprojl}, @code{cproj},
-@code{crealf}, @code{creall}, @code{creal}, @code{csinf}, @code{csinhf},
-@code{csinhl}, @code{csinh}, @code{csinl}, @code{csin}, @code{csqrtf},
-@code{csqrtl}, @code{csqrt}, @code{ctanf}, @code{ctanhf}, @code{ctanhl},
-@code{ctanh}, @code{ctanl}, @code{ctan}, @code{erfcf}, @code{erfcl},
-@code{erfc}, @code{erff}, @code{erfl}, @code{erf}, @code{exp2f},
-@code{exp2l}, @code{exp2}, @code{expm1f}, @code{expm1l}, @code{expm1},
-@code{fdimf}, @code{fdiml}, @code{fdim}, @code{fmaf}, @code{fmal},
-@code{fmaxf}, @code{fmaxl}, @code{fmax}, @code{fma}, @code{fminf},
-@code{fminl}, @code{fmin}, @code{hypotf}, @code{hypotl}, @code{hypot},
-@code{ilogbf}, @code{ilogbl}, @code{ilogb}, @code{imaxabs},
-@code{isblank}, @code{iswblank}, @code{lgammaf}, @code{lgammal},
-@code{lgamma}, @code{llabs}, @code{llrintf}, @code{llrintl},
+@code{cimagl}, @code{cimag}, @code{clogf}, @code{clogl}, @code{clog},
+@code{conjf}, @code{conjl}, @code{conj}, @code{copysignf}, @code{copysignl},
+@code{copysign}, @code{cpowf}, @code{cpowl}, @code{cpow}, @code{cprojf},
+@code{cprojl}, @code{cproj}, @code{crealf}, @code{creall}, @code{creal},
+@code{csinf}, @code{csinhf}, @code{csinhl}, @code{csinh}, @code{csinl},
+@code{csin}, @code{csqrtf}, @code{csqrtl}, @code{csqrt}, @code{ctanf},
+@code{ctanhf}, @code{ctanhl}, @code{ctanh}, @code{ctanl}, @code{ctan},
+@code{erfcf}, @code{erfcl}, @code{erfc}, @code{erff}, @code{erfl},
+@code{erf}, @code{exp2f}, @code{exp2l}, @code{exp2}, @code{expm1f},
+@code{expm1l}, @code{expm1}, @code{fdimf}, @code{fdiml}, @code{fdim},
+@code{fmaf}, @code{fmal}, @code{fmaxf}, @code{fmaxl}, @code{fmax},
+@code{fma}, @code{fminf}, @code{fminl}, @code{fmin}, @code{hypotf},
+@code{hypotl}, @code{hypot}, @code{ilogbf}, @code{ilogbl}, @code{ilogb},
+@code{imaxabs}, @code{isblank}, @code{iswblank}, @code{lgammaf},
+@code{lgammal}, @code{lgamma}, @code{llabs}, @code{llrintf}, @code{llrintl},
@code{llrint}, @code{llroundf}, @code{llroundl}, @code{llround},
@code{log1pf}, @code{log1pl}, @code{log1p}, @code{log2f}, @code{log2l},
@code{log2}, @code{logbf}, @code{logbl}, @code{logb}, @code{lrintf},
diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
index 80a655b8948..8d816be3ef1 100644
--- a/gcc/doc/install.texi
+++ b/gcc/doc/install.texi
@@ -1072,6 +1072,27 @@ do a @samp{make -C gcc gnatlib_and_tools}.
Specify that the compiler should
use DWARF 2 debugging information as the default.
+@item --enable-targets=all
+@itemx --enable-targets=@var{target_list}
+Some GCC targets, e.g.@: powerpc64-linux, build bi-arch compilers.
+These are compilers that are able to generate either 64-bit or 32-bit
+code. Typically, the corresponding 32-bit target, e.g.@:
+powerpc-linux for powerpc64-linux, only generates 32-bit code. This
+option enables the 32-bit target to be a bi-arch compiler, which is
+useful when you want a bi-arch compiler that defaults to 32-bit, and
+you are building a bi-arch or multi-arch binutils in a combined tree.
+Currently, this option only affects powerpc-linux.
+
+@item --enable-secureplt
+This option enables @option{-msecure-plt} by default for powerpc-linux.
+@ifnothtml
+@xref{RS/6000 and PowerPC Options,, RS/6000 and PowerPC Options, gcc,
+Using the GNU Compiler Collection (GCC)},
+@end ifnothtml
+@ifhtml
+See ``RS/6000 and PowerPC Options'' in the main manual
+@end ifhtml
+
@item --enable-win32-registry
@itemx --enable-win32-registry=@var{key}
@itemx --disable-win32-registry
@@ -2465,7 +2486,7 @@ ARM-family processors. These targets support the AOUT file format:
ATMEL AVR-family micro controllers. These are used in embedded
applications. There are no standard Unix configurations.
@ifnothtml
-@xref{AVR Options,, AVR Options, gcc, Using and Porting the GNU Compiler
+@xref{AVR Options,, AVR Options, gcc, Using the GNU Compiler
Collection (GCC)},
@end ifnothtml
@ifhtml
@@ -2503,8 +2524,8 @@ indicates that you should upgrade to a newer version of the binutils.
The Blackfin processor, an Analog Devices DSP.
@ifnothtml
-@xref{Blackfin Options,, Blackfin Options, gcc, Using and Porting the GNU
-Compiler Collection (GCC)},
+@xref{Blackfin Options,, Blackfin Options, gcc, Using the GNU Compiler
+Collection (GCC)},
@end ifnothtml
@ifhtml
See ``Blackfin Options'' in the main manual
@@ -2522,8 +2543,8 @@ Texas Instruments TMS320C3x and TMS320C4x Floating Point Digital Signal
Processors. These are used in embedded applications. There are no
standard Unix configurations.
@ifnothtml
-@xref{TMS320C3x/C4x Options,, TMS320C3x/C4x Options, gcc, Using and
-Porting the GNU Compiler Collection (GCC)},
+@xref{TMS320C3x/C4x Options,, TMS320C3x/C4x Options, gcc, Using the
+GNU Compiler Collection (GCC)},
@end ifnothtml
@ifhtml
See ``TMS320C3x/C4x Options'' in the main manual
@@ -2552,7 +2573,7 @@ CRIS is the CPU architecture in Axis Communications ETRAX system-on-a-chip
series. These are used in embedded applications.
@ifnothtml
-@xref{CRIS Options,, CRIS Options, gcc, Using and Porting the GNU Compiler
+@xref{CRIS Options,, CRIS Options, gcc, Using the GNU Compiler
Collection (GCC)},
@end ifnothtml
@ifhtml
@@ -3623,11 +3644,11 @@ failure in form of a miscompilation of the stage1 compiler by the Sun
compiler. This is Sun bug 4974440. This is fixed with patch 112760-07.
GCC 3.4 changed the default debugging format from STABS to DWARF-2 for
-32-bit code on Solaris 7 and later. If you are using the Sun
-assembler, this change apparently runs afoul of Sun bug 4910101, for
-which (as of 2004-05-23) there is no fix. A symptom of the problem is
-that you cannot compile C++ programs like @command{groff} 1.19.1
-without getting messages similar to the following:
+32-bit code on Solaris 7 and later. If you use the Sun assembler, this
+change apparently runs afoul of Sun bug 4910101 (which is referenced as
+a x86-only problem by Sun, probably because they do not use DWARF-2).
+A symptom of the problem is that you cannot compile C++ programs like
+@command{groff} 1.19.1 without getting messages similar to the following:
@smallexample
ld: warning: relocation error: R_SPARC_UA32: @dots{}
@@ -3697,6 +3718,17 @@ ld: fatal: relocation error: R_SPARC_32: file libgcc/sparcv9/_muldi3.o:
This bug has been fixed in the final 5.0 version of the assembler.
+A similar problem was reported for version Sun WorkShop 6 99/08/18 of the
+Sun assembler, which causes a bootstrap failure with GCC 4.0.0:
+
+@smallexample
+ld: fatal: relocation error: R_SPARC_DISP32:
+ file .libs/libstdc++.lax/libsupc++convenience.a/vterminate.o:
+ symbol <unknown>: offset 0xfccd33ad is non-aligned
+@end smallexample
+
+This bug has been fixed in more recent revisions of the assembler.
+
@html
<hr />
@end html
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index a104c548e38..0bcd3d9d85c 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -277,6 +277,7 @@ Objective-C and Objective-C++ Dialects}.
-fdump-tree-sra@r{[}-@var{n}@r{]} @gol
-fdump-tree-salias @gol
-fdump-tree-fre@r{[}-@var{n}@r{]} @gol
+-fdump-tree-vrp@r{[}-@var{n}@r{]} @gol
-ftree-vectorizer-verbose=@var{n} @gol
-fdump-tree-storeccp@r{[}-@var{n}@r{]} @gol
-feliminate-dwarf2-dups -feliminate-unused-debug-types @gol
@@ -636,7 +637,7 @@ See RS/6000 and PowerPC Options.
-minsert-sched-nops=@var{scheme} @gol
-mcall-sysv -mcall-netbsd @gol
-maix-struct-return -msvr4-struct-return @gol
--mabi=@var{abi-type} @gol
+-mabi=@var{abi-type} -msecure-plt -mbss-plt @gol
-misel -mno-isel @gol
-misel=yes -misel=no @gol
-mspe -mno-spe @gol
@@ -732,6 +733,7 @@ See S/390 and zSeries Options.
-finhibit-size-directive -finstrument-functions @gol
-fno-common -fno-ident @gol
-fpcc-struct-return -fpic -fPIC -fpie -fPIE @gol
+-fno-jump-tables @gol
-freg-struct-return -fshared-data -fshort-enums @gol
-fshort-double -fshort-wchar @gol
-fverbose-asm -fpack-struct[=@var{n}] -fstack-check @gol
@@ -4066,6 +4068,11 @@ file name.
Dump each function after applying vectorization of loops. The file name is
made by appending @file{.vect} to the source file name.
+@item vrp
+@opindex fdump-tree-vrp
+Dump each function after Value Range Propagation (VRP). The file name
+is made by appending @file{.vrp} to the source file name.
+
@item all
@opindex fdump-tree-all
Enable all the available tree dumps with the flags provided in this option.
@@ -4320,6 +4327,7 @@ also turns on the following optimization flags:
-funit-at-a-time @gol
-falign-functions -falign-jumps @gol
-falign-loops -falign-labels @gol
+-ftree-vrp @gol
-ftree-pre}
Please note the warning under @option{-fgcse} about
@@ -4470,7 +4478,7 @@ See below for a documentation of the individual
parameters controlling inlining.
@emph{Note:} pseudo instruction represents, in this particular context, an
-abstract measurement of function's size. In no way, it represents a count
+abstract measurement of function's size. In no way does it represent a count
of assembly instructions and as such its exact meaning might change from one
release to an another.
@@ -4962,6 +4970,15 @@ optimization later. This is enabled by default at @option{-O} and higher.
@item -ftree-vectorize
Perform loop vectorization on trees.
+@item -ftree-vrp
+Perform Value Range Propagation on trees. This is similar to the
+constant propagation pass, but instead of values, ranges of values are
+propagated. This allows the optimizers to remove unnecessary range
+checks like array bound checks and null pointer checks. This is
+enabled by default at @option{-O2} and higher. Null pointer check
+elimination is only done if @option{-fdelete-null-pointer-checks} is
+enabled.
+
@item -ftracer
@opindex ftracer
Perform tail duplication to enlarge superblock size. This transformation
@@ -6883,10 +6900,6 @@ Some configurations of the compiler also support additional special
options, usually for compatibility with other compilers on the same
platform.
-These options are defined by the macro @code{TARGET_SWITCHES} in the
-machine description. The default for the options is also defined by
-that macro, which enables you to change the defaults.
-
@c This list is ordered alphanumerically by subsection name.
@c It should be the same order and spelling as these options are listed
@c in Machine Dependent Options
@@ -10733,6 +10746,18 @@ ABI@.
@opindex mabi=no-spe
Disable Booke SPE ABI extensions for the current ABI@.
+@item -msecure-plt
+@opindex msecure-plt
+Generate code that allows ld and ld.so to build executables and shared
+libraries with non-exec .plt and .got sections. This is a PowerPC
+32-bit SYSV ABI option.
+
+@item -mbss-plt
+@opindex mbss-plt
+Generate code that uses a BSS .plt section that ld.so fills in, and
+requires .plt and .got sections that are both writable and executable.
+This is a PowerPC 32-bit SYSV ABI option.
+
@item -misel
@itemx -mno-isel
@opindex misel
@@ -12574,6 +12599,15 @@ generated position independent code can be only linked into executables.
Usually these options are used when @option{-pie} GCC option will be
used during linking.
+@item -fno-jump-tables
+@opindex fno-jump-tables
+Do not use jump tables for switch statements even where it would be
+more efficient than other code generation strategies. This option is
+of use in conjunction with @option{-fpic} or @option{-fPIC} for
+building code which forms part of a dynamic linker and cannot
+reference the address of a jump table. On some targets, jump tables
+do not require a GOT and this option is not needed.
+
@item -ffixed-@var{reg}
@opindex ffixed
Treat the register named @var{reg} as a fixed register; generated code
@@ -12774,8 +12808,8 @@ For those adding visibility support to existing code, you may find
@samp{#pragma GCC visibility} of use. This works by you enclosing
the declarations you wish to set visibility for with (for example)
@samp{#pragma GCC visibility push(hidden)} and
-@samp{#pragma GCC visibility pop}. These can be nested up to sixteen
-times. Bear in mind that symbol visibility should be viewed @strong{as
+@samp{#pragma GCC visibility pop}.
+Bear in mind that symbol visibility should be viewed @strong{as
part of the API interface contract} and thus all new code should
always specify visibility when it is not the default ie; declarations
only for use within the local DSO should @strong{always} be marked explicitly
diff --git a/gcc/doc/options.texi b/gcc/doc/options.texi
index 307a325e5de..b4ada5bebdb 100644
--- a/gcc/doc/options.texi
+++ b/gcc/doc/options.texi
@@ -121,12 +121,29 @@ will check and convert the argument before passing it to the relevant
option handler.
@item Var(@var{var})
-The option controls an integer variable @var{var}. If the option has
-the @code{UInteger} property, the option parser will set @var{var} to
-the value of the user-specified argument. Otherwise the option is
-assumed to be an on/off switch that is active when @var{var} is nonzero.
-In this case, the option parser will set @var{var} to 1 when the positive
-form of the option is used and 0 when the ``no-'' form is used.
+The state of this option should be stored in variable @var{var}.
+The way that the state is stored depends on the type of option:
+
+@itemize @bullet
+@item
+If the option uses the @code{Mask} or @code{InverseMask} properties,
+@var{var} is the integer variable that contains the mask.
+
+@item
+If the option is a normal on/off switch, @var{var} is an integer
+variable that is nonzero when the option is enabled. The options
+parser will set the variable to 1 when the positive form of the
+option is used and 0 when the ``no-'' form is used.
+
+@item
+If the option takes an argument and has the @code{UInteger} property,
+@var{var} is an integer variable that stores the value of the argument.
+
+@item
+Otherwise, if the option takes an argument, @var{var} is a pointer to
+the argument string. The pointer will be null if the argument is optional
+and wasn't given.
+@end itemize
The option-processing script will usually declare @var{var} in
@file{options.c} and leave it to be zero-initialized at start-up time.
diff --git a/gcc/doc/rtl.texi b/gcc/doc/rtl.texi
index f917c85e016..1f9372ebdd5 100644
--- a/gcc/doc/rtl.texi
+++ b/gcc/doc/rtl.texi
@@ -3115,9 +3115,6 @@ Appears near the end of the function body, just before the label that
does not suffice for returning). This note may be deleted by jump
optimization.
-@findex NOTE_INSN_SETJMP
-@item NOTE_INSN_SETJMP
-Appears following each call to @code{setjmp} or a related function.
@end table
These codes are printed symbolically when they appear in debugging dumps.
@@ -3298,6 +3295,11 @@ of this note indicates to other optimizations that this this branching
instruction should not be ``collapsed'' into a simpler branching
construct. It is used when the optimization to partition basic blocks
into hot and cold sections is turned on.
+
+@findex REG_SETJMP
+@item REG_SETJMP
+Appears attached to each @code{CALL_INSN} to @code{setjmp} or a
+related function.
@end table
The following notes describe attributes of outputs of an insn:
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index e541a20d2a9..a4adcb9db55 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -728,11 +728,11 @@ any target-specific headers.
@deftypevar {Target Hook} int TARGET_DEFAULT_TARGET_FLAGS
This variable specifies the initial value of @code{target_flags}.
Its default setting is 0.
-
-If the target defines @code{TARGET_SWITCHES}, the null
-@code{TARGET_SWITCHES} entry will override this value.
@end deftypevar
+@cindex optional hardware or system features
+@cindex features, optional, in system conventions
+
@deftypefn {Target Hook} bool TARGET_HANDLE_OPTION (size_t @var{code}, const char *@var{arg}, int @var{value})
This hook is called whenever the user specifies one of the
target-specific options described by the @file{.opt} definition files
@@ -750,153 +750,6 @@ argument. Otherwise @var{value} is 1 if the positive form of the
option was used and 0 if the ``no-'' form was.
@end deftypefn
-@cindex optional hardware or system features
-@cindex features, optional, in system conventions
-
-@defmac TARGET_@var{featurename}
-This series of macros is to allow compiler command arguments to
-enable or disable the use of optional features of the target machine.
-For example, one machine description serves both the 68000 and
-the 68020; a command argument tells the compiler whether it should
-use 68020-only instructions or not. This command argument works
-by means of a macro @code{TARGET_68020} that tests a bit in
-@code{target_flags}.
-
-Define a macro @code{TARGET_@var{featurename}} for each such option.
-Its definition should test a bit in @code{target_flags}. It is
-recommended that a helper macro @code{MASK_@var{featurename}}
-is defined for each bit-value to test, and used in
-@code{TARGET_@var{featurename}} and @code{TARGET_SWITCHES}. For
-example:
-
-@smallexample
-#define TARGET_MASK_68020 1
-#define TARGET_68020 (target_flags & MASK_68020)
-@end smallexample
-
-One place where these macros are used is in the condition-expressions
-of instruction patterns. Note how @code{TARGET_68020} appears
-frequently in the 68000 machine description file, @file{m68k.md}.
-Another place they are used is in the definitions of the other
-macros in the @file{@var{machine}.h} file.
-@end defmac
-
-@defmac TARGET_SWITCHES
-This macro defines names of command options to set and clear
-bits in @code{target_flags}. Its definition is an initializer
-with a subgrouping for each command option.
-
-Each subgrouping contains a string constant, that defines the option
-name, a number, which contains the bits to set in
-@code{target_flags}, and a second string which is the description
-displayed by @option{--help}. If the number is negative then the bits specified
-by the number are cleared instead of being set. If the description
-string is present but empty, then no help information will be displayed
-for that option, but it will not count as an undocumented option. The
-actual option name is made by appending @samp{-m} to the specified name.
-Non-empty description strings should be marked with @code{N_(@dots{})} for
-@command{xgettext}. Please do not mark empty strings because the empty
-string is reserved by GNU gettext. @code{gettext("")} returns the header entry
-of the message catalog with meta information, not the empty string.
-
-In addition to the description for @option{--help},
-more detailed documentation for each option should be added to
-@file{invoke.texi}.
-
-One of the subgroupings should have a null string. The number in
-this grouping is the default value for @code{target_flags}. Any
-target options act starting with that value.
-
-Here is an example which defines @option{-m68000} and @option{-m68020}
-with opposite meanings, and picks the latter as the default:
-
-@smallexample
-#define TARGET_SWITCHES \
- @{ @{ "68020", MASK_68020, "" @}, \
- @{ "68000", -MASK_68020, \
- N_("Compile for the 68000") @}, \
- @{ "", MASK_68020, "" @}, \
- @}
-@end smallexample
-
-This macro is being kept for compatibility with older backends.
-New targets should use option definition files instead.
-@xref{Back End}.
-@end defmac
-
-@defmac TARGET_OPTIONS
-This macro is similar to @code{TARGET_SWITCHES} but defines names of command
-options that have values. Its definition is an initializer with a
-subgrouping for each command option.
-
-Each subgrouping contains a string constant, that defines the option
-name, the address of a variable, a description string, and a value.
-Non-empty description strings should be marked with @code{N_(@dots{})}
-for @command{xgettext}. Please do not mark empty strings because the
-empty string is reserved by GNU gettext. @code{gettext("")} returns the
-header entry of the message catalog with meta information, not the empty
-string.
-
-If the value listed in the table is @code{NULL}, then the variable, type
-@code{char *}, is set to the variable part of the given option if the
-fixed part matches. In other words, if the first part of the option
-matches what's in the table, the variable will be set to point to the
-rest of the option. This allows the user to specify a value for that
-option. The actual option name is made by appending @samp{-m} to the
-specified name. Again, each option should also be documented in
-@file{invoke.texi}.
-
-If the value listed in the table is non-@code{NULL}, then the option
-must match the option in the table exactly (with @samp{-m}), and the
-variable is set to point to the value listed in the table.
-
-Here is an example which defines @option{-mshort-data-@var{number}}. If the
-given option is @option{-mshort-data-512}, the variable @code{m88k_short_data}
-will be set to the string @code{"512"}.
-
-@smallexample
-extern char *m88k_short_data;
-#define TARGET_OPTIONS \
- @{ @{ "short-data-", &m88k_short_data, \
- N_("Specify the size of the short data section"), 0 @} @}
-@end smallexample
-
-Here is a variant of the above that allows the user to also specify
-just @option{-mshort-data} where a default of @code{"64"} is used.
-
-@smallexample
-extern char *m88k_short_data;
-#define TARGET_OPTIONS \
- @{ @{ "short-data-", &m88k_short_data, \
- N_("Specify the size of the short data section"), 0 @} \
- @{ "short-data", &m88k_short_data, "", "64" @},
- @}
-@end smallexample
-
-Here is an example which defines @option{-mno-alu}, @option{-malu1}, and
-@option{-malu2} as a three-state switch, along with suitable macros for
-checking the state of the option (documentation is elided for brevity).
-
-@smallexample
-[chip.c]
-char *chip_alu = ""; /* @r{Specify default here.} */
-
-[chip.h]
-extern char *chip_alu;
-#define TARGET_OPTIONS \
- @{ @{ "no-alu", &chip_alu, "", "" @}, \
- @{ "alu1", &chip_alu, "", "1" @}, \
- @{ "alu2", &chip_alu, "", "2" @}, @}
-#define TARGET_ALU (chip_alu[0] != '\0')
-#define TARGET_ALU1 (chip_alu[0] == '1')
-#define TARGET_ALU2 (chip_alu[0] == '2')
-@end smallexample
-
-This macro is being kept for compatibility with older backends.
-New targets should use option definition files instead.
-@xref{Back End}.
-@end defmac
-
@defmac TARGET_VERSION
This macro is a C statement to print on @code{stderr} a string
describing the particular machine description choice. Every machine
@@ -8668,24 +8521,32 @@ Default: empty.
@section Parameters for Precompiled Header Validity Checking
@cindex parameters, precompiled headers
-@deftypefn {Target Hook} void * TARGET_GET_PCH_VALIDITY (size_t * @var{sz})
-Define this hook if your target needs to check a different collection
-of flags than the default, which is every flag defined by
-@code{TARGET_SWITCHES} and @code{TARGET_OPTIONS}. It should return
-some data which will be saved in the PCH file and presented to
-@code{TARGET_PCH_VALID_P} later; it should set @code{SZ} to the size
-of the data.
+@deftypefn {Target Hook} void *TARGET_GET_PCH_VALIDITY (size_t *@var{sz})
+This hook returns the data needed by @code{TARGET_PCH_VALID_P} and sets
+@samp{*@var{sz}} to the size of the data in bytes.
+@end deftypefn
+
+@deftypefn {Target Hook} const char *TARGET_PCH_VALID_P (const void *@var{data}, size_t @var{sz})
+This hook checks whether the options used to create a PCH file are
+compatible with the current settings. It returns @code{NULL}
+if so and a suitable error message if not. Error messages will
+be presented to the user and must be localized using @samp{_(@var{msg})}.
+
+@var{data} is the data that was returned by @code{TARGET_GET_PCH_VALIDITY}
+when the PCH file was created and @var{sz} is the size of that data in bytes.
+It's safe to assume that the data was created by the same version of the
+compiler, so no format checking is needed.
+
+The default definition of @code{default_pch_valid_p} should be
+suitable for most targets.
@end deftypefn
-@deftypefn {Target Hook} const char * TARGET_PCH_VALID_P (const void * @var{data}, size_t @var{sz})
-Define this hook if your target needs to check a different collection of
-flags than the default, which is every flag defined by @code{TARGET_SWITCHES}
-and @code{TARGET_OPTIONS}. It is given data which came from
-@code{TARGET_GET_PCH_VALIDITY} (in this version of this compiler, so there
-is no need for extensive validity checking). It returns @code{NULL} if
-it is safe to load a PCH file with this data, or a suitable error message
-if not. The error message will be presented to the user, so it should
-be localized.
+@deftypefn {Target Hook} const char *TARGET_CHECK_PCH_TARGET_FLAGS (int @var{pch_flags})
+If this hook is nonnull, the default implementation of
+@code{TARGET_PCH_VALID_P} will use it to check for compatible values
+of @code{target_flags}. @var{pch_flags} specifies the value that
+@code{target_flags} had when the PCH file was created. The return
+value is the same as for @code{TARGET_PCH_VALID_P}.
@end deftypefn
@node C++ ABI
@@ -9519,7 +9380,7 @@ low-overhead loop.
Many targets use special registers for low-overhead looping. This function
should return false for any instruction that clobbers these.
By default, the RTL loop optimizer does not use a present doloop pattern for
-loops containing function calls or brach on table instructions.
+loops containing function calls or branch on table instructions.
@end deftypefn
@defmac MD_CAN_REDIRECT_BRANCH (@var{branch1}, @var{branch2})
diff --git a/gcc/doc/tree-ssa.texi b/gcc/doc/tree-ssa.texi
index bdafee85966..d637149d278 100644
--- a/gcc/doc/tree-ssa.texi
+++ b/gcc/doc/tree-ssa.texi
@@ -1287,7 +1287,7 @@ After the replacement mappings have been registered and new symbols
marked for renaming, a call to @code{update_ssa} makes the registered
changes. This can be done with an explicit call or by creating
@code{TODO} flags in the @code{tree_opt_pass} structure for your pass.
-There are several @code{TODO} flags that control the behaviour of
+There are several @code{TODO} flags that control the behavior of
@code{update_ssa}:
@itemize @bullet
@@ -1309,7 +1309,7 @@ There are several @code{TODO} flags that control the behaviour of
@item @code{TODO_update_ssa_full_phi}. Insert PHI nodes everywhere
- they are needed. No prunning of the IDF is done. This is used
+ they are needed. No pruning of the IDF is done. This is used
by passes that need the PHI nodes for @code{O_j} even if it
means that some arguments will come from the default definition
of @code{O_j}'s symbol (e.g., @code{pass_linear_transform})@.
diff --git a/gcc/dominance.c b/gcc/dominance.c
index ce977e292fe..00e3495d923 100644
--- a/gcc/dominance.c
+++ b/gcc/dominance.c
@@ -41,7 +41,7 @@
#include "hard-reg-set.h"
#include "obstack.h"
#include "basic-block.h"
-#include "errors.h"
+#include "toplev.h"
#include "et-forest.h"
/* Whether the dominators and the postdominators are available. */
diff --git a/gcc/domwalk.c b/gcc/domwalk.c
index 2713e04c097..389dac23e4d 100644
--- a/gcc/domwalk.c
+++ b/gcc/domwalk.c
@@ -161,10 +161,9 @@ walk_dominator_tree (struct dom_walk_data *walk_data, basic_block bb)
/* First get some local data, reusing any local data pointer we may
have saved. */
- if (VARRAY_ACTIVE_SIZE (walk_data->free_block_data) > 0)
+ if (VEC_length (void_p, walk_data->free_block_data) > 0)
{
- bd = VARRAY_TOP_GENERIC_PTR (walk_data->free_block_data);
- VARRAY_POP (walk_data->free_block_data);
+ bd = VEC_pop (void_p, walk_data->free_block_data);
recycled = 1;
}
else
@@ -174,7 +173,7 @@ walk_dominator_tree (struct dom_walk_data *walk_data, basic_block bb)
}
/* Push the local data into the local data stack. */
- VARRAY_PUSH_GENERIC_PTR (walk_data->block_data_stack, bd);
+ VEC_safe_push (void_p, heap, walk_data->block_data_stack, bd);
/* Call the initializer. */
walk_data->initialize_block_local_data (walk_data, bb, recycled);
@@ -237,26 +236,18 @@ walk_dominator_tree (struct dom_walk_data *walk_data, basic_block bb)
if (walk_data->initialize_block_local_data)
{
/* And save the block data so that we can re-use it. */
- VARRAY_PUSH_GENERIC_PTR (walk_data->free_block_data, bd);
+ VEC_safe_push (void_p, heap, walk_data->free_block_data, bd);
/* And finally pop the record off the block local data stack. */
- VARRAY_POP (walk_data->block_data_stack);
+ VEC_pop (void_p, walk_data->block_data_stack);
}
}
void
init_walk_dominator_tree (struct dom_walk_data *walk_data)
{
- if (walk_data->initialize_block_local_data)
- {
- VARRAY_GENERIC_PTR_INIT (walk_data->free_block_data, 2, "freelist ");
- VARRAY_GENERIC_PTR_INIT (walk_data->block_data_stack, 2, "block_data");
- }
- else
- {
- walk_data->free_block_data = NULL;
- walk_data->block_data_stack = NULL;
- }
+ walk_data->free_block_data = NULL;
+ walk_data->block_data_stack = NULL;
}
void
@@ -264,10 +255,10 @@ fini_walk_dominator_tree (struct dom_walk_data *walk_data)
{
if (walk_data->initialize_block_local_data)
{
- while (VARRAY_ACTIVE_SIZE (walk_data->free_block_data) > 0)
- {
- free (VARRAY_TOP_GENERIC_PTR (walk_data->free_block_data));
- VARRAY_POP (walk_data->free_block_data);
- }
+ while (VEC_length (void_p, walk_data->free_block_data) > 0)
+ free (VEC_pop (void_p, walk_data->free_block_data));
}
+
+ VEC_free (void_p, heap, walk_data->free_block_data);
+ VEC_free (void_p, heap, walk_data->block_data_stack);
}
diff --git a/gcc/domwalk.h b/gcc/domwalk.h
index bf16229b488..ba0624ef160 100644
--- a/gcc/domwalk.h
+++ b/gcc/domwalk.h
@@ -19,6 +19,10 @@ along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
+typedef void *void_p;
+DEF_VEC_P(void_p);
+DEF_VEC_ALLOC_P(void_p,heap);
+
/* This is the main data structure for the dominator walker. It provides
the callback hooks as well as a convenient place to hang block local
data and pass-global data. */
@@ -94,7 +98,7 @@ struct dom_walk_data
/* Stack of any data we need to keep on a per-block basis.
If you have no local data, then BLOCK_DATA_STACK will be NULL. */
- varray_type block_data_stack;
+ VEC(void_p,heap) *block_data_stack;
/* Size of the block local data. If this is zero, then it is assumed
you have no local data and thus no BLOCK_DATA_STACK as well. */
@@ -104,7 +108,7 @@ struct dom_walk_data
information/data outside domwalk.c. */
/* Stack of available block local structures. */
- varray_type free_block_data;
+ VEC(void_p,heap) *free_block_data;
/* Interesting blocks to process. If this field is not NULL, this
set is used to determine which blocks to walk. If we encounter
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 32711c7227c..1afe52e540d 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -13283,7 +13283,7 @@ dwarf2out_var_location (rtx loc_note)
last_insn = loc_note;
last_label = newloc->label;
decl = NOTE_VAR_LOCATION_DECL (loc_note);
- if (DECL_DEBUG_EXPR (decl) && DECL_DEBUG_EXPR_IS_FROM (decl)
+ if (DECL_DEBUG_EXPR_IS_FROM (decl) && DECL_DEBUG_EXPR (decl)
&& DECL_P (DECL_DEBUG_EXPR (decl)))
decl = DECL_DEBUG_EXPR (decl);
add_var_loc_to_decl (decl, newloc);
diff --git a/gcc/errors.h b/gcc/errors.h
index 9aa87e72852..cc0c4a07b96 100644
--- a/gcc/errors.h
+++ b/gcc/errors.h
@@ -30,10 +30,10 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#ifndef GCC_ERRORS_H
#define GCC_ERRORS_H
-extern void warning (int, const char *, ...);
-extern void error (const char *, ...);
-extern void fatal (const char *, ...) ATTRIBUTE_NORETURN;
-extern void internal_error (const char *, ...) ATTRIBUTE_NORETURN;
+extern void warning (int, const char *, ...) ATTRIBUTE_PRINTF_2;
+extern void error (const char *, ...) ATTRIBUTE_PRINTF_1;
+extern void fatal (const char *, ...) ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF_1;
+extern void internal_error (const char *, ...) ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF_1;
extern const char *trim_filename (const char *);
extern int have_error;
diff --git a/gcc/except.c b/gcc/except.c
index 9f1bfe926af..c10fc883df7 100644
--- a/gcc/except.c
+++ b/gcc/except.c
@@ -139,8 +139,7 @@ struct eh_region GTY(())
ERT_CATCH,
ERT_ALLOWED_EXCEPTIONS,
ERT_MUST_NOT_THROW,
- ERT_THROW,
- ERT_FIXUP
+ ERT_THROW
} type;
/* Holds the action to perform based on the preceding type. */
@@ -150,8 +149,6 @@ struct eh_region GTY(())
struct eh_region_u_try {
struct eh_region *catch;
struct eh_region *last_catch;
- struct eh_region *prev_try;
- rtx continue_label;
} GTY ((tag ("ERT_TRY"))) try;
/* The list through the catch handlers, the list of type objects
@@ -180,13 +177,6 @@ struct eh_region GTY(())
struct eh_region_u_cleanup {
struct eh_region *prev_try;
} GTY ((tag ("ERT_CLEANUP"))) cleanup;
-
- /* The real region (by expression and by pointer) that fixup code
- should live in. */
- struct eh_region_u_fixup {
- struct eh_region *real_region;
- bool resolved;
- } GTY ((tag ("ERT_FIXUP"))) fixup;
} GTY ((desc ("%0.type"))) u;
/* Entry point for this region's handler before landing pads are built. */
@@ -2430,7 +2420,6 @@ reachable_next_level (struct eh_region *region, tree type_thrown,
return RNL_BLOCKED;
case ERT_THROW:
- case ERT_FIXUP:
case ERT_UNKNOWN:
/* Shouldn't see these here. */
gcc_unreachable ();
@@ -2539,7 +2528,7 @@ reachable_handlers (rtx insn)
within the function. */
bool
-can_throw_internal_1 (int region_number)
+can_throw_internal_1 (int region_number, bool is_resx)
{
struct eh_region *region;
tree type_thrown;
@@ -2547,7 +2536,9 @@ can_throw_internal_1 (int region_number)
region = cfun->eh->region_array[region_number];
type_thrown = NULL_TREE;
- if (region->type == ERT_THROW)
+ if (is_resx)
+ region = region->outer;
+ else if (region->type == ERT_THROW)
{
type_thrown = region->u.throw.type;
region = region->outer;
@@ -2579,7 +2570,7 @@ can_throw_internal (rtx insn)
if (JUMP_P (insn)
&& GET_CODE (PATTERN (insn)) == RESX
&& XINT (PATTERN (insn), 0) > 0)
- return can_throw_internal_1 (XINT (PATTERN (insn), 0));
+ return can_throw_internal_1 (XINT (PATTERN (insn), 0), true);
if (NONJUMP_INSN_P (insn)
&& GET_CODE (PATTERN (insn)) == SEQUENCE)
@@ -2590,14 +2581,14 @@ can_throw_internal (rtx insn)
if (!note || INTVAL (XEXP (note, 0)) <= 0)
return false;
- return can_throw_internal_1 (INTVAL (XEXP (note, 0)));
+ return can_throw_internal_1 (INTVAL (XEXP (note, 0)), false);
}
/* Determine if the given INSN can throw an exception that is
visible outside the function. */
bool
-can_throw_external_1 (int region_number)
+can_throw_external_1 (int region_number, bool is_resx)
{
struct eh_region *region;
tree type_thrown;
@@ -2605,7 +2596,9 @@ can_throw_external_1 (int region_number)
region = cfun->eh->region_array[region_number];
type_thrown = NULL_TREE;
- if (region->type == ERT_THROW)
+ if (is_resx)
+ region = region->outer;
+ else if (region->type == ERT_THROW)
{
type_thrown = region->u.throw.type;
region = region->outer;
@@ -2628,6 +2621,11 @@ can_throw_external (rtx insn)
if (! INSN_P (insn))
return false;
+ if (JUMP_P (insn)
+ && GET_CODE (PATTERN (insn)) == RESX
+ && XINT (PATTERN (insn), 0) > 0)
+ return can_throw_external_1 (XINT (PATTERN (insn), 0), true);
+
if (NONJUMP_INSN_P (insn)
&& GET_CODE (PATTERN (insn)) == SEQUENCE)
insn = XVECEXP (PATTERN (insn), 0, 0);
@@ -2647,7 +2645,7 @@ can_throw_external (rtx insn)
if (INTVAL (XEXP (note, 0)) <= 0)
return false;
- return can_throw_external_1 (INTVAL (XEXP (note, 0)));
+ return can_throw_external_1 (INTVAL (XEXP (note, 0)), false);
}
/* Set TREE_NOTHROW and cfun->all_throwers_are_sibcalls. */
@@ -3605,7 +3603,7 @@ dump_eh_tree (FILE *out, struct function *fun)
int depth = 0;
static const char * const type_name[] = {"unknown", "cleanup", "try", "catch",
"allowed_exceptions", "must_not_throw",
- "throw", "fixup"};
+ "throw"};
i = fun->eh->region_tree;
if (! i)
diff --git a/gcc/except.h b/gcc/except.h
index 9526b865909..9188c3bb60f 100644
--- a/gcc/except.h
+++ b/gcc/except.h
@@ -46,9 +46,9 @@ extern void for_each_eh_label (void (*) (rtx));
extern void for_each_eh_region (void (*) (struct eh_region *));
/* Determine if the given INSN can throw an exception. */
-extern bool can_throw_internal_1 (int);
+extern bool can_throw_internal_1 (int, bool);
extern bool can_throw_internal (rtx);
-extern bool can_throw_external_1 (int);
+extern bool can_throw_external_1 (int, bool);
extern bool can_throw_external (rtx);
/* Set TREE_NOTHROW and cfun->all_throwers_are_sibcalls. */
diff --git a/gcc/expmed.c b/gcc/expmed.c
index c814233d24c..ff8c278ced3 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -3030,7 +3030,7 @@ expand_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target,
/* These are the operations that are potentially turned into a sequence
of shifts and additions. */
- if (GET_MODE_CLASS (mode) == MODE_INT
+ if (SCALAR_INT_MODE_P (mode)
&& (unsignedp || !flag_trapv))
{
HOST_WIDE_INT coeff = 0;
diff --git a/gcc/expr.c b/gcc/expr.c
index dd89cad94f5..2ec75b7aa7c 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -466,19 +466,27 @@ convert_move (rtx to, rtx from, int unsignedp)
}
if (GET_MODE_CLASS (from_mode) == MODE_PARTIAL_INT)
{
+ rtx new_from;
enum machine_mode full_mode
= smallest_mode_for_size (GET_MODE_BITSIZE (from_mode), MODE_INT);
gcc_assert (sext_optab->handlers[full_mode][from_mode].insn_code
!= CODE_FOR_nothing);
- emit_unop_insn (sext_optab->handlers[full_mode][from_mode].insn_code,
- to, from, UNKNOWN);
if (to_mode == full_mode)
- return;
+ {
+ emit_unop_insn (sext_optab->handlers[full_mode][from_mode].insn_code,
+ to, from, UNKNOWN);
+ return;
+ }
+
+ new_from = gen_reg_rtx (full_mode);
+ emit_unop_insn (sext_optab->handlers[full_mode][from_mode].insn_code,
+ new_from, from, UNKNOWN);
/* else proceed to integer conversions below. */
from_mode = full_mode;
+ from = new_from;
}
/* Now both modes are integers. */
@@ -7753,7 +7761,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
optab other_optab = zextend_p ? smul_widen_optab : umul_widen_optab;
this_optab = zextend_p ? umul_widen_optab : smul_widen_optab;
- if (mode == GET_MODE_WIDER_MODE (innermode))
+ if (mode == GET_MODE_2XWIDER_MODE (innermode))
{
if (this_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
{
diff --git a/gcc/expr.h b/gcc/expr.h
index 267daf0119f..550c0d0afc6 100644
--- a/gcc/expr.h
+++ b/gcc/expr.h
@@ -588,7 +588,7 @@ extern rtx eliminate_constant_term (rtx, rtx *);
by emitting insns to perform arithmetic if nec. */
extern rtx memory_address (enum machine_mode, rtx);
-/* Like `memory_address' but pretent `flag_force_addr' is 0. */
+/* Like `memory_address' but pretend `flag_force_addr' is 0. */
extern rtx memory_address_noforce (enum machine_mode, rtx);
/* Return a memory reference like MEMREF, but with its mode changed
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 050d45c6069..21a5b1a6698 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -89,7 +89,6 @@ static tree negate_expr (tree);
static tree split_tree (tree, enum tree_code, tree *, tree *, tree *, int);
static tree associate_trees (tree, tree, enum tree_code, tree);
static tree const_binop (enum tree_code, tree, tree, int);
-static enum tree_code invert_tree_comparison (enum tree_code, bool);
static enum comparison_code comparison_to_compcode (enum tree_code);
static enum tree_code compcode_to_comparison (enum comparison_code);
static tree combine_comparisons (enum tree_code, enum tree_code,
@@ -1600,33 +1599,36 @@ const_binop (enum tree_code code, tree arg1, tree arg2, int notrunc)
case RDIV_EXPR:
{
+ tree t1, t2, real, imag;
tree magsquared
= const_binop (PLUS_EXPR,
const_binop (MULT_EXPR, r2, r2, notrunc),
const_binop (MULT_EXPR, i2, i2, notrunc),
notrunc);
- t = build_complex (type,
- const_binop
- (INTEGRAL_TYPE_P (TREE_TYPE (r1))
- ? TRUNC_DIV_EXPR : RDIV_EXPR,
- const_binop (PLUS_EXPR,
- const_binop (MULT_EXPR, r1, r2,
- notrunc),
- const_binop (MULT_EXPR, i1, i2,
- notrunc),
- notrunc),
- magsquared, notrunc),
- const_binop
- (INTEGRAL_TYPE_P (TREE_TYPE (r1))
- ? TRUNC_DIV_EXPR : RDIV_EXPR,
- const_binop (MINUS_EXPR,
- const_binop (MULT_EXPR, i1, r2,
- notrunc),
- const_binop (MULT_EXPR, r1, i2,
- notrunc),
- notrunc),
- magsquared, notrunc));
+ t1 = const_binop (PLUS_EXPR,
+ const_binop (MULT_EXPR, r1, r2, notrunc),
+ const_binop (MULT_EXPR, i1, i2, notrunc),
+ notrunc);
+ t2 = const_binop (MINUS_EXPR,
+ const_binop (MULT_EXPR, i1, r2, notrunc),
+ const_binop (MULT_EXPR, r1, i2, notrunc),
+ notrunc);
+
+ if (INTEGRAL_TYPE_P (TREE_TYPE (r1)))
+ {
+ real = const_binop (TRUNC_DIV_EXPR, t1, magsquared, notrunc);
+ imag = const_binop (TRUNC_DIV_EXPR, t2, magsquared, notrunc);
+ }
+ else
+ {
+ real = const_binop (RDIV_EXPR, t1, magsquared, notrunc);
+ imag = const_binop (RDIV_EXPR, t2, magsquared, notrunc);
+ if (!real || !imag)
+ return NULL_TREE;
+ }
+
+ t = build_complex (type, real, imag);
}
break;
@@ -2116,7 +2118,7 @@ pedantic_non_lvalue (tree x)
comparisons, except for NE_EXPR and EQ_EXPR, so we receive a machine mode
as well: if reversing the comparison is unsafe, return ERROR_MARK. */
-static enum tree_code
+enum tree_code
invert_tree_comparison (enum tree_code code, bool honor_nans)
{
if (honor_nans && flag_trapping_math)
@@ -5485,26 +5487,31 @@ constant_boolean_node (int value, tree type)
/* Return true if expr looks like an ARRAY_REF and set base and
offset to the appropriate trees. If there is no offset,
- offset is set to NULL_TREE. */
+ offset is set to NULL_TREE. Base will be canonicalized to
+ something you can get the element type from using
+ TREE_TYPE (TREE_TYPE (base)). */
static bool
extract_array_ref (tree expr, tree *base, tree *offset)
{
- /* We have to be careful with stripping nops as with the
- base type the meaning of the offset can change. */
- tree inner_expr = expr;
- STRIP_NOPS (inner_expr);
/* One canonical form is a PLUS_EXPR with the first
argument being an ADDR_EXPR with a possible NOP_EXPR
attached. */
if (TREE_CODE (expr) == PLUS_EXPR)
{
tree op0 = TREE_OPERAND (expr, 0);
+ tree inner_base, dummy1;
+ /* Strip NOP_EXPRs here because the C frontends and/or
+ folders present us (int *)&x.a + 4B possibly. */
STRIP_NOPS (op0);
- if (TREE_CODE (op0) == ADDR_EXPR)
+ if (extract_array_ref (op0, &inner_base, &dummy1))
{
- *base = TREE_OPERAND (expr, 0);
- *offset = TREE_OPERAND (expr, 1);
+ *base = inner_base;
+ if (dummy1 == NULL_TREE)
+ *offset = TREE_OPERAND (expr, 1);
+ else
+ *offset = fold_build2 (PLUS_EXPR, TREE_TYPE (expr),
+ dummy1, TREE_OPERAND (expr, 1));
return true;
}
}
@@ -5513,21 +5520,33 @@ extract_array_ref (tree expr, tree *base, tree *offset)
offset. For other arguments to the ADDR_EXPR we assume
zero offset and as such do not care about the ADDR_EXPR
type and strip possible nops from it. */
- else if (TREE_CODE (inner_expr) == ADDR_EXPR)
+ else if (TREE_CODE (expr) == ADDR_EXPR)
{
- tree op0 = TREE_OPERAND (inner_expr, 0);
+ tree op0 = TREE_OPERAND (expr, 0);
if (TREE_CODE (op0) == ARRAY_REF)
{
- *base = build_fold_addr_expr (TREE_OPERAND (op0, 0));
+ *base = TREE_OPERAND (op0, 0);
*offset = TREE_OPERAND (op0, 1);
}
else
{
- *base = inner_expr;
+ /* Handle array-to-pointer decay as &a. */
+ if (TREE_CODE (TREE_TYPE (op0)) == ARRAY_TYPE)
+ *base = TREE_OPERAND (expr, 0);
+ else
+ *base = expr;
*offset = NULL_TREE;
}
return true;
}
+ /* The next canonical form is a VAR_DECL with POINTER_TYPE. */
+ else if (SSA_VAR_P (expr)
+ && TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE)
+ {
+ *base = expr;
+ *offset = NULL_TREE;
+ return true;
+ }
return false;
}
@@ -7928,7 +7947,9 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
&& (TREE_CODE (arg1) != REAL_CST
|| REAL_VALUE_NEGATIVE (TREE_REAL_CST (arg1))))
|| (INTEGRAL_TYPE_P (type) && flag_wrapv && !flag_trapv)))
- return fold_build2 (PLUS_EXPR, type, arg0, negate_expr (arg1));
+ return fold_build2 (PLUS_EXPR, type,
+ fold_convert (type, arg0),
+ fold_convert (type, negate_expr (arg1)));
/* Try folding difference of addresses. */
{
@@ -8447,7 +8468,8 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
if (exact_real_inverse (TYPE_MODE(TREE_TYPE(arg0)), &r))
{
tem = build_real (type, r);
- return fold_build2 (MULT_EXPR, type, arg0, tem);
+ return fold_build2 (MULT_EXPR, type,
+ fold_convert (type, arg0), tem);
}
}
}
@@ -9014,6 +9036,12 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
&& extract_array_ref (arg1, &base1, &offset1)
&& operand_equal_p (base0, base1, 0))
{
+ if (TYPE_SIZE (TREE_TYPE (TREE_TYPE (base0)))
+ && integer_zerop (TYPE_SIZE (TREE_TYPE (TREE_TYPE (base0)))))
+ offset0 = NULL_TREE;
+ if (TYPE_SIZE (TREE_TYPE (TREE_TYPE (base1)))
+ && integer_zerop (TYPE_SIZE (TREE_TYPE (TREE_TYPE (base1)))))
+ offset1 = NULL_TREE;
if (offset0 == NULL_TREE
&& offset1 == NULL_TREE)
{
@@ -9275,12 +9303,16 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
switch (code)
{
case GE_EXPR:
- arg1 = const_binop (MINUS_EXPR, arg1, integer_one_node, 0);
- return fold_build2 (GT_EXPR, type, arg0, arg1);
+ arg1 = const_binop (MINUS_EXPR, arg1,
+ build_int_cst (TREE_TYPE (arg1), 1), 0);
+ return fold_build2 (GT_EXPR, type, arg0,
+ fold_convert (TREE_TYPE (arg0), arg1));
case LT_EXPR:
- arg1 = const_binop (MINUS_EXPR, arg1, integer_one_node, 0);
- return fold_build2 (LE_EXPR, type, arg0, arg1);
+ arg1 = const_binop (MINUS_EXPR, arg1,
+ build_int_cst (TREE_TYPE (arg1), 1), 0);
+ return fold_build2 (LE_EXPR, type, arg0,
+ fold_convert (TREE_TYPE (arg0), arg1));
default:
break;
@@ -9889,11 +9921,11 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
&& (arglist = TREE_OPERAND (arg0, 1))
&& TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) == POINTER_TYPE
&& ! TREE_CHAIN (arglist))
- return fold_build2 (code, type,
- build1 (INDIRECT_REF, char_type_node,
- TREE_VALUE (arglist)),
- fold_convert (char_type_node,
- integer_zero_node));
+ {
+ tree iref = build_fold_indirect_ref (TREE_VALUE (arglist));
+ return fold_build2 (code, type, iref,
+ build_int_cst (TREE_TYPE (iref), 0));
+ }
}
/* We can fold X/C1 op C2 where C1 and C2 are integer constants
@@ -10258,6 +10290,29 @@ fold_ternary (enum tree_code code, tree type, tree op0, tree op1, tree op2)
}
return NULL_TREE;
+ case BIT_FIELD_REF:
+ if (TREE_CODE (arg0) == VECTOR_CST
+ && type == TREE_TYPE (TREE_TYPE (arg0))
+ && host_integerp (arg1, 1)
+ && host_integerp (op2, 1))
+ {
+ unsigned HOST_WIDE_INT width = tree_low_cst (arg1, 1);
+ unsigned HOST_WIDE_INT idx = tree_low_cst (op2, 1);
+
+ if (width != 0
+ && simple_cst_equal (arg1, TYPE_SIZE (type)) == 1
+ && (idx % width) == 0
+ && (idx = idx / width)
+ < TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0)))
+ {
+ tree elements = TREE_VECTOR_CST_ELTS (arg0);
+ while (idx-- > 0)
+ elements = TREE_CHAIN (elements);
+ return TREE_VALUE (elements);
+ }
+ }
+ return NULL_TREE;
+
default:
return NULL_TREE;
} /* switch (code) */
@@ -10393,6 +10448,8 @@ fold_checksum_tree (tree expr, struct md5_ctx *ctx, htab_t ht)
enum tree_code code;
char buf[sizeof (struct tree_decl)];
int i, len;
+
+recursive_label:
gcc_assert ((sizeof (struct tree_exp) + 5 * sizeof (tree)
<= sizeof (struct tree_decl))
@@ -10414,11 +10471,13 @@ fold_checksum_tree (tree expr, struct md5_ctx *ctx, htab_t ht)
}
else if (TREE_CODE_CLASS (code) == tcc_type
&& (TYPE_POINTER_TO (expr) || TYPE_REFERENCE_TO (expr)
- || TYPE_CACHED_VALUES_P (expr)))
+ || TYPE_CACHED_VALUES_P (expr)
+ || TYPE_CONTAINS_PLACEHOLDER_INTERNAL (expr)))
{
/* Allow these fields to be modified. */
memcpy (buf, expr, tree_size (expr));
expr = (tree) buf;
+ TYPE_CONTAINS_PLACEHOLDER_INTERNAL (expr) = 0;
TYPE_POINTER_TO (expr) = NULL;
TYPE_REFERENCE_TO (expr) = NULL;
if (TYPE_CACHED_VALUES_P (expr))
@@ -10430,7 +10489,8 @@ fold_checksum_tree (tree expr, struct md5_ctx *ctx, htab_t ht)
md5_process_bytes (expr, tree_size (expr), ctx);
fold_checksum_tree (TREE_TYPE (expr), ctx, ht);
if (TREE_CODE_CLASS (code) != tcc_type
- && TREE_CODE_CLASS (code) != tcc_declaration)
+ && TREE_CODE_CLASS (code) != tcc_declaration
+ && code != TREE_LIST)
fold_checksum_tree (TREE_CHAIN (expr), ctx, ht);
switch (TREE_CODE_CLASS (code))
{
@@ -10458,6 +10518,8 @@ fold_checksum_tree (tree expr, struct md5_ctx *ctx, htab_t ht)
case TREE_LIST:
fold_checksum_tree (TREE_PURPOSE (expr), ctx, ht);
fold_checksum_tree (TREE_VALUE (expr), ctx, ht);
+ expr = TREE_CHAIN (expr);
+ goto recursive_label;
break;
case TREE_VEC:
for (i = 0; i < TREE_VEC_LENGTH (expr); ++i)
@@ -11448,14 +11510,14 @@ build_fold_addr_expr (tree t)
return build_fold_addr_expr_with_type (t, build_pointer_type (TREE_TYPE (t)));
}
-/* Given a pointer value T, return a simplified version of an indirection
- through T, or NULL_TREE if no simplification is possible. */
+/* Given a pointer value OP0 and a type TYPE, return a simplified version
+ of an indirection through OP0, or NULL_TREE if no simplification is
+ possible. */
-static tree
-fold_indirect_ref_1 (tree t)
+tree
+fold_indirect_ref_1 (tree type, tree op0)
{
- tree type = TREE_TYPE (TREE_TYPE (t));
- tree sub = t;
+ tree sub = op0;
tree subtype;
STRIP_NOPS (sub);
@@ -11468,11 +11530,11 @@ fold_indirect_ref_1 (tree t)
tree op = TREE_OPERAND (sub, 0);
tree optype = TREE_TYPE (op);
/* *&p => p */
- if (lang_hooks.types_compatible_p (type, optype))
+ if (type == optype)
return op;
/* *(foo *)&fooarray => fooarray[0] */
else if (TREE_CODE (optype) == ARRAY_TYPE
- && lang_hooks.types_compatible_p (type, TREE_TYPE (optype)))
+ && type == TREE_TYPE (optype))
{
tree type_domain = TYPE_DOMAIN (optype);
tree min_val = size_zero_node;
@@ -11484,7 +11546,7 @@ fold_indirect_ref_1 (tree t)
/* *(foo *)fooarrptr => (*fooarrptr)[0] */
if (TREE_CODE (TREE_TYPE (subtype)) == ARRAY_TYPE
- && lang_hooks.types_compatible_p (type, TREE_TYPE (TREE_TYPE (subtype))))
+ && type == TREE_TYPE (TREE_TYPE (subtype)))
{
tree type_domain;
tree min_val = size_zero_node;
@@ -11504,12 +11566,13 @@ fold_indirect_ref_1 (tree t)
tree
build_fold_indirect_ref (tree t)
{
- tree sub = fold_indirect_ref_1 (t);
+ tree type = TREE_TYPE (TREE_TYPE (t));
+ tree sub = fold_indirect_ref_1 (type, t);
if (sub)
return sub;
else
- return build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (t)), t);
+ return build1 (INDIRECT_REF, type, t);
}
/* Given an INDIRECT_REF T, return either T or a simplified version. */
@@ -11517,7 +11580,7 @@ build_fold_indirect_ref (tree t)
tree
fold_indirect_ref (tree t)
{
- tree sub = fold_indirect_ref_1 (TREE_OPERAND (t, 0));
+ tree sub = fold_indirect_ref_1 (TREE_TYPE (t), TREE_OPERAND (t, 0));
if (sub)
return sub;
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 711cb74deb1..e7c0c95f712 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,134 @@
+2005-06-01 Roger Sayle <roger@eyesopen.com>
+
+ * intrinsic.c (add_conv): No longer take a "simplify" argument as
+ its always gfc_convert_constant, instead take a "standard" argument.
+ (add_conversions): Change all existing calls of add_conv to pass
+ GFC_STD_F77 as appropriate. Additionally, if we're allowing GNU
+ extensions support integer-logical and logical-integer conversions.
+ (gfc_convert_type_warn): Warn about use the use of these conversions
+ as a extension when appropriate, i.e. with -pedantic.
+ * simplify.c (gfc_convert_constant): Add support for integer to
+ logical and logical to integer conversions, using gfc_int2log and
+ gfc_log2int.
+ * arith.c (gfc_log2int, gfc_int2log): New functions.
+ * arith.h (gfc_log2int, gfc_int2log): Prototype here.
+ * gfortran.texi: Document this new GNU extension.
+
+2005-06-01 Paul Thomas <pault@gcc.gnu.org>
+
+ * fortran/trans-expr.c (gfc_conv_variable): Clean up bracketting.
+ * fortran/trans-expr.c (gfc_conv_function_call): Insert spaces.
+ Correct comments and replace convert of integer_one_node with
+ build_int_cst.
+
+2005-06-01 Jakub Jelinek <jakub@redhat.com>
+
+ PR fortran/21729
+ * resolve.c (resolve_contained_fntype): Use sym->attr.untyped
+ to avoid giving error multiple times.
+ (resolve_entries): Don't error about BT_UNKNOWN here.
+ (resolve_unknown_f): Capitalize IMPLICIT for consistency.
+ (resolve_fntype): New function.
+ (gfc_resolve): Call resolve_fntype.
+
+2005-06-01 Feng Wang <fengwang@nudt.edu.cn>
+
+ PR fortran/20883
+ * fortran/io.c (resolve_tag): Fix error message.
+
+2005-05-31 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * fortran/trans-decl.c: Don't include errors.h.
+ * fortran/Make-lang.in: Updates dependencies.
+
+2005-05-31 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/18109
+ PR fortran/18283
+ PR fortran/19107
+ * fortran/trans-array.c (gfc_conv_expr_descriptor): Obtain the
+ string length from the expression typespec character length value
+ and set temp_ss->stringlength and backend_decl. Obtain the
+ tree expression from gfc_conv_expr rather than gfc_conv_expr_val.
+ Dereference the expression to obtain the character.
+ * fortran/trans-expr.c (gfc_conv_component_ref): Remove the
+ dereference of scalar character pointer structure components.
+ * fortran/trans-expr.c (gfc_trans_subarray_assign): Obtain the
+ string length for the structure component from the component
+ expression.
+
+2005-05-30 Roger Sayle <roger@eyesopen.com>
+
+ * gfortran.h (GFC_STD_LEGACY): New "standard" macro. Reindent.
+ * options.c (gfc_init_options): By default, allow legacy extensions
+ but warn about them.
+ (gfc_post_options): Make -pedantic warn about legacy extensions
+ even with -std=legacy.
+ (gfc_handle_option): Make -std=gnu follow the default behaviour
+ of warning about legacy extensions, but allowing them. Make the
+ new -std=legacy accept everything and warn about nothing.
+ * lang.opt (std=legacy): New F95 command line option.
+ * invoke.texi: Document both -std=f2003 and -std=legacy.
+ * gfortran.texi: Explain the two types of extensions and document
+ how they are affected by the various -std= command line options.
+
+2005-05-30 Kazu Hirata <kazu@cs.umass.edu>
+
+ * trans-expr.c: Remove trailing ^M.
+
+ * trans-expr.c: Fix comment typos.
+
+2005-05-29 Paul Thomas <pault@gcc.gnu.org>
+
+ PR fortran/16939
+ PR fortran/17192
+ PR fortran/17193
+ PR fortran/17202
+ PR fortran/18689
+ PR fortran/18890
+ * fortran/trans-array.c (gfc_conv_resolve_dependencies): Add string
+ length to temp_ss for character pointer array assignments.
+ * fortran/trans-expr.c (gfc_conv_variable): Correct errors in
+ dereferencing of characters and character pointers.
+ * fortran/trans-expr.c (gfc_conv_function_call): Provide string
+ length as return argument for various kinds of handling of return.
+ Return a char[]* temporary for character pointer functions and
+ dereference the temporary upon return.
+
+2005-05-29 Janne Blomqvist <jblomqvi@vipunen.hut.fi>
+ Steven G. Kargl <kargls@comcast.net>
+
+ fortran/PR20846
+ * io.c (gfc_match_inquire): Implement constraints on UNIT and FILE usage.
+
+2005-05-29 Francois-Xavier Coudert <coudert@clipper.ens.fr>
+
+ PR libfortran/20006
+ * io.c (format_item_1): Add check and extension warning for
+ $ edit descriptor.
+
+2005-05-28 Steven G. Kargl <kargls@comcast.net>
+
+ * arith.c (gfc_arith_init_1): Fix off by one problem;
+ (gfc_check_integer_range): Chop extra bits in subnormal numbers.
+
+2005-05-28 Jerry DeLisle <jvdelisle@verizon.net>
+ Steven G. Kargl <kargls@comcast.net>
+
+ * intrinsic.texi: added documentation for BIT_SIZE, BTEST, CHAR, CEILING
+ and CMPLX
+
+2005-05-27 Steven G. Kargl <kargls@comcast.net>
+
+ * trans-array.c (gfc_trans_deferred_array): Use build_int_cst to force
+ like types in comparsion.
+
+2005-05-26 Kazu Hirata <kazu@cs.umass.edu>
+
+ * data.c, parse.c, trans-array.c, trans-decl.c,
+ trans-intrinsic.c, trans-stmt.c, trans-types.c, trans.c,
+ trans.h: Fix comment typos. Follow spelling conventions.
+
2005-05-22 Roger Sayle <roger@eyesopen.com>
* gfortran.texi: Document some more GNU extensions.
diff --git a/gcc/fortran/Make-lang.in b/gcc/fortran/Make-lang.in
index 29b41920899..83992b63aef 100644
--- a/gcc/fortran/Make-lang.in
+++ b/gcc/fortran/Make-lang.in
@@ -284,7 +284,7 @@ fortran/f95-lang.o: $(GFORTRAN_TRANS_DEPS) fortran/mathbuiltins.def \
fortran/convert.o: $(GFORTRAN_TRANS_DEPS)
fortran/trans.o: $(GFORTRAN_TRANS_DEPS)
fortran/trans-decl.o: $(GFORTRAN_TRANS_DEPS) gt-fortran-trans-decl.h \
- cgraph.h $(TARGET_H) function.h errors.h $(FLAGS_H) tree-gimple.h \
+ cgraph.h $(TARGET_H) function.h $(FLAGS_H) tree-gimple.h \
tree-dump.h
fortran/trans-types.o: $(GFORTRAN_TRANS_DEPS) gt-fortran-trans-types.h \
real.h toplev.h $(TARGET_H)
diff --git a/gcc/fortran/arith.c b/gcc/fortran/arith.c
index ef19217ae04..684ae7bfd8b 100644
--- a/gcc/fortran/arith.c
+++ b/gcc/fortran/arith.c
@@ -259,9 +259,9 @@ gfc_arith_init_1 (void)
mpfr_init (real_info->tiny);
mpfr_set (real_info->tiny, b, GFC_RND_MODE);
- /* subnormal (x) = b**(emin - digit + 1) */
+ /* subnormal (x) = b**(emin - digit) */
mpfr_set_ui (b, real_info->radix, GFC_RND_MODE);
- mpfr_pow_si (b, b, real_info->min_exponent - real_info->digits + 1,
+ mpfr_pow_si (b, b, real_info->min_exponent - real_info->digits,
GFC_RND_MODE);
mpfr_init (real_info->subnormal);
@@ -381,9 +381,42 @@ gfc_check_real_range (mpfr_t p, int kind)
if (mpfr_sgn (q) == 0)
retval = ARITH_OK;
else if (mpfr_cmp (q, gfc_real_kinds[i].huge) > 0)
- retval = ARITH_OVERFLOW;
+ retval = ARITH_OVERFLOW;
else if (mpfr_cmp (q, gfc_real_kinds[i].subnormal) < 0)
retval = ARITH_UNDERFLOW;
+ else if (mpfr_cmp (q, gfc_real_kinds[i].tiny) < 0)
+ {
+ /* MPFR operates on a numbers with a given precision and enormous
+ exponential range. To represent subnormal numbers the exponent is
+ allowed to become smaller than emin, but always retains the full
+ precision. This function resets unused bits to 0 to alleviate
+ rounding problems. Note, a future version of MPFR will have a
+ mpfr_subnormalize() function, which handles this truncation in a
+ more efficient and robust way. */
+
+ int j, k;
+ char *bin, *s;
+ mp_exp_t e;
+
+ bin = mpfr_get_str (NULL, &e, gfc_real_kinds[i].radix, 0, q, GMP_RNDN);
+ k = gfc_real_kinds[i].digits - (gfc_real_kinds[i].min_exponent - e);
+ for (j = k; j < gfc_real_kinds[i].digits; j++)
+ bin[j] = '0';
+ /* Need space for '0.', bin, 'E', and e */
+ s = (char *) gfc_getmem (strlen(bin)+10);
+ sprintf (s, "0.%sE%d", bin, (int) e);
+ mpfr_set_str (q, s, gfc_real_kinds[i].radix, GMP_RNDN);
+
+ if (mpfr_sgn (p) < 0)
+ mpfr_neg (p, q, GMP_RNDN);
+ else
+ mpfr_set (p, q, GMP_RNDN);
+
+ gfc_free (s);
+ gfc_free (bin);
+
+ retval = ARITH_OK;
+ }
else
retval = ARITH_OK;
@@ -2158,3 +2191,26 @@ gfc_log2log (gfc_expr * src, int kind)
return result;
}
+
+/* Convert logical to integer. */
+
+gfc_expr *
+gfc_log2int (gfc_expr *src, int kind)
+{
+ gfc_expr *result;
+ result = gfc_constant_result (BT_INTEGER, kind, &src->where);
+ mpz_set_si (result->value.integer, src->value.logical);
+ return result;
+}
+
+/* Convert integer to logical. */
+
+gfc_expr *
+gfc_int2log (gfc_expr *src, int kind)
+{
+ gfc_expr *result;
+ result = gfc_constant_result (BT_LOGICAL, kind, &src->where);
+ result->value.logical = (mpz_cmp_si (src->value.integer, 0) != 0);
+ return result;
+}
+
diff --git a/gcc/fortran/arith.h b/gcc/fortran/arith.h
index 1a718d4ea4c..f75b826ee7c 100644
--- a/gcc/fortran/arith.h
+++ b/gcc/fortran/arith.h
@@ -80,6 +80,8 @@ gfc_expr *gfc_complex2int (gfc_expr *, int);
gfc_expr *gfc_complex2real (gfc_expr *, int);
gfc_expr *gfc_complex2complex (gfc_expr *, int);
gfc_expr *gfc_log2log (gfc_expr *, int);
+gfc_expr *gfc_log2int (gfc_expr *, int);
+gfc_expr *gfc_int2log (gfc_expr *, int);
#endif /* GFC_ARITH_H */
diff --git a/gcc/fortran/data.c b/gcc/fortran/data.c
index 5a74516c758..17354d2fbe7 100644
--- a/gcc/fortran/data.c
+++ b/gcc/fortran/data.c
@@ -132,7 +132,7 @@ find_con_by_component (gfc_component *com, gfc_constructor *con)
}
-/* Create a character type intialization expression from RVALUE.
+/* Create a character type initialization expression from RVALUE.
TS [and REF] describe [the substring of] the variable being initialized.
INIT is thh existing initializer, not NULL. Initialization is performed
according to normal assignment rules. */
@@ -556,7 +556,7 @@ formalize_structure_cons (gfc_expr * expr)
c = expr->value.constructor;
- /* Constructor is already fomalized. */
+ /* Constructor is already formalized. */
if (c->n.component == NULL)
return;
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index d17f388212c..69a56e188ac 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -92,13 +92,14 @@ mstring;
/* Flags to specify which standard/extension contains a feature. */
-#define GFC_STD_GNU (1<<5) /* GNU Fortran extension. */
-#define GFC_STD_F2003 (1<<4) /* New in F2003. */
+#define GFC_STD_LEGACY (1<<6) /* Backward compatibility. */
+#define GFC_STD_GNU (1<<5) /* GNU Fortran extension. */
+#define GFC_STD_F2003 (1<<4) /* New in F2003. */
/* Note that no features were obsoleted nor deleted in F2003. */
-#define GFC_STD_F95 (1<<3) /* New in F95. */
-#define GFC_STD_F95_DEL (1<<2) /* Deleted in F95. */
-#define GFC_STD_F95_OBS (1<<1) /* Obsoleted in F95. */
-#define GFC_STD_F77 (1<<0) /* Up to and including F77. */
+#define GFC_STD_F95 (1<<3) /* New in F95. */
+#define GFC_STD_F95_DEL (1<<2) /* Deleted in F95. */
+#define GFC_STD_F95_OBS (1<<1) /* Obsoleted in F95. */
+#define GFC_STD_F77 (1<<0) /* Up to and including F77. */
/*************************** Enums *****************************/
diff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi
index 2644e40257e..50b64990985 100644
--- a/gcc/fortran/gfortran.texi
+++ b/gcc/fortran/gfortran.texi
@@ -618,7 +618,14 @@ Variable for swapping Endianness during unformatted write.
@command{gfortran} implements a number of extensions over standard
Fortran. This chapter contains information on their syntax and
-meaning.
+meaning. There are currently two categories of @command{gfortran}
+extensions, those that provide functionality beyond that provided
+by any standard, and those that are supported by @command{gfortran}
+purely for backward compatibility with legacy compilers. By default,
+@option{-std=gnu} allows the compiler to accept both types of
+extensions, but to warn about the use of the latter. Specifying
+either @option{-std=f95} or @option{-std=f2003} disables both types
+of extensions, and @option{-std=legacy} allows both without warning.
@menu
* Old-style kind specifications::
@@ -630,6 +637,7 @@ meaning.
* Hexadecimal constants::
* Real array indices::
* Unary operators::
+* Implicitly interconvert LOGICAL and INTEGER::
@end menu
@node Old-style kind specifications
@@ -786,6 +794,22 @@ operators without the need for parenthesis.
X = Y * -Z
@end smallexample
+@node Implicitly interconvert LOGICAL and INTEGER
+@section Implicitly interconvert LOGICAL and INTEGER
+@cindex Implicitly interconvert LOGICAL and INTEGER
+
+As a GNU extension for backwards compatability with other compilers,
+@command{gfortran} allows the implicit conversion of LOGICALs to INTEGERs
+and vice versa. When converting from a LOGICAL to an INTEGER, the numeric
+value of @code{.FALSE.} is zero, and that of @code{.TRUE.} is one. When
+converting from INTEGER to LOGICAL, the value zero is interpreted as
+@code{.FALSE.} and any non-zero value is interpreted as @code{.TRUE.}.
+
+@smallexample
+ INTEGER*4 i
+ i = .FALSE.
+@end smallexample
+
@include intrinsic.texi
@c ---------------------------------------------------------------------
@c Contributing
diff --git a/gcc/fortran/intrinsic.c b/gcc/fortran/intrinsic.c
index 0b50cdcaa11..66cf1902689 100644
--- a/gcc/fortran/intrinsic.c
+++ b/gcc/fortran/intrinsic.c
@@ -2227,8 +2227,7 @@ add_subroutines (void)
/* Add a function to the list of conversion symbols. */
static void
-add_conv (bt from_type, int from_kind, bt to_type, int to_kind,
- gfc_expr * (*simplify) (gfc_expr *, bt, int))
+add_conv (bt from_type, int from_kind, bt to_type, int to_kind, int standard)
{
gfc_typespec from, to;
@@ -2250,9 +2249,10 @@ add_conv (bt from_type, int from_kind, bt to_type, int to_kind,
sym = conversion + nconv;
- sym->name = conv_name (&from, &to);
+ sym->name = conv_name (&from, &to);
sym->lib_name = sym->name;
- sym->simplify.cc = simplify;
+ sym->simplify.cc = gfc_convert_constant;
+ sym->standard = standard;
sym->elemental = 1;
sym->ts = to;
sym->generic_id = GFC_ISYM_CONVERSION;
@@ -2277,7 +2277,7 @@ add_conversions (void)
continue;
add_conv (BT_INTEGER, gfc_integer_kinds[i].kind,
- BT_INTEGER, gfc_integer_kinds[j].kind, gfc_convert_constant);
+ BT_INTEGER, gfc_integer_kinds[j].kind, GFC_STD_F77);
}
/* Integer-Real/Complex conversions. */
@@ -2285,16 +2285,16 @@ add_conversions (void)
for (j = 0; gfc_real_kinds[j].kind != 0; j++)
{
add_conv (BT_INTEGER, gfc_integer_kinds[i].kind,
- BT_REAL, gfc_real_kinds[j].kind, gfc_convert_constant);
+ BT_REAL, gfc_real_kinds[j].kind, GFC_STD_F77);
add_conv (BT_REAL, gfc_real_kinds[j].kind,
- BT_INTEGER, gfc_integer_kinds[i].kind, gfc_convert_constant);
+ BT_INTEGER, gfc_integer_kinds[i].kind, GFC_STD_F77);
add_conv (BT_INTEGER, gfc_integer_kinds[i].kind,
- BT_COMPLEX, gfc_real_kinds[j].kind, gfc_convert_constant);
+ BT_COMPLEX, gfc_real_kinds[j].kind, GFC_STD_F77);
add_conv (BT_COMPLEX, gfc_real_kinds[j].kind,
- BT_INTEGER, gfc_integer_kinds[i].kind, gfc_convert_constant);
+ BT_INTEGER, gfc_integer_kinds[i].kind, GFC_STD_F77);
}
/* Real/Complex - Real/Complex conversions. */
@@ -2304,17 +2304,17 @@ add_conversions (void)
if (i != j)
{
add_conv (BT_REAL, gfc_real_kinds[i].kind,
- BT_REAL, gfc_real_kinds[j].kind, gfc_convert_constant);
+ BT_REAL, gfc_real_kinds[j].kind, GFC_STD_F77);
add_conv (BT_COMPLEX, gfc_real_kinds[i].kind,
- BT_COMPLEX, gfc_real_kinds[j].kind, gfc_convert_constant);
+ BT_COMPLEX, gfc_real_kinds[j].kind, GFC_STD_F77);
}
add_conv (BT_REAL, gfc_real_kinds[i].kind,
- BT_COMPLEX, gfc_real_kinds[j].kind, gfc_convert_constant);
+ BT_COMPLEX, gfc_real_kinds[j].kind, GFC_STD_F77);
add_conv (BT_COMPLEX, gfc_real_kinds[i].kind,
- BT_REAL, gfc_real_kinds[j].kind, gfc_convert_constant);
+ BT_REAL, gfc_real_kinds[j].kind, GFC_STD_F77);
}
/* Logical/Logical kind conversion. */
@@ -2325,8 +2325,19 @@ add_conversions (void)
continue;
add_conv (BT_LOGICAL, gfc_logical_kinds[i].kind,
- BT_LOGICAL, gfc_logical_kinds[j].kind, gfc_convert_constant);
+ BT_LOGICAL, gfc_logical_kinds[j].kind, GFC_STD_F77);
}
+
+ /* Integer-Logical and Logical-Integer conversions. */
+ if ((gfc_option.allow_std & GFC_STD_LEGACY) != 0)
+ for (i=0; gfc_integer_kinds[i].kind; i++)
+ for (j=0; gfc_logical_kinds[j].kind; j++)
+ {
+ add_conv (BT_INTEGER, gfc_integer_kinds[i].kind,
+ BT_LOGICAL, gfc_logical_kinds[j].kind, GFC_STD_LEGACY);
+ add_conv (BT_LOGICAL, gfc_logical_kinds[j].kind,
+ BT_INTEGER, gfc_integer_kinds[i].kind, GFC_STD_LEGACY);
+ }
}
@@ -3142,7 +3153,10 @@ gfc_convert_type_warn (gfc_expr * expr, gfc_typespec * ts, int eflag,
goto bad;
/* At this point, a conversion is necessary. A warning may be needed. */
- if (wflag && gfc_option.warn_conversion)
+ if ((gfc_option.warn_std & sym->standard) != 0)
+ gfc_warning_now ("Extension: Conversion from %s to %s at %L",
+ gfc_typename (&from_ts), gfc_typename (ts), &expr->where);
+ else if (wflag && gfc_option.warn_conversion)
gfc_warning_now ("Conversion from %s to %s at %L",
gfc_typename (&from_ts), gfc_typename (ts), &expr->where);
diff --git a/gcc/fortran/intrinsic.texi b/gcc/fortran/intrinsic.texi
index ad09185bd45..31a4c51580b 100644
--- a/gcc/fortran/intrinsic.texi
+++ b/gcc/fortran/intrinsic.texi
@@ -32,41 +32,46 @@ This portion of the document is incomplete and undergoing massive expansion
and editing. All contributions and corrections are strongly encouraged.
@menu
-* Introduction: Introduction
-* @code{ABORT}: ABORT, Abort the program
-* @code{ABS}: ABS, Absolute value
-* @code{ACHAR}: ACHAR, Character in @acronym{ASCII} collating sequence
-* @code{ACOS}: ACOS, Arccosine function
-* @code{ADJUSTL}: ADJUSTL, Left adjust a string
-* @code{ADJUSTR}: ADJUSTR, Right adjust a string
-* @code{AIMAG}: AIMAG, Imaginary part of complex number
-* @code{AINT}: AINT, Truncate to a whole number
-* @code{ALL}: ALL, Determine if all values are true
-* @code{ALLOCATED}: ALLOCATED, Status of allocatable entity
-* @code{ANINT}: ANINT, Nearest whole number
-* @code{ANY}: ANY, Determine if any values are true
-* @code{ASIN}: ASIN, Arcsine function
-* @code{ASSOCIATED}: ASSOCIATED, Status of a pointer or pointer/target pair
-* @code{ATAN}: ATAN, Arctangent function
-* @code{ATAN2}: ATAN2, Arctangent function
-* @code{BESJ0}: BESJ0, Bessel function of the first kind of order 0
-* @code{BESJ1}: BESJ1, Bessel function of the first kind of order 1
-* @code{BESJN}: BESJN, Bessel function of the first kind
-* @code{BESY0}: BESY0, Bessel function of the second kind of order 0
-* @code{BESY1}: BESY1, Bessel function of the second kind of order 1
-* @code{BESYN}: BESYN, Bessel function of the second kind
-* @code{COS}: COS, Cosine function
-* @code{COSH}: COSH, Hyperbolic cosine function
-* @code{ERF}: ERF, Error function
-* @code{ERFC}: ERFC, Complementary error function
-* @code{EXP}: EXP, Cosine function
-* @code{LOG}: LOG, Logarithm function
-* @code{LOG10}: LOG10, Base 10 logarithm function
-* @code{SQRT}: SQRT, Square-root function
-* @code{SIN}: SIN, Sine function
-* @code{SINH}: SINH, Hyperbolic sine function
-* @code{TAN}: TAN, Tangent function
-* @code{TANH}: TANH, Hyperbolic tangent function
+* Introduction: Introduction
+* @code{ABORT}: ABORT, Abort the program
+* @code{ABS}: ABS, Absolute value
+* @code{ACHAR}: ACHAR, Character in @acronym{ASCII} collating sequence
+* @code{ACOS}: ACOS, Arccosine function
+* @code{ADJUSTL}: ADJUSTL, Left adjust a string
+* @code{ADJUSTR}: ADJUSTR, Right adjust a string
+* @code{AIMAG}: AIMAG, Imaginary part of complex number
+* @code{AINT}: AINT, Truncate to a whole number
+* @code{ALL}: ALL, Determine if all values are true
+* @code{ALLOCATED}: ALLOCATED, Status of allocatable entity
+* @code{ANINT}: ANINT, Nearest whole number
+* @code{ANY}: ANY, Determine if any values are true
+* @code{ASIN}: ASIN, Arcsine function
+* @code{ASSOCIATED}: ASSOCIATED, Status of a pointer or pointer/target pair
+* @code{ATAN}: ATAN, Arctangent function
+* @code{ATAN2}: ATAN2, Arctangent function
+* @code{BESJ0}: BESJ0, Bessel function of the first kind of order 0
+* @code{BESJ1}: BESJ1, Bessel function of the first kind of order 1
+* @code{BESJN}: BESJN, Bessel function of the first kind
+* @code{BESY0}: BESY0, Bessel function of the second kind of order 0
+* @code{BESY1}: BESY1, Bessel function of the second kind of order 1
+* @code{BESYN}: BESYN, Bessel function of the second kind
+* @code{BIT_SIZE}: BIT_SIZE, Bit size inquiry function
+* @code{BTEST}: BTEST, Bit test function
+* @code{CEILING}: CEILING, Integer ceiling function
+* @code{CHAR}: CHAR, Character conversion function
+* @code{CMPLX}: CMPLX, Complex conversion function
+* @code{COS}: COS, Cosine function
+* @code{COSH}: COSH, Hyperbolic cosine function
+* @code{ERF}: ERF, Error function
+* @code{ERFC}: ERFC, Complementary error function
+* @code{EXP}: EXP, Cosine function
+* @code{LOG}: LOG, Logarithm function
+* @code{LOG10}: LOG10, Base 10 logarithm function
+* @code{SQRT}: SQRT, Square-root function
+* @code{SIN}: SIN, Sine function
+* @code{SINH}: SINH, Hyperbolic sine function
+* @code{TAN}: TAN, Tangent function
+* @code{TANH}: TANH, Hyperbolic tangent function
@end menu
@node Introduction
@@ -124,7 +129,7 @@ which is suitable for debugging purposes.
@item @emph{Option}:
gnu
-@item @emph{Type}:
+@item @emph{Class}:
non-elemental subroutine
@item @emph{Syntax}:
@@ -161,7 +166,7 @@ end program test_abort
@item @emph{Option}:
f95, gnu
-@item @emph{Type}:
+@item @emph{Class}:
elemental function
@item @emph{Syntax}:
@@ -216,7 +221,7 @@ in the @acronym{ASCII} collating sequence.
@item @emph{Option}:
f95, gnu
-@item @emph{Type}:
+@item @emph{Class}:
elemental function
@item @emph{Syntax}:
@@ -224,7 +229,7 @@ elemental function
@item @emph{Arguments}:
@multitable @columnfractions .15 .80
-@item @var{I} @tab The type shall be an @code{INTEGER(*)}.
+@item @var{I} @tab The type shall be @code{INTEGER(*)}.
@end multitable
@item @emph{Return value}:
@@ -255,7 +260,7 @@ end program test_achar
@item @emph{Option}:
f95, gnu
-@item @emph{Type}:
+@item @emph{Class}:
elemental function
@item @emph{Syntax}:
@@ -263,7 +268,7 @@ elemental function
@item @emph{Arguments}:
@multitable @columnfractions .15 .80
-@item @var{X} @tab The type shall be an @code{REAL(*)}, and a magnitude that is
+@item @var{X} @tab The type shall be @code{REAL(*)}, and a magnitude that is
less than one.
@end multitable
@@ -302,7 +307,7 @@ Spaces are inserted at the end of the string as needed.
@item @emph{Option}:
f95, gnu
-@item @emph{Type}:
+@item @emph{Class}:
elemental function
@item @emph{Syntax}:
@@ -329,6 +334,7 @@ end program test_adjustl
@end table
+
@node ADJUSTR
@section @code{ADJUSTR} --- Right adjust a string
@findex @code{ADJUSTR} intrinsic
@@ -342,7 +348,7 @@ Spaces are inserted at the start of the string as needed.
@item @emph{Option}:
f95, gnu
-@item @emph{Type}:
+@item @emph{Class}:
elemental function
@item @emph{Syntax}:
@@ -369,6 +375,7 @@ end program test_adjustr
@end table
+
@node AIMAG
@section @code{AIMAG} --- Imaginary part of complex number
@findex @code{AIMAG} intrinsic
@@ -382,7 +389,7 @@ end program test_adjustr
@item @emph{Option}:
f95, gnu
-@item @emph{Type}:
+@item @emph{Class}:
elemental function
@item @emph{Syntax}:
@@ -416,6 +423,7 @@ end program test_aimag
@end table
+
@node AINT
@section @code{AINT} --- Imaginary part of complex number
@findex @code{AINT} intrinsic
@@ -429,7 +437,7 @@ end program test_aimag
@item @emph{Option}:
f95, gnu
-@item @emph{Type}:
+@item @emph{Class}:
elemental function
@item @emph{Syntax}:
@@ -472,6 +480,7 @@ end program test_aint
@end table
+
@node ALL
@section @code{ALL} --- All values in @var{MASK} along @var{DIM} are true
@findex @code{ALL} intrinsic
@@ -485,7 +494,7 @@ in the array along dimension @var{DIM}.
@item @emph{Option}:
f95, gnu
-@item @emph{Type}:
+@item @emph{Class}:
transformational function
@item @emph{Syntax}:
@@ -551,7 +560,7 @@ end program test_all
@item @emph{Option}:
f95, gnu
-@item @emph{Type}:
+@item @emph{Class}:
inquiry function
@item @emph{Syntax}:
@@ -578,6 +587,7 @@ end program test_allocated
@end table
+
@node ANINT
@section @code{ANINT} --- Imaginary part of complex number
@findex @code{ANINT} intrinsic
@@ -591,7 +601,7 @@ end program test_allocated
@item @emph{Option}:
f95, gnu
-@item @emph{Type}:
+@item @emph{Class}:
elemental function
@item @emph{Syntax}:
@@ -632,6 +642,7 @@ end program test_anint
@end table
+
@node ANY
@section @code{ANY} --- Any value in @var{MASK} along @var{DIM} is true
@findex @code{ANY} intrinsic
@@ -645,7 +656,7 @@ in the array along dimension @var{DIM}.
@item @emph{Option}:
f95, gnu
-@item @emph{Type}:
+@item @emph{Class}:
transformational function
@item @emph{Syntax}:
@@ -698,6 +709,7 @@ end program test_any
@end table
+
@node ASIN
@section @code{ASIN} --- Arcsine function
@findex @code{ASIN} intrinsic
@@ -711,7 +723,7 @@ end program test_any
@item @emph{Option}:
f95, gnu
-@item @emph{Type}:
+@item @emph{Class}:
elemental function
@item @emph{Syntax}:
@@ -719,7 +731,7 @@ elemental function
@item @emph{Arguments}:
@multitable @columnfractions .15 .80
-@item @var{X} @tab The type shall be an @code{REAL(*)}, and a magnitude that is
+@item @var{X} @tab The type shall be @code{REAL(*)}, and a magnitude that is
less than one.
@end multitable
@@ -744,6 +756,7 @@ end program test_asin
@end table
+
@node ASSOCIATED
@section @code{ASSOCIATED} --- Status of a pointer or pointer/target pair
@findex @code{ASSOCIATED} intrinsic
@@ -757,7 +770,7 @@ or if @var{PTR} is associated with the target @var{TGT}.
@item @emph{Option}:
f95, gnu
-@item @emph{Type}:
+@item @emph{Class}:
inquiry function
@item @emph{Syntax}:
@@ -816,6 +829,7 @@ end program test_associated
@end table
+
@node ATAN
@section @code{ATAN} --- Arctangent function
@findex @code{ATAN} intrinsic
@@ -829,7 +843,7 @@ end program test_associated
@item @emph{Option}:
f95, gnu
-@item @emph{Type}:
+@item @emph{Class}:
elemental function
@item @emph{Syntax}:
@@ -837,7 +851,7 @@ elemental function
@item @emph{Arguments}:
@multitable @columnfractions .15 .80
-@item @var{X} @tab The type shall be an @code{REAL(*)}.
+@item @var{X} @tab The type shall be @code{REAL(*)}.
@end multitable
@item @emph{Return value}:
@@ -860,6 +874,7 @@ end program test_atan
@end table
+
@node ATAN2
@section @code{ATAN2} --- Arctangent function
@findex @code{ATAN2} intrinsic
@@ -873,7 +888,7 @@ end program test_atan
@item @emph{Option}:
f95, gnu
-@item @emph{Type}:
+@item @emph{Class}:
elemental function
@item @emph{Syntax}:
@@ -911,6 +926,7 @@ end program test_atan2
@end table
+
@node BESJ0
@section @code{BESJ0} --- Bessel function of the first kind of order 0
@findex @code{BESJ0} intrinsic
@@ -925,7 +941,7 @@ of @var{X}.
@item @emph{Option}:
gnu
-@item @emph{Type}:
+@item @emph{Class}:
elemental function
@item @emph{Syntax}:
@@ -933,7 +949,7 @@ elemental function
@item @emph{Arguments}:
@multitable @columnfractions .15 .80
-@item @var{X} @tab The type shall be an @code{REAL(*)}, and it shall be scalar.
+@item @var{X} @tab The type shall be @code{REAL(*)}, and it shall be scalar.
@end multitable
@item @emph{Return value}:
@@ -971,7 +987,7 @@ of @var{X}.
@item @emph{Option}:
gnu
-@item @emph{Type}:
+@item @emph{Class}:
elemental function
@item @emph{Syntax}:
@@ -979,7 +995,7 @@ elemental function
@item @emph{Arguments}:
@multitable @columnfractions .15 .80
-@item @var{X} @tab The type shall be an @code{REAL(*)}, and it shall be scalar.
+@item @var{X} @tab The type shall be @code{REAL(*)}, and it shall be scalar.
@end multitable
@item @emph{Return value}:
@@ -1017,7 +1033,7 @@ end program test_besj1
@item @emph{Option}:
gnu
-@item @emph{Type}:
+@item @emph{Class}:
elemental function
@item @emph{Syntax}:
@@ -1025,8 +1041,8 @@ elemental function
@item @emph{Arguments}:
@multitable @columnfractions .15 .80
-@item @var{N} @tab The type shall be an @code{INTEGER(*)}, and it shall be scalar.
-@item @var{X} @tab The type shall be an @code{REAL(*)}, and it shall be scalar.
+@item @var{N} @tab The type shall be @code{INTEGER(*)}, and it shall be scalar.
+@item @var{X} @tab The type shall be @code{REAL(*)}, and it shall be scalar.
@end multitable
@item @emph{Return value}:
@@ -1064,7 +1080,7 @@ of @var{X}.
@item @emph{Option}:
gnu
-@item @emph{Type}:
+@item @emph{Class}:
elemental function
@item @emph{Syntax}:
@@ -1072,7 +1088,7 @@ elemental function
@item @emph{Arguments}:
@multitable @columnfractions .15 .80
-@item @var{X} @tab The type shall be an @code{REAL(*)}, and it shall be scalar.
+@item @var{X} @tab The type shall be @code{REAL(*)}, and it shall be scalar.
@end multitable
@item @emph{Return value}:
@@ -1109,7 +1125,7 @@ of @var{X}.
@item @emph{Option}:
gnu
-@item @emph{Type}:
+@item @emph{Class}:
elemental function
@item @emph{Syntax}:
@@ -1117,7 +1133,7 @@ elemental function
@item @emph{Arguments}:
@multitable @columnfractions .15 .80
-@item @var{X} @tab The type shall be an @code{REAL(*)}, and it shall be scalar.
+@item @var{X} @tab The type shall be @code{REAL(*)}, and it shall be scalar.
@end multitable
@item @emph{Return value}:
@@ -1154,7 +1170,7 @@ end program test_besy1
@item @emph{Option}:
gnu
-@item @emph{Type}:
+@item @emph{Class}:
elemental function
@item @emph{Syntax}:
@@ -1162,8 +1178,8 @@ elemental function
@item @emph{Arguments}:
@multitable @columnfractions .15 .80
-@item @var{N} @tab The type shall be an @code{INTEGER(*)}, and it shall be scalar.
-@item @var{X} @tab The type shall be an @code{REAL(*)}, and it shall be scalar.
+@item @var{N} @tab The type shall be @code{INTEGER(*)}, and it shall be scalar.
+@item @var{X} @tab The type shall be @code{REAL(*)}, and it shall be scalar.
@end multitable
@item @emph{Return value}:
@@ -1186,6 +1202,214 @@ end program test_besyn
@end table
+
+@node BIT_SIZE
+@section @code{BIT_SIZE} --- Bit size inquiry function
+@findex @code{BIT_SIZE} intrinsic
+@cindex bit_size
+
+@table @asis
+@item @emph{Description}:
+@code{BIT_SIZE(I)} returns the number of bits (integer precision plus sign bit) represented by the type of @var{I}.
+
+@item @emph{Option}:
+f95, gnu
+
+@item @emph{Class}:
+elemental function
+
+@item @emph{Syntax}:
+@code{I = BIT_SIZE(I)}
+
+@item @emph{Arguments}:
+@multitable @columnfractions .15 .80
+@item @var{I} @tab The type shall be @code{INTEGER(*)}.
+@end multitable
+
+@item @emph{Return value}:
+The return value is of type @code{INTEGER(*)}
+
+@item @emph{Example}:
+@smallexample
+program test_bit_size
+ integer :: i = 123
+ integer :: size
+ size = bit_size(i)
+ print *, size
+end program test_bit_size
+@end smallexample
+@end table
+
+
+
+@node BTEST
+@section @code{BTEST} --- Bit test function
+@findex @code{BTEST} intrinsic
+@cindex BTEST
+
+@table @asis
+@item @emph{Description}:
+@code{BTEST(I,POS)} returns logical .TRUE. if the bit at @var{POS} in @var{I} is set.
+
+@item @emph{Option}:
+f95, gnu
+
+@item @emph{Class}:
+elemental function
+
+@item @emph{Syntax}:
+@code{I = BTEST(I,POS)}
+
+@item @emph{Arguments}:
+@multitable @columnfractions .15 .80
+@item @var{I} @tab The type shall be @code{INTEGER(*)}.
+@item @var{POS} @tab The type shall be @code{INTEGER(*)}.
+@end multitable
+
+@item @emph{Return value}:
+The return value is of type @code{LOGICAL}
+
+@item @emph{Example}:
+@smallexample
+program test_btest
+ integer :: i = 32768 + 1024 + 64
+ integer :: pos
+ logical :: bool
+ do pos=0,16
+ bool = btest(i, pos)
+ print *, pos, bool
+ end do
+end program test_btest
+@end smallexample
+@end table
+
+
+
+@node CEILING
+@section @code{CEILING} --- Integer ceiling function
+@findex @code{CEILING} intrinsic
+@cindex CEILING
+
+@table @asis
+@item @emph{Description}:
+@code{CEILING(X,[KIND])} returns the least integer greater than or equal to @var{X}.
+
+@item @emph{Option}:
+f95, gnu
+
+@item @emph{Class}:
+elemental function
+
+@item @emph{Syntax}:
+@code{X = CEILING(X)}
+
+@item @emph{Arguments}:
+@multitable @columnfractions .15 .80
+@item @var{X} @tab The type shall be @code{REAL(*)}.
+@item @var{KIND} @tab Optional scaler integer initialization expression.
+@end multitable
+
+@item @emph{Return value}:
+The return value is of type @code{INTEGER(KIND)}
+
+@item @emph{Example}:
+@smallexample
+program test_ceiling
+ real :: x = 63.29
+ real :: y = -63.59
+ print *, ceiling(x) ! returns 64
+ print *, ceiling(y) ! returns -63
+end program test_ceiling
+@end smallexample
+@end table
+
+
+
+@node CHAR
+@section @code{CHAR} --- Character conversion function
+@findex @code{CHAR} intrinsic
+@cindex CHAR
+
+@table @asis
+@item @emph{Description}:
+@code{CHAR(I,[KIND])} returns the character represented by the integer @var{I}.
+
+@item @emph{Option}:
+f95, gnu
+
+@item @emph{Class}:
+elemental function
+
+@item @emph{Syntax}:
+@code{C = CHAR(I)}
+
+@item @emph{Arguments}:
+@multitable @columnfractions .15 .80
+@item @var{I} @tab The type shall be @code{INTEGER(*)}.
+@item @var{KIND} @tab Optional scaler integer initialization expression.
+@end multitable
+
+@item @emph{Return value}:
+The return value is of type @code{CHARACTER(1)}
+
+@item @emph{Example}:
+@smallexample
+program test_char
+ integer :: i = 74
+ character(1) :: c
+ c = char(i)
+ print *, i, c ! returns 'J'
+end program test_char
+@end smallexample
+@end table
+
+
+
+@node CMPLX
+@section @code{CMPLX} --- Complex conversion function
+@findex @code{CMPLX} intrinsic
+@cindex CMPLX
+
+@table @asis
+@item @emph{Description}:
+@code{CMPLX(X,[Y,KIND])} returns a complex number where @var{X} is converted to the real component. If @var{Y} is present it is converted to the imaginary component. If @var{Y} is not present then the imaginary component is set to
+0.0. If @var{X} is complex then @var{Y} must not be present.
+
+@item @emph{Option}:
+f95, gnu
+
+@item @emph{Class}:
+elemental function
+
+@item @emph{Syntax}:
+@code{C = CMPLX(X)}
+@code{C = CMPLX(X,Y)}
+@code{C = CMPLX(X,Y,KIND)}
+
+@item @emph{Arguments}:
+@multitable @columnfractions .15 .80
+@item @var{X} @tab The type may be @code{INTEGER(*)} or @code{REAL(*)} or @code{COMPLEX(*)}.
+@item @var{Y} @tab Optional, allowed if @var{X} is not @code{COMPLEX(*)}. May be @code{INTEGER(*)} or @code{REAL(*)}.
+@item @var{KIND} @tab Optional scaler integer initialization expression.
+@end multitable
+
+@item @emph{Return value}:
+The return value is of type @code{COMPLEX(*)}
+
+@item @emph{Example}:
+@smallexample
+program test_cmplx
+ integer :: i = 42
+ real :: x = 3.14
+ complex :: z
+ z = cmplx(i, x)
+ print *, z, cmplx(x)
+end program test_cmplx
+@end smallexample
+@end table
+
+
+
@node COS
@section @code{COS} --- Cosine function
@findex @code{COS} intrinsic
@@ -1201,7 +1425,7 @@ end program test_besyn
@item @emph{Option}:
f95, gnu
-@item @emph{Type}:
+@item @emph{Class}:
elemental function
@item @emph{Syntax}:
@@ -1209,7 +1433,7 @@ elemental function
@item @emph{Arguments}:
@multitable @columnfractions .15 .80
-@item @var{X} @tab The type shall be an @code{REAL(*)} or
+@item @var{X} @tab The type shall be @code{REAL(*)} or
@code{COMPLEX(*)}.
@end multitable
@@ -1235,6 +1459,7 @@ end program test_cos
@end table
+
@node COSH
@section @code{COSH} --- Hyperbolic cosine function
@findex @code{COSH} intrinsic
@@ -1248,7 +1473,7 @@ end program test_cos
@item @emph{Option}:
f95, gnu
-@item @emph{Type}:
+@item @emph{Class}:
elemental function
@item @emph{Syntax}:
@@ -1256,7 +1481,7 @@ elemental function
@item @emph{Arguments}:
@multitable @columnfractions .15 .80
-@item @var{X} @tab The type shall be an @code{REAL(*)}.
+@item @var{X} @tab The type shall be @code{REAL(*)}.
@end multitable
@item @emph{Return value}:
@@ -1279,6 +1504,7 @@ end program test_cosh
@end table
+
@node ERF
@section @code{ERF} --- Error function
@findex @code{ERF} intrinsic
@@ -1291,7 +1517,7 @@ end program test_cosh
@item @emph{Option}:
gnu
-@item @emph{Type}:
+@item @emph{Class}:
elemental function
@item @emph{Syntax}:
@@ -1299,7 +1525,7 @@ elemental function
@item @emph{Arguments}:
@multitable @columnfractions .15 .80
-@item @var{X} @tab The type shall be an @code{REAL(*)}, and it shall be scalar.
+@item @var{X} @tab The type shall be @code{REAL(*)}, and it shall be scalar.
@end multitable
@item @emph{Return value}:
@@ -1335,7 +1561,7 @@ end program test_erf
@item @emph{Option}:
gnu
-@item @emph{Type}:
+@item @emph{Class}:
elemental function
@item @emph{Syntax}:
@@ -1343,7 +1569,7 @@ elemental function
@item @emph{Arguments}:
@multitable @columnfractions .15 .80
-@item @var{X} @tab The type shall be an @code{REAL(*)}, and it shall be scalar.
+@item @var{X} @tab The type shall be @code{REAL(*)}, and it shall be scalar.
@end multitable
@item @emph{Return value}:
@@ -1382,7 +1608,7 @@ end program test_erfc
@item @emph{Option}:
f95, gnu
-@item @emph{Type}:
+@item @emph{Class}:
elemental function
@item @emph{Syntax}:
@@ -1390,12 +1616,12 @@ elemental function
@item @emph{Arguments}:
@multitable @columnfractions .15 .80
-@item @var{X} @tab The type shall be an @code{REAL(*)} or
+@item @var{X} @tab The type shall be @code{REAL(*)} or
@code{COMPLEX(*)}.
@end multitable
@item @emph{Return value}:
-The return value has same type and kind than @var{X}.
+The return value has same type and kind as @var{X}.
@item @emph{Example}:
@smallexample
@@ -1416,6 +1642,7 @@ end program test_exp
@end table
+
@node LOG
@section @code{LOG} --- Logarithm function
@findex @code{LOG} intrinsic
@@ -1433,7 +1660,7 @@ end program test_exp
@item @emph{Option}:
f95, gnu
-@item @emph{Type}:
+@item @emph{Class}:
elemental function
@item @emph{Syntax}:
@@ -1441,7 +1668,7 @@ elemental function
@item @emph{Arguments}:
@multitable @columnfractions .15 .80
-@item @var{X} @tab The type shall be an @code{REAL(*)} or
+@item @var{X} @tab The type shall be @code{REAL(*)} or
@code{COMPLEX(*)}.
@end multitable
@@ -1486,7 +1713,7 @@ end program test_log
@item @emph{Option}:
f95, gnu
-@item @emph{Type}:
+@item @emph{Class}:
elemental function
@item @emph{Syntax}:
@@ -1494,7 +1721,7 @@ elemental function
@item @emph{Arguments}:
@multitable @columnfractions .15 .80
-@item @var{X} @tab The type shall be an @code{REAL(*)} or
+@item @var{X} @tab The type shall be @code{REAL(*)} or
@code{COMPLEX(*)}.
@end multitable
@@ -1535,7 +1762,7 @@ end program test_log10
@item @emph{Option}:
f95, gnu
-@item @emph{Type}:
+@item @emph{Class}:
elemental function
@item @emph{Syntax}:
@@ -1543,7 +1770,7 @@ elemental function
@item @emph{Arguments}:
@multitable @columnfractions .15 .80
-@item @var{X} @tab The type shall be an @code{REAL(*)} or
+@item @var{X} @tab The type shall be @code{REAL(*)} or
@code{COMPLEX(*)}.
@end multitable
@@ -1570,7 +1797,6 @@ end program test_sin
-
@node SINH
@section @code{SINH} --- Hyperbolic sine function
@findex @code{SINH} intrinsic
@@ -1584,7 +1810,7 @@ end program test_sin
@item @emph{Option}:
f95, gnu
-@item @emph{Type}:
+@item @emph{Class}:
elemental function
@item @emph{Syntax}:
@@ -1592,7 +1818,7 @@ elemental function
@item @emph{Arguments}:
@multitable @columnfractions .15 .80
-@item @var{X} @tab The type shall be an @code{REAL(*)}.
+@item @var{X} @tab The type shall be @code{REAL(*)}.
@end multitable
@item @emph{Return value}:
@@ -1631,7 +1857,7 @@ end program test_sinh
@item @emph{Option}:
f95, gnu
-@item @emph{Type}:
+@item @emph{Class}:
elemental function
@item @emph{Syntax}:
@@ -1639,7 +1865,7 @@ elemental function
@item @emph{Arguments}:
@multitable @columnfractions .15 .80
-@item @var{X} @tab The type shall be an @code{REAL(*)} or
+@item @var{X} @tab The type shall be @code{REAL(*)} or
@code{COMPLEX(*)}.
@end multitable
@@ -1682,7 +1908,7 @@ end program test_sqrt
@item @emph{Option}:
f95, gnu
-@item @emph{Type}:
+@item @emph{Class}:
elemental function
@item @emph{Syntax}:
@@ -1690,7 +1916,7 @@ elemental function
@item @emph{Arguments}:
@multitable @columnfractions .15 .80
-@item @var{X} @tab The type shall be an @code{REAL(*)}.
+@item @var{X} @tab The type shall be @code{REAL(*)}.
@end multitable
@item @emph{Return value}:
@@ -1713,6 +1939,7 @@ end program test_tan
@end table
+
@node TANH
@section @code{TANH} --- Hyperbolic tangent function
@findex @code{TANH} intrinsic
@@ -1726,7 +1953,7 @@ end program test_tan
@item @emph{Option}:
f95, gnu
-@item @emph{Type}:
+@item @emph{Class}:
elemental function
@item @emph{Syntax}:
@@ -1734,7 +1961,7 @@ elemental function
@item @emph{Arguments}:
@multitable @columnfractions .15 .80
-@item @var{X} @tab The type shall be an @code{REAL(*)}.
+@item @var{X} @tab The type shall be @code{REAL(*)}.
@end multitable
@item @emph{Return value}:
@@ -1758,18 +1985,6 @@ end program test_tanh
-
-
-@comment gen bit_size
-@comment
-@comment gen btest
-@comment
-@comment gen ceiling
-@comment
-@comment gen char
-@comment
-@comment gen cmplx
-@comment
@comment gen command_argument_count
@comment
@comment gen conjg
diff --git a/gcc/fortran/invoke.texi b/gcc/fortran/invoke.texi
index 996556fb5bc..098882ecbe3 100644
--- a/gcc/fortran/invoke.texi
+++ b/gcc/fortran/invoke.texi
@@ -248,7 +248,7 @@ Specify that no implicit typing is allowed, unless overridden by explicit
@cindex option, -std=@var{std}
@item -std=@var{std}
Conform to the specified standard. Allowed values for @var{std} are
-@samp{gnu} and @samp{f95}.
+@samp{gnu}, @samp{f95}, @samp{f2003} and @samp{legacy}.
@end table
diff --git a/gcc/fortran/io.c b/gcc/fortran/io.c
index 8dab5f59afd..34619ab27df 100644
--- a/gcc/fortran/io.c
+++ b/gcc/fortran/io.c
@@ -491,9 +491,13 @@ format_item_1:
case FMT_DOLLAR:
t = format_lex ();
+
+ if (gfc_notify_std (GFC_STD_GNU, "Extension: $ descriptor at %C")
+ == FAILURE)
+ return FAILURE;
if (t != FMT_RPAREN || level > 0)
{
- error = "$ must the last specifier";
+ error = "$ must be the last specifier";
goto syntax;
}
@@ -970,8 +974,9 @@ resolve_tag (const io_tag * tag, gfc_expr * e)
/* Format label can be integer varibale. */
if (tag != &tag_format || e->ts.type != BT_INTEGER)
{
- gfc_error ("%s tag at %L must be of type %s", tag->name, &e->where,
- gfc_basic_typename (tag->type));
+ gfc_error ("%s tag at %L must be of type %s or %s", tag->name,
+ &e->where, gfc_basic_typename (tag->type),
+ gfc_basic_typename (BT_INTEGER));
return FAILURE;
}
}
@@ -2359,6 +2364,7 @@ gfc_match_inquire (void)
gfc_inquire *inquire;
gfc_code *code;
match m;
+ locus loc;
m = gfc_match_char ('(');
if (m == MATCH_NO)
@@ -2366,6 +2372,8 @@ gfc_match_inquire (void)
inquire = gfc_getmem (sizeof (gfc_inquire));
+ loc = gfc_current_locus;
+
m = match_inquire_element (inquire);
if (m == MATCH_ERROR)
goto cleanup;
@@ -2431,6 +2439,20 @@ gfc_match_inquire (void)
if (gfc_match_eos () != MATCH_YES)
goto syntax;
+ if (inquire->unit != NULL && inquire->file != NULL)
+ {
+ gfc_error ("INQUIRE statement at %L cannot contain both FILE and"
+ " UNIT specifiers", &loc);
+ goto cleanup;
+ }
+
+ if (inquire->unit == NULL && inquire->file == NULL)
+ {
+ gfc_error ("INQUIRE statement at %L requires either FILE or"
+ " UNIT specifier", &loc);
+ goto cleanup;
+ }
+
if (gfc_pure (NULL))
{
gfc_error ("INQUIRE statement not allowed in PURE procedure at %C");
diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt
index d1ca5f02ebd..6798b6d4f14 100644
--- a/gcc/fortran/lang.opt
+++ b/gcc/fortran/lang.opt
@@ -161,4 +161,8 @@ std=gnu
F95
Conform nothing in particular.
+std=legacy
+F95
+Accept extensions to support legacy code.
+
; This comment is to ensure we retain the blank line above.
diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c
index 2603caa67a8..347f7068b96 100644
--- a/gcc/fortran/options.c
+++ b/gcc/fortran/options.c
@@ -77,9 +77,10 @@ gfc_init_options (unsigned int argc ATTRIBUTE_UNUSED,
flag_errno_math = 0;
gfc_option.allow_std = GFC_STD_F95_OBS | GFC_STD_F95_DEL
- | GFC_STD_F2003 | GFC_STD_F95 | GFC_STD_F77 | GFC_STD_GNU;
+ | GFC_STD_F2003 | GFC_STD_F95 | GFC_STD_F77 | GFC_STD_GNU
+ | GFC_STD_LEGACY;
gfc_option.warn_std = GFC_STD_F95_OBS | GFC_STD_F95_DEL
- | GFC_STD_F2003;
+ | GFC_STD_F2003 | GFC_STD_LEGACY;
gfc_option.warn_nonstd_intrinsics = 0;
@@ -113,6 +114,9 @@ gfc_post_options (const char **pfilename)
/* If -pedantic, warn about the use of GNU extensions. */
if (pedantic && (gfc_option.allow_std & GFC_STD_GNU) != 0)
gfc_option.warn_std |= GFC_STD_GNU;
+ /* -std=legacy -pedantic is effectively -std=gnu. */
+ if (pedantic && (gfc_option.allow_std & GFC_STD_LEGACY) != 0)
+ gfc_option.warn_std |= GFC_STD_F95_OBS | GFC_STD_F95_DEL | GFC_STD_LEGACY;
/* If the user didn't explicitly specify -f(no)-second-underscore we
use it if we're trying to be compatible with f2c, and not
@@ -333,8 +337,16 @@ gfc_handle_option (size_t scode, const char *arg, int value)
case OPT_std_gnu:
gfc_option.allow_std = GFC_STD_F95_OBS | GFC_STD_F95_DEL
| GFC_STD_F77 | GFC_STD_F95 | GFC_STD_F2003
- | GFC_STD_GNU;
- gfc_option.warn_std = GFC_STD_F95_OBS | GFC_STD_F95_DEL;
+ | GFC_STD_GNU | GFC_STD_LEGACY;
+ gfc_option.warn_std = GFC_STD_F95_OBS | GFC_STD_F95_DEL
+ | GFC_STD_LEGACY;
+ break;
+
+ case OPT_std_legacy:
+ gfc_option.allow_std = GFC_STD_F95_OBS | GFC_STD_F95_DEL
+ | GFC_STD_F77 | GFC_STD_F95 | GFC_STD_F2003
+ | GFC_STD_GNU | GFC_STD_LEGACY;
+ gfc_option.warn_std = 0;
break;
case OPT_Wnonstd_intrinsics:
diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c
index 94bf6d0d28d..13b815ad62e 100644
--- a/gcc/fortran/parse.c
+++ b/gcc/fortran/parse.c
@@ -2157,7 +2157,7 @@ gfc_fixup_sibling_symbols (gfc_symbol * sym, gfc_namespace * siblings)
gfc_free_symbol (old_sym);
}
- /* Do the same for any contined procedures. */
+ /* Do the same for any contained procedures. */
gfc_fixup_sibling_symbols (sym, ns->contained);
}
}
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index 5f7a76a57a4..f0367acea3d 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -267,9 +267,12 @@ resolve_contained_fntype (gfc_symbol * sym, gfc_namespace * ns)
{
t = gfc_set_default_type (sym, 0, ns);
- if (t == FAILURE)
- gfc_error ("Contained function '%s' at %L has no IMPLICIT type",
- sym->name, &sym->declared_at); /* FIXME */
+ if (t == FAILURE && !sym->attr.untyped)
+ {
+ gfc_error ("Contained function '%s' at %L has no IMPLICIT type",
+ sym->name, &sym->declared_at); /* FIXME */
+ sym->attr.untyped = 1;
+ }
}
}
@@ -439,6 +442,10 @@ resolve_entries (gfc_namespace * ns)
if (ts->kind == gfc_default_logical_kind)
sym = NULL;
break;
+ case BT_UNKNOWN:
+ /* We will issue error elsewhere. */
+ sym = NULL;
+ break;
default:
break;
}
@@ -957,7 +964,7 @@ set_type:
if (ts->type == BT_UNKNOWN)
{
- gfc_error ("Function '%s' at %L has no implicit type",
+ gfc_error ("Function '%s' at %L has no IMPLICIT type",
sym->name, &expr->where);
return FAILURE;
}
@@ -4810,8 +4817,51 @@ resolve_equivalence (gfc_equiv *eq)
}
}
}
-
-
+
+
+/* Resolve function and ENTRY types, issue diagnostics if needed. */
+
+static void
+resolve_fntype (gfc_namespace * ns)
+{
+ gfc_entry_list *el;
+ gfc_symbol *sym;
+
+ if (ns->proc_name == NULL || !ns->proc_name->attr.function)
+ return;
+
+ /* If there are any entries, ns->proc_name is the entry master
+ synthetic symbol and ns->entries->sym actual FUNCTION symbol. */
+ if (ns->entries)
+ sym = ns->entries->sym;
+ else
+ sym = ns->proc_name;
+ if (sym->result == sym
+ && sym->ts.type == BT_UNKNOWN
+ && gfc_set_default_type (sym, 0, NULL) == FAILURE
+ && !sym->attr.untyped)
+ {
+ gfc_error ("Function '%s' at %L has no IMPLICIT type",
+ sym->name, &sym->declared_at);
+ sym->attr.untyped = 1;
+ }
+
+ if (ns->entries)
+ for (el = ns->entries->next; el; el = el->next)
+ {
+ if (el->sym->result == el->sym
+ && el->sym->ts.type == BT_UNKNOWN
+ && gfc_set_default_type (el->sym, 0, NULL) == FAILURE
+ && !el->sym->attr.untyped)
+ {
+ gfc_error ("ENTRY '%s' at %L has no IMPLICIT type",
+ el->sym->name, &el->sym->declared_at);
+ el->sym->attr.untyped = 1;
+ }
+ }
+}
+
+
/* This function is called after a complete program unit has been compiled.
Its purpose is to examine all of the expressions associated with a program
unit, assign types to all intermediate expressions, make sure that all
@@ -4835,6 +4885,8 @@ gfc_resolve (gfc_namespace * ns)
gfc_traverse_ns (ns, resolve_symbol);
+ resolve_fntype (ns);
+
for (n = ns->contained; n; n = n->sibling)
{
if (gfc_pure (ns->proc_name) && !gfc_pure (n->proc_name))
diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c
index fa6c2c6aa7c..6797bcad9fa 100644
--- a/gcc/fortran/simplify.c
+++ b/gcc/fortran/simplify.c
@@ -3659,6 +3659,9 @@ gfc_convert_constant (gfc_expr * e, bt type, int kind)
case BT_COMPLEX:
f = gfc_int2complex;
break;
+ case BT_LOGICAL:
+ f = gfc_int2log;
+ break;
default:
goto oops;
}
@@ -3700,9 +3703,17 @@ gfc_convert_constant (gfc_expr * e, bt type, int kind)
break;
case BT_LOGICAL:
- if (type != BT_LOGICAL)
- goto oops;
- f = gfc_log2log;
+ switch (type)
+ {
+ case BT_INTEGER:
+ f = gfc_log2int;
+ break;
+ case BT_LOGICAL:
+ f = gfc_log2log;
+ break;
+ default:
+ goto oops;
+ }
break;
default:
diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c
index 87e37ea6308..fabbef99dc9 100644
--- a/gcc/fortran/trans-array.c
+++ b/gcc/fortran/trans-array.c
@@ -2342,7 +2342,7 @@ gfc_conv_resolve_dependencies (gfc_loopinfo * loop, gfc_ss * dest,
loop->temp_ss->type = GFC_SS_TEMP;
loop->temp_ss->data.temp.type =
gfc_get_element_type (TREE_TYPE (dest->data.info.descriptor));
- loop->temp_ss->string_length = NULL_TREE;
+ loop->temp_ss->string_length = dest->string_length;
loop->temp_ss->data.temp.dimen = loop->dimen;
loop->temp_ss->next = gfc_ss_terminator;
gfc_add_ss_to_loop (loop, loop->temp_ss);
@@ -3616,11 +3616,23 @@ gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss)
loop.temp_ss = gfc_get_ss ();
loop.temp_ss->type = GFC_SS_TEMP;
loop.temp_ss->next = gfc_ss_terminator;
- loop.temp_ss->data.temp.type = gfc_typenode_for_spec (&expr->ts);
+ if (expr->ts.type == BT_CHARACTER)
+ {
+ gcc_assert (expr->ts.cl && expr->ts.cl->length
+ && expr->ts.cl->length->expr_type == EXPR_CONSTANT);
+ loop.temp_ss->string_length = gfc_conv_mpz_to_tree
+ (expr->ts.cl->length->value.integer,
+ expr->ts.cl->length->ts.kind);
+ expr->ts.cl->backend_decl = loop.temp_ss->string_length;
+ }
+ loop.temp_ss->data.temp.type = gfc_typenode_for_spec (&expr->ts);
+
/* ... which can hold our string, if present. */
if (expr->ts.type == BT_CHARACTER)
- se->string_length = loop.temp_ss->string_length
- = TYPE_SIZE_UNIT (loop.temp_ss->data.temp.type);
+ {
+ loop.temp_ss->string_length = TYPE_SIZE_UNIT (loop.temp_ss->data.temp.type);
+ se->string_length = loop.temp_ss->string_length;
+ }
else
loop.temp_ss->string_length = NULL;
loop.temp_ss->data.temp.dimen = loop.dimen;
@@ -3652,7 +3664,13 @@ gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss)
rse.ss = ss;
gfc_conv_scalarized_array_ref (&lse, NULL);
- gfc_conv_expr_val (&rse, expr);
+ if (expr->ts.type == BT_CHARACTER)
+ {
+ gfc_conv_expr (&rse, expr);
+ rse.expr = gfc_build_indirect_ref (rse.expr);
+ }
+ else
+ gfc_conv_expr_val (&rse, expr);
gfc_add_block_to_block (&block, &rse.pre);
gfc_add_block_to_block (&block, &lse.pre);
@@ -4000,7 +4018,8 @@ gfc_trans_deferred_array (gfc_symbol * sym, tree body)
deallocate = gfc_array_deallocate (descriptor);
tmp = gfc_conv_descriptor_data (descriptor);
- tmp = build2 (NE_EXPR, boolean_type_node, tmp, integer_zero_node);
+ tmp = build2 (NE_EXPR, boolean_type_node, tmp,
+ build_int_cst (TREE_TYPE (tmp), 0));
tmp = build3_v (COND_EXPR, tmp, deallocate, build_empty_stmt ());
gfc_add_expr_to_block (&block, tmp);
@@ -4349,7 +4368,7 @@ gfc_walk_array_constructor (gfc_ss * ss, gfc_expr * expr)
/* Walk an expression. Add walked expressions to the head of the SS chain.
- A wholy scalar expression will not be added. */
+ A wholly scalar expression will not be added. */
static gfc_ss *
gfc_walk_subexpr (gfc_ss * ss, gfc_expr * expr)
diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index 3d89effb7c2..9b2b669a5b2 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -32,7 +32,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "tm.h"
#include "target.h"
#include "function.h"
-#include "errors.h"
#include "flags.h"
#include "cgraph.h"
#include "gfortran.h"
@@ -537,7 +536,7 @@ gfc_build_qualified_array (tree decl, gfc_symbol * sym)
{
if (GFC_TYPE_ARRAY_LBOUND (type, dim) == NULL_TREE)
GFC_TYPE_ARRAY_LBOUND (type, dim) = create_index_var ("lbound", nest);
- /* Don't try to use the unkown bound for assumed shape arrays. */
+ /* Don't try to use the unknown bound for assumed shape arrays. */
if (GFC_TYPE_ARRAY_UBOUND (type, dim) == NULL_TREE
&& (sym->as->type != AS_ASSUMED_SIZE
|| dim < GFC_TYPE_ARRAY_RANK (type) - 1))
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index 52a532d2408..52d37039753 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -281,7 +281,7 @@ gfc_conv_component_ref (gfc_se * se, gfc_ref * ref)
se->string_length = tmp;
}
- if (c->pointer && c->dimension == 0)
+ if (c->pointer && c->dimension == 0 && c->ts.type != BT_CHARACTER)
se->expr = gfc_build_indirect_ref (se->expr);
}
@@ -356,27 +356,41 @@ gfc_conv_variable (gfc_se * se, gfc_expr * expr)
return;
}
- /* Dereference scalar dummy variables. */
- if (sym->attr.dummy
- && sym->ts.type != BT_CHARACTER
- && !sym->attr.dimension)
- se->expr = gfc_build_indirect_ref (se->expr);
-
- /* Dereference scalar hidden result. */
- if (gfc_option.flag_f2c
- && (sym->attr.function || sym->attr.result)
- && sym->ts.type == BT_COMPLEX
- && !sym->attr.dimension)
- se->expr = gfc_build_indirect_ref (se->expr);
-
- /* Dereference pointer variables. */
- if ((sym->attr.pointer || sym->attr.allocatable)
- && (sym->attr.dummy
- || sym->attr.result
- || sym->attr.function
- || !sym->attr.dimension)
- && sym->ts.type != BT_CHARACTER)
- se->expr = gfc_build_indirect_ref (se->expr);
+
+ /* Dereference the expression, where needed. Since characters
+ are entirely different from other types, they are treated
+ separately. */
+ if (sym->ts.type == BT_CHARACTER)
+ {
+ /* Dereference character pointer dummy arguments
+ or results. */
+ if ((sym->attr.pointer || sym->attr.allocatable)
+ && (sym->attr.dummy
+ || sym->attr.function
+ || sym->attr.result))
+ se->expr = gfc_build_indirect_ref (se->expr);
+ }
+ else
+ {
+ /* Dereference non-character scalar dummy arguments. */
+ if (sym->attr.dummy && !sym->attr.dimension)
+ se->expr = gfc_build_indirect_ref (se->expr);
+
+ /* Dereference scalar hidden result. */
+ if (gfc_option.flag_f2c && sym->ts.type == BT_COMPLEX
+ && (sym->attr.function || sym->attr.result)
+ && !sym->attr.dimension)
+ se->expr = gfc_build_indirect_ref (se->expr);
+
+ /* Dereference non-character pointer variables.
+ These must be dummies, results, or scalars. */
+ if ((sym->attr.pointer || sym->attr.allocatable)
+ && (sym->attr.dummy
+ || sym->attr.function
+ || sym->attr.result
+ || !sym->attr.dimension))
+ se->expr = gfc_build_indirect_ref (se->expr);
+ }
ref = expr->ref;
}
@@ -1083,6 +1097,15 @@ gfc_conv_function_call (gfc_se * se, gfc_symbol * sym,
var = NULL_TREE;
len = NULL_TREE;
+ /* Obtain the string length now because it is needed often below. */
+ if (sym->ts.type == BT_CHARACTER)
+ {
+ gcc_assert (sym->ts.cl && sym->ts.cl->length
+ && sym->ts.cl->length->expr_type == EXPR_CONSTANT);
+ len = gfc_conv_mpz_to_tree
+ (sym->ts.cl->length->value.integer, sym->ts.cl->length->ts.kind);
+ }
+
if (se->ss != NULL)
{
if (!sym->attr.elemental)
@@ -1097,6 +1120,9 @@ gfc_conv_function_call (gfc_se * se, gfc_symbol * sym,
/* Access the previously obtained result. */
gfc_conv_tmp_array_ref (se);
gfc_advance_se_ss_chain (se);
+
+ /* Bundle in the string length. */
+ se->string_length = len;
return;
}
}
@@ -1108,14 +1134,26 @@ gfc_conv_function_call (gfc_se * se, gfc_symbol * sym,
byref = gfc_return_by_reference (sym);
if (byref)
{
- if (se->direct_byref)
- arglist = gfc_chainon_list (arglist, se->expr);
+ if (se->direct_byref)
+ {
+ arglist = gfc_chainon_list (arglist, se->expr);
+
+ /* Add string length to argument list. */
+ if (sym->ts.type == BT_CHARACTER)
+ {
+ sym->ts.cl->backend_decl = len;
+ arglist = gfc_chainon_list (arglist,
+ convert (gfc_charlen_type_node, len));
+ }
+ }
else if (sym->result->attr.dimension)
{
gcc_assert (se->loop && se->ss);
+
/* Set the type of the array. */
tmp = gfc_typenode_for_spec (&sym->ts);
info->dimen = se->loop->dimen;
+
/* Allocate a temporary to store the result. */
gfc_trans_allocate_temp_array (se->loop, info, tmp);
@@ -1124,22 +1162,46 @@ gfc_conv_function_call (gfc_se * se, gfc_symbol * sym,
gfc_conv_descriptor_stride (info->descriptor, gfc_rank_cst[0]);
gfc_add_modify_expr (&se->pre, tmp,
convert (TREE_TYPE (tmp), integer_zero_node));
+
/* Pass the temporary as the first argument. */
tmp = info->descriptor;
tmp = gfc_build_addr_expr (NULL, tmp);
arglist = gfc_chainon_list (arglist, tmp);
+
+ /* Add string length to argument list. */
+ if (sym->ts.type == BT_CHARACTER)
+ {
+ sym->ts.cl->backend_decl = len;
+ arglist = gfc_chainon_list (arglist,
+ convert (gfc_charlen_type_node, len));
+ }
+
}
else if (sym->ts.type == BT_CHARACTER)
{
- gcc_assert (sym->ts.cl && sym->ts.cl->length
- && sym->ts.cl->length->expr_type == EXPR_CONSTANT);
- len = gfc_conv_mpz_to_tree
- (sym->ts.cl->length->value.integer, sym->ts.cl->length->ts.kind);
+
+ /* Pass the string length. */
sym->ts.cl->backend_decl = len;
type = gfc_get_character_type (sym->ts.kind, sym->ts.cl);
type = build_pointer_type (type);
- var = gfc_conv_string_tmp (se, type, len);
+ /* Return an address to a char[0:len-1]* temporary for character pointers. */
+ if (sym->attr.pointer || sym->attr.allocatable)
+ {
+ /* Build char[0:len-1] * pstr. */
+ tmp = fold_build2 (MINUS_EXPR, gfc_charlen_type_node, len,
+ build_int_cst (gfc_charlen_type_node, 1));
+ tmp = build_range_type (gfc_array_index_type, gfc_index_zero_node, tmp);
+ tmp = build_array_type (gfc_character1_type_node, tmp);
+ var = gfc_create_var (build_pointer_type (tmp), "pstr");
+
+ /* Provide an address expression for the function arguments. */
+ var = gfc_build_addr_expr (NULL, var);
+ }
+ else
+ {
+ var = gfc_conv_string_tmp (se, type, len);
+ }
arglist = gfc_chainon_list (arglist, var);
arglist = gfc_chainon_list (arglist,
convert (gfc_charlen_type_node, len));
@@ -1205,8 +1267,8 @@ gfc_conv_function_call (gfc_se * se, gfc_symbol * sym,
&& arg->expr->expr_type != EXPR_NULL)
{
/* Scalar pointer dummy args require an extra level of
- indirection. The null pointer already contains
- this level of indirection. */
+ indirection. The null pointer already contains
+ this level of indirection. */
parmse.expr = gfc_build_addr_expr (NULL, parmse.expr);
}
}
@@ -1299,10 +1361,17 @@ gfc_conv_function_call (gfc_se * se, gfc_symbol * sym,
gfc_trans_runtime_check (tmp, gfc_strconst_fault, &se->pre);
}
se->expr = info->descriptor;
+ /* Bundle in the string length. */
+ se->string_length = len;
}
else if (sym->ts.type == BT_CHARACTER)
{
- se->expr = var;
+ /* Dereference for character pointer results. */
+ if (sym->attr.pointer || sym->attr.allocatable)
+ se->expr = gfc_build_indirect_ref (var);
+ else
+ se->expr = var;
+
se->string_length = len;
}
else
@@ -1603,6 +1672,9 @@ gfc_trans_subarray_assign (tree dest, gfc_component * cm, gfc_expr * expr)
gfc_start_scalarized_body (&loop, &body);
gfc_conv_tmp_array_ref (&lse);
+ if (cm->ts.type == BT_CHARACTER)
+ lse.string_length = cm->ts.cl->backend_decl;
+
gfc_conv_expr (&rse, expr);
tmp = gfc_trans_scalar_assign (&lse, &rse, cm->ts.type);
diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c
index 97f00dc441a..8a0cfe43422 100644
--- a/gcc/fortran/trans-intrinsic.c
+++ b/gcc/fortran/trans-intrinsic.c
@@ -158,7 +158,7 @@ gfc_conv_intrinsic_function_args (gfc_se * se, gfc_expr * expr)
args = NULL_TREE;
for (actual = expr->value.function.actual; actual; actual = actual->next)
{
- /* Skip ommitted optional arguments. */
+ /* Skip omitted optional arguments. */
if (!actual->expr)
continue;
diff --git a/gcc/fortran/trans-stmt.c b/gcc/fortran/trans-stmt.c
index d3e86dd9d9d..85f2660bf7c 100644
--- a/gcc/fortran/trans-stmt.c
+++ b/gcc/fortran/trans-stmt.c
@@ -2965,7 +2965,7 @@ gfc_trans_where_assign (gfc_expr *expr1, gfc_expr *expr2, tree mask,
/* Translate the WHERE construct or statement.
- This fuction can be called iteratively to translate the nested WHERE
+ This function can be called iteratively to translate the nested WHERE
construct or statement.
MASK is the control mask, and PMASK is the pending control mask.
TEMP records the temporary address which must be freed later. */
diff --git a/gcc/fortran/trans-types.c b/gcc/fortran/trans-types.c
index a70784cbf3c..1338297c3e8 100644
--- a/gcc/fortran/trans-types.c
+++ b/gcc/fortran/trans-types.c
@@ -1611,7 +1611,7 @@ gfc_get_function_type (gfc_symbol * sym)
The problem arises if a function is called via an implicit
prototype. In this situation the INTENT is not known.
For this reason all parameters to global functions must be
- passed by reference. Passing by value would potentialy
+ passed by reference. Passing by value would potentially
generate bad code. Worse there would be no way of telling that
this code was bad, except that it would give incorrect results.
diff --git a/gcc/fortran/trans.c b/gcc/fortran/trans.c
index 70630cbecab..c4ae36674de 100644
--- a/gcc/fortran/trans.c
+++ b/gcc/fortran/trans.c
@@ -314,7 +314,7 @@ gfc_build_array_ref (tree base, tree offset)
}
-/* Given a funcion declaration FNDECL and an argument list ARGLIST,
+/* Given a function declaration FNDECL and an argument list ARGLIST,
build a CALL_EXPR. */
tree
diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h
index d44c67d6d48..f3bcbaa386d 100644
--- a/gcc/fortran/trans.h
+++ b/gcc/fortran/trans.h
@@ -251,8 +251,8 @@ gfc_saved_var;
/* Advance the SS chain to the next term. */
void gfc_advance_se_ss_chain (gfc_se *);
-/* Call this to initialise a gfc_se structure before use
- first parameter is structure to initialise, second is
+/* Call this to initialize a gfc_se structure before use
+ first parameter is structure to initialize, second is
parent to get scalarization data from, or NULL. */
void gfc_init_se (gfc_se *, gfc_se *);
diff --git a/gcc/gcse.c b/gcc/gcse.c
index 39b18bf1469..d29a507d238 100644
--- a/gcc/gcse.c
+++ b/gcc/gcse.c
@@ -507,11 +507,11 @@ static int gcse_subst_count;
static int gcse_create_count;
/* Number of local constants propagated. */
static int local_const_prop_count;
-/* Number of local copys propagated. */
+/* Number of local copies propagated. */
static int local_copy_prop_count;
/* Number of global constants propagated. */
static int global_const_prop_count;
-/* Number of global copys propagated. */
+/* Number of global copies propagated. */
static int global_copy_prop_count;
/* For available exprs */
@@ -1370,6 +1370,11 @@ static int
load_killed_in_block_p (basic_block bb, int uid_limit, rtx x, int avail_p)
{
rtx list_entry = modify_mem_list[bb->index];
+
+ /* If this is a readonly then we aren't going to be changing it. */
+ if (MEM_READONLY_P (x))
+ return 0;
+
while (list_entry)
{
rtx setter;
@@ -2462,51 +2467,53 @@ compute_transp (rtx x, int indx, sbitmap *bmap, int set_p)
return;
case MEM:
- {
- bitmap_iterator bi;
- unsigned bb_index;
-
- /* First handle all the blocks with calls. We don't need to
- do any list walking for them. */
- EXECUTE_IF_SET_IN_BITMAP (blocks_with_calls, 0, bb_index, bi)
- {
- if (set_p)
- SET_BIT (bmap[bb_index], indx);
- else
- RESET_BIT (bmap[bb_index], indx);
- }
+ if (! MEM_READONLY_P (x))
+ {
+ bitmap_iterator bi;
+ unsigned bb_index;
- /* Now iterate over the blocks which have memory modifications
- but which do not have any calls. */
- EXECUTE_IF_AND_COMPL_IN_BITMAP (modify_mem_list_set, blocks_with_calls,
- 0, bb_index, bi)
- {
- rtx list_entry = canon_modify_mem_list[bb_index];
+ /* First handle all the blocks with calls. We don't need to
+ do any list walking for them. */
+ EXECUTE_IF_SET_IN_BITMAP (blocks_with_calls, 0, bb_index, bi)
+ {
+ if (set_p)
+ SET_BIT (bmap[bb_index], indx);
+ else
+ RESET_BIT (bmap[bb_index], indx);
+ }
- while (list_entry)
+ /* Now iterate over the blocks which have memory modifications
+ but which do not have any calls. */
+ EXECUTE_IF_AND_COMPL_IN_BITMAP (modify_mem_list_set,
+ blocks_with_calls,
+ 0, bb_index, bi)
{
- rtx dest, dest_addr;
+ rtx list_entry = canon_modify_mem_list[bb_index];
- /* LIST_ENTRY must be an INSN of some kind that sets memory.
- Examine each hunk of memory that is modified. */
+ while (list_entry)
+ {
+ rtx dest, dest_addr;
- dest = XEXP (list_entry, 0);
- list_entry = XEXP (list_entry, 1);
- dest_addr = XEXP (list_entry, 0);
+ /* LIST_ENTRY must be an INSN of some kind that sets memory.
+ Examine each hunk of memory that is modified. */
- if (canon_true_dependence (dest, GET_MODE (dest), dest_addr,
- x, rtx_addr_varies_p))
- {
- if (set_p)
- SET_BIT (bmap[bb_index], indx);
- else
- RESET_BIT (bmap[bb_index], indx);
- break;
- }
- list_entry = XEXP (list_entry, 1);
+ dest = XEXP (list_entry, 0);
+ list_entry = XEXP (list_entry, 1);
+ dest_addr = XEXP (list_entry, 0);
+
+ if (canon_true_dependence (dest, GET_MODE (dest), dest_addr,
+ x, rtx_addr_varies_p))
+ {
+ if (set_p)
+ SET_BIT (bmap[bb_index], indx);
+ else
+ RESET_BIT (bmap[bb_index], indx);
+ break;
+ }
+ list_entry = XEXP (list_entry, 1);
+ }
}
- }
- }
+ }
x = XEXP (x, 0);
goto repeat;
diff --git a/gcc/genmodes.c b/gcc/genmodes.c
index 6e282f36dd9..42a8d03c83e 100644
--- a/gcc/genmodes.c
+++ b/gcc/genmodes.c
@@ -64,6 +64,7 @@ struct mode_data
struct mode_data *component; /* mode of components */
struct mode_data *wider; /* next wider mode */
+ struct mode_data *wider_2x; /* 2x wider mode */
struct mode_data *contained; /* Pointer to list of modes that have
this mode as a component. */
@@ -80,7 +81,7 @@ static struct mode_data *void_mode;
static const struct mode_data blank_mode = {
0, "<unknown>", MAX_MODE_CLASS,
-1U, -1U, -1U, -1U,
- 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
"<unknown>", 0
};
@@ -619,7 +620,7 @@ make_vector_mode (enum mode_class bclass,
ncomponents, base) >= sizeof namebuf)
{
error ("%s:%d: mode name \"%s\" is too long",
- base, file, line);
+ file, line, base);
return;
}
@@ -717,6 +718,7 @@ calc_wider_mode (void)
for (prev = 0, m = modes[c]; m; m = next)
{
m->wider = void_mode;
+ m->wider_2x = void_mode;
/* this is nreverse */
next = m->next;
@@ -951,6 +953,39 @@ emit_mode_wider (void)
m->name);
print_closer ();
+ print_decl ("unsigned char", "mode_2xwider", "NUM_MACHINE_MODES");
+
+ for_all_modes (c, m)
+ {
+ struct mode_data * m2;
+
+ for (m2 = m;
+ m2 && m2 != void_mode;
+ m2 = m2->wider)
+ {
+ if (m2->bytesize < 2 * m->bytesize)
+ continue;
+ if (m->precision != (unsigned int) -1)
+ {
+ if (m2->precision != 2 * m->precision)
+ continue;
+ }
+ else
+ {
+ if (m2->precision != (unsigned int) -1)
+ continue;
+ }
+
+ break;
+ }
+ if (m2 == void_mode)
+ m2 = 0;
+ tagged_printf ("%smode",
+ m2 ? m2->name : void_mode->name,
+ m->name);
+ }
+
+ print_closer ();
}
static void
diff --git a/gcc/ggc-page.c b/gcc/ggc-page.c
index 15f22c9f7f4..4da04b378bd 100644
--- a/gcc/ggc-page.c
+++ b/gcc/ggc-page.c
@@ -75,7 +75,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#define USING_MALLOC_PAGE_GROUPS
#endif
-/* Stategy:
+/* Strategy:
This garbage-collecting allocator allocates objects on one of a set
of pages. Each page can allocate objects of a single size only;
diff --git a/gcc/ggc-zone.c b/gcc/ggc-zone.c
index e3c72679d51..eb4fc1484ef 100644
--- a/gcc/ggc-zone.c
+++ b/gcc/ggc-zone.c
@@ -100,7 +100,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
ggc_set_mark for any object in the garbage zone, which cuts off
marking quickly. */
-/* Stategy:
+/* Strategy:
This garbage-collecting allocator segregates objects into zones.
It also segregates objects into "large" and "small" bins. Large
diff --git a/gcc/gimple-low.c b/gcc/gimple-low.c
index 4d3712b7f74..365e1957bb1 100644
--- a/gcc/gimple-low.c
+++ b/gcc/gimple-low.c
@@ -25,7 +25,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "tm.h"
#include "tree.h"
#include "rtl.h"
-#include "errors.h"
#include "varray.h"
#include "tree-gimple.h"
#include "tree-inline.h"
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 3dd48a8d09e..0639fd05bb5 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -27,7 +27,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "tm.h"
#include "tree.h"
#include "rtl.h"
-#include "errors.h"
#include "varray.h"
#include "tree-gimple.h"
#include "tree-inline.h"
@@ -45,6 +44,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "output.h"
#include "expr.h"
#include "ggc.h"
+#include "toplev.h"
#include "target.h"
static struct gimplify_ctx
@@ -54,7 +54,7 @@ static struct gimplify_ctx
tree conditional_cleanups;
tree exit_label;
tree return_temp;
- varray_type case_labels;
+ VEC(tree,heap) *case_labels;
/* The formal temporary table. Should this be persistent? */
htab_t temp_htab;
int conditions;
@@ -1008,10 +1008,12 @@ gimplify_decl_expr (tree *stmt_p)
if (TREE_TYPE (decl) == error_mark_node)
return GS_ERROR;
- else if (TREE_CODE (decl) == TYPE_DECL)
+ if ((TREE_CODE (decl) == TYPE_DECL
+ || TREE_CODE (decl) == VAR_DECL)
+ && !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl)))
gimplify_type_sizes (TREE_TYPE (decl), stmt_p);
- else if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl))
+ if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl))
{
tree init = DECL_INITIAL (decl);
@@ -1022,12 +1024,6 @@ gimplify_decl_expr (tree *stmt_p)
of the emitted code: see mx_register_decls(). */
tree t, args, addr, ptr_type;
- /* ??? We really shouldn't need to gimplify the type of the variable
- since it already should have been done. But leave this here
- for now to avoid disrupting too many things at once. */
- if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl)))
- gimplify_type_sizes (TREE_TYPE (decl), stmt_p);
-
gimplify_one_sizepos (&DECL_SIZE (decl), stmt_p);
gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), stmt_p);
@@ -1167,7 +1163,7 @@ gimplify_switch_expr (tree *expr_p, tree *pre_p)
if (SWITCH_BODY (switch_expr))
{
- varray_type labels, saved_labels;
+ VEC(tree,heap) *labels, *saved_labels;
tree label_vec, default_case = NULL_TREE;
size_t i, len;
@@ -1176,23 +1172,23 @@ gimplify_switch_expr (tree *expr_p, tree *pre_p)
gcc_assert (!SWITCH_LABELS (switch_expr));
saved_labels = gimplify_ctxp->case_labels;
- VARRAY_TREE_INIT (gimplify_ctxp->case_labels, 8, "case_labels");
+ gimplify_ctxp->case_labels = VEC_alloc (tree, heap, 8);
gimplify_to_stmt_list (&SWITCH_BODY (switch_expr));
labels = gimplify_ctxp->case_labels;
gimplify_ctxp->case_labels = saved_labels;
- len = VARRAY_ACTIVE_SIZE (labels);
+ len = VEC_length (tree, labels);
for (i = 0; i < len; ++i)
{
- tree t = VARRAY_TREE (labels, i);
+ tree t = VEC_index (tree, labels, i);
if (!CASE_LOW (t))
{
/* The default case must be the last label in the list. */
default_case = t;
- VARRAY_TREE (labels, i) = VARRAY_TREE (labels, len - 1);
+ VEC_replace (tree, labels, i, VEC_index (tree, labels, len - 1));
len--;
break;
}
@@ -1216,9 +1212,11 @@ gimplify_switch_expr (tree *expr_p, tree *pre_p)
*expr_p = SWITCH_BODY (switch_expr);
for (i = 0; i < len; ++i)
- TREE_VEC_ELT (label_vec, i) = VARRAY_TREE (labels, i);
+ TREE_VEC_ELT (label_vec, i) = VEC_index (tree, labels, i);
TREE_VEC_ELT (label_vec, len) = default_case;
+ VEC_free (tree, heap, labels);
+
sort_case_labels (label_vec);
SWITCH_BODY (switch_expr) = NULL;
@@ -1235,7 +1233,7 @@ gimplify_case_label_expr (tree *expr_p)
tree expr = *expr_p;
gcc_assert (gimplify_ctxp->case_labels);
- VARRAY_PUSH_TREE (gimplify_ctxp->case_labels, expr);
+ VEC_safe_push (tree, heap, gimplify_ctxp->case_labels, expr);
*expr_p = build (LABEL_EXPR, void_type_node, CASE_LABEL (expr));
return GS_ALL_DONE;
}
@@ -2530,6 +2528,17 @@ gimplify_init_ctor_eval_range (tree object, tree lower, tree upper,
pre_p);
}
+/* Return true if FDECL is accessing a field that is zero sized. */
+
+static bool
+zero_sized_field_decl (tree fdecl)
+{
+ if (TREE_CODE (fdecl) == FIELD_DECL && DECL_SIZE (fdecl)
+ && integer_zerop (DECL_SIZE (fdecl)))
+ return true;
+ return false;
+}
+
/* A subroutine of gimplify_init_constructor. Generate individual
MODIFY_EXPRs for a CONSTRUCTOR. OBJECT is the LHS against which the
assignments should happen. LIST is the CONSTRUCTOR_ELTS of the
@@ -2562,6 +2571,9 @@ gimplify_init_ctor_eval (tree object, tree list, tree *pre_p, bool cleared)
so we don't have to figure out what's missing ourselves. */
gcc_assert (purpose);
+ if (zero_sized_field_decl (purpose))
+ continue;
+
/* If we have a RANGE_EXPR, we have to build a loop to assign the
whole range. */
if (TREE_CODE (purpose) == RANGE_EXPR)
@@ -2678,10 +2690,35 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p,
break;
}
+ /* If there are "lots" of initialized elements, even discounting
+ those that are not address constants (and thus *must* be
+ computed at runtime), then partition the constructor into
+ constant and non-constant parts. Block copy the constant
+ parts in, then generate code for the non-constant parts. */
+ /* TODO. There's code in cp/typeck.c to do this. */
+
+ num_type_elements = count_type_elements (TREE_TYPE (ctor));
+
+ /* If there are "lots" of zeros, then block clear the object first. */
+ if (num_type_elements - num_nonzero_elements > CLEAR_RATIO
+ && num_nonzero_elements < num_type_elements/4)
+ cleared = true;
+
+ /* ??? This bit ought not be needed. For any element not present
+ in the initializer, we should simply set them to zero. Except
+ we'd need to *find* the elements that are not present, and that
+ requires trickery to avoid quadratic compile-time behavior in
+ large cases or excessive memory use in small cases. */
+ else if (num_ctor_elements < num_type_elements)
+ cleared = true;
+
/* If there are "lots" of initialized elements, and all of them
are valid address constants, then the entire initializer can
- be dropped to memory, and then memcpy'd out. */
- if (num_nonconstant_elements == 0)
+ be dropped to memory, and then memcpy'd out. Don't do this
+ for sparse arrays, though, as it's more efficient to follow
+ the standard CONSTRUCTOR behavior of memset followed by
+ individual element initialization. */
+ if (num_nonconstant_elements == 0 && !cleared)
{
HOST_WIDE_INT size = int_size_in_bytes (type);
unsigned int align;
@@ -2727,28 +2764,6 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p,
}
}
- /* If there are "lots" of initialized elements, even discounting
- those that are not address constants (and thus *must* be
- computed at runtime), then partition the constructor into
- constant and non-constant parts. Block copy the constant
- parts in, then generate code for the non-constant parts. */
- /* TODO. There's code in cp/typeck.c to do this. */
-
- num_type_elements = count_type_elements (TREE_TYPE (ctor));
-
- /* If there are "lots" of zeros, then block clear the object first. */
- if (num_type_elements - num_nonzero_elements > CLEAR_RATIO
- && num_nonzero_elements < num_type_elements/4)
- cleared = true;
-
- /* ??? This bit ought not be needed. For any element not present
- in the initializer, we should simply set them to zero. Except
- we'd need to *find* the elements that are not present, and that
- requires trickery to avoid quadratic compile-time behavior in
- large cases or excessive memory use in small cases. */
- else if (num_ctor_elements < num_type_elements)
- cleared = true;
-
if (cleared)
{
/* Zap the CONSTRUCTOR element list, which simplifies this case.
@@ -2871,6 +2886,62 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p,
return GS_ALL_DONE;
}
+/* Given a pointer value OP0, return a simplified version of an
+ indirection through OP0, or NULL_TREE if no simplification is
+ possible. This may only be applied to a rhs of an expression.
+ Note that the resulting type may be different from the type pointed
+ to in the sense that it is still compatible from the langhooks
+ point of view. */
+
+static tree
+fold_indirect_ref_rhs (tree t)
+{
+ tree type = TREE_TYPE (TREE_TYPE (t));
+ tree sub = t;
+ tree subtype;
+
+ STRIP_NOPS (sub);
+ subtype = TREE_TYPE (sub);
+ if (!POINTER_TYPE_P (subtype))
+ return NULL_TREE;
+
+ if (TREE_CODE (sub) == ADDR_EXPR)
+ {
+ tree op = TREE_OPERAND (sub, 0);
+ tree optype = TREE_TYPE (op);
+ /* *&p => p */
+ if (lang_hooks.types_compatible_p (type, optype))
+ return op;
+ /* *(foo *)&fooarray => fooarray[0] */
+ else if (TREE_CODE (optype) == ARRAY_TYPE
+ && lang_hooks.types_compatible_p (type, TREE_TYPE (optype)))
+ {
+ tree type_domain = TYPE_DOMAIN (optype);
+ tree min_val = size_zero_node;
+ if (type_domain && TYPE_MIN_VALUE (type_domain))
+ min_val = TYPE_MIN_VALUE (type_domain);
+ return build4 (ARRAY_REF, type, op, min_val, NULL_TREE, NULL_TREE);
+ }
+ }
+
+ /* *(foo *)fooarrptr => (*fooarrptr)[0] */
+ if (TREE_CODE (TREE_TYPE (subtype)) == ARRAY_TYPE
+ && lang_hooks.types_compatible_p (type, TREE_TYPE (TREE_TYPE (subtype))))
+ {
+ tree type_domain;
+ tree min_val = size_zero_node;
+ sub = fold_indirect_ref_rhs (sub);
+ if (! sub)
+ sub = build1 (INDIRECT_REF, TREE_TYPE (subtype), sub);
+ type_domain = TYPE_DOMAIN (TREE_TYPE (sub));
+ if (type_domain && TYPE_MIN_VALUE (type_domain))
+ min_val = TYPE_MIN_VALUE (type_domain);
+ return build4 (ARRAY_REF, type, sub, min_val, NULL_TREE, NULL_TREE);
+ }
+
+ return NULL_TREE;
+}
+
/* Subroutine of gimplify_modify_expr to do simplifications of MODIFY_EXPRs
based on the code of the RHS. We loop for as long as something changes. */
@@ -2894,8 +2965,8 @@ gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p, tree *pre_p,
This kind of code arises in C++ when an object is bound
to a const reference, and if "x" is a TARGET_EXPR we want
to take advantage of the optimization below. */
- tree t = fold_indirect_ref (*from_p);
- if (t != *from_p)
+ tree t = fold_indirect_ref_rhs (TREE_OPERAND (*from_p, 0));
+ if (t)
{
*from_p = t;
ret = GS_OK;
@@ -3042,7 +3113,7 @@ gimplify_modify_expr (tree *expr_p, tree *pre_p, tree *post_p, bool want_value)
if (gimplify_ctxp->into_ssa && is_gimple_reg (*to_p))
{
/* If we've somehow already got an SSA_NAME on the LHS, then
- we're probably modifying it twice. Not good. */
+ we're probably modified it twice. Not good. */
gcc_assert (TREE_CODE (*to_p) != SSA_NAME);
*to_p = make_ssa_name (*to_p, *expr_p);
}
@@ -4390,21 +4461,21 @@ gimplify_type_sizes (tree type, tree *list_p)
{
tree field, t;
- /* Note that we do not check for TYPE_SIZES_GIMPLIFIED already set because
- that's not supposed to happen on types where gimplification does anything.
- We should assert that it isn't set, but we can indeed be called multiple
- times on pointers. Unfortunately, this includes fat pointers which we
- can't easily test for. We could pass TYPE down to gimplify_one_sizepos
- and test there, but it doesn't seem worth it. */
+ if (type == NULL)
+ return;
/* We first do the main variant, then copy into any other variants. */
type = TYPE_MAIN_VARIANT (type);
+ /* Avoid infinite recursion. */
+ if (TYPE_SIZES_GIMPLIFIED (type)
+ || type == error_mark_node)
+ return;
+
+ TYPE_SIZES_GIMPLIFIED (type) = 1;
+
switch (TREE_CODE (type))
{
- case ERROR_MARK:
- return;
-
case INTEGER_TYPE:
case ENUMERAL_TYPE:
case BOOLEAN_TYPE:
@@ -4417,17 +4488,13 @@ gimplify_type_sizes (tree type, tree *list_p)
{
TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (type);
TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (type);
- TYPE_SIZES_GIMPLIFIED (t) = 1;
}
break;
case ARRAY_TYPE:
/* These types may not have declarations, so handle them here. */
- if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (type)))
- gimplify_type_sizes (TREE_TYPE (type), list_p);
-
- if (!TYPE_SIZES_GIMPLIFIED (TYPE_DOMAIN (type)))
- gimplify_type_sizes (TYPE_DOMAIN (type), list_p);
+ gimplify_type_sizes (TREE_TYPE (type), list_p);
+ gimplify_type_sizes (TYPE_DOMAIN (type), list_p);
break;
case RECORD_TYPE:
@@ -4435,7 +4502,15 @@ gimplify_type_sizes (tree type, tree *list_p)
case QUAL_UNION_TYPE:
for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
if (TREE_CODE (field) == FIELD_DECL)
- gimplify_one_sizepos (&DECL_FIELD_OFFSET (field), list_p);
+ {
+ gimplify_one_sizepos (&DECL_FIELD_OFFSET (field), list_p);
+ gimplify_type_sizes (TREE_TYPE (field), list_p);
+ }
+ break;
+
+ case POINTER_TYPE:
+ case REFERENCE_TYPE:
+ gimplify_type_sizes (TREE_TYPE (type), list_p);
break;
default:
@@ -4451,8 +4526,6 @@ gimplify_type_sizes (tree type, tree *list_p)
TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (type);
TYPE_SIZES_GIMPLIFIED (t) = 1;
}
-
- TYPE_SIZES_GIMPLIFIED (type) = 1;
}
/* A subroutine of gimplify_type_sizes to make sure that *EXPR_P,
diff --git a/gcc/global.c b/gcc/global.c
index b11e6d7f6c7..dea1fc55347 100644
--- a/gcc/global.c
+++ b/gcc/global.c
@@ -2098,8 +2098,8 @@ mark_reg_change (rtx reg, rtx setter, void *data)
/* Classes of registers which could be early clobbered in the current
insn. */
-DEF_VEC_P(int);
-DEF_VEC_ALLOC_P(int,heap);
+DEF_VEC_I(int);
+DEF_VEC_ALLOC_I(int,heap);
static VEC(int,heap) *earlyclobber_regclass;
diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c
index be02aaa7d24..d4b66a58f7a 100644
--- a/gcc/ifcvt.c
+++ b/gcc/ifcvt.c
@@ -687,7 +687,61 @@ noce_emit_move_insn (rtx x, rtx y)
if (GET_CODE (x) != STRICT_LOW_PART)
{
- emit_move_insn (x, y);
+ rtx seq, insn, target;
+ optab ot;
+
+ start_sequence ();
+ /* Check that the SET_SRC is reasonable before calling emit_move_insn,
+ otherwise construct a suitable SET pattern ourselves. */
+ insn = (OBJECT_P (y) || CONSTANT_P (y) || GET_CODE (y) == SUBREG)
+ ? emit_move_insn (x, y)
+ : emit_insn (gen_rtx_SET (VOIDmode, x, y));
+ seq = get_insns ();
+ end_sequence();
+
+ if (recog_memoized (insn) <= 0)
+ switch (GET_RTX_CLASS (GET_CODE (y)))
+ {
+ case RTX_UNARY:
+ ot = code_to_optab[GET_CODE (y)];
+ if (ot)
+ {
+ start_sequence ();
+ target = expand_unop (GET_MODE (y), ot, XEXP (y, 0), x, 0);
+ if (target != NULL_RTX)
+ {
+ if (target != x)
+ emit_move_insn (x, target);
+ seq = get_insns ();
+ }
+ end_sequence ();
+ }
+ break;
+
+ case RTX_BIN_ARITH:
+ case RTX_COMM_ARITH:
+ ot = code_to_optab[GET_CODE (y)];
+ if (ot)
+ {
+ start_sequence ();
+ target = expand_binop (GET_MODE (y), ot,
+ XEXP (y, 0), XEXP (y, 1),
+ x, 0, OPTAB_DIRECT);
+ if (target != NULL_RTX)
+ {
+ if (target != x)
+ emit_move_insn (x, target);
+ seq = get_insns ();
+ }
+ end_sequence ();
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ emit_insn (seq);
return;
}
@@ -1815,6 +1869,105 @@ noce_try_sign_mask (struct noce_if_info *if_info)
}
+/* Optimize away "if (x & C) x |= C" and similar bit manipulation
+ transformations. */
+
+static int
+noce_try_bitop (struct noce_if_info *if_info)
+{
+ rtx cond, x, a, result, seq;
+ enum machine_mode mode;
+ enum rtx_code code;
+ int bitnum;
+
+ x = if_info->x;
+ cond = if_info->cond;
+ code = GET_CODE (cond);
+
+ /* Check for no else condition. */
+ if (! rtx_equal_p (x, if_info->b))
+ return FALSE;
+
+ /* Check for a suitable condition. */
+ if (code != NE && code != EQ)
+ return FALSE;
+ if (XEXP (cond, 1) != const0_rtx)
+ return FALSE;
+ cond = XEXP (cond, 0);
+
+ /* ??? We could also handle AND here. */
+ if (GET_CODE (cond) == ZERO_EXTRACT)
+ {
+ if (XEXP (cond, 1) != const1_rtx
+ || GET_CODE (XEXP (cond, 2)) != CONST_INT
+ || ! rtx_equal_p (x, XEXP (cond, 0)))
+ return FALSE;
+ bitnum = INTVAL (XEXP (cond, 2));
+ mode = GET_MODE (x);
+ if (bitnum >= HOST_BITS_PER_WIDE_INT)
+ return FALSE;
+ }
+ else
+ return FALSE;
+
+ a = if_info->a;
+ if (GET_CODE (a) == IOR || GET_CODE (a) == XOR)
+ {
+ /* Check for "if (X & C) x = x op C". */
+ if (! rtx_equal_p (x, XEXP (a, 0))
+ || GET_CODE (XEXP (a, 1)) != CONST_INT
+ || (INTVAL (XEXP (a, 1)) & GET_MODE_MASK (mode))
+ != (unsigned HOST_WIDE_INT) 1 << bitnum)
+ return FALSE;
+
+ /* if ((x & C) == 0) x |= C; is transformed to x |= C. */
+ /* if ((x & C) != 0) x |= C; is transformed to nothing. */
+ if (GET_CODE (a) == IOR)
+ result = (code == NE) ? a : NULL_RTX;
+ else if (code == NE)
+ {
+ /* if ((x & C) == 0) x ^= C; is transformed to x |= C. */
+ result = gen_int_mode ((HOST_WIDE_INT) 1 << bitnum, mode);
+ result = simplify_gen_binary (IOR, mode, x, result);
+ }
+ else
+ {
+ /* if ((x & C) != 0) x ^= C; is transformed to x &= ~C. */
+ result = gen_int_mode (~((HOST_WIDE_INT) 1 << bitnum), mode);
+ result = simplify_gen_binary (AND, mode, x, result);
+ }
+ }
+ else if (GET_CODE (a) == AND)
+ {
+ /* Check for "if (X & C) x &= ~C". */
+ if (! rtx_equal_p (x, XEXP (a, 0))
+ || GET_CODE (XEXP (a, 1)) != CONST_INT
+ || (INTVAL (XEXP (a, 1)) & GET_MODE_MASK (mode))
+ != (~((HOST_WIDE_INT) 1 << bitnum) & GET_MODE_MASK (mode)))
+ return FALSE;
+
+ /* if ((x & C) == 0) x &= ~C; is transformed to nothing. */
+ /* if ((x & C) != 0) x &= ~C; is transformed to x &= ~C. */
+ result = (code == EQ) ? a : NULL_RTX;
+ }
+ else
+ return FALSE;
+
+ if (result)
+ {
+ start_sequence ();
+ noce_emit_move_insn (x, result);
+ seq = end_ifcvt_sequence (if_info);
+ if (!seq)
+ return FALSE;
+
+ emit_insn_before_setloc (seq, if_info->jump,
+ INSN_LOCATOR (if_info->insn_a));
+ }
+ return TRUE;
+}
+
+
/* Similar to get_condition, only the resulting condition must be
valid at JUMP, instead of at EARLIEST. */
@@ -2078,6 +2231,8 @@ noce_process_if_block (struct ce_if_block * ce_info)
goto success;
if (noce_try_store_flag (&if_info))
goto success;
+ if (noce_try_bitop (&if_info))
+ goto success;
if (noce_try_minmax (&if_info))
goto success;
if (noce_try_abs (&if_info))
@@ -3275,12 +3430,31 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb,
/* Move the insns out of MERGE_BB to before the branch. */
if (head != NULL)
{
+ rtx insn;
+
if (end == BB_END (merge_bb))
BB_END (merge_bb) = PREV_INSN (head);
if (squeeze_notes (&head, &end))
return TRUE;
+ /* PR 21767: When moving insns above a conditional branch, REG_EQUAL
+ notes might become invalid. */
+ insn = head;
+ do
+ {
+ rtx note, set;
+
+ if (! INSN_P (insn))
+ continue;
+ note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
+ if (! note)
+ continue;
+ set = single_set (insn);
+ if (!set || !function_invariant_p (SET_SRC (set)))
+ remove_note (insn, note);
+ } while (insn != end && (insn = NEXT_INSN (insn)));
+
reorder_insns (head, end, PREV_INSN (earliest));
}
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index 1e65e710458..262dea50d53 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -322,13 +322,13 @@ cgraph_maybe_hot_edge_p (struct cgraph_edge *edge)
/* A cost model driving the inlining heuristics in a way so the edges with
smallest badness are inlined first. After each inlining is performed
- the costs of all caller edges of nodes affected are recompted so the
+ the costs of all caller edges of nodes affected are recomputed so the
metrics may accurately depend on values such as number of inlinable callers
of the function or function body size.
For the moment we use estimated growth caused by inlining callee into all
it's callers for driving the inlining but once we have loop depth or
- frequency information readilly available we should do better.
+ frequency information readily available we should do better.
With profiling we use number of executions of each edge to drive the cost.
We also should distinguish hot and cold calls where the cold calls are
@@ -346,7 +346,7 @@ cgraph_edge_badness (struct cgraph_edge *edge)
cgraph_estimate_size_after_inlining (1, edge->caller, edge->callee);
growth -= edge->caller->global.insns;
- /* Always preffer inlining saving code size. */
+ /* Always prefer inlining saving code size. */
if (growth <= 0)
return INT_MIN - growth;
return ((int)((double)edge->count * INT_MIN / max_count)) / growth;
@@ -419,7 +419,7 @@ update_callee_keys (fibheap_t heap, struct cgraph_node *node,
}
/* Enqueue all recursive calls from NODE into priority queue depending on
- how likely we want to recursivly inline the call. */
+ how likely we want to recursively inline the call. */
static void
lookup_recursive_calls (struct cgraph_node *node, struct cgraph_node *where,
@@ -611,7 +611,7 @@ cgraph_decide_inlining_of_small_functions (void)
continue;
/* When not having profile info ready we don't weight by any way the
- possition of call in procedure itself. This means if call of
+ position of call in procedure itself. This means if call of
function A from function B seems profitable to inline, the recursive
call of function A in inline copy of A in B will look profitable too
and we end up inlining until reaching maximal function growth. This
@@ -633,7 +633,7 @@ cgraph_decide_inlining_of_small_functions (void)
edge->inline_failed
= (edge->callee->local.disregard_inline_limits ? N_("recursive inlining") : "");
if (dump_file)
- fprintf (dump_file, " inline_failed:Recursive inlining perfomed only for function itself.\n");
+ fprintf (dump_file, " inline_failed:Recursive inlining performed only for function itself.\n");
continue;
}
}
@@ -860,17 +860,6 @@ cgraph_decide_inlining (void)
}
}
- /* We will never output extern functions we didn't inline.
- ??? Perhaps we can prevent accounting of growth of external
- inline functions. */
-
- /* FIXME: at the moment we don't want to remove nodes here
- or we confuse aliasing code. This needs to be dealt with
- better later by reorganizing the order of analysis.
-
- Uncommenting this should make same call in cgraph_optimize unnecesary.
- cgraph_remove_unreachable_nodes (false, dump_file); */
-
if (dump_file)
fprintf (dump_file,
"\nInlined %i calls, eliminated %i functions, "
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index 368eac7cf72..957593967f4 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -245,7 +245,7 @@ ipa_callsite_param_map_create (struct cgraph_edge *cs)
static inline tree
ipa_callsite_tree (struct cgraph_edge *cs)
{
- return cs->call_expr;
+ return get_call_expr_in (cs->call_stmt);
}
/* Gets the caller of callsite cs. */
diff --git a/gcc/ipcp.c b/gcc/ipcp.c
index 2519f4faa8f..7db491790d0 100644
--- a/gcc/ipcp.c
+++ b/gcc/ipcp.c
@@ -1170,7 +1170,7 @@ ipcp_update_callgraph (void)
if (ipcp_redirect (cs))
{
cgraph_redirect_edge_callee (cs, orig_callee);
- TREE_OPERAND (TREE_OPERAND (cs->call_expr, 0), 0) =
+ TREE_OPERAND (TREE_OPERAND (get_call_expr_in (cs->call_stmt), 0), 0) =
orig_callee->decl;
}
}
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog
index a9bcf444403..117cea996d4 100644
--- a/gcc/java/ChangeLog
+++ b/gcc/java/ChangeLog
@@ -1,3 +1,97 @@
+2005-06-01 Tom Tromey <tromey@redhat.com>
+
+ PR java/21722:
+ * class.c (build_static_field_ref): Don't fold constant fields if
+ current class is from a .class file and we're using indirect
+ dispatch.
+
+2005-05-31 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * java/verify-glue.c: Don't include errors.h and include toplev.h.
+ * java/Make-lang.in: Updates dependencies.
+
+2005-05-26 Ranjit Mathew <rmathew@hotmail.com>
+
+ PR java/19870.
+ * java-tree.h (OUTER_FIELD_ACCESS_IDENTIFIER_P): Rename to
+ NESTED_FIELD_ACCESS_IDENTIFIER_P.
+ (FIELD_INNER_ACCESS): Rename to FIELD_NESTED_ACCESS.
+ (FIELD_INNER_ACCESS_P): Rename to FIELD_NESTED_ACCESS_P.
+ * jcf-write.c (generate_classfile): Use
+ NESTED_FIELD_ACCESS_IDENTIFIER_P instead of
+ OUTER_FIELD_ACCESS_IDENTIFIER_P.
+ * parse.y (build_outer_field_access): Rename to
+ build_nested_field_access. Support static fields and outer-to-inner
+ class accesses.
+ (outer_field_access_p): Rename to nested_field_access_p. Support
+ static fields and generalise to outer-to-inner class and sibling
+ inner class accesses.
+ (outer_field_expanded_access_p): Rename to
+ nested_field_expanded_access_p and support static fields.
+ (outer_field_access_fix): Rename to nested_field_access_fix and
+ support static fields.
+ (build_outer_field_access_expr): Rename to
+ build_nested_field_access_expr and support static fields.
+ (build_outer_field_access_methods): Rename to
+ build_nested_field_access_methods and support static fields. For
+ static fields, generate accessors without class instance parameters.
+ (build_outer_field_access_method): Rename to
+ build_nested_field_access_method and support static fields.
+ (build_outer_method_access_method): Use
+ NESTED_FIELD_ACCESS_IDENTIFIER_P instead of
+ OUTER_FIELD_ACCESS_IDENTIFIER_P.
+ (resolve_expression_name): Consider static field accesses across
+ nested classes.
+ (resolve_qualified_expression_name): Likewise.
+ (java_complete_lhs): Use nested_field_access_fix instead of
+ outer_field_access_fix.
+ (patch_unary_op): Rename outer_field_flag to nested_field_flag.
+ Use nested_field_expanded_access_p instead of
+ outer_field_expanded_access_p. Use nested_field_access_fix instead
+ of outer_field_access_fix.
+ (check_thrown_exceptions): Use NESTED_FIELD_ACCESS_IDENTIFIER_P
+ instead of OUTER_FIELD_ACCESS_IDENTIFIER_P.
+
+2005-05-26 Bryce McKinlay <mckinlay@redhat.com>
+
+ * decl.c (GCJ_BINARYCOMPAT_ADDITION,
+ GCJ_BOOTSTRAP_LOADER_ADDITION): Removed.
+ (FLAG_BINARYCOMPAT_ABI, FLAG_BOOTSTRAP_LOADER,
+ MINOR_BINARYCOMPAT_ABI_VERSION): New.
+ (GCJ_CURRENT_BC_ABI_VERSION): Use new method to calculate version ID.
+ (parse_version): Calculate version ID using new method. Use bit-flags
+ for flag_indirect_dispatch and flag_bootstrap_classes.
+
+2005-05-25 Richard Henderson <rth@redhat.com>
+
+ PR libgcj/21692
+ * Make-lang.in (java/mangle.o): Depend on LANGHOOKS_DEF_H.
+ * class.c (build_class_ref): Set DECL_CLASS_FIELD_P and
+ DECL_CONTEXT; avoid pushdecl_top_level.
+ (build_dtable_decl): Set DECL_VTABLE_P and DECL_CONTEXT.
+ (layout_class): Don't SET_DECL_ASSEMBLER_NAME.
+ (layout_class_method): Likewise.
+ * decl.c (java_mark_cni_decl_local): New.
+ (java_mark_class_local): Use it.
+ * java-tree.h (DECL_LOCAL_CNI_METHOD_P): New.
+ (DECL_CLASS_FIELD_P, DECL_VTABLE_P): New.
+ (struct lang_decl_func): Add local_cni;
+ (struct lang_decl_var): Add class_field, vtable.
+ (java_mangle_decl): Declare.
+ * lang.c (LANG_HOOKS_SET_DECL_ASSEMBLER_NAME): New.
+ * mangle.c: Remove dup obstack.h; include langhooks-def.h.
+ (mangle_obstack_1): New.
+ (java_mangle_decl): Remove obstack argument. Call mangle_class_field,
+ mangle_vtable, and mangle_local_cni_method_decl. Fall back to
+ lhd_set_decl_assembler_name for things that don't need mangling.
+ (mangle_class_field): Rename from java_mangle_class_field, make
+ static, don't call init_mangling or finish_mangling.
+ (mangle_vtable): Similarly.
+ (mangle_local_cni_method_decl): New.
+ (init_mangling): Remove obstack argument. Use &mangle_obstack_1,
+ gcc_assert, and MANGLE_RAW_STRING.
+ (finish_mangling): Use gcc_assert, remove if 0 debugging code.
+
2005-05-25 DJ Delorie <dj@redhat.com>
* class.c (set_constant_value): Move warning control from if() to
@@ -10421,7 +10515,7 @@
properly initialize `finished_label'. Don't emit gotos for empty
try statements.
-2000-03-19 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+2000-03-19 Martin v. Loewis <loewis@informatik.hu-berlin.de>
* except.c (emit_handlers): Clear catch_clauses_last.
diff --git a/gcc/java/Make-lang.in b/gcc/java/Make-lang.in
index 17aa70a7a94..31bb323f668 100644
--- a/gcc/java/Make-lang.in
+++ b/gcc/java/Make-lang.in
@@ -340,7 +340,7 @@ java/lang.o: java/lang.c $(CONFIG_H) $(JAVA_TREE_H) java/jcf.h input.h \
toplev.h $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(EXPR_H) diagnostic.h \
langhooks.h $(LANGHOOKS_DEF_H) gt-java-lang.h opts.h options.h
java/mangle.o: java/mangle.c $(CONFIG_H) java/jcf.h $(JAVA_TREE_H) $(SYSTEM_H) \
- coretypes.h $(TM_H) toplev.h $(GGC_H) gt-java-mangle.h
+ coretypes.h $(TM_H) toplev.h $(GGC_H) gt-java-mangle.h $(LANGHOOKS_DEF_H)
java/mangle_name.o: java/mangle_name.c $(CONFIG_H) java/jcf.h $(JAVA_TREE_H) \
$(SYSTEM_H) coretypes.h $(TM_H) toplev.h $(GGC_H)
java/resource.o: java/resource.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
@@ -353,7 +353,7 @@ java/verify.o: java/verify.c $(CONFIG_H) $(JAVA_TREE_H) java/jcf.h \
java/javaop.h java/java-opcodes.h java/java-except.h toplev.h $(SYSTEM_H) \
coretypes.h $(TM_H)
java/verify-glue.o: java/verify-glue.c $(CONFIG_H) $(SYSTEM_H) $(JAVA_TREE_H) \
- coretypes.h $(TM_H) java/verify.h
+ coretypes.h $(TM_H) java/verify.h toplev.h
java/verify-impl.o: java/verify-impl.c $(CONFIG_H) java/verify.h $(SYSTEM_H) \
coretypes.h java/jcf.h $(JAVA_TREE_H)
java/zextract.o: java/zextract.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
diff --git a/gcc/java/class.c b/gcc/java/class.c
index 3e8ae2693d6..68732b74dd5 100644
--- a/gcc/java/class.c
+++ b/gcc/java/class.c
@@ -970,10 +970,13 @@ build_class_ref (tree type)
DECL_ARTIFICIAL (decl) = 1;
if (is_compiled == 1)
DECL_EXTERNAL (decl) = 1;
- SET_DECL_ASSEMBLER_NAME (decl,
- java_mangle_class_field
- (&temporary_obstack, type));
- pushdecl_top_level (decl);
+ MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
+ DECL_CLASS_FIELD_P (decl) = 1;
+ DECL_CONTEXT (decl) = type;
+
+ /* ??? We want to preserve the DECL_CONTEXT we set just above,
+ that that means not calling pushdecl_top_level. */
+ IDENTIFIER_GLOBAL_VALUE (decl_name) = decl;
}
}
else
@@ -1065,19 +1068,18 @@ build_static_field_ref (tree fdecl)
{
tree fclass = DECL_CONTEXT (fdecl);
int is_compiled = is_compiled_class (fclass);
+ int from_class = ! CLASS_FROM_SOURCE_P (current_class);
/* Allow static final fields to fold to a constant. When using
- -fno-assume-compiled, gcj will sometimes try to fold a field from
- an uncompiled class. This is required when the field in question
- meets the appropriate criteria for a compile-time constant.
- However, currently sometimes gcj is too eager and will end up
- returning the field itself, leading to an incorrect external
- reference being generated. */
- if ((is_compiled && !flag_indirect_dispatch)
- || (FIELD_FINAL (fdecl) && DECL_INITIAL (fdecl) != NULL_TREE
- && (JSTRING_TYPE_P (TREE_TYPE (fdecl))
- || JNUMERIC_TYPE_P (TREE_TYPE (fdecl)))
- && TREE_CONSTANT (DECL_INITIAL (fdecl))))
+ -findirect-dispatch, we simply never do this folding if compiling
+ from .class; in the .class file constants will be referred to via
+ the constant pool. */
+ if ((!flag_indirect_dispatch || !from_class)
+ && (is_compiled
+ || (FIELD_FINAL (fdecl) && DECL_INITIAL (fdecl) != NULL_TREE
+ && (JSTRING_TYPE_P (TREE_TYPE (fdecl))
+ || JNUMERIC_TYPE_P (TREE_TYPE (fdecl)))
+ && TREE_CONSTANT (DECL_INITIAL (fdecl)))))
{
if (is_compiled == 1)
DECL_EXTERNAL (fdecl) = 1;
@@ -1969,7 +1971,7 @@ is_compiled_class (tree class)
tree
build_dtable_decl (tree type)
{
- tree dtype;
+ tree dtype, decl;
/* We need to build a new dtable type so that its size is uniquely
computed when we're dealing with the class for real and not just
@@ -2017,8 +2019,12 @@ build_dtable_decl (tree type)
else
dtype = dtable_type;
- return build_decl (VAR_DECL,
- java_mangle_vtable (&temporary_obstack, type), dtype);
+ decl = build_decl (VAR_DECL, get_identifier ("vt$"), dtype);
+ DECL_CONTEXT (decl) = type;
+ MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
+ DECL_VTABLE_P (decl) = 1;
+
+ return decl;
}
/* Pre-pend the TYPE_FIELDS of THIS_CLASS with a dummy FIELD_DECL for the
@@ -2092,7 +2098,6 @@ void
layout_class (tree this_class)
{
tree super_class = CLASSTYPE_SUPER (this_class);
- tree field;
class_list = tree_cons (this_class, NULL_TREE, class_list);
if (CLASS_BEING_LAIDOUT (this_class))
@@ -2140,18 +2145,6 @@ layout_class (tree this_class)
push_super_field (this_class, maybe_super_class);
}
- for (field = TYPE_FIELDS (this_class);
- field != NULL_TREE; field = TREE_CHAIN (field))
- {
- if (FIELD_STATIC (field))
- {
- /* Set DECL_ASSEMBLER_NAME to something suitably mangled. */
- SET_DECL_ASSEMBLER_NAME (field,
- java_mangle_decl
- (&temporary_obstack, field));
- }
- }
-
layout_type (this_class);
/* Also recursively load/layout any superinterfaces, but only if
@@ -2319,11 +2312,6 @@ layout_class_method (tree this_class, tree super_class,
compiled into this object file. */
DECL_EXTERNAL (method_decl) = 1;
- /* This is a good occasion to mangle the method's name */
- SET_DECL_ASSEMBLER_NAME (method_decl,
- java_mangle_decl (&temporary_obstack,
- method_decl));
-
if (ID_INIT_P (method_name))
{
const char *p = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (this_class)));
diff --git a/gcc/java/decl.c b/gcc/java/decl.c
index 5b693cb50f6..891e4dbe406 100644
--- a/gcc/java/decl.c
+++ b/gcc/java/decl.c
@@ -61,19 +61,31 @@ static tree create_primitive_vtable (const char *);
static tree check_local_unnamed_variable (tree, tree, tree);
static void parse_version (void);
-/* Used when computing the ABI version. */
-#define GCJ_BINARYCOMPAT_ADDITION 5
-/* Used when defining a class that should be loaded by the bootstrap
- loader. */
-#define GCJ_BOOTSTRAP_LOADER_ADDITION 1
+/* The following ABI flags are used in the high-order bits of the version
+ ID field. The version ID number itself should never be larger than
+ 0xfffff, so it should be safe to use top 12 bits for these flags. */
-/* The version of the BC ABI that we generate. At the moment we are
- compatible with what shipped in GCC 4.0. This must be kept in sync
- with parse_version(), libgcj, and reality (if the BC format
- changes, this must change. */
+#define FLAG_BINARYCOMPAT_ABI (1<<31) /* Class is built with the BC-ABI. */
+
+#define FLAG_BOOTSTRAP_LOADER (1<<30) /* Used when defining a class that
+ should be loaded by the bootstrap
+ loader. */
+
+/* If an ABI change is made within a GCC release series, rendering current
+ binaries incompatible with the old runtimes, this number can be set to
+ enforce the compatibility rules. */
+#define MINOR_BINARYCOMPAT_ABI_VERSION 0
+
+/* The runtime may recognize a variety of BC ABIs (objects generated by
+ different version of gcj), but will probably always require strict
+ matching for the ordinary (C++) ABI. */
+
+/* The version ID of the BC ABI that we generate. This must be kept in
+ sync with parse_version(), libgcj, and reality (if the BC format changes,
+ this must change). */
#define GCJ_CURRENT_BC_ABI_VERSION \
- (4 * 10000 + 0 * 10 + GCJ_BINARYCOMPAT_ADDITION)
+ (4 * 100000 + 0 * 1000 + MINOR_BINARYCOMPAT_ABI_VERSION)
/* The ABI version number. */
tree gcj_abi_version;
@@ -613,18 +625,20 @@ parse_version (void)
++p;
}
- /* Implicit in this computation is the idea that we won't break the
- old-style binary ABI in a sub-minor release (e.g., from 4.0.0 to
- 4.0.1). */
- abi_version = 10000 * major + 10 * minor;
- /* It is helpful to distinguish BC ABI from ordinary ABI at this
- level, since at some point we will recognize a variety of BC ABIs
- (objects generated by different version of gcj), but will
- probably always require strict matching for ordinary ABI. */
if (flag_indirect_dispatch)
- abi_version = GCJ_CURRENT_BC_ABI_VERSION;
+ {
+ abi_version = GCJ_CURRENT_BC_ABI_VERSION;
+ abi_version |= FLAG_BINARYCOMPAT_ABI;
+ }
+ else /* C++ ABI */
+ {
+ /* Implicit in this computation is the idea that we won't break the
+ old-style binary ABI in a sub-minor release (e.g., from 4.0.0 to
+ 4.0.1). */
+ abi_version = 100000 * major + 1000 * minor;
+ }
if (flag_bootstrap_classes)
- abi_version += GCJ_BOOTSTRAP_LOADER_ADDITION;
+ abi_version |= FLAG_BOOTSTRAP_LOADER;
gcj_abi_version = build_int_cstu (ptr_type_node, abi_version);
}
@@ -2133,6 +2147,30 @@ java_mark_decl_local (tree decl)
make_decl_rtl (decl);
}
+/* Given appropriate target support, G++ will emit hidden aliases for native
+ methods. Using this hidden name is required for proper operation of
+ _Jv_Method::ncode, but it doesn't hurt to use it everywhere. Look for
+ proper target support, then mark the method for aliasing. */
+
+static void
+java_mark_cni_decl_local (tree decl)
+{
+ /* Setting DECL_LOCAL_CNI_METHOD_P changes the behaviour of the mangler.
+ We expect that we should not yet have referenced this decl in a
+ context that requires it. Check this invariant even if we don't have
+ support for hidden aliases. */
+ gcc_assert (!DECL_ASSEMBLER_NAME_SET_P (decl));
+
+#if !defined(HAVE_GAS_HIDDEN) || !defined(ASM_OUTPUT_DEF)
+ return;
+#endif
+
+ DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
+ DECL_LOCAL_CNI_METHOD_P (decl) = 1;
+}
+
+/* Use the preceeding two functions and mark all members of the class. */
+
void
java_mark_class_local (tree class)
{
@@ -2143,8 +2181,13 @@ java_mark_class_local (tree class)
java_mark_decl_local (t);
for (t = TYPE_METHODS (class); t ; t = TREE_CHAIN (t))
- if (!METHOD_ABSTRACT (t) && (!METHOD_NATIVE (t) || flag_jni))
- java_mark_decl_local (t);
+ if (!METHOD_ABSTRACT (t))
+ {
+ if (METHOD_NATIVE (t) && !flag_jni)
+ java_mark_cni_decl_local (t);
+ else
+ java_mark_decl_local (t);
+ }
}
/* Add a statement to a compound_expr. */
diff --git a/gcc/java/java-tree.h b/gcc/java/java-tree.h
index 68eb1d6c55d..37995632f21 100644
--- a/gcc/java/java-tree.h
+++ b/gcc/java/java-tree.h
@@ -71,7 +71,7 @@ struct JCF;
IS_CRAFTED_STRING_BUFFER_P (in CALL_EXPR)
IS_INIT_CHECKED (in SAVE_EXPR)
6: CAN_COMPLETE_NORMALLY (in statement nodes)
- OUTER_FIELD_ACCESS_IDENTIFIER_P (in IDENTIFIER_NODE)
+ NESTED_FIELD_ACCESS_IDENTIFIER_P (in IDENTIFIER_NODE)
Usage of TYPE_LANG_FLAG_?:
0: CLASS_ACCESS0_GENERATED_P (in RECORD_TYPE)
@@ -818,6 +818,9 @@ union lang_tree_node
#define DECL_FIXED_CONSTRUCTOR_P(DECL) \
(DECL_LANG_SPECIFIC(DECL)->u.f.fixed_ctor)
+#define DECL_LOCAL_CNI_METHOD_P(NODE) \
+ (DECL_LANG_SPECIFIC (NODE)->u.f.local_cni)
+
/* A constructor that calls this. */
#define DECL_INIT_CALLS_THIS(DECL) \
(DECL_LANG_SPECIFIC(DECL)->u.f.init_calls_this)
@@ -893,16 +896,16 @@ union lang_tree_node
#define DECL_LOCAL_START_PC(NODE) (DECL_LANG_SPECIFIC (NODE)->u.v.start_pc)
/* The end (bytecode) pc for the valid range of this local variable. */
#define DECL_LOCAL_END_PC(NODE) (DECL_LANG_SPECIFIC (NODE)->u.v.end_pc)
-/* For a VAR_DECLor PARM_DECL, used to chain decls with the same
+/* For a VAR_DECL or PARM_DECL, used to chain decls with the same
slot_number in decl_map. */
#define DECL_LOCAL_SLOT_CHAIN(NODE) (DECL_LANG_SPECIFIC(NODE)->u.v.slot_chain)
/* For a FIELD_DECL, holds the name of the access method. Used to
- read/write the content of the field from an inner class. */
-#define FIELD_INNER_ACCESS(DECL) \
+ read/write the content of the field across nested class boundaries. */
+#define FIELD_NESTED_ACCESS(DECL) \
(DECL_LANG_SPECIFIC (VAR_OR_FIELD_CHECK (DECL))->u.v.am)
-/* Safely tests whether FIELD_INNER_ACCESS exists or not. */
-#define FIELD_INNER_ACCESS_P(DECL) \
- DECL_LANG_SPECIFIC (DECL) && FIELD_INNER_ACCESS (DECL)
+/* Safely tests whether FIELD_NESTED_ACCESS exists or not. */
+#define FIELD_NESTED_ACCESS_P(DECL) \
+ DECL_LANG_SPECIFIC (DECL) && FIELD_NESTED_ACCESS (DECL)
/* True if a final field was initialized upon its declaration
or in an initializer. Set after definite assignment. */
#define DECL_FIELD_FINAL_IUD(NODE) (DECL_LANG_SPECIFIC (NODE)->u.v.final_iud)
@@ -931,6 +934,12 @@ union lang_tree_node
(DECL_LANG_SPECIFIC (NODE)->u.v.freed)
#define LOCAL_SLOT_P(NODE) \
(DECL_LANG_SPECIFIC (NODE)->u.v.local_slot)
+
+#define DECL_CLASS_FIELD_P(NODE) \
+ (DECL_LANG_SPECIFIC (NODE)->u.v.class_field)
+#define DECL_VTABLE_P(NODE) \
+ (DECL_LANG_SPECIFIC (NODE)->u.v.vtable)
+
/* Create a DECL_LANG_SPECIFIC if necessary. */
#define MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC(T) \
if (DECL_LANG_SPECIFIC (T) == NULL) \
@@ -993,7 +1002,8 @@ struct lang_decl_func GTY(())
unsigned int invisible : 1; /* Set for methods we generate
internally but which shouldn't be
written to the .class file. */
- unsigned int dummy:1;
+ unsigned int dummy : 1;
+ unsigned int local_cni : 1; /* Decl needs mangle_local_cni_method. */
};
struct treetreehash_entry GTY(())
@@ -1037,6 +1047,8 @@ struct lang_decl_var GTY(())
unsigned int cif : 1; /* True: decl is a class initialization flag */
unsigned int freed : 1; /* Decl is no longer in scope. */
unsigned int local_slot : 1; /* Decl is a temporary in the stack frame. */
+ unsigned int class_field : 1; /* Decl needs mangle_class_field. */
+ unsigned int vtable : 1; /* Decl needs mangle_vtable. */
};
/* This is what 'lang_decl' really points to. */
@@ -1367,7 +1379,7 @@ extern void init_jcf_parse (void);
extern void init_src_parse (void);
extern int cxx_keyword_p (const char *, int);
-extern tree java_mangle_decl (struct obstack *, tree);
+extern void java_mangle_decl (tree);
extern tree java_mangle_class_field (struct obstack *, tree);
extern tree java_mangle_vtable (struct obstack *, tree);
extern void append_gpp_mangled_name (const char *, int);
@@ -1677,9 +1689,9 @@ extern tree *type_map;
/* True if NODE (a statement) can complete normally. */
#define CAN_COMPLETE_NORMALLY(NODE) TREE_LANG_FLAG_6 (NODE)
-/* True if NODE (an IDENTIFIER) bears the name of a outer field from
- inner class access function. */
-#define OUTER_FIELD_ACCESS_IDENTIFIER_P(NODE) \
+/* True if NODE (an IDENTIFIER) bears the name of an outer field from
+ inner class (or vice versa) access function. */
+#define NESTED_FIELD_ACCESS_IDENTIFIER_P(NODE) \
TREE_LANG_FLAG_6 (IDENTIFIER_NODE_CHECK (NODE))
/* True if NODE belongs to an inner class TYPE_DECL node.
diff --git a/gcc/java/jcf-write.c b/gcc/java/jcf-write.c
index 6f1516d5a1a..5deb5c84487 100644
--- a/gcc/java/jcf-write.c
+++ b/gcc/java/jcf-write.c
@@ -3087,7 +3087,7 @@ generate_classfile (tree clas, struct jcf_partial *state)
/* Make room for the Synthetic attribute (of zero length.) */
if (DECL_FINIT_P (part)
|| DECL_INSTINIT_P (part)
- || OUTER_FIELD_ACCESS_IDENTIFIER_P (DECL_NAME (part))
+ || NESTED_FIELD_ACCESS_IDENTIFIER_P (DECL_NAME (part))
|| TYPE_DOT_CLASS (clas) == part)
{
i++;
diff --git a/gcc/java/lang.c b/gcc/java/lang.c
index e0d2672b2a5..4ade9364113 100644
--- a/gcc/java/lang.c
+++ b/gcc/java/lang.c
@@ -213,6 +213,9 @@ struct language_function GTY(())
#undef LANG_HOOKS_CLEAR_BINDING_STACK
#define LANG_HOOKS_CLEAR_BINDING_STACK java_clear_binding_stack
+#undef LANG_HOOKS_SET_DECL_ASSEMBLER_NAME
+#define LANG_HOOKS_SET_DECL_ASSEMBLER_NAME java_mangle_decl
+
/* Each front end provides its own. */
const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
diff --git a/gcc/java/mangle.c b/gcc/java/mangle.c
index e0b53a13c2b..22a391839a7 100644
--- a/gcc/java/mangle.c
+++ b/gcc/java/mangle.c
@@ -35,11 +35,14 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#include "java-tree.h"
#include "obstack.h"
#include "toplev.h"
-#include "obstack.h"
#include "ggc.h"
+#include "langhooks-def.h"
+static void mangle_class_field (tree);
+static void mangle_vtable (tree);
static void mangle_field_decl (tree);
static void mangle_method_decl (tree);
+static void mangle_local_cni_method_decl (tree);
static void mangle_type (tree);
static void mangle_pointer_type (tree);
@@ -55,15 +58,15 @@ static void set_type_package_list (tree);
static int entry_match_pointer_p (tree, int);
static void emit_compression_string (int);
-static void init_mangling (struct obstack *);
+static void init_mangling (void);
static tree finish_mangling (void);
static void compression_table_add (tree);
static void mangle_member_name (tree);
-/* We use an incoming obstack, always to be provided to the interface
- functions. */
+static struct obstack mangle_obstack_1;
struct obstack *mangle_obstack;
+
#define MANGLE_RAW_STRING(S) \
obstack_grow (mangle_obstack, (S), sizeof (S)-1)
@@ -73,46 +76,75 @@ static GTY(()) tree atms;
/* This is the mangling interface: a decl, a class field (.class) and
the vtable. */
-tree
-java_mangle_decl (struct obstack *obstack, tree decl)
+void
+java_mangle_decl (tree decl)
{
- init_mangling (obstack);
- switch (TREE_CODE (decl))
+ /* A copy of the check from the beginning of lhd_set_decl_assembler_name.
+ Only FUNCTION_DECLs and VAR_DECLs for variables with static storage
+ duration need a real DECL_ASSEMBLER_NAME. */
+ gcc_assert (TREE_CODE (decl) == FUNCTION_DECL
+ || (TREE_CODE (decl) == VAR_DECL
+ && (TREE_STATIC (decl)
+ || DECL_EXTERNAL (decl)
+ || TREE_PUBLIC (decl))));
+
+ /* Mangling only applies to class members. */
+ if (DECL_CONTEXT (decl) && TYPE_P (DECL_CONTEXT (decl)))
{
- case VAR_DECL:
- mangle_field_decl (decl);
- break;
- case FUNCTION_DECL:
- mangle_method_decl (decl);
- break;
- default:
- internal_error ("can't mangle %s", tree_code_name [TREE_CODE (decl)]);
+ init_mangling ();
+ switch (TREE_CODE (decl))
+ {
+ case VAR_DECL:
+ if (DECL_LANG_SPECIFIC (decl))
+ {
+ if (DECL_CLASS_FIELD_P (decl))
+ {
+ mangle_class_field (DECL_CONTEXT (decl));
+ break;
+ }
+ else if (DECL_VTABLE_P (decl))
+ {
+ mangle_vtable (DECL_CONTEXT (decl));
+ break;
+ }
+ }
+ mangle_field_decl (decl);
+ break;
+
+ case FUNCTION_DECL:
+ if (DECL_LANG_SPECIFIC (decl) && DECL_LOCAL_CNI_METHOD_P (decl))
+ mangle_local_cni_method_decl (decl);
+ else
+ mangle_method_decl (decl);
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+ SET_DECL_ASSEMBLER_NAME (decl, finish_mangling ());
}
- return finish_mangling ();
+ else
+ lhd_set_decl_assembler_name (decl);
}
-tree
-java_mangle_class_field (struct obstack *obstack, tree type)
+/* Beginning of the helper functions */
+
+static void
+mangle_class_field (tree type)
{
- init_mangling (obstack);
mangle_record_type (type, /* for_pointer = */ 0);
MANGLE_RAW_STRING ("6class$");
obstack_1grow (mangle_obstack, 'E');
- return finish_mangling ();
}
-tree
-java_mangle_vtable (struct obstack *obstack, tree type)
+static void
+mangle_vtable (tree type)
{
- init_mangling (obstack);
MANGLE_RAW_STRING ("TV");
mangle_record_type (type, /* for_pointer = */ 0);
obstack_1grow (mangle_obstack, 'E');
- return finish_mangling ();
}
-/* Beginning of the helper functions */
-
/* This mangles a field decl */
static void
@@ -167,6 +199,18 @@ mangle_method_decl (tree mdecl)
}
}
+/* This mangles a CNI method for a local class. If the target supports
+ hidden aliases, then G++ will have generated one for us. It is the
+ responsibility of java_mark_class_local to check target support, since
+ we need to set DECL_VISIBILITY (or not) much earlier. */
+
+static void
+mangle_local_cni_method_decl (tree decl)
+{
+ MANGLE_RAW_STRING ("GA");
+ mangle_method_decl (decl);
+}
+
/* This mangles a member name, like a function name or a field
name. Handle cases were `name' is a C++ keyword. Return a nonzero
value if unicode encoding was required. */
@@ -585,17 +629,19 @@ compression_table_add (tree type)
/* Mangling initialization routine. */
static void
-init_mangling (struct obstack *obstack)
+init_mangling (void)
{
- mangle_obstack = obstack;
- if (!compression_table)
- compression_table = make_tree_vec (10);
- else
- /* Mangling already in progress. */
- abort ();
+ if (!mangle_obstack)
+ {
+ mangle_obstack = &mangle_obstack_1;
+ gcc_obstack_init (mangle_obstack);
+ }
+
+ gcc_assert (compression_table == NULL);
+ compression_table = make_tree_vec (10);
/* Mangled name are to be suffixed */
- obstack_grow (mangle_obstack, "_Z", 2);
+ MANGLE_RAW_STRING ("_Z");
}
/* Mangling finalization routine. The mangled name is returned as a
@@ -606,18 +652,14 @@ finish_mangling (void)
{
tree result;
- if (!compression_table)
- /* Mangling already finished. */
- abort ();
+ gcc_assert (compression_table);
compression_table = NULL_TREE;
compression_next = 0;
obstack_1grow (mangle_obstack, '\0');
result = get_identifier (obstack_base (mangle_obstack));
obstack_free (mangle_obstack, obstack_base (mangle_obstack));
-#if 0
- printf ("// %s\n", IDENTIFIER_POINTER (result));
-#endif
+
return result;
}
diff --git a/gcc/java/parse.y b/gcc/java/parse.y
index 388062e625a..9067dfc1ba2 100644
--- a/gcc/java/parse.y
+++ b/gcc/java/parse.y
@@ -320,19 +320,17 @@ static tree build_current_thisn (tree);
static tree build_access_to_thisn (tree, tree, int);
static tree maybe_build_thisn_access_method (tree);
-static tree build_outer_field_access (tree, tree);
-static tree build_outer_field_access_methods (tree);
-static tree build_outer_field_access_expr (int, tree, tree,
- tree, tree);
+static tree build_nested_field_access (tree, tree);
+static tree build_nested_field_access_methods (tree);
+static tree build_nested_field_access_method (tree, tree, tree, tree, tree);
+static tree build_nested_field_access_expr (int, tree, tree, tree, tree);
static tree build_outer_method_access_method (tree);
static tree build_new_access_id (void);
-static tree build_outer_field_access_method (tree, tree, tree,
- tree, tree);
-static int outer_field_access_p (tree, tree);
-static int outer_field_expanded_access_p (tree, tree *,
- tree *, tree *);
-static tree outer_field_access_fix (tree, tree, tree);
+static int nested_field_access_p (tree, tree);
+static int nested_field_expanded_access_p (tree, tree *, tree *, tree *);
+static tree nested_field_access_fix (tree, tree, tree);
+
static tree build_incomplete_class_ref (int, tree);
static tree patch_incomplete_class_ref (tree);
static tree create_anonymous_class (tree);
@@ -8289,114 +8287,159 @@ java_expand_method_bodies (tree class)
fields either directly by using the relevant access to this$<n> or
by invoking an access method crafted for that purpose. */
-/* Build the necessary access from an inner class to an outer
- class. This routine could be optimized to cache previous result
+/* Build the necessary access across nested class boundaries.
+ This routine could be optimized to cache previous result
(decl, current_class and returned access). When an access method
- needs to be generated, it always takes the form of a read. It might
- be later turned into a write by calling outer_field_access_fix. */
+ needs to be generated, it always takes the form of a read. It might
+ be later turned into a write by calling nested_field_access_fix. */
static tree
-build_outer_field_access (tree id, tree decl)
+build_nested_field_access (tree id, tree decl)
{
tree access = NULL_TREE;
- tree ctx = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (current_class)));
+ tree ctx = NULL_TREE;
tree decl_ctx = DECL_CONTEXT (decl);
+ bool is_static = FIELD_STATIC (decl);
+
+ if (DECL_CONTEXT (TYPE_NAME (current_class)))
+ ctx = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (current_class)));
- /* If the immediate enclosing context of the current class is the
- field decl's class or inherits from it; build the access as
- `this$<n>.<field>'. Note that we will break the `private' barrier
- if we're not emitting bytecodes. */
- if ((ctx == decl_ctx || inherits_from_p (ctx, decl_ctx))
- && (!FIELD_PRIVATE (decl) || !flag_emit_class_files ))
+ /* For non-static fields, if the immediate enclosing context of the
+ current class is the field decl's class or inherits from it,
+ build the access as `this$<n>.<field>'. Note that we will break
+ the `private' barrier if we're not emitting bytecodes. */
+ if (!is_static
+ && ctx
+ && (ctx == decl_ctx || inherits_from_p (ctx, decl_ctx))
+ && (!FIELD_PRIVATE (decl) || !flag_emit_class_files))
{
tree thisn = build_current_thisn (current_class);
access = make_qualified_primary (build_wfl_node (thisn),
id, EXPR_WFL_LINECOL (id));
}
- /* Otherwise, generate access methods to outer this and access the
- field (either using an access method or by direct access.) */
+ /* Otherwise, generate and use accessor methods for the field as
+ needed. */
else
{
int lc = EXPR_WFL_LINECOL (id);
/* Now we chain the required number of calls to the access$0 to
- get a hold to the enclosing instance we need, and then we
- build the field access. */
- access = build_access_to_thisn (current_class, decl_ctx, lc);
+ get a hold to the enclosing instance we need for a non-static
+ field, and then we build the field access. */
+ if (!is_static)
+ access = build_access_to_thisn (current_class, decl_ctx, lc);
/* If the field is private and we're generating bytecode, then
- we generate an access method */
- if (FIELD_PRIVATE (decl) && flag_emit_class_files )
+ we generate an access method. */
+ if (FIELD_PRIVATE (decl) && flag_emit_class_files)
{
- tree name = build_outer_field_access_methods (decl);
- access = build_outer_field_access_expr (lc, decl_ctx,
- name, access, NULL_TREE);
+ tree name = build_nested_field_access_methods (decl);
+ access = build_nested_field_access_expr (lc, decl_ctx,
+ name, access, NULL_TREE);
}
- /* Otherwise we use `access$(this$<j>). ... access$(this$<i>).<field>'.
+ /* Otherwise we use `access$(this$<j>). ... access$(this$<i>).<field>'
+ for non-static fields.
Once again we break the `private' access rule from a foreign
- class. */
+ class. */
+ else if (is_static)
+ {
+ tree class_name = DECL_NAME (TYPE_NAME (decl_ctx));
+ access
+ = make_qualified_primary (build_wfl_node (class_name), id, lc);
+ }
else
- access = make_qualified_primary (access, id, lc);
+ access = make_qualified_primary (access, id, lc);
}
+
return resolve_expression_name (access, NULL);
}
-/* Return a nonzero value if NODE describes an outer field inner
- access. */
+/* Return a nonzero value if DECL describes a field access across nested
+ class boundaries. That is, DECL is in a class that either encloses,
+ is enclosed by or shares a common enclosing class with, the class
+ TYPE. */
static int
-outer_field_access_p (tree type, tree decl)
+nested_field_access_p (tree type, tree decl)
{
+ bool is_static = false;
+ tree decl_type = DECL_CONTEXT (decl);
+ tree type_root, decl_type_root;
+
+ if (decl_type == type
+ || (TREE_CODE (decl) != FIELD_DECL && TREE_CODE (decl) != VAR_DECL))
+ return 0;
+
if (!INNER_CLASS_TYPE_P (type)
- || TREE_CODE (decl) != FIELD_DECL
- || DECL_CONTEXT (decl) == type)
+ && !(TREE_CODE (decl_type) == RECORD_TYPE
+ && INNER_CLASS_TYPE_P (decl_type)))
return 0;
- /* If the inner class extends the declaration context of the field
- we're trying to access, then this isn't an outer field access */
- if (inherits_from_p (type, DECL_CONTEXT (decl)))
+ is_static = FIELD_STATIC (decl);
+
+ /* If TYPE extends the declaration context of the non-static
+ field we're trying to access, then this isn't a nested field
+ access we need to worry about. */
+ if (!is_static && inherits_from_p (type, decl_type))
return 0;
- for (type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))); ;
- type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))))
+ for (type_root = type;
+ DECL_CONTEXT (TYPE_NAME (type_root));
+ type_root = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type_root))))
{
- if (type == DECL_CONTEXT (decl))
- return 1;
+ if (type_root == decl_type)
+ return 1;
- if (!DECL_CONTEXT (TYPE_NAME (type)))
- {
- /* Before we give up, see whether the field is inherited from
- the enclosing context we're considering. */
- if (inherits_from_p (type, DECL_CONTEXT (decl)))
- return 1;
- break;
- }
+ /* Before we give up, see whether it is a non-static field
+ inherited from the enclosing context we are considering. */
+ if (!DECL_CONTEXT (TYPE_NAME (type_root))
+ && !is_static
+ && inherits_from_p (type_root, decl_type))
+ return 1;
}
+ if (TREE_CODE (decl_type) == RECORD_TYPE
+ && INNER_CLASS_TYPE_P (decl_type))
+ {
+ for (decl_type_root = decl_type;
+ DECL_CONTEXT (TYPE_NAME (decl_type_root));
+ decl_type_root
+ = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (decl_type_root))))
+ {
+ if (decl_type_root == type)
+ return 1;
+ }
+ }
+ else
+ decl_type_root = decl_type;
+
+ if (type_root == decl_type_root)
+ return 1;
+
return 0;
}
-/* Return a nonzero value if NODE represents an outer field inner
- access that was been already expanded. As a side effect, it returns
+/* Return a nonzero value if NODE represents a cross-nested-class
+ access that has already been expanded. As a side effect, it returns
the name of the field being accessed and the argument passed to the
access function, suitable for a regeneration of the access method
- call if necessary. */
+ call if necessary. */
static int
-outer_field_expanded_access_p (tree node, tree *name, tree *arg_type,
- tree *arg)
+nested_field_expanded_access_p (tree node, tree *name, tree *arg_type,
+ tree *arg)
{
int identified = 0;
if (TREE_CODE (node) != CALL_EXPR)
return 0;
- /* Well, gcj generates slightly different tree nodes when compiling
- to native or bytecodes. It's the case for function calls. */
+ /* Well, GCJ generates slightly different tree nodes when compiling
+ to native or bytecodes. It's the case for function calls. */
if (flag_emit_class_files
&& TREE_CODE (node) == CALL_EXPR
- && OUTER_FIELD_ACCESS_IDENTIFIER_P (DECL_NAME (TREE_OPERAND (node, 0))))
+ && NESTED_FIELD_ACCESS_IDENTIFIER_P (DECL_NAME (TREE_OPERAND (node, 0))))
identified = 1;
else if (!flag_emit_class_files)
{
@@ -8408,7 +8451,7 @@ outer_field_expanded_access_p (tree node, tree *name, tree *arg_type,
node = TREE_OPERAND (node, 0);
if (TREE_OPERAND (node, 0)
&& TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL
- && (OUTER_FIELD_ACCESS_IDENTIFIER_P
+ && (NESTED_FIELD_ACCESS_IDENTIFIER_P
(DECL_NAME (TREE_OPERAND (node, 0)))))
identified = 1;
}
@@ -8418,26 +8461,37 @@ outer_field_expanded_access_p (tree node, tree *name, tree *arg_type,
{
tree argument = TREE_OPERAND (node, 1);
*name = DECL_NAME (TREE_OPERAND (node, 0));
- *arg_type = TREE_TYPE (TREE_TYPE (TREE_VALUE (argument)));
- *arg = TREE_VALUE (argument);
+
+ /* The accessors for static fields do not take in a this$<n> argument,
+ so we take the class name from the accessor's context instead. */
+ if (argument)
+ {
+ *arg_type = TREE_TYPE (TREE_TYPE (TREE_VALUE (argument)));
+ *arg = TREE_VALUE (argument);
+ }
+ else
+ {
+ *arg_type = DECL_CONTEXT (TREE_OPERAND (node, 0));
+ *arg = NULL_TREE;
+ }
}
return identified;
}
-/* Detect in NODE an outer field read access from an inner class and
- transform it into a write with RHS as an argument. This function is
- called from the java_complete_lhs when an assignment to a LHS can
- be identified. */
+/* Detect in NODE cross-nested-class field read access and
+ transform it into a write with RHS as an argument. This function
+ is called from the java_complete_lhs when an assignment to a LHS can
+ be identified. */
static tree
-outer_field_access_fix (tree wfl, tree node, tree rhs)
+nested_field_access_fix (tree wfl, tree node, tree rhs)
{
tree name, arg_type, arg;
- if (outer_field_expanded_access_p (node, &name, &arg_type, &arg))
+ if (nested_field_expanded_access_p (node, &name, &arg_type, &arg))
{
- node = build_outer_field_access_expr (EXPR_WFL_LINECOL (wfl),
- arg_type, name, arg, rhs);
+ node = build_nested_field_access_expr (EXPR_WFL_LINECOL (wfl),
+ arg_type, name, arg, rhs);
return java_complete_tree (node);
}
return NULL_TREE;
@@ -8450,23 +8504,34 @@ outer_field_access_fix (tree wfl, tree node, tree rhs)
read access. */
static tree
-build_outer_field_access_expr (int lc, tree type, tree access_method_name,
- tree arg1, tree arg2)
+build_nested_field_access_expr (int lc, tree type, tree access_method_name,
+ tree arg1, tree arg2)
{
tree args, cn, access;
- args = arg1 ? arg1 :
- build_wfl_node (build_current_thisn (current_class));
- args = build_tree_list (NULL_TREE, args);
+ if (arg1)
+ args = build_tree_list (NULL_TREE, arg1);
+ else
+ args = NULL_TREE;
if (arg2)
- args = tree_cons (NULL_TREE, arg2, args);
+ {
+ if (args)
+ args = tree_cons (NULL_TREE, arg2, args);
+ else
+ args = build_tree_list (NULL_TREE, arg2);
+ }
- access = build_method_invocation (build_wfl_node (access_method_name), args);
+ access
+ = build_method_invocation (build_wfl_node (access_method_name), args);
cn = build_wfl_node (DECL_NAME (TYPE_NAME (type)));
+
return make_qualified_primary (cn, access, lc);
}
+/* Build the name of a synthetic accessor used to access class members
+ across nested class boundaries. */
+
static tree
build_new_access_id (void)
{
@@ -8477,8 +8542,8 @@ build_new_access_id (void)
return get_identifier (buffer);
}
-/* Create the static access functions for the outer field DECL. We define a
- read:
+/* Create the static access functions for the cross-nested-class field DECL.
+ We define a read:
TREE_TYPE (<field>) access$<n> (DECL_CONTEXT (<field>) inst$) {
return inst$.field;
}
@@ -8487,63 +8552,89 @@ build_new_access_id (void)
TREE_TYPE (<field>) value$) {
return inst$.field = value$;
}
- We should have a usage flags on the DECL so we can lazily turn the ones
- we're using for code generation. FIXME.
+ For static fields, these methods are generated without the instance
+ parameter.
+ We should have a usage flag on the DECL so we can lazily turn the ones
+ we're using for code generation. FIXME.
*/
static tree
-build_outer_field_access_methods (tree decl)
+build_nested_field_access_methods (tree decl)
{
- tree id, args, stmt, mdecl;
+ tree id, args, stmt, mdecl, class_name = NULL_TREE;
+ bool is_static = FIELD_STATIC (decl);
- if (FIELD_INNER_ACCESS_P (decl))
- return FIELD_INNER_ACCESS (decl);
+ if (FIELD_NESTED_ACCESS_P (decl))
+ return FIELD_NESTED_ACCESS (decl);
MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
- /* Create the identifier and a function named after it. */
+ /* Create the identifier and a function named after it. */
id = build_new_access_id ();
/* The identifier is marked as bearing the name of a generated write
- access function for outer field accessed from inner classes. */
- OUTER_FIELD_ACCESS_IDENTIFIER_P (id) = 1;
+ access function for outer field accessed from inner classes. */
+ NESTED_FIELD_ACCESS_IDENTIFIER_P (id) = 1;
- /* Create the read access */
- args = build_tree_list (inst_id, build_pointer_type (DECL_CONTEXT (decl)));
- TREE_CHAIN (args) = end_params_node;
- stmt = make_qualified_primary (build_wfl_node (inst_id),
- build_wfl_node (DECL_NAME (decl)), 0);
+ /* Create the read access. */
+ if (!is_static)
+ {
+ args = build_tree_list (inst_id,
+ build_pointer_type (DECL_CONTEXT (decl)));
+ TREE_CHAIN (args) = end_params_node;
+ stmt = make_qualified_primary (build_wfl_node (inst_id),
+ build_wfl_node (DECL_NAME (decl)), 0);
+ }
+ else
+ {
+ args = end_params_node;
+ class_name = DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl)));
+ stmt = make_qualified_primary (build_wfl_node (class_name),
+ build_wfl_node (DECL_NAME (decl)), 0);
+ }
stmt = build_return (0, stmt);
- mdecl = build_outer_field_access_method (DECL_CONTEXT (decl),
- TREE_TYPE (decl), id, args, stmt);
+ mdecl = build_nested_field_access_method (DECL_CONTEXT (decl),
+ TREE_TYPE (decl), id, args, stmt);
DECL_FUNCTION_ACCESS_DECL (mdecl) = decl;
- /* Create the write access method. No write access for final variable */
+ /* Create the write access method. No write access for final variable */
if (!FIELD_FINAL (decl))
{
- args = build_tree_list (inst_id,
- build_pointer_type (DECL_CONTEXT (decl)));
- TREE_CHAIN (args) = build_tree_list (wpv_id, TREE_TYPE (decl));
- TREE_CHAIN (TREE_CHAIN (args)) = end_params_node;
- stmt = make_qualified_primary (build_wfl_node (inst_id),
- build_wfl_node (DECL_NAME (decl)), 0);
+ if (!is_static)
+ {
+ args = build_tree_list (inst_id,
+ build_pointer_type (DECL_CONTEXT (decl)));
+ TREE_CHAIN (args) = build_tree_list (wpv_id, TREE_TYPE (decl));
+ TREE_CHAIN (TREE_CHAIN (args)) = end_params_node;
+ stmt = make_qualified_primary (build_wfl_node (inst_id),
+ build_wfl_node (DECL_NAME (decl)),
+ 0);
+ }
+ else
+ {
+ args = build_tree_list (wpv_id, TREE_TYPE (decl));
+ TREE_CHAIN (args) = end_params_node;
+ stmt = make_qualified_primary (build_wfl_node (class_name),
+ build_wfl_node (DECL_NAME (decl)),
+ 0);
+ }
stmt = build_return (0, build_assignment (ASSIGN_TK, 0, stmt,
build_wfl_node (wpv_id)));
- mdecl = build_outer_field_access_method (DECL_CONTEXT (decl),
- TREE_TYPE (decl), id,
- args, stmt);
+ mdecl = build_nested_field_access_method (DECL_CONTEXT (decl),
+ TREE_TYPE (decl), id,
+ args, stmt);
}
DECL_FUNCTION_ACCESS_DECL (mdecl) = decl;
/* Return the access name */
- return FIELD_INNER_ACCESS (decl) = id;
+ return FIELD_NESTED_ACCESS (decl) = id;
}
-/* Build an field access method NAME. */
+/* Build a field access method NAME. */
static tree
-build_outer_field_access_method (tree class, tree type, tree name,
- tree args, tree body)
+build_nested_field_access_method (tree class, tree type, tree name,
+ tree args, tree body)
{
tree saved_current_function_decl, mdecl;
@@ -8587,7 +8678,7 @@ build_outer_method_access_method (tree decl)
/* Obtain an access identifier and mark it */
id = build_new_access_id ();
- OUTER_FIELD_ACCESS_IDENTIFIER_P (id) = 1;
+ NESTED_FIELD_ACCESS_IDENTIFIER_P (id) = 1;
carg = TYPE_ARG_TYPES (TREE_TYPE (decl));
/* Create the arguments, as much as the original */
@@ -8653,7 +8744,7 @@ build_outer_method_access_method (tree decl)
others. Access methods to this$<n> are build on the fly if
necessary. This CAN'T be used to solely access this$<n-1> from
this$<n> (which alway yield to special cases and optimization, see
- for example build_outer_field_access). */
+ for example build_nested_field_access). */
static tree
build_access_to_thisn (tree from, tree to, int lc)
@@ -9456,15 +9547,15 @@ resolve_expression_name (tree id, tree *orig)
/* If we're processing an inner class and we're trying
to access a field belonging to an outer class, build
- the access to the field */
- if (!fs && outer_field_access_p (current_class, decl))
+ the access to the field. */
+ if (nested_field_access_p (current_class, decl))
{
- if (CLASS_STATIC (TYPE_NAME (current_class)))
+ if (!fs && CLASS_STATIC (TYPE_NAME (current_class)))
{
static_ref_err (id, DECL_NAME (decl), current_class);
return error_mark_node;
}
- access = build_outer_field_access (id, decl);
+ access = build_nested_field_access (id, decl);
if (orig)
*orig = access;
return access;
@@ -9993,18 +10084,29 @@ resolve_qualified_expression_name (tree wfl, tree *found_decl,
decl = QUAL_RESOLUTION (q);
if (!type)
{
- if (TREE_CODE (decl) == FIELD_DECL && !FIELD_STATIC (decl))
+ if (TREE_CODE (decl) == FIELD_DECL
+ || TREE_CODE (decl) == VAR_DECL)
{
- if (current_this)
- *where_found = current_this;
- else
- {
- static_ref_err (qual_wfl, DECL_NAME (decl),
- current_class);
- return 1;
- }
- if (outer_field_access_p (current_class, decl))
- decl = build_outer_field_access (qual_wfl, decl);
+ if (TREE_CODE (decl) == FIELD_DECL
+ && !FIELD_STATIC (decl))
+ {
+ if (current_this)
+ *where_found = current_this;
+ else
+ {
+ static_ref_err (qual_wfl, DECL_NAME (decl),
+ current_class);
+ return 1;
+ }
+ }
+ else
+ {
+ *where_found = TREE_TYPE (decl);
+ if (TREE_CODE (*where_found) == POINTER_TYPE)
+ *where_found = TREE_TYPE (*where_found);
+ }
+ if (nested_field_access_p (current_class, decl))
+ decl = build_nested_field_access (qual_wfl, decl);
}
else
{
@@ -10113,7 +10215,7 @@ resolve_qualified_expression_name (tree wfl, tree *found_decl,
}
from_cast = from_super = 0;
- /* It's an access from a type but it isn't static, we
+ /* If it's an access from a type but isn't static, we
make it relative to `this'. */
if (!is_static && from_type)
decl = current_this;
@@ -10128,8 +10230,8 @@ resolve_qualified_expression_name (tree wfl, tree *found_decl,
return 1;
}
- /* We want to keep the location were found it, and the type
- we found. */
+ /* We want to keep the location where we found it, and the
+ type we found. */
*where_found = decl;
*type_found = type;
@@ -10137,10 +10239,18 @@ resolve_qualified_expression_name (tree wfl, tree *found_decl,
qualified this */
if (from_qualified_this)
{
- field_decl = build_outer_field_access (qual_wfl, field_decl);
+ field_decl
+ = build_nested_field_access (qual_wfl, field_decl);
from_qualified_this = 0;
}
+ /* If needed, generate accessors for static field access. */
+ if (is_static
+ && FIELD_PRIVATE (field_decl)
+ && flag_emit_class_files
+ && nested_field_access_p (current_class, field_decl))
+ field_decl = build_nested_field_access (qual_wfl, field_decl);
+
/* This is the decl found and eventually the next one to
search from */
decl = field_decl;
@@ -12120,10 +12230,10 @@ java_complete_lhs (tree node)
if ((nn = patch_string (TREE_OPERAND (node, 1))))
TREE_OPERAND (node, 1) = nn;
- if ((nn = outer_field_access_fix (wfl_op1, TREE_OPERAND (node, 0),
- TREE_OPERAND (node, 1))))
+ if ((nn = nested_field_access_fix (wfl_op1, TREE_OPERAND (node, 0),
+ TREE_OPERAND (node, 1))))
{
- /* We return error_mark_node if outer_field_access_fix
+ /* We return error_mark_node if nested_field_access_fix
detects we write into a final. */
if (nn == error_mark_node)
return error_mark_node;
@@ -14143,7 +14253,7 @@ patch_unaryop (tree node, tree wfl_op)
tree op = TREE_OPERAND (node, 0);
tree op_type = TREE_TYPE (op);
tree prom_type = NULL_TREE, value, decl;
- int outer_field_flag = 0;
+ int nested_field_flag = 0;
int code = TREE_CODE (node);
int error_found = 0;
@@ -14160,10 +14270,11 @@ patch_unaryop (tree node, tree wfl_op)
/* 15.14.2 Prefix Decrement Operator -- */
case PREDECREMENT_EXPR:
op = decl = extract_field_decl (op);
- outer_field_flag = outer_field_expanded_access_p (op, NULL, NULL, NULL);
+ nested_field_flag
+ = nested_field_expanded_access_p (op, NULL, NULL, NULL);
/* We might be trying to change an outer field accessed using
access method. */
- if (outer_field_flag)
+ if (nested_field_flag)
{
/* Retrieve the decl of the field we're trying to access. We
do that by first retrieving the function we would call to
@@ -14217,15 +14328,15 @@ patch_unaryop (tree node, tree wfl_op)
}
/* We remember we might be accessing an outer field */
- if (outer_field_flag)
+ if (nested_field_flag)
{
/* We re-generate an access to the field */
value = build2 (PLUS_EXPR, TREE_TYPE (op),
- build_outer_field_access (wfl_op, decl), value);
+ build_nested_field_access (wfl_op, decl), value);
/* And we patch the original access$() into a write
with plus_op as a rhs */
- return outer_field_access_fix (node, op, value);
+ return nested_field_access_fix (node, op, value);
}
/* And write back into the node. */
@@ -15809,7 +15920,7 @@ check_thrown_exceptions (
int is_array_call = 0;
/* Skip check within generated methods, such as access$<n>. */
- if (OUTER_FIELD_ACCESS_IDENTIFIER_P (DECL_NAME (current_function_decl)))
+ if (NESTED_FIELD_ACCESS_IDENTIFIER_P (DECL_NAME (current_function_decl)))
return;
if (this_expr != NULL_TREE
diff --git a/gcc/java/verify-glue.c b/gcc/java/verify-glue.c
index b8eed71736e..e743f98e8c1 100644
--- a/gcc/java/verify-glue.c
+++ b/gcc/java/verify-glue.c
@@ -30,12 +30,12 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
-#include "errors.h"
#include "parse.h"
#include "verify.h"
#include "java-tree.h"
#include "java-except.h"
+#include "toplev.h"
void *
vfy_alloc (size_t bytes)
diff --git a/gcc/lambda-code.c b/gcc/lambda-code.c
index 13115b0df59..aeba13e0629 100644
--- a/gcc/lambda-code.c
+++ b/gcc/lambda-code.c
@@ -23,7 +23,6 @@
#include "system.h"
#include "coretypes.h"
#include "tm.h"
-#include "errors.h"
#include "ggc.h"
#include "tree.h"
#include "target.h"
@@ -115,8 +114,8 @@
Fourier-Motzkin elimination is used to compute the bounds of the base space
of the lattice. */
-DEF_VEC_P(int);
-DEF_VEC_ALLOC_P(int,heap);
+DEF_VEC_I(int);
+DEF_VEC_ALLOC_I(int,heap);
static bool perfect_nestify (struct loops *,
struct loop *, VEC(tree,heap) *,
diff --git a/gcc/lambda-trans.c b/gcc/lambda-trans.c
index 2179c7f113e..a3a11f190ca 100644
--- a/gcc/lambda-trans.c
+++ b/gcc/lambda-trans.c
@@ -23,7 +23,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "system.h"
#include "coretypes.h"
#include "tm.h"
-#include "errors.h"
#include "ggc.h"
#include "tree.h"
#include "target.h"
diff --git a/gcc/local-alloc.c b/gcc/local-alloc.c
index 1cbc489e668..017530830cb 100644
--- a/gcc/local-alloc.c
+++ b/gcc/local-alloc.c
@@ -991,7 +991,7 @@ update_equiv_regs (void)
/* Now scan all regs killed in an insn to see if any of them are
registers only used that once. If so, see if we can replace the
- reference with the equivalent from. If we can, delete the
+ reference with the equivalent form. If we can, delete the
initializing reference and this register will go away. If we
can't replace the reference, and the initializing reference is
within the same loop (or in an inner loop), then move the register
@@ -1077,6 +1077,11 @@ update_equiv_regs (void)
reg_equiv[regno].init_insns
= XEXP (reg_equiv[regno].init_insns, 1);
+
+ /* Remember to clear REGNO from all basic block's live
+ info. */
+ SET_REGNO_REG_SET (&cleared_regs, regno);
+ clear_regnos++;
}
/* Move the initialization of the register to just before
INSN. Update the flow information. */
diff --git a/gcc/longlong.h b/gcc/longlong.h
index 05a706517b8..57ae6343447 100644
--- a/gcc/longlong.h
+++ b/gcc/longlong.h
@@ -46,8 +46,8 @@
/* Define auxiliary asm macros.
- 1) umul_ppmm(high_prod, low_prod, multipler, multiplicand) multiplies two
- UWtype integers MULTIPLER and MULTIPLICAND, and generates a two UWtype
+ 1) umul_ppmm(high_prod, low_prod, multiplier, multiplicand) multiplies two
+ UWtype integers MULTIPLIER and MULTIPLICAND, and generates a two UWtype
word product in HIGH_PROD and LOW_PROD.
2) __umulsidi3(a,b) multiplies two UWtype integers A and B, and returns a
diff --git a/gcc/loop-doloop.c b/gcc/loop-doloop.c
index 4a2bb8774ee..dd15aab919f 100644
--- a/gcc/loop-doloop.c
+++ b/gcc/loop-doloop.c
@@ -69,12 +69,13 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
/* Return the loop termination condition for PATTERN or zero
if it is not a decrement and branch jump insn. */
-static rtx
+rtx
doloop_condition_get (rtx pattern)
{
rtx cmp;
rtx inc;
rtx reg;
+ rtx inc_src;
rtx condition;
/* The canonical doloop pattern we expect is:
@@ -85,12 +86,13 @@ doloop_condition_get (rtx pattern)
(set (reg) (plus (reg) (const_int -1)))
(additional clobbers and uses)])
- Some machines (IA-64) make the decrement conditional on
- the condition as well, so we don't bother verifying the
- actual decrement. In summary, the branch must be the
- first entry of the parallel (also required by jump.c),
- and the second entry of the parallel must be a set of
- the loop counter register. */
+ Some targets (IA-64) wrap the set of the loop counter in
+ an if_then_else too.
+
+ In summary, the branch must be the first entry of the
+ parallel (also required by jump.c), and the second
+ entry of the parallel must be a set of the loop counter
+ register. */
if (GET_CODE (pattern) != PARALLEL)
return 0;
@@ -99,11 +101,21 @@ doloop_condition_get (rtx pattern)
inc = XVECEXP (pattern, 0, 1);
/* Check for (set (reg) (something)). */
- if (GET_CODE (inc) != SET || ! REG_P (SET_DEST (inc)))
+ if (GET_CODE (inc) != SET)
return 0;
-
- /* Extract loop counter register. */
reg = SET_DEST (inc);
+ if (! REG_P (reg))
+ return 0;
+
+ /* Check if something = (plus (reg) (const_int -1)).
+ On IA-64, this decrement is wrapped in an if_then_else. */
+ inc_src = SET_SRC (inc);
+ if (GET_CODE (inc_src) == IF_THEN_ELSE)
+ inc_src = XEXP (inc_src, 1);
+ if (GET_CODE (inc_src) != PLUS
+ || XEXP (inc_src, 0) != reg
+ || XEXP (inc_src, 1) != constm1_rtx)
+ return 0;
/* Check for (set (pc) (if_then_else (condition)
(label_ref (label))
@@ -118,15 +130,16 @@ doloop_condition_get (rtx pattern)
/* Extract loop termination condition. */
condition = XEXP (SET_SRC (cmp), 0);
- if ((GET_CODE (condition) != GE && GET_CODE (condition) != NE)
- || GET_CODE (XEXP (condition, 1)) != CONST_INT)
+ /* We expect a GE or NE comparison with 0 or 1. */
+ if ((GET_CODE (condition) != GE
+ && GET_CODE (condition) != NE)
+ || (XEXP (condition, 1) != const0_rtx
+ && XEXP (condition, 1) != const1_rtx))
return 0;
- if (XEXP (condition, 0) == reg)
- return condition;
-
- if (GET_CODE (XEXP (condition, 0)) == PLUS
- && XEXP (XEXP (condition, 0), 0) == reg)
+ if ((XEXP (condition, 0) == reg)
+ || (GET_CODE (XEXP (condition, 0)) == PLUS
+ && XEXP (XEXP (condition, 0), 0) == reg))
return condition;
/* ??? If a machine uses a funny comparison, we could return a
diff --git a/gcc/loop-iv.c b/gcc/loop-iv.c
index bacf8382b7f..ba0d64c78f3 100644
--- a/gcc/loop-iv.c
+++ b/gcc/loop-iv.c
@@ -844,7 +844,7 @@ iv_analyze_biv (rtx def, struct rtx_iv *iv)
if (dump_file)
{
- fprintf (dump_file, "Analysing ");
+ fprintf (dump_file, "Analyzing ");
print_rtl (dump_file, def);
fprintf (dump_file, " for bivness.\n");
}
@@ -927,7 +927,7 @@ iv_analyze_op (rtx insn, rtx op, struct rtx_iv *iv)
if (dump_file)
{
- fprintf (dump_file, "Analysing operand ");
+ fprintf (dump_file, "Analyzing operand ");
print_rtl (dump_file, op);
fprintf (dump_file, " of insn ");
print_rtl_single (dump_file, insn);
@@ -1012,7 +1012,7 @@ iv_analyze (rtx insn, rtx def, struct rtx_iv *iv)
if (dump_file)
{
- fprintf (dump_file, "Analysing def of ");
+ fprintf (dump_file, "Analyzing def of ");
print_rtl (dump_file, def);
fprintf (dump_file, " in insn ");
print_rtl_single (dump_file, insn);
diff --git a/gcc/loop.c b/gcc/loop.c
index eaa1bd931b7..a25c1c0cbac 100644
--- a/gcc/loop.c
+++ b/gcc/loop.c
@@ -6719,7 +6719,7 @@ valid_initial_value_p (rtx x, rtx insn, int call_seen, rtx loop_start)
some machines, don't use any hard registers at all. */
if (REGNO (x) < FIRST_PSEUDO_REGISTER
&& (SMALL_REGISTER_CLASSES
- || (call_used_regs[REGNO (x)] && call_seen)))
+ || (call_seen && call_used_regs[REGNO (x)])))
return 0;
/* Don't use registers that have been clobbered before the start of the
diff --git a/gcc/machmode.h b/gcc/machmode.h
index c978c0a9b52..10016f86ac7 100644
--- a/gcc/machmode.h
+++ b/gcc/machmode.h
@@ -115,6 +115,9 @@ extern const unsigned char mode_nunits[NUM_MACHINE_MODES];
extern const unsigned char mode_wider[NUM_MACHINE_MODES];
#define GET_MODE_WIDER_MODE(MODE) mode_wider[MODE]
+extern const unsigned char mode_2xwider[NUM_MACHINE_MODES];
+#define GET_MODE_2XWIDER_MODE(MODE) mode_2xwider[MODE]
+
/* Return the mode for data of a given size SIZE and mode class CLASS.
If LIMIT is nonzero, then don't use modes bigger than MAX_FIXED_MODE_SIZE.
The value is BLKmode if no other mode is found. */
diff --git a/gcc/modulo-sched.c b/gcc/modulo-sched.c
index 2dffc3170a1..082b059bc22 100644
--- a/gcc/modulo-sched.c
+++ b/gcc/modulo-sched.c
@@ -269,74 +269,35 @@ static struct sched_info sms_sched_info =
};
-/* Return the register decremented and tested or zero if it is not a decrement
- and branch jump insn (similar to doloop_condition_get). */
+/* Return the register decremented and tested in INSN,
+ or zero if it is not a decrement-and-branch insn. */
+
static rtx
-doloop_register_get (rtx insn, rtx *comp)
+doloop_register_get (rtx insn ATTRIBUTE_UNUSED)
{
- rtx pattern, cmp, inc, reg, condition;
-
- if (!JUMP_P (insn))
- return NULL_RTX;
- pattern = PATTERN (insn);
-
- /* The canonical doloop pattern we expect is:
-
- (parallel [(set (pc) (if_then_else (condition)
- (label_ref (label))
- (pc)))
- (set (reg) (plus (reg) (const_int -1)))
- (additional clobbers and uses)])
-
- where condition is further restricted to be
- (ne (reg) (const_int 1)). */
-
- if (GET_CODE (pattern) != PARALLEL)
- return NULL_RTX;
-
- cmp = XVECEXP (pattern, 0, 0);
- inc = XVECEXP (pattern, 0, 1);
- /* Return the compare rtx. */
- *comp = cmp;
+#ifdef HAVE_doloop_end
+ rtx pattern, reg, condition;
- /* Check for (set (reg) (something)). */
- if (GET_CODE (inc) != SET || ! REG_P (SET_DEST (inc)))
+ if (! JUMP_P (insn))
return NULL_RTX;
- /* Extract loop counter register. */
- reg = SET_DEST (inc);
-
- /* Check if something = (plus (reg) (const_int -1)). */
- if (GET_CODE (SET_SRC (inc)) != PLUS
- || XEXP (SET_SRC (inc), 0) != reg
- || XEXP (SET_SRC (inc), 1) != constm1_rtx)
- return NULL_RTX;
-
- /* Check for (set (pc) (if_then_else (condition)
- (label_ref (label))
- (pc))). */
- if (GET_CODE (cmp) != SET
- || SET_DEST (cmp) != pc_rtx
- || GET_CODE (SET_SRC (cmp)) != IF_THEN_ELSE
- || GET_CODE (XEXP (SET_SRC (cmp), 1)) != LABEL_REF
- || XEXP (SET_SRC (cmp), 2) != pc_rtx)
- return NULL_RTX;
-
- /* Extract loop termination condition. */
- condition = XEXP (SET_SRC (cmp), 0);
-
- /* Check if condition = (ne (reg) (const_int 1)), which is more
- restrictive than the check in doloop_condition_get:
- if ((GET_CODE (condition) != GE && GET_CODE (condition) != NE)
- || GET_CODE (XEXP (condition, 1)) != CONST_INT). */
- if (GET_CODE (condition) != NE
- || XEXP (condition, 1) != const1_rtx)
+ pattern = PATTERN (insn);
+ condition = doloop_condition_get (pattern);
+ if (! condition)
return NULL_RTX;
- if (XEXP (condition, 0) == reg)
- return reg;
+ if (REG_P (XEXP (condition, 0)))
+ reg = XEXP (condition, 0);
+ else if (GET_CODE (XEXP (condition, 0)) == PLUS
+ && REG_P (XEXP (XEXP (condition, 0), 0)))
+ reg = XEXP (XEXP (condition, 0), 0);
+ else
+ gcc_unreachable ();
+ return reg;
+#else
return NULL_RTX;
+#endif
}
/* Check if COUNT_REG is set to a constant in the PRE_HEADER block, so
@@ -597,6 +558,7 @@ undo_generate_reg_moves (partial_schedule_ptr ps,
delete_insn (crr);
crr = prev;
}
+ SCHED_FIRST_REG_MOVE (u) = NULL_RTX;
}
while (reg_move_replaces)
@@ -1024,7 +986,7 @@ sms_schedule (FILE *dump_file)
for (i = 0; i < loops->num; i++)
{
rtx head, tail;
- rtx count_reg, comp;
+ rtx count_reg;
struct loop *loop = loops->parray[i];
/* For debugging. */
@@ -1087,7 +1049,7 @@ sms_schedule (FILE *dump_file)
}
/* Make sure this is a doloop. */
- if ( !(count_reg = doloop_register_get (tail, &comp)))
+ if ( !(count_reg = doloop_register_get (tail)))
continue;
/* Don't handle BBs with calls or barriers, or !single_set insns. */
@@ -1133,7 +1095,7 @@ sms_schedule (FILE *dump_file)
for (i = 0; i < num_loops; i++)
{
rtx head, tail;
- rtx count_reg, count_init, comp;
+ rtx count_reg, count_init;
int mii, rec_mii;
unsigned stage_count = 0;
HOST_WIDEST_INT loop_count = 0;
@@ -1185,7 +1147,7 @@ sms_schedule (FILE *dump_file)
/* In case of th loop have doloop register it gets special
handling. */
count_init = NULL_RTX;
- if ((count_reg = doloop_register_get (tail, &comp)))
+ if ((count_reg = doloop_register_get (tail)))
{
basic_block pre_header;
@@ -1283,7 +1245,7 @@ sms_schedule (FILE *dump_file)
/* SMS is not profitable so undo the permutation and reg move generation
and return the kernel to its original state. */
if (dump_file)
- fprintf (dump_file, "Undoing SMS becuase it is not profitable.\n");
+ fprintf (dump_file, "Undoing SMS because it is not profitable.\n");
}
else
diff --git a/gcc/opt-functions.awk b/gcc/opt-functions.awk
index 9dc9640d998..9097dfb8d96 100644
--- a/gcc/opt-functions.awk
+++ b/gcc/opt-functions.awk
@@ -89,6 +89,17 @@ function var_name(flags)
return nth_arg(0, opt_args("Var", flags))
}
+# Return the type of variable that should be associated with the given flags.
+function var_type(flags)
+{
+ if (!flag_set_p("Joined.*", flags))
+ return "int "
+ else if (flag_set_p("UInteger", flags))
+ return "int "
+ else
+ return "const char *"
+}
+
# Given that an option has flags FLAGS, return an initializer for the
# "var_cond" and "var_value" fields of its cl_options[] entry.
function var_set(flags)
@@ -109,9 +120,11 @@ function var_set(flags)
vn = var_name(flags);
if (vn)
return "CLVC_BIT_CLEAR, OPTION_MASK_" s
- else
+ else
return "CLVC_BIT_CLEAR, MASK_" s
}
+ if (var_type(flags) == "const char *")
+ return "CLVC_STRING, 0"
return "CLVC_BOOLEAN, 0"
}
diff --git a/gcc/optabs.c b/gcc/optabs.c
index d3c4934c544..2e84ac3a0b8 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -5627,6 +5627,7 @@ expand_bool_compare_and_swap (rtx mem, rtx old_val, rtx new_val, rtx target)
emit_jump_insn (bcc_gen_fctn[EQ] (label0));
emit_move_insn (target, const0_rtx);
emit_jump_insn (gen_jump (label1));
+ emit_barrier ();
emit_label (label0);
emit_move_insn (target, const1_rtx);
emit_label (label1);
diff --git a/gcc/optc-gen.awk b/gcc/optc-gen.awk
index 4c4eef7a8a2..a71eb2a05b0 100644
--- a/gcc/optc-gen.awk
+++ b/gcc/optc-gen.awk
@@ -77,8 +77,10 @@ for (i = 0; i < n_opts; i++) {
else if (name in var_seen)
continue;
- printf ("/* Set by -%s.\n %s */\nint %s%s;\n\n",
- opts[i], help[i], name,init)
+ print "/* Set by -" opts[i] "."
+ print " " help[i] " */"
+ print var_type(flags[i]) name init ";"
+ print ""
var_seen[name] = 1;
}
diff --git a/gcc/opth-gen.awk b/gcc/opth-gen.awk
index e95af00d2c4..1a63bc90f63 100644
--- a/gcc/opth-gen.awk
+++ b/gcc/opth-gen.awk
@@ -68,12 +68,9 @@ for (i = 0; i < n_opts; i++) {
if (name == "")
continue;
- print "/* Set by -" opts[i] "."
- print " " help[i] " */"
- print "extern int " name ";"
- print ""
-
- }
+ print "extern " var_type(flags[i]) name ";"
+}
+print ""
for (i = 0; i < n_opts; i++) {
name = opt_args("Mask", flags[i])
diff --git a/gcc/opts.c b/gcc/opts.c
index 312209cabb1..16f53fc68ab 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -111,8 +111,10 @@ static void complain_wrong_lang (const char *, const struct cl_option *,
unsigned int lang_mask);
static void handle_options (unsigned int, const char **, unsigned int);
static void wrap_help (const char *help, const char *item, unsigned int);
+static void print_target_help (void);
static void print_help (void);
static void print_param_help (void);
+static void print_filtered_help (unsigned int);
static unsigned int print_switch (const char *text, unsigned int indent);
static void set_debug_level (enum debug_info_type type, int extended,
const char *arg);
@@ -295,16 +297,7 @@ handle_option (const char **argv, unsigned int lang_mask)
}
if (opt_index == cl_options_count)
- {
-#if defined (TARGET_OPTIONS) || defined (TARGET_SWITCHES)
- if (opt[1] == 'm')
- {
- set_target_switch (argv[0] + 2);
- result = 1;
- }
-#endif
- goto done;
- }
+ goto done;
option = &cl_options[opt_index];
@@ -380,25 +373,31 @@ handle_option (const char **argv, unsigned int lang_mask)
}
if (option->flag_var)
- switch (option->var_cond)
+ switch (option->var_type)
{
case CLVC_BOOLEAN:
- *option->flag_var = value;
+ *(int *) option->flag_var = value;
break;
case CLVC_EQUAL:
- *option->flag_var = value ? option->var_value : !option->var_value;
+ *(int *) option->flag_var = (value
+ ? option->var_value
+ : !option->var_value);
break;
case CLVC_BIT_CLEAR:
case CLVC_BIT_SET:
- if ((value != 0) == (option->var_cond == CLVC_BIT_SET))
- *option->flag_var |= option->var_value;
+ if ((value != 0) == (option->var_type == CLVC_BIT_SET))
+ *(int *) option->flag_var |= option->var_value;
else
- *option->flag_var &= ~option->var_value;
+ *(int *) option->flag_var &= ~option->var_value;
if (option->flag_var == &target_flags)
target_flags_explicit |= option->var_value;
break;
+
+ case CLVC_STRING:
+ *(const char **) option->flag_var = arg;
+ break;
}
if (option->flags & lang_mask)
@@ -628,7 +627,6 @@ decode_options (unsigned int argc, const char **argv)
/* Initialize target_flags before OPTIMIZATION_OPTIONS so the latter can
modify it. */
target_flags = targetm.default_target_flags;
- set_target_switch ("");
/* Unwind tables are always present when a target has ABI-specified unwind
tables, so the default should be ON. */
@@ -721,7 +719,7 @@ common_handle_option (size_t scode, const char *arg, int value)
break;
case OPT__target_help:
- display_target_options ();
+ print_target_help ();
exit_after_options = true;
break;
@@ -932,7 +930,7 @@ common_handle_option (size_t scode, const char *arg, int value)
else if (!strcmp(arg, "protected"))
default_visibility = VISIBILITY_PROTECTED;
else
- error ("unrecognised visibility value \"%s\"", arg);
+ error ("unrecognized visibility value \"%s\"", arg);
}
break;
@@ -1208,6 +1206,27 @@ set_debug_level (enum debug_info_type type, int extended, const char *arg)
}
}
+/* Display help for target options. */
+static void
+print_target_help (void)
+{
+ unsigned int i;
+ static bool displayed = false;
+
+ /* Avoid double printing for --help --target-help. */
+ if (displayed)
+ return;
+
+ displayed = true;
+ for (i = 0; i < cl_options_count; i++)
+ if ((cl_options[i].flags & (CL_TARGET | CL_UNDOCUMENTED)) == CL_TARGET)
+ {
+ printf (_("\nTarget specific options:\n"));
+ print_filtered_help (CL_TARGET);
+ break;
+ }
+}
+
/* Output --help text. */
static void
print_help (void)
@@ -1234,8 +1253,7 @@ print_help (void)
lang_names[i]);
print_filtered_help (1U << i);
}
-
- display_target_options ();
+ print_target_help ();
}
/* Print the help for --param. */
@@ -1264,7 +1282,7 @@ print_param_help (void)
}
/* Print help for a specific front-end, etc. */
-void
+static void
print_filtered_help (unsigned int flag)
{
unsigned int i, len, filter, indent = 0;
@@ -1428,19 +1446,56 @@ option_enabled (int opt_idx)
{
const struct cl_option *option = &(cl_options[opt_idx]);
if (option->flag_var)
- switch (option->var_cond)
+ switch (option->var_type)
{
case CLVC_BOOLEAN:
- return *option->flag_var != 0;
+ return *(int *) option->flag_var != 0;
case CLVC_EQUAL:
- return *option->flag_var == option->var_value;
+ return *(int *) option->flag_var == option->var_value;
case CLVC_BIT_CLEAR:
- return (*option->flag_var & option->var_value) == 0;
+ return (*(int *) option->flag_var & option->var_value) == 0;
case CLVC_BIT_SET:
- return (*option->flag_var & option->var_value) != 0;
+ return (*(int *) option->flag_var & option->var_value) != 0;
+
+ case CLVC_STRING:
+ break;
}
return -1;
}
+
+/* Fill STATE with the current state of option OPTION. Return true if
+ there is some state to store. */
+
+bool
+get_option_state (int option, struct cl_option_state *state)
+{
+ if (cl_options[option].flag_var == 0)
+ return false;
+
+ switch (cl_options[option].var_type)
+ {
+ case CLVC_BOOLEAN:
+ case CLVC_EQUAL:
+ state->data = cl_options[option].flag_var;
+ state->size = sizeof (int);
+ break;
+
+ case CLVC_BIT_CLEAR:
+ case CLVC_BIT_SET:
+ state->ch = option_enabled (option);
+ state->data = &state->ch;
+ state->size = 1;
+ break;
+
+ case CLVC_STRING:
+ state->data = *(const char **) cl_options[option].flag_var;
+ if (state->data == 0)
+ state->data = "";
+ state->size = strlen (state->data) + 1;
+ break;
+ }
+ return true;
+}
diff --git a/gcc/opts.h b/gcc/opts.h
index 758f8309abd..bc05ac97957 100644
--- a/gcc/opts.h
+++ b/gcc/opts.h
@@ -22,7 +22,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#define GCC_OPTS_H
/* Specifies how a switch's VAR_VALUE relates to its FLAG_VAR. */
-enum cl_var_cond {
+enum cl_var_type {
/* The switch is enabled when FLAG_VAR is nonzero. */
CLVC_BOOLEAN,
@@ -33,7 +33,11 @@ enum cl_var_cond {
CLVC_BIT_CLEAR,
/* The switch is enabled when VAR_VALUE is set in FLAG_VAR. */
- CLVC_BIT_SET
+ CLVC_BIT_SET,
+
+ /* The switch takes a string argument and FLAG_VAR points to that
+ argument. */
+ CLVC_STRING
};
struct cl_option
@@ -43,11 +47,19 @@ struct cl_option
unsigned short back_chain;
unsigned char opt_len;
unsigned int flags;
- int *flag_var;
- enum cl_var_cond var_cond;
+ void *flag_var;
+ enum cl_var_type var_type;
int var_value;
};
+/* Records that the state of an option consists of SIZE bytes starting
+ at DATA. DATA might point to CH in some cases. */
+struct cl_option_state {
+ const void *data;
+ size_t size;
+ char ch;
+};
+
extern const struct cl_option cl_options[];
extern const unsigned int cl_options_count;
extern const char *const lang_names[];
@@ -73,6 +85,6 @@ extern unsigned num_in_fnames;
extern void decode_options (unsigned int argc, const char **argv);
extern int option_enabled (int opt_idx);
-extern void print_filtered_help (unsigned int);
+extern bool get_option_state (int, struct cl_option_state *);
#endif
diff --git a/gcc/po/ChangeLog b/gcc/po/ChangeLog
index 54e353c6a23..dac737f8a93 100644
--- a/gcc/po/ChangeLog
+++ b/gcc/po/ChangeLog
@@ -1,3 +1,7 @@
+2005-05-31 Joseph S. Myers <joseph@codesourcery.com>
+
+ * sv.po: Update.
+
2005-05-19 Joseph S. Myers <joseph@codesourcery.com>
* de.po, zh_CN.po: Update.
diff --git a/gcc/po/sv.po b/gcc/po/sv.po
index dff8663fdcc..304310826d2 100644
--- a/gcc/po/sv.po
+++ b/gcc/po/sv.po
@@ -1,35 +1,16 @@
-# Swedish translation for the GNU CC.
-# Copyright (C) 2000 Free Software Foundation, Inc.
+# Swedish messages for GCC.
+# Copyright © 2000, 2005 Free Software Foundation, Inc.
# Dennis Björklund <db@zigo.dhs.org>, 2000, 2001, 2002.
-#
-# Kom ihåg att i svenskan så använder vi "" för citat
-# och inte '' som det är i originaluttrycken.
-#
-# Jag har gjort en liten ordlista över uttryck som kan finnas i
-# översättningen
-#
-# http://www.zigo.dhs.org/~dennis/gcc/
-#
-# Denna lista är inte komplett men är det någon som vill hjälpa till
-# att översätta gcc och har åsikter om hur dessa uttryck skall skrivas
-# så ta kontakt så kan vi uppdatera den.
-#
-# Det mesta av övdersättningen som finns nu kommer från tiden
-# innan version 3.0 av gcc. Dessvärre så fungerade aldrig gcc
-# med översättningar korrekt då, så den kom inte till användning.
-# Jag har överfört de gamla strängarna till dagens version (3.2)
-# så det finns en början, men det är mycket kvar. Men vill någon hjälpa
-# till så vore det jättebra. Jag kommer översätta en bit då och då
-# i mån av tid, men det är en stor fil med komplicerade uttryck så
-# det tar en stund att bli klar.
+# Göran Uddeborg <goeran@uddeborg.se>, 2005.
+# $Revision: 1.13 $
#
msgid ""
msgstr ""
-"Project-Id-Version: gcc 3.2\n"
+"Project-Id-Version: gcc 4.0.0\n"
"Report-Msgid-Bugs-To: http://gcc.gnu.org/bugs.html\n"
"POT-Creation-Date: 2005-04-20 21:41-0700\n"
-"PO-Revision-Date: 2002-08-26 12:58+0200\n"
-"Last-Translator: Dennis Björklund <db@zigo.dhs.org>\n"
+"PO-Revision-Date: 2005-05-31 11:09+0200\n"
+"Last-Translator: Göran Uddeborg <goeran@uddeborg.se>\n"
"Language-Team: Swedish <sv@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=iso-8859-1\n"
@@ -508,7 +489,6 @@ msgid "%J%qD defined both normally and as an alias"
msgstr "\"%s\" är definierad både normalt och som ett alias"
#: c-common.c:4579
-#, fuzzy
msgid "alias argument not a string"
msgstr "aliasargumentet är inte en sträng"
@@ -2545,9 +2525,8 @@ msgid "used struct type value where scalar is required"
msgstr "struct-värde använt där skalär krävs"
#: c-objc-common.c:252
-#, fuzzy
msgid "used union type value where scalar is required"
-msgstr "union-värde använt där skalär krävs"
+msgstr "värde av uniontyp använt där skalär krävs"
#: c-opts.c:144
#, fuzzy, c-format
diff --git a/gcc/postreload-gcse.c b/gcc/postreload-gcse.c
index 3734ed1c609..b821db1a122 100644
--- a/gcc/postreload-gcse.c
+++ b/gcc/postreload-gcse.c
@@ -439,7 +439,7 @@ dump_hash_table_entry (void **slot, void *filep)
fprintf (file, "expr: ");
print_rtl (file, expr->expr);
fprintf (file,"\nhashcode: %u\n", expr->hash);
- fprintf (file,"list of occurences:\n");
+ fprintf (file,"list of occurrences:\n");
occr = expr->avail_occr;
while (occr)
{
diff --git a/gcc/predict.c b/gcc/predict.c
index aa696b7ad58..23eae43b143 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -171,8 +171,8 @@ rtl_predicted_by_p (basic_block bb, enum br_predictor predictor)
bool
tree_predicted_by_p (basic_block bb, enum br_predictor predictor)
{
- struct edge_prediction *i = bb_ann (bb)->predictions;
- for (i = bb_ann (bb)->predictions; i; i = i->next)
+ struct edge_prediction *i;
+ for (i = bb->predictions; i; i = i->next)
if (i->predictor == predictor)
return true;
return false;
@@ -235,8 +235,8 @@ tree_predict_edge (edge e, enum br_predictor predictor, int probability)
if (!flag_guess_branch_prob)
return;
- i->next = bb_ann (e->src)->predictions;
- bb_ann (e->src)->predictions = i;
+ i->next = e->src->predictions;
+ e->src->predictions = i;
i->probability = probability;
i->predictor = predictor;
i->edge = e;
@@ -490,7 +490,7 @@ combine_predictions_for_bb (FILE *file, basic_block bb)
{
if (!bb->count)
set_even_probabilities (bb);
- bb_ann (bb)->predictions = NULL;
+ bb->predictions = NULL;
if (file)
fprintf (file, "%i edges in bb %i predicted to even probabilities\n",
nedges, bb->index);
@@ -502,7 +502,7 @@ combine_predictions_for_bb (FILE *file, basic_block bb)
/* We implement "first match" heuristics and use probability guessed
by predictor with smallest index. */
- for (pred = bb_ann (bb)->predictions; pred; pred = pred->next)
+ for (pred = bb->predictions; pred; pred = pred->next)
{
int predictor = pred->predictor;
int probability = pred->probability;
@@ -548,7 +548,7 @@ combine_predictions_for_bb (FILE *file, basic_block bb)
combined_probability = best_probability;
dump_prediction (file, PRED_COMBINED, combined_probability, bb, true);
- for (pred = bb_ann (bb)->predictions; pred; pred = pred->next)
+ for (pred = bb->predictions; pred; pred = pred->next)
{
int predictor = pred->predictor;
int probability = pred->probability;
@@ -558,7 +558,7 @@ combine_predictions_for_bb (FILE *file, basic_block bb)
dump_prediction (file, predictor, probability, bb,
!first_match || best_predictor == predictor);
}
- bb_ann (bb)->predictions = NULL;
+ bb->predictions = NULL;
if (!bb->count)
{
diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c
index a49d9e9a108..5e5fcc74744 100644
--- a/gcc/reg-stack.c
+++ b/gcc/reg-stack.c
@@ -224,6 +224,11 @@ enum emit_where
/* The block we're currently working on. */
static basic_block current_block;
+/* In the current_block, whether we're processing the first register
+ stack or call instruction, i.e. the the regstack is currently the
+ same as BLOCK_INFO(current_block)->stack_in. */
+static bool starting_stack_p;
+
/* This is the register file for all register after conversion. */
static rtx
FP_mode_reg[LAST_STACK_REG+1-FIRST_STACK_REG][(int) MAX_MACHINE_MODE];
@@ -237,7 +242,6 @@ static rtx not_a_num;
/* Forward declarations */
static int stack_regs_mentioned_p (rtx pat);
-static void straighten_stack (rtx, stack);
static void pop_stack (stack, int);
static rtx *get_true_reg (rtx *);
@@ -248,7 +252,6 @@ static void replace_reg (rtx *, int);
static void remove_regno_note (rtx, enum reg_note, unsigned int);
static int get_hard_regnum (stack, rtx);
static rtx emit_pop_insn (rtx, stack, rtx, enum emit_where);
-static void emit_swap_insn (rtx, stack, rtx);
static void swap_to_top(rtx, stack, rtx, rtx);
static bool move_for_stack_reg (rtx, stack, rtx);
static bool move_nan_for_stack_reg (rtx, stack, rtx);
@@ -259,14 +262,8 @@ static bool subst_stack_regs_pat (rtx, stack, rtx);
static void subst_asm_stack_regs (rtx, stack);
static bool subst_stack_regs (rtx, stack);
static void change_stack (rtx, stack, stack, enum emit_where);
-static int convert_regs_entry (void);
-static void convert_regs_exit (void);
-static int convert_regs_1 (FILE *, basic_block);
-static int convert_regs_2 (FILE *, basic_block);
-static int convert_regs (FILE *);
static void print_stack (FILE *, stack);
static rtx next_flags_user (rtx);
-static bool compensate_edge (edge, FILE *);
/* Return nonzero if any stack register is mentioned somewhere within PAT. */
@@ -350,8 +347,7 @@ next_flags_user (rtx insn)
return NULL_RTX;
}
-/* Reorganize the stack into ascending numbers,
- after this insn. */
+/* Reorganize the stack into ascending numbers, before this insn. */
static void
straighten_stack (rtx insn, stack regstack)
@@ -371,7 +367,7 @@ straighten_stack (rtx insn, stack regstack)
for (top = temp_stack.top = regstack->top; top >= 0; top--)
temp_stack.reg[top] = FIRST_STACK_REG + temp_stack.top - top;
- change_stack (insn, regstack, &temp_stack, EMIT_AFTER);
+ change_stack (insn, regstack, &temp_stack, EMIT_BEFORE);
}
/* Pop a register from the stack. */
@@ -398,101 +394,6 @@ pop_stack (stack regstack, int regno)
}
}
-/* Convert register usage from "flat" register file usage to a "stack
- register file. FILE is the dump file, if used.
-
- Construct a CFG and run life analysis. Then convert each insn one
- by one. Run a last cleanup_cfg pass, if optimizing, to eliminate
- code duplication created when the converter inserts pop insns on
- the edges. */
-
-bool
-reg_to_stack (FILE *file)
-{
- basic_block bb;
- int i;
- int max_uid;
-
- /* Clean up previous run. */
- stack_regs_mentioned_data = 0;
-
- /* See if there is something to do. Flow analysis is quite
- expensive so we might save some compilation time. */
- for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
- if (regs_ever_live[i])
- break;
- if (i > LAST_STACK_REG)
- return false;
-
- /* Ok, floating point instructions exist. If not optimizing,
- build the CFG and run life analysis.
- Also need to rebuild life when superblock scheduling is done
- as it don't update liveness yet. */
- if (!optimize
- || (flag_sched2_use_superblocks
- && flag_schedule_insns_after_reload))
- {
- count_or_remove_death_notes (NULL, 1);
- life_analysis (file, PROP_DEATH_NOTES);
- }
- mark_dfs_back_edges ();
-
- /* Set up block info for each basic block. */
- alloc_aux_for_blocks (sizeof (struct block_info_def));
- FOR_EACH_BB_REVERSE (bb)
- {
- edge e;
- edge_iterator ei;
-
- FOR_EACH_EDGE (e, ei, bb->preds)
- if (!(e->flags & EDGE_DFS_BACK)
- && e->src != ENTRY_BLOCK_PTR)
- BLOCK_INFO (bb)->predecessors++;
- }
-
- /* Create the replacement registers up front. */
- for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
- {
- enum machine_mode mode;
- for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
- mode != VOIDmode;
- mode = GET_MODE_WIDER_MODE (mode))
- FP_MODE_REG (i, mode) = gen_rtx_REG (mode, i);
- for (mode = GET_CLASS_NARROWEST_MODE (MODE_COMPLEX_FLOAT);
- mode != VOIDmode;
- mode = GET_MODE_WIDER_MODE (mode))
- FP_MODE_REG (i, mode) = gen_rtx_REG (mode, i);
- }
-
- ix86_flags_rtx = gen_rtx_REG (CCmode, FLAGS_REG);
-
- /* A QNaN for initializing uninitialized variables.
-
- ??? We can't load from constant memory in PIC mode, because
- we're inserting these instructions before the prologue and
- the PIC register hasn't been set up. In that case, fall back
- on zero, which we can get from `ldz'. */
-
- if (flag_pic)
- not_a_num = CONST0_RTX (SFmode);
- else
- {
- not_a_num = gen_lowpart (SFmode, GEN_INT (0x7fc00000));
- not_a_num = force_const_mem (SFmode, not_a_num);
- }
-
- /* Allocate a cache for stack_regs_mentioned. */
- max_uid = get_max_uid ();
- VARRAY_CHAR_INIT (stack_regs_mentioned_data, max_uid + 1,
- "stack_regs_mentioned cache");
-
- convert_regs (file);
-
- free_aux_for_blocks ();
- return true;
-}
-
-
/* Return a pointer to the REG expression within PAT. If PAT is not a
REG, possible enclosed by a conversion rtx, return the inner part of
PAT that stopped the search. */
@@ -965,6 +866,16 @@ emit_swap_insn (rtx insn, stack regstack, rtx reg)
return;
}
+ /* Avoid emitting the swap if this is the first register stack insn
+ of the current_block. Instead update the current_block's stack_in
+ and let compensate edges take care of this for us. */
+ if (current_block && starting_stack_p)
+ {
+ BLOCK_INFO (current_block)->stack_in = *regstack;
+ starting_stack_p = false;
+ return;
+ }
+
swap_rtx = gen_swapxf (FP_MODE_REG (hard_regno, XFmode),
FP_MODE_REG (FIRST_STACK_REG, XFmode));
@@ -1231,9 +1142,9 @@ swap_rtx_condition (rtx insn)
pat = PATTERN (insn);
}
- /* See if this is, or ends in, a fnstsw, aka unspec 9. If so, we're
- not doing anything with the cc value right now. We may be able to
- search for one though. */
+ /* See if this is, or ends in, a fnstsw. If so, we're not doing anything
+ with the cc value right now. We may be able to search for one
+ though. */
if (GET_CODE (pat) == SET
&& GET_CODE (SET_SRC (pat)) == UNSPEC
@@ -1252,9 +1163,13 @@ swap_rtx_condition (rtx insn)
return 0;
}
+ /* We haven't found it. */
+ if (insn == BB_END (current_block))
+ return 0;
+
/* So we've found the insn using this value. If it is anything
- other than sahf, aka unspec 10, or the value does not die
- (meaning we'd have to search further), then we must give up. */
+ other than sahf or the value does not die (meaning we'd have
+ to search further), then we must give up. */
pat = PATTERN (insn);
if (GET_CODE (pat) != SET
|| GET_CODE (SET_SRC (pat)) != UNSPEC
@@ -2302,7 +2217,7 @@ subst_stack_regs (rtx insn, stack regstack)
if (top >= 0)
{
- straighten_stack (PREV_INSN (insn), regstack);
+ straighten_stack (insn, regstack);
/* Now mark the arguments as dead after the call. */
@@ -2393,6 +2308,19 @@ change_stack (rtx insn, stack old, stack new, enum emit_where where)
int reg;
int update_end = 0;
+ /* Stack adjustments for the first insn in a block update the
+ current_block's stack_in instead of inserting insns directly.
+ compensate_edges will add the necessary code later. */
+ if (current_block
+ && starting_stack_p
+ && where == EMIT_BEFORE)
+ {
+ BLOCK_INFO (current_block)->stack_in = *new;
+ starting_stack_p = false;
+ *old = *new;
+ return;
+ }
+
/* We will be inserting new insns "backwards". If we are to insert
after INSN, find the next insn, and insert before it. */
@@ -2604,25 +2532,6 @@ convert_regs_entry (void)
int inserted = 0;
edge e;
edge_iterator ei;
- basic_block block;
-
- FOR_EACH_BB_REVERSE (block)
- {
- block_info bi = BLOCK_INFO (block);
- int reg;
-
- /* Set current register status at last instruction `uninitialized'. */
- bi->stack_in.top = -2;
-
- /* Copy live_at_end and live_at_start into temporaries. */
- for (reg = FIRST_STACK_REG; reg <= LAST_STACK_REG; reg++)
- {
- if (REGNO_REG_SET_P (block->global_live_at_end, reg))
- SET_HARD_REG_BIT (bi->out_reg_set, reg);
- if (REGNO_REG_SET_P (block->global_live_at_start, reg))
- SET_HARD_REG_BIT (bi->stack_in.reg_set, reg);
- }
- }
/* Load something into each stack register live at function entry.
Such live registers can be caused by uninitialized variables or
@@ -2694,9 +2603,29 @@ convert_regs_exit (void)
}
}
-/* Adjust the stack of this block on exit to match the stack of the
- target block, or copy stack info into the stack of the successor
- of the successor hasn't been processed yet. */
+/* Copy the stack info from the end of edge E's source block to the
+ start of E's destination block. */
+
+static void
+propagate_stack (edge e)
+{
+ stack src_stack = &BLOCK_INFO (e->src)->stack_out;
+ stack dest_stack = &BLOCK_INFO (e->dest)->stack_in;
+ int reg;
+
+ /* Preserve the order of the original stack, but check whether
+ any pops are needed. */
+ dest_stack->top = -1;
+ for (reg = 0; reg <= src_stack->top; ++reg)
+ if (TEST_HARD_REG_BIT (dest_stack->reg_set, src_stack->reg[reg]))
+ dest_stack->reg[++dest_stack->top] = src_stack->reg[reg];
+}
+
+
+/* Adjust the stack of edge E's source block on exit to match the stack
+ of it's target block upon input. The stack layouts of both blocks
+ should have been defined by now. */
+
static bool
compensate_edge (edge e, FILE *file)
{
@@ -2711,50 +2640,27 @@ compensate_edge (edge e, FILE *file)
if (file)
fprintf (file, "Edge %d->%d: ", block->index, target->index);
- if (target_stack->top == -2)
+ gcc_assert (target_stack->top != -2);
+
+ /* Check whether stacks are identical. */
+ if (target_stack->top == regstack.top)
{
- /* The target block hasn't had a stack order selected.
- We need merely ensure that no pops are needed. */
- for (reg = regstack.top; reg >= 0; --reg)
- if (!TEST_HARD_REG_BIT (target_stack->reg_set, regstack.reg[reg]))
+ for (reg = target_stack->top; reg >= 0; --reg)
+ if (target_stack->reg[reg] != regstack.reg[reg])
break;
if (reg == -1)
{
if (file)
- fprintf (file, "new block; copying stack position\n");
-
- /* change_stack kills values in regstack. */
- tmpstack = regstack;
-
- change_stack (BB_END (block), &tmpstack, target_stack, EMIT_AFTER);
+ fprintf (file, "no changes needed\n");
return false;
}
-
- if (file)
- fprintf (file, "new block; pops needed\n");
}
- else
- {
- if (target_stack->top == regstack.top)
- {
- for (reg = target_stack->top; reg >= 0; --reg)
- if (target_stack->reg[reg] != regstack.reg[reg])
- break;
- if (reg == -1)
- {
- if (file)
- fprintf (file, "no changes needed\n");
- return false;
- }
- }
-
- if (file)
- {
- fprintf (file, "correcting stack to ");
- print_stack (file, target_stack);
- }
+ if (file)
+ {
+ fprintf (file, "correcting stack to ");
+ print_stack (file, target_stack);
}
/* Care for non-call EH edges specially. The normal return path have
@@ -2829,72 +2735,97 @@ compensate_edge (edge e, FILE *file)
return false;
}
+/* Traverse all non-entry edges in the CFG, and emit the necessary
+ edge compensation code to change the stack from stack_out of the
+ source block to the stack_in of the destination block. */
+
+static bool
+compensate_edges (FILE *file)
+{
+ bool inserted = false;
+ basic_block bb;
+
+ starting_stack_p = false;
+
+ FOR_EACH_BB (bb)
+ if (bb != ENTRY_BLOCK_PTR)
+ {
+ edge e;
+ edge_iterator ei;
+
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ inserted |= compensate_edge (e, file);
+ }
+ return inserted;
+}
+
+/* Select the better of two edges E1 and E2 to use to determine the
+ stack layout for their shared destination basic block. This is
+ typically the more frequently executed. The edge E1 may be NULL
+ (in which case E2 is returned), but E2 is always non-NULL. */
+
+static edge
+better_edge (edge e1, edge e2)
+{
+ if (!e1)
+ return e2;
+
+ if (EDGE_FREQUENCY (e1) > EDGE_FREQUENCY (e2))
+ return e1;
+ if (EDGE_FREQUENCY (e1) < EDGE_FREQUENCY (e2))
+ return e2;
+
+ if (e1->count > e2->count)
+ return e1;
+ if (e1->count < e2->count)
+ return e2;
+
+ /* Prefer critical edges to minimize inserting compensation code on
+ critical edges. */
+
+ if (EDGE_CRITICAL_P (e1) != EDGE_CRITICAL_P (e2))
+ return EDGE_CRITICAL_P (e1) ? e1 : e2;
+
+ /* Avoid non-deterministic behaviour. */
+ return (e1->src->index < e2->src->index) ? e1 : e2;
+}
+
/* Convert stack register references in one block. */
-static int
+static void
convert_regs_1 (FILE *file, basic_block block)
{
struct stack_def regstack;
block_info bi = BLOCK_INFO (block);
- int inserted, reg;
+ int reg;
rtx insn, next;
- edge e, beste = NULL;
bool control_flow_insn_deleted = false;
- edge_iterator ei;
- inserted = 0;
any_malformed_asm = false;
- /* Find the edge we will copy stack from. It should be the most frequent
- one as it will get cheapest after compensation code is generated,
- if multiple such exists, take one with largest count, prefer critical
- one (as splitting critical edges is more expensive), or one with lowest
- index, to avoid random changes with different orders of the edges. */
- FOR_EACH_EDGE (e, ei, block->preds)
- {
- if (e->flags & EDGE_DFS_BACK)
- ;
- else if (! beste)
- beste = e;
- else if (EDGE_FREQUENCY (beste) < EDGE_FREQUENCY (e))
- beste = e;
- else if (EDGE_FREQUENCY (beste) > EDGE_FREQUENCY (e))
- ;
- else if (beste->count < e->count)
- beste = e;
- else if (beste->count > e->count)
- ;
- else if ((EDGE_CRITICAL_P (e) != 0)
- != (EDGE_CRITICAL_P (beste) != 0))
- {
- if (EDGE_CRITICAL_P (e))
- beste = e;
- }
- else if (e->src->index < beste->src->index)
- beste = e;
- }
-
- /* Initialize stack at block entry. */
+ /* Choose an initial stack layout, if one hasn't already been chosen. */
if (bi->stack_in.top == -2)
{
+ edge e, beste = NULL;
+ edge_iterator ei;
+
+ /* Select the best incoming edge (typically the most frequent) to
+ use as a template for this basic block. */
+ FOR_EACH_EDGE (e, ei, block->preds)
+ if (BLOCK_INFO (e->src)->done)
+ beste = better_edge (beste, e);
+
if (beste)
- inserted |= compensate_edge (beste, file);
+ propagate_stack (beste);
else
{
/* No predecessors. Create an arbitrary input stack. */
- int reg;
-
bi->stack_in.top = -1;
for (reg = LAST_STACK_REG; reg >= FIRST_STACK_REG; --reg)
if (TEST_HARD_REG_BIT (bi->stack_in.reg_set, reg))
bi->stack_in.reg[++bi->stack_in.top] = reg;
}
}
- else
- /* Entry blocks do have stack already initialized. */
- beste = NULL;
-
- current_block = block;
if (file)
{
@@ -2904,8 +2835,11 @@ convert_regs_1 (FILE *file, basic_block block)
/* Process all insns in this block. Keep track of NEXT so that we
don't process insns emitted while substituting in INSN. */
+ current_block = block;
next = BB_HEAD (block);
regstack = bi->stack_in;
+ starting_stack_p = true;
+
do
{
insn = next;
@@ -2928,6 +2862,7 @@ convert_regs_1 (FILE *file, basic_block block)
print_stack (file, &regstack);
}
control_flow_insn_deleted |= subst_stack_regs (insn, &regstack);
+ starting_stack_p = false;
}
}
while (next);
@@ -2993,38 +2928,14 @@ convert_regs_1 (FILE *file, basic_block block)
gcc_assert (any_malformed_asm);
win:
bi->stack_out = regstack;
-
- /* Compensate the back edges, as those wasn't visited yet. */
- FOR_EACH_EDGE (e, ei, block->succs)
- {
- if (e->flags & EDGE_DFS_BACK
- || (e->dest == EXIT_BLOCK_PTR))
- {
- gcc_assert (BLOCK_INFO (e->dest)->done
- || e->dest == block);
- inserted |= compensate_edge (e, file);
- }
- }
- FOR_EACH_EDGE (e, ei, block->preds)
- {
- if (e != beste && !(e->flags & EDGE_DFS_BACK)
- && e->src != ENTRY_BLOCK_PTR)
- {
- gcc_assert (BLOCK_INFO (e->src)->done);
- inserted |= compensate_edge (e, file);
- }
- }
-
- return inserted;
}
/* Convert registers in all blocks reachable from BLOCK. */
-static int
+static void
convert_regs_2 (FILE *file, basic_block block)
{
basic_block *stack, *sp;
- int inserted;
/* We process the blocks in a top-down manner, in a way such that one block
is only processed after all its predecessors. The number of predecessors
@@ -3035,7 +2946,6 @@ convert_regs_2 (FILE *file, basic_block block)
*sp++ = block;
- inserted = 0;
do
{
edge e;
@@ -3064,21 +2974,19 @@ convert_regs_2 (FILE *file, basic_block block)
*sp++ = e->dest;
}
- inserted |= convert_regs_1 (file, block);
+ convert_regs_1 (file, block);
BLOCK_INFO (block)->done = 1;
}
while (sp != stack);
free (stack);
-
- return inserted;
}
/* Traverse all basic blocks in a function, converting the register
references in each insn from the "flat" register file that gcc uses,
to the stack-like registers the 387 uses. */
-static int
+static void
convert_regs (FILE *file)
{
int inserted;
@@ -3099,7 +3007,7 @@ convert_regs (FILE *file)
/* Process all blocks reachable from all entry points. */
FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs)
- inserted |= convert_regs_2 (file, e->dest);
+ convert_regs_2 (file, e->dest);
/* ??? Process all unreachable blocks. Though there's no excuse
for keeping these even when not optimizing. */
@@ -3108,8 +3016,11 @@ convert_regs (FILE *file)
block_info bi = BLOCK_INFO (b);
if (! bi->done)
- inserted |= convert_regs_2 (file, b);
+ convert_regs_2 (file, b);
}
+
+ inserted |= compensate_edges (file);
+
clear_aux_for_blocks ();
fixup_abnormal_edges ();
@@ -3118,8 +3029,114 @@ convert_regs (FILE *file)
if (file)
fputc ('\n', file);
+}
+
+/* Convert register usage from "flat" register file usage to a "stack
+ register file. FILE is the dump file, if used.
- return inserted;
+ Construct a CFG and run life analysis. Then convert each insn one
+ by one. Run a last cleanup_cfg pass, if optimizing, to eliminate
+ code duplication created when the converter inserts pop insns on
+ the edges. */
+
+bool
+reg_to_stack (FILE *file)
+{
+ basic_block bb;
+ int i;
+ int max_uid;
+
+ /* Clean up previous run. */
+ stack_regs_mentioned_data = 0;
+
+ /* See if there is something to do. Flow analysis is quite
+ expensive so we might save some compilation time. */
+ for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
+ if (regs_ever_live[i])
+ break;
+ if (i > LAST_STACK_REG)
+ return false;
+
+ /* Ok, floating point instructions exist. If not optimizing,
+ build the CFG and run life analysis.
+ Also need to rebuild life when superblock scheduling is done
+ as it don't update liveness yet. */
+ if (!optimize
+ || (flag_sched2_use_superblocks
+ && flag_schedule_insns_after_reload))
+ {
+ count_or_remove_death_notes (NULL, 1);
+ life_analysis (file, PROP_DEATH_NOTES);
+ }
+ mark_dfs_back_edges ();
+
+ /* Set up block info for each basic block. */
+ alloc_aux_for_blocks (sizeof (struct block_info_def));
+ FOR_EACH_BB (bb)
+ {
+ block_info bi = BLOCK_INFO (bb);
+ edge_iterator ei;
+ edge e;
+ int reg;
+
+ FOR_EACH_EDGE (e, ei, bb->preds)
+ if (!(e->flags & EDGE_DFS_BACK)
+ && e->src != ENTRY_BLOCK_PTR)
+ bi->predecessors++;
+
+ /* Set current register status at last instruction `uninitialized'. */
+ bi->stack_in.top = -2;
+
+ /* Copy live_at_end and live_at_start into temporaries. */
+ for (reg = FIRST_STACK_REG; reg <= LAST_STACK_REG; reg++)
+ {
+ if (REGNO_REG_SET_P (bb->global_live_at_end, reg))
+ SET_HARD_REG_BIT (bi->out_reg_set, reg);
+ if (REGNO_REG_SET_P (bb->global_live_at_start, reg))
+ SET_HARD_REG_BIT (bi->stack_in.reg_set, reg);
+ }
+ }
+
+ /* Create the replacement registers up front. */
+ for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
+ {
+ enum machine_mode mode;
+ for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
+ mode != VOIDmode;
+ mode = GET_MODE_WIDER_MODE (mode))
+ FP_MODE_REG (i, mode) = gen_rtx_REG (mode, i);
+ for (mode = GET_CLASS_NARROWEST_MODE (MODE_COMPLEX_FLOAT);
+ mode != VOIDmode;
+ mode = GET_MODE_WIDER_MODE (mode))
+ FP_MODE_REG (i, mode) = gen_rtx_REG (mode, i);
+ }
+
+ ix86_flags_rtx = gen_rtx_REG (CCmode, FLAGS_REG);
+
+ /* A QNaN for initializing uninitialized variables.
+
+ ??? We can't load from constant memory in PIC mode, because
+ we're inserting these instructions before the prologue and
+ the PIC register hasn't been set up. In that case, fall back
+ on zero, which we can get from `ldz'. */
+
+ if (flag_pic)
+ not_a_num = CONST0_RTX (SFmode);
+ else
+ {
+ not_a_num = gen_lowpart (SFmode, GEN_INT (0x7fc00000));
+ not_a_num = force_const_mem (SFmode, not_a_num);
+ }
+
+ /* Allocate a cache for stack_regs_mentioned. */
+ max_uid = get_max_uid ();
+ VARRAY_CHAR_INIT (stack_regs_mentioned_data, max_uid + 1,
+ "stack_regs_mentioned cache");
+
+ convert_regs (file);
+
+ free_aux_for_blocks ();
+ return true;
}
#endif /* STACK_REGS */
diff --git a/gcc/reload1.c b/gcc/reload1.c
index a1974dfa3b6..0caa411fb4b 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -405,7 +405,6 @@ static int reload_reg_free_for_value_p (int, int, int, enum reload_type,
rtx, rtx, int, int);
static int free_for_value_p (int, enum machine_mode, int, enum reload_type,
rtx, rtx, int, int);
-static int function_invariant_p (rtx);
static int reload_reg_reaches_end_p (unsigned int, int, enum reload_type);
static int allocate_reload_reg (struct insn_chain *, int, int);
static int conflicts_with_override (rtx);
@@ -3315,14 +3314,16 @@ verify_initial_elim_offsets (void)
return true;
#ifdef ELIMINABLE_REGS
- struct elim_table *ep;
-
- for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
- {
- INITIAL_ELIMINATION_OFFSET (ep->from, ep->to, t);
- if (t != ep->initial_offset)
- return false;
- }
+ {
+ struct elim_table *ep;
+
+ for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
+ {
+ INITIAL_ELIMINATION_OFFSET (ep->from, ep->to, t);
+ if (t != ep->initial_offset)
+ return false;
+ }
+ }
#else
INITIAL_FRAME_POINTER_OFFSET (t);
if (t != reg_eliminate[0].initial_offset)
@@ -4982,7 +4983,7 @@ free_for_value_p (int regno, enum machine_mode mode, int opnum,
pic_offset_table_rtx is not, and we must not spill these things to
memory. */
-static int
+int
function_invariant_p (rtx x)
{
if (CONSTANT_P (x))
diff --git a/gcc/rtl.c b/gcc/rtl.c
index 2f52544ee0c..0c46c6066c0 100644
--- a/gcc/rtl.c
+++ b/gcc/rtl.c
@@ -33,7 +33,11 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "rtl.h"
#include "real.h"
#include "ggc.h"
-#include "errors.h"
+#ifdef GENERATOR_FILE
+# include "errors.h"
+#else
+# include "toplev.h"
+#endif
/* Indexed by rtx code, gives number of operands for an rtx with that code.
diff --git a/gcc/rtl.h b/gcc/rtl.h
index 52ea65e7cf5..47a68e9bad3 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -2062,6 +2062,9 @@ extern void dbr_schedule (rtx, FILE *);
extern void dump_local_alloc (FILE *);
extern int local_alloc (void);
+/* In reload1.c */
+extern int function_invariant_p (rtx);
+
/* In reg-stack.c */
extern bool reg_to_stack (FILE *);
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index d7e9da6062f..338978992df 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -145,6 +145,7 @@ avoid_constant_pool_reference (rtx x)
{
rtx c, tmp, addr;
enum machine_mode cmode;
+ HOST_WIDE_INT offset = 0;
switch (GET_CODE (x))
{
@@ -173,26 +174,40 @@ avoid_constant_pool_reference (rtx x)
/* Call target hook to avoid the effects of -fpic etc.... */
addr = targetm.delegitimize_address (addr);
+ /* Split the address into a base and integer offset. */
+ if (GET_CODE (addr) == CONST
+ && GET_CODE (XEXP (addr, 0)) == PLUS
+ && GET_CODE (XEXP (XEXP (addr, 0), 1)) == CONST_INT)
+ {
+ offset = INTVAL (XEXP (XEXP (addr, 0), 1));
+ addr = XEXP (XEXP (addr, 0), 0);
+ }
+
if (GET_CODE (addr) == LO_SUM)
addr = XEXP (addr, 1);
- if (GET_CODE (addr) != SYMBOL_REF
- || ! CONSTANT_POOL_ADDRESS_P (addr))
- return x;
-
- c = get_pool_constant (addr);
- cmode = get_pool_mode (addr);
-
- /* If we're accessing the constant in a different mode than it was
- originally stored, attempt to fix that up via subreg simplifications.
- If that fails we have no choice but to return the original memory. */
- if (cmode != GET_MODE (x))
+ /* If this is a constant pool reference, we can turn it into its
+ constant and hope that simplifications happen. */
+ if (GET_CODE (addr) == SYMBOL_REF
+ && CONSTANT_POOL_ADDRESS_P (addr))
{
- c = simplify_subreg (GET_MODE (x), c, cmode, 0);
- return c ? c : x;
+ c = get_pool_constant (addr);
+ cmode = get_pool_mode (addr);
+
+ /* If we're accessing the constant in a different mode than it was
+ originally stored, attempt to fix that up via subreg simplifications.
+ If that fails we have no choice but to return the original memory. */
+ if (offset != 0 || cmode != GET_MODE (x))
+ {
+ rtx tem = simplify_subreg (GET_MODE (x), c, cmode, offset);
+ if (tem && CONSTANT_P (tem))
+ return tem;
+ }
+ else
+ return c;
}
- return c;
+ return x;
}
/* Make a unary operation by first seeing if it folds and otherwise making
diff --git a/gcc/stmt.c b/gcc/stmt.c
index d1e71dea4f1..6df6eaa3e2e 100644
--- a/gcc/stmt.c
+++ b/gcc/stmt.c
@@ -2437,7 +2437,7 @@ expand_case (tree exp)
if (compare_tree_int (minval, 0) > 0
&& compare_tree_int (maxval, GET_MODE_BITSIZE (word_mode)) < 0)
{
- minval = fold_convert (index_type, integer_zero_node);
+ minval = build_int_cst (index_type, 0);
range = maxval;
}
emit_case_bit_tests (index_type, index_expr, minval, range,
@@ -2458,6 +2458,7 @@ expand_case (tree exp)
#ifndef ASM_OUTPUT_ADDR_DIFF_ELT
|| flag_pic
#endif
+ || !flag_jump_tables
|| TREE_CONSTANT (index_expr)
/* If neither casesi or tablejump is available, we can
only go this way. */
@@ -2522,7 +2523,7 @@ expand_case (tree exp)
&& compare_tree_int (minval, 0) > 0
&& compare_tree_int (minval, 3) < 0)
{
- minval = fold_convert (index_type, integer_zero_node);
+ minval = build_int_cst (index_type, 0);
range = maxval;
}
@@ -2829,7 +2830,8 @@ node_has_low_bound (case_node_ptr node, tree index_type)
return 0;
low_minus_one = fold_build2 (MINUS_EXPR, TREE_TYPE (node->low),
- node->low, integer_one_node);
+ node->low,
+ build_int_cst (TREE_TYPE (node->low), 1));
/* If the subtraction above overflowed, we can't verify anything.
Otherwise, look for a parent that tests our value - 1. */
@@ -2879,7 +2881,8 @@ node_has_high_bound (case_node_ptr node, tree index_type)
return 0;
high_plus_one = fold_build2 (PLUS_EXPR, TREE_TYPE (node->high),
- node->high, integer_one_node);
+ node->high,
+ build_int_cst (TREE_TYPE (node->high), 1));
/* If the addition above overflowed, we can't verify anything.
Otherwise, look for a parent that tests our value + 1. */
diff --git a/gcc/system.h b/gcc/system.h
index 4eac3691481..6b0919f2bc8 100644
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -738,7 +738,8 @@ extern void fancy_abort (const char *, int, const char *) ATTRIBUTE_NORETURN;
NON_SAVING_SETJMP TARGET_LATE_RTL_PROLOGUE_EPILOGUE \
CASE_DROPS_THROUGH TARGET_BELL TARGET_BS TARGET_CR TARGET_DIGIT0 \
TARGET_ESC TARGET_FF TARGET_NEWLINE TARGET_TAB TARGET_VT \
- LINK_LIBGCC_SPECIAL DONT_ACCESS_GBLS_AFTER_EPILOGUE
+ LINK_LIBGCC_SPECIAL DONT_ACCESS_GBLS_AFTER_EPILOGUE \
+ TARGET_OPTIONS TARGET_SWITCHES
/* Hooks that are no longer used. */
#pragma GCC poison LANG_HOOKS_FUNCTION_MARK LANG_HOOKS_FUNCTION_FREE \
diff --git a/gcc/target-def.h b/gcc/target-def.h
index 49e25a168ba..f5d98f95e09 100644
--- a/gcc/target-def.h
+++ b/gcc/target-def.h
@@ -379,6 +379,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define TARGET_GET_PCH_VALIDITY default_get_pch_validity
#define TARGET_PCH_VALID_P default_pch_valid_p
+#define TARGET_CHECK_PCH_TARGET_FLAGS NULL
#define TARGET_DEFAULT_SHORT_ENUMS hook_bool_void_false
@@ -551,6 +552,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
TARGET_GIMPLIFY_VA_ARG_EXPR, \
TARGET_GET_PCH_VALIDITY, \
TARGET_PCH_VALID_P, \
+ TARGET_CHECK_PCH_TARGET_FLAGS, \
TARGET_DEFAULT_SHORT_ENUMS, \
TARGET_BUILTIN_SETJMP_FRAME_VALUE, \
TARGET_MD_ASM_CLOBBERS, \
diff --git a/gcc/target.h b/gcc/target.h
index 38f09b01e05..1527819d916 100644
--- a/gcc/target.h
+++ b/gcc/target.h
@@ -485,6 +485,11 @@ struct gcc_target
void * (* get_pch_validity) (size_t *);
const char * (* pch_valid_p) (const void *, size_t);
+ /* If nonnull, this function checks whether a PCH file with the
+ given set of target flags can be used. It returns NULL if so,
+ otherwise it returns an error message. */
+ const char *(*check_pch_target_flags) (int);
+
/* True if the compiler should give an enum type only as many
bytes as it takes to represent the range of possible values of
that type. */
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
index 1f8b5b76ee7..42992b78c34 100644
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -264,7 +264,7 @@ default_scalar_mode_supported_p (enum machine_mode mode)
/* TRUE if INSN insn is valid within a low-overhead loop.
- This function checks wheter a given INSN is valid within a low-overhead
+ This function checks whether a given INSN is valid within a low-overhead
loop. A called function may clobber any special registers required for
low-overhead looping. Additionally, some targets (eg, PPC) use the count
register for branch on table instructions. We reject the doloop pattern in
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 9323ecbe054..523873461f4 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,490 @@
+2005-06-03 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/21336
+ * g++.dg/template/new2.C: New test.
+
+2005-06-03 Josh Conner <jconner@apple.com>
+
+ * gcc.dg/ppc-vector-memcpy.c (foo): Use non-zero values for
+ all entries in initializer.
+
+2005-06-03 Richard Guenther <rguenth@gcc.gnu.org>
+
+ PR middle-end/21858
+ * gcc.dg/pr21858.c: New testcase.
+
+2005-06-03 Paolo Bonzini <bonzini@gnu.org>
+
+ PR tree-optimization/21292
+
+ * lib/target-supports.exp (check_effective_target_vect_cmdline_needed):
+ New.
+ * gcc.dg/tree-ssa/gen-vect-11.c, gcc.dg/tree-ssa/gen-vect-11a.c,
+ gcc.dg/tree-ssa/gen-vect-11b.c, gcc.dg/tree-ssa/gen-vect-11c.c,
+ gcc.dg/tree-ssa/gen-vect-2.c, gcc.dg/tree-ssa/gen-vect-25.c,
+ gcc.dg/tree-ssa/gen-vect-26.c, gcc.dg/tree-ssa/gen-vect-28.c,
+ gcc.dg/tree-ssa/gen-vect-32.c: Require it.
+
+2005-06-02 Richard Henderson <rth@redhat.com>
+
+ * gcc.dg/sync-2.c: Use -march=i486 for i386.
+
+2005-06-02 Richard Guenther <rguenth@gcc.gnu.org>
+
+ * gcc.dg/wtypequal.c: New testcase.
+
+2005-06-02 Diego Novillo <dnovillo@redhat.com>
+
+ PR 21582
+ * gcc.dg/tree-ssa/pr21582.c: New test.
+
+2005-06-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/21280
+ * g++.dg/opt/interface2.h: New.
+ * g++.dg/opt/interface2.C: New.
+ * g++.dg/init/ctor4.C: Adjust error lines.
+ * g++.old-deja/g++.bob/inherit2.C: Likewise.
+ * g++.old-deja/g++.bugs/900205_04.C: Likewise.
+ * g++.old-deja/g++.jason/opeq3.C: Likewise.
+ * g++.old-deja/g++.pt/assign1.C: Likewise.
+ * g++.old-deja/g++.pt/crash20.C: Likewise.
+
+2005-06-02 Dorit Nuzman <dorit@il.ibm.com>
+
+ PR tree-optimization/21734
+ * g++.dg/vect/pr21734_1.cc: New.
+ * g++.dg/vect/pr21734_2.cc: New.
+
+2005-06-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/20350
+ * g++.dg/template/spec24.C: New.
+
+ PR c++/21151
+ * g++.dg/pch/local-1.C: New.
+ * g++.dg/pch/local-1.Hs: New.
+
+2005-06-01 Diego Novillo <dnovillo@redhat.com>
+
+ PR 14341, PR 21332, PR 20701, PR 21086, PR 21090
+ PR 21289, PR 21348, PR 21367, PR 21368, PR 21458.
+ * gcc.dg/tree-ssa/pr14341.c: New test.
+ * gcc.dg/tree-ssa/pr14841.c: New test.
+ * gcc.dg/tree-ssa/pr20701.c: New test.
+ * gcc.dg/tree-ssa/pr21086.c: New test.
+ * gcc.dg/tree-ssa/pr21090.c: New test.
+ * gcc.dg/tree-ssa/pr21332.c: New test.
+ * gcc.dg/tree-ssa/pr21458.c: New test.
+ * gcc.dg/tree-ssa/pr21658.c: New test.
+ * gcc.dg/tree-ssa/vrp01.c: New test.
+ * gcc.dg/tree-ssa/vrp02.c: New test.
+ * gcc.dg/tree-ssa/vrp03.c: New test.
+ * gcc.dg/tree-ssa/vrp04.c: New test.
+ * gcc.dg/tree-ssa/vrp05.c: New test.
+ * gcc.dg/tree-ssa/vrp06.c: New test.
+ * gcc.dg/tree-ssa/vrp07.c: New test.
+ * gcc.dg/tree-ssa/vrp08.c: New test.
+ * gcc.dg/tree-ssa/vrp09.c: New test.
+ * gcc.dg/tree-ssa/vrp10.c: New test.
+ * gcc.dg/tree-ssa/vrp11.c: New test.
+ * gcc.dg/tree-ssa/vrp12.c: New test.
+ * gcc.dg/tree-ssa/vrp13.c: New test.
+
+2005-06-01 Alexandre Oliva <aoliva@redhat.com>
+
+ PR 21029
+ * gcc.dg/tree-ssa/pr21029.c: New test.
+
+2005-06-01 Roger Sayle <roger@eyesopen.com>
+
+ * gfortran.dg/logint-1.f: New test case.
+ * gfortran.dg/logint-2.f: Likewise.
+ * gfortran.dg/logint-3.f: Likewise.
+
+2005-06-01 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/21536
+ PR c/20760
+ * gcc.dg/20050527-1.c: New test.
+
+ * gcc.dg/i386-sse-12.c: New test.
+
+ PR fortran/21729
+ * gfortran.dg/implicit_5.f90: New test.
+
+2005-06-01 Feng Wang <fengwang@nudt.edu.cn>
+
+ PR fortran/20883
+ * gfortran/assign_4.f90: New test.
+ * gfortran/assign_2.f90: Change compile to run.
+
+2005-05-31 Geoffrey Keating <geoffk@geoffk.org>
+
+ * lib/target-supports.exp
+ (check_effective_target_sync_char_short): New.
+ * gcc.dg/sync-2.c: New.
+
+2005-05-31 Zdenek Dvorak <dvorakz@suse.cz>
+
+ PR tree-optimization/21817
+ * gcc.dg/torture/pr21817-1.c: New.
+
+2005-05-31 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/21165
+ * g++.dg/template/init5.C: New.
+
+2005-05-31 Paul Thomas <pault@gcc.gnu.org>
+
+ * gfortran.dg/char_initialiser_actual.f90:
+ Test character initialisers as actual arguments.
+ * gfortran.dg/char_pointer_comp_assign.f90:
+ Test character pointer structure component assignments.
+ * gfortran.dg/char_array_structure_constructor.f90:
+ Test character components in structure constructors.
+
+2005-05-31 Andrew pinski <pinskia@physics.uc.edu>
+
+ PR middle-end/20931
+ * g++.dg/opt/pr20931.C: New test.
+
+2005-05-31 Andreas Jaeger <aj@suse.de>
+
+ PR testsuite/20772
+ * g++.dg/abi/dtor1.C, g++.dg/abi/empty10.C, g++.dg/abi/layout3.C,
+ g++.dg/eh/simd-2.C, g++.dg/opt/cse2.C,
+ g++.old-deja/g++.ext/asmspec1.C,
+ g++.old-deja/g++.other/regstack.C,
+ gcc.dg/20000614-1.c, gcc.dg/20000807-1.c, gcc.dg/20000904-1.c,
+ gcc.dg/20001127-1.c, gcc.dg/20010202-1.c, gcc.dg/20010520-1.c,
+ gcc.dg/20011009-1.c, gcc.dg/20011029-2.c, gcc.dg/20020224-1.c,
+ gcc.dg/20020531-1.c, gcc.dg/20020616-1.c, gcc.dg/980226-1.c,
+ gcc.dg/980414-1.c, gcc.dg/980520-1.c, gcc.dg/980709-1.c,
+ gcc.dg/990117-1.c, gcc.dg/990130-1.c, gcc.dg/990213-2.c,
+ gcc.dg/990214-1.c, gcc.dg/991129-1.c, gcc.dg/991209-1.c,
+ gcc.dg/991214-1.c, gcc.dg/asm-1.c, gcc.dg/attr-returns_twice-1.c,
+ gcc.dg/clobbers.c, gcc.dg/i386-387-7.c, gcc.dg/i386-387-8.c,
+ gcc.dg/i386-3dnowA-1.c, gcc.dg/i386-3dnowA-2.c, gcc.dg/i386-asm-1.c
+ gcc.dg/i386-asm-2.c, gcc.dg/i386-asm-3.c, gcc.dg/i386-bitfield3.c
+ gcc.dg/i386-call-1.c, gcc.dg/i386-memset-1.c,
+ gcc.dg/i386-signbit-3.c, gcc.dg/i386-ssefn-1.c,
+ gcc.dg/i386-ssefn-2.c, gcc.dg/i386-ssefn-3.c, gcc.dg/i386-ssefn-4.c
+ gcc.dg/i386-volatile-1.c, gcc.dg/i386-xorps.c, gcc.dg/pr12092-1.c
+ gcc.dg/pr14289-1.c, gcc.dg/pr19236-1.c, gcc.dg/pr20204.c,
+ gcc.dg/pr9771-1.c, gcc.dg/register-var-1.c,
+ gcc.dg/sibcall-5.c, gcc.dg/charset/asm3.c,
+ gcc.dg/cpp/trad/num-sign.c: Run tests also on x86_64.
+
+2005-05-31 Jeff Law <law@redhat.com>
+
+ * gcc.dg/tree-ssa/foldaddr-1.c: New test.
+
+2005-05-30 Paolo Carlini <pcarlini@suse.de>
+
+ PR middle-end/21743
+ * gcc.dg/builtins-1.c: Activate disabled clog test.
+ * gcc.dg/torture/builtin-attr-1.c: Likewise.
+
+2005-05-29 Paul Thomas <pault@gcc.gnu.org>
+
+ * gfortran.dg/char_pointer_assign.f90:
+ Test character-pointer assignments and pointer assignments.
+ * gfortran.dg/char_pointer_dummy.f90:
+ Test character-pointer dummy arguments.
+ * gfortran.dg/char_pointer_func.f90:
+ Test character-pointer function returns.
+ * gfortran.dg/char_pointer_dependency.f90:
+ Test character-pointer functions with dependencies.
+
+2005-05-30 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/21784
+ * g++.dg/lookup/using14.C: New test.
+
+2005-05-30 Kazu Hirata <kazu@cs.umass.edu>
+
+ * gcc.dg/c99-math-double-1.c, gcc.dg/c99-math-float-1.c,
+ gcc.dg/c99-math-long-double-1.c, gcc.dg/c99-math.h: Remove
+ trailing ^M.
+
+2005-05-29 Geoffrey Keating <geoffk@apple.com>
+
+ PR c++/17413
+ * g++.dg/template/local5.C: New.
+
+ PR target/21761
+ * gcc.c-torture/compile/pr21761.c: New.
+
+ * g++.old-deja/g++.eh/badalloc1.C: Make XFAIL only on darwin
+ before darwin8.
+
+2005-05-30 Steven G. Kargl
+
+ PR fortran/20846
+ * gfortran.dg/inquire_8.f90: New test.
+
+2005-05-29 Francois-Xavier Coudert <coudert@clipper.ens.fr>
+
+ PR libfortran/21376
+ * gfortran.dg/output_exponents_1.f90: New test.
+
+2005-05-29 Francois-Xavier Coudert <coudert@clipper.ens.fr>
+
+ PR libfortran/20006
+ * gfortran.dg/dollar_edit_descriptor-1.f: New test.
+
+2005-05-28 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/21210
+ * g++.dg/ext/complex1.C: New test.
+
+ PR c++/21340
+ * g++.dg/init/ctor6.C: New test.
+
+2005-05-29 Jan Hubicka <jh@suse.cz>
+
+ * gcc.c-torture/compile/pr21562.c: New.
+
+2005-05-28 Steven G. Kargl <kargls@comcast.net>
+
+ * gfortran.dg/subnormal_1.f90: New test.
+
+2005-05-28 Jan Hubicka <jh@suse.cz>
+
+ * tree-prof.exp: Fix comment.
+ * value-prof-1.c: New.
+ * value-prof-2.c: New.
+ * value-prof-3.c: New.
+ * value-prof-4.c: New.
+
+2005-05-27 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/21614
+ * g++.dg/expr/ptrmem6.C: New test.
+ * g++.dg/expr/ptrmem6a.C: Likewise.
+
+2005-05-27 Kazu Hirata <kazu@cs.umass.edu>
+
+ PR tree-optimization/21658
+ * gcc.dg/tree-ssa/pr21658.c: New.
+
+2005-05-27 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/21455
+ * g++.dg/inherit/ptrmem3.C: New.
+
+ PR c++/21681
+ * g++.dg/parse/template16.C: New.
+
+2005-05-27 Andreas Jaeger <aj@suse.de>
+
+ * gcc.dg/setjmp-2.c: Only run in 32-bit.
+
+ * gcc.dg/i386-sse-8.c: Run test on all archs.
+
+2005-05-26 Mike Stump <mrs@apple.com>
+
+ * objc.dg/isa-field-1.m: Only run on darwin.
+ * objc.dg/lookup-1.m: Likewise.
+ * objc.dg/try-catch-8.m: Likewise.
+
+2005-05-26 Roger Sayle <roger@eyesopen.com>
+
+ PR tree-optimization/9814
+ * gcc.dg/pr9814-1.c: New test case.
+
+2005-05-26 Ziemowit Laski <zlaski@apple.com>
+
+ * objc.dg/comp-types-8.m, objc.dg/encode-6.m,
+ objc.dg/extra-semi.m, objc.dg/fix-and-continue-2.m,
+ objc.dg/isa-field-1.m, objc.dg/lookup-1.m, objc.dg/method-15.m,
+ objc.dg/method-16.m, objc.dg/method-17.m, objc.dg/method-18.m,
+ objc.dg/method-19.m, objc.dg/next-runtime-1.m,
+ objc.dg/no-extra-load.m, objc.dg/pragma-1.m, objc.dg/stubify-1.m,
+ objc.dg/stubify-2.m, objc.dg/super-class-4.m,
+ objc.dg/super-dealloc-1.m, objc.dg/super-dealloc-2.m,
+ objc.dg/try-catch-6.m, objc.dg/try-catch-7.m,
+ objc.dg/try-catch-8.m: New.
+
+2005-05-26 Janis Johnson <janis187@us.ibm.com>
+
+ * lib/obj-c++.exp (obj-c++_target_compile): Declare global variable,
+ remove extraneous semicolons.
+
+2005-05-26 Ziemowit Laski <zlaski@apple.com>
+
+ * obj-c++.dg/comp-types-12.mm: New.
+ * objc.dg/comp-types-11.m: New.
+ * objc.dg/selector-4.m: New.
+
+2005-05-26 Andreas Jaeger <aj@suse.de>
+
+ PR testsuite/20772
+ * g++.old-deja/g++.ext/attrib1.C, g++.old-deja/g++.ext/attrib2.C,
+ g++.old-deja/g++.ext/attrib3.C,
+ g++.old-deja/g++.other/store-expr1.C,
+ g++.old-deja/g++.other/store-expr2.C, g++.dg/opt/longbranch2.C,
+ gcc.dg/20000609-1.c, gcc.dg/20000720-1.c, gcc.dg/20011107-1.c,
+ gcc.dg/20011119-1.c, gcc.dg/20020108-1.c, gcc.dg/20020122-2.c,
+ gcc.dg/20020122-3.c, gcc.dg/20020201-3.c, gcc.dg/20020206-1.c,
+ gcc.dg/20020218-1.c, gcc.dg/20020310-1.c, gcc.dg/20020411-1.c,
+ gcc.dg/20020418-2.c, gcc.dg/20020426-1.c, gcc.dg/20020426-2.c,
+ gcc.dg/20020517-1.c, gcc.dg/20020523-1.c, gcc.dg/20020523-2.c,
+ gcc.dg/20020729-1.c, gcc.dg/20030204-1.c, gcc.dg/20030826-2.c,
+ gcc.dg/20030926-1.c, gcc.dg/20031202-1.c, gcc.dg/980312-1.c,
+ gcc.dg/980313-1.c, gcc.dg/990424-1.c, gcc.dg/990524-1.c,
+ gcc.dg/991230-1.c, gcc.dg/i386-387-1.c, gcc.dg/i386-387-2.c,
+ gcc.dg/i386-387-3.c, gcc.dg/i386-387-4.c, gcc.dg/i386-387-5.c,
+ gcc.dg/i386-387-6.c, gcc.dg/i386-bitfield1.c,
+ gcc.dg/i386-bitfield2.c, gcc.dg/i386-loop-1.c,
+ gcc.dg/i386-loop-2.c, gcc.dg/i386-loop-3.c, gcc.dg/i386-pic-1.c,
+ gcc.dg/i386-regparm.c, gcc.dg/i386-signbit-1.c,
+ gcc.dg/i386-signbit-2.c, gcc.dg/i386-sse-5.c, gcc.dg/i386-sse-8.c,
+ gcc.dg/i386-unroll-1.c, gcc.dg/tls/opt-1.c, gcc.dg/tls/opt-2.c,
+ gcc.dg/unroll-1.c: Handle 32-bit x86-64 compilation.
+
+2005-05-26 Andreas Jaeger <aj@suse.de>
+
+ * gcc.c-torture/execute/ieee/ieee.exp: Set float-store for 32-bit
+ x86-64 compilation.
+
+2005-05-26 Andreas Jaeger <aj@suse.de>
+
+ PR testsuite/20772
+ * gfortran.dg/promotion.f90, gcc.misc-tests/i386-pf-3dnow-1.c,
+ gcc.misc-tests/i386-pf-athlon-1.c,
+ gcc.misc-tests/i386-pf-none-1.c, gcc.misc-tests/i386-pf-sse-1.c,
+ g++.dg/opt/mmx1.C, g++.dg/other/big-struct.C,
+ g++.dg/abi/bitfield3.C, g++.dg/abi/bitfield8.C,
+ g++.dg/abi/bitfield9.C, g++.dg/abi/empty7.C, g++.dg/abi/empty9.C,
+ g++.dg/abi/layout4.C, g++.dg/abi/thunk1.C, g++.dg/abi/thunk2.C,
+ g++.dg/abi/vbase11.C, g++.dg/abi/vthunk2.C, g++.dg/abi/vthunk3.C,
+ g++.dg/ext/attrib8.C: Run also on x86_64 compiling 32-bit x86
+ programs.
+
+ * g++.dg/opt/reg-stack4.C, g++.dg/eh/simd-1.C, g++.dg/eh/simd-1.C,
+ gcc.dg/setjmp-2.c, gcc.dg/short-compare-1.c,
+ gcc.dg/short-compare-2.c, gcc.target/i386/asm-1.c: Handle 32-bit
+ x86-64 compilation.
+
+ * g++.dg/warn/register-var-1.C, g++.dg/charset/asm2.c: Run also on
+ x86_64.
+
+ * gcc.dg/i386-pentium4-not-mull.c: Change option handling to use
+ effective-target ilp32.
+
+2005-05-26 David Ung <davidu@mips.com>
+
+ * gcc.target/mips/ext_ins.c: New test for testing the generation
+ of MIPS32/64 rev 2 ext/ins instructions.
+
+2005-05-26 Andreas Jaeger <aj@suse.de>
+
+ * treelang/compile/unsigned.tree: Use gimple instead of
+ nonexisting generic dump.
+
+2005-05-26 Paolo Bonzini <bonzini@gnu.org>
+
+ * gcc.dg/vect/vect-7.c: Remove xfail for alpha.
+
+2005-05-26 Andreas Jaeger <aj@suse.de>
+
+ * gcc.dg/tree-ssa/ssa-pre-14.c (foo): Use correct type for strlen.
+
+2005-05-26 Thomas Koenig <Thomas.Koenig@online.de>
+
+ PR libfortran/17283
+ * gfortran.fortran-torture/execute/intrinsic_unpack.f90:
+ Test callee-allocated memory with write statements.
+
+2005-05-25 Roger Sayle <roger@eyesopen.com>
+
+ PR middle-end/21709
+ * gcc.dg/pr21709-1.c: New test case.
+
+2005-05-25 Ziemowit Laski <zlaski@apple.com>
+ Mike Stump <mrs@apple.com>
+
+ * objc/execute/next_mapping.h: Update for C++.
+
+ * obj-c++.dg/selector-1.mm: Move to...
+ * obj-c++.dg/selector-4.mm: here...
+
+ * obj-c++.dg/basic.mm: New.
+ * obj-c++.dg/comp-types-1.mm: New.
+ * obj-c++.dg/cxx-class-1.mm: New.
+ * obj-c++.dg/cxx-ivars-1.mm: New.
+ * obj-c++.dg/cxx-ivars-2.mm: New.
+ * obj-c++.dg/cxx-ivars-3.mm: New.
+ * obj-c++.dg/cxx-scope-1.mm: New.
+ * obj-c++.dg/cxx-scope-2.mm: New.
+ * obj-c++.dg/defs.mm: New.
+ * obj-c++.dg/empty-private-1.mm: New.
+ * obj-c++.dg/encode-1.mm: New.
+ * obj-c++.dg/encode-2.mm: New.
+ * obj-c++.dg/encode-3.mm: New.
+ * obj-c++.dg/extern-c-1.mm: New.
+ * obj-c++.dg/extra-semi.mm: New.
+ * obj-c++.dg/fix-and-continue-2.mm: New.
+ * obj-c++.dg/isa-field-1.mm: New.
+ * obj-c++.dg/ivar-list-semi.mm: New.
+ * obj-c++.dg/local-decl-1.mm: New.
+ * obj-c++.dg/lookup-1.mm: New.
+ * obj-c++.dg/lookup-2.mm: New.
+ * obj-c++.dg/method-1.mm: New.
+ * obj-c++.dg/method-2.mm: New.
+ * obj-c++.dg/method-3.mm: New.
+ * obj-c++.dg/method-4.mm: New.
+ * obj-c++.dg/method-5.mm: New.
+ * obj-c++.dg/method-6.mm: New.
+ * obj-c++.dg/method-7.mm: New.
+ * obj-c++.dg/no-extra-load.mm: New.
+ * obj-c++.dg/overload-1.mm: New.
+ * obj-c++.dg/pragma-1.mm: New.
+ * obj-c++.dg/pragma-2.mm: New.
+ * obj-c++.dg/private-1.mm: New.
+ * obj-c++.dg/private-2.mm: New.
+ * obj-c++.dg/proto-qual-1.mm: New.
+ * obj-c++.dg/qual-types-1.mm: New.
+ * obj-c++.dg/stubify-1.mm: New.
+ * obj-c++.dg/stubify-2.mm: New.
+ * obj-c++.dg/super-class-1.mm: New.
+ * obj-c++.dg/super-class-2.mm: New.
+ * obj-c++.dg/super-dealloc-1.mm: New.
+ * obj-c++.dg/super-dealloc-2.mm: New.
+ * obj-c++.dg/template-1.mm: New.
+ * obj-c++.dg/template-2.mm: New.
+ * obj-c++.dg/template-3.mm: New.
+ * obj-c++.dg/template-4.mm: New.
+ * obj-c++.dg/template-5.mm: New.
+ * obj-c++.dg/template-6.mm: New.
+ * obj-c++.dg/try-catch-1.mm: New.
+ * obj-c++.dg/try-catch-2.mm: New.
+ * obj-c++.dg/try-catch-3.mm: New.
+ * obj-c++.dg/try-catch-4.mm: New.
+ * obj-c++.dg/try-catch-5.mm: New.
+ * obj-c++.dg/try-catch-6.mm: New.
+ * obj-c++.dg/try-catch-7.mm: New.
+ * obj-c++.dg/try-catch-8.mm: New.
+ * obj-c++.dg/try-catch-9.mm: New.
+ * obj-c++.dg/va-meth-1.mm: New.
+
+2005-05-25 Ziemowit Laski <zlaski@apple.com>
+
+ * obj-c++.dg/selector-1.mm: New.
+ * obj-c++.dg/selector-2.mm: New.
+
+2005-05-25 Ziemowit Laski <zlaski@apple.com>
+
+ * obj-c++.dg/selector-3.mm: New.
+ * objc.dg/selector-3.m: New.
+
+2005-05-25 Ziemowit Laski <zlaski@apple.com>
+
+ * objc.dg/selector-2.m: Remove "-fgnu-runtime"; be flexible
+ about where warning appears.
+
2005-05-25 Ulrich Weigand <uweigand@de.ibm.com>
* gcc.dg/tree-ssa/stdarg-2.c: Add tests for s390*-*-linux* targets.
@@ -120,7 +607,7 @@
* gcc.c-torture/execute/20020720-1.x: Add xfail for m32r*-*.
2005-05-20 Bjoern Haase <bjoern.m.haase@web.de>
-
+
* gcc.c-torture/execute/20020720-1.x: Add xfail for avr-*-*.
2004-05-19 Richard Henderson <rth@redhat.com>
@@ -153,7 +640,7 @@
2005-05-18 Devang Patel <dpatel@apple.com>
* g++.dg/opt/20050511-1.C: New test.
-
+
2005-05-18 Thomas Koenig <Thomas.Koenig@online.de>
PR libfortran/21127
@@ -182,7 +669,7 @@
2005-05-17 Mark Mitchell <mark@codesourcery.com>
* gcc.dg/compat/struct-layout-1_generate.c (iterative_hash):
- Remove little-endian optimizations.
+ Remove little-endian optimizations.
2005-05-17 Jeff Law <law@redhat.com>
@@ -239,7 +726,7 @@
* gcc.dg/compat/struct-layout-1.exp: Do not link with libiberty.
* gcc.dg/compat/struct-layout-1_generate.c (config.h): Do not include.
(limits.h): Include unconditionally.
- (stdlib.h): Likewise.
+ (stdlib.h): Likewise.
(hashtab.h): Do not include.
(getopt.h): Likewise.
(stddef.h): Include.
@@ -255,7 +742,7 @@
(e_insert): Likewise.
(output): Use, instead of libiberty hashtable functions.
(main): Do not use getopt. Do not call htab_create.
-
+
2005-05-16 David Billinghurst <David.Billinghurst@riotinto.com>
PR libstdc++/21526
@@ -438,7 +925,7 @@
2005-05-05 Mark Mitchell <mark@codesourcery.com>
PR c++/21352
- * g++.dg/template/crash37.C: New test.
+ * g++.dg/template/crash37.C: New test.
2005-05-05 Paul Brook <paul@codesourcery.com>
@@ -570,7 +1057,7 @@
PR tree-optimization/21272
* gcc.dg/vect/vect-ifcvt-10.c: New test.
-
+
2005-04-29 Jakub Jelinek <jakub@redhat.com>
PR fortran/13082
@@ -703,7 +1190,7 @@
2005-04-25 Devang Patel <dpatel@apple.com>
* gcc.dg/stabs-attrib-vect-darwin.c: New test.
-
+
2005-04-25 Andrew Pinski <pinskia@physics.uc.edu>
PR testsuite/21062
@@ -803,7 +1290,7 @@
PR optimization/20994
* gcc.dg/tree-ssa/ifc-3.c: New test.
-
+
2005-04-20 Joseph S. Myers <joseph@codesourcery.com>
PR c/12913
@@ -813,7 +1300,7 @@
2005-04-19 Richard Henderson <rth@redhat.com>
- * lib/target-supports.exp (check_effective_target_vect_int_mult):
+ * lib/target-supports.exp (check_effective_target_vect_int_mult):
Fix typo in exists check.
(check_effective_target_sync_int_long): New.
* gcc.dg/ia64-sync-1.c: Enable for all effective-target sync_int_long.
@@ -880,7 +1367,7 @@
2005-04-18 Laurent GUERBY <laurent@guerby.net>
* ada/acats/run_all.sh: Use sync when executable not present.
-
+
2005-04-18 Devang Patel <dpatel@apple.com>
* gcc.dg/vect/vect-11.c: Require effective target vect_int_mult.
@@ -953,7 +1440,7 @@
* typeck.c (cxx_sizeof_or_alignof_type): Check whether the type to
which sizeof/alignof is dependent, rather than just whether we are
processing_template_decl.
-
+
2005-04-15 Thomas Koenig <Thomas.Koenig@online.de>
* gfortran.fortran-torture/execute/intrinsic_spread.f90:
@@ -978,7 +1465,7 @@
* gcc.dg/builtins-53.c: Include builtins-config.h.
Check floorf, ceilf, floorl and ceill transformations
only when HAVE_C99_RUNTIME is defined.
-
+
2005-04-15 Alexandre Oliva <aoliva@redhat.com>
PR middle-end/20739
@@ -1126,12 +1613,12 @@
* gcc.dg/vect/vect-ifcvt-6.c: New test.
* gcc.dg/vect/vect-ifcvt-7.c: New test.
* gcc.dg/vect/vect-none.c: Now one loop is vectorized.
-
+
2004-04-11 Devang Patel <dpatel@apple.com>
* gcc.dg/vect/vect-dv-1.c: New test.
* gcc.dg/vect/vect-dv-2.c: New test.
-
+
2005-04-11 Diego Novillo <dnovillo@redhat.com>
PR tree-optimization/20933
@@ -1154,7 +1641,7 @@
* gcc.dg/builtins-53.c: Also check (int)ceil* and
(long long int)ceil*.
-
+
2005-04-10 Mark Mitchell <mark@codesourcery.com>
* g++.dg/warn/Wdtor1.C: Declare template in system header with
@@ -1323,7 +1810,7 @@
2005-04-06 Dorit Naishlos <dorit@il.ibm.com>
- * gfortran.dg/vect/vect-5.f90: xfail for lp64.
+ * gfortran.dg/vect/vect-5.f90: xfail for lp64.
2005-04-05 Mark Mitchell <mark@codesourcery.com>
@@ -1370,7 +1857,7 @@
* lib/target-supports.exp (check_effective_target_vect_shif): New.
* gcc.dg/vect/vect-shift-1.c: New test.
-
+
2005-04-05 Francois-Xavier Coudert <coudert@clipper.ens.fr>
PR libfortran/20755
@@ -1842,7 +2329,7 @@
(g++_init): Make sure that CXXFLAGS is set.
* lib/gcc-defs.exp (gcc-set-multilib-library-path): New function.
* lib/gcc-dg.exp: Use gcc-set-multilib-library-path.
- * lib/gfortran.exp (gfortran_link_flags): Likewise.
+ * lib/gfortran.exp (gfortran_link_flags): Likewise.
* lib/objc.exp (objc_init): Likewise.
* lib/treelang.exp (treelang_init): Likewise.
@@ -1926,7 +2413,7 @@
* gfortran.dg/pr18025.f90: New test.
2005-03-23 Dale Johannesen <dalej@apple.com>
-
+
* gcc.dg/20020312-2.c: Fix for non-PowerPC Darwin.
2005-03-23 Mark Mitchell <mark@codesourcery.com>
@@ -1995,7 +2482,7 @@
2005-03-21 Stuart Hastings <stuart@apple.com>
* gcc.target/i386/sse-2.c: New.
-
+
2005-03-21 Uros Bizjak <uros@kss-loka.si>
* gcc.dg/builtins-46.c: Also check lrint* and llrint*.
@@ -2014,7 +2501,7 @@
2005-03-21 Paolo Carlini <pcarlini@suse.de>
- PR c++/20147
+ PR c++/20147
* g++.dg/ext/stmtexpr4.C: New test.
2005-03-20 Roger Sayle <roger@eyesopen.com>
@@ -2338,7 +2825,7 @@
PR c++/20142
* g++.dg/init/array18.C: Add dg-do run marker.
-
+
PR c++/20142
* g++.dg/init/array18.C: New test.
@@ -2438,13 +2925,13 @@
* objc.dg/stabs-1.m: hppa*64*-*-* doesn't have stabs.
-2005-03-05 Steven G. Kargl <kargls@comcast.net>
+2005-03-05 Steven G. Kargl <kargls@comcast.net>
* gfortran.dg/pr19936_1.f90: New test.
* gfortran.dg/pr19936_2.f90: New test.
* gfortran.dg/pr19936_3.f90: New test.
-2005-03-05 Steven G. Kargl <kargls@comcast.net>
+2005-03-05 Steven G. Kargl <kargls@comcast.net>
Paul Thomas <prthomas@drfccad.cea.fr>
* gfortran.dg/PR19754_1.f90: New test.
@@ -2653,7 +3140,7 @@
* g++.dg/parse/error27.C: New test.
* g++.dg/template/qualttp15.C: Adjust error markers.
* g++.old-deja/g++.other/struct1.C: Likewise.
-
+
PR c++/20153
* g++.dg/template/error17.C: New test.
@@ -2683,7 +3170,7 @@
PR 19952
* g++.dg/tree-ssa/pr19952.C: New test.
-
+
2005-02-22 Mark Mitchell <mark@codesourcery.com>
PR c++/19883
@@ -28989,7 +29476,7 @@ Thu Apr 27 15:58:18 MET DST 2000 Jan Hubicka <jh@suse.cz>
* gcc.c-torture/compile/labels-2.c: New test.
-1999-12-27 Martin von L�is <loewis@informatik.hu-berlin.de>
+1999-12-27 Martin von L�is <loewis@informatik.hu-berlin.de>
* gcc.c-torture/execute/991227-1.c: New test.
@@ -28997,7 +29484,7 @@ Thu Apr 27 15:58:18 MET DST 2000 Jan Hubicka <jh@suse.cz>
* g++.old-deja/g++.pt/instantiate6.C: Remove excess errors XFAIL.
-1999-12-21 Martin von L�is <loewis@informatik.hu-berlin.de>
+1999-12-21 Martin von L�is <loewis@informatik.hu-berlin.de>
* gcc.c-torture/execute/991221-1.c: New test.
diff --git a/gcc/testsuite/g++.dg/abi/bitfield3.C b/gcc/testsuite/g++.dg/abi/bitfield3.C
index 864abc33b8d..b96c9ed8d93 100644
--- a/gcc/testsuite/g++.dg/abi/bitfield3.C
+++ b/gcc/testsuite/g++.dg/abi/bitfield3.C
@@ -1,10 +1,10 @@
// Test for oversized bitfield alignment in structs on IA-32
-// { dg-do run { target i?86-*-* } }
+// { dg-do run { target i?86-*-* x86_64-*-* } }
// { dg-options "-O2" }
// Cygwin and mingw32 default to MASK_ALIGN_DOUBLE. Override to ensure
// 4-byte alignment.
// { dg-options "-mno-align-double" { target i?86-*-cygwin* i?86-*-mingw* } }
-// { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } }
+// { dg-require-effective-target ilp32 }
struct A
{
diff --git a/gcc/testsuite/g++.dg/abi/bitfield8.C b/gcc/testsuite/g++.dg/abi/bitfield8.C
index 6130ae45739..58e74be08fb 100644
--- a/gcc/testsuite/g++.dg/abi/bitfield8.C
+++ b/gcc/testsuite/g++.dg/abi/bitfield8.C
@@ -1,6 +1,7 @@
-// { dg-do run { target i?86-*-* } }
+// { dg-do run { target i?86-*-* x86_64-*-* } }
// { dg-options "-fabi-version=0" }
-// { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } }
+// { dg-require-effective-target ilp32 }
+
struct A {
virtual void f() {}
diff --git a/gcc/testsuite/g++.dg/abi/bitfield9.C b/gcc/testsuite/g++.dg/abi/bitfield9.C
index 0d744c7318f..0d3a8bf8985 100644
--- a/gcc/testsuite/g++.dg/abi/bitfield9.C
+++ b/gcc/testsuite/g++.dg/abi/bitfield9.C
@@ -1,4 +1,5 @@
-// { dg-do run { target i?86-*-* } }
+// { dg-do run { target i?86-*-* x86_64-*-* } }
+// { dg-require-effective-target ilp32 }
// { dg-options -w }
struct X {
diff --git a/gcc/testsuite/g++.dg/abi/dtor1.C b/gcc/testsuite/g++.dg/abi/dtor1.C
index 9ec44ae7520..f9425e013df 100644
--- a/gcc/testsuite/g++.dg/abi/dtor1.C
+++ b/gcc/testsuite/g++.dg/abi/dtor1.C
@@ -1,5 +1,5 @@
-// { dg-do compile { target i?86-*-* } }
-// { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } }
+// { dg-do compile { target i?86-*-* x86_64-*-* } }
+// { dg-require-effective-target ilp32 }
// { dg-options "-fabi-version=0" }
struct A {
diff --git a/gcc/testsuite/g++.dg/abi/empty10.C b/gcc/testsuite/g++.dg/abi/empty10.C
index 9147e9692f5..ae992944dee 100644
--- a/gcc/testsuite/g++.dg/abi/empty10.C
+++ b/gcc/testsuite/g++.dg/abi/empty10.C
@@ -1,5 +1,5 @@
-// { dg-do run { target i?86-*-* } }
-// { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } }
+// { dg-do run { target i?86-*-* x86_64-*-* } }
+// { dg-require-effective-target ilp32 }
// { dg-options "-fabi-version=0 -w" }
struct E {};
diff --git a/gcc/testsuite/g++.dg/abi/empty7.C b/gcc/testsuite/g++.dg/abi/empty7.C
index 5ff75e65d97..0a665a84531 100644
--- a/gcc/testsuite/g++.dg/abi/empty7.C
+++ b/gcc/testsuite/g++.dg/abi/empty7.C
@@ -1,5 +1,5 @@
-// { dg-do run { target i?86-*-* } }
-// { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } }
+// { dg-do run { target i?86-*-* x86_64-*-* } }
+// { dg-require-effective-target ilp32 }
// { dg-options "-fabi-version=0" }
struct S1 {};
diff --git a/gcc/testsuite/g++.dg/abi/empty9.C b/gcc/testsuite/g++.dg/abi/empty9.C
index 3c4b71f100f..06e616adb30 100644
--- a/gcc/testsuite/g++.dg/abi/empty9.C
+++ b/gcc/testsuite/g++.dg/abi/empty9.C
@@ -1,5 +1,5 @@
-// { dg-do run { target i?86-*-* } }
-// { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } }
+// { dg-do run { target i?86-*-* x86_64-*-* } }
+// { dg-require-effective-target ilp32 }
// { dg-options "-w -fabi-version=0" }
struct E1 {};
diff --git a/gcc/testsuite/g++.dg/abi/layout3.C b/gcc/testsuite/g++.dg/abi/layout3.C
index 121310862db..a30a85219fd 100644
--- a/gcc/testsuite/g++.dg/abi/layout3.C
+++ b/gcc/testsuite/g++.dg/abi/layout3.C
@@ -1,5 +1,5 @@
-// { dg-do run { target i?86-*-* } }
-// { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } }
+// { dg-do run { target i?86-*-* x86_64-*-* } }
+// { dg-require-effective-target ilp32 }
// { dg-options "-fabi-version=0 -w" }
struct S {
diff --git a/gcc/testsuite/g++.dg/abi/layout4.C b/gcc/testsuite/g++.dg/abi/layout4.C
index 13d3648d6f5..da3c2f5d8c7 100644
--- a/gcc/testsuite/g++.dg/abi/layout4.C
+++ b/gcc/testsuite/g++.dg/abi/layout4.C
@@ -1,5 +1,5 @@
-// { dg-do run { target i?86-*-* } }
-// { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } }
+// { dg-do run { target i?86-*-* x86_64-*-* } }
+// { dg-require-effective-target ilp32 }
// { dg-options "-fabi-version=1" }
struct C4
diff --git a/gcc/testsuite/g++.dg/abi/thunk1.C b/gcc/testsuite/g++.dg/abi/thunk1.C
index 5508882359f..343a2aa6e27 100644
--- a/gcc/testsuite/g++.dg/abi/thunk1.C
+++ b/gcc/testsuite/g++.dg/abi/thunk1.C
@@ -1,5 +1,6 @@
-// { dg-do compile { target i?86-*-* } }
-// { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } }
+// { dg-do compile { target i?86-*-* x86_64-*-* } }
+// { dg-require-effective-target ilp32 }
+
struct A {
virtual void f ();
diff --git a/gcc/testsuite/g++.dg/abi/thunk2.C b/gcc/testsuite/g++.dg/abi/thunk2.C
index c1f88682df9..e6b2924cfdb 100644
--- a/gcc/testsuite/g++.dg/abi/thunk2.C
+++ b/gcc/testsuite/g++.dg/abi/thunk2.C
@@ -1,5 +1,5 @@
-// { dg-do compile { target i?86-*-* } }
-// { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } }
+// { dg-do compile { target i?86-*-* x86_64-*-* } }
+// { dg-require-effective-target ilp32 }
// { dg-options -w }
struct A {
diff --git a/gcc/testsuite/g++.dg/abi/vbase11.C b/gcc/testsuite/g++.dg/abi/vbase11.C
index 1dcc75647ca..8c854b9c13e 100644
--- a/gcc/testsuite/g++.dg/abi/vbase11.C
+++ b/gcc/testsuite/g++.dg/abi/vbase11.C
@@ -1,5 +1,5 @@
-// { dg-do run { target i?86-*-* } }
-// { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } }
+// { dg-do run { target i?86-*-* x86_64-*-* } }
+// { dg-require-effective-target ilp32 }
// { dg-options "-fabi-version=0" }
struct A { virtual void f(); char c1; };
diff --git a/gcc/testsuite/g++.dg/abi/vthunk2.C b/gcc/testsuite/g++.dg/abi/vthunk2.C
index 698c691cc0a..9b6f14c50e2 100644
--- a/gcc/testsuite/g++.dg/abi/vthunk2.C
+++ b/gcc/testsuite/g++.dg/abi/vthunk2.C
@@ -1,5 +1,5 @@
-// { dg-do compile { target i?86-*-* } }
-// { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } }
+// { dg-do compile { target i?86-*-* x86_64-*-*} }
+// { dg-require-effective-target ilp32 }
struct c0 {
virtual void f ();
diff --git a/gcc/testsuite/g++.dg/abi/vthunk3.C b/gcc/testsuite/g++.dg/abi/vthunk3.C
index 969cd2da84c..59fbbdc4be3 100644
--- a/gcc/testsuite/g++.dg/abi/vthunk3.C
+++ b/gcc/testsuite/g++.dg/abi/vthunk3.C
@@ -1,5 +1,5 @@
-// { dg-do compile { target i?86-*-* } }
-// { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } }
+// { dg-do compile { target i?86-*-* x86_64-*-* } }
+// { dg-require-effective-target ilp32 }
// { dg-options "-fabi-version=0" }
struct A {
diff --git a/gcc/testsuite/g++.dg/charset/asm2.c b/gcc/testsuite/g++.dg/charset/asm2.c
index 8ae2212fd26..7fb1959d260 100644
--- a/gcc/testsuite/g++.dg/charset/asm2.c
+++ b/gcc/testsuite/g++.dg/charset/asm2.c
@@ -1,6 +1,6 @@
/* Test for complex asm statements. Make sure it compiles
then test for some of the asm statements not being translated. */
-/* { dg-do compile { target i?86-*-* } }
+/* { dg-do compile { target i?86-*-* x86_64-*-* } }
{ dg-require-iconv "IBM1047" }
{ dg-final { scan-assembler "std" } }
{ dg-final { scan-assembler "cld" } }
diff --git a/gcc/testsuite/g++.dg/eh/simd-1.C b/gcc/testsuite/g++.dg/eh/simd-1.C
index fe71b78043f..e7c30dbf3bd 100644
--- a/gcc/testsuite/g++.dg/eh/simd-1.C
+++ b/gcc/testsuite/g++.dg/eh/simd-1.C
@@ -2,6 +2,7 @@
// Contributed by Aldy Hernandez (aldy@quesejoda.com).
// { dg-options "-O" }
// { dg-options "-O -w" { target i?86-*-* } }
+// { dg-options "-O -w" { target { x86_64-*-* && ilp32 } } }
// { dg-do run }
typedef int __attribute__((vector_size (8))) vecint;
diff --git a/gcc/testsuite/g++.dg/eh/simd-2.C b/gcc/testsuite/g++.dg/eh/simd-2.C
index 9d9dce509bd..c012670190c 100644
--- a/gcc/testsuite/g++.dg/eh/simd-2.C
+++ b/gcc/testsuite/g++.dg/eh/simd-2.C
@@ -2,6 +2,7 @@
// Contributed by Aldy Hernandez (aldy@quesejoda.com).
// { dg-options "-O" }
// { dg-options "-O -w" { target i?86-*-* } }
+// { dg-options "-O -w" { target { x86_64-*-* && ilp32 } } }
// { dg-options "-O -w -maltivec" { target powerpc*-*-linux* } }
// { dg-do run }
diff --git a/gcc/testsuite/g++.dg/ext/attrib8.C b/gcc/testsuite/g++.dg/ext/attrib8.C
index df2d48fecf4..7d99132c175 100644
--- a/gcc/testsuite/g++.dg/ext/attrib8.C
+++ b/gcc/testsuite/g++.dg/ext/attrib8.C
@@ -1,6 +1,6 @@
// PR 8656
-// { dg-do compile { target i?86-*-* } }
-// { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } }
+// { dg-do compile { target i?86-*-* x86_64-*-* } }
+// { dg-require-effective-target ilp32 }
extern int * (__attribute__((stdcall)) *fooPtr)( void);
int * __attribute__((stdcall)) myFn01( void) { return 0; }
diff --git a/gcc/testsuite/g++.dg/init/ctor4.C b/gcc/testsuite/g++.dg/init/ctor4.C
index b217b204000..70643ec4e10 100644
--- a/gcc/testsuite/g++.dg/init/ctor4.C
+++ b/gcc/testsuite/g++.dg/init/ctor4.C
@@ -6,7 +6,7 @@ public:
foo();
};
-class bar: public foo {
+class bar: public foo {// { dg-error "uninitialized" }
private:
int &a;
};
@@ -16,5 +16,5 @@ foo::foo() {
int main(int argc, char **argv)
{
- bar x; // { dg-error "uninitialized" }
+ bar x; // { dg-error "synthesized" }
}
diff --git a/gcc/testsuite/g++.dg/opt/cse2.C b/gcc/testsuite/g++.dg/opt/cse2.C
index 5a04bf53ecb..325169dff34 100644
--- a/gcc/testsuite/g++.dg/opt/cse2.C
+++ b/gcc/testsuite/g++.dg/opt/cse2.C
@@ -1,6 +1,6 @@
// This testcase caused ICE on IA-32 in simplify_unary_operation
// CSE did not assume SUBREGs changing mode from integral to floating.
-// { dg-do run { target i?86-*-* sparc*-*-* } }
+// { dg-do run { target i?86-*-* sparc*-*-* x86_64-*-* } }
// { dg-options "-O2" }
struct A
diff --git a/gcc/testsuite/g++.dg/opt/longbranch2.C b/gcc/testsuite/g++.dg/opt/longbranch2.C
index 88594b04ef7..dbc8a1d94d2 100644
--- a/gcc/testsuite/g++.dg/opt/longbranch2.C
+++ b/gcc/testsuite/g++.dg/opt/longbranch2.C
@@ -2,8 +2,9 @@
// Originator: thor@math.tu-berlin.de
// { dg-do compile }
-// { dg-options "-O3 -funroll-loops -mtune=k6 -fomit-frame-pointer" { target i?86-*-* } }
-// { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } }
+// { dg-options "-O3 -funroll-loops -mtune=k6 -fomit-frame-pointer" { target { i?86-*-* && ilp32 } } }
+// { dg-options "-O3 -funroll-loops -mtune=k6 -fomit-frame-pointer" { target { x86_64-*-* && ilp32 } } }
+
// This used to fail to assemble because of an out-of-range 'loop' instructions.
diff --git a/gcc/testsuite/g++.dg/opt/mmx1.C b/gcc/testsuite/g++.dg/opt/mmx1.C
index e433d554aea..f13b2f844af 100644
--- a/gcc/testsuite/g++.dg/opt/mmx1.C
+++ b/gcc/testsuite/g++.dg/opt/mmx1.C
@@ -3,7 +3,8 @@
// mmx -> mmx register moves.
// { dg-do compile }
// { dg-options "-O2" }
-// { dg-options "-fno-exceptions -O2 -mmmx -fPIC" { target i?86-*-* } }
+// { dg-options "-fno-exceptions -O2 -mmmx -fPIC" { target { i?86-*-* && ilp32 } } }
+// { dg-options "-fno-exceptions -O2 -mmmx -fPIC" { target { x86_64-*-* && ilp32 } } }
struct A {
unsigned a0;
diff --git a/gcc/testsuite/g++.dg/opt/reg-stack4.C b/gcc/testsuite/g++.dg/opt/reg-stack4.C
index 9ea77c23230..9d52845db64 100644
--- a/gcc/testsuite/g++.dg/opt/reg-stack4.C
+++ b/gcc/testsuite/g++.dg/opt/reg-stack4.C
@@ -5,8 +5,8 @@
// deleted a valid edge.
// { dg-do compile }
-// { dg-options "-mtune=i586 -O2" { target i?86-*-* } }
-// { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } }
+// { dg-options "-mtune=i586 -O2" { target { i?86-*-* && ilp32 } } }
+// { dg-options "-mtune=i586 -O2" { target { x86_64-*-* && ilp32 } } }
struct array {
double data;
diff --git a/gcc/testsuite/g++.dg/other/big-struct.C b/gcc/testsuite/g++.dg/other/big-struct.C
index b00683135f3..dcf230dd69c 100644
--- a/gcc/testsuite/g++.dg/other/big-struct.C
+++ b/gcc/testsuite/g++.dg/other/big-struct.C
@@ -1,4 +1,5 @@
-// { dg-do compile { target i?86-*-* } }
+// { dg-do compile { target i?86-*-* x86_64-*-* } }
+// { dg-require-effective-target ilp32 }
struct A
{
diff --git a/gcc/testsuite/g++.dg/warn/register-var-1.C b/gcc/testsuite/g++.dg/warn/register-var-1.C
index 88e4a6419a0..3396d211385 100644
--- a/gcc/testsuite/g++.dg/warn/register-var-1.C
+++ b/gcc/testsuite/g++.dg/warn/register-var-1.C
@@ -1,6 +1,6 @@
/* PR/18160 */
-/* { dg-do compile { target i?86-*-* } } */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
/* This should yield an error even without -pedantic. */
/* { dg-options "-ansi" } */
diff --git a/gcc/testsuite/g++.old-deja/g++.bob/inherit2.C b/gcc/testsuite/g++.old-deja/g++.bob/inherit2.C
index e943a1caa18..9a64de4dc3e 100644
--- a/gcc/testsuite/g++.old-deja/g++.bob/inherit2.C
+++ b/gcc/testsuite/g++.old-deja/g++.bob/inherit2.C
@@ -6,11 +6,11 @@ public:
void z();
A(void) {}
private:
- A(const A &) { abort(); } // { dg-error "" }
+ A(const A &) { abort(); } // { dg-error "private" }
const A& operator =(const A &) { abort(); }
};
-class B : public A {
+class B : public A { // { dg-error "within" }
public:
B(void) {}
};
@@ -20,5 +20,5 @@ void f(B b) {
void g() {
B h;
- f(h); // { dg-error "" }
+ f(h); // { dg-error "synthesized|argument" }
}
diff --git a/gcc/testsuite/g++.old-deja/g++.bugs/900205_04.C b/gcc/testsuite/g++.old-deja/g++.bugs/900205_04.C
index a2c84fadb9e..d93181ebb1e 100644
--- a/gcc/testsuite/g++.old-deja/g++.bugs/900205_04.C
+++ b/gcc/testsuite/g++.old-deja/g++.bugs/900205_04.C
@@ -23,9 +23,9 @@ struct0::struct0 (int, void *) // { dg-error "note" }
{
}
-struct struct0_derived_struct_0 : public struct0 { // { dg-error "" }
+struct struct0_derived_struct_0 : public struct0 { // { dg-error "no matching" }
};
-struct0_derived_struct_0 object;
+struct0_derived_struct_0 object; // { dg-error "synthesized" }
int main () { return 0; }
diff --git a/gcc/testsuite/g++.old-deja/g++.eh/badalloc1.C b/gcc/testsuite/g++.old-deja/g++.eh/badalloc1.C
index 1cd7bf458a7..3c9941d65c8 100644
--- a/gcc/testsuite/g++.old-deja/g++.eh/badalloc1.C
+++ b/gcc/testsuite/g++.old-deja/g++.eh/badalloc1.C
@@ -1,4 +1,4 @@
-// { dg-do run { xfail xstormy16-*-* *-*-darwin* } }
+// { dg-do run { xfail xstormy16-*-* *-*-darwin[1-7]* } }
// Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 6 June 2000 <nathan@codesourcery.com>
diff --git a/gcc/testsuite/g++.old-deja/g++.ext/asmspec1.C b/gcc/testsuite/g++.old-deja/g++.ext/asmspec1.C
index 146f3ac7348..97d4b8e6bfc 100644
--- a/gcc/testsuite/g++.old-deja/g++.ext/asmspec1.C
+++ b/gcc/testsuite/g++.old-deja/g++.ext/asmspec1.C
@@ -1,4 +1,4 @@
-// { dg-do assemble { target i?86-*-* } }
+// { dg-do assemble { target i?86-*-* x86_64-*-* } }
// Origin: Anthony Green <green@cygnus.com>
void foo ()
diff --git a/gcc/testsuite/g++.old-deja/g++.ext/attrib1.C b/gcc/testsuite/g++.old-deja/g++.ext/attrib1.C
index bdc3ade8b74..e879791665d 100644
--- a/gcc/testsuite/g++.old-deja/g++.ext/attrib1.C
+++ b/gcc/testsuite/g++.old-deja/g++.ext/attrib1.C
@@ -1,5 +1,5 @@
-// { dg-do assemble { target i?86-*-* } }
-// { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } }
+// { dg-do assemble { target i?86-*-* x86_64-*-* } }
+// { dg-require-effective-target ilp32 }
// Test for using prefix attributes in a parameter decl.
// Contributed by Jason Merrill <jason@cygnus.com>
diff --git a/gcc/testsuite/g++.old-deja/g++.ext/attrib2.C b/gcc/testsuite/g++.old-deja/g++.ext/attrib2.C
index c60ff823130..09b2bf2e67d 100644
--- a/gcc/testsuite/g++.old-deja/g++.ext/attrib2.C
+++ b/gcc/testsuite/g++.old-deja/g++.ext/attrib2.C
@@ -1,5 +1,5 @@
-// { dg-do run { target i?86-*-* } }
-// { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } }
+// { dg-do run { target i?86-*-* x86_64-*-* } }
+// { dg-require-effective-target ilp32 }
// Test that stdcall doesn't prevent us from using op delete.
// Contributed by Jason Merrill <jason@cygnus.com>
diff --git a/gcc/testsuite/g++.old-deja/g++.ext/attrib3.C b/gcc/testsuite/g++.old-deja/g++.ext/attrib3.C
index 492cd9d7c49..7d9c70e3b75 100644
--- a/gcc/testsuite/g++.old-deja/g++.ext/attrib3.C
+++ b/gcc/testsuite/g++.old-deja/g++.ext/attrib3.C
@@ -1,5 +1,5 @@
-// { dg-do run { target i?86-*-* } }
-// { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } }
+// { dg-do run { target i?86-*-* x86_64-*-* } }
+// { dg-require-effective-target ilp32 }
// Test for proper handling of attributes in template instantiation.
// Contributed by Jason Merrill <jason@cygnus.com>
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/opeq3.C b/gcc/testsuite/g++.old-deja/g++.jason/opeq3.C
index 50b749eb628..1267fafbe49 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/opeq3.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/opeq3.C
@@ -1,7 +1,7 @@
// { dg-do assemble }
// Bug: g++ generates code for assignment in invalid situations.
-class X {
+class X { // { dg-error "assignment" }
int& a;
public:
X(int& i): a(i) { };
@@ -11,5 +11,5 @@ void foo ()
{
int one=1, two=2;
X a(one), b(two);
- a = b; // { dg-error "" } no assignment semantics defined
+ a = b; // { dg-error "synthesized" }
}
diff --git a/gcc/testsuite/g++.old-deja/g++.other/regstack.C b/gcc/testsuite/g++.old-deja/g++.other/regstack.C
index 5be2fcd9974..5b833473332 100644
--- a/gcc/testsuite/g++.old-deja/g++.other/regstack.C
+++ b/gcc/testsuite/g++.old-deja/g++.other/regstack.C
@@ -1,4 +1,4 @@
-// { dg-do run { target i?86-*-* } }
+// { dg-do run { target i?86-*-* x86_64-*-* } }
// { dg-options "-O2" }
inline double foo (double x)
diff --git a/gcc/testsuite/g++.old-deja/g++.other/store-expr1.C b/gcc/testsuite/g++.old-deja/g++.other/store-expr1.C
index 49456242b4e..31c81a02dd3 100644
--- a/gcc/testsuite/g++.old-deja/g++.other/store-expr1.C
+++ b/gcc/testsuite/g++.old-deja/g++.other/store-expr1.C
@@ -1,5 +1,5 @@
-// { dg-do run { target i?86-*-* } }
-// { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } }
+// { dg-do run { target i?86-*-* x86_64-*-* } }
+// { dg-require-effective-target ilp32 }
// { dg-options "-mtune=i686 -O2 -fpic" }
// { dg-bogus "\[Uu\]nresolved symbol .(_GLOBAL_OFFSET_TABLE_|\[_.A-Za-z\]\[_.0-9A-Za-z\]*@(PLT|GOT|GOTOFF))" "PIC unsupported" { xfail *-*-netware* } 0 }
class G {};
diff --git a/gcc/testsuite/g++.old-deja/g++.other/store-expr2.C b/gcc/testsuite/g++.old-deja/g++.other/store-expr2.C
index d35e3b77dfa..99e0943b3b6 100644
--- a/gcc/testsuite/g++.old-deja/g++.other/store-expr2.C
+++ b/gcc/testsuite/g++.old-deja/g++.other/store-expr2.C
@@ -1,5 +1,5 @@
-// { dg-do run { target i?86-*-* } }
-// { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } }
+// { dg-do run { target i?86-*-* x86_64-*-*} }
+// { dg-require-effective-target ilp32 }
// { dg-options "-mtune=i686 -O2" }
class G {};
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/assign1.C b/gcc/testsuite/g++.old-deja/g++.pt/assign1.C
index 5f6ad345513..9f2a4bf065b 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/assign1.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/assign1.C
@@ -1,8 +1,8 @@
-// { dg-do assemble }
+// { dg-do compile }
// Origin: Mark Mitchell <mark@codesourcery.com>
template <class T>
-struct S {
+struct S { // { dg-error "assignment" }
S();
T t;
};
@@ -10,5 +10,5 @@ struct S {
void f()
{
S<const int> s;
- s = s; // { dg-error "" } generated assignment operator is illegal
+ s = s; // { dg-error "synthesized" }
}
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/crash20.C b/gcc/testsuite/g++.old-deja/g++.pt/crash20.C
index 44f6c8c447a..f910294e65c 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/crash20.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/crash20.C
@@ -1,9 +1,16 @@
-// { dg-do assemble }
+// { dg-do compile }
template <class T = int>
-struct A { const T x; A() : x(0) { } A(T x) : x(x) { } };
+struct A { // { dg-error "assignment" }
+ const T x;
+ A() : x(0) { } A(T x) : x(x) { }
+};
template <class B>
-void func () { B y; y = B(); } // { dg-error "" } can't use default assignment
+void func ()
+{
+ B y;
+ y = B(); // { dg-error "synthesized" }
+}
int main (void) { func< A<> >(); }
diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/ieee.exp b/gcc/testsuite/gcc.c-torture/execute/ieee/ieee.exp
index ff508d3f420..64bbdad7e84 100644
--- a/gcc/testsuite/gcc.c-torture/execute/ieee/ieee.exp
+++ b/gcc/testsuite/gcc.c-torture/execute/ieee/ieee.exp
@@ -1,6 +1,6 @@
#
# Expect driver script for GCC Regression Tests
-# Copyright (C) 1993, 1996, 2001 Free Software Foundation
+# Copyright (C) 1993, 1996, 2001, 2005 Free Software Foundation
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -38,6 +38,9 @@ set additional_flags ""
if [istarget "i\[34567\]86-*-*"] then {
lappend additional_flags "-ffloat-store"
}
+if { [istarget "x86_64-*-*"] && [check_effective_target_ilp32] } then {
+ lappend additional_flags "-ffloat-store"
+}
if [istarget "m68k-*-*"] then {
lappend additional_flags "-ffloat-store"
}
diff --git a/gcc/testsuite/gcc.dg/20000609-1.c b/gcc/testsuite/gcc.dg/20000609-1.c
index dfa64983ef2..5d452ac9d82 100644
--- a/gcc/testsuite/gcc.dg/20000609-1.c
+++ b/gcc/testsuite/gcc.dg/20000609-1.c
@@ -1,6 +1,7 @@
-/* { dg-do run { target i?86-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target ilp32 } */
/* { dg-options "-O1 -ffast-math -march=i686" } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+
/* Sanity check for fp_jcc_* with TARGET_CMOVE. */
diff --git a/gcc/testsuite/gcc.dg/20000614-1.c b/gcc/testsuite/gcc.dg/20000614-1.c
index abc8ca2f714..507596787a6 100644
--- a/gcc/testsuite/gcc.dg/20000614-1.c
+++ b/gcc/testsuite/gcc.dg/20000614-1.c
@@ -1,4 +1,4 @@
-/* { dg-do run { target i?86-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
/* { dg-options "-O2" } */
void bar(char *p)
diff --git a/gcc/testsuite/gcc.dg/20000720-1.c b/gcc/testsuite/gcc.dg/20000720-1.c
index 89b570d750a..65bf68544b4 100644
--- a/gcc/testsuite/gcc.dg/20000720-1.c
+++ b/gcc/testsuite/gcc.dg/20000720-1.c
@@ -1,5 +1,5 @@
-/* { dg-do compile { target i?86-*-* } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target ilp32 } */
/* { dg-options "-mpreferred-stack-boundary=2 -march=i586 -O2 -fomit-frame-pointer" } */
extern void *foo(void *a, const void *b, unsigned c);
diff --git a/gcc/testsuite/gcc.dg/20000807-1.c b/gcc/testsuite/gcc.dg/20000807-1.c
index f6547649483..360e3245989 100644
--- a/gcc/testsuite/gcc.dg/20000807-1.c
+++ b/gcc/testsuite/gcc.dg/20000807-1.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target i?86-*-* } } */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
/* { dg-options "-Os -fpic" } */
#include <string.h>
diff --git a/gcc/testsuite/gcc.dg/20000904-1.c b/gcc/testsuite/gcc.dg/20000904-1.c
index c6238e35099..31f937cab71 100644
--- a/gcc/testsuite/gcc.dg/20000904-1.c
+++ b/gcc/testsuite/gcc.dg/20000904-1.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target i?86-*-* } } */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
/* { dg-options "-O0 -fpic" } */
static struct {
diff --git a/gcc/testsuite/gcc.dg/20001127-1.c b/gcc/testsuite/gcc.dg/20001127-1.c
index 6ac76e29e92..f63d1149322 100644
--- a/gcc/testsuite/gcc.dg/20001127-1.c
+++ b/gcc/testsuite/gcc.dg/20001127-1.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target i?86-*-* } } */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
/* { dg-options "-O2" } */
extern inline float bar (float x)
diff --git a/gcc/testsuite/gcc.dg/20010202-1.c b/gcc/testsuite/gcc.dg/20010202-1.c
index f600373b8a3..5f789042eba 100644
--- a/gcc/testsuite/gcc.dg/20010202-1.c
+++ b/gcc/testsuite/gcc.dg/20010202-1.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target i?86-*-* sparc*-*-* } } */
+/* { dg-do compile { target i?86-*-* sparc*-*-* x86_64-*-* } } */
/* { dg-options "-O2" } */
extern void abort (void);
diff --git a/gcc/testsuite/gcc.dg/20010520-1.c b/gcc/testsuite/gcc.dg/20010520-1.c
index c96dbc4eee5..97ee32b0b82 100644
--- a/gcc/testsuite/gcc.dg/20010520-1.c
+++ b/gcc/testsuite/gcc.dg/20010520-1.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target i?86-*-* } } */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
/* { dg-options "-w" } */
void f ()
diff --git a/gcc/testsuite/gcc.dg/20011009-1.c b/gcc/testsuite/gcc.dg/20011009-1.c
index dbf32e63fba..b78d99e997b 100644
--- a/gcc/testsuite/gcc.dg/20011009-1.c
+++ b/gcc/testsuite/gcc.dg/20011009-1.c
@@ -1,4 +1,4 @@
-/* { dg-do run { target i?86-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
/* { dg-options "-O2" } */
extern void abort (void);
diff --git a/gcc/testsuite/gcc.dg/20011029-2.c b/gcc/testsuite/gcc.dg/20011029-2.c
index 6fdc6216678..07ef1a806fe 100644
--- a/gcc/testsuite/gcc.dg/20011029-2.c
+++ b/gcc/testsuite/gcc.dg/20011029-2.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target i?86-*-* } } */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
/* { dg-options "-O2" } */
int foo (int s)
diff --git a/gcc/testsuite/gcc.dg/20011107-1.c b/gcc/testsuite/gcc.dg/20011107-1.c
index a53f4f1912e..0d09427a0b4 100644
--- a/gcc/testsuite/gcc.dg/20011107-1.c
+++ b/gcc/testsuite/gcc.dg/20011107-1.c
@@ -1,5 +1,5 @@
-/* { dg-do compile { target i?86-*-* } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target ilp32 } */
/* { dg-options "-O2 -mtune=k6" } */
void
diff --git a/gcc/testsuite/gcc.dg/20011119-1.c b/gcc/testsuite/gcc.dg/20011119-1.c
index 5758f8b1bf0..bbdf104d1c8 100644
--- a/gcc/testsuite/gcc.dg/20011119-1.c
+++ b/gcc/testsuite/gcc.dg/20011119-1.c
@@ -1,6 +1,7 @@
/* Test for reload failing to eliminate from argp to sp. */
-/* { dg-do run { target i?86-*-* } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" "-fpic" "-fPIC" } { "" } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-skip-if "" { "*-*-*" } { "-fpic" "-fPIC" } { "" } } */
/* { dg-options "-O2 -fomit-frame-pointer" } */
static int ustrsize (const char *s);
diff --git a/gcc/testsuite/gcc.dg/20020108-1.c b/gcc/testsuite/gcc.dg/20020108-1.c
index 03b97d1fec6..32d24fdca3e 100644
--- a/gcc/testsuite/gcc.dg/20020108-1.c
+++ b/gcc/testsuite/gcc.dg/20020108-1.c
@@ -5,8 +5,9 @@
is not valid general_operand in HImode. */
/* { dg-do compile } */
/* { dg-options "-O2" } */
-/* { dg-options "-O2 -mtune=i686" { target i?86-*-* } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-options "-O2 -mtune=i686" { target { i?86-*-* && ilp32 } } } */
+/* { dg-options "-O2 -mtune=i686" { target { x86_64-*-* && ilp32 } } } */
+
void
foo (unsigned short *cp)
diff --git a/gcc/testsuite/gcc.dg/20020122-2.c b/gcc/testsuite/gcc.dg/20020122-2.c
index de92bd82880..5dca0dba4c4 100644
--- a/gcc/testsuite/gcc.dg/20020122-2.c
+++ b/gcc/testsuite/gcc.dg/20020122-2.c
@@ -3,8 +3,8 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fprefetch-loop-arrays -w" } */
-/* { dg-options "-O2 -fprefetch-loop-arrays -march=athlon" { target i?86-*-* } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-options "-O2 -fprefetch-loop-arrays -march=athlon" { target { i?86-*-* && ilp32 } } } */
+/* { dg-options "-O2 -fprefetch-loop-arrays -march=athlon" { target { x86_64-*-* && ilp32 } } } */
extern int access( char* );
extern int a();
diff --git a/gcc/testsuite/gcc.dg/20020122-3.c b/gcc/testsuite/gcc.dg/20020122-3.c
index 4aafc4777c9..bcf257527c0 100644
--- a/gcc/testsuite/gcc.dg/20020122-3.c
+++ b/gcc/testsuite/gcc.dg/20020122-3.c
@@ -4,8 +4,8 @@
/* { dg-do compile } */
/* { dg-options "-Os -fprefetch-loop-arrays -w" } */
-/* { dg-options "-Os -fprefetch-loop-arrays -mtune=pentium3 -w" { target i?86-*-* } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-options "-Os -fprefetch-loop-arrays -mtune=pentium3 -w" { target { i?86-*-* && ilp32 } } } */
+/* { dg-options "-Os -fprefetch-loop-arrays -mtune=pentium3 -w" { target { x86_64-*-* && ilp32 } } } */
int foo (int *p, int n)
{
diff --git a/gcc/testsuite/gcc.dg/20020201-3.c b/gcc/testsuite/gcc.dg/20020201-3.c
index 66a48022b16..e95c44fbdfb 100644
--- a/gcc/testsuite/gcc.dg/20020201-3.c
+++ b/gcc/testsuite/gcc.dg/20020201-3.c
@@ -1,7 +1,7 @@
/* This testcase ICEd because a SFmode variable was given a MMX register
for which there is no movsf exists. */
-/* { dg-do compile { target i?86-*-* } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target ilp32 } */
/* { dg-options "-O2 -march=i686 -mmmx -fno-strict-aliasing" } */
struct A { unsigned int a, b; };
diff --git a/gcc/testsuite/gcc.dg/20020206-1.c b/gcc/testsuite/gcc.dg/20020206-1.c
index 1bdb25de166..26c36c43b8e 100644
--- a/gcc/testsuite/gcc.dg/20020206-1.c
+++ b/gcc/testsuite/gcc.dg/20020206-1.c
@@ -4,8 +4,9 @@
/* { dg-do run } */
/* { dg-options "-O2 -fprefetch-loop-arrays -w" } */
-/* { dg-options "-O2 -fprefetch-loop-arrays -mtune=pentium3 -w" { target i?86-*-* } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-options "-O2 -fprefetch-loop-arrays -mtune=pentium3 -w" { target { i?86-*-* && ilp32 } } } */
+/* { dg-options "-O2 -fprefetch-loop-arrays -mtune=pentium3 -w" { target { x86_64-*-* && ilp32 } } } */
+
struct reload
{
diff --git a/gcc/testsuite/gcc.dg/20020218-1.c b/gcc/testsuite/gcc.dg/20020218-1.c
index 240c3d7e2ab..bef4d66fc13 100644
--- a/gcc/testsuite/gcc.dg/20020218-1.c
+++ b/gcc/testsuite/gcc.dg/20020218-1.c
@@ -1,6 +1,6 @@
/* Verify that X86-64 only SSE registers aren't restored on IA-32. */
-/* { dg-do compile { target i?86-*-* } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target ilp32 } */
/* { dg-options "-O2 -msse" } */
/* { dg-final { scan-assembler-not "xmm8" } } */
diff --git a/gcc/testsuite/gcc.dg/20020224-1.c b/gcc/testsuite/gcc.dg/20020224-1.c
index a286b6b0599..c37de2e21b7 100644
--- a/gcc/testsuite/gcc.dg/20020224-1.c
+++ b/gcc/testsuite/gcc.dg/20020224-1.c
@@ -3,7 +3,7 @@
expected the callee to pop up the hidden return structure pointer,
while callee was actually not poping it up (as the hidden argument
was passed in register). */
-/* { dg-do run { target i?86-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
/* { dg-options "-O2 -fomit-frame-pointer" } */
extern void abort (void);
diff --git a/gcc/testsuite/gcc.dg/20020310-1.c b/gcc/testsuite/gcc.dg/20020310-1.c
index 6067e190622..345199dcd72 100644
--- a/gcc/testsuite/gcc.dg/20020310-1.c
+++ b/gcc/testsuite/gcc.dg/20020310-1.c
@@ -2,8 +2,8 @@
This testcase was miscompiled because of an rtx sharing bug. */
/* { dg-do run } */
/* { dg-options "-O2" } */
-/* { dg-options "-O2 -mtune=i586" { target i?86-*-* } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-options "-O2 -mtune=i586" { target { i?86-*-* && ilp32 } } } */
+/* { dg-options "-O2 -mtune=i586" { target { x86_64-*-* && ilp32 } } } */
struct A
{
diff --git a/gcc/testsuite/gcc.dg/20020411-1.c b/gcc/testsuite/gcc.dg/20020411-1.c
index 0413ed9b56b..8908c32afaf 100644
--- a/gcc/testsuite/gcc.dg/20020411-1.c
+++ b/gcc/testsuite/gcc.dg/20020411-1.c
@@ -3,8 +3,8 @@
for its mode. */
/* { dg-do compile } */
/* { dg-options "-O2" } */
-/* { dg-options "-O2 -march=i686" { target i?86-*-* } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-options "-O2 -march=i686" { target { i?86-*-* && ilp32 } } } */
+/* { dg-options "-O2 -march=i686" { target { x86_64-*-* && ilp32 } } } */
#if __INT_MAX__ > 32767
diff --git a/gcc/testsuite/gcc.dg/20020418-2.c b/gcc/testsuite/gcc.dg/20020418-2.c
index 8a15b2644f5..07722ce758f 100644
--- a/gcc/testsuite/gcc.dg/20020418-2.c
+++ b/gcc/testsuite/gcc.dg/20020418-2.c
@@ -1,8 +1,8 @@
/* PR optimization/6010 */
/* { dg-do compile } */
/* { dg-options "-O2 -funroll-all-loops" } */
-/* { dg-options "-O2 -funroll-all-loops -march=pentium3" { target i?86-*-* } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-options "-O2 -funroll-all-loops -march=pentium3" { target { i?86-*-* && ilp32 } } } */
+/* { dg-options "-O2 -funroll-all-loops -march=pentium3" { target { x86_64-*-* && ilp32 } } } */
void bar (float);
diff --git a/gcc/testsuite/gcc.dg/20020426-1.c b/gcc/testsuite/gcc.dg/20020426-1.c
index 67b09b3f80d..31be74712c0 100644
--- a/gcc/testsuite/gcc.dg/20020426-1.c
+++ b/gcc/testsuite/gcc.dg/20020426-1.c
@@ -1,6 +1,6 @@
-/* { dg-do compile { target i?86-*-* } } */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target ilp32 } */
/* { dg-options "-msoft-float -mfp-ret-in-387" } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
void f() {
__builtin_apply(0, 0, 0);
diff --git a/gcc/testsuite/gcc.dg/20020426-2.c b/gcc/testsuite/gcc.dg/20020426-2.c
index 19bf991b346..6bb53cf598c 100644
--- a/gcc/testsuite/gcc.dg/20020426-2.c
+++ b/gcc/testsuite/gcc.dg/20020426-2.c
@@ -2,8 +2,8 @@
Distilled from zlib sources. */
/* { dg-do run } */
/* { dg-options "-O2" } */
-/* { dg-options "-O2 -frename-registers -fomit-frame-pointer -fPIC -mtune=i686" { target i?86-*-* } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-options "-O2 -frename-registers -fomit-frame-pointer -fPIC -mtune=i686" { target { i?86-*-* && ilp32 } } } */
+/* { dg-options "-O2 -frename-registers -fomit-frame-pointer -fPIC -mtune=i686" { target { x86_64-*-* && ilp32 } } } */
/* { dg-bogus "\[Uu\]nresolved symbol .(_GLOBAL_OFFSET_TABLE_|\[_.A-Za-z\]\[_.0-9A-Za-z\]*@(PLT|GOT|GOTOFF))" "PIC unsupported" { xfail *-*-netware* } 0 } */
extern void exit (int);
diff --git a/gcc/testsuite/gcc.dg/20020517-1.c b/gcc/testsuite/gcc.dg/20020517-1.c
index 72b252900d4..bde20095594 100644
--- a/gcc/testsuite/gcc.dg/20020517-1.c
+++ b/gcc/testsuite/gcc.dg/20020517-1.c
@@ -2,8 +2,8 @@
was not sign-extended for QImode. */
/* { dg-do run } */
/* { dg-options "-O2" } */
-/* { dg-options "-O2 -mtune=i686" { target i?86-*-* } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-options "-O2 -mtune=i686" { target { i?86-*-* && ilp32 } } } */
+/* { dg-options "-O2 -mtune=i686" { target { x86_64-*-* && ilp32 } } } */
#include <limits.h>
diff --git a/gcc/testsuite/gcc.dg/20020523-1.c b/gcc/testsuite/gcc.dg/20020523-1.c
index d29f20ae2e6..51ae5ecb689 100644
--- a/gcc/testsuite/gcc.dg/20020523-1.c
+++ b/gcc/testsuite/gcc.dg/20020523-1.c
@@ -1,8 +1,8 @@
/* PR target/6753
This testcase was miscompiled because sse_mov?fcc_const0*
patterns were missing earlyclobber. */
-/* { dg-do run { target i386-*-* } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target ilp32 } */
/* { dg-options "-march=pentium3 -msse -ffast-math -O2" } */
extern void abort (void);
diff --git a/gcc/testsuite/gcc.dg/20020523-2.c b/gcc/testsuite/gcc.dg/20020523-2.c
index 086f1d469e6..ebe8bb8f5cd 100644
--- a/gcc/testsuite/gcc.dg/20020523-2.c
+++ b/gcc/testsuite/gcc.dg/20020523-2.c
@@ -1,8 +1,8 @@
/* PR target/6753
This testcase was miscompiled because sse_mov?fcc_const0*
patterns were missing earlyclobber. */
-/* { dg-do run { target i386-*-* } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target ilp32 } */
/* { dg-options "-march=pentium3 -msse -ffast-math -O2" } */
#include "i386-cpuid.h"
diff --git a/gcc/testsuite/gcc.dg/20020531-1.c b/gcc/testsuite/gcc.dg/20020531-1.c
index 19f198fcac1..dfefc17c45a 100644
--- a/gcc/testsuite/gcc.dg/20020531-1.c
+++ b/gcc/testsuite/gcc.dg/20020531-1.c
@@ -1,7 +1,7 @@
/* PR optimization/6842
This testcase caused ICE when trying to optimize V8QI subreg of VOIDmode
CONST_DOUBLE. */
-/* { dg-do compile { target i?86-*-* } } */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
/* { dg-options "-O2 -mmmx" } */
typedef unsigned char __v8qi __attribute__ ((vector_size (8)));
diff --git a/gcc/testsuite/gcc.dg/20020616-1.c b/gcc/testsuite/gcc.dg/20020616-1.c
index 4630664d957..6db78425596 100644
--- a/gcc/testsuite/gcc.dg/20020616-1.c
+++ b/gcc/testsuite/gcc.dg/20020616-1.c
@@ -1,5 +1,5 @@
/* PR opt/6722 */
-/* { dg-do run { target i?86-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
/* { dg-options "-O2" } */
register int k asm("%ebx");
diff --git a/gcc/testsuite/gcc.dg/20020729-1.c b/gcc/testsuite/gcc.dg/20020729-1.c
index 929b5c361bd..eeab6985422 100644
--- a/gcc/testsuite/gcc.dg/20020729-1.c
+++ b/gcc/testsuite/gcc.dg/20020729-1.c
@@ -1,5 +1,5 @@
-/* { dg-do compile { target i?86-*-* } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target ilp32 } */
/* { dg-options "-O2 -march=k6" } */
static inline void *
diff --git a/gcc/testsuite/gcc.dg/20030204-1.c b/gcc/testsuite/gcc.dg/20030204-1.c
index 33a9eb229f9..0d4286c08cf 100644
--- a/gcc/testsuite/gcc.dg/20030204-1.c
+++ b/gcc/testsuite/gcc.dg/20030204-1.c
@@ -1,8 +1,9 @@
/* PR optimization/8555 */
/* { dg-do compile } */
/* { dg-options "-O -ffast-math -funroll-loops" } */
-/* { dg-options "-march=pentium3 -O -ffast-math -funroll-loops" { target i?86-*-* } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-options "-march=pentium3 -O -ffast-math -funroll-loops" { target { i?86-*-* && ilp32 } } } */
+/* { dg-options "-march=pentium3 -O -ffast-math -funroll-loops" { target { x86_64-*-* && ilp32 } } } */
+
float foo (float *a, int i)
{
diff --git a/gcc/testsuite/gcc.dg/20030826-2.c b/gcc/testsuite/gcc.dg/20030826-2.c
index e69c5346a26..6ad7e9a1292 100644
--- a/gcc/testsuite/gcc.dg/20030826-2.c
+++ b/gcc/testsuite/gcc.dg/20030826-2.c
@@ -1,7 +1,7 @@
/* { dg-do run } */
/* { dg-options "-O2 -fomit-frame-pointer" } */
-/* { dg-options "-O2 -fomit-frame-pointer -march=i386" { target i?86-*-* } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-options "-O2 -fomit-frame-pointer -march=i386" { target { i?86-*-* && ilp32 } } } */
+/* { dg-options "-O2 -fomit-frame-pointer -march=i386" { target { x86_64-*-* && ilp32 } } } */
extern void abort (void);
extern void exit (int);
diff --git a/gcc/testsuite/gcc.dg/20030926-1.c b/gcc/testsuite/gcc.dg/20030926-1.c
index 09931b378dd..866ebb808d5 100644
--- a/gcc/testsuite/gcc.dg/20030926-1.c
+++ b/gcc/testsuite/gcc.dg/20030926-1.c
@@ -1,8 +1,8 @@
/* PR optimization/11741 */
/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
/* { dg-options "-O2 -minline-all-stringops" } */
-/* { dg-options "-O2 -minline-all-stringops -march=pentium4" { target i?86-*-* } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-options "-O2 -minline-all-stringops -march=pentium4" { target { i?86-*-* && ilp32 } } } */
+/* { dg-options "-O2 -minline-all-stringops -march=pentium4" { target { x86_64-*-* && ilp32 } } } */
extern void *memcpy (void *, const void *, __SIZE_TYPE__);
extern __SIZE_TYPE__ strlen (const char *);
diff --git a/gcc/testsuite/gcc.dg/20031202-1.c b/gcc/testsuite/gcc.dg/20031202-1.c
index ac443a28425..4290f86889b 100644
--- a/gcc/testsuite/gcc.dg/20031202-1.c
+++ b/gcc/testsuite/gcc.dg/20031202-1.c
@@ -1,7 +1,7 @@
/* { dg-do run } */
/* { dg-options "-O2" } */
-/* { dg-options "-O2 -mtune=i686" { target i?86-*-* } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-options "-O2 -mtune=i686" { target { i?86-*-* && ilp32 } } } */
+/* { dg-options "-O2 -mtune=i686" { target { x86_64-*-* && ilp32 } } } */
extern void abort (void);
extern void exit (int);
diff --git a/gcc/testsuite/gcc.dg/980226-1.c b/gcc/testsuite/gcc.dg/980226-1.c
index f9d915f22d4..52ff614ed3a 100644
--- a/gcc/testsuite/gcc.dg/980226-1.c
+++ b/gcc/testsuite/gcc.dg/980226-1.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target i?86-*-* } } */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
/* { dg-options -O2 } */
extern int printf (const char *, ...);
diff --git a/gcc/testsuite/gcc.dg/980312-1.c b/gcc/testsuite/gcc.dg/980312-1.c
index 83f1488745a..edf3cf5d79d 100644
--- a/gcc/testsuite/gcc.dg/980312-1.c
+++ b/gcc/testsuite/gcc.dg/980312-1.c
@@ -1,5 +1,5 @@
-/* { dg-do link { target i?86-*-* } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-do link { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target ilp32 } */
/* { dg-options "-O2 -march=pentiumpro" } */
extern __inline double
diff --git a/gcc/testsuite/gcc.dg/980313-1.c b/gcc/testsuite/gcc.dg/980313-1.c
index 75566222116..889654fc792 100644
--- a/gcc/testsuite/gcc.dg/980313-1.c
+++ b/gcc/testsuite/gcc.dg/980313-1.c
@@ -1,5 +1,5 @@
-/* { dg-do link { target i?86-*-* } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-do link { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target ilp32 } */
/* { dg-options "-O2 -march=pentiumpro" } */
extern __inline double
diff --git a/gcc/testsuite/gcc.dg/980414-1.c b/gcc/testsuite/gcc.dg/980414-1.c
index 59382ef2c49..e179c8137c0 100644
--- a/gcc/testsuite/gcc.dg/980414-1.c
+++ b/gcc/testsuite/gcc.dg/980414-1.c
@@ -1,6 +1,6 @@
/* Test double on x86. */
-/* { dg-do run { target i?86-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
/* { dg-options -O2 } */
extern void abort (void);
diff --git a/gcc/testsuite/gcc.dg/980520-1.c b/gcc/testsuite/gcc.dg/980520-1.c
index e1401824f54..b11f0d3a893 100644
--- a/gcc/testsuite/gcc.dg/980520-1.c
+++ b/gcc/testsuite/gcc.dg/980520-1.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target i?86-*-* } } */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
/* { dg-options -O2 } */
int bug(void)
diff --git a/gcc/testsuite/gcc.dg/980709-1.c b/gcc/testsuite/gcc.dg/980709-1.c
index a4359300587..01b6bfe358e 100644
--- a/gcc/testsuite/gcc.dg/980709-1.c
+++ b/gcc/testsuite/gcc.dg/980709-1.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target i?86-*-* } } */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
/* { dg-options -O2 } */
extern __inline__ int test_and_set_bit(int nr, volatile void * addr)
diff --git a/gcc/testsuite/gcc.dg/990117-1.c b/gcc/testsuite/gcc.dg/990117-1.c
index 6d71787f305..24c56f2febf 100644
--- a/gcc/testsuite/gcc.dg/990117-1.c
+++ b/gcc/testsuite/gcc.dg/990117-1.c
@@ -1,5 +1,5 @@
-/* { dg-do compile { target i?86-*-* } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target ilp32 } */
/* { dg-options "-O2 -march=pentiumpro" } */
extern __inline double
diff --git a/gcc/testsuite/gcc.dg/990130-1.c b/gcc/testsuite/gcc.dg/990130-1.c
index 3e711c2febb..57e046b22a6 100644
--- a/gcc/testsuite/gcc.dg/990130-1.c
+++ b/gcc/testsuite/gcc.dg/990130-1.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target i?86-*-* } } */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
/* { dg-options -O0 } */
typedef int SItype __attribute__ ((mode (SI)));
diff --git a/gcc/testsuite/gcc.dg/990213-2.c b/gcc/testsuite/gcc.dg/990213-2.c
index a0a13b560f9..d095e3723f9 100644
--- a/gcc/testsuite/gcc.dg/990213-2.c
+++ b/gcc/testsuite/gcc.dg/990213-2.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target i?86-*-* } } */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
/* { dg-options "-fPIC" } */
struct normal_encoding {};
diff --git a/gcc/testsuite/gcc.dg/990214-1.c b/gcc/testsuite/gcc.dg/990214-1.c
index 7ad81b6b90b..b3cb519a471 100644
--- a/gcc/testsuite/gcc.dg/990214-1.c
+++ b/gcc/testsuite/gcc.dg/990214-1.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target i?86-*-* } } */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
/* { dg-options "-fPIC" } */
typedef int int64_t __attribute__ ((__mode__ ( __DI__ ))) ;
diff --git a/gcc/testsuite/gcc.dg/990424-1.c b/gcc/testsuite/gcc.dg/990424-1.c
index d479754a9ef..5b5af818076 100644
--- a/gcc/testsuite/gcc.dg/990424-1.c
+++ b/gcc/testsuite/gcc.dg/990424-1.c
@@ -1,8 +1,8 @@
/* Test that stack alignment is preserved with pending_stack_adjust
with stdcall functions. */
-/* { dg-do run { target i?86-*-* } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target ilp32 } */
/* { dg-options -mpreferred-stack-boundary=4 } */
void __attribute__((stdcall)) foo(int a, int b, int c);
diff --git a/gcc/testsuite/gcc.dg/990524-1.c b/gcc/testsuite/gcc.dg/990524-1.c
index 203c1dd452d..ee4ebd62671 100644
--- a/gcc/testsuite/gcc.dg/990524-1.c
+++ b/gcc/testsuite/gcc.dg/990524-1.c
@@ -1,5 +1,5 @@
-/* { dg-do compile { target i?86-*-* } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target ilp32 } */
/* { dg-options "-O2 -march=pentiumpro" } */
typedef struct t_anim_info {
diff --git a/gcc/testsuite/gcc.dg/991129-1.c b/gcc/testsuite/gcc.dg/991129-1.c
index 24faefddaff..489b7f987fa 100644
--- a/gcc/testsuite/gcc.dg/991129-1.c
+++ b/gcc/testsuite/gcc.dg/991129-1.c
@@ -1,6 +1,6 @@
/* Test against a problem in push_reload. */
-/* { dg-do compile { target i?86-*-* } } */
+/* { dg-do compile { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
/* { dg-options "-O2" } */
unsigned long foo (unsigned long long x, unsigned long y)
diff --git a/gcc/testsuite/gcc.dg/991209-1.c b/gcc/testsuite/gcc.dg/991209-1.c
index 2381922c660..ab455da098d 100644
--- a/gcc/testsuite/gcc.dg/991209-1.c
+++ b/gcc/testsuite/gcc.dg/991209-1.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target i?86-*-* } } */
+/* { dg-do compile { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
/* { dg-options "-ansi -pedantic" } */
int foo ()
diff --git a/gcc/testsuite/gcc.dg/991214-1.c b/gcc/testsuite/gcc.dg/991214-1.c
index 68b6b927916..cfe3a9a4121 100644
--- a/gcc/testsuite/gcc.dg/991214-1.c
+++ b/gcc/testsuite/gcc.dg/991214-1.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target i?86-*-* } } */
+/* { dg-do compile { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
/* { dg-options "-O2" } */
/* Test against a problem with the combiner substituting explicit hard reg
diff --git a/gcc/testsuite/gcc.dg/991230-1.c b/gcc/testsuite/gcc.dg/991230-1.c
index 1cb66f5c379..b87d0e2e3cb 100644
--- a/gcc/testsuite/gcc.dg/991230-1.c
+++ b/gcc/testsuite/gcc.dg/991230-1.c
@@ -1,5 +1,5 @@
-/* { dg-do run { target i?86-*-* } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target ilp32 } */
/* { dg-options "-O -ffast-math -mtune=i486" } */
/* Test that floating point greater-than tests are compiled correctly with
diff --git a/gcc/testsuite/gcc.dg/asm-1.c b/gcc/testsuite/gcc.dg/asm-1.c
index 1f509422e97..ac4b6be4b10 100644
--- a/gcc/testsuite/gcc.dg/asm-1.c
+++ b/gcc/testsuite/gcc.dg/asm-1.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target i?86-*-* } } */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
struct x {
int selector;
diff --git a/gcc/testsuite/gcc.dg/attr-returns_twice-1.c b/gcc/testsuite/gcc.dg/attr-returns_twice-1.c
index 9d3f6f10997..9eb082f4b03 100644
--- a/gcc/testsuite/gcc.dg/attr-returns_twice-1.c
+++ b/gcc/testsuite/gcc.dg/attr-returns_twice-1.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target i?86-*-* } } */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
/* { dg-options "-W" } */
int newsetjmp(void) __attribute__((returns_twice));
diff --git a/gcc/testsuite/gcc.dg/builtins-1.c b/gcc/testsuite/gcc.dg/builtins-1.c
index 74144f7befa..640576a50a7 100644
--- a/gcc/testsuite/gcc.dg/builtins-1.c
+++ b/gcc/testsuite/gcc.dg/builtins-1.c
@@ -190,7 +190,7 @@ CPTEST1 (ccos)
CPTEST1 (ccosh)
CPTEST1 (cexp)
CPTEST1RETFP (cimag)
-/*CPTEST1 (clog)*/
+CPTEST1 (clog)
CPTEST1 (conj)
CPTEST2 (cpow)
CPTEST1 (cproj)
diff --git a/gcc/testsuite/gcc.dg/c99-math-double-1.c b/gcc/testsuite/gcc.dg/c99-math-double-1.c
index 227b6e26cac..54bdf60dfe7 100644
--- a/gcc/testsuite/gcc.dg/c99-math-double-1.c
+++ b/gcc/testsuite/gcc.dg/c99-math-double-1.c
@@ -1,18 +1,18 @@
-/* { dg-do run { target *-*-solaris2.1[0-9]* } } */
-/* { dg-options "-std=c99 -O" } */
-
-#include <math.h>
-#include "c99-math.h"
-
-int main(void)
-{
- double nan = NAN;
- double inf = INFINITY;
- double huge = HUGE_VAL;
- double norm = __DBL_MIN__;
- double zero = 0.0;
-
- C99_MATH_TESTS (nan, inf, huge, norm, zero)
-
- return 0;
-}
+/* { dg-do run { target *-*-solaris2.1[0-9]* } } */
+/* { dg-options "-std=c99 -O" } */
+
+#include <math.h>
+#include "c99-math.h"
+
+int main(void)
+{
+ double nan = NAN;
+ double inf = INFINITY;
+ double huge = HUGE_VAL;
+ double norm = __DBL_MIN__;
+ double zero = 0.0;
+
+ C99_MATH_TESTS (nan, inf, huge, norm, zero)
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/c99-math-float-1.c b/gcc/testsuite/gcc.dg/c99-math-float-1.c
index 9dd4e9a0483..ba27a710bde 100644
--- a/gcc/testsuite/gcc.dg/c99-math-float-1.c
+++ b/gcc/testsuite/gcc.dg/c99-math-float-1.c
@@ -1,18 +1,18 @@
-/* { dg-do run { target *-*-solaris2.1[0-9]* } } */
-/* { dg-options "-std=c99 -O" } */
-
-#include <math.h>
-#include "c99-math.h"
-
-int main(void)
-{
- float nan = NAN;
- float inf = INFINITY;
- float huge = HUGE_VALF;
- float norm = __FLT_MIN__;
- float zero = 0.0f;
-
- C99_MATH_TESTS (nan, inf, huge, norm, zero)
-
- return 0;
-}
+/* { dg-do run { target *-*-solaris2.1[0-9]* } } */
+/* { dg-options "-std=c99 -O" } */
+
+#include <math.h>
+#include "c99-math.h"
+
+int main(void)
+{
+ float nan = NAN;
+ float inf = INFINITY;
+ float huge = HUGE_VALF;
+ float norm = __FLT_MIN__;
+ float zero = 0.0f;
+
+ C99_MATH_TESTS (nan, inf, huge, norm, zero)
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/c99-math-long-double-1.c b/gcc/testsuite/gcc.dg/c99-math-long-double-1.c
index 43d15885473..a8fa4d21fc1 100644
--- a/gcc/testsuite/gcc.dg/c99-math-long-double-1.c
+++ b/gcc/testsuite/gcc.dg/c99-math-long-double-1.c
@@ -1,18 +1,18 @@
-/* { dg-do run { target *-*-solaris2.1[0-9]* } } */
-/* { dg-options "-std=c99 -O" } */
-
-#include <math.h>
-#include "c99-math.h"
-
-int main(void)
-{
- long double nan = NAN;
- long double inf = INFINITY;
- long double huge = HUGE_VALL;
- long double norm = __LDBL_MIN__;
- long double zero = 0.0l;
-
- C99_MATH_TESTS (nan, inf, huge, norm, zero)
-
- return 0;
-}
+/* { dg-do run { target *-*-solaris2.1[0-9]* } } */
+/* { dg-options "-std=c99 -O" } */
+
+#include <math.h>
+#include "c99-math.h"
+
+int main(void)
+{
+ long double nan = NAN;
+ long double inf = INFINITY;
+ long double huge = HUGE_VALL;
+ long double norm = __LDBL_MIN__;
+ long double zero = 0.0l;
+
+ C99_MATH_TESTS (nan, inf, huge, norm, zero)
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/c99-math.h b/gcc/testsuite/gcc.dg/c99-math.h
index a1e217c8ef3..3f42f67319d 100644
--- a/gcc/testsuite/gcc.dg/c99-math.h
+++ b/gcc/testsuite/gcc.dg/c99-math.h
@@ -1,111 +1,111 @@
-#include <math.h>
-
-extern void abort(void);
-
-#define C99_MATH_TESTS(nan, inf, huge, norm, zero) \
-{ \
- if (fpclassify (nan) != FP_NAN) \
- abort (); \
- \
- if (fpclassify (inf) != FP_INFINITE) \
- abort (); \
- \
- if (fpclassify (huge) != FP_INFINITE) \
- abort (); \
- \
- if (fpclassify (norm) != FP_NORMAL) \
- abort (); \
- \
- if (fpclassify (zero) != FP_ZERO) \
- abort (); \
- \
- \
- if (!isnan (nan)) \
- abort (); \
- \
- if (isnan (inf)) \
- abort (); \
- \
- if (isnan (huge)) \
- abort (); \
- \
- if (isnan (norm)) \
- abort (); \
- \
- if (isnan (zero)) \
- abort (); \
- \
- \
- if (isinf (nan)) \
- abort (); \
- \
- if (!isinf (inf)) \
- abort (); \
- \
- if (!isinf (huge)) \
- abort (); \
- \
- if (isnan (norm)) \
- abort (); \
- \
- if (isinf (zero)) \
- abort (); \
- \
- \
- if (isfinite (nan)) \
- abort (); \
- \
- if (isfinite (inf)) \
- abort (); \
- \
- if (isfinite (huge)) \
- abort (); \
- \
- if (!isfinite (norm)) \
- abort (); \
- \
- if (!isfinite (zero)) \
- abort (); \
- \
- \
- if (isnormal (nan)) \
- abort (); \
- \
- if (isnormal (inf)) \
- abort (); \
- \
- if (isnormal (huge)) \
- abort (); \
- \
- if (!isnormal (norm)) \
- abort (); \
- \
- if (isnormal (zero)) \
- abort (); \
- \
- \
- if (signbit (norm)) \
- abort (); \
- \
- if (!signbit (-(norm))) \
- abort (); \
- \
- \
- if (!isgreater ((inf), (norm))) \
- abort (); \
- \
- if (!isgreaterequal ((inf), (huge))) \
- abort (); \
- \
- if (!isless ((norm), (inf))) \
- abort (); \
- \
- if (!islessequal ((huge), (inf))) \
- abort (); \
- \
- if (!islessgreater ((inf), (norm))) \
- abort (); \
- \
- if (!isunordered ((nan), (norm))) \
- abort (); \
-}
+#include <math.h>
+
+extern void abort(void);
+
+#define C99_MATH_TESTS(nan, inf, huge, norm, zero) \
+{ \
+ if (fpclassify (nan) != FP_NAN) \
+ abort (); \
+ \
+ if (fpclassify (inf) != FP_INFINITE) \
+ abort (); \
+ \
+ if (fpclassify (huge) != FP_INFINITE) \
+ abort (); \
+ \
+ if (fpclassify (norm) != FP_NORMAL) \
+ abort (); \
+ \
+ if (fpclassify (zero) != FP_ZERO) \
+ abort (); \
+ \
+ \
+ if (!isnan (nan)) \
+ abort (); \
+ \
+ if (isnan (inf)) \
+ abort (); \
+ \
+ if (isnan (huge)) \
+ abort (); \
+ \
+ if (isnan (norm)) \
+ abort (); \
+ \
+ if (isnan (zero)) \
+ abort (); \
+ \
+ \
+ if (isinf (nan)) \
+ abort (); \
+ \
+ if (!isinf (inf)) \
+ abort (); \
+ \
+ if (!isinf (huge)) \
+ abort (); \
+ \
+ if (isnan (norm)) \
+ abort (); \
+ \
+ if (isinf (zero)) \
+ abort (); \
+ \
+ \
+ if (isfinite (nan)) \
+ abort (); \
+ \
+ if (isfinite (inf)) \
+ abort (); \
+ \
+ if (isfinite (huge)) \
+ abort (); \
+ \
+ if (!isfinite (norm)) \
+ abort (); \
+ \
+ if (!isfinite (zero)) \
+ abort (); \
+ \
+ \
+ if (isnormal (nan)) \
+ abort (); \
+ \
+ if (isnormal (inf)) \
+ abort (); \
+ \
+ if (isnormal (huge)) \
+ abort (); \
+ \
+ if (!isnormal (norm)) \
+ abort (); \
+ \
+ if (isnormal (zero)) \
+ abort (); \
+ \
+ \
+ if (signbit (norm)) \
+ abort (); \
+ \
+ if (!signbit (-(norm))) \
+ abort (); \
+ \
+ \
+ if (!isgreater ((inf), (norm))) \
+ abort (); \
+ \
+ if (!isgreaterequal ((inf), (huge))) \
+ abort (); \
+ \
+ if (!isless ((norm), (inf))) \
+ abort (); \
+ \
+ if (!islessequal ((huge), (inf))) \
+ abort (); \
+ \
+ if (!islessgreater ((inf), (norm))) \
+ abort (); \
+ \
+ if (!isunordered ((nan), (norm))) \
+ abort (); \
+}
diff --git a/gcc/testsuite/gcc.dg/charset/asm3.c b/gcc/testsuite/gcc.dg/charset/asm3.c
index 8ae2212fd26..842bd5cfcfa 100644
--- a/gcc/testsuite/gcc.dg/charset/asm3.c
+++ b/gcc/testsuite/gcc.dg/charset/asm3.c
@@ -1,6 +1,6 @@
/* Test for complex asm statements. Make sure it compiles
then test for some of the asm statements not being translated. */
-/* { dg-do compile { target i?86-*-* } }
+/* { dg-do compile { target { { i?86-*-* x86_64-*-* } && ilp32 } } }
{ dg-require-iconv "IBM1047" }
{ dg-final { scan-assembler "std" } }
{ dg-final { scan-assembler "cld" } }
diff --git a/gcc/testsuite/gcc.dg/clobbers.c b/gcc/testsuite/gcc.dg/clobbers.c
index 474a396a051..44c46b0bf02 100644
--- a/gcc/testsuite/gcc.dg/clobbers.c
+++ b/gcc/testsuite/gcc.dg/clobbers.c
@@ -1,6 +1,6 @@
/* Test asm clobbers on x86. */
-/* { dg-do run { target i?86-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
extern void abort (void);
diff --git a/gcc/testsuite/gcc.dg/cpp/trad/num-sign.c b/gcc/testsuite/gcc.dg/cpp/trad/num-sign.c
index 7522bbf41e2..64f12c07211 100644
--- a/gcc/testsuite/gcc.dg/cpp/trad/num-sign.c
+++ b/gcc/testsuite/gcc.dg/cpp/trad/num-sign.c
@@ -1,6 +1,6 @@
/* Copyright (C) 2001 Free Software Foundation, Inc. */
-/* { dg-do preprocess { target i?86-*-* } } */
+/* { dg-do preprocess { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
/* Tests that traditional numbers are signed, unless otherwise
specified. This test assumes a 32 bit target.
diff --git a/gcc/testsuite/gcc.dg/i386-387-1.c b/gcc/testsuite/gcc.dg/i386-387-1.c
index 7be1ba34aaa..9b31dcaed55 100644
--- a/gcc/testsuite/gcc.dg/i386-387-1.c
+++ b/gcc/testsuite/gcc.dg/i386-387-1.c
@@ -1,6 +1,6 @@
/* Verify that -mno-fancy-math-387 works. */
-/* { dg-do compile { target "i?86-*-*" } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target ilp32 } */
/* { dg-options "-O -ffast-math -mfpmath=387 -mno-fancy-math-387 -march=i386" } */
/* { dg-final { scan-assembler "call\t_?sin" } } */
/* { dg-final { scan-assembler "call\t_?cos" } } */
diff --git a/gcc/testsuite/gcc.dg/i386-387-2.c b/gcc/testsuite/gcc.dg/i386-387-2.c
index ebbe619df36..7358866eceb 100644
--- a/gcc/testsuite/gcc.dg/i386-387-2.c
+++ b/gcc/testsuite/gcc.dg/i386-387-2.c
@@ -1,6 +1,6 @@
/* Verify that -march overrides -mno-fancy-math-387. */
-/* { dg-do compile { target "i?86-*-*" } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target ilp32 } */
/* { dg-options "-O -ffast-math -mfpmath=387 -march=i686 -mno-fancy-math-387" } */
/* { dg-final { scan-assembler "fsin" } } */
/* { dg-final { scan-assembler "fcos" } } */
diff --git a/gcc/testsuite/gcc.dg/i386-387-3.c b/gcc/testsuite/gcc.dg/i386-387-3.c
index b68928a1adf..ed80f78187d 100644
--- a/gcc/testsuite/gcc.dg/i386-387-3.c
+++ b/gcc/testsuite/gcc.dg/i386-387-3.c
@@ -1,6 +1,6 @@
/* Verify that 387 mathematical constants are recognized. */
-/* { dg-do compile { target "i?86-*-*" } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target ilp32 } */
/* { dg-options "-O2 -march=i686" } */
/* { dg-final { scan-assembler "fldpi" } } */
diff --git a/gcc/testsuite/gcc.dg/i386-387-4.c b/gcc/testsuite/gcc.dg/i386-387-4.c
index dbe340ca4b6..55398275570 100644
--- a/gcc/testsuite/gcc.dg/i386-387-4.c
+++ b/gcc/testsuite/gcc.dg/i386-387-4.c
@@ -1,5 +1,5 @@
-/* { dg-do compile { target "i?86-*-*" } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target ilp32 } */
/* { dg-options "-O2 -march=i686" } */
/* { dg-final { scan-assembler "fldpi" } } */
diff --git a/gcc/testsuite/gcc.dg/i386-387-5.c b/gcc/testsuite/gcc.dg/i386-387-5.c
index d438b254db9..fd3106e0270 100644
--- a/gcc/testsuite/gcc.dg/i386-387-5.c
+++ b/gcc/testsuite/gcc.dg/i386-387-5.c
@@ -1,6 +1,6 @@
/* Verify that -mno-fancy-math-387 works. */
-/* { dg-do compile { target "i?86-*-*" } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target ilp32 } */
/* { dg-options "-O -ffast-math -mfpmath=387 -mno-fancy-math-387 -march=i386" } */
/* { dg-final { scan-assembler "call\t_?atan" } } */
/* { dg-final { scan-assembler "call\t_?log1p" } } */
diff --git a/gcc/testsuite/gcc.dg/i386-387-6.c b/gcc/testsuite/gcc.dg/i386-387-6.c
index ab6412b7aff..b3ad64dac48 100644
--- a/gcc/testsuite/gcc.dg/i386-387-6.c
+++ b/gcc/testsuite/gcc.dg/i386-387-6.c
@@ -1,6 +1,6 @@
/* Verify that -march overrides -mno-fancy-math-387. */
-/* { dg-do compile { target "i?86-*-*" } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target ilp32 } */
/* { dg-options "-O -ffast-math -mfpmath=387 -march=i686 -mno-fancy-math-387" } */
/* { dg-final { scan-assembler "fpatan" } } */
/* { dg-final { scan-assembler "fyl2xp1" } } */
diff --git a/gcc/testsuite/gcc.dg/i386-387-7.c b/gcc/testsuite/gcc.dg/i386-387-7.c
index 1a40cd719d8..edcdac1ae3f 100644
--- a/gcc/testsuite/gcc.dg/i386-387-7.c
+++ b/gcc/testsuite/gcc.dg/i386-387-7.c
@@ -1,5 +1,5 @@
/* Verify that 387 fsincos instruction is generated. */
-/* { dg-do compile { target "i?86-*-*" } } */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
/* { dg-require-effective-target ilp32 } */
/* { dg-options "-O -ffast-math -march=i686" } */
/* { dg-final { scan-assembler "fsincos" } } */
diff --git a/gcc/testsuite/gcc.dg/i386-387-8.c b/gcc/testsuite/gcc.dg/i386-387-8.c
index 67c16d92c18..6af895998d0 100644
--- a/gcc/testsuite/gcc.dg/i386-387-8.c
+++ b/gcc/testsuite/gcc.dg/i386-387-8.c
@@ -1,6 +1,7 @@
/* Verify that 387 fptan instruction is generated. Also check fptan
peephole2 optimizer. */
-/* { dg-do compile { target "i?86-*-*" } } */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target ilp32 } */
/* { dg-options "-O2 -ffast-math -march=i686" } */
/* { dg-final { scan-assembler "fptan" } } */
/* { dg-final { scan-assembler-not "fld1" } } */
diff --git a/gcc/testsuite/gcc.dg/i386-3dnowA-1.c b/gcc/testsuite/gcc.dg/i386-3dnowA-1.c
index b5327b3d9ec..80209b00c29 100644
--- a/gcc/testsuite/gcc.dg/i386-3dnowA-1.c
+++ b/gcc/testsuite/gcc.dg/i386-3dnowA-1.c
@@ -1,4 +1,4 @@
-/* { dg-do assemble { target i?86-*-* } } */
+/* { dg-do assemble { target i?86-*-* x86_64-*-* } } */
/* { dg-require-effective-target ilp32 } */
/* { dg-options "-O2 -Werror-implicit-function-declaration -m3dnow -march=athlon" } */
diff --git a/gcc/testsuite/gcc.dg/i386-3dnowA-2.c b/gcc/testsuite/gcc.dg/i386-3dnowA-2.c
index ea336af4147..0cce3b1318c 100644
--- a/gcc/testsuite/gcc.dg/i386-3dnowA-2.c
+++ b/gcc/testsuite/gcc.dg/i386-3dnowA-2.c
@@ -1,4 +1,4 @@
-/* { dg-do assemble { target i?86-*-* } } */
+/* { dg-do assemble { target i?86-*-* x86_64-*-* } } */
/* { dg-require-effective-target ilp32 } */
/* { dg-options "-O0 -Werror-implicit-function-declaration -m3dnow -march=athlon" } */
diff --git a/gcc/testsuite/gcc.dg/i386-asm-1.c b/gcc/testsuite/gcc.dg/i386-asm-1.c
index a23e0a09298..e871dd9343f 100644
--- a/gcc/testsuite/gcc.dg/i386-asm-1.c
+++ b/gcc/testsuite/gcc.dg/i386-asm-1.c
@@ -1,6 +1,6 @@
/* PR inline-asm/11676 */
-/* { dg-do run { target i?86-*-* } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target ilp32 } */
/* { dg-options "-O2" } */
extern void abort (void);
diff --git a/gcc/testsuite/gcc.dg/i386-asm-2.c b/gcc/testsuite/gcc.dg/i386-asm-2.c
index e143ea36978..7e9ecb7797d 100644
--- a/gcc/testsuite/gcc.dg/i386-asm-2.c
+++ b/gcc/testsuite/gcc.dg/i386-asm-2.c
@@ -1,5 +1,6 @@
/* PR opt/13862 */
-/* { dg-do compile { target i?86-*-* } } */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target ilp32 } */
/* { dg-options "-O" } */
typedef struct _fame_syntax_t_ {
diff --git a/gcc/testsuite/gcc.dg/i386-asm-3.c b/gcc/testsuite/gcc.dg/i386-asm-3.c
index f60f7d6378a..19bf1534521 100644
--- a/gcc/testsuite/gcc.dg/i386-asm-3.c
+++ b/gcc/testsuite/gcc.dg/i386-asm-3.c
@@ -1,5 +1,5 @@
/* PR inline-asm/6806 */
-/* { dg-do run { target i?86-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
/* { dg-options "-O2" } */
extern void abort (void);
diff --git a/gcc/testsuite/gcc.dg/i386-bitfield1.c b/gcc/testsuite/gcc.dg/i386-bitfield1.c
index 5b53acf8dfd..e285ba0526a 100644
--- a/gcc/testsuite/gcc.dg/i386-bitfield1.c
+++ b/gcc/testsuite/gcc.dg/i386-bitfield1.c
@@ -1,6 +1,6 @@
// Test for bitfield alignment in structs on IA-32
-// { dg-do run { target i?86-*-* } }
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+// { dg-do run { target i?86-*-* x86_64-*-* } }
+// { dg-require-effective-target ilp32 }
// { dg-options "-O2" }
// { dg-options "-mno-align-double -mno-ms-bitfields" { target i?86-*-interix* i?86-*-cygwin* i?86-*-mingw*} }
diff --git a/gcc/testsuite/gcc.dg/i386-bitfield2.c b/gcc/testsuite/gcc.dg/i386-bitfield2.c
index f77a4ab4097..54f5c8dbfd3 100644
--- a/gcc/testsuite/gcc.dg/i386-bitfield2.c
+++ b/gcc/testsuite/gcc.dg/i386-bitfield2.c
@@ -1,6 +1,6 @@
// Test for bitfield alignment in structs on IA-32
-// { dg-do run { target i?86-*-* } }
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+// { dg-do run { target i?86-*-* x86_64-*-* } }
+// { dg-require-effective-target ilp32 }
// { dg-options "-O2" }
// { dg-options "-mno-align-double -mno-ms-bitfields" { target i?86-*-interix* i?86-*-cygwin* i?86-*-mingw* } }
diff --git a/gcc/testsuite/gcc.dg/i386-bitfield3.c b/gcc/testsuite/gcc.dg/i386-bitfield3.c
index 781c2f7ba4e..111f5f28c42 100644
--- a/gcc/testsuite/gcc.dg/i386-bitfield3.c
+++ b/gcc/testsuite/gcc.dg/i386-bitfield3.c
@@ -1,5 +1,5 @@
// Test for bitfield alignment in structs on IA-32
-// { dg-do run { target i?86-*-* } }
+// { dg-do run { target i?86-*-* x86_64-*-* } }
// { dg-options "-O2" }
// { dg-options "-mno-align-double -mno-ms-bitfields" { target *-*-interix* } }
diff --git a/gcc/testsuite/gcc.dg/i386-call-1.c b/gcc/testsuite/gcc.dg/i386-call-1.c
index 9cd49da3b2f..3c3d642babd 100644
--- a/gcc/testsuite/gcc.dg/i386-call-1.c
+++ b/gcc/testsuite/gcc.dg/i386-call-1.c
@@ -1,6 +1,6 @@
/* PR optimization/11304 */
/* Originator: <manuel.serrano@sophia.inria.fr> */
-/* { dg-do run { target i?86-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
/* { dg-options "-O -fomit-frame-pointer" } */
/* Verify that %eax is always restored after a call. */
diff --git a/gcc/testsuite/gcc.dg/i386-loop-1.c b/gcc/testsuite/gcc.dg/i386-loop-1.c
index 9aa23ef900f..479c80a2d7a 100644
--- a/gcc/testsuite/gcc.dg/i386-loop-1.c
+++ b/gcc/testsuite/gcc.dg/i386-loop-1.c
@@ -1,6 +1,6 @@
/* PR optimization/9888 */
-/* { dg-do run { target i?86-*-* } } */
-/* { dg-xfail-if "" { *-*-* } { "-m64" } { "" } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target ilp32 } */
/* { dg-options "-mtune=k6 -O3" } */
/* Verify that GCC doesn't emit out of range 'loop' instructions. */
diff --git a/gcc/testsuite/gcc.dg/i386-loop-2.c b/gcc/testsuite/gcc.dg/i386-loop-2.c
index 548819a336c..8994eada46e 100644
--- a/gcc/testsuite/gcc.dg/i386-loop-2.c
+++ b/gcc/testsuite/gcc.dg/i386-loop-2.c
@@ -1,7 +1,7 @@
/* PR optimization/9888 */
/* Originator: Jim Bray <jb@as220.org> */
-/* { dg-do run { target i?86-*-* } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target ilp32 } */
/* { dg-options "-mtune=k6 -Os" } */
enum reload_type
diff --git a/gcc/testsuite/gcc.dg/i386-loop-3.c b/gcc/testsuite/gcc.dg/i386-loop-3.c
index 394b4e99246..4e046b28acb 100644
--- a/gcc/testsuite/gcc.dg/i386-loop-3.c
+++ b/gcc/testsuite/gcc.dg/i386-loop-3.c
@@ -1,8 +1,8 @@
/* PR target/11044 */
/* Originator: Tim McGrath <misty-@charter.net> */
/* Testcase contributed by Eric Botcazou <ebotcazou@libertysurf.fr> */
-/* { dg-do run { target i?86-*-* } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target ilp32 } */
/* { dg-options "-mtune=k6 -O3 -ffast-math -funroll-loops" } */
extern void *memset (void *, int, __SIZE_TYPE__);
diff --git a/gcc/testsuite/gcc.dg/i386-memset-1.c b/gcc/testsuite/gcc.dg/i386-memset-1.c
index b87a05b8df7..4da21b97ee0 100644
--- a/gcc/testsuite/gcc.dg/i386-memset-1.c
+++ b/gcc/testsuite/gcc.dg/i386-memset-1.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 Free Software Foundation.
+/* Copyright (C) 2002, 2005 Free Software Foundation.
Test -minline-all-stringops memset with various combinations of pointer
alignments and lengths to make sure builtin optimizations are correct.
@@ -7,7 +7,7 @@
Written by Michael Meissner, March 9, 2002.
Target by Roger Sayle, April 25, 2002. */
-/* { dg-do run { target "i?86-*-*" } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
/* { dg-options "-O2 -minline-all-stringops" } */
extern void *memset (void *, int, __SIZE_TYPE__);
diff --git a/gcc/testsuite/gcc.dg/i386-pentium4-not-mull.c b/gcc/testsuite/gcc.dg/i386-pentium4-not-mull.c
index 2df07822ded..2ae7512cb48 100644
--- a/gcc/testsuite/gcc.dg/i386-pentium4-not-mull.c
+++ b/gcc/testsuite/gcc.dg/i386-pentium4-not-mull.c
@@ -1,7 +1,6 @@
/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
-/* { dg-options "-O2 -march=pentium4" { target i?86-*-* } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
-/* { dg-options "-O2 -march=pentium4 -m32" { target x86_64-*-* } } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-options "-O2 -march=pentium4" } */
/* { dg-final { scan-assembler-not "imull" } } */
/* Should be done not using imull. */
diff --git a/gcc/testsuite/gcc.dg/i386-pic-1.c b/gcc/testsuite/gcc.dg/i386-pic-1.c
index 8fa2caf67f7..7762230c2f6 100644
--- a/gcc/testsuite/gcc.dg/i386-pic-1.c
+++ b/gcc/testsuite/gcc.dg/i386-pic-1.c
@@ -1,6 +1,6 @@
/* PR target/8340 */
-/* { dg-do compile { target i?86-*-* } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target ilp32 } */
/* { dg-options "-fPIC" } */
int foo ()
diff --git a/gcc/testsuite/gcc.dg/i386-regparm.c b/gcc/testsuite/gcc.dg/i386-regparm.c
index 601688f6489..e3cd8b090ff 100644
--- a/gcc/testsuite/gcc.dg/i386-regparm.c
+++ b/gcc/testsuite/gcc.dg/i386-regparm.c
@@ -1,5 +1,5 @@
-/* { dg-do compile { target i?86-*-* } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target ilp32 } */
/* { dg-options "-W -Wall" } */
/* Verify that GCC correctly detects non-matching regparm attributes. */
diff --git a/gcc/testsuite/gcc.dg/i386-signbit-1.c b/gcc/testsuite/gcc.dg/i386-signbit-1.c
index 57c1f5f2cb3..adb351a2772 100644
--- a/gcc/testsuite/gcc.dg/i386-signbit-1.c
+++ b/gcc/testsuite/gcc.dg/i386-signbit-1.c
@@ -1,6 +1,6 @@
/* PR optimization/8746 */
-/* { dg-do run { target i?86-*-* } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target ilp32 } */
/* { dg-options "-O1 -mtune=i586" } */
extern void abort (void);
diff --git a/gcc/testsuite/gcc.dg/i386-signbit-2.c b/gcc/testsuite/gcc.dg/i386-signbit-2.c
index 3e35249dadd..8ca63965062 100644
--- a/gcc/testsuite/gcc.dg/i386-signbit-2.c
+++ b/gcc/testsuite/gcc.dg/i386-signbit-2.c
@@ -1,6 +1,6 @@
/* PR optimization/8746 */
-/* { dg-do run { target i?86-*-* } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target ilp32 } */
/* { dg-options "-O1 -mtune=i586" } */
extern void abort (void);
diff --git a/gcc/testsuite/gcc.dg/i386-signbit-3.c b/gcc/testsuite/gcc.dg/i386-signbit-3.c
index 882e6421415..a08ca498142 100644
--- a/gcc/testsuite/gcc.dg/i386-signbit-3.c
+++ b/gcc/testsuite/gcc.dg/i386-signbit-3.c
@@ -1,6 +1,6 @@
/* PR optimization/8746 */
-/* { dg-do run { target i?86-*-* } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target ilp32 } */
/* { dg-options "-O1 -mtune=i586" } */
extern void abort (void);
diff --git a/gcc/testsuite/gcc.dg/i386-sse-5.c b/gcc/testsuite/gcc.dg/i386-sse-5.c
index a35e5d60cb6..ced075ae97d 100644
--- a/gcc/testsuite/gcc.dg/i386-sse-5.c
+++ b/gcc/testsuite/gcc.dg/i386-sse-5.c
@@ -1,6 +1,7 @@
-/* { dg-do compile { target i?86-*-* } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target ilp32 } */
/* { dg-options "-Winline -O2 -march=i386" } */
+
typedef double v2df __attribute__ ((vector_size (16)));
v2df p;
q(v2df t)
diff --git a/gcc/testsuite/gcc.dg/i386-sse-8.c b/gcc/testsuite/gcc.dg/i386-sse-8.c
index 7ae52fdca7c..ec3acc16906 100644
--- a/gcc/testsuite/gcc.dg/i386-sse-8.c
+++ b/gcc/testsuite/gcc.dg/i386-sse-8.c
@@ -1,11 +1,10 @@
-/* PR target/14313 */
+/* PR target/14343 */
/* Origin: <Pawe Sikora <pluto@ds14.agh.edu.pl> */
/* The xstormy16 doesn't support V2DI. */
/* { dg-do compile { xfail xstormy16-*-* } } */
/* { dg-options "" } */
-/* { dg-options "-march=pentium3" { target i?86-*-* } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-options "-march=pentium3" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
int main()
{
diff --git a/gcc/testsuite/gcc.dg/i386-ssefn-1.c b/gcc/testsuite/gcc.dg/i386-ssefn-1.c
index a8b0b14e73c..548c580571f 100644
--- a/gcc/testsuite/gcc.dg/i386-ssefn-1.c
+++ b/gcc/testsuite/gcc.dg/i386-ssefn-1.c
@@ -1,7 +1,8 @@
/* Test argument passing with SSE and local functions
Written by Paolo Bonzini, 25 January 2005 */
-/* { dg-do compile { target i?86-*-* } } */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target ilp32 } */
/* { dg-final { scan-assembler "movss" } } */
/* { dg-final { scan-assembler "mulss" } } */
/* { dg-final { scan-assembler-not "movsd" } } */
diff --git a/gcc/testsuite/gcc.dg/i386-ssefn-2.c b/gcc/testsuite/gcc.dg/i386-ssefn-2.c
index 0e1970032e9..ded8b724f94 100644
--- a/gcc/testsuite/gcc.dg/i386-ssefn-2.c
+++ b/gcc/testsuite/gcc.dg/i386-ssefn-2.c
@@ -1,7 +1,8 @@
/* Test argument passing with SSE2 and local functions
Written by Paolo Bonzini, 25 January 2005 */
-/* { dg-do compile { target i?86-*-* } } */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target ilp32 } */
/* { dg-final { scan-assembler "movss" } } */
/* { dg-final { scan-assembler "mulss" } } */
/* { dg-final { scan-assembler "movsd" } } */
diff --git a/gcc/testsuite/gcc.dg/i386-ssefn-3.c b/gcc/testsuite/gcc.dg/i386-ssefn-3.c
index 2816919f7c2..c1b61301f34 100644
--- a/gcc/testsuite/gcc.dg/i386-ssefn-3.c
+++ b/gcc/testsuite/gcc.dg/i386-ssefn-3.c
@@ -1,7 +1,7 @@
/* Execution test for argument passing with SSE and local functions
Written by Paolo Bonzini, 25 January 2005 */
-/* { dg-do run { target i?86-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
/* { dg-options "-O2 -msse -mfpmath=sse" } */
#include <assert.h>
#include "i386-cpuid.h"
diff --git a/gcc/testsuite/gcc.dg/i386-ssefn-4.c b/gcc/testsuite/gcc.dg/i386-ssefn-4.c
index 353afcec0a1..a28382e2826 100644
--- a/gcc/testsuite/gcc.dg/i386-ssefn-4.c
+++ b/gcc/testsuite/gcc.dg/i386-ssefn-4.c
@@ -1,7 +1,7 @@
/* Execution test for argument passing with SSE2 and local functions
Written by Paolo Bonzini, 25 January 2005 */
-/* { dg-do run { target i?86-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
/* { dg-options "-O2 -msse2 -mfpmath=sse" } */
#include <assert.h>
#include "i386-cpuid.h"
diff --git a/gcc/testsuite/gcc.dg/i386-unroll-1.c b/gcc/testsuite/gcc.dg/i386-unroll-1.c
index 8ffd2ebe110..e681474725a 100644
--- a/gcc/testsuite/gcc.dg/i386-unroll-1.c
+++ b/gcc/testsuite/gcc.dg/i386-unroll-1.c
@@ -1,6 +1,6 @@
/* PR optimization/8599 */
-/* { dg-do run { target i?86-*-* } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target ilp32 } */
/* { dg-options "-mtune=k6 -O2 -funroll-loops" } */
extern void exit (int);
diff --git a/gcc/testsuite/gcc.dg/i386-volatile-1.c b/gcc/testsuite/gcc.dg/i386-volatile-1.c
index 633ea5022ec..8a37df48b20 100644
--- a/gcc/testsuite/gcc.dg/i386-volatile-1.c
+++ b/gcc/testsuite/gcc.dg/i386-volatile-1.c
@@ -1,6 +1,6 @@
/* PR optimization/11381 */
/* Originator: <tobias@ringstrom.mine.nu> */
-/* { dg-do compile { target i?86-*-* } } */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
/* { dg-options "-O" } */
/* Verify that the comparison is not optimized away. */
diff --git a/gcc/testsuite/gcc.dg/i386-xorps.c b/gcc/testsuite/gcc.dg/i386-xorps.c
index 86daa794ab4..0cf7532a1b9 100644
--- a/gcc/testsuite/gcc.dg/i386-xorps.c
+++ b/gcc/testsuite/gcc.dg/i386-xorps.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target i?86-*-* } } */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
/* { dg-options "-Os -msse2" } */
typedef float __m128 __attribute__ ((vector_size (16)));
diff --git a/gcc/testsuite/gcc.dg/ppc-vector-memcpy.c b/gcc/testsuite/gcc.dg/ppc-vector-memcpy.c
index 630ff2e88b1..99ca85e972c 100644
--- a/gcc/testsuite/gcc.dg/ppc-vector-memcpy.c
+++ b/gcc/testsuite/gcc.dg/ppc-vector-memcpy.c
@@ -5,6 +5,6 @@
void foo(void)
{
- int x[8] __attribute__((aligned(128))) = { 1 };
+ int x[8] __attribute__((aligned(128))) = { 1, 1, 1, 1, 1, 1, 1, 1 };
bar (x);
}
diff --git a/gcc/testsuite/gcc.dg/pr12092-1.c b/gcc/testsuite/gcc.dg/pr12092-1.c
index 1b29452881f..80c7546d9fb 100644
--- a/gcc/testsuite/gcc.dg/pr12092-1.c
+++ b/gcc/testsuite/gcc.dg/pr12092-1.c
@@ -1,6 +1,6 @@
/* PR rtl-optimization/12092 */
/* Test case reduced by Andrew Pinski <pinskia@physics.uc.edu> */
-/* { dg-do compile { target i?86-*-* } } */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
/* { dg-require-effective-target ilp32 } */
/* { dg-options "-O2 -mtune=i486 -march=pentium4 -fprefetch-loop-arrays" } */
diff --git a/gcc/testsuite/gcc.dg/pr14289-1.c b/gcc/testsuite/gcc.dg/pr14289-1.c
index 652916325c2..71317d542c7 100644
--- a/gcc/testsuite/gcc.dg/pr14289-1.c
+++ b/gcc/testsuite/gcc.dg/pr14289-1.c
@@ -1,5 +1,5 @@
/* PR middle-end/14289 */
-/* { dg-do compile { target i?86-*-* } } */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
/* { dg-options "-O0" } */
register int a[2] asm("ebx");
diff --git a/gcc/testsuite/gcc.dg/pr19236-1.c b/gcc/testsuite/gcc.dg/pr19236-1.c
index 77365aa4074..73b75384384 100644
--- a/gcc/testsuite/gcc.dg/pr19236-1.c
+++ b/gcc/testsuite/gcc.dg/pr19236-1.c
@@ -1,5 +1,5 @@
/* PR target/19236 */
-/* { dg-do compile { target i?86-*-* } } */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
/* { dg-options "-ffast-math" } */
extern float log1pf (float);
diff --git a/gcc/testsuite/gcc.dg/pr20204.c b/gcc/testsuite/gcc.dg/pr20204.c
index ad85af5baa3..7f24abc5529 100644
--- a/gcc/testsuite/gcc.dg/pr20204.c
+++ b/gcc/testsuite/gcc.dg/pr20204.c
@@ -1,4 +1,4 @@
-/* { dg-do run { target i?86-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
/* { dg-options "-O2" } */
void *x (void *pdst, const void *psrc, unsigned int pn)
diff --git a/gcc/testsuite/gcc.dg/pr9771-1.c b/gcc/testsuite/gcc.dg/pr9771-1.c
index 1e3bc036aee..30e42de60b1 100644
--- a/gcc/testsuite/gcc.dg/pr9771-1.c
+++ b/gcc/testsuite/gcc.dg/pr9771-1.c
@@ -1,5 +1,6 @@
/* PR rtl-optimization/9771 */
-/* { dg-do run { target i?86-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target ilp32 } */
/* { dg-options "-O2 -fomit-frame-pointer -ffixed-ebp" } */
extern void abort(void);
diff --git a/gcc/testsuite/gcc.dg/register-var-1.c b/gcc/testsuite/gcc.dg/register-var-1.c
index 6869b034dcf..a27d56c4b66 100644
--- a/gcc/testsuite/gcc.dg/register-var-1.c
+++ b/gcc/testsuite/gcc.dg/register-var-1.c
@@ -1,6 +1,6 @@
/* PR/18160 */
-/* { dg-do compile { target i?86-*-* } } */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
/* This should yield an error even without -pedantic. */
/* { dg-options "-ansi" } */
diff --git a/gcc/testsuite/gcc.dg/setjmp-2.c b/gcc/testsuite/gcc.dg/setjmp-2.c
index 6c89f8e9697..b44ac666145 100644
--- a/gcc/testsuite/gcc.dg/setjmp-2.c
+++ b/gcc/testsuite/gcc.dg/setjmp-2.c
@@ -1,8 +1,9 @@
/* PR middle-end/17813 */
/* Origin: Tom Hughes <tom@compton.nu> */
/* { dg-do run { target i?86-*-linux* x86_64-*-linux* } } */
-/* { dg-options "-O -fomit-frame-pointer -march=i386" { target i?86-*-linux* } } */
-/* { dg-options "-O -fomit-frame-pointer -m32 -march=i386" { target x86_64-*-linux* } } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-options "-O -fomit-frame-pointer -march=i386" { target { i?86-*-linux* && ilp32 } } } */
+/* { dg-options "-O -fomit-frame-pointer -march=i386" { target { x86_64-*-linux* && ilp32 } } } */
#include <setjmp.h>
#include <signal.h>
diff --git a/gcc/testsuite/gcc.dg/short-compare-1.c b/gcc/testsuite/gcc.dg/short-compare-1.c
index 7ecca243a7c..8c02a893347 100644
--- a/gcc/testsuite/gcc.dg/short-compare-1.c
+++ b/gcc/testsuite/gcc.dg/short-compare-1.c
@@ -4,7 +4,7 @@
/* { dg-do run } */
/* { dg-options "-O" } */
/* { dg-options "-O -mtune=i686" { target { i?86-*-* && ilp32 } } } */
-/* { dg-options "-O -m32 -mtune=i686" { target x86_64-*-* } } */
+/* { dg-options "-O -mtune=i686" { target { x86_64-*-* && ilp32 } } } */
extern void abort(void);
diff --git a/gcc/testsuite/gcc.dg/short-compare-2.c b/gcc/testsuite/gcc.dg/short-compare-2.c
index 736e1510e8d..1c2192e821a 100644
--- a/gcc/testsuite/gcc.dg/short-compare-2.c
+++ b/gcc/testsuite/gcc.dg/short-compare-2.c
@@ -5,7 +5,7 @@
/* { dg-do run } */
/* { dg-options "-O" } */
/* { dg-options "-O -mtune=i686" { target { i?86-*-* && ilp32 } } } */
-/* { dg-options "-O -m32 -mtune=i686" { target x86_64-*-* } } */
+/* { dg-options "-O -mtune=i686" { target { x86_64-*-* && ilp32 } } } */
extern void abort();
diff --git a/gcc/testsuite/gcc.dg/sibcall-5.c b/gcc/testsuite/gcc.dg/sibcall-5.c
index da95f13e25c..d94750099fe 100644
--- a/gcc/testsuite/gcc.dg/sibcall-5.c
+++ b/gcc/testsuite/gcc.dg/sibcall-5.c
@@ -1,5 +1,6 @@
/* Check that indirect sibcalls understand regparm. */
-/* { dg-do run { target i?86-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target ilp32 } */
/* { dg-options "-O2" } */
extern void abort (void);
diff --git a/gcc/testsuite/gcc.dg/tls/opt-1.c b/gcc/testsuite/gcc.dg/tls/opt-1.c
index f817c04e151..f7dcceee7c8 100644
--- a/gcc/testsuite/gcc.dg/tls/opt-1.c
+++ b/gcc/testsuite/gcc.dg/tls/opt-1.c
@@ -1,7 +1,7 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fPIC" } */
-/* { dg-options "-O2 -fPIC -mtune=i686" { target i?86-*-* } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-options "-O2 -fPIC -mtune=i686" { target { i?86-*-* && ilp32 } } } */
+/* { dg-options "-O2 -fPIC -mtune=i686" { target { x86_64-*-* && ilp32 } } } */
extern __thread int thr;
diff --git a/gcc/testsuite/gcc.dg/tls/opt-2.c b/gcc/testsuite/gcc.dg/tls/opt-2.c
index 6dc2b0e05aa..dde54f00674 100644
--- a/gcc/testsuite/gcc.dg/tls/opt-2.c
+++ b/gcc/testsuite/gcc.dg/tls/opt-2.c
@@ -4,8 +4,8 @@
on IA-32. */
/* { dg-do link } */
/* { dg-options "-O2 -ftls-model=initial-exec" } */
-/* { dg-options "-O2 -ftls-model=initial-exec -march=i686" { target i?86-*-* } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-options "-O2 -ftls-model=initial-exec -march=i686" { target { i?86-*-* && ilp32 } } } */
+/* { dg-options "-O2 -ftls-model=initial-exec -march=i686" { target { x86_64-*-* && ilp32 } } } */
__thread int thr;
diff --git a/gcc/testsuite/gcc.dg/torture/builtin-attr-1.c b/gcc/testsuite/gcc.dg/torture/builtin-attr-1.c
index 0e521d84e3f..4bf77892bab 100644
--- a/gcc/testsuite/gcc.dg/torture/builtin-attr-1.c
+++ b/gcc/testsuite/gcc.dg/torture/builtin-attr-1.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003 Free Software Foundation.
+/* Copyright (C) 2003, 2005 Free Software Foundation.
Verify that the `const' function attribute is applied to various
builtins and that these functions are optimized away by the
@@ -393,7 +393,7 @@ CPTEST1 (ccos)
CPTEST1 (ccosh)
CPTEST1 (cexp)
CPTEST1R (cimag)
-/*CPTEST1 (clog)*/
+CPTEST1 (clog)
CPTEST1 (conj)
CPTEST2 (cpow)
CPTEST1 (cproj)
diff --git a/gcc/testsuite/gcc.dg/tree-prof/tree-prof.exp b/gcc/testsuite/gcc.dg/tree-prof/tree-prof.exp
index 307cc2c52ae..9559a80e187 100644
--- a/gcc/testsuite/gcc.dg/tree-prof/tree-prof.exp
+++ b/gcc/testsuite/gcc.dg/tree-prof/tree-prof.exp
@@ -15,7 +15,7 @@
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# Test the functionality of programs compiled with profile-directed block
-# ordering using -fprofile-generate followed by -fprofile-use
+# ordering using -fprofile-generate followed by -fbranch-use.
load_lib target-supports.exp
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11.c b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11.c
index bc6c2869d75..faba5451436 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11.c
@@ -1,4 +1,4 @@
-/* { dg-do run } */
+/* { dg-do run { target vect_cmdline_needed } } */
/* { dg-options "-O2 -ftree-vectorize -ftree-vectorizer-verbose=3 -fdump-tree-vect-stats" } */
#include <stdlib.h>
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11a.c b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11a.c
index 75ec7ce8863..7fbbc0cf37e 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11a.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11a.c
@@ -1,4 +1,4 @@
-/* { dg-do run } */
+/* { dg-do run { target vect_cmdline_needed } } */
/* { dg-options "-O2 -ftree-vectorize -ftree-vectorizer-verbose=3 -fdump-tree-vect-stats" } */
#include <stdlib.h>
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11b.c b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11b.c
index 20833533468..c1c33c3ce1d 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11b.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11b.c
@@ -1,4 +1,4 @@
-/* { dg-do run } */
+/* { dg-do run { target vect_cmdline_needed } } */
/* { dg-options "-O2 -ftree-vectorize -ftree-vectorizer-verbose=3 -fdump-tree-vect-stats" } */
#include <stdlib.h>
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11c.c b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11c.c
index 8632ae42b3a..e57554b8d4e 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11c.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11c.c
@@ -1,4 +1,4 @@
-/* { dg-do run } */
+/* { dg-do run { target vect_cmdline_needed } } */
/* { dg-options "-O2 -ftree-vectorize -ftree-vectorizer-verbose=3 -fdump-tree-vect-stats" } */
#include <stdlib.h>
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-2.c b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-2.c
index be89c268258..8bee1522dc9 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-2.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-2.c
@@ -1,4 +1,4 @@
-/* { dg-do run } */
+/* { dg-do run { target vect_cmdline_needed } } */
/* { dg-options "-O2 -ftree-vectorize -ftree-vectorizer-verbose=3 -fdump-tree-vect-stats" } */
#include <stdlib.h>
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-25.c b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-25.c
index 5cfec85144a..e6127d8b8e6 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-25.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-25.c
@@ -1,4 +1,4 @@
-/* { dg-do run } */
+/* { dg-do run { target vect_cmdline_needed } } */
/* { dg-options "-O2 -ftree-vectorize -ftree-vectorizer-verbose=3 -fdump-tree-vect-stats" } */
#include <stdlib.h>
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-26.c b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-26.c
index b90413aa4bf..bd6a51390e1 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-26.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-26.c
@@ -1,4 +1,4 @@
-/* { dg-do run } */
+/* { dg-do run { target vect_cmdline_needed } } */
/* { dg-options "-O2 -ftree-vectorize -ftree-vectorizer-verbose=3 -fdump-tree-vect-stats" } */
#include <stdlib.h>
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-28.c b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-28.c
index 0d017529357..4f3bcf84375 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-28.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-28.c
@@ -1,4 +1,4 @@
-/* { dg-do run } */
+/* { dg-do run { target vect_cmdline_needed } } */
/* { dg-options "-O2 -ftree-vectorize -ftree-vectorizer-verbose=3 -fdump-tree-vect-stats" } */
#include <stdlib.h>
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-32.c b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-32.c
index 681c7071685..1a46a309daf 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-32.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-32.c
@@ -1,4 +1,4 @@
-/* { dg-do run } */
+/* { dg-do run { target vect_cmdline_needed } } */
/* { dg-options "-O2 -ftree-vectorize -ftree-vectorizer-verbose=3 -fdump-tree-vect-stats" } */
#include <stdlib.h>
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr14841.c b/gcc/testsuite/gcc.dg/tree-ssa/pr14841.c
index 4acc6ce3fc8..4f9c759da90 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr14841.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr14841.c
@@ -25,5 +25,5 @@ foo (void)
link_error ();
}
-/* { dg-final { scan-tree-dump-times "with if \\(0\\)" 1 "store_ccp"} } */
+/* { dg-final { scan-tree-dump-times "Folded statement: if " 1 "store_ccp"} } */
/* { dg-final { cleanup-tree-dump "store_ccp" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-14.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-14.c
index 9ead438cc26..2371cfa1a58 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-14.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-14.c
@@ -1,12 +1,12 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-optimized" } */
-extern unsigned int strlen (const char *) __attribute__ ((__pure__));
+extern __SIZE_TYPE__ strlen (const char *) __attribute__ ((__pure__));
void
foo (const char *str)
{
- unsigned int a = strlen (str);
- unsigned int b = strlen (str);
+ __SIZE_TYPE__ a = strlen (str);
+ __SIZE_TYPE__ b = strlen (str);
if (a != b)
link_error ();
}
diff --git a/gcc/testsuite/gcc.dg/unroll-1.c b/gcc/testsuite/gcc.dg/unroll-1.c
index 2ea694f3521..7b09cd1d209 100644
--- a/gcc/testsuite/gcc.dg/unroll-1.c
+++ b/gcc/testsuite/gcc.dg/unroll-1.c
@@ -1,8 +1,9 @@
/* PR optimization/8599 */
/* { dg-do run } */
/* { dg-options "-O2 -funroll-loops" } */
-/* { dg-options "-mtune=k6 -O2 -funroll-loops" { target i?86-*-* } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-options "-mtune=k6 -O2 -funroll-loops" { target { i?86-*-* && ilp32 } } } */
+/* { dg-options "-mtune=k6 -O2 -funroll-loops" { target { x86_64-*-* && ilp32 } } } */
+
extern void abort (void);
diff --git a/gcc/testsuite/gcc.dg/vect/vect-7.c b/gcc/testsuite/gcc.dg/vect/vect-7.c
index c753de8cd81..e359bbe2c56 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-7.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-7.c
@@ -45,7 +45,7 @@ int main (void)
return main1 ();
}
-/* Fails for targets that don't vectorize PLUS. */
-/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" { xfail alpha*-*-* } } } */
+/* Fails for 32-bit targets that don't vectorize PLUS. */
+/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" } } */
/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.misc-tests/i386-pf-3dnow-1.c b/gcc/testsuite/gcc.misc-tests/i386-pf-3dnow-1.c
index e4961cf6c51..ffb2e79530b 100644
--- a/gcc/testsuite/gcc.misc-tests/i386-pf-3dnow-1.c
+++ b/gcc/testsuite/gcc.misc-tests/i386-pf-3dnow-1.c
@@ -1,8 +1,8 @@
/* Test that the correct data prefetch instructions are generated for i386
variants that use 3DNow! prefetch instructions. */
-/* { dg-do compile { target i?86-*-* } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-do compile { target i?86-*-* x86_64-*-*} } */
+/* { dg-require-effective-target ilp32 } */
extern void exit (int);
diff --git a/gcc/testsuite/gcc.misc-tests/i386-pf-athlon-1.c b/gcc/testsuite/gcc.misc-tests/i386-pf-athlon-1.c
index 08d046bf1c8..8d5ad1efe7d 100644
--- a/gcc/testsuite/gcc.misc-tests/i386-pf-athlon-1.c
+++ b/gcc/testsuite/gcc.misc-tests/i386-pf-athlon-1.c
@@ -2,8 +2,8 @@
variants that use 3DNow! prefetchw or SSE prefetch instructions with
locality hints. */
-/* { dg-do compile { target i?86-*-* } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target ilp32 } */
extern void exit (int);
diff --git a/gcc/testsuite/gcc.misc-tests/i386-pf-none-1.c b/gcc/testsuite/gcc.misc-tests/i386-pf-none-1.c
index 155e0f4ac02..d87a2100dda 100644
--- a/gcc/testsuite/gcc.misc-tests/i386-pf-none-1.c
+++ b/gcc/testsuite/gcc.misc-tests/i386-pf-none-1.c
@@ -1,8 +1,8 @@
/* Test that data prefetch instructions are not generated for i386 variants
that do not support those instructions. */
-/* { dg-do compile { target i?86-*-* } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target ilp32 } */
extern void exit (int);
diff --git a/gcc/testsuite/gcc.misc-tests/i386-pf-sse-1.c b/gcc/testsuite/gcc.misc-tests/i386-pf-sse-1.c
index 7d1ed99ecbc..fb47c9dfc53 100644
--- a/gcc/testsuite/gcc.misc-tests/i386-pf-sse-1.c
+++ b/gcc/testsuite/gcc.misc-tests/i386-pf-sse-1.c
@@ -1,8 +1,8 @@
/* Test that the correct data prefetch instructions are generated for i386
variants that use SSE prefetch instructions. */
-/* { dg-do compile { target i?86-*-* } } */
-/* { dg-skip-if "" { i?86-*-* } { "-m64" } { "" } } */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target ilp32 } */
extern void exit (int);
diff --git a/gcc/testsuite/gfortran.dg/assign_2.f90 b/gcc/testsuite/gfortran.dg/assign_2.f90
index 4119cd94f58..6db1f2fe85c 100644
--- a/gcc/testsuite/gfortran.dg/assign_2.f90
+++ b/gcc/testsuite/gfortran.dg/assign_2.f90
@@ -1,4 +1,4 @@
-! { dg-do compile }
+! { dg-do run }
! Option passed to avoid excess errors from obsolete warning
! { dg-options "-w" }
! PR18827
diff --git a/gcc/testsuite/gfortran.dg/promotion.f90 b/gcc/testsuite/gfortran.dg/promotion.f90
index d1b9b686e58..80716093136 100644
--- a/gcc/testsuite/gfortran.dg/promotion.f90
+++ b/gcc/testsuite/gfortran.dg/promotion.f90
@@ -1,4 +1,5 @@
-! { dg-do run { target i?86-*-* } }
+! { dg-do run { target i?86-*-* x86_64-*-* } }
+! { dg-require-effective-target ilp32 }
! { dg-options "-fdefault-integer-8 -fdefault-real-8" }
program a
logical l
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_unpack.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_unpack.f90
index 807aadf136f..88f09c321b4 100644
--- a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_unpack.f90
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_unpack.f90
@@ -2,6 +2,7 @@
program intrinsic_unpack
integer, dimension(3, 3) :: a, b
logical, dimension(3, 3) :: mask;
+ character(len=50) line1, line2
integer i
mask = reshape ((/.false.,.true.,.false.,.true.,.false.,.false.,&
@@ -10,6 +11,9 @@ program intrinsic_unpack
b = unpack ((/2, 3, 4/), mask, a)
if (any (b .ne. reshape ((/1, 2, 0, 3, 1, 0, 0, 0, 4/), (/3, 3/)))) &
call abort
+ write (line1,'(10I4)') b
+ write (line2,'(10I4)') unpack((/2, 3, 4/), mask, a)
+ if (line1 .ne. line2) call abort
b = -1
b = unpack ((/2, 3, 4/), mask, 0)
if (any (b .ne. reshape ((/0, 2, 0, 3, 0, 0, 0, 0, 4/), (/3, 3/)))) &
diff --git a/gcc/testsuite/lib/obj-c++.exp b/gcc/testsuite/lib/obj-c++.exp
index 2b7c944b557..e88e011bb2c 100644
--- a/gcc/testsuite/lib/obj-c++.exp
+++ b/gcc/testsuite/lib/obj-c++.exp
@@ -284,11 +284,12 @@ proc obj-c++_init { args } {
#
proc obj-c++_target_compile { source dest type options } {
- global tmpdir;
+ global tmpdir
+ global srcdir
global gpp_compile_options
global gluefile wrap_flags
- global ALWAYS_OBJCXXFLAGS;
- global OBJCXX_UNDER_TEST;
+ global ALWAYS_OBJCXXFLAGS
+ global OBJCXX_UNDER_TEST
lappend options "libs=-lobjc"
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index ac6dda5fd57..3b98c6b2d0f 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -725,6 +725,28 @@ proc check_effective_target_lp64 { } {
return $et_lp64_saved
}
+# Return 1 if the target needs a command line argument to enable a SIMD
+# instruction set.
+#
+# This won't change for different subtargets so cache the result.
+
+proc check_effective_target_vect_cmdline_needed { } {
+ global et_vect_cmdline_needed_saved
+
+ if [info exists et_vect_cmdline_needed_saved] {
+ verbose "check_effective_target_vect_cmdline_needed: using cached result" 2
+ } else {
+ set et_vect_cmdline_needed_saved 1
+ if { [istarget ia64-*-*]
+ || [istarget x86_64-*-*] } {
+ set et_vect_cmdline_needed_saved 0
+ }
+ }
+
+ verbose "check_effective_target_vect_cmdline_needed: returning $et_vect_cmdline_needed_saved" 2
+ return $et_vect_cmdline_needed_saved
+}
+
# Return 1 if the target supports hardware vectors of int, 0 otherwise.
#
# This won't change for different subtargets so cache the result.
@@ -990,6 +1012,29 @@ proc check_effective_target_sync_int_long { } {
return $et_sync_int_long_saved
}
+# Return 1 if the target supports atomic operations on "char" and "short".
+
+proc check_effective_target_sync_char_short { } {
+ global et_sync_char_short_saved
+
+ if [info exists et_sync_char_short_saved] {
+ verbose "check_effective_target_sync_char_short: using cached result" 2
+ } else {
+ set et_sync_char_short_saved 0
+# This is intentionally powerpc but not rs6000, rs6000 doesn't have the
+# load-reserved/store-conditional instructions.
+ if { [istarget ia64-*-*]
+ || [istarget i?86-*-*]
+ || [istarget x86_64-*-*]
+ || [istarget powerpc*-*-*] } {
+ set et_sync_char_short_saved 1
+ }
+ }
+
+ verbose "check_effective_target_sync_char_short: returning $et_sync_char_short_saved" 2
+ return $et_sync_char_short_saved
+}
+
# Return 1 if the target matches the effective target 'arg', 0 otherwise.
# This can be used with any check_* proc that takes no argument and
# returns only 1 or 0. It could be used with check_* procs that take
diff --git a/gcc/testsuite/objc.dg/selector-2.m b/gcc/testsuite/objc.dg/selector-2.m
index 5584f1511b6..09fbc252836 100644
--- a/gcc/testsuite/objc.dg/selector-2.m
+++ b/gcc/testsuite/objc.dg/selector-2.m
@@ -1,5 +1,5 @@
/* Test that we don't ICE when issuing a -Wselector warning. */
-/* { dg-options "-Wselector -fgnu-runtime" } */
+/* { dg-options "-Wselector" } */
/* { dg-do compile } */
#include <objc/Object.h>
@@ -12,5 +12,6 @@
SEL a;
a = @selector(b1ar);
}
-@end /* { dg-warning "creating selector for nonexistent method .b1ar." } */
+@end
+/* { dg-warning "creating selector for nonexistent method .b1ar." "" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/objc/execute/next_mapping.h b/gcc/testsuite/objc/execute/next_mapping.h
index 0a361896e12..41d40fdf0dc 100644
--- a/gcc/testsuite/objc/execute/next_mapping.h
+++ b/gcc/testsuite/objc/execute/next_mapping.h
@@ -8,6 +8,8 @@
#include <objc/objc-class.h>
#include <objc/Object.h>
#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
#define objc_get_class(C) objc_getClass(C)
#define objc_get_meta_class(C) objc_getMetaClass(C)
@@ -45,22 +47,28 @@
/* The following is necessary to "cover" the bf*.m test cases on NeXT. */
#undef MAX
+#undef MIN
+#undef ROUND
+
+#ifdef __cplusplus
+#define MAX(X, Y) ((X > Y) ? X : Y)
+#define MIN(X, Y) ((X < Y) ? X : Y)
+#define ROUND(V, A) (A * ((V + A - 1) / A))
+#else
#define MAX(X, Y) \
({ typeof (X) __x = (X), __y = (Y); \
(__x > __y ? __x : __y); })
-
-#undef MIN
#define MIN(X, Y) \
({ typeof (X) __x = (X), __y = (Y); \
(__x < __y ? __x : __y); })
-
-#undef ROUND
#define ROUND(V, A) \
({ typeof (V) __v = (V); typeof (A) __a = (A); \
__a * ((__v+__a - 1)/__a); })
+#endif
#define BITS_PER_UNIT __CHAR_BIT__
-#define STRUCTURE_SIZE_BOUNDARY (BITS_PER_UNIT * sizeof (struct{char a;}))
+typedef struct{ char a; } __small_struct;
+#define STRUCTURE_SIZE_BOUNDARY (BITS_PER_UNIT * sizeof (__small_struct))
/* Not sure why the following are missing from NeXT objc headers... */
@@ -104,7 +112,7 @@ struct objc_struct_layout
unsigned int record_align;
};
-typedef union {
+typedef union arglist {
char *arg_ptr;
char arg_regs[sizeof (char*)];
} *arglist_t; /* argument frame */
@@ -117,6 +125,7 @@ void objc_layout_structure (const char *type,
BOOL objc_layout_structure_next_member (struct objc_struct_layout *layout);
void objc_layout_finish_structure (struct objc_struct_layout *layout,
unsigned int *size, unsigned int *align);
+int objc_aligned_size (const char *type);
/*
return the size of an object specified by type
@@ -193,10 +202,6 @@ objc_sizeof_type (const char *type)
return sizeof (double);
break;
- case _C_VOID:
- return sizeof (void);
- break;
-
case _C_PTR:
case _C_ATOM:
case _C_CHARPTR:
diff --git a/gcc/testsuite/treelang/compile/unsigned.tree b/gcc/testsuite/treelang/compile/unsigned.tree
index 03e7a2a0038..67f3404df90 100644
--- a/gcc/testsuite/treelang/compile/unsigned.tree
+++ b/gcc/testsuite/treelang/compile/unsigned.tree
@@ -1,5 +1,5 @@
// { dg-do compile }
-// { dg-options "-fdump-tree-generic" }
+// { dg-options "-fdump-tree-gimple" }
external_reference void abort ();
external_reference void exit (int status);
external_definition int main (int argc, int argv);
@@ -16,5 +16,5 @@ main
}
return +1;
}
-// { dg-final { scan-tree-dump-not "\\\(int\\\)" "generic" } }
-// { dg-final { cleanup-tree-dump "generic" } }
+// { dg-final { scan-tree-dump-not "\\\(int\\\)" "gimple" } }
+// { dg-final { cleanup-tree-dump "gimple" } }
diff --git a/gcc/timevar.c b/gcc/timevar.c
index 589b59cf820..ad9e5f5f914 100644
--- a/gcc/timevar.c
+++ b/gcc/timevar.c
@@ -1,5 +1,5 @@
/* Timing variables for measuring compiler performance.
- Copyright (C) 2000, 2003, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2003, 2004, 2005 Free Software Foundation, Inc.
Contributed by Alex Samuel <samuel@codesourcery.com>
This file is part of GCC.
diff --git a/gcc/timevar.h b/gcc/timevar.h
index f62f76e6383..e4eaca261d5 100644
--- a/gcc/timevar.h
+++ b/gcc/timevar.h
@@ -1,5 +1,5 @@
/* Timing variables for measuring compiler performance.
- Copyright (C) 2000, 2003, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2003, 2004, 2005 Free Software Foundation, Inc.
Contributed by Alex Samuel <samuel@codesourcery.com>
This file is part of GCC.
diff --git a/gcc/toplev.c b/gcc/toplev.c
index e4cfac4deed..7eab7d5c898 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -374,35 +374,6 @@ static const param_info lang_independent_params[] = {
{ NULL, 0, 0, 0, NULL }
};
-#ifdef TARGET_SWITCHES
-/* Here is a table, controlled by the tm.h file, listing each -m switch
- and which bits in `target_switches' it should set or clear.
- If VALUE is positive, it is bits to set.
- If VALUE is negative, -VALUE is bits to clear.
- (The sign bit is not used so there is no confusion.) */
-
-static const struct
-{
- const char *const name;
- const int value;
- const char *const description;
-}
-target_switches[] = TARGET_SWITCHES;
-#endif
-
-/* This table is similar, but allows the switch to have a value. */
-
-#ifdef TARGET_OPTIONS
-static const struct
-{
- const char *const prefix;
- const char **const variable;
- const char *const description;
- const char *const value;
-}
-target_options[] = TARGET_OPTIONS;
-#endif
-
/* Output files for assembler code (real compiler output)
and debugging dumps. */
@@ -1057,92 +1028,6 @@ compile_file (void)
targetm.asm_out.file_end ();
}
-/* Display help for target options. */
-void
-display_target_options (void)
-{
- int undoc;
-#if defined (TARGET_SWITCHES) || defined (TARGET_OPTIONS)
- int i;
-#endif
- unsigned int cli;
- static bool displayed = false;
-
- /* Avoid double printing for --help --target-help. */
- if (displayed)
- return;
-
- displayed = true;
-
- for (cli = 0; cli < cl_options_count; cli++)
- if ((cl_options[cli].flags & (CL_TARGET | CL_UNDOCUMENTED)) == CL_TARGET)
- break;
-
- if (cli < cl_options_count
-#ifdef TARGET_SWITCHES
- || ARRAY_SIZE (target_switches) > 1
-#endif
-#ifdef TARGET_OPTIONS
- || ARRAY_SIZE (target_options) > 1
-#endif
- )
- {
- int doc = cli < cl_options_count;
-
- undoc = 0;
-
- printf (_("\nTarget specific options:\n"));
-
-#ifdef TARGET_SWITCHES
- for (i = ARRAY_SIZE (target_switches); i--;)
- {
- const char *option = target_switches[i].name;
- const char *description = target_switches[i].description;
-
- if (option == NULL || *option == 0)
- continue;
- else if (description == NULL)
- {
- undoc = 1;
-
- if (extra_warnings)
- printf (_(" -m%-23s [undocumented]\n"), option);
- }
- else if (*description != 0)
- doc += printf (" -m%-23s %s\n", option, _(description));
- }
-#endif
-
-#ifdef TARGET_OPTIONS
- for (i = ARRAY_SIZE (target_options); i--;)
- {
- const char *option = target_options[i].prefix;
- const char *description = target_options[i].description;
-
- if (option == NULL || *option == 0)
- continue;
- else if (description == NULL)
- {
- undoc = 1;
-
- if (extra_warnings)
- printf (_(" -m%-23s [undocumented]\n"), option);
- }
- else if (*description != 0)
- doc += printf (" -m%-23s %s\n", option, _(description));
- }
-#endif
- print_filtered_help (CL_TARGET);
- if (undoc)
- {
- if (doc)
- printf (_("\nThere are undocumented target specific options as well.\n"));
- else
- printf (_(" They exist, but they are not documented.\n"));
- }
- }
-}
-
/* Parse a -d... command line switch. */
void
@@ -1193,64 +1078,6 @@ const char *const debug_type_names[] =
"none", "stabs", "coff", "dwarf-2", "xcoff", "vms"
};
-/* Decode -m switches. */
-/* Decode the switch -mNAME. */
-
-void
-set_target_switch (const char *name)
-{
-#if defined (TARGET_SWITCHES) || defined (TARGET_OPTIONS)
- size_t j;
-#endif
- int valid_target_option = 0;
-
-#ifdef TARGET_SWITCHES
- for (j = 0; j < ARRAY_SIZE (target_switches); j++)
- if (!strcmp (target_switches[j].name, name))
- {
- if (target_switches[j].value < 0)
- target_flags &= ~-target_switches[j].value;
- else
- target_flags |= target_switches[j].value;
- if (name[0] != 0)
- {
- if (target_switches[j].value < 0)
- target_flags_explicit |= -target_switches[j].value;
- else
- target_flags_explicit |= target_switches[j].value;
- }
- valid_target_option = 1;
- }
-#endif
-
-#ifdef TARGET_OPTIONS
- if (!valid_target_option)
- for (j = 0; j < ARRAY_SIZE (target_options); j++)
- {
- int len = strlen (target_options[j].prefix);
- if (target_options[j].value)
- {
- if (!strcmp (target_options[j].prefix, name))
- {
- *target_options[j].variable = target_options[j].value;
- valid_target_option = 1;
- }
- }
- else
- {
- if (!strncmp (target_options[j].prefix, name, len))
- {
- *target_options[j].variable = name + len;
- valid_target_option = 1;
- }
- }
- }
-#endif
-
- if (name[0] != 0 && !valid_target_option)
- error ("invalid option %qs", name);
-}
-
/* Print version information to FILE.
Each line begins with INDENT (for the case where FILE is the
assembler output file). */
@@ -1359,31 +1186,6 @@ print_switch_values (FILE *file, int pos, int max,
pos = print_single_switch (file, pos, max, indent, sep, term,
"", cl_options[j].opt_text);
- /* Print target specific options. */
-
-#ifdef TARGET_SWITCHES
- for (j = 0; j < ARRAY_SIZE (target_switches); j++)
- if (target_switches[j].name[0] != '\0'
- && target_switches[j].value > 0
- && ((target_switches[j].value & target_flags)
- == target_switches[j].value))
- {
- pos = print_single_switch (file, pos, max, indent, sep, term,
- "-m", target_switches[j].name);
- }
-#endif
-
-#ifdef TARGET_OPTIONS
- for (j = 0; j < ARRAY_SIZE (target_options); j++)
- if (*target_options[j].variable != NULL)
- {
- char prefix[256];
- sprintf (prefix, "-m%s", target_options[j].prefix);
- pos = print_single_switch (file, pos, max, indent, sep, term,
- prefix, *target_options[j].variable);
- }
-#endif
-
fprintf (file, "%s", term);
}
@@ -1434,6 +1236,21 @@ init_asm_output (const char *name)
}
}
+/* Return true if the state of option OPTION should be stored in PCH files
+ and checked by default_pch_valid_p. Store the option's current state
+ in STATE if so. */
+
+static inline bool
+option_affects_pch_p (int option, struct cl_option_state *state)
+{
+ if ((cl_options[option].flags & CL_TARGET) == 0)
+ return false;
+ if (cl_options[option].flag_var == &target_flags)
+ if (targetm.check_pch_target_flags)
+ return false;
+ return get_option_state (option, state);
+}
+
/* Default version of get_pch_validity.
By default, every flag difference is fatal; that will be mostly right for
most targets, but completely right for very few. */
@@ -1441,51 +1258,58 @@ init_asm_output (const char *name)
void *
default_get_pch_validity (size_t *len)
{
-#ifdef TARGET_OPTIONS
+ struct cl_option_state state;
size_t i;
-#endif
char *result, *r;
- *len = sizeof (target_flags) + 2;
-#ifdef TARGET_OPTIONS
- for (i = 0; i < ARRAY_SIZE (target_options); i++)
- {
- *len += 1;
- if (*target_options[i].variable)
- *len += strlen (*target_options[i].variable);
- }
-#endif
+ *len = 2;
+ if (targetm.check_pch_target_flags)
+ *len += sizeof (target_flags);
+ for (i = 0; i < cl_options_count; i++)
+ if (option_affects_pch_p (i, &state))
+ *len += state.size;
result = r = xmalloc (*len);
r[0] = flag_pic;
r[1] = flag_pie;
r += 2;
- memcpy (r, &target_flags, sizeof (target_flags));
- r += sizeof (target_flags);
-
-#ifdef TARGET_OPTIONS
- for (i = 0; i < ARRAY_SIZE (target_options); i++)
+ if (targetm.check_pch_target_flags)
{
- const char *str = *target_options[i].variable;
- size_t l;
- if (! str)
- str = "";
- l = strlen (str) + 1;
- memcpy (r, str, l);
- r += l;
+ memcpy (r, &target_flags, sizeof (target_flags));
+ r += sizeof (target_flags);
}
-#endif
+
+ for (i = 0; i < cl_options_count; i++)
+ if (option_affects_pch_p (i, &state))
+ {
+ memcpy (r, state.data, state.size);
+ r += state.size;
+ }
return result;
}
+/* Return a message which says that a PCH file was created with a different
+ setting of OPTION. */
+
+static const char *
+pch_option_mismatch (const char *option)
+{
+ char *r;
+
+ asprintf (&r, _("created and used with differing settings of '%s'"), option);
+ if (r == NULL)
+ return _("out of memory");
+ return r;
+}
+
/* Default version of pch_valid_p. */
const char *
default_pch_valid_p (const void *data_p, size_t len)
{
+ struct cl_option_state state;
const char *data = (const char *)data_p;
- const char *flag_that_differs = NULL;
size_t i;
/* -fpic and -fpie also usually make a PCH invalid. */
@@ -1496,68 +1320,29 @@ default_pch_valid_p (const void *data_p, size_t len)
data += 2;
/* Check target_flags. */
- if (memcmp (data, &target_flags, sizeof (target_flags)) != 0)
+ if (targetm.check_pch_target_flags)
{
int tf;
+ const char *r;
memcpy (&tf, data, sizeof (target_flags));
-#ifdef TARGET_SWITCHES
- for (i = 0; i < ARRAY_SIZE (target_switches); i++)
- {
- int bits;
-
- bits = target_switches[i].value;
- if (bits < 0)
- bits = -bits;
- if ((target_flags & bits) != (tf & bits))
- {
- flag_that_differs = target_switches[i].name;
- goto make_message;
- }
- }
-#endif
- for (i = 0; i < cl_options_count; i++)
- if (cl_options[i].flag_var == &target_flags
- && (cl_options[i].var_value & (target_flags ^ tf)) != 0)
- {
- flag_that_differs = cl_options[i].opt_text + 2;
- goto make_message;
- }
- gcc_unreachable ();
+ data += sizeof (target_flags);
+ len -= sizeof (target_flags);
+ r = targetm.check_pch_target_flags (tf);
+ if (r != NULL)
+ return r;
}
- data += sizeof (target_flags);
- len -= sizeof (target_flags);
- /* Check string options. */
-#ifdef TARGET_OPTIONS
- for (i = 0; i < ARRAY_SIZE (target_options); i++)
- {
- const char *str = *target_options[i].variable;
- size_t l;
- if (! str)
- str = "";
- l = strlen (str) + 1;
- if (len < l || memcmp (data, str, l) != 0)
- {
- flag_that_differs = target_options[i].prefix;
- goto make_message;
- }
- data += l;
- len -= l;
- }
-#endif
+ for (i = 0; i < cl_options_count; i++)
+ if (option_affects_pch_p (i, &state))
+ {
+ if (memcmp (data, state.data, state.size) != 0)
+ return pch_option_mismatch (cl_options[i].opt_text);
+ data += state.size;
+ len -= state.size;
+ }
return NULL;
-
- make_message:
- {
- char *r;
- asprintf (&r, _("created and used with differing settings of '-m%s'"),
- flag_that_differs);
- if (r == NULL)
- return _("out of memory");
- return r;
- }
}
/* Default tree printer. Handles declarations only. */
@@ -1570,7 +1355,7 @@ default_tree_printer (pretty_printer * pp, text_info *text)
{
case 'D':
t = va_arg (*text->args_ptr, tree);
- if (DECL_DEBUG_EXPR (t) && DECL_DEBUG_EXPR_IS_FROM (t))
+ if (DECL_DEBUG_EXPR_IS_FROM (t) && DECL_DEBUG_EXPR (t))
t = DECL_DEBUG_EXPR (t);
break;
diff --git a/gcc/toplev.h b/gcc/toplev.h
index cf11d29441b..7e759e16c63 100644
--- a/gcc/toplev.h
+++ b/gcc/toplev.h
@@ -138,9 +138,7 @@ extern int time_report;
extern int flag_tree_based_profiling;
/* Things to do with target switches. */
-extern void display_target_options (void);
extern void print_version (FILE *, const char *);
-extern void set_target_switch (const char *);
extern void * default_get_pch_validity (size_t *);
extern const char * default_pch_valid_p (const void *, size_t);
diff --git a/gcc/tree-browser.c b/gcc/tree-browser.c
index df1c7e9cc2d..f07cf968fce 100644
--- a/gcc/tree-browser.c
+++ b/gcc/tree-browser.c
@@ -23,7 +23,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "system.h"
#include "coretypes.h"
#include "tm.h"
-#include "errors.h"
#include "tree.h"
#include "tree-inline.h"
#include "diagnostic.h"
diff --git a/gcc/tree-browser.def b/gcc/tree-browser.def
index 57fb1df8044..ef14492d83f 100644
--- a/gcc/tree-browser.def
+++ b/gcc/tree-browser.def
@@ -33,7 +33,7 @@ DEFTBCODE (TB_UPDATE_UP, "update", "Update information about parent expre
DEFTBCODE (TB_VERBOSE, "verbose", "Sets/unsets verbose mode (default is on).")
/* Walking commands. */
-DEFTBCODE (TB_FUN, "fun", "Go to the curent function declaration.")
+DEFTBCODE (TB_FUN, "fun", "Go to the current function declaration.")
DEFTBCODE (TB_NEXT, "nx", "Go to the next expression in a BIND_EXPR.")
DEFTBCODE (TB_PREV, "pr", "Go to the previous expression in a BIND_EXPR.")
DEFTBCODE (TB_UP, "up", "Go to the parent tree node.")
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 4ec1215951b..285133480b4 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -29,7 +29,6 @@ Boston, MA 02111-1307, USA. */
#include "hard-reg-set.h"
#include "basic-block.h"
#include "output.h"
-#include "errors.h"
#include "flags.h"
#include "function.h"
#include "expr.h"
@@ -95,9 +94,6 @@ static bool found_computed_goto;
/* Basic blocks and flowgraphs. */
static basic_block create_bb (void *, void *, basic_block);
-static void create_block_annotation (basic_block);
-static void free_blocks_annotations (void);
-static void clear_blocks_annotations (void);
static void make_blocks (tree);
static void factor_computed_gotos (void);
@@ -111,27 +107,21 @@ static void make_goto_expr_edges (basic_block);
static edge tree_redirect_edge_and_branch (edge, basic_block);
static edge tree_try_redirect_by_replacing_jump (edge, basic_block);
static void split_critical_edges (void);
-static bool remove_fallthru_edge (VEC(edge,gc) *);
/* Various helpers. */
static inline bool stmt_starts_bb_p (tree, tree);
static int tree_verify_flow_info (void);
static void tree_make_forwarder_block (edge);
-static bool tree_forwarder_block_p (basic_block, bool);
static void tree_cfg2vcg (FILE *);
/* Flowgraph optimization and cleanup. */
static void tree_merge_blocks (basic_block, basic_block);
static bool tree_can_merge_blocks_p (basic_block, basic_block);
static void remove_bb (basic_block);
-static bool cleanup_control_flow (void);
-static bool cleanup_control_expr_graph (basic_block, block_stmt_iterator);
static edge find_taken_edge_computed_goto (basic_block, tree);
static edge find_taken_edge_cond_expr (basic_block, tree);
static edge find_taken_edge_switch_expr (basic_block, tree);
static tree find_case_label_for_value (tree, tree);
-static bool phi_alternatives_equal (basic_block, edge, edge);
-static bool cleanup_forwarder_blocks (void);
void
init_empty_tree_cfg (void)
@@ -149,9 +139,6 @@ init_empty_tree_cfg (void)
ENTRY_BLOCK_PTR->next_bb = EXIT_BLOCK_PTR;
EXIT_BLOCK_PTR->prev_bb = ENTRY_BLOCK_PTR;
-
- create_block_annotation (ENTRY_BLOCK_PTR);
- create_block_annotation (EXIT_BLOCK_PTR);
}
/*---------------------------------------------------------------------------
@@ -324,37 +311,6 @@ factor_computed_gotos (void)
}
-/* Create annotations for a single basic block. */
-
-static void
-create_block_annotation (basic_block bb)
-{
- /* Verify that the tree_annotations field is clear. */
- gcc_assert (!bb->tree_annotations);
- bb->tree_annotations = ggc_alloc_cleared (sizeof (struct bb_ann_d));
-}
-
-
-/* Free the annotations for all the basic blocks. */
-
-static void free_blocks_annotations (void)
-{
- clear_blocks_annotations ();
-}
-
-
-/* Clear the annotations for all the basic blocks. */
-
-static void
-clear_blocks_annotations (void)
-{
- basic_block bb;
-
- FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
- bb->tree_annotations = NULL;
-}
-
-
/* Build a flowgraph for the statement_list STMT_LIST. */
static void
@@ -433,8 +389,6 @@ create_bb (void *h, void *e, basic_block after)
/* Add the newly created block to the array. */
BASIC_BLOCK (last_basic_block) = bb;
- create_block_annotation (bb);
-
n_basic_blocks++;
last_basic_block++;
@@ -508,12 +462,11 @@ make_edges (void)
builder inserted for completeness. */
remove_fake_exit_edges ();
- /* To speed up statement iterator walks, we first purge dead labels. */
- cleanup_dead_labels ();
+ /* Fold COND_EXPR_COND of each COND_EXPR. */
+ fold_cond_expr_cond ();
- /* We can not do complette cleanup here as it would mess up coverage info.
- */
- delete_unreachable_blocks ();
+ /* Clean up the graph and warn for unreachable code. */
+ cleanup_tree_cfg ();
}
@@ -687,7 +640,7 @@ edge_to_cases_cleanup (void *p)
/* Start recording information mapping edges to case labels. */
-static void
+void
start_recording_case_labels (void)
{
gcc_assert (edge_to_cases == NULL);
@@ -708,7 +661,7 @@ recording_case_labels_p (void)
/* Stop recording information mapping edges to case labels and
remove any information we have recorded. */
-static void
+void
end_recording_case_labels (void)
{
htab_delete (edge_to_cases);
@@ -923,73 +876,6 @@ make_goto_expr_edges (basic_block bb)
Flowgraph analysis
---------------------------------------------------------------------------*/
-/* Remove unreachable blocks and other miscellaneous clean up work. */
-
-bool
-cleanup_tree_cfg (void)
-{
- bool retval = false;
-
- timevar_push (TV_TREE_CLEANUP_CFG);
-
- retval = cleanup_control_flow ();
- retval |= delete_unreachable_blocks ();
-
- /* cleanup_forwarder_blocks can redirect edges out of SWITCH_EXPRs,
- which can get expensive. So we want to enable recording of edge
- to CASE_LABEL_EXPR mappings around the call to
- cleanup_forwarder_blocks. */
- start_recording_case_labels ();
- retval |= cleanup_forwarder_blocks ();
- end_recording_case_labels ();
-
-#ifdef ENABLE_CHECKING
- if (retval)
- {
- gcc_assert (!cleanup_control_flow ());
- gcc_assert (!delete_unreachable_blocks ());
- gcc_assert (!cleanup_forwarder_blocks ());
- }
-#endif
-
- /* Merging the blocks creates no new opportunities for the other
- optimizations, so do it here. */
- retval |= merge_seq_blocks ();
-
- compact_blocks ();
-
-#ifdef ENABLE_CHECKING
- verify_flow_info ();
-#endif
- timevar_pop (TV_TREE_CLEANUP_CFG);
- return retval;
-}
-
-
-/* Cleanup cfg and repair loop structures. */
-
-void
-cleanup_tree_cfg_loop (void)
-{
- bitmap changed_bbs = BITMAP_ALLOC (NULL);
-
- cleanup_tree_cfg ();
-
- fix_loop_structure (current_loops, changed_bbs);
- calculate_dominance_info (CDI_DOMINATORS);
-
- /* This usually does nothing. But sometimes parts of cfg that originally
- were inside a loop get out of it due to edge removal (since they
- become unreachable by back edges from latch). */
- rewrite_into_loop_closed_ssa (changed_bbs, TODO_update_ssa);
-
- BITMAP_FREE (changed_bbs);
-
-#ifdef ENABLE_CHECKING
- verify_loop_structure (current_loops);
-#endif
-}
-
/* Cleanup useless labels in basic blocks. This is something we wish
to do early because it allows us to group case labels before creating
the edges for the CFG, and it speeds up block statement iterators in
@@ -2000,7 +1886,7 @@ struct tree_opt_pass pass_remove_useless_stmts =
NULL, /* gate */
NULL, NULL, /* IPA analysis */
remove_useless_stmts, /* execute */
- NULL, NULL, /* IPA modification */
+ NULL, NULL, /* IPA analysis */
NULL, /* sub */
NULL, /* next */
0, /* static_pass_number */
@@ -2125,182 +2011,6 @@ remove_bb (basic_block bb)
remove_phi_nodes_and_edges_for_unreachable_block (bb);
}
-/* A list of all the noreturn calls passed to modify_stmt.
- cleanup_control_flow uses it to detect cases where a mid-block
- indirect call has been turned into a noreturn call. When this
- happens, all the instructions after the call are no longer
- reachable and must be deleted as dead. */
-
-VEC(tree,gc) *modified_noreturn_calls;
-
-/* Try to remove superfluous control structures. */
-
-static bool
-cleanup_control_flow (void)
-{
- basic_block bb;
- block_stmt_iterator bsi;
- bool retval = false;
- tree stmt;
-
- /* Detect cases where a mid-block call is now known not to return. */
- while (VEC_length (tree, modified_noreturn_calls))
- {
- stmt = VEC_pop (tree, modified_noreturn_calls);
- bb = bb_for_stmt (stmt);
- if (bb != NULL && last_stmt (bb) != stmt && noreturn_call_p (stmt))
- split_block (bb, stmt);
- }
-
- FOR_EACH_BB (bb)
- {
- bsi = bsi_last (bb);
-
- if (bsi_end_p (bsi))
- continue;
-
- stmt = bsi_stmt (bsi);
- if (TREE_CODE (stmt) == COND_EXPR
- || TREE_CODE (stmt) == SWITCH_EXPR)
- retval |= cleanup_control_expr_graph (bb, bsi);
-
- /* If we had a computed goto which has a compile-time determinable
- destination, then we can eliminate the goto. */
- if (TREE_CODE (stmt) == GOTO_EXPR
- && TREE_CODE (GOTO_DESTINATION (stmt)) == ADDR_EXPR
- && TREE_CODE (TREE_OPERAND (GOTO_DESTINATION (stmt), 0)) == LABEL_DECL)
- {
- edge e;
- tree label;
- edge_iterator ei;
- basic_block target_block;
- bool removed_edge = false;
-
- /* First look at all the outgoing edges. Delete any outgoing
- edges which do not go to the right block. For the one
- edge which goes to the right block, fix up its flags. */
- label = TREE_OPERAND (GOTO_DESTINATION (stmt), 0);
- target_block = label_to_block (label);
- for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); )
- {
- if (e->dest != target_block)
- {
- removed_edge = true;
- remove_edge (e);
- }
- else
- {
- /* Turn off the EDGE_ABNORMAL flag. */
- e->flags &= ~EDGE_ABNORMAL;
-
- /* And set EDGE_FALLTHRU. */
- e->flags |= EDGE_FALLTHRU;
- ei_next (&ei);
- }
- }
-
- /* If we removed one or more edges, then we will need to fix the
- dominators. It may be possible to incrementally update them. */
- if (removed_edge)
- free_dominance_info (CDI_DOMINATORS);
-
- /* Remove the GOTO_EXPR as it is not needed. The CFG has all the
- relevant information we need. */
- bsi_remove (&bsi);
- retval = true;
- }
-
- /* Check for indirect calls that have been turned into
- noreturn calls. */
- if (noreturn_call_p (stmt) && remove_fallthru_edge (bb->succs))
- {
- free_dominance_info (CDI_DOMINATORS);
- retval = true;
- }
- }
- return retval;
-}
-
-
-/* Disconnect an unreachable block in the control expression starting
- at block BB. */
-
-static bool
-cleanup_control_expr_graph (basic_block bb, block_stmt_iterator bsi)
-{
- edge taken_edge;
- bool retval = false;
- tree expr = bsi_stmt (bsi), val;
-
- if (!single_succ_p (bb))
- {
- edge e;
- edge_iterator ei;
-
- switch (TREE_CODE (expr))
- {
- case COND_EXPR:
- val = COND_EXPR_COND (expr);
- break;
-
- case SWITCH_EXPR:
- val = SWITCH_COND (expr);
- if (TREE_CODE (val) != INTEGER_CST)
- return false;
- break;
-
- default:
- gcc_unreachable ();
- }
-
- taken_edge = find_taken_edge (bb, val);
- if (!taken_edge)
- return false;
-
- /* Remove all the edges except the one that is always executed. */
- for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); )
- {
- if (e != taken_edge)
- {
- taken_edge->probability += e->probability;
- taken_edge->count += e->count;
- remove_edge (e);
- retval = true;
- }
- else
- ei_next (&ei);
- }
- if (taken_edge->probability > REG_BR_PROB_BASE)
- taken_edge->probability = REG_BR_PROB_BASE;
- }
- else
- taken_edge = single_succ_edge (bb);
-
- bsi_remove (&bsi);
- taken_edge->flags = EDGE_FALLTHRU;
-
- /* We removed some paths from the cfg. */
- free_dominance_info (CDI_DOMINATORS);
-
- return retval;
-}
-
-/* Remove any fallthru edge from EV. Return true if an edge was removed. */
-
-static bool
-remove_fallthru_edge (VEC(edge,gc) *ev)
-{
- edge_iterator ei;
- edge e;
-
- FOR_EACH_EDGE (e, ei, ev)
- if ((e->flags & EDGE_FALLTHRU) != 0)
- {
- remove_edge (e);
- return true;
- }
- return false;
-}
/* Given a basic block BB ending with COND_EXPR or SWITCH_EXPR, and a
predicate VAL, return the edge that will be taken out of the block.
@@ -2431,31 +2141,6 @@ find_case_label_for_value (tree switch_expr, tree val)
}
-/* If all the PHI nodes in DEST have alternatives for E1 and E2 and
- those alternatives are equal in each of the PHI nodes, then return
- true, else return false. */
-
-static bool
-phi_alternatives_equal (basic_block dest, edge e1, edge e2)
-{
- int n1 = e1->dest_idx;
- int n2 = e2->dest_idx;
- tree phi;
-
- for (phi = phi_nodes (dest); phi; phi = PHI_CHAIN (phi))
- {
- tree val1 = PHI_ARG_DEF (phi, n1);
- tree val2 = PHI_ARG_DEF (phi, n2);
-
- gcc_assert (val1 != NULL_TREE);
- gcc_assert (val2 != NULL_TREE);
-
- if (!operand_equal_for_phi_arg_p (val1, val2))
- return false;
- }
-
- return true;
-}
/*---------------------------------------------------------------------------
@@ -2566,11 +2251,6 @@ dump_cfg_stats (FILE *file)
total += size;
fprintf (file, fmt_str_1, "Edges", num_edges, SCALE (size), LABEL (size));
- size = n_basic_blocks * sizeof (struct bb_ann_d);
- total += size;
- fprintf (file, fmt_str_1, "Basic block annotations", n_basic_blocks,
- SCALE (size), LABEL (size));
-
fprintf (file, "---------------------------------------------------------\n");
fprintf (file, fmt_str_3, "Total memory used by CFG data", SCALE (total),
LABEL (total));
@@ -2881,8 +2561,6 @@ void
delete_tree_cfg_annotations (void)
{
basic_block bb;
- if (n_basic_blocks > 0)
- free_blocks_annotations ();
label_to_block_map = NULL;
FOR_EACH_BB (bb)
@@ -3434,32 +3112,67 @@ verify_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
break;
case ADDR_EXPR:
- /* ??? tree-ssa-alias.c may have overlooked dead PHI nodes, missing
- dead PHIs that take the address of something. But if the PHI
- result is dead, the fact that it takes the address of anything
- is irrelevant. Because we can not tell from here if a PHI result
- is dead, we just skip this check for PHIs altogether. This means
- we may be missing "valid" checks, but what can you do?
- This was PR19217. */
- if (in_phi)
- break;
+ {
+ bool old_invariant;
+ bool old_constant;
+ bool old_side_effects;
+ bool new_invariant;
+ bool new_constant;
+ bool new_side_effects;
+
+ /* ??? tree-ssa-alias.c may have overlooked dead PHI nodes, missing
+ dead PHIs that take the address of something. But if the PHI
+ result is dead, the fact that it takes the address of anything
+ is irrelevant. Because we can not tell from here if a PHI result
+ is dead, we just skip this check for PHIs altogether. This means
+ we may be missing "valid" checks, but what can you do?
+ This was PR19217. */
+ if (in_phi)
+ break;
- /* Skip any references (they will be checked when we recurse down the
- tree) and ensure that any variable used as a prefix is marked
- addressable. */
- for (x = TREE_OPERAND (t, 0);
- handled_component_p (x);
- x = TREE_OPERAND (x, 0))
- ;
-
- if (TREE_CODE (x) != VAR_DECL && TREE_CODE (x) != PARM_DECL)
- return NULL;
- if (!TREE_ADDRESSABLE (x))
- {
- error ("address taken, but ADDRESSABLE bit not set");
- return x;
- }
- break;
+ old_invariant = TREE_INVARIANT (t);
+ old_constant = TREE_CONSTANT (t);
+ old_side_effects = TREE_SIDE_EFFECTS (t);
+
+ recompute_tree_invarant_for_addr_expr (t);
+ new_invariant = TREE_INVARIANT (t);
+ new_side_effects = TREE_SIDE_EFFECTS (t);
+ new_constant = TREE_CONSTANT (t);
+
+ if (old_invariant != new_invariant)
+ {
+ error ("invariant not recomputed when ADDR_EXPR changed");
+ return t;
+ }
+
+ if (old_constant != new_constant)
+ {
+ error ("constant not recomputed when ADDR_EXPR changed");
+ return t;
+ }
+ if (old_side_effects != new_side_effects)
+ {
+ error ("side effects not recomputed when ADDR_EXPR changed");
+ return t;
+ }
+
+ /* Skip any references (they will be checked when we recurse down the
+ tree) and ensure that any variable used as a prefix is marked
+ addressable. */
+ for (x = TREE_OPERAND (t, 0);
+ handled_component_p (x);
+ x = TREE_OPERAND (x, 0))
+ ;
+
+ if (TREE_CODE (x) != VAR_DECL && TREE_CODE (x) != PARM_DECL)
+ return NULL;
+ if (!TREE_ADDRESSABLE (x))
+ {
+ error ("address taken, but ADDRESSABLE bit not set");
+ return x;
+ }
+ break;
+ }
case COND_EXPR:
x = COND_EXPR_COND (t);
@@ -3468,6 +3181,11 @@ verify_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
error ("non-boolean used in condition");
return x;
}
+ if (!is_gimple_condexpr (x))
+ {
+ error ("Invalid conditional operand");
+ return x;
+ }
break;
case NOP_EXPR:
@@ -3854,13 +3572,6 @@ tree_verify_flow_info (void)
{
tree stmt = bsi_stmt (bsi);
- if (bb_for_stmt (stmt) != bb)
- {
- debug_generic_stmt (stmt);
- error ("bb_for_stmt is invalid\n");
- err = 1;
- }
-
if (found_ctrl_stmt)
{
error ("Control flow in the middle of basic block %d\n",
@@ -4119,449 +3830,6 @@ tree_make_forwarder_block (edge fallthru)
}
-/* Return true if basic block BB does nothing except pass control
- flow to another block and that we can safely insert a label at
- the start of the successor block.
-
- As a precondition, we require that BB be not equal to
- ENTRY_BLOCK_PTR. */
-
-static bool
-tree_forwarder_block_p (basic_block bb, bool phi_wanted)
-{
- block_stmt_iterator bsi;
-
- /* BB must have a single outgoing edge. */
- if (single_succ_p (bb) != 1
- /* If PHI_WANTED is false, BB must not have any PHI nodes.
- Otherwise, BB must have PHI nodes. */
- || (phi_nodes (bb) != NULL_TREE) != phi_wanted
- /* BB may not be a predecessor of EXIT_BLOCK_PTR. */
- || single_succ (bb) == EXIT_BLOCK_PTR
- /* Nor should this be an infinite loop. */
- || single_succ (bb) == bb
- /* BB may not have an abnormal outgoing edge. */
- || (single_succ_edge (bb)->flags & EDGE_ABNORMAL))
- return false;
-
-#if ENABLE_CHECKING
- gcc_assert (bb != ENTRY_BLOCK_PTR);
-#endif
-
- /* Now walk through the statements backward. We can ignore labels,
- anything else means this is not a forwarder block. */
- for (bsi = bsi_last (bb); !bsi_end_p (bsi); bsi_prev (&bsi))
- {
- tree stmt = bsi_stmt (bsi);
-
- switch (TREE_CODE (stmt))
- {
- case LABEL_EXPR:
- if (DECL_NONLOCAL (LABEL_EXPR_LABEL (stmt)))
- return false;
- break;
-
- default:
- return false;
- }
- }
-
- if (find_edge (ENTRY_BLOCK_PTR, bb))
- return false;
-
- if (current_loops)
- {
- basic_block dest;
- /* Protect loop latches, headers and preheaders. */
- if (bb->loop_father->header == bb)
- return false;
- dest = EDGE_SUCC (bb, 0)->dest;
-
- if (dest->loop_father->header == dest)
- return false;
- }
-
- return true;
-}
-
-/* Return true if BB has at least one abnormal incoming edge. */
-
-static inline bool
-has_abnormal_incoming_edge_p (basic_block bb)
-{
- edge e;
- edge_iterator ei;
-
- FOR_EACH_EDGE (e, ei, bb->preds)
- if (e->flags & EDGE_ABNORMAL)
- return true;
-
- return false;
-}
-
-/* Removes forwarder block BB. Returns false if this failed. If a new
- forwarder block is created due to redirection of edges, it is
- stored to worklist. */
-
-static bool
-remove_forwarder_block (basic_block bb, basic_block **worklist)
-{
- edge succ = single_succ_edge (bb), e, s;
- basic_block dest = succ->dest;
- tree label;
- tree phi;
- edge_iterator ei;
- block_stmt_iterator bsi, bsi_to;
- bool seen_abnormal_edge = false;
-
- /* We check for infinite loops already in tree_forwarder_block_p.
- However it may happen that the infinite loop is created
- afterwards due to removal of forwarders. */
- if (dest == bb)
- return false;
-
- /* If the destination block consists of a nonlocal label, do not merge
- it. */
- label = first_stmt (dest);
- if (label
- && TREE_CODE (label) == LABEL_EXPR
- && DECL_NONLOCAL (LABEL_EXPR_LABEL (label)))
- return false;
-
- /* If there is an abnormal edge to basic block BB, but not into
- dest, problems might occur during removal of the phi node at out
- of ssa due to overlapping live ranges of registers.
-
- If there is an abnormal edge in DEST, the problems would occur
- anyway since cleanup_dead_labels would then merge the labels for
- two different eh regions, and rest of exception handling code
- does not like it.
-
- So if there is an abnormal edge to BB, proceed only if there is
- no abnormal edge to DEST and there are no phi nodes in DEST. */
- if (has_abnormal_incoming_edge_p (bb))
- {
- seen_abnormal_edge = true;
-
- if (has_abnormal_incoming_edge_p (dest)
- || phi_nodes (dest) != NULL_TREE)
- return false;
- }
-
- /* If there are phi nodes in DEST, and some of the blocks that are
- predecessors of BB are also predecessors of DEST, check that the
- phi node arguments match. */
- if (phi_nodes (dest))
- {
- FOR_EACH_EDGE (e, ei, bb->preds)
- {
- s = find_edge (e->src, dest);
- if (!s)
- continue;
-
- if (!phi_alternatives_equal (dest, succ, s))
- return false;
- }
- }
-
- /* Redirect the edges. */
- for (ei = ei_start (bb->preds); (e = ei_safe_edge (ei)); )
- {
- if (e->flags & EDGE_ABNORMAL)
- {
- /* If there is an abnormal edge, redirect it anyway, and
- move the labels to the new block to make it legal. */
- s = redirect_edge_succ_nodup (e, dest);
- }
- else
- s = redirect_edge_and_branch (e, dest);
-
- if (s == e)
- {
- /* Create arguments for the phi nodes, since the edge was not
- here before. */
- for (phi = phi_nodes (dest); phi; phi = PHI_CHAIN (phi))
- add_phi_arg (phi, PHI_ARG_DEF (phi, succ->dest_idx), s);
- }
- else
- {
- /* The source basic block might become a forwarder. We know
- that it was not a forwarder before, since it used to have
- at least two outgoing edges, so we may just add it to
- worklist. */
- if (tree_forwarder_block_p (s->src, false))
- *(*worklist)++ = s->src;
- }
- }
-
- if (seen_abnormal_edge)
- {
- /* Move the labels to the new block, so that the redirection of
- the abnormal edges works. */
-
- bsi_to = bsi_start (dest);
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); )
- {
- label = bsi_stmt (bsi);
- gcc_assert (TREE_CODE (label) == LABEL_EXPR);
- bsi_remove (&bsi);
- bsi_insert_before (&bsi_to, label, BSI_CONTINUE_LINKING);
- }
- }
-
- /* Update the dominators. */
- if (dom_info_available_p (CDI_DOMINATORS))
- {
- basic_block dom, dombb, domdest;
-
- dombb = get_immediate_dominator (CDI_DOMINATORS, bb);
- domdest = get_immediate_dominator (CDI_DOMINATORS, dest);
- if (domdest == bb)
- {
- /* Shortcut to avoid calling (relatively expensive)
- nearest_common_dominator unless necessary. */
- dom = dombb;
- }
- else
- dom = nearest_common_dominator (CDI_DOMINATORS, domdest, dombb);
-
- set_immediate_dominator (CDI_DOMINATORS, dest, dom);
- }
-
- /* And kill the forwarder block. */
- delete_basic_block (bb);
-
- return true;
-}
-
-/* Removes forwarder blocks. */
-
-static bool
-cleanup_forwarder_blocks (void)
-{
- basic_block bb;
- bool changed = false;
- basic_block *worklist = xmalloc (sizeof (basic_block) * n_basic_blocks);
- basic_block *current = worklist;
-
- FOR_EACH_BB (bb)
- {
- if (tree_forwarder_block_p (bb, false))
- *current++ = bb;
- }
-
- while (current != worklist)
- {
- bb = *--current;
- changed |= remove_forwarder_block (bb, &current);
- }
-
- free (worklist);
- return changed;
-}
-
-/* Merge the PHI nodes at BB into those at BB's sole successor. */
-
-static void
-remove_forwarder_block_with_phi (basic_block bb)
-{
- edge succ = single_succ_edge (bb);
- basic_block dest = succ->dest;
- tree label;
- basic_block dombb, domdest, dom;
-
- /* We check for infinite loops already in tree_forwarder_block_p.
- However it may happen that the infinite loop is created
- afterwards due to removal of forwarders. */
- if (dest == bb)
- return;
-
- /* If the destination block consists of a nonlocal label, do not
- merge it. */
- label = first_stmt (dest);
- if (label
- && TREE_CODE (label) == LABEL_EXPR
- && DECL_NONLOCAL (LABEL_EXPR_LABEL (label)))
- return;
-
- /* Redirect each incoming edge to BB to DEST. */
- while (EDGE_COUNT (bb->preds) > 0)
- {
- edge e = EDGE_PRED (bb, 0), s;
- tree phi;
-
- s = find_edge (e->src, dest);
- if (s)
- {
- /* We already have an edge S from E->src to DEST. If S and
- E->dest's sole successor edge have the same PHI arguments
- at DEST, redirect S to DEST. */
- if (phi_alternatives_equal (dest, s, succ))
- {
- e = redirect_edge_and_branch (e, dest);
- PENDING_STMT (e) = NULL_TREE;
- continue;
- }
-
- /* PHI arguments are different. Create a forwarder block by
- splitting E so that we can merge PHI arguments on E to
- DEST. */
- e = single_succ_edge (split_edge (e));
- }
-
- s = redirect_edge_and_branch (e, dest);
-
- /* redirect_edge_and_branch must not create a new edge. */
- gcc_assert (s == e);
-
- /* Add to the PHI nodes at DEST each PHI argument removed at the
- destination of E. */
- for (phi = phi_nodes (dest); phi; phi = PHI_CHAIN (phi))
- {
- tree def = PHI_ARG_DEF (phi, succ->dest_idx);
-
- if (TREE_CODE (def) == SSA_NAME)
- {
- tree var;
-
- /* If DEF is one of the results of PHI nodes removed during
- redirection, replace it with the PHI argument that used
- to be on E. */
- for (var = PENDING_STMT (e); var; var = TREE_CHAIN (var))
- {
- tree old_arg = TREE_PURPOSE (var);
- tree new_arg = TREE_VALUE (var);
-
- if (def == old_arg)
- {
- def = new_arg;
- break;
- }
- }
- }
-
- add_phi_arg (phi, def, s);
- }
-
- PENDING_STMT (e) = NULL;
- }
-
- /* Update the dominators. */
- dombb = get_immediate_dominator (CDI_DOMINATORS, bb);
- domdest = get_immediate_dominator (CDI_DOMINATORS, dest);
- if (domdest == bb)
- {
- /* Shortcut to avoid calling (relatively expensive)
- nearest_common_dominator unless necessary. */
- dom = dombb;
- }
- else
- dom = nearest_common_dominator (CDI_DOMINATORS, domdest, dombb);
-
- set_immediate_dominator (CDI_DOMINATORS, dest, dom);
-
- /* Remove BB since all of BB's incoming edges have been redirected
- to DEST. */
- delete_basic_block (bb);
-}
-
-/* This pass merges PHI nodes if one feeds into another. For example,
- suppose we have the following:
-
- goto <bb 9> (<L9>);
-
-<L8>:;
- tem_17 = foo ();
-
- # tem_6 = PHI <tem_17(8), tem_23(7)>;
-<L9>:;
-
- # tem_3 = PHI <tem_6(9), tem_2(5)>;
-<L10>:;
-
- Then we merge the first PHI node into the second one like so:
-
- goto <bb 9> (<L10>);
-
-<L8>:;
- tem_17 = foo ();
-
- # tem_3 = PHI <tem_23(7), tem_2(5), tem_17(8)>;
-<L10>:;
-*/
-
-static void
-merge_phi_nodes (void)
-{
- basic_block *worklist = xmalloc (sizeof (basic_block) * n_basic_blocks);
- basic_block *current = worklist;
- basic_block bb;
-
- calculate_dominance_info (CDI_DOMINATORS);
-
- /* Find all PHI nodes that we may be able to merge. */
- FOR_EACH_BB (bb)
- {
- basic_block dest;
-
- /* Look for a forwarder block with PHI nodes. */
- if (!tree_forwarder_block_p (bb, true))
- continue;
-
- dest = single_succ (bb);
-
- /* We have to feed into another basic block with PHI
- nodes. */
- if (!phi_nodes (dest)
- /* We don't want to deal with a basic block with
- abnormal edges. */
- || has_abnormal_incoming_edge_p (bb))
- continue;
-
- if (!dominated_by_p (CDI_DOMINATORS, dest, bb))
- {
- /* If BB does not dominate DEST, then the PHI nodes at
- DEST must be the only users of the results of the PHI
- nodes at BB. */
- *current++ = bb;
- }
- }
-
- /* Now let's drain WORKLIST. */
- while (current != worklist)
- {
- bb = *--current;
- remove_forwarder_block_with_phi (bb);
- }
-
- free (worklist);
-}
-
-static bool
-gate_merge_phi (void)
-{
- return 1;
-}
-
-struct tree_opt_pass pass_merge_phi = {
- "mergephi", /* name */
- gate_merge_phi, /* gate */
- NULL, NULL, /* IPA analysis */
- merge_phi_nodes, /* execute */
- NULL, NULL, /* IPA modification */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_MERGE_PHI, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_dump_func | TODO_ggc_collect /* todo_flags_finish */
- | TODO_verify_ssa,
- 0 /* letter */
-};
-
/* Return a non-special label in the head of basic block BLOCK.
Create one if it doesn't exist. */
diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c
index f250f1fc05e..79488dfabc7 100644
--- a/gcc/tree-cfgcleanup.c
+++ b/gcc/tree-cfgcleanup.c
@@ -741,7 +741,9 @@ gate_merge_phi (void)
struct tree_opt_pass pass_merge_phi = {
"mergephi", /* name */
gate_merge_phi, /* gate */
+ NULL, NULL, /* IPA analysis */
merge_phi_nodes, /* execute */
+ NULL, NULL, /* IPA analysis */
NULL, /* sub */
NULL, /* next */
0, /* static_pass_number */
diff --git a/gcc/tree-chrec.c b/gcc/tree-chrec.c
index cb72df0aad3..bd8bafc9762 100644
--- a/gcc/tree-chrec.c
+++ b/gcc/tree-chrec.c
@@ -28,7 +28,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "system.h"
#include "coretypes.h"
#include "tm.h"
-#include "errors.h"
#include "ggc.h"
#include "tree.h"
#include "diagnostic.h"
@@ -294,7 +293,9 @@ chrec_fold_plus_1 (enum tree_code code,
&& size < PARAM_VALUE (PARAM_SCEV_MAX_EXPR_SIZE))
return build2 (code, type, op0, op1);
else if (size < PARAM_VALUE (PARAM_SCEV_MAX_EXPR_SIZE))
- return fold_build2 (code, type, op0, op1);
+ return fold_build2 (code, type,
+ fold_convert (type, op0),
+ fold_convert (type, op1));
else
return chrec_dont_know;
}
diff --git a/gcc/tree-complex.c b/gcc/tree-complex.c
index 57f05516ef2..c1e502e3fe3 100644
--- a/gcc/tree-complex.c
+++ b/gcc/tree-complex.c
@@ -1,4 +1,4 @@
-/* Lower complex number and vector operations to scalar operations.
+/* Lower complex number operations to scalar operations.
Copyright (C) 2004, 2005 Free Software Foundation, Inc.
This file is part of GCC.
@@ -563,462 +563,9 @@ expand_complex_operations_1 (block_stmt_iterator *bsi)
}
update_stmt_if_modified (stmt);
}
-
-/* Build a constant of type TYPE, made of VALUE's bits replicated
- every TYPE_SIZE (INNER_TYPE) bits to fit TYPE's precision. */
-static tree
-build_replicated_const (tree type, tree inner_type, HOST_WIDE_INT value)
-{
- int width = tree_low_cst (TYPE_SIZE (inner_type), 1);
- int n = HOST_BITS_PER_WIDE_INT / width;
- unsigned HOST_WIDE_INT low, high, mask;
- tree ret;
-
- gcc_assert (n);
-
- if (width == HOST_BITS_PER_WIDE_INT)
- low = value;
- else
- {
- mask = ((HOST_WIDE_INT)1 << width) - 1;
- low = (unsigned HOST_WIDE_INT) ~0 / mask * (value & mask);
- }
-
- if (TYPE_PRECISION (type) < HOST_BITS_PER_WIDE_INT)
- low &= ((HOST_WIDE_INT)1 << TYPE_PRECISION (type)) - 1, high = 0;
- else if (TYPE_PRECISION (type) == HOST_BITS_PER_WIDE_INT)
- high = 0;
- else if (TYPE_PRECISION (type) == 2 * HOST_BITS_PER_WIDE_INT)
- high = low;
- else
- gcc_unreachable ();
-
- ret = build_int_cst_wide (type, low, high);
- return ret;
-}
-
-static GTY(()) tree vector_inner_type;
-static GTY(()) tree vector_last_type;
-static GTY(()) int vector_last_nunits;
-
-/* Return a suitable vector types made of SUBPARTS units each of mode
- "word_mode" (the global variable). */
-static tree
-build_word_mode_vector_type (int nunits)
-{
- if (!vector_inner_type)
- vector_inner_type = lang_hooks.types.type_for_mode (word_mode, 1);
- else if (vector_last_nunits == nunits)
- {
- gcc_assert (TREE_CODE (vector_last_type) == VECTOR_TYPE);
- return vector_last_type;
- }
-
- /* We build a new type, but we canonicalize it nevertheless,
- because it still saves some memory. */
- vector_last_nunits = nunits;
- vector_last_type = type_hash_canon (nunits,
- build_vector_type (vector_inner_type,
- nunits));
- return vector_last_type;
-}
-
-typedef tree (*elem_op_func) (block_stmt_iterator *,
- tree, tree, tree, tree, tree, enum tree_code);
-
-static inline tree
-tree_vec_extract (block_stmt_iterator *bsi, tree type,
- tree t, tree bitsize, tree bitpos)
-{
- if (bitpos)
- return gimplify_build3 (bsi, BIT_FIELD_REF, type, t, bitsize, bitpos);
-
- /* Build a conversion; VIEW_CONVERT_EXPR is very expensive unless T will
- anyway be stored in memory, so prefer NOP_EXPR. */
- else if (TYPE_MODE (type) == BLKmode)
- return gimplify_build1 (bsi, VIEW_CONVERT_EXPR, type, t);
- else
- return gimplify_build1 (bsi, NOP_EXPR, type, t);
-}
-
-static tree
-do_unop (block_stmt_iterator *bsi, tree inner_type, tree a,
- tree b ATTRIBUTE_UNUSED, tree bitpos, tree bitsize,
- enum tree_code code)
-{
- a = tree_vec_extract (bsi, inner_type, a, bitsize, bitpos);
- return gimplify_build1 (bsi, code, inner_type, a);
-}
-
-static tree
-do_binop (block_stmt_iterator *bsi, tree inner_type, tree a, tree b,
- tree bitpos, tree bitsize, enum tree_code code)
-{
- a = tree_vec_extract (bsi, inner_type, a, bitsize, bitpos);
- b = tree_vec_extract (bsi, inner_type, b, bitsize, bitpos);
- return gimplify_build2 (bsi, code, inner_type, a, b);
-}
-
-/* Expand vector addition to scalars. This does bit twiddling
- in order to increase parallelism:
-
- a + b = (((int) a & 0x7f7f7f7f) + ((int) b & 0x7f7f7f7f)) ^
- (a ^ b) & 0x80808080
-
- a - b = (((int) a | 0x80808080) - ((int) b & 0x7f7f7f7f)) ^
- (a ^ ~b) & 0x80808080
-
- -b = (0x80808080 - ((int) b & 0x7f7f7f7f)) ^ (~b & 0x80808080)
-
- This optimization should be done only if 4 vector items or more
- fit into a word. */
-static tree
-do_plus_minus (block_stmt_iterator *bsi, tree word_type, tree a, tree b,
- tree bitpos ATTRIBUTE_UNUSED, tree bitsize ATTRIBUTE_UNUSED,
- enum tree_code code)
-{
- tree inner_type = TREE_TYPE (TREE_TYPE (a));
- unsigned HOST_WIDE_INT max;
- tree low_bits, high_bits, a_low, b_low, result_low, signs;
-
- max = GET_MODE_MASK (TYPE_MODE (inner_type));
- low_bits = build_replicated_const (word_type, inner_type, max >> 1);
- high_bits = build_replicated_const (word_type, inner_type, max & ~(max >> 1));
-
- a = tree_vec_extract (bsi, word_type, a, bitsize, bitpos);
- b = tree_vec_extract (bsi, word_type, b, bitsize, bitpos);
-
- signs = gimplify_build2 (bsi, BIT_XOR_EXPR, word_type, a, b);
- b_low = gimplify_build2 (bsi, BIT_AND_EXPR, word_type, b, low_bits);
- if (code == PLUS_EXPR)
- a_low = gimplify_build2 (bsi, BIT_AND_EXPR, word_type, a, low_bits);
- else
- {
- a_low = gimplify_build2 (bsi, BIT_IOR_EXPR, word_type, a, high_bits);
- signs = gimplify_build1 (bsi, BIT_NOT_EXPR, word_type, signs);
- }
-
- signs = gimplify_build2 (bsi, BIT_AND_EXPR, word_type, signs, high_bits);
- result_low = gimplify_build2 (bsi, code, word_type, a_low, b_low);
- return gimplify_build2 (bsi, BIT_XOR_EXPR, word_type, result_low, signs);
-}
-
-static tree
-do_negate (block_stmt_iterator *bsi, tree word_type, tree b,
- tree unused ATTRIBUTE_UNUSED, tree bitpos ATTRIBUTE_UNUSED,
- tree bitsize ATTRIBUTE_UNUSED,
- enum tree_code code ATTRIBUTE_UNUSED)
-{
- tree inner_type = TREE_TYPE (TREE_TYPE (b));
- HOST_WIDE_INT max;
- tree low_bits, high_bits, b_low, result_low, signs;
-
- max = GET_MODE_MASK (TYPE_MODE (inner_type));
- low_bits = build_replicated_const (word_type, inner_type, max >> 1);
- high_bits = build_replicated_const (word_type, inner_type, max & ~(max >> 1));
-
- b = tree_vec_extract (bsi, word_type, b, bitsize, bitpos);
-
- b_low = gimplify_build2 (bsi, BIT_AND_EXPR, word_type, b, low_bits);
- signs = gimplify_build1 (bsi, BIT_NOT_EXPR, word_type, b);
- signs = gimplify_build2 (bsi, BIT_AND_EXPR, word_type, signs, high_bits);
- result_low = gimplify_build2 (bsi, MINUS_EXPR, word_type, high_bits, b_low);
- return gimplify_build2 (bsi, BIT_XOR_EXPR, word_type, result_low, signs);
-}
-
-/* Expand a vector operation to scalars, by using many operations
- whose type is the vector type's inner type. */
-static tree
-expand_vector_piecewise (block_stmt_iterator *bsi, elem_op_func f,
- tree type, tree inner_type,
- tree a, tree b, enum tree_code code)
-{
- tree head, *chain = &head;
- tree part_width = TYPE_SIZE (inner_type);
- tree index = bitsize_int (0);
- int nunits = TYPE_VECTOR_SUBPARTS (type);
- int delta = tree_low_cst (part_width, 1)
- / tree_low_cst (TYPE_SIZE (TREE_TYPE (type)), 1);
- int i;
-
- for (i = 0; i < nunits;
- i += delta, index = int_const_binop (PLUS_EXPR, index, part_width, 0))
- {
- tree result = f (bsi, inner_type, a, b, index, part_width, code);
- *chain = tree_cons (NULL_TREE, result, NULL_TREE);
- chain = &TREE_CHAIN (*chain);
- }
-
- return build1 (CONSTRUCTOR, type, head);
-}
-
-/* Expand a vector operation to scalars with the freedom to use
- a scalar integer type, or to use a different size for the items
- in the vector type. */
-static tree
-expand_vector_parallel (block_stmt_iterator *bsi, elem_op_func f, tree type,
- tree a, tree b,
- enum tree_code code)
-{
- tree result, compute_type;
- enum machine_mode mode;
- int n_words = tree_low_cst (TYPE_SIZE_UNIT (type), 1) / UNITS_PER_WORD;
-
- /* We have three strategies. If the type is already correct, just do
- the operation an element at a time. Else, if the vector is wider than
- one word, do it a word at a time; finally, if the vector is smaller
- than one word, do it as a scalar. */
- if (TYPE_MODE (TREE_TYPE (type)) == word_mode)
- return expand_vector_piecewise (bsi, f,
- type, TREE_TYPE (type),
- a, b, code);
- else if (n_words > 1)
- {
- tree word_type = build_word_mode_vector_type (n_words);
- result = expand_vector_piecewise (bsi, f,
- word_type, TREE_TYPE (word_type),
- a, b, code);
- result = gimplify_val (bsi, word_type, result);
- }
- else
- {
- /* Use a single scalar operation with a mode no wider than word_mode. */
- mode = mode_for_size (tree_low_cst (TYPE_SIZE (type), 1), MODE_INT, 0);
- compute_type = lang_hooks.types.type_for_mode (mode, 1);
- result = f (bsi, compute_type, a, b, NULL_TREE, NULL_TREE, code);
- }
-
- return result;
-}
-
-/* Expand a vector operation to scalars; for integer types we can use
- special bit twiddling tricks to do the sums a word at a time, using
- function F_PARALLEL instead of F. These tricks are done only if
- they can process at least four items, that is, only if the vector
- holds at least four items and if a word can hold four items. */
-static tree
-expand_vector_addition (block_stmt_iterator *bsi,
- elem_op_func f, elem_op_func f_parallel,
- tree type, tree a, tree b, enum tree_code code)
-{
- int parts_per_word = UNITS_PER_WORD
- / tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (type)), 1);
-
- if (INTEGRAL_TYPE_P (TREE_TYPE (type))
- && parts_per_word >= 4
- && TYPE_VECTOR_SUBPARTS (type) >= 4)
- return expand_vector_parallel (bsi, f_parallel,
- type, a, b, code);
- else
- return expand_vector_piecewise (bsi, f,
- type, TREE_TYPE (type),
- a, b, code);
-}
-
-static tree
-expand_vector_operation (block_stmt_iterator *bsi, tree type, tree compute_type,
- tree rhs, enum tree_code code)
-{
- enum machine_mode compute_mode = TYPE_MODE (compute_type);
-
- /* If the compute mode is not a vector mode (hence we are not decomposing
- a BLKmode vector to smaller, hardware-supported vectors), we may want
- to expand the operations in parallel. */
- if (GET_MODE_CLASS (compute_mode) != MODE_VECTOR_INT
- && GET_MODE_CLASS (compute_mode) != MODE_VECTOR_FLOAT)
- switch (code)
- {
- case PLUS_EXPR:
- case MINUS_EXPR:
- if (!TYPE_TRAP_SIGNED (type))
- return expand_vector_addition (bsi, do_binop, do_plus_minus, type,
- TREE_OPERAND (rhs, 0),
- TREE_OPERAND (rhs, 1), code);
- break;
-
- case NEGATE_EXPR:
- if (!TYPE_TRAP_SIGNED (type))
- return expand_vector_addition (bsi, do_unop, do_negate, type,
- TREE_OPERAND (rhs, 0),
- NULL_TREE, code);
- break;
-
- case BIT_AND_EXPR:
- case BIT_IOR_EXPR:
- case BIT_XOR_EXPR:
- return expand_vector_parallel (bsi, do_binop, type,
- TREE_OPERAND (rhs, 0),
- TREE_OPERAND (rhs, 1), code);
-
- case BIT_NOT_EXPR:
- return expand_vector_parallel (bsi, do_unop, type,
- TREE_OPERAND (rhs, 0),
- NULL_TREE, code);
-
- default:
- break;
- }
-
- if (TREE_CODE_CLASS (code) == tcc_unary)
- return expand_vector_piecewise (bsi, do_unop, type, compute_type,
- TREE_OPERAND (rhs, 0),
- NULL_TREE, code);
- else
- return expand_vector_piecewise (bsi, do_binop, type, compute_type,
- TREE_OPERAND (rhs, 0),
- TREE_OPERAND (rhs, 1), code);
-}
-
-/* Return a type for the widest vector mode whose components are of mode
- INNER_MODE, or NULL_TREE if none is found. */
-static tree
-type_for_widest_vector_mode (enum machine_mode inner_mode, optab op)
-{
- enum machine_mode best_mode = VOIDmode, mode;
- int best_nunits = 0;
-
- if (GET_MODE_CLASS (inner_mode) == MODE_FLOAT)
- mode = MIN_MODE_VECTOR_FLOAT;
- else
- mode = MIN_MODE_VECTOR_INT;
-
- for (; mode != VOIDmode; mode = GET_MODE_WIDER_MODE (mode))
- if (GET_MODE_INNER (mode) == inner_mode
- && GET_MODE_NUNITS (mode) > best_nunits
- && op->handlers[mode].insn_code != CODE_FOR_nothing)
- best_mode = mode, best_nunits = GET_MODE_NUNITS (mode);
-
- if (best_mode == VOIDmode)
- return NULL_TREE;
- else
- return lang_hooks.types.type_for_mode (best_mode, 1);
-}
-
-/* Process one statement. If we identify a vector operation, expand it. */
-
-static void
-expand_vector_operations_1 (block_stmt_iterator *bsi)
-{
- tree stmt = bsi_stmt (*bsi);
- tree *p_lhs, *p_rhs, lhs, rhs, type, compute_type;
- enum tree_code code;
- enum machine_mode compute_mode;
- optab op;
-
- switch (TREE_CODE (stmt))
- {
- case RETURN_EXPR:
- stmt = TREE_OPERAND (stmt, 0);
- if (!stmt || TREE_CODE (stmt) != MODIFY_EXPR)
- return;
-
- /* FALLTHRU */
-
- case MODIFY_EXPR:
- p_lhs = &TREE_OPERAND (stmt, 0);
- p_rhs = &TREE_OPERAND (stmt, 1);
- lhs = *p_lhs;
- rhs = *p_rhs;
- break;
-
- default:
- return;
- }
-
- type = TREE_TYPE (rhs);
- if (TREE_CODE (type) != VECTOR_TYPE)
- return;
-
- code = TREE_CODE (rhs);
- if (TREE_CODE_CLASS (code) != tcc_unary
- && TREE_CODE_CLASS (code) != tcc_binary)
- return;
-
- if (code == NOP_EXPR || code == VIEW_CONVERT_EXPR)
- return;
-
- gcc_assert (code != CONVERT_EXPR);
- op = optab_for_tree_code (code, type);
-
- /* Optabs will try converting a negation into a subtraction, so
- look for it as well. TODO: negation of floating-point vectors
- might be turned into an exclusive OR toggling the sign bit. */
- if (op == NULL
- && code == NEGATE_EXPR
- && INTEGRAL_TYPE_P (TREE_TYPE (type)))
- op = optab_for_tree_code (MINUS_EXPR, type);
-
- /* For very wide vectors, try using a smaller vector mode. */
- compute_type = type;
- if (TYPE_MODE (type) == BLKmode && op)
- {
- tree vector_compute_type
- = type_for_widest_vector_mode (TYPE_MODE (TREE_TYPE (type)), op);
- if (vector_compute_type != NULL_TREE)
- compute_type = vector_compute_type;
- }
-
- /* If we are breaking a BLKmode vector into smaller pieces,
- type_for_widest_vector_mode has already looked into the optab,
- so skip these checks. */
- if (compute_type == type)
- {
- compute_mode = TYPE_MODE (compute_type);
- if ((GET_MODE_CLASS (compute_mode) == MODE_VECTOR_INT
- || GET_MODE_CLASS (compute_mode) == MODE_VECTOR_FLOAT)
- && op != NULL
- && op->handlers[compute_mode].insn_code != CODE_FOR_nothing)
- return;
- else
- /* There is no operation in hardware, so fall back to scalars. */
- compute_type = TREE_TYPE (type);
- }
-
- rhs = expand_vector_operation (bsi, type, compute_type, rhs, code);
- if (lang_hooks.types_compatible_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
- *p_rhs = rhs;
- else
- {
- /* Build a conversion; VIEW_CONVERT_EXPR is very expensive unless T will
- be stored in memory anyway, so prefer NOP_EXPR. We should also try
- performing the VIEW_CONVERT_EXPR on the left side of the
- assignment. */
- if (TYPE_MODE (TREE_TYPE (rhs)) == BLKmode)
- *p_rhs = gimplify_build1 (bsi, VIEW_CONVERT_EXPR, TREE_TYPE (lhs), rhs);
- else
- *p_rhs = gimplify_build1 (bsi, NOP_EXPR, TREE_TYPE (lhs), rhs);
- }
-
- mark_stmt_modified (bsi_stmt (*bsi));
-}
-
-/* Use this to lower vector operations introduced by the vectorizer,
- if it may need the bit-twiddling tricks implemented in this file. */
-
-static bool
-gate_expand_vector_operations (void)
-{
- return flag_tree_vectorize != 0;
-}
-
-static void
-expand_vector_operations (void)
-{
- block_stmt_iterator bsi;
- basic_block bb;
-
- FOR_EACH_BB (bb)
- {
- for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
- {
- expand_vector_operations_1 (&bsi);
- update_stmt_if_modified (bsi_stmt (bsi));
- }
- }
-}
static void
-tree_lower_operations (void)
+tree_lower_complex (void)
{
int old_last_basic_block = last_basic_block;
block_stmt_iterator bsi;
@@ -1029,42 +576,18 @@ tree_lower_operations (void)
if (bb->index >= old_last_basic_block)
continue;
for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
- {
- expand_complex_operations_1 (&bsi);
- expand_vector_operations_1 (&bsi);
- }
+ expand_complex_operations_1 (&bsi);
}
}
-struct tree_opt_pass pass_lower_vector_ssa =
+struct tree_opt_pass pass_lower_complex =
{
- "veclower", /* name */
- gate_expand_vector_operations, /* gate */
- NULL, NULL, /* IPA analysis */
- expand_vector_operations, /* execute */
- NULL, NULL, /* IPA modification */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- 0, /* tv_id */
- PROP_cfg, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_dump_func | TODO_update_ssa /* todo_flags_finish */
- | TODO_ggc_collect | TODO_verify_ssa
- | TODO_verify_stmts | TODO_verify_flow,
- 0 /* letter */
-};
-
-struct tree_opt_pass pass_pre_expand =
-{
- "oplower", /* name */
+ "cplxlower", /* name */
0, /* gate */
NULL, NULL, /* IPA analysis */
- tree_lower_operations, /* execute */
- NULL, NULL, /* IPA modification */
+ tree_lower_complex, /* execute */
+ NULL, NULL, /* IPA analysis */
NULL, /* sub */
NULL, /* next */
0, /* static_pass_number */
@@ -1077,5 +600,3 @@ struct tree_opt_pass pass_pre_expand =
| TODO_verify_stmts, /* todo_flags_finish */
0 /* letter */
};
-
-#include "gt-tree-complex.h"
diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c
index b1d160545bb..c1fdb8ff53a 100644
--- a/gcc/tree-data-ref.c
+++ b/gcc/tree-data-ref.c
@@ -78,7 +78,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "system.h"
#include "coretypes.h"
#include "tm.h"
-#include "errors.h"
#include "ggc.h"
#include "tree.h"
diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c
index 10159a78e69..785dace40b2 100644
--- a/gcc/tree-dfa.c
+++ b/gcc/tree-dfa.c
@@ -31,7 +31,6 @@ Boston, MA 02111-1307, USA. */
#include "hard-reg-set.h"
#include "basic-block.h"
#include "output.h"
-#include "errors.h"
#include "timevar.h"
#include "expr.h"
#include "ggc.h"
diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
index 10b8680ae72..9897b62f0ee 100644
--- a/gcc/tree-eh.c
+++ b/gcc/tree-eh.c
@@ -36,6 +36,7 @@ Boston, MA 02111-1307, USA. */
#include "timevar.h"
#include "langhooks.h"
#include "ggc.h"
+#include "toplev.h"
/* Nonzero if we are using EH to handle cleanups. */
@@ -1828,7 +1829,7 @@ verify_eh_edges (tree stmt)
{
if ((e->flags & EDGE_EH) && !e->aux)
{
- error ("Unnecesary EH edge %i->%i", bb->index, e->dest->index);
+ error ("Unnecessary EH edge %i->%i", bb->index, e->dest->index);
mark_eh_edge_found_error = true;
return true;
}
@@ -2011,29 +2012,31 @@ bool
tree_can_throw_internal (tree stmt)
{
int region_nr;
+ bool is_resx = false;
if (TREE_CODE (stmt) == RESX_EXPR)
- region_nr = TREE_INT_CST_LOW (TREE_OPERAND (stmt, 0));
+ region_nr = TREE_INT_CST_LOW (TREE_OPERAND (stmt, 0)), is_resx = true;
else
region_nr = lookup_stmt_eh_region (stmt);
if (region_nr < 0)
return false;
- return can_throw_internal_1 (region_nr);
+ return can_throw_internal_1 (region_nr, is_resx);
}
bool
tree_can_throw_external (tree stmt)
{
int region_nr;
+ bool is_resx = false;
if (TREE_CODE (stmt) == RESX_EXPR)
- region_nr = TREE_INT_CST_LOW (TREE_OPERAND (stmt, 0));
+ region_nr = TREE_INT_CST_LOW (TREE_OPERAND (stmt, 0)), is_resx = true;
else
region_nr = lookup_stmt_eh_region (stmt);
if (region_nr < 0)
return tree_could_throw_p (stmt);
else
- return can_throw_external_1 (region_nr);
+ return can_throw_external_1 (region_nr, is_resx);
}
/* Given a statement OLD_STMT and a new statement NEW_STMT that has replaced
diff --git a/gcc/tree-flow-inline.h b/gcc/tree-flow-inline.h
index 063d1a47e12..d7b0aa45b50 100644
--- a/gcc/tree-flow-inline.h
+++ b/gcc/tree-flow-inline.h
@@ -238,7 +238,7 @@ set_ssa_use_from_ptr (use_operand_p use, tree val)
link_imm_use (use, val);
}
-/* Link ssa_imm_use node LINKNODE into the chain for DEF, with use occuring
+/* Link ssa_imm_use node LINKNODE into the chain for DEF, with use occurring
in STMT. */
static inline void
link_imm_use_stmt (ssa_use_operand_t *linknode, tree def, tree stmt)
@@ -267,7 +267,7 @@ relink_imm_use (ssa_use_operand_t *node, ssa_use_operand_t *old)
}
}
-/* Relink ssa_imm_use node LINKNODE into the chain for OLD, with use occuring
+/* Relink ssa_imm_use node LINKNODE into the chain for OLD, with use occurring
in STMT. */
static inline void
relink_imm_use_stmt (ssa_use_operand_t *linknode, ssa_use_operand_t *old, tree stmt)
@@ -494,19 +494,12 @@ addresses_taken (tree stmt)
return ann ? ann->addresses_taken : NULL;
}
-/* Return the basic_block annotation for BB. */
-static inline bb_ann_t
-bb_ann (basic_block bb)
-{
- return (bb_ann_t)bb->tree_annotations;
-}
-
/* Return the PHI nodes for basic block BB, or NULL if there are no
PHI nodes. */
static inline tree
phi_nodes (basic_block bb)
{
- return bb_ann (bb)->phi_nodes;
+ return bb->phi_nodes;
}
/* Set list of phi nodes of a basic block BB to L. */
@@ -516,7 +509,7 @@ set_phi_nodes (basic_block bb, tree l)
{
tree phi;
- bb_ann (bb)->phi_nodes = l;
+ bb->phi_nodes = l;
for (phi = l; phi; phi = PHI_CHAIN (phi))
set_bb_for_stmt (phi, bb);
}
diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h
index 9f338f0b5ad..9f9a3cd92c4 100644
--- a/gcc/tree-flow.h
+++ b/gcc/tree-flow.h
@@ -84,34 +84,6 @@ struct ptr_info_def GTY(())
};
-/* Types of value ranges. */
-enum value_range_type { VR_UNDEFINED, VR_RANGE, VR_ANTI_RANGE, VR_VARYING };
-
-
-/* Ranges of values that can be associated with an SSA_NAME after VRP
- has executed. */
-struct value_range_def GTY(())
-{
- /* Lattice value represented by this range. */
- enum value_range_type type;
-
- /* Minimum and maximum values represented by this range. These
- values are _CST nodes that should be interpreted as follows:
-
- - If TYPE == VR_UNDEFINED then MIN and MAX must be NULL.
-
- - If TYPE == VR_RANGE then MIN holds the minimum value and
- MAX holds the maximum value of the range [MIN, MAX].
-
- - If TYPE == ANTI_RANGE the variable is known to NOT
- take any values in the range [MIN, MAX]. */
- tree min;
- tree max;
-};
-
-typedef struct value_range_def value_range;
-
-
/*---------------------------------------------------------------------------
Tree annotations stored in tree_common.ann
---------------------------------------------------------------------------*/
@@ -383,25 +355,7 @@ struct edge_prediction GTY((chain_next ("%h.next")))
int probability;
};
-/*---------------------------------------------------------------------------
- Block annotations stored in basic_block.tree_annotations
----------------------------------------------------------------------------*/
-struct bb_ann_d GTY(())
-{
- /* Chain of PHI nodes for this block. */
- tree phi_nodes;
-
- /* Nonzero if one or more incoming edges to this block should be threaded
- to an outgoing edge of this block. */
- unsigned incoming_edge_threaded : 1;
-
- struct edge_prediction *predictions;
-};
-
-typedef struct bb_ann_d *bb_ann_t;
-
/* Accessors for basic block annotations. */
-static inline bb_ann_t bb_ann (basic_block);
static inline tree phi_nodes (basic_block);
static inline void set_phi_nodes (basic_block, tree);
@@ -519,8 +473,6 @@ extern void debug_loop_ir (void);
extern void print_loop_ir (FILE *);
extern void cleanup_dead_labels (void);
extern void group_case_labels (void);
-extern bool cleanup_tree_cfg (void);
-extern void cleanup_tree_cfg_loop (void);
extern tree first_stmt (basic_block);
extern tree last_stmt (basic_block);
extern tree *last_stmt_ptr (basic_block);
@@ -553,6 +505,12 @@ extern tree gimplify_build3 (block_stmt_iterator *, enum tree_code,
extern void init_empty_tree_cfg (void);
extern void fold_cond_expr_cond (void);
extern void replace_uses_by (tree, tree);
+extern void start_recording_case_labels (void);
+extern void end_recording_case_labels (void);
+
+/* In tree-cfgcleanup.c */
+extern bool cleanup_tree_cfg (void);
+extern void cleanup_tree_cfg_loop (void);
/* In tree-pretty-print.c. */
extern void dump_generic_bb (FILE *, basic_block, int, int);
@@ -596,6 +554,7 @@ extern void debug_points_to_info_for (tree);
extern bool may_be_aliased (tree);
extern struct ptr_info_def *get_ptr_info (tree);
extern void add_type_alias (tree, tree);
+extern void new_type_alias (tree, tree);
extern void count_uses_and_derefs (tree, tree, unsigned *, unsigned *, bool *);
static inline subvar_t get_subvars_for_var (tree);
static inline bool ref_contains_array_ref (tree);
@@ -644,12 +603,8 @@ bool fold_stmt_inplace (tree);
tree widen_bitfield (tree, tree, tree);
/* In tree-vrp.c */
-value_range *get_value_range (tree);
-void dump_value_range (FILE *, value_range *);
-void debug_value_range (value_range *);
-void dump_all_value_ranges (FILE *);
-void debug_all_value_ranges (void);
bool expr_computes_nonzero (tree);
+tree vrp_evaluate_conditional (tree, bool);
/* In tree-ssa-dom.c */
extern void dump_dominator_optimization_stats (FILE *);
@@ -795,6 +750,9 @@ extern void linear_transform_loops (struct loops *);
/* In tree-ssa-loop-ivopts.c */
extern bool expr_invariant_in_loop_p (struct loop *, tree);
+/* In tree-ssa-threadupdate.c. */
+extern bool thread_through_all_blocks (bitmap);
+
/* In gimplify.c */
tree force_gimple_operand (tree, tree *, bool, tree);
tree force_gimple_operand_bsi (block_stmt_iterator *, tree, bool, tree);
diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c
index 5c7620143a9..78d5768d79a 100644
--- a/gcc/tree-if-conv.c
+++ b/gcc/tree-if-conv.c
@@ -84,7 +84,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "system.h"
#include "coretypes.h"
#include "tm.h"
-#include "errors.h"
#include "tree.h"
#include "c-common.h"
#include "flags.h"
@@ -840,7 +839,7 @@ process_phi_nodes (struct loop *loop)
release_phi_node (phi);
phi = next;
}
- bb_ann (bb)->phi_nodes = NULL;
+ bb->phi_nodes = NULL;
}
return;
}
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 62353ec3605..81e14ac9786 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -589,8 +589,6 @@ copy_body_r (tree *tp, int *walk_subtrees, void *data)
knows not to copy VAR_DECLs, etc., so this is safe. */
else
{
- tree old_node = *tp;
-
/* Here we handle trees that are not completely rewritten.
First we detect some inlining-induced bogosities for
discarding. */
@@ -628,7 +626,21 @@ copy_body_r (tree *tp, int *walk_subtrees, void *data)
n = splay_tree_lookup (id->decl_map, (splay_tree_key) decl);
if (n)
{
- *tp = build_fold_indirect_ref ((tree)n->value);
+ /* If we happen to get an ADDR_EXPR in n->value, strip
+ it manually here as we'll eventually get ADDR_EXPRs
+ which lie about their types pointed to. In this case
+ build_fold_indirect_ref wouldn't strip the INDIRECT_REF,
+ but we absolutely rely on that. As fold_indirect_ref
+ does other useful transformations, try that first, though. */
+ tree type = TREE_TYPE (TREE_TYPE ((tree)n->value));
+ *tp = fold_indirect_ref_1 (type, (tree)n->value);
+ if (! *tp)
+ {
+ if (TREE_CODE ((tree)n->value) == ADDR_EXPR)
+ *tp = TREE_OPERAND ((tree)n->value, 0);
+ else
+ *tp = build1 (INDIRECT_REF, type, (tree)n->value);
+ }
*walk_subtrees = 0;
return NULL;
}
@@ -644,57 +656,7 @@ copy_body_r (tree *tp, int *walk_subtrees, void *data)
&& IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (*tp))))
TREE_BLOCK (*tp) = id->block;
- /* We're duplicating a CALL_EXPR. Find any corresponding
- callgraph edges and update or duplicate them. */
- if (TREE_CODE (*tp) == CALL_EXPR
- && id->node
- && get_callee_fndecl (*tp))
- {
- if (id->saving_p)
- {
- struct cgraph_node *node;
- struct cgraph_edge *edge;
-
- /* We're saving a copy of the body, so we'll update the
- callgraph nodes in place. Note that we avoid
- altering the original callgraph node; we begin with
- the first clone. */
- for (node = id->node->next_clone;
- node;
- node = node->next_clone)
- {
- edge = cgraph_edge (node, old_node);
- gcc_assert (edge);
- edge->call_expr = *tp;
- }
- }
- else
- {
- struct cgraph_edge *edge;
-
- /* We're cloning or inlining this body; duplicate the
- associate callgraph nodes. */
- if (!id->versioning_p)
- {
- edge = cgraph_edge (id->current_node, old_node);
- if (edge)
- cgraph_clone_edge (edge, id->node, *tp,
- REG_BR_PROB_BASE, 1);
- }
- }
- if (id->versioning_p)
- {
- /* Update the call_expr on the edges from the new versions
- to it's callees. */
- struct cgraph_edge *edge;
- tree callee;
- callee = get_callee_fndecl (*tp);
- edge = cgraph_edge (id->node, old_node);
- if (edge)
- edge->call_expr = *tp;
- }
- }
- else if (TREE_CODE (*tp) == RESX_EXPR && id->eh_region_offset)
+ if (TREE_CODE (*tp) == RESX_EXPR && id->eh_region_offset)
TREE_OPERAND (*tp, 0) =
build_int_cst
(NULL_TREE,
@@ -754,7 +716,52 @@ copy_bb (inline_data *id, basic_block bb, int frequency_scale, int count_scale)
this is signalled by making stmt pointer NULL. */
if (stmt)
{
+ tree call, decl;
bsi_insert_after (&copy_bsi, stmt, BSI_NEW_STMT);
+ call = get_call_expr_in (stmt);
+ /* We're duplicating a CALL_EXPR. Find any corresponding
+ callgraph edges and update or duplicate them. */
+ if (call && (decl = get_callee_fndecl (call)))
+ {
+ if (id->saving_p)
+ {
+ struct cgraph_node *node;
+ struct cgraph_edge *edge;
+
+ /* We're saving a copy of the body, so we'll update the
+ callgraph nodes in place. Note that we avoid
+ altering the original callgraph node; we begin with
+ the first clone. */
+ for (node = id->node->next_clone;
+ node;
+ node = node->next_clone)
+ {
+ edge = cgraph_edge (node, orig_stmt);
+ gcc_assert (edge);
+ edge->call_stmt = stmt;
+ }
+ }
+ else if (!id->versioning_p)
+ {
+ struct cgraph_edge *edge;
+
+ /* We're cloning or inlining this body; duplicate the
+ associate callgraph nodes. */
+ edge = cgraph_edge (id->current_node, orig_stmt);
+ if (edge)
+ cgraph_clone_edge (edge, id->node, stmt,
+ REG_BR_PROB_BASE, 1);
+ }
+ else
+ {
+ /* Update the call_expr on the edges from the new versions
+ to it's callees. */
+ struct cgraph_edge *edge;
+ edge = cgraph_edge (id->node, orig_stmt);
+ if (edge)
+ edge->call_stmt = stmt;
+ }
+ }
/* If you think we can abort here, you are wrong.
There is no region 0 in tree land. */
gcc_assert (lookup_stmt_eh_region_fn (id->callee_cfun, orig_stmt)
@@ -800,24 +807,24 @@ copy_edges_for_bb (basic_block bb, int count_scale)
/* Use the indices from the original blocks to create edges for the
new ones. */
FOR_EACH_EDGE (old_edge, ei, bb->succs)
- {
- edge new;
+ if (!(old_edge->flags & EDGE_EH))
+ {
+ edge new;
- flags = old_edge->flags;
+ flags = old_edge->flags;
- /* Return edges do get a FALLTHRU flag when the get inlined. */
- if (old_edge->dest->index == EXIT_BLOCK && !old_edge->flags
- && old_edge->dest->aux != EXIT_BLOCK_PTR)
- flags |= EDGE_FALLTHRU;
- new = make_edge (new_bb, old_edge->dest->aux, flags);
- new->count = old_edge->count * count_scale / REG_BR_PROB_BASE;
- new->probability = old_edge->probability;
- }
+ /* Return edges do get a FALLTHRU flag when the get inlined. */
+ if (old_edge->dest->index == EXIT_BLOCK && !old_edge->flags
+ && old_edge->dest->aux != EXIT_BLOCK_PTR)
+ flags |= EDGE_FALLTHRU;
+ new = make_edge (new_bb, old_edge->dest->aux, flags);
+ new->count = old_edge->count * count_scale / REG_BR_PROB_BASE;
+ new->probability = old_edge->probability;
+ }
if (bb->index == ENTRY_BLOCK || bb->index == EXIT_BLOCK)
return;
- tree_purge_dead_eh_edges (new_bb);
for (bsi = bsi_start (new_bb); !bsi_end_p (bsi);)
{
tree copy_stmt;
@@ -839,9 +846,7 @@ copy_edges_for_bb (basic_block bb, int count_scale)
into a COMPONENT_REF which doesn't. If the copy
can throw, the original could also throw. */
- if (TREE_CODE (copy_stmt) == RESX_EXPR
- || (tree_could_throw_p (copy_stmt)
- && lookup_stmt_eh_region (copy_stmt) > 0))
+ if (tree_can_throw_internal (copy_stmt))
{
if (!bsi_end_p (bsi))
/* Note that bb's predecessor edges aren't necessarily
@@ -1839,28 +1844,25 @@ estimate_num_insns (tree expr)
return num;
}
+typedef struct function *function_p;
+
+DEF_VEC_P(function_p);
+DEF_VEC_ALLOC_P(function_p,heap);
+
/* Initialized with NOGC, making this poisonous to the garbage collector. */
-static varray_type cfun_stack;
+static VEC(function_p,heap) *cfun_stack;
void
push_cfun (struct function *new_cfun)
{
- static bool initialized = false;
-
- if (!initialized)
- {
- VARRAY_GENERIC_PTR_NOGC_INIT (cfun_stack, 20, "cfun_stack");
- initialized = true;
- }
- VARRAY_PUSH_GENERIC_PTR (cfun_stack, cfun);
+ VEC_safe_push (function_p, heap, cfun_stack, cfun);
cfun = new_cfun;
}
void
pop_cfun (void)
{
- cfun = (struct function *)VARRAY_TOP_GENERIC_PTR (cfun_stack);
- VARRAY_POP (cfun_stack);
+ cfun = VEC_pop (function_p, cfun_stack);
}
/* Install new lexical TREE_BLOCK underneath 'current_block'. */
@@ -1944,7 +1946,7 @@ expand_call_inline (basic_block bb, tree stmt, tree *tp, void *data)
if (!id->current_node->analyzed)
goto egress;
- cg_edge = cgraph_edge (id->current_node, t);
+ cg_edge = cgraph_edge (id->current_node, stmt);
/* Constant propagation on argument done during previous inlining
may create new direct call. Produce an edge for it. */
@@ -1957,7 +1959,7 @@ expand_call_inline (basic_block bb, tree stmt, tree *tp, void *data)
constant propagating arguments. In all other cases we hit a bug
(incorrect node sharing is most common reason for missing edges. */
gcc_assert (dest->needed || !flag_unit_at_a_time);
- cgraph_create_edge (id->node, dest, t,
+ cgraph_create_edge (id->node, dest, stmt,
bb->count, bb->loop_depth)->inline_failed
= N_("originally indirect function call not considered for inlining");
goto egress;
diff --git a/gcc/tree-into-ssa.c b/gcc/tree-into-ssa.c
index 1569b40eb57..dc68eb9676d 100644
--- a/gcc/tree-into-ssa.c
+++ b/gcc/tree-into-ssa.c
@@ -31,7 +31,6 @@ Boston, MA 02111-1307, USA. */
#include "hard-reg-set.h"
#include "basic-block.h"
#include "output.h"
-#include "errors.h"
#include "expr.h"
#include "function.h"
#include "diagnostic.h"
@@ -107,8 +106,8 @@ static VEC(tree,heap) *block_defs_stack;
/* Basic block vectors used in this file ought to be allocated in the
heap. We use pointer vector, because ints can be easily passed by
value. */
-DEF_VEC_P(int);
-DEF_VEC_ALLOC_P(int,heap);
+DEF_VEC_I(int);
+DEF_VEC_ALLOC_I(int,heap);
/* Set of existing SSA names being replaced by update_ssa. */
static sbitmap old_ssa_names;
@@ -2681,6 +2680,10 @@ update_ssa (unsigned update_flags)
for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
{
tree stmt = bsi_stmt (si);
+ /* We are going to use the operand cache API, such as
+ SET_USE, SET_DEF, and FOR_EACH_IMM_USE_FAST. The operand
+ cache for each statement should be up-to-date. */
+ gcc_assert (!stmt_modified_p (stmt));
REWRITE_THIS_STMT (stmt) = 0;
REGISTER_DEFS_IN_THIS_STMT (stmt) = 0;
}
diff --git a/gcc/tree-loop-linear.c b/gcc/tree-loop-linear.c
index 5c289964774..741c95df4d2 100644
--- a/gcc/tree-loop-linear.c
+++ b/gcc/tree-loop-linear.c
@@ -24,7 +24,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "system.h"
#include "coretypes.h"
#include "tm.h"
-#include "errors.h"
#include "ggc.h"
#include "tree.h"
#include "target.h"
diff --git a/gcc/tree-mudflap.c b/gcc/tree-mudflap.c
index b0f3d5258a9..60e181a76cf 100644
--- a/gcc/tree-mudflap.c
+++ b/gcc/tree-mudflap.c
@@ -22,7 +22,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
-#include "errors.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
@@ -45,6 +44,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "langhooks.h"
#include "ggc.h"
#include "cgraph.h"
+#include "toplev.h"
/* Internal function decls */
diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c
index 124bbf98cfb..2f9985dcfac 100644
--- a/gcc/tree-nested.c
+++ b/gcc/tree-nested.c
@@ -871,9 +871,14 @@ convert_nonlocal_reference (tree *tp, int *walk_subtrees, void *data)
if (wi->changed)
{
+ tree save_context;
+
/* If we changed anything, then TREE_INVARIANT is be wrong,
since we're no longer directly referencing a decl. */
+ save_context = current_function_decl;
+ current_function_decl = info->context;
recompute_tree_invarant_for_addr_expr (t);
+ current_function_decl = save_context;
/* If the callback converted the address argument in a context
where we only accept variables (and min_invariant, presumably),
@@ -996,10 +1001,15 @@ convert_local_reference (tree *tp, int *walk_subtrees, void *data)
/* If we converted anything ... */
if (wi->changed)
{
+ tree save_context;
+
/* Then the frame decl is now addressable. */
TREE_ADDRESSABLE (info->frame_decl) = 1;
+ save_context = current_function_decl;
+ current_function_decl = info->context;
recompute_tree_invarant_for_addr_expr (t);
+ current_function_decl = save_context;
/* If we are in a context where we only accept values, then
compute the address into a temporary. */
diff --git a/gcc/tree-nomudflap.c b/gcc/tree-nomudflap.c
index f4290c43f83..47b201272cb 100644
--- a/gcc/tree-nomudflap.c
+++ b/gcc/tree-nomudflap.c
@@ -21,7 +21,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "config.h"
-#include "errors.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
@@ -38,6 +37,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "tree-mudflap.h"
#include "tree-pass.h"
#include "ggc.h"
+#include "toplev.h"
diff --git a/gcc/tree-optimize.c b/gcc/tree-optimize.c
index 7419e8620dc..a552f2361e8 100644
--- a/gcc/tree-optimize.c
+++ b/gcc/tree-optimize.c
@@ -477,7 +477,8 @@ init_tree_optimization_passes (void)
NEXT_PASS (pass_lower_cf);
NEXT_PASS (pass_lower_eh);
NEXT_PASS (pass_build_cfg);
- NEXT_PASS (pass_pre_expand);
+ NEXT_PASS (pass_lower_complex);
+ NEXT_PASS (pass_lower_vector);
NEXT_PASS (pass_warn_function_return);
NEXT_PASS (pass_tree_profile);
NEXT_PASS (pass_cleanup_cfg);
@@ -619,6 +620,9 @@ init_tree_optimization_passes (void)
NEXT_PASS (pass_iv_canon);
NEXT_PASS (pass_if_conversion);
NEXT_PASS (pass_vectorize);
+ /* NEXT_PASS (pass_may_alias) cannot be done again because the
+ vectorizer creates alias relations that are not supported by
+ pass_may_alias. */
NEXT_PASS (pass_lower_vector_ssa);
NEXT_PASS (pass_complete_unroll);
NEXT_PASS (pass_iv_optimize);
diff --git a/gcc/tree-outof-ssa.c b/gcc/tree-outof-ssa.c
index 0d9e591268c..2606ef55389 100644
--- a/gcc/tree-outof-ssa.c
+++ b/gcc/tree-outof-ssa.c
@@ -32,7 +32,6 @@ Boston, MA 02111-1307, USA. */
#include "hard-reg-set.h"
#include "basic-block.h"
#include "output.h"
-#include "errors.h"
#include "expr.h"
#include "function.h"
#include "diagnostic.h"
@@ -46,6 +45,7 @@ Boston, MA 02111-1307, USA. */
#include "tree-dump.h"
#include "tree-ssa-live.h"
#include "tree-pass.h"
+#include "toplev.h"
/* Flags to pass to remove_ssa_form. */
@@ -53,6 +53,9 @@ Boston, MA 02111-1307, USA. */
#define SSANORM_COMBINE_TEMPS 0x2
#define SSANORM_COALESCE_PARTITIONS 0x4
+DEF_VEC_I(int);
+DEF_VEC_ALLOC_I(int,heap);
+
/* Used to hold all the components required to do SSA PHI elimination.
The node and pred/succ list is a simple linear list of nodes and
edges represented as pairs of nodes.
@@ -82,7 +85,7 @@ typedef struct _elim_graph {
VEC(tree,heap) *nodes;
/* The predecessor and successor edge list. */
- varray_type edge_list;
+ VEC(int,heap) *edge_list;
/* Visited vector. */
sbitmap visited;
@@ -155,14 +158,14 @@ create_temp (tree t)
name = "temp";
tmp = create_tmp_var (type, name);
- if (DECL_DEBUG_EXPR (t) && DECL_DEBUG_EXPR_IS_FROM (t))
+ if (DECL_DEBUG_EXPR_IS_FROM (t) && DECL_DEBUG_EXPR (t))
{
- DECL_DEBUG_EXPR (tmp) = DECL_DEBUG_EXPR (t);
+ SET_DECL_DEBUG_EXPR (tmp, DECL_DEBUG_EXPR (t));
DECL_DEBUG_EXPR_IS_FROM (tmp) = 1;
}
else if (!DECL_IGNORED_P (t))
{
- DECL_DEBUG_EXPR (tmp) = t;
+ SET_DECL_DEBUG_EXPR (tmp, t);
DECL_DEBUG_EXPR_IS_FROM (tmp) = 1;
}
DECL_ARTIFICIAL (tmp) = DECL_ARTIFICIAL (t);
@@ -220,7 +223,7 @@ new_elim_graph (int size)
g->nodes = VEC_alloc (tree, heap, 30);
g->const_copies = VEC_alloc (tree, heap, 20);
- VARRAY_INT_INIT (g->edge_list, 20, "Elimination Edge List");
+ g->edge_list = VEC_alloc (int, heap, 20);
VARRAY_INT_INIT (g->stack, 30, " Elimination Stack");
g->visited = sbitmap_alloc (size);
@@ -235,7 +238,7 @@ static inline void
clear_elim_graph (elim_graph g)
{
VEC_truncate (tree, g->nodes, 0);
- VARRAY_POP_ALL (g->edge_list);
+ VEC_truncate (int, g->edge_list, 0);
}
@@ -245,6 +248,7 @@ static inline void
delete_elim_graph (elim_graph g)
{
sbitmap_free (g->visited);
+ VEC_free (int, heap, g->edge_list);
VEC_free (tree, heap, g->const_copies);
VEC_free (tree, heap, g->nodes);
free (g);
@@ -280,8 +284,8 @@ elim_graph_add_node (elim_graph g, tree node)
static inline void
elim_graph_add_edge (elim_graph g, int pred, int succ)
{
- VARRAY_PUSH_INT (g->edge_list, pred);
- VARRAY_PUSH_INT (g->edge_list, succ);
+ VEC_safe_push (int, heap, g->edge_list, pred);
+ VEC_safe_push (int, heap, g->edge_list, succ);
}
@@ -293,12 +297,12 @@ elim_graph_remove_succ_edge (elim_graph g, int node)
{
int y;
unsigned x;
- for (x = 0; x < VARRAY_ACTIVE_SIZE (g->edge_list); x += 2)
- if (VARRAY_INT (g->edge_list, x) == node)
+ for (x = 0; x < VEC_length (int, g->edge_list); x += 2)
+ if (VEC_index (int, g->edge_list, x) == node)
{
- VARRAY_INT (g->edge_list, x) = -1;
- y = VARRAY_INT (g->edge_list, x + 1);
- VARRAY_INT (g->edge_list, x + 1) = -1;
+ VEC_replace (int, g->edge_list, x, -1);
+ y = VEC_index (int, g->edge_list, x + 1);
+ VEC_replace (int, g->edge_list, x + 1, -1);
return y;
}
return -1;
@@ -313,12 +317,12 @@ elim_graph_remove_succ_edge (elim_graph g, int node)
do { \
unsigned x_; \
int y_; \
- for (x_ = 0; x_ < VARRAY_ACTIVE_SIZE ((GRAPH)->edge_list); x_ += 2) \
+ for (x_ = 0; x_ < VEC_length (int, (GRAPH)->edge_list); x_ += 2) \
{ \
- y_ = VARRAY_INT ((GRAPH)->edge_list, x_); \
+ y_ = VEC_index (int, (GRAPH)->edge_list, x_); \
if (y_ != (NODE)) \
continue; \
- (VAR) = VARRAY_INT ((GRAPH)->edge_list, x_ + 1); \
+ (VAR) = VEC_index (int, (GRAPH)->edge_list, x_ + 1); \
CODE; \
} \
} while (0)
@@ -332,12 +336,12 @@ do { \
do { \
unsigned x_; \
int y_; \
- for (x_ = 0; x_ < VARRAY_ACTIVE_SIZE ((GRAPH)->edge_list); x_ += 2) \
+ for (x_ = 0; x_ < VEC_length (int, (GRAPH)->edge_list); x_ += 2) \
{ \
- y_ = VARRAY_INT ((GRAPH)->edge_list, x_ + 1); \
+ y_ = VEC_index (int, (GRAPH)->edge_list, x_ + 1); \
if (y_ != (NODE)) \
continue; \
- (VAR) = VARRAY_INT ((GRAPH)->edge_list, x_); \
+ (VAR) = VEC_index (int, (GRAPH)->edge_list, x_); \
CODE; \
} \
} while (0)
diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
index 874e62a1403..1e638e4e993 100644
--- a/gcc/tree-pass.h
+++ b/gcc/tree-pass.h
@@ -147,7 +147,7 @@ struct dump_file_info
chains for virtuals (e.g., DCE). */
#define TODO_update_ssa_no_phi (1 << 8)
-/* Insert PHI nodes everywhere they are needed. No prunning of the
+/* Insert PHI nodes everywhere they are needed. No pruning of the
IDF is done. This is used by passes that need the PHI nodes for
O_j even if it means that some arguments will come from the default
definition of O_j's symbol (e.g., pass_linear_transform).
@@ -217,7 +217,8 @@ extern struct tree_opt_pass pass_may_alias;
extern struct tree_opt_pass pass_split_crit_edges;
extern struct tree_opt_pass pass_pre;
extern struct tree_opt_pass pass_profile;
-extern struct tree_opt_pass pass_pre_expand;
+extern struct tree_opt_pass pass_lower_complex;
+extern struct tree_opt_pass pass_lower_vector;
extern struct tree_opt_pass pass_lower_vector_ssa;
extern struct tree_opt_pass pass_fold_builtins;
extern struct tree_opt_pass pass_stdarg;
diff --git a/gcc/tree-phinodes.c b/gcc/tree-phinodes.c
index ca01c8c52d1..7faedc907be 100644
--- a/gcc/tree-phinodes.c
+++ b/gcc/tree-phinodes.c
@@ -314,7 +314,7 @@ reserve_phi_args_for_new_edge (basic_block bb)
int len = EDGE_COUNT (bb->preds);
int cap = ideal_phi_node_len (len + 4);
- for (loc = &(bb_ann (bb)->phi_nodes);
+ for (loc = &(bb->phi_nodes);
*loc;
loc = &PHI_CHAIN (*loc))
{
@@ -354,7 +354,7 @@ create_phi_node (tree var, basic_block bb)
/* Add the new PHI node to the list of PHI nodes for block BB. */
PHI_CHAIN (phi) = phi_nodes (bb);
- bb_ann (bb)->phi_nodes = phi;
+ bb->phi_nodes = phi;
/* Associate BB to the PHI node. */
set_bb_for_stmt (phi, bb);
@@ -450,7 +450,7 @@ remove_phi_node (tree phi, tree prev)
}
else
{
- for (loc = &(bb_ann (bb_for_stmt (phi))->phi_nodes);
+ for (loc = &(bb_for_stmt (phi)->phi_nodes);
*loc != phi;
loc = &PHI_CHAIN (*loc))
;
diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c
index 39b433023f4..0c5d4e8750c 100644
--- a/gcc/tree-pretty-print.c
+++ b/gcc/tree-pretty-print.c
@@ -23,7 +23,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "system.h"
#include "coretypes.h"
#include "tm.h"
-#include "errors.h"
#include "tree.h"
#include "diagnostic.h"
#include "real.h"
@@ -2354,8 +2353,7 @@ dump_generic_bb_buff (pretty_printer *buffer, basic_block bb,
dump_bb_header (buffer, bb, indent, flags);
- if (bb_ann (bb))
- dump_phi_nodes (buffer, bb, indent, flags);
+ dump_phi_nodes (buffer, bb, indent, flags);
for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
{
diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c
index 4ff50e61890..82cbc2f6b82 100644
--- a/gcc/tree-scalar-evolution.c
+++ b/gcc/tree-scalar-evolution.c
@@ -235,7 +235,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "system.h"
#include "coretypes.h"
#include "tm.h"
-#include "errors.h"
#include "ggc.h"
#include "tree.h"
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index d9c50b78b32..cc9550db58a 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -25,7 +25,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "system.h"
#include "coretypes.h"
#include "tm.h"
-#include "errors.h"
#include "ggc.h"
#include "tree.h"
@@ -1126,9 +1125,9 @@ instantiate_element (struct sra_elt *elt)
DECL_NAME (var) = get_identifier (pretty_name);
obstack_free (&sra_obstack, pretty_name);
- DECL_DEBUG_EXPR (var) = generate_element_ref (elt);
+ SET_DECL_DEBUG_EXPR (var, generate_element_ref (elt));
DECL_DEBUG_EXPR_IS_FROM (var) = 1;
-
+
DECL_IGNORED_P (var) = 0;
TREE_NO_WARNING (var) = TREE_NO_WARNING (base);
}
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index 18b519b0328..abcf629af8a 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -2853,6 +2853,39 @@ found_tag:
}
+/* Create a type tag for PTR. Construct the may-alias list of this type tag
+ so that it has the aliasing of VAR. */
+
+void
+new_type_alias (tree ptr, tree var)
+{
+ var_ann_t p_ann = var_ann (ptr);
+ tree tag_type = TREE_TYPE (TREE_TYPE (ptr));
+ var_ann_t v_ann = var_ann (var);
+ tree tag;
+ subvar_t svars;
+
+ gcc_assert (p_ann->type_mem_tag == NULL_TREE);
+ gcc_assert (v_ann->mem_tag_kind == NOT_A_TAG);
+ tag = create_memory_tag (tag_type, true);
+ p_ann->type_mem_tag = tag;
+
+ /* Add VAR to the may-alias set of PTR's new type tag. If VAR has
+ subvars, add the subvars to the tag instead of the actual var. */
+ if (var_can_have_subvars (var)
+ && (svars = get_subvars_for_var (var)))
+ {
+ subvar_t sv;
+ for (sv = svars; sv; sv = sv->next)
+ add_may_alias (tag, sv->var);
+ }
+ else
+ add_may_alias (tag, var);
+
+ /* Note, TAG and its set of aliases are not marked for renaming. */
+}
+
+
/* This structure is simply used during pushing fields onto the fieldstack
to track the offset of the field, since bitpos_of_field gives it relative
to its immediate containing type, and we want it relative to the ultimate
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index b1de12d6d2c..930b949d1cd 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -199,7 +199,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "ggc.h"
#include "basic-block.h"
#include "output.h"
-#include "errors.h"
#include "expr.h"
#include "function.h"
#include "diagnostic.h"
@@ -228,7 +227,7 @@ typedef enum
(i.e., a V_MAY_DEF or V_MUST_DEF), CONST_VAL[I].MEM_REF will
contain the actual memory reference used to store (i.e., the LHS of
the assignment doing the store). */
-prop_value_t *const_val;
+static prop_value_t *const_val;
/* True if we are also propagating constants in stores and loads. */
static bool do_store_ccp;
@@ -581,7 +580,7 @@ static void
ccp_finalize (void)
{
/* Perform substitutions based on the known constant values. */
- substitute_and_fold (const_val);
+ substitute_and_fold (const_val, false);
free (const_val);
}
@@ -849,27 +848,7 @@ ccp_fold (tree stmt)
op0 = get_value (op0, true)->value;
}
- retval = fold_unary_to_constant (code, TREE_TYPE (rhs), op0);
-
- /* If we folded, but did not create an invariant, then we can not
- use this expression. */
- if (retval && ! is_gimple_min_invariant (retval))
- return NULL;
-
- /* If we could not fold the expression, but the arguments are all
- constants and gimple values, then build and return the new
- expression.
-
- In some cases the new expression is still something we can
- use as a replacement for an argument. This happens with
- NOP conversions of types for example.
-
- In other cases the new expression can not be used as a
- replacement for an argument (as it would create non-gimple
- code). But the new expression can still be used to derive
- other constants. */
- if (! retval && is_gimple_min_invariant (op0))
- return build1 (code, TREE_TYPE (rhs), op0);
+ return fold_unary (code, TREE_TYPE (rhs), op0);
}
/* Binary and comparison operators. We know one or both of the
@@ -900,29 +879,7 @@ ccp_fold (tree stmt)
op1 = val->value;
}
- retval = fold_binary_to_constant (code, TREE_TYPE (rhs), op0, op1);
-
- /* If we folded, but did not create an invariant, then we can not
- use this expression. */
- if (retval && ! is_gimple_min_invariant (retval))
- return NULL;
-
- /* If we could not fold the expression, but the arguments are all
- constants and gimple values, then build and return the new
- expression.
-
- In some cases the new expression is still something we can
- use as a replacement for an argument. This happens with
- NOP conversions of types for example.
-
- In other cases the new expression can not be used as a
- replacement for an argument (as it would create non-gimple
- code). But the new expression can still be used to derive
- other constants. */
- if (! retval
- && is_gimple_min_invariant (op0)
- && is_gimple_min_invariant (op1))
- return build (code, TREE_TYPE (rhs), op0, op1);
+ return fold_binary (code, TREE_TYPE (rhs), op0, op1);
}
/* We may be able to fold away calls to builtin functions if their
diff --git a/gcc/tree-ssa-copy.c b/gcc/tree-ssa-copy.c
index 6affd0470ac..b57f74cbe05 100644
--- a/gcc/tree-ssa-copy.c
+++ b/gcc/tree-ssa-copy.c
@@ -29,7 +29,6 @@ Boston, MA 02111-1307, USA. */
#include "ggc.h"
#include "basic-block.h"
#include "output.h"
-#include "errors.h"
#include "expr.h"
#include "function.h"
#include "diagnostic.h"
@@ -475,24 +474,31 @@ static void
dump_copy_of (FILE *dump_file, tree var)
{
tree val;
+ sbitmap visited;
print_generic_expr (dump_file, var, dump_flags);
if (TREE_CODE (var) != SSA_NAME)
return;
-
+
+ visited = sbitmap_alloc (num_ssa_names);
+ sbitmap_zero (visited);
+ SET_BIT (visited, SSA_NAME_VERSION (var));
+
fprintf (dump_file, " copy-of chain: ");
val = var;
print_generic_expr (dump_file, val, 0);
fprintf (dump_file, " ");
- while (copy_of[SSA_NAME_VERSION (val)].value
- && copy_of[SSA_NAME_VERSION (val)].value != val)
+ while (copy_of[SSA_NAME_VERSION (val)].value)
{
fprintf (dump_file, "-> ");
val = copy_of[SSA_NAME_VERSION (val)].value;
print_generic_expr (dump_file, val, 0);
fprintf (dump_file, " ");
+ if (TEST_BIT (visited, SSA_NAME_VERSION (val)))
+ break;
+ SET_BIT (visited, SSA_NAME_VERSION (val));
}
val = get_copy_of_val (var)->value;
@@ -502,6 +508,8 @@ dump_copy_of (FILE *dump_file, tree var)
fprintf (dump_file, "[COPY]");
else
fprintf (dump_file, "[NOT A COPY]");
+
+ sbitmap_free (visited);
}
@@ -887,7 +895,7 @@ fini_copy_prop (void)
copy_of[i].value = get_last_copy_of (var);
}
- substitute_and_fold (copy_of);
+ substitute_and_fold (copy_of, false);
free (cached_last_copy_of);
free (copy_of);
diff --git a/gcc/tree-ssa-copyrename.c b/gcc/tree-ssa-copyrename.c
index 5d1b6e0ff5f..ad4335f156d 100644
--- a/gcc/tree-ssa-copyrename.c
+++ b/gcc/tree-ssa-copyrename.c
@@ -253,7 +253,7 @@ copy_rename_partition_coalesce (var_map map, tree var1, tree var2, FILE *debug)
!= get_alias_set (TREE_TYPE (TREE_TYPE (root2))))
{
if (debug)
- fprintf (debug, " : 2 different alasing sets. No coalesce.\n");
+ fprintf (debug, " : 2 different aliasing sets. No coalesce.\n");
return;
}
diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c
index 3faa0cdc4bc..b816a22e3f9 100644
--- a/gcc/tree-ssa-dce.c
+++ b/gcc/tree-ssa-dce.c
@@ -47,7 +47,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "system.h"
#include "coretypes.h"
#include "tm.h"
-#include "errors.h"
#include "ggc.h"
/* These RTL headers are needed for basic-block.h. */
diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c
index 6c07c90c84f..90e64016c11 100644
--- a/gcc/tree-ssa-dom.c
+++ b/gcc/tree-ssa-dom.c
@@ -31,7 +31,6 @@ Boston, MA 02111-1307, USA. */
#include "basic-block.h"
#include "cfgloop.h"
#include "output.h"
-#include "errors.h"
#include "expr.h"
#include "function.h"
#include "diagnostic.h"
@@ -141,6 +140,10 @@ static VEC(tree,heap) *const_and_copies_stack;
know their exact value. */
static bitmap nonzero_vars;
+/* Bitmap of blocks that are scheduled to be threaded through. This
+ is used to communicate with thread_through_blocks. */
+static bitmap threaded_blocks;
+
/* Stack of SSA_NAMEs which need their NONZERO_VARS property cleared
when the current block is finalized.
@@ -224,12 +227,17 @@ struct vrp_element
with useful information is very low. */
static htab_t vrp_data;
+typedef struct vrp_element *vrp_element_p;
+
+DEF_VEC_P(vrp_element_p);
+DEF_VEC_ALLOC_P(vrp_element_p,heap);
+
/* An entry in the VRP_DATA hash table. We record the variable and a
varray of VRP_ELEMENT records associated with that variable. */
struct vrp_hash_elt
{
tree var;
- varray_type records;
+ VEC(vrp_element_p,heap) *records;
};
/* Array of variables which have their values constrained by operations
@@ -346,6 +354,18 @@ free_all_edge_infos (void)
}
}
+/* Free an instance of vrp_hash_elt. */
+
+static void
+vrp_free (void *data)
+{
+ struct vrp_hash_elt *elt = data;
+ struct VEC(vrp_element_p,heap) **vrp_elt = &elt->records;
+
+ VEC_free (vrp_element_p, heap, *vrp_elt);
+ free (elt);
+}
+
/* Jump threading, redundancy elimination and const/copy propagation.
This pass may expose new symbols that need to be renamed into SSA. For
@@ -363,13 +383,15 @@ tree_ssa_dominator_optimize (void)
/* Create our hash tables. */
avail_exprs = htab_create (1024, real_avail_expr_hash, avail_expr_eq, free);
- vrp_data = htab_create (ceil_log2 (num_ssa_names), vrp_hash, vrp_eq, free);
+ vrp_data = htab_create (ceil_log2 (num_ssa_names), vrp_hash, vrp_eq,
+ vrp_free);
avail_exprs_stack = VEC_alloc (tree, heap, 20);
const_and_copies_stack = VEC_alloc (tree, heap, 20);
nonzero_vars_stack = VEC_alloc (tree, heap, 20);
vrp_variables_stack = VEC_alloc (tree, heap, 20);
stmts_to_rescan = VEC_alloc (tree, heap, 20);
nonzero_vars = BITMAP_ALLOC (NULL);
+ threaded_blocks = BITMAP_ALLOC (NULL);
need_eh_cleanup = BITMAP_ALLOC (NULL);
/* Setup callbacks for the generic dominator tree walker. */
@@ -423,15 +445,6 @@ tree_ssa_dominator_optimize (void)
/* Recursively walk the dominator tree optimizing statements. */
walk_dominator_tree (&walk_data, ENTRY_BLOCK_PTR);
- /* If we exposed any new variables, go ahead and put them into
- SSA form now, before we handle jump threading. This simplifies
- interactions between rewriting of _DECL nodes into SSA form
- and rewriting SSA_NAME nodes into SSA form after block
- duplication and CFG manipulation. */
- update_ssa (TODO_update_ssa);
-
- free_all_edge_infos ();
-
{
block_stmt_iterator bsi;
basic_block bb;
@@ -444,8 +457,17 @@ tree_ssa_dominator_optimize (void)
}
}
+ /* If we exposed any new variables, go ahead and put them into
+ SSA form now, before we handle jump threading. This simplifies
+ interactions between rewriting of _DECL nodes into SSA form
+ and rewriting SSA_NAME nodes into SSA form after block
+ duplication and CFG manipulation. */
+ update_ssa (TODO_update_ssa);
+
+ free_all_edge_infos ();
+
/* Thread jumps, creating duplicate blocks as needed. */
- cfg_altered |= thread_through_all_blocks ();
+ cfg_altered |= thread_through_all_blocks (threaded_blocks);
/* Removal of statements may make some EH edges dead. Purge
such edges from the CFG as needed. */
@@ -480,6 +502,7 @@ tree_ssa_dominator_optimize (void)
/* Reinitialize the various tables. */
bitmap_clear (nonzero_vars);
+ bitmap_clear (threaded_blocks);
htab_empty (avail_exprs);
htab_empty (vrp_data);
@@ -523,6 +546,7 @@ tree_ssa_dominator_optimize (void)
/* Free nonzero_vars. */
BITMAP_FREE (nonzero_vars);
+ BITMAP_FREE (threaded_blocks);
BITMAP_FREE (need_eh_cleanup);
VEC_free (tree, heap, avail_exprs_stack);
@@ -832,7 +856,7 @@ thread_across_edge (struct dom_walk_data *walk_data, edge e)
else
edge_info = allocate_edge_info (e);
edge_info->redirection_target = taken_edge;
- bb_ann (e->dest)->incoming_edge_threaded = true;
+ bitmap_set_bit (threaded_blocks, e->dest->index);
}
}
}
@@ -1111,7 +1135,7 @@ dom_opt_finalize_block (struct dom_walk_data *walk_data, basic_block bb)
the array backwards popping off records associated with our
block. Once we hit a record not associated with our block
we are done. */
- varray_type var_vrp_records;
+ VEC(vrp_element_p,heap) **var_vrp_records;
if (var == NULL)
break;
@@ -1122,17 +1146,17 @@ dom_opt_finalize_block (struct dom_walk_data *walk_data, basic_block bb)
slot = htab_find_slot (vrp_data, &vrp_hash_elt, NO_INSERT);
vrp_hash_elt_p = (struct vrp_hash_elt *) *slot;
- var_vrp_records = vrp_hash_elt_p->records;
+ var_vrp_records = &vrp_hash_elt_p->records;
- while (VARRAY_ACTIVE_SIZE (var_vrp_records) > 0)
+ while (VEC_length (vrp_element_p, *var_vrp_records) > 0)
{
struct vrp_element *element
- = (struct vrp_element *)VARRAY_TOP_GENERIC_PTR (var_vrp_records);
+ = VEC_last (vrp_element_p, *var_vrp_records);
if (element->bb != bb)
break;
- VARRAY_POP (var_vrp_records);
+ VEC_pop (vrp_element_p, *var_vrp_records);
}
}
@@ -2036,7 +2060,7 @@ simplify_cond_and_lookup_avail_expr (tree stmt,
int limit;
tree low, high, cond_low, cond_high;
int lowequal, highequal, swapped, no_overlap, subset, cond_inverted;
- varray_type vrp_records;
+ VEC(vrp_element_p,heap) **vrp_records;
struct vrp_element *element;
struct vrp_hash_elt vrp_hash_elt, *vrp_hash_elt_p;
void **slot;
@@ -2089,11 +2113,9 @@ simplify_cond_and_lookup_avail_expr (tree stmt,
return NULL;
vrp_hash_elt_p = (struct vrp_hash_elt *) *slot;
- vrp_records = vrp_hash_elt_p->records;
- if (vrp_records == NULL)
- return NULL;
+ vrp_records = &vrp_hash_elt_p->records;
- limit = VARRAY_ACTIVE_SIZE (vrp_records);
+ limit = VEC_length (vrp_element_p, *vrp_records);
/* If we have no value range records for this variable, or we are
unable to extract a range for this condition, then there is
@@ -2125,8 +2147,7 @@ simplify_cond_and_lookup_avail_expr (tree stmt,
conditional into the current range.
These properties also help us avoid unnecessary work. */
- element
- = (struct vrp_element *)VARRAY_GENERIC_PTR (vrp_records, limit - 1);
+ element = VEC_last (vrp_element_p, *vrp_records);
if (element->high && element->low)
{
@@ -2165,8 +2186,7 @@ simplify_cond_and_lookup_avail_expr (tree stmt,
{
/* Get the high/low value from the previous element. */
struct vrp_element *prev
- = (struct vrp_element *)VARRAY_GENERIC_PTR (vrp_records,
- limit - 2);
+ = VEC_index (vrp_element_p, *vrp_records, limit - 2);
low = prev->low;
high = prev->high;
@@ -3306,7 +3326,7 @@ record_range (tree cond, basic_block bb)
{
struct vrp_hash_elt *vrp_hash_elt;
struct vrp_element *element;
- varray_type *vrp_records_p;
+ VEC(vrp_element_p,heap) **vrp_records_p;
void **slot;
@@ -3318,7 +3338,7 @@ record_range (tree cond, basic_block bb)
if (*slot == NULL)
*slot = (void *) vrp_hash_elt;
else
- free (vrp_hash_elt);
+ vrp_free (vrp_hash_elt);
vrp_hash_elt = (struct vrp_hash_elt *) *slot;
vrp_records_p = &vrp_hash_elt->records;
@@ -3329,10 +3349,7 @@ record_range (tree cond, basic_block bb)
element->cond = cond;
element->bb = bb;
- if (*vrp_records_p == NULL)
- VARRAY_GENERIC_PTR_INIT (*vrp_records_p, 2, "vrp records");
-
- VARRAY_PUSH_GENERIC_PTR (*vrp_records_p, element);
+ VEC_safe_push (vrp_element_p, heap, *vrp_records_p, element);
VEC_safe_push (tree, heap, vrp_variables_stack, TREE_OPERAND (cond, 0));
}
}
diff --git a/gcc/tree-ssa-dse.c b/gcc/tree-ssa-dse.c
index f16b02931f1..8385ddce4b1 100644
--- a/gcc/tree-ssa-dse.c
+++ b/gcc/tree-ssa-dse.c
@@ -22,7 +22,6 @@ Boston, MA 02111-1307, USA. */
#include "system.h"
#include "coretypes.h"
#include "tm.h"
-#include "errors.h"
#include "ggc.h"
#include "tree.h"
#include "rtl.h"
@@ -135,7 +134,7 @@ dse_initialize_block_local_data (struct dom_walk_data *walk_data,
bool recycled)
{
struct dse_block_local_data *bd
- = VARRAY_TOP_GENERIC_PTR (walk_data->block_data_stack);
+ = VEC_last (void_p, walk_data->block_data_stack);
/* If we are given a recycled block local data structure, ensure any
bitmap associated with the block is cleared. */
@@ -163,7 +162,7 @@ dse_optimize_stmt (struct dom_walk_data *walk_data,
block_stmt_iterator bsi)
{
struct dse_block_local_data *bd
- = VARRAY_TOP_GENERIC_PTR (walk_data->block_data_stack);
+ = VEC_last (void_p, walk_data->block_data_stack);
struct dse_global_data *dse_gd = walk_data->global_data;
tree stmt = bsi_stmt (bsi);
stmt_ann_t ann = stmt_ann (stmt);
@@ -195,7 +194,7 @@ dse_optimize_stmt (struct dom_walk_data *walk_data,
/* We want to verify that each virtual definition in STMT has
precisely one use and that all the virtual definitions are
used by the same single statement. When complete, we
- want USE_STMT to refer to the one statment which uses
+ want USE_STMT to refer to the one statement which uses
all of the virtual definitions from STMT. */
use_stmt = NULL;
FOR_EACH_SSA_MUST_AND_MAY_DEF_OPERAND (var1, var2, stmt, op_iter)
@@ -298,7 +297,7 @@ static void
dse_record_phis (struct dom_walk_data *walk_data, basic_block bb)
{
struct dse_block_local_data *bd
- = VARRAY_TOP_GENERIC_PTR (walk_data->block_data_stack);
+ = VEC_last (void_p, walk_data->block_data_stack);
struct dse_global_data *dse_gd = walk_data->global_data;
tree phi;
@@ -314,7 +313,7 @@ dse_finalize_block (struct dom_walk_data *walk_data,
basic_block bb ATTRIBUTE_UNUSED)
{
struct dse_block_local_data *bd
- = VARRAY_TOP_GENERIC_PTR (walk_data->block_data_stack);
+ = VEC_last (void_p, walk_data->block_data_stack);
struct dse_global_data *dse_gd = walk_data->global_data;
bitmap stores = dse_gd->stores;
unsigned int i;
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index 45d03ddd196..19c00dfdec5 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -22,7 +22,6 @@ Boston, MA 02111-1307, USA. */
#include "system.h"
#include "coretypes.h"
#include "tm.h"
-#include "errors.h"
#include "ggc.h"
#include "tree.h"
#include "rtl.h"
@@ -560,7 +559,8 @@ forward_propagate_addr_expr (tree stmt)
if (bb_for_stmt (use_stmt)->loop_depth > stmt_loop_depth)
return false;
- /* Strip away any outer COMPONENT_REF/ARRAY_REF nodes from the LHS. */
+ /* Strip away any outer COMPONENT_REF/ARRAY_REF nodes from the LHS.
+ ADDR_EXPR will not appear on the LHS. */
lhs = TREE_OPERAND (use_stmt, 0);
while (TREE_CODE (lhs) == COMPONENT_REF || TREE_CODE (lhs) == ARRAY_REF)
lhs = TREE_OPERAND (lhs, 0);
@@ -591,9 +591,12 @@ forward_propagate_addr_expr (tree stmt)
return true;
}
- /* Strip away any outer COMPONENT_REF/ARRAY_REF nodes from the RHS. */
+ /* Strip away any outer COMPONENT_REF, ARRAY_REF or ADDR_EXPR
+ nodes from the RHS. */
rhs = TREE_OPERAND (use_stmt, 1);
- while (TREE_CODE (rhs) == COMPONENT_REF || TREE_CODE (rhs) == ARRAY_REF)
+ while (TREE_CODE (rhs) == COMPONENT_REF
+ || TREE_CODE (rhs) == ARRAY_REF
+ || TREE_CODE (rhs) == ADDR_EXPR)
rhs = TREE_OPERAND (rhs, 0);
/* Now see if the RHS node is an INDIRECT_REF using NAME. If so,
diff --git a/gcc/tree-ssa-live.c b/gcc/tree-ssa-live.c
index f40df907d6a..886a9eba0ab 100644
--- a/gcc/tree-ssa-live.c
+++ b/gcc/tree-ssa-live.c
@@ -37,7 +37,7 @@ Boston, MA 02111-1307, USA. */
#include "hashtab.h"
#include "tree-dump.h"
#include "tree-ssa-live.h"
-#include "errors.h"
+#include "toplev.h"
static void live_worklist (tree_live_info_p, int *, int);
static tree_live_info_p new_tree_live_info (var_map);
@@ -1281,8 +1281,8 @@ add_conflicts_if_valid (tpa_p tpa, conflict_graph graph,
}
}
-DEF_VEC_P(int);
-DEF_VEC_ALLOC_P(int,heap);
+DEF_VEC_I(int);
+DEF_VEC_ALLOC_I(int,heap);
/* Return a conflict graph for the information contained in LIVE_INFO. Only
conflicts between items in the same TPA list are added. If optional
diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c
index 25203c4c759..6fdb0dc2f5b 100644
--- a/gcc/tree-ssa-loop-im.c
+++ b/gcc/tree-ssa-loop-im.c
@@ -129,7 +129,7 @@ struct mem_ref
table, but the hash function depends
on values of pointers. Thus we cannot use
htab_traverse, since then we would get
- misscompares during bootstrap (although the
+ miscompares during bootstrap (although the
produced code would be correct). */
};
@@ -201,6 +201,7 @@ for_each_index (tree *addr_p, bool (*cbck) (tree, tree *, void *), void *data)
case PARM_DECL:
case STRING_CST:
case RESULT_DECL:
+ case VECTOR_CST:
return true;
case MEM_REF:
@@ -639,7 +640,7 @@ determine_invariantness_stmt (struct dom_walk_data *dw_data ATTRIBUTE_UNUSED,
bsi_insert_after (&bsi, stmt2, BSI_NEW_STMT);
SSA_NAME_DEF_STMT (lhs) = stmt2;
- /* Continue processing with invariant reciprocal statment. */
+ /* Continue processing with invariant reciprocal statement. */
stmt = stmt1;
}
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
index 5cb623b871e..81bec044c5f 100644
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -1389,7 +1389,7 @@ idx_find_step (tree base, tree *idx, void *data)
{
struct ifs_ivopts_data *dta = data;
struct iv *iv;
- tree step, type, iv_type, iv_step, lbound, off;
+ tree step, iv_step, lbound, off;
struct loop *loop = dta->ivopts_data->current_loop;
if (TREE_CODE (base) == MISALIGNED_INDIRECT_REF
@@ -1430,8 +1430,6 @@ idx_find_step (tree base, tree *idx, void *data)
if (!iv->step)
return true;
- iv_type = TREE_TYPE (iv->base);
- type = build_pointer_type (TREE_TYPE (base));
if (TREE_CODE (base) == ARRAY_REF)
{
step = array_ref_element_size (base);
@@ -1442,13 +1440,13 @@ idx_find_step (tree base, tree *idx, void *data)
}
else
/* The step for pointer arithmetics already is 1 byte. */
- step = build_int_cst (type, 1);
+ step = build_int_cst (sizetype, 1);
- if (TYPE_PRECISION (iv_type) < TYPE_PRECISION (type))
+ if (TYPE_PRECISION (TREE_TYPE (iv->base)) < TYPE_PRECISION (sizetype))
iv_step = can_count_iv_in_wider_type (dta->ivopts_data->current_loop,
- type, iv->base, iv->step, dta->stmt);
+ sizetype, iv->base, iv->step, dta->stmt);
else
- iv_step = fold_convert (iv_type, iv->step);
+ iv_step = fold_convert (sizetype, iv->step);
if (!iv_step)
{
@@ -1456,12 +1454,12 @@ idx_find_step (tree base, tree *idx, void *data)
return false;
}
- step = fold_build2 (MULT_EXPR, type, step, iv_step);
+ step = fold_build2 (MULT_EXPR, sizetype, step, iv_step);
if (!*dta->step_p)
*dta->step_p = step;
else
- *dta->step_p = fold_build2 (PLUS_EXPR, type, *dta->step_p, step);
+ *dta->step_p = fold_build2 (PLUS_EXPR, sizetype, *dta->step_p, step);
return true;
}
@@ -1513,25 +1511,6 @@ may_be_unaligned_p (tree ref)
return false;
}
-/* Builds ADDR_EXPR of object OBJ. If OBJ is an INDIRECT_REF, the indirect_ref
- is stripped instead. */
-
-static tree
-build_addr_strip_iref (tree obj)
-{
- tree type;
-
- if (TREE_CODE (obj) == INDIRECT_REF)
- {
- type = build_pointer_type (TREE_TYPE (obj));
- obj = fold_convert (type, TREE_OPERAND (obj, 0));
- }
- else
- obj = build_addr (obj, current_function_decl);
-
- return obj;
-}
-
/* Finds addresses in *OP_P inside STMT. */
static void
@@ -1566,7 +1545,7 @@ find_interesting_uses_address (struct ivopts_data *data, tree stmt, tree *op_p)
gcc_assert (TREE_CODE (base) != ALIGN_INDIRECT_REF);
gcc_assert (TREE_CODE (base) != MISALIGNED_INDIRECT_REF);
- base = build_addr_strip_iref (base);
+ base = build_fold_addr_expr (base);
civ = alloc_iv (base, step);
record_use (data, op_p, civ, stmt, USE_ADDRESS);
@@ -1859,7 +1838,7 @@ strip_offset_1 (tree expr, bool inside_addr, bool top_compref,
if (op0 == TREE_OPERAND (expr, 0))
return orig_expr;
- expr = build_addr_strip_iref (op0);
+ expr = build_fold_addr_expr (op0);
return fold_convert (orig_type, expr);
case INDIRECT_REF:
@@ -1886,7 +1865,7 @@ strip_offset_1 (tree expr, bool inside_addr, bool top_compref,
TREE_OPERAND (expr, 1) = op1;
/* Inside address, we might strip the top level component references,
- thus changing type of the expresion. Handling of ADDR_EXPR
+ thus changing type of the expression. Handling of ADDR_EXPR
will fix that. */
expr = fold_convert (orig_type, expr);
@@ -2847,7 +2826,7 @@ tree_to_aff_combination (tree expr, tree type,
if (bitpos % BITS_PER_UNIT != 0)
break;
aff_combination_const (comb, type, bitpos / BITS_PER_UNIT);
- core = build_addr_strip_iref (core);
+ core = build_fold_addr_expr (core);
if (TREE_CODE (core) == ADDR_EXPR)
aff_combination_add_elt (comb, core, 1);
else
diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c
index a4f85b6b3a5..146d533996b 100644
--- a/gcc/tree-ssa-operands.c
+++ b/gcc/tree-ssa-operands.c
@@ -26,12 +26,12 @@ Boston, MA 02111-1307, USA. */
#include "flags.h"
#include "function.h"
#include "diagnostic.h"
-#include "errors.h"
#include "tree-flow.h"
#include "tree-inline.h"
#include "tree-pass.h"
#include "ggc.h"
#include "timevar.h"
+#include "toplev.h"
#include "langhooks.h"
#include "ipa-static.h"
@@ -1817,7 +1817,7 @@ add_stmt_operand (tree *var_p, stmt_ann_t s_ann, int flags)
/* If the variable cannot be modified and this is a V_MAY_DEF change
it into a VUSE. This happens when read-only variables are marked
- call-clobbered and/or aliased to writeable variables. So we only
+ call-clobbered and/or aliased to writable variables. So we only
check that this only happens on non-specific stores.
Note that if this is a specific store, i.e. associated with a
diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c
index 580b3b7395f..1778c12a816 100644
--- a/gcc/tree-ssa-phiopt.c
+++ b/gcc/tree-ssa-phiopt.c
@@ -22,7 +22,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "system.h"
#include "coretypes.h"
#include "tm.h"
-#include "errors.h"
#include "ggc.h"
#include "tree.h"
#include "rtl.h"
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index 439f9746d37..7d11876ba60 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -24,7 +24,6 @@ Boston, MA 02111-1307, USA. */
#include "system.h"
#include "coretypes.h"
#include "tm.h"
-#include "errors.h"
#include "ggc.h"
#include "tree.h"
#include "basic-block.h"
diff --git a/gcc/tree-ssa-propagate.c b/gcc/tree-ssa-propagate.c
index 865853df1e1..37c644b50c4 100644
--- a/gcc/tree-ssa-propagate.c
+++ b/gcc/tree-ssa-propagate.c
@@ -30,7 +30,6 @@
#include "ggc.h"
#include "basic-block.h"
#include "output.h"
-#include "errors.h"
#include "expr.h"
#include "function.h"
#include "diagnostic.h"
@@ -774,6 +773,7 @@ struct prop_stats_d
{
long num_const_prop;
long num_copy_prop;
+ long num_pred_folded;
};
static struct prop_stats_d prop_stats;
@@ -965,6 +965,11 @@ static void
replace_phi_args_in (tree phi, prop_value_t *prop_value)
{
int i;
+ bool replaced = false;
+ tree prev_phi = NULL;
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ prev_phi = unshare_expr (phi);
for (i = 0; i < PHI_NUM_ARGS (phi); i++)
{
@@ -982,6 +987,7 @@ replace_phi_args_in (tree phi, prop_value_t *prop_value)
prop_stats.num_copy_prop++;
propagate_value (PHI_ARG_DEF_PTR (phi, i), val);
+ replaced = true;
/* If we propagated a copy and this argument flows
through an abnormal edge, update the replacement
@@ -992,19 +998,79 @@ replace_phi_args_in (tree phi, prop_value_t *prop_value)
}
}
}
+
+ if (replaced && dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Folded PHI node: ");
+ print_generic_stmt (dump_file, prev_phi, TDF_SLIM);
+ fprintf (dump_file, " into: ");
+ print_generic_stmt (dump_file, phi, TDF_SLIM);
+ fprintf (dump_file, "\n");
+ }
+}
+
+
+/* If STMT has a predicate whose value can be computed using the value
+ range information computed by VRP, compute its value and return true.
+ Otherwise, return false. */
+
+static bool
+fold_predicate_in (tree stmt)
+{
+ tree *pred_p = NULL;
+ tree val;
+
+ if (TREE_CODE (stmt) == MODIFY_EXPR
+ && COMPARISON_CLASS_P (TREE_OPERAND (stmt, 1)))
+ pred_p = &TREE_OPERAND (stmt, 1);
+ else if (TREE_CODE (stmt) == COND_EXPR)
+ pred_p = &COND_EXPR_COND (stmt);
+ else
+ return false;
+
+ val = vrp_evaluate_conditional (*pred_p, true);
+ if (val)
+ {
+ if (dump_file)
+ {
+ fprintf (dump_file, "Folding predicate ");
+ print_generic_expr (dump_file, *pred_p, 0);
+ fprintf (dump_file, " to ");
+ print_generic_expr (dump_file, val, 0);
+ fprintf (dump_file, "\n");
+ }
+
+ prop_stats.num_pred_folded++;
+ *pred_p = val;
+ return true;
+ }
+
+ return false;
}
-/* Perform final substitution and folding of propagated values. */
+/* Perform final substitution and folding of propagated values.
+
+ PROP_VALUE[I] contains the single value that should be substituted
+ at every use of SSA name N_I. If PROP_VALUE is NULL, no values are
+ substituted.
+
+ If USE_RANGES_P is true, statements that contain predicate
+ expressions are evaluated with a call to vrp_evaluate_conditional.
+ This will only give meaningful results when called from tree-vrp.c
+ (the information used by vrp_evaluate_conditional is built by the
+ VRP pass). */
void
-substitute_and_fold (prop_value_t *prop_value)
+substitute_and_fold (prop_value_t *prop_value, bool use_ranges_p)
{
basic_block bb;
+ if (prop_value == NULL && !use_ranges_p)
+ return;
+
if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file,
- "\nSubstituing values and folding statements\n\n");
+ fprintf (dump_file, "\nSubstituing values and folding statements\n\n");
memset (&prop_stats, 0, sizeof (prop_stats));
@@ -1014,41 +1080,51 @@ substitute_and_fold (prop_value_t *prop_value)
block_stmt_iterator i;
tree phi;
- /* Propagate our known values into PHI nodes. */
- for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "Replaced ");
- print_generic_stmt (dump_file, phi, TDF_SLIM);
- }
-
+ /* Propagate known values into PHI nodes. */
+ if (prop_value)
+ for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
replace_phi_args_in (phi, prop_value);
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, " with ");
- print_generic_stmt (dump_file, phi, TDF_SLIM);
- fprintf (dump_file, "\n");
- }
- }
-
for (i = bsi_start (bb); !bsi_end_p (i); bsi_next (&i))
{
bool replaced_address, did_replace;
+ tree prev_stmt = NULL;
tree stmt = bsi_stmt (i);
+ /* Ignore ASSERT_EXPRs. They are used by VRP to generate
+ range information for names and they are discarded
+ afterwards. */
+ if (TREE_CODE (stmt) == MODIFY_EXPR
+ && TREE_CODE (TREE_OPERAND (stmt, 1)) == ASSERT_EXPR)
+ continue;
+
/* Replace the statement with its folded version and mark it
folded. */
+ did_replace = false;
+ replaced_address = false;
if (dump_file && (dump_flags & TDF_DETAILS))
+ prev_stmt = unshare_expr (stmt);
+
+ /* If we have range information, see if we can fold
+ predicate expressions. */
+ if (use_ranges_p)
+ did_replace = fold_predicate_in (stmt);
+
+ if (prop_value)
{
- fprintf (dump_file, "Replaced ");
- print_generic_stmt (dump_file, stmt, TDF_SLIM);
+ /* Only replace real uses if we couldn't fold the
+ statement using value range information (value range
+ information is not collected on virtuals, so we only
+ need to check this for real uses). */
+ if (!did_replace)
+ did_replace |= replace_uses_in (stmt, &replaced_address,
+ prop_value);
+
+ did_replace |= replace_vuses_in (stmt, &replaced_address,
+ prop_value);
}
- replaced_address = false;
- did_replace = replace_uses_in (stmt, &replaced_address, prop_value);
- did_replace |= replace_vuses_in (stmt, &replaced_address, prop_value);
+ /* If we made a replacement, fold and cleanup the statement. */
if (did_replace)
{
tree old_stmt = stmt;
@@ -1069,13 +1145,15 @@ substitute_and_fold (prop_value_t *prop_value)
rhs = get_rhs (stmt);
if (TREE_CODE (rhs) == ADDR_EXPR)
recompute_tree_invarant_for_addr_expr (rhs);
- }
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, " with ");
- print_generic_stmt (dump_file, stmt, TDF_SLIM);
- fprintf (dump_file, "\n");
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Folded statement: ");
+ print_generic_stmt (dump_file, prev_stmt, TDF_SLIM);
+ fprintf (dump_file, " into: ");
+ print_generic_stmt (dump_file, stmt, TDF_SLIM);
+ fprintf (dump_file, "\n");
+ }
}
}
}
@@ -1086,6 +1164,9 @@ substitute_and_fold (prop_value_t *prop_value)
prop_stats.num_const_prop);
fprintf (dump_file, "Copies propagated: %6ld\n",
prop_stats.num_copy_prop);
+ fprintf (dump_file, "Predicates folded: %6ld\n",
+ prop_stats.num_pred_folded);
}
}
+
#include "gt-tree-ssa-propagate.h"
diff --git a/gcc/tree-ssa-propagate.h b/gcc/tree-ssa-propagate.h
index f0124f45204..f7265fe0e6c 100644
--- a/gcc/tree-ssa-propagate.h
+++ b/gcc/tree-ssa-propagate.h
@@ -73,6 +73,39 @@ struct prop_value_d {
typedef struct prop_value_d prop_value_t;
+/* Type of value ranges. See value_range_d for a description of these
+ types. */
+enum value_range_type { VR_UNDEFINED, VR_RANGE, VR_ANTI_RANGE, VR_VARYING };
+
+/* Range of values that can be associated with an SSA_NAME after VRP
+ has executed. */
+struct value_range_d
+{
+ /* Lattice value represented by this range. */
+ enum value_range_type type;
+
+ /* Minimum and maximum values represented by this range. These
+ values should be interpreted as follows:
+
+ - If TYPE is VR_UNDEFINED or VR_VARYING then MIN and MAX must
+ be NULL.
+
+ - If TYPE == VR_RANGE then MIN holds the minimum value and
+ MAX holds the maximum value of the range [MIN, MAX].
+
+ - If TYPE == ANTI_RANGE the variable is known to NOT
+ take any values in the range [MIN, MAX]. */
+ tree min;
+ tree max;
+
+ /* Set of SSA names whose value ranges are equivalent to this one.
+ This set is only valid when TYPE is VR_RANGE or VR_ANTI_RANGE. */
+ bitmap equiv;
+};
+
+typedef struct value_range_d value_range_t;
+
+
/* Call-back functions used by the value propagation engine. */
typedef enum ssa_prop_result (*ssa_prop_visit_stmt_fn) (tree, edge *, tree *);
typedef enum ssa_prop_result (*ssa_prop_visit_phi_fn) (tree);
@@ -87,6 +120,6 @@ bool stmt_makes_single_load (tree);
bool stmt_makes_single_store (tree);
prop_value_t *get_value_loaded_by (tree, prop_value_t *);
bool replace_uses_in (tree, bool *, prop_value_t *);
-void substitute_and_fold (prop_value_t *);
+void substitute_and_fold (prop_value_t *, bool);
#endif /* _TREE_SSA_PROPAGATE_H */
diff --git a/gcc/tree-ssa-sink.c b/gcc/tree-ssa-sink.c
index 7fb1bc9d009..e883b21193a 100644
--- a/gcc/tree-ssa-sink.c
+++ b/gcc/tree-ssa-sink.c
@@ -23,7 +23,6 @@ Boston, MA 02111-1307, USA. */
#include "system.h"
#include "coretypes.h"
#include "tm.h"
-#include "errors.h"
#include "ggc.h"
#include "tree.h"
#include "basic-block.h"
diff --git a/gcc/tree-ssa-threadupdate.c b/gcc/tree-ssa-threadupdate.c
index e72598d830e..25f6cdfdc02 100644
--- a/gcc/tree-ssa-threadupdate.c
+++ b/gcc/tree-ssa-threadupdate.c
@@ -29,7 +29,6 @@ Boston, MA 02111-1307, USA. */
#include "ggc.h"
#include "basic-block.h"
#include "output.h"
-#include "errors.h"
#include "expr.h"
#include "function.h"
#include "diagnostic.h"
@@ -299,6 +298,9 @@ create_edge_and_update_destination_phis (struct redirection_data *rd)
edge e = make_edge (rd->dup_block, rd->outgoing_edge->dest, EDGE_FALLTHRU);
tree phi;
+ e->probability = REG_BR_PROB_BASE;
+ e->count = rd->dup_block->count;
+
/* If there are any PHI nodes at the destination of the outgoing edge
from the duplicate block, then we will need to add a new argument
to them. The argument should have the same value as the argument
@@ -802,22 +804,20 @@ thread_block (basic_block bb)
Returns true if one or more edges were threaded, false otherwise. */
bool
-thread_through_all_blocks (void)
+thread_through_all_blocks (bitmap threaded_blocks)
{
- basic_block bb;
bool retval = false;
+ unsigned int i;
+ bitmap_iterator bi;
rediscover_loops_after_threading = false;
- FOR_EACH_BB (bb)
+ EXECUTE_IF_SET_IN_BITMAP (threaded_blocks, 0, i, bi)
{
- if (bb_ann (bb)->incoming_edge_threaded
- && EDGE_COUNT (bb->preds) > 0)
- {
- retval |= thread_block (bb);
- bb_ann (bb)->incoming_edge_threaded = false;
-
- }
+ basic_block bb = BASIC_BLOCK (i);
+
+ if (EDGE_COUNT (bb->preds) > 0)
+ retval |= thread_block (bb);
}
return retval;
diff --git a/gcc/tree-ssa-uncprop.c b/gcc/tree-ssa-uncprop.c
index 318160949cb..27debc3277e 100644
--- a/gcc/tree-ssa-uncprop.c
+++ b/gcc/tree-ssa-uncprop.c
@@ -29,7 +29,6 @@ Boston, MA 02111-1307, USA. */
#include "ggc.h"
#include "basic-block.h"
#include "output.h"
-#include "errors.h"
#include "expr.h"
#include "function.h"
#include "diagnostic.h"
diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c
index 5d58d220562..4f6cd4188ae 100644
--- a/gcc/tree-ssa.c
+++ b/gcc/tree-ssa.c
@@ -31,7 +31,6 @@ Boston, MA 02111-1307, USA. */
#include "hard-reg-set.h"
#include "basic-block.h"
#include "output.h"
-#include "errors.h"
#include "expr.h"
#include "function.h"
#include "diagnostic.h"
@@ -45,6 +44,7 @@ Boston, MA 02111-1307, USA. */
#include "hashtab.h"
#include "tree-dump.h"
#include "tree-pass.h"
+#include "toplev.h"
/* Remove the corresponding arguments from the PHI nodes in E's
destination block and redirect it to DEST. Return redirected edge.
diff --git a/gcc/tree-vect-analyze.c b/gcc/tree-vect-analyze.c
index 7529effb076..4d2058f9371 100644
--- a/gcc/tree-vect-analyze.c
+++ b/gcc/tree-vect-analyze.c
@@ -23,7 +23,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "system.h"
#include "coretypes.h"
#include "tm.h"
-#include "errors.h"
#include "ggc.h"
#include "tree.h"
#include "basic-block.h"
@@ -1246,7 +1245,7 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
/* Function vect_analyze_data_refs_alignment
Analyze the alignment of the data-references in the loop.
- FOR NOW: Until support for misliagned accesses is in place, only if all
+ FOR NOW: Until support for misaligned accesses is in place, only if all
accesses are aligned can the loop be vectorized. This restriction will be
relaxed. */
@@ -1908,7 +1907,7 @@ vect_object_analysis (tree memref, tree stmt, bool is_read,
foreach ref
base_address = vect_object_analysis(ref)
1.1- vect_object_analysis(ref):
- Analyze ref, and build a DR (data_referece struct) for it;
+ Analyze ref, and build a DR (data_reference struct) for it;
compute base, initial_offset, step and alignment.
Call get_inner_reference for refs handled in this function.
Call vect_addr_analysis(addr) to analyze pointer type expressions.
@@ -2466,7 +2465,7 @@ vect_analyze_loop_form (struct loop *loop)
if (!empty_block_p (loop->latch))
{
if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS, loop_loc))
- fprintf (vect_dump, "not vectorized: unexpectd loop form.");
+ fprintf (vect_dump, "not vectorized: unexpected loop form.");
return NULL;
}
diff --git a/gcc/tree-vect-generic.c b/gcc/tree-vect-generic.c
index 2da1ed2e936..69eabbd0481 100644
--- a/gcc/tree-vect-generic.c
+++ b/gcc/tree-vect-generic.c
@@ -495,7 +495,9 @@ struct tree_opt_pass pass_lower_vector =
{
"veclower", /* name */
0, /* gate */
+ NULL, NULL, /* IPA analysis */
expand_vector_operations, /* execute */
+ NULL, NULL, /* IPA analysis */
NULL, /* sub */
NULL, /* next */
0, /* static_pass_number */
@@ -513,7 +515,9 @@ struct tree_opt_pass pass_lower_vector_ssa =
{
"veclower2", /* name */
gate_expand_vector_operations, /* gate */
+ NULL, NULL, /* IPA analysis */
expand_vector_operations, /* execute */
+ NULL, NULL, /* IPA analysis */
NULL, /* sub */
NULL, /* next */
0, /* static_pass_number */
diff --git a/gcc/tree-vect-transform.c b/gcc/tree-vect-transform.c
index 17d65897cdb..97d338441b3 100644
--- a/gcc/tree-vect-transform.c
+++ b/gcc/tree-vect-transform.c
@@ -23,7 +23,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "system.h"
#include "coretypes.h"
#include "tm.h"
-#include "errors.h"
#include "ggc.h"
#include "tree.h"
#include "target.h"
@@ -231,7 +230,7 @@ vect_create_addr_base_for_vector_ref (tree stmt,
/* Function vect_align_data_ref.
- Handle mislignment of a memory accesses.
+ Handle misalignment of a memory accesses.
FORNOW: Can't handle misaligned accesses.
Make sure that the dataref is aligned. */
@@ -350,16 +349,13 @@ vect_create_data_ref_ptr (tree stmt, block_stmt_iterator *bsi, tree offset,
tag = STMT_VINFO_MEMTAG (stmt_info);
gcc_assert (tag);
- /* If the memory tag of the original reference was not a type tag or
- if the pointed-to type of VECT_PTR has an alias set number
- different than TAG's, then we need to create a new type tag for
- VECT_PTR and add TAG to its alias set. */
- if (var_ann (tag)->mem_tag_kind == NOT_A_TAG
- || get_alias_set (tag) != get_alias_set (TREE_TYPE (vect_ptr_type)))
- add_type_alias (vect_ptr, tag);
+ /* If tag is a variable (and NOT_A_TAG) than a new type alias
+ tag must be created with tag added to its may alias list. */
+ if (var_ann (tag)->mem_tag_kind == NOT_A_TAG)
+ new_type_alias (vect_ptr, tag);
else
var_ann (vect_ptr)->type_mem_tag = tag;
-
+
var_ann (vect_ptr)->subvars = STMT_VINFO_SUBVARS (stmt_info);
/** (3) Calculate the initial address the vector-pointer, and set
@@ -815,7 +811,12 @@ vectorizable_operation (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
{
if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
fprintf (vect_dump, "op not supported by target.");
- return false;
+ if (GET_MODE_SIZE (vec_mode) != UNITS_PER_WORD
+ || LOOP_VINFO_VECT_FACTOR (loop_vinfo)
+ < vect_min_worthwhile_factor (code))
+ return false;
+ if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
+ fprintf (vect_dump, "proceeding using word mode.");
}
/* Worthwhile without SIMD support? */
@@ -891,8 +892,8 @@ vectorizable_store (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
enum machine_mode vec_mode;
tree dummy;
enum dr_alignment_support alignment_support_cheme;
- ssa_op_iter iter;
tree def;
+ ssa_op_iter iter;
/* Is vectorizable store? */
@@ -950,16 +951,22 @@ vectorizable_store (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
*vec_stmt = build2 (MODIFY_EXPR, vectype, data_ref, vec_oprnd1);
vect_finish_stmt_generation (stmt, *vec_stmt, bsi);
- /* Mark all non-SSA variables in the statement for rewriting. */
- mark_new_vars_to_rename (*vec_stmt);
-
- /* The new vectorized statement will have better aliasing
- information, so some of the virtual definitions of the old
- statement will likely disappear from the IL. Mark them to have
- their SSA form updated. */
+ /* Copy the V_MAY_DEFS representing the aliasing of the original array
+ element's definition to the vector's definition then update the
+ defining statement. The original is being deleted so the same
+ SSA_NAMEs can be used. */
+ copy_virtual_operands (*vec_stmt, stmt);
+
FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_VMAYDEF)
- mark_sym_for_renaming (SSA_NAME_VAR (def));
-
+ {
+ SSA_NAME_DEF_STMT (def) = *vec_stmt;
+
+ /* If this virtual def has a use outside the loop and a loop peel is performed
+ then the def may be renamed by the peel. Mark it for renaming so the
+ later use will also be renamed. */
+ mark_sym_for_renaming (SSA_NAME_VAR (def));
+ }
+
return true;
}
diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c
index 95ecdd9fa97..883f403051c 100644
--- a/gcc/tree-vectorizer.c
+++ b/gcc/tree-vectorizer.c
@@ -124,7 +124,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "system.h"
#include "coretypes.h"
#include "tm.h"
-#include "errors.h"
#include "ggc.h"
#include "tree.h"
#include "target.h"
@@ -321,8 +320,11 @@ slpeel_update_phis_for_duplicate_loop (struct loop *orig_loop,
new_ssa_name = get_current_def (def);
if (!new_ssa_name)
- /* Something defined outside of the loop. */
- continue;
+ {
+ /* This only happens if there are no definitions
+ inside the loop. use the phi_result in this case. */
+ new_ssa_name = PHI_RESULT (phi_new);
+ }
/* An ordinary ssa name defined in the loop. */
add_phi_arg (phi_new, new_ssa_name, loop_latch_edge (new_loop));
@@ -566,7 +568,12 @@ slpeel_update_phi_nodes_for_guard1 (edge guard_edge, struct loop *loop,
else
{
current_new_name = get_current_def (loop_arg);
- gcc_assert (current_new_name);
+ /* current_def is not available only if the variable does not
+ change inside the loop, in which case we also don't care
+ about recording a current_def for it because we won't be
+ trying to create loop-exit-phis for it. */
+ if (!current_new_name)
+ continue;
}
#ifdef ENABLE_CHECKING
gcc_assert (get_current_def (current_new_name) == NULL_TREE);
@@ -987,7 +994,7 @@ slpeel_verify_cfg_after_peeling (struct loop *first_loop,
/* 1. Verify that one of the successors of first_loopt->exit is the preheader
of second_loop. */
- /* The preheader of new_loop is expected to have two predessors:
+ /* The preheader of new_loop is expected to have two predecessors:
first_loop->exit and the block that precedes first_loop. */
gcc_assert (EDGE_COUNT (loop2_entry_bb->preds) == 2
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index b824652795c..68fcf5dc9c2 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -38,8 +38,8 @@ Boston, MA 02111-1307, USA. */
#include "tree-chrec.h"
/* Set of SSA names found during the dominator traversal of a
- sub-graph in maybe_add_assert_expr. */
-static sbitmap found;
+ sub-graph in find_assert_locations. */
+static sbitmap found_in_subgraph;
/* Loop structure of the program. Used to analyze scalar evolutions
inside adjust_range_with_scev. */
@@ -48,20 +48,51 @@ static struct loops *cfg_loops;
/* Local functions. */
static int compare_values (tree val1, tree val2);
-/* Given a conditional predicate COND that has WHICH as one of its
- operands, return the other operand. No error checking is done.
- This helper assumes that COND is a comparison and WHICH is one of
- its operands. */
-
-static inline tree
-get_opposite_operand (tree cond, tree which)
+/* Location information for ASSERT_EXPRs. Each instance of this
+ structure describes an ASSERT_EXPR for an SSA name. Since a single
+ SSA name may have more than one assertion associated with it, these
+ locations are kept in a linked list attached to the corresponding
+ SSA name. */
+struct assert_locus_d
{
- if (TREE_OPERAND (cond, 0) == which)
- return TREE_OPERAND (cond, 1);
- else
- return TREE_OPERAND (cond, 0);
-}
+ /* Basic block where the assertion would be inserted. */
+ basic_block bb;
+
+ /* Some assertions need to be inserted on an edge (e.g., assertions
+ generated by COND_EXPRs). In those cases, BB will be NULL. */
+ edge e;
+
+ /* Pointer to the statement that generated this assertion. */
+ block_stmt_iterator si;
+
+ /* Predicate code for the ASSERT_EXPR. Must be COMPARISON_CLASS_P. */
+ enum tree_code comp_code;
+
+ /* Value being compared against. */
+ tree val;
+
+ /* Next node in the linked list. */
+ struct assert_locus_d *next;
+};
+typedef struct assert_locus_d *assert_locus_t;
+
+/* If bit I is present, it means that SSA name N_i has a list of
+ assertions that should be inserted in the IL. */
+static bitmap need_assert_for;
+
+/* Array of locations lists where to insert assertions. ASSERTS_FOR[I]
+ holds a list of ASSERT_LOCUS_T nodes that describe where
+ ASSERT_EXPRs for SSA name N_I should be inserted. */
+static assert_locus_t *asserts_for;
+
+/* Set of blocks visited in find_assert_locations. Used to avoid
+ visiting the same block more than once. */
+static sbitmap blocks_visited;
+
+/* Value range array. After propagation, VR_VALUE[I] holds the range
+ of values that SSA name N_I may take. */
+static value_range_t **vr_value;
/* Given a comparison code, return its opposite. Note that this is *not*
the same as inverting its truth value (invert_tree_comparison). Here we
@@ -104,12 +135,88 @@ opposite_comparison (enum tree_code code)
}
-/* Set value range VR to {T, MIN, MAX}. */
+/* Return true if EXPR computes a non-zero value. */
-static inline void
-set_value_range (value_range *vr, enum value_range_type t, tree min, tree max)
+bool
+expr_computes_nonzero (tree expr)
+{
+ /* Type casts won't change anything, so just strip them. */
+ STRIP_NOPS (expr);
+
+ /* Calling alloca, guarantees that the value is non-NULL. */
+ if (alloca_call_p (expr))
+ return true;
+
+ /* The address of a non-weak symbol is never NULL, unless the user
+ has requested not to remove NULL pointer checks. */
+ if (flag_delete_null_pointer_checks
+ && TREE_CODE (expr) == ADDR_EXPR
+ && DECL_P (TREE_OPERAND (expr, 0))
+ && !DECL_WEAK (TREE_OPERAND (expr, 0)))
+ return true;
+
+ /* IOR of any value with a nonzero value will result in a nonzero
+ value. */
+ if (TREE_CODE (expr) == BIT_IOR_EXPR
+ && integer_nonzerop (TREE_OPERAND (expr, 1)))
+ return true;
+
+ return false;
+}
+
+
+/* Return true if ARG is marked with the nonnull attribute in the
+ current function signature. */
+
+static bool
+nonnull_arg_p (tree arg)
+{
+ tree t, attrs, fntype;
+ unsigned HOST_WIDE_INT arg_num;
+
+ gcc_assert (TREE_CODE (arg) == PARM_DECL && POINTER_TYPE_P (TREE_TYPE (arg)));
+
+ fntype = TREE_TYPE (current_function_decl);
+ attrs = lookup_attribute ("nonnull", TYPE_ATTRIBUTES (fntype));
+
+ /* If "nonnull" wasn't specified, we know nothing about the argument. */
+ if (attrs == NULL_TREE)
+ return false;
+
+ /* If "nonnull" applies to all the arguments, then ARG is non-null. */
+ if (TREE_VALUE (attrs) == NULL_TREE)
+ return true;
+
+ /* Get the position number for ARG in the function signature. */
+ for (arg_num = 1, t = DECL_ARGUMENTS (current_function_decl);
+ t;
+ t = TREE_CHAIN (t), arg_num++)
+ {
+ if (t == arg)
+ break;
+ }
+
+ gcc_assert (t == arg);
+
+ /* Now see if ARG_NUM is mentioned in the nonnull list. */
+ for (t = TREE_VALUE (attrs); t; t = TREE_CHAIN (t))
+ {
+ if (compare_tree_int (TREE_VALUE (t), arg_num) == 0)
+ return true;
+ }
+
+ return false;
+}
+
+
+/* Set value range VR to {T, MIN, MAX, EQUIV}. */
+
+static void
+set_value_range (value_range_t *vr, enum value_range_type t, tree min,
+ tree max, bitmap equiv)
{
#if defined ENABLE_CHECKING
+ /* Check the validity of the range. */
if (t == VR_RANGE || t == VR_ANTI_RANGE)
{
int cmp;
@@ -123,114 +230,181 @@ set_value_range (value_range *vr, enum value_range_type t, tree min, tree max)
cmp = compare_values (min, max);
gcc_assert (cmp == 0 || cmp == -1 || cmp == -2);
}
-#endif
- if (t == VR_RANGE
- && INTEGRAL_TYPE_P (TREE_TYPE (min))
- && min == TYPE_MIN_VALUE (TREE_TYPE (min))
- && max == TYPE_MAX_VALUE (TREE_TYPE (max)))
- {
- /* Ranges that cover all the possible values for the type decay
- to VARYING. */
- vr->type = VR_VARYING;
- vr->min = NULL_TREE;
- vr->max = NULL_TREE;
- return;
- }
+ if (t == VR_UNDEFINED || t == VR_VARYING)
+ gcc_assert (min == NULL_TREE && max == NULL_TREE);
+
+ if (t == VR_UNDEFINED || t == VR_VARYING)
+ gcc_assert (equiv == NULL || bitmap_empty_p (equiv));
+#endif
vr->type = t;
vr->min = min;
vr->max = max;
+
+ /* Since updating the equivalence set involves deep copying the
+ bitmaps, only do it if absolutely necessary. */
+ if (vr->equiv == NULL)
+ vr->equiv = BITMAP_ALLOC (NULL);
+
+ if (equiv != vr->equiv)
+ {
+ if (equiv && !bitmap_empty_p (equiv))
+ bitmap_copy (vr->equiv, equiv);
+ else
+ bitmap_clear (vr->equiv);
+ }
}
-/* Similar to set_value_range but return true if any field of VR
- changed from its previous value. */
+/* Copy value range FROM into value range TO. */
-static inline bool
-update_value_range (value_range *vr, enum value_range_type t, tree min,
- tree max)
+static inline void
+copy_value_range (value_range_t *to, value_range_t *from)
{
- bool is_new = vr->type != t || vr->min != min || vr->max != max;
- if (is_new)
- set_value_range (vr, t, min, max);
+ set_value_range (to, from->type, from->min, from->max, from->equiv);
+}
- return is_new;
+
+/* Set value range VR to a non-NULL range of type TYPE. */
+
+static inline void
+set_value_range_to_nonnull (value_range_t *vr, tree type)
+{
+ tree zero = build_int_cst (type, 0);
+ set_value_range (vr, VR_ANTI_RANGE, zero, zero, vr->equiv);
+}
+
+
+/* Set value range VR to a NULL range of type TYPE. */
+
+static inline void
+set_value_range_to_null (value_range_t *vr, tree type)
+{
+ tree zero = build_int_cst (type, 0);
+ set_value_range (vr, VR_RANGE, zero, zero, vr->equiv);
+}
+
+
+/* Set value range VR to VR_VARYING. */
+
+static inline void
+set_value_range_to_varying (value_range_t *vr)
+{
+ vr->type = VR_VARYING;
+ vr->min = vr->max = NULL_TREE;
+ if (vr->equiv)
+ bitmap_clear (vr->equiv);
+}
+
+
+/* Set value range VR to VR_UNDEFINED. */
+
+static inline void
+set_value_range_to_undefined (value_range_t *vr)
+{
+ vr->type = VR_UNDEFINED;
+ vr->min = vr->max = NULL_TREE;
+ if (vr->equiv)
+ bitmap_clear (vr->equiv);
}
-/* Return value range information for VAR. Create an empty range if
- none existed. */
+/* Return value range information for VAR. Create an empty range
+ if none existed. */
-value_range *
+static value_range_t *
get_value_range (tree var)
{
- value_range *vr;
+ value_range_t *vr;
tree sym;
+ unsigned ver = SSA_NAME_VERSION (var);
- vr = SSA_NAME_VALUE_RANGE (var);
+ vr = vr_value[ver];
if (vr)
return vr;
/* Create a default value range. */
- vr = ggc_alloc (sizeof (*vr));
- memset ((void *) vr, 0, sizeof (*vr));
- SSA_NAME_VALUE_RANGE (var) = vr;
+ vr_value[ver] = vr = xmalloc (sizeof (*vr));
+ memset (vr, 0, sizeof (*vr));
- /* If VAR is a default definition for a PARM_DECL, then we have to
- assume a VARYING range for it. */
+ /* Allocate an equivalence set. */
+ vr->equiv = BITMAP_ALLOC (NULL);
+
+ /* If VAR is a default definition, the variable can take any value
+ in VAR's type. */
sym = SSA_NAME_VAR (var);
- if (TREE_CODE (sym) == PARM_DECL && var == var_ann (sym)->default_def)
- set_value_range (vr, VR_VARYING, NULL_TREE, NULL_TREE);
+ if (var == var_ann (sym)->default_def)
+ {
+ /* Try to use the "nonnull" attribute to create ~[0, 0]
+ anti-ranges for pointers. Note that this is only valid with
+ default definitions of PARM_DECLs. */
+ if (TREE_CODE (sym) == PARM_DECL
+ && POINTER_TYPE_P (TREE_TYPE (sym))
+ && nonnull_arg_p (sym))
+ set_value_range_to_nonnull (vr, TREE_TYPE (sym));
+ else
+ set_value_range_to_varying (vr);
+ }
return vr;
}
-/* Return true if value range VR involves at least one symbol. */
+/* Update the value range and equivalence set for variable VAR to
+ NEW_VR. Return true if NEW_VR is different from VAR's previous
+ value.
+
+ NOTE: This function assumes that NEW_VR is a temporary value range
+ object created for the sole purpose of updating VAR's range. The
+ storage used by the equivalence set from NEW_VR will be freed by
+ this function. Do not call update_value_range when NEW_VR
+ is the range object associated with another SSA name. */
static inline bool
-symbolic_range_p (value_range *vr)
+update_value_range (tree var, value_range_t *new_vr)
{
- return (!is_gimple_min_invariant (vr->min)
- || !is_gimple_min_invariant (vr->max));
-}
+ value_range_t *old_vr;
+ bool is_new;
+
+ /* Update the value range, if necessary. */
+ old_vr = get_value_range (var);
+ is_new = old_vr->type != new_vr->type
+ || old_vr->min != new_vr->min
+ || old_vr->max != new_vr->max
+ || (old_vr->equiv == NULL && new_vr->equiv)
+ || (old_vr->equiv && new_vr->equiv == NULL)
+ || (!bitmap_equal_p (old_vr->equiv, new_vr->equiv));
+ if (is_new)
+ set_value_range (old_vr, new_vr->type, new_vr->min, new_vr->max,
+ new_vr->equiv);
-/* Return true if EXPR computes a non-zero value. */
+ BITMAP_FREE (new_vr->equiv);
+ new_vr->equiv = NULL;
-bool
-expr_computes_nonzero (tree expr)
-{
- /* Type casts won't change anything, so just strip it. */
- STRIP_NOPS (expr);
+ return is_new;
+}
- /* Calling alloca, guarantees that the value is non-NULL. */
- if (alloca_call_p (expr))
- return true;
- /* The address of a non-weak symbol is never NULL, unless the user
- has requested not to remove NULL pointer checks. */
- if (flag_delete_null_pointer_checks
- && TREE_CODE (expr) == ADDR_EXPR
- && DECL_P (TREE_OPERAND (expr, 0))
- && !DECL_WEAK (TREE_OPERAND (expr, 0)))
- return true;
+/* Add VAR and VAR's equivalence set to EQUIV. */
- /* IOR of any value with a nonzero value will result in a nonzero
- value. */
- if (TREE_CODE (expr) == BIT_IOR_EXPR
- && integer_nonzerop (TREE_OPERAND (expr, 1)))
- return true;
+static void
+add_equivalence (bitmap equiv, tree var)
+{
+ unsigned ver = SSA_NAME_VERSION (var);
+ value_range_t *vr = vr_value[ver];
- return false;
+ bitmap_set_bit (equiv, ver);
+ if (vr && vr->equiv)
+ bitmap_ior_into (equiv, vr->equiv);
}
/* Return true if VR is ~[0, 0]. */
static inline bool
-range_is_nonnull (value_range *vr)
+range_is_nonnull (value_range_t *vr)
{
return vr->type == VR_ANTI_RANGE
&& integer_zerop (vr->min)
@@ -241,7 +415,7 @@ range_is_nonnull (value_range *vr)
/* Return true if VR is [0, 0]. */
static inline bool
-range_is_null (value_range *vr)
+range_is_null (value_range_t *vr)
{
return vr->type == VR_RANGE
&& integer_zerop (vr->min)
@@ -249,32 +423,42 @@ range_is_null (value_range *vr)
}
-/* Set value range VR to a non-NULL range of type TYPE. */
+/* Return true if value range VR involves at least one symbol. */
-static inline void
-set_value_range_to_nonnull (value_range *vr, tree type)
+static inline bool
+symbolic_range_p (value_range_t *vr)
{
- tree zero = build_int_cst (type, 0);
- set_value_range (vr, VR_ANTI_RANGE, zero, zero);
+ return (!is_gimple_min_invariant (vr->min)
+ || !is_gimple_min_invariant (vr->max));
}
-/* Set value range VR to a NULL range of type TYPE. */
+/* Like expr_computes_nonzero, but this function uses value ranges
+ obtained so far. */
-static inline void
-set_value_range_to_null (value_range *vr, tree type)
+static bool
+vrp_expr_computes_nonzero (tree expr)
{
- tree zero = build_int_cst (type, 0);
- set_value_range (vr, VR_RANGE, zero, zero);
-}
+ if (expr_computes_nonzero (expr))
+ return true;
+ /* If we have an expression of the form &X->a, then the expression
+ is nonnull if X is nonnull. */
+ if (TREE_CODE (expr) == ADDR_EXPR)
+ {
+ tree base = get_base_address (TREE_OPERAND (expr, 0));
-/* Set value range VR to VR_VARYING. */
+ if (base != NULL_TREE
+ && TREE_CODE (base) == INDIRECT_REF
+ && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
+ {
+ value_range_t *vr = get_value_range (TREE_OPERAND (base, 0));
+ if (range_is_nonnull (vr))
+ return true;
+ }
+ }
-static inline void
-set_value_range_to_varying (value_range *vr)
-{
- set_value_range (vr, VR_VARYING, NULL_TREE, NULL_TREE);
+ return false;
}
@@ -414,6 +598,10 @@ compare_values (tree val1, tree val2)
if (!is_gimple_min_invariant (val1) || !is_gimple_min_invariant (val2))
return -2;
+ /* We cannot compare overflowed values. */
+ if (TREE_OVERFLOW (val1) || TREE_OVERFLOW (val2))
+ return -2;
+
if (!POINTER_TYPE_P (TREE_TYPE (val1)))
return tree_int_cst_compare (val1, val2);
else
@@ -449,7 +637,7 @@ compare_values (tree val1, tree val2)
-2 if we cannot tell either way. */
static inline int
-value_inside_range (tree val, value_range *vr)
+value_inside_range (tree val, value_range_t *vr)
{
int cmp1, cmp2;
@@ -469,7 +657,7 @@ value_inside_range (tree val, value_range *vr)
intersection. */
static inline bool
-value_ranges_intersect_p (value_range *vr0, value_range *vr1)
+value_ranges_intersect_p (value_range_t *vr0, value_range_t *vr1)
{
return (value_inside_range (vr1->min, vr0) == 1
|| value_inside_range (vr1->max, vr0) == 1
@@ -478,38 +666,77 @@ value_ranges_intersect_p (value_range *vr0, value_range *vr1)
}
+/* Return true if VR includes the value zero, false otherwise. */
+
+static inline bool
+range_includes_zero_p (value_range_t *vr)
+{
+ tree zero;
+
+ gcc_assert (vr->type != VR_UNDEFINED
+ && vr->type != VR_VARYING
+ && !symbolic_range_p (vr));
+
+ zero = build_int_cst (TREE_TYPE (vr->min), 0);
+ return (value_inside_range (zero, vr) == 1);
+}
+
+
/* Extract value range information from an ASSERT_EXPR EXPR and store
it in *VR_P. */
static void
-extract_range_from_assert (value_range *vr_p, tree expr)
+extract_range_from_assert (value_range_t *vr_p, tree expr)
{
- tree var, cond, limit, type;
- value_range *var_vr;
+ tree var, cond, limit, min, max, type;
+ value_range_t *var_vr, *limit_vr;
enum tree_code cond_code;
var = ASSERT_EXPR_VAR (expr);
cond = ASSERT_EXPR_COND (expr);
- cond_code = TREE_CODE (cond);
gcc_assert (COMPARISON_CLASS_P (cond));
/* Find VAR in the ASSERT_EXPR conditional. */
- limit = get_opposite_operand (cond, var);
- type = TREE_TYPE (limit);
+ if (var == TREE_OPERAND (cond, 0))
+ {
+ /* If the predicate is of the form VAR COMP LIMIT, then we just
+ take LIMIT from the RHS and use the same comparison code. */
+ limit = TREE_OPERAND (cond, 1);
+ cond_code = TREE_CODE (cond);
+ }
+ else
+ {
+ /* If the predicate is of the form LIMIT COMP VAR, then we need
+ to flip around the comparison code to create the proper range
+ for VAR. */
+ limit = TREE_OPERAND (cond, 0);
+ cond_code = opposite_comparison (TREE_CODE (cond));
+ }
+ type = TREE_TYPE (limit);
gcc_assert (limit != var);
- /* For pointer arithmetic, we only keep track of anti-ranges
- (NE_EXPR). Notice that we don't need to handle EQ_EXPR in these
- cases because assertions with equalities are never generated.
- The assert pass generates straight assignments in those cases. */
- if (POINTER_TYPE_P (type) && cond_code != NE_EXPR)
+ /* For pointer arithmetic, we only keep track of pointer equality
+ and inequality. */
+ if (POINTER_TYPE_P (type) && cond_code != NE_EXPR && cond_code != EQ_EXPR)
{
set_value_range_to_varying (vr_p);
return;
}
+ /* If LIMIT is another SSA name and LIMIT has a range of its own,
+ try to use LIMIT's range to avoid creating symbolic ranges
+ unnecessarily. */
+ limit_vr = (TREE_CODE (limit) == SSA_NAME) ? get_value_range (limit) : NULL;
+
+ /* LIMIT's range is only interesting if it has any useful information. */
+ if (limit_vr
+ && (limit_vr->type == VR_UNDEFINED
+ || limit_vr->type == VR_VARYING
+ || symbolic_range_p (limit_vr)))
+ limit_vr = NULL;
+
/* Special handling for integral types with super-types. Some FEs
construct integral types derived from other types and restrict
the range of values these new types may take.
@@ -538,7 +765,9 @@ extract_range_from_assert (value_range *vr_p, tree expr)
So, the only sensible thing we can do for now is set the
resulting range to VR_VARYING. TODO, would having symbolic -INF
and +INF values be worth the trouble? */
- if (TREE_TYPE (type))
+ if (TREE_CODE (limit) != SSA_NAME
+ && INTEGRAL_TYPE_P (type)
+ && TREE_TYPE (type))
{
if (cond_code == LE_EXPR || cond_code == LT_EXPR)
{
@@ -568,29 +797,125 @@ extract_range_from_assert (value_range *vr_p, tree expr)
}
}
- if (TREE_CODE (cond) == NE_EXPR)
- set_value_range (vr_p, VR_ANTI_RANGE, limit, limit);
- else if (TREE_CODE (cond) == LE_EXPR)
- set_value_range (vr_p, VR_RANGE, TYPE_MIN_VALUE (type), limit);
- else if (TREE_CODE (cond) == LT_EXPR)
+ /* The new range has the same set of equivalences of VAR's range. */
+ gcc_assert (vr_p->equiv == NULL);
+ vr_p->equiv = BITMAP_ALLOC (NULL);
+ add_equivalence (vr_p->equiv, var);
+
+ /* Extract a new range based on the asserted comparison for VAR and
+ LIMIT's value range. Notice that if LIMIT has an anti-range, we
+ will only use it for equality comparisons (EQ_EXPR). For any
+ other kind of assertion, we cannot derive a range from LIMIT's
+ anti-range that can be used to describe the new range. For
+ instance, ASSERT_EXPR <x_2, x_2 <= b_4>. If b_4 is ~[2, 10],
+ then b_4 takes on the ranges [-INF, 1] and [11, +INF]. There is
+ no single range for x_2 that could describe LE_EXPR, so we might
+ as well build the range [b_4, +INF] for it. */
+ if (cond_code == EQ_EXPR)
{
- tree one = build_int_cst (type, 1);
- set_value_range (vr_p, VR_RANGE, TYPE_MIN_VALUE (type),
- fold (build (MINUS_EXPR, type, limit, one)));
+ enum value_range_type range_type;
+
+ if (limit_vr)
+ {
+ range_type = limit_vr->type;
+ min = limit_vr->min;
+ max = limit_vr->max;
+ }
+ else
+ {
+ range_type = VR_RANGE;
+ min = limit;
+ max = limit;
+ }
+
+ set_value_range (vr_p, range_type, min, max, vr_p->equiv);
+
+ /* When asserting the equality VAR == LIMIT and LIMIT is another
+ SSA name, the new range will also inherit the equivalence set
+ from LIMIT. */
+ if (TREE_CODE (limit) == SSA_NAME)
+ add_equivalence (vr_p->equiv, limit);
+ }
+ else if (cond_code == NE_EXPR)
+ {
+ /* As described above, when LIMIT's range is an anti-range and
+ this assertion is an inequality (NE_EXPR), then we cannot
+ derive anything from the anti-range. For instance, if
+ LIMIT's range was ~[0, 0], the assertion 'VAR != LIMIT' does
+ not imply that VAR's range is [0, 0]. So, in the case of
+ anti-ranges, we just assert the inequality using LIMIT and
+ not its anti-range. */
+ if (limit_vr == NULL
+ || limit_vr->type == VR_ANTI_RANGE)
+ {
+ min = limit;
+ max = limit;
+ }
+ else
+ {
+ min = limit_vr->min;
+ max = limit_vr->max;
+ }
+
+ /* If MIN and MAX cover the whole range for their type, then
+ just use the original LIMIT. */
+ if (INTEGRAL_TYPE_P (type)
+ && min == TYPE_MIN_VALUE (type)
+ && max == TYPE_MAX_VALUE (type))
+ min = max = limit;
+
+ set_value_range (vr_p, VR_ANTI_RANGE, min, max, vr_p->equiv);
+ }
+ else if (cond_code == LE_EXPR || cond_code == LT_EXPR)
+ {
+ min = TYPE_MIN_VALUE (type);
+
+ if (limit_vr == NULL || limit_vr->type == VR_ANTI_RANGE)
+ max = limit;
+ else
+ {
+ /* If LIMIT_VR is of the form [N1, N2], we need to build the
+ range [MIN, N2] for LE_EXPR and [MIN, N2 - 1] for
+ LT_EXPR. */
+ max = limit_vr->max;
+ }
+
+ /* For LT_EXPR, we create the range [MIN, MAX - 1]. */
+ if (cond_code == LT_EXPR)
+ {
+ tree one = build_int_cst (type, 1);
+ max = fold (build (MINUS_EXPR, type, max, one));
+ }
+
+ set_value_range (vr_p, VR_RANGE, min, max, vr_p->equiv);
}
- else if (TREE_CODE (cond) == GE_EXPR)
- set_value_range (vr_p, VR_RANGE, limit, TYPE_MAX_VALUE (type));
- else if (TREE_CODE (cond) == GT_EXPR)
+ else if (cond_code == GE_EXPR || cond_code == GT_EXPR)
{
- tree one = build_int_cst (type, 1);
- set_value_range (vr_p, VR_RANGE,
- fold (build (PLUS_EXPR, type, limit, one)),
- TYPE_MAX_VALUE (type));
+ max = TYPE_MAX_VALUE (type);
+
+ if (limit_vr == NULL || limit_vr->type == VR_ANTI_RANGE)
+ min = limit;
+ else
+ {
+ /* If LIMIT_VR is of the form [N1, N2], we need to build the
+ range [N1, MAX] for GE_EXPR and [N1 + 1, MAX] for
+ GT_EXPR. */
+ min = limit_vr->min;
+ }
+
+ /* For GT_EXPR, we create the range [MIN + 1, MAX]. */
+ if (cond_code == GT_EXPR)
+ {
+ tree one = build_int_cst (type, 1);
+ min = fold (build (PLUS_EXPR, type, min, one));
+ }
+
+ set_value_range (vr_p, VR_RANGE, min, max, vr_p->equiv);
}
else
gcc_unreachable ();
- /* If VAR already has a known range and the two ranges have a
+ /* If VAR already had a known range and the two ranges have a
non-empty intersection, we can refine the resulting range.
Since the assert expression creates an equivalency and at the
same time it asserts a predicate, we can take the intersection of
@@ -600,8 +925,6 @@ extract_range_from_assert (value_range *vr_p, tree expr)
&& vr_p->type == VR_RANGE
&& value_ranges_intersect_p (var_vr, vr_p))
{
- tree min, max;
-
/* Use the larger of the two minimums. */
if (compare_values (vr_p->min, var_vr->min) == -1)
min = var_vr->min;
@@ -614,7 +937,7 @@ extract_range_from_assert (value_range *vr_p, tree expr)
else
max = vr_p->max;
- set_value_range (vr_p, vr_p->type, min, max);
+ set_value_range (vr_p, vr_p->type, min, max, vr_p->equiv);
}
}
@@ -633,14 +956,16 @@ extract_range_from_assert (value_range *vr_p, tree expr)
always false. */
static void
-extract_range_from_ssa_name (value_range *vr, tree var)
+extract_range_from_ssa_name (value_range_t *vr, tree var)
{
- value_range *var_vr = get_value_range (var);
+ value_range_t *var_vr = get_value_range (var);
if (var_vr->type != VR_UNDEFINED && var_vr->type != VR_VARYING)
- *vr = *var_vr;
+ copy_value_range (vr, var_vr);
else
- set_value_range (vr, VR_RANGE, var, var);
+ set_value_range (vr, VR_RANGE, var, var, NULL);
+
+ add_equivalence (vr->equiv, var);
}
@@ -648,12 +973,13 @@ extract_range_from_ssa_name (value_range *vr, tree var)
the ranges of each of its operands and the expression code. */
static void
-extract_range_from_binary_expr (value_range *vr, tree expr)
+extract_range_from_binary_expr (value_range_t *vr, tree expr)
{
enum tree_code code = TREE_CODE (expr);
tree op0, op1, min, max;
- value_range vr0, vr1;
int cmp;
+ value_range_t vr0 = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
+ value_range_t vr1 = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
/* Not all binary expressions can be applied to ranges in a
meaningful way. Handle only arithmetic operations. */
@@ -666,7 +992,12 @@ extract_range_from_binary_expr (value_range *vr, tree expr)
&& code != EXACT_DIV_EXPR
&& code != ROUND_DIV_EXPR
&& code != MIN_EXPR
- && code != MAX_EXPR)
+ && code != MAX_EXPR
+ && code != TRUTH_ANDIF_EXPR
+ && code != TRUTH_ORIF_EXPR
+ && code != TRUTH_AND_EXPR
+ && code != TRUTH_OR_EXPR
+ && code != TRUTH_XOR_EXPR)
{
set_value_range_to_varying (vr);
return;
@@ -677,48 +1008,34 @@ extract_range_from_binary_expr (value_range *vr, tree expr)
op0 = TREE_OPERAND (expr, 0);
if (TREE_CODE (op0) == SSA_NAME)
vr0 = *(get_value_range (op0));
+ else if (is_gimple_min_invariant (op0))
+ set_value_range (&vr0, VR_RANGE, op0, op0, NULL);
else
- {
- if (is_gimple_min_invariant (op0))
- set_value_range (&vr0, VR_RANGE, op0, op0);
- else
- set_value_range_to_varying (&vr0);
- }
+ set_value_range_to_varying (&vr0);
op1 = TREE_OPERAND (expr, 1);
if (TREE_CODE (op1) == SSA_NAME)
vr1 = *(get_value_range (op1));
+ else if (is_gimple_min_invariant (op1))
+ set_value_range (&vr1, VR_RANGE, op1, op1, NULL);
else
- {
- if (is_gimple_min_invariant (op1))
- set_value_range (&vr1, VR_RANGE, op1, op1);
- else
- set_value_range_to_varying (&vr1);
- }
+ set_value_range_to_varying (&vr1);
/* If either range is UNDEFINED, so is the result. */
if (vr0.type == VR_UNDEFINED || vr1.type == VR_UNDEFINED)
{
- set_value_range (vr, VR_UNDEFINED, NULL_TREE, NULL_TREE);
+ set_value_range_to_undefined (vr);
return;
}
- /* If either range is VARYING, so is the result. */
- if (vr0.type == VR_VARYING || vr1.type == VR_VARYING)
- {
- set_value_range_to_varying (vr);
- return;
- }
-
- /* If the ranges are of different types, the result is VARYING. */
- if (vr0.type != vr1.type)
- {
- set_value_range_to_varying (vr);
- return;
- }
-
- /* TODO. Refuse to do any symbolic range operations for now. */
- if (symbolic_range_p (&vr0) || symbolic_range_p (&vr1))
+ /* Refuse to operate on VARYING ranges, ranges of different kinds
+ and symbolic ranges. TODO, we may be able to derive anti-ranges
+ in some cases. */
+ if (vr0.type == VR_VARYING
+ || vr1.type == VR_VARYING
+ || vr0.type != vr1.type
+ || symbolic_range_p (&vr0)
+ || symbolic_range_p (&vr1))
{
set_value_range_to_varying (vr);
return;
@@ -730,17 +1047,12 @@ extract_range_from_binary_expr (value_range *vr, tree expr)
|| POINTER_TYPE_P (TREE_TYPE (op1)))
{
/* For pointer types, we are really only interested in asserting
- whether the expression evaluates to non-NULL. FIXME. We
- used to gcc_assert (code == PLUS_EXPR || code == MINUS_EXPR),
- but ivopts is generating expressions with pointer
- multiplication in them. */
+ whether the expression evaluates to non-NULL. FIXME, we used
+ to gcc_assert (code == PLUS_EXPR || code == MINUS_EXPR), but
+ ivopts is generating expressions with pointer multiplication
+ in them. */
if (code == PLUS_EXPR)
- {
- /* Assume that pointers can never wrap around. FIXME, Is
- this always safe? */
- tree zero = build_int_cst (TREE_TYPE (expr), 0);
- set_value_range (vr, VR_ANTI_RANGE, zero, zero);
- }
+ set_value_range_to_nonnull (vr, TREE_TYPE (expr));
else
{
/* Subtracting from a pointer, may yield 0, so just drop the
@@ -753,10 +1065,20 @@ extract_range_from_binary_expr (value_range *vr, tree expr)
/* For integer ranges, apply the operation to each end of the
range and see what we end up with. */
- if (code == PLUS_EXPR
- || code == MULT_EXPR
- || code == MIN_EXPR
- || code == MAX_EXPR)
+ if (code == TRUTH_ANDIF_EXPR
+ || code == TRUTH_ORIF_EXPR
+ || code == TRUTH_AND_EXPR
+ || code == TRUTH_OR_EXPR
+ || code == TRUTH_XOR_EXPR)
+ {
+ /* Boolean expressions cannot be folded with int_const_binop. */
+ min = fold_binary (code, TREE_TYPE (expr), vr0.min, vr1.min);
+ max = fold_binary (code, TREE_TYPE (expr), vr0.max, vr1.max);
+ }
+ else if (code == PLUS_EXPR
+ || code == MULT_EXPR
+ || code == MIN_EXPR
+ || code == MAX_EXPR)
{
/* For operations that make the resulting range directly
proportional to the original ranges, apply the operation to
@@ -764,14 +1086,130 @@ extract_range_from_binary_expr (value_range *vr, tree expr)
min = int_const_binop (code, vr0.min, vr1.min, 0);
max = int_const_binop (code, vr0.max, vr1.max, 0);
}
- else
+ else if (code == TRUNC_DIV_EXPR
+ || code == FLOOR_DIV_EXPR
+ || code == CEIL_DIV_EXPR
+ || code == EXACT_DIV_EXPR
+ || code == ROUND_DIV_EXPR)
+ {
+ tree zero;
+
+ /* Divisions are a bit tricky to handle, depending on the mix of
+ signs we have in the two range, we will need to divide
+ different values to get the minimum and maximum values for
+ the new range. If VR1 includes zero, the result is VARYING. */
+ if (range_includes_zero_p (&vr1))
+ {
+ set_value_range_to_varying (vr);
+ return;
+ }
+
+ /* We have three main variations to handle for VR0: all negative
+ values, all positive values and a mix of negative and
+ positive. For each of these, we need to consider if VR1 is
+ all negative or all positive. In total, there are 6
+ combinations to handle. */
+ zero = build_int_cst (TREE_TYPE (expr), 0);
+ if (compare_values (vr0.max, zero) == -1)
+ {
+ /* VR0 is all negative. */
+ if (compare_values (vr1.min, zero) == 1)
+ {
+ /* If VR1 is all positive, the new range is obtained
+ with [VR0.MIN / VR1.MIN, VR0.MAX / VR1.MAX]. */
+ min = int_const_binop (code, vr0.min, vr1.min, 0);
+ max = int_const_binop (code, vr0.max, vr1.max, 0);
+ }
+ else
+ {
+ /* If VR1 is all negative, the new range is obtained
+ with [VR0.MAX / VR1.MIN, VR0.MIN / VR1.MAX]. */
+ gcc_assert (compare_values (vr1.max, zero) == -1);
+ min = int_const_binop (code, vr0.max, vr1.min, 0);
+ max = int_const_binop (code, vr0.min, vr1.max, 0);
+ }
+ }
+ else if (range_includes_zero_p (&vr0))
+ {
+ /* VR0 is a mix of negative and positive values. */
+ if (compare_values (vr1.min, zero) == 1)
+ {
+ /* If VR1 is all positive, the new range is obtained
+ with [VR0.MIN / VR1.MIN, VR0.MAX / VR1.MIN]. */
+ min = int_const_binop (code, vr0.min, vr1.min, 0);
+ max = int_const_binop (code, vr0.max, vr1.min, 0);
+ }
+ else
+ {
+ /* If VR1 is all negative, the new range is obtained
+ with [VR0.MAX / VR1.MAX, VR0.MIN / VR1.MAX]. */
+ gcc_assert (compare_values (vr1.max, zero) == -1);
+ min = int_const_binop (code, vr0.max, vr1.max, 0);
+ max = int_const_binop (code, vr0.min, vr1.max, 0);
+ }
+ }
+ else
+ {
+ /* VR0 is all positive. */
+ gcc_assert (compare_values (vr0.min, zero) == 1);
+ if (compare_values (vr1.min, zero) == 1)
+ {
+ /* If VR1 is all positive, the new range is obtained
+ with [VR0.MIN / VR1.MAX, VR0.MAX / VR1.MIN]. */
+ min = int_const_binop (code, vr0.min, vr1.max, 0);
+ max = int_const_binop (code, vr0.max, vr1.min, 0);
+ }
+ else
+ {
+ /* If VR1 is all negative, the new range is obtained
+ with [VR0.MAX / VR1.MAX, VR0.MIN / VR1.MIN]. */
+ gcc_assert (compare_values (vr1.max, zero) == -1);
+ min = int_const_binop (code, vr0.max, vr1.max, 0);
+ max = int_const_binop (code, vr0.min, vr1.min, 0);
+ }
+ }
+ }
+ else if (code == MINUS_EXPR)
{
- /* For operations that make the resulting range inversely
- proportional to the original ranges (-, /), apply the
- operation to the opposite ends of each range. */
+ /* For MINUS_EXPR, apply the operation to the opposite ends of
+ each range. */
min = int_const_binop (code, vr0.min, vr1.max, 0);
max = int_const_binop (code, vr0.max, vr1.min, 0);
}
+ else
+ gcc_unreachable ();
+
+ /* If MAX overflowed, then the result depends on whether we are
+ using wrapping arithmetic or not. */
+ if (TREE_OVERFLOW (max))
+ {
+ /* If we are using wrapping arithmetic, set the result to
+ VARYING. */
+ if (flag_wrapv)
+ {
+ set_value_range_to_varying (vr);
+ return;
+ }
+
+ /* Otherwise, set MAX to +INF. */
+ max = TYPE_MAX_VALUE (TREE_TYPE (expr));
+ }
+
+ /* If MIN overflowed, then the result depends on whether we are
+ using wrapping arithmetic or not. */
+ if (TREE_OVERFLOW (min))
+ {
+ /* If we are using wrapping arithmetic, set the result to
+ VARYING. */
+ if (flag_wrapv)
+ {
+ set_value_range_to_varying (vr);
+ return;
+ }
+
+ /* Otherwise, set MIN to -INF. */
+ min = TYPE_MIN_VALUE (TREE_TYPE (expr));
+ }
cmp = compare_values (min, max);
if (cmp == -2 || cmp == 1)
@@ -782,36 +1220,7 @@ extract_range_from_binary_expr (value_range *vr, tree expr)
set_value_range_to_varying (vr);
}
else
- set_value_range (vr, vr0.type, min, max);
-}
-
-
-/* Like expr_computes_nonzero, but this function uses value ranges
- obtained so far. */
-
-static bool
-vrp_expr_computes_nonzero (tree expr)
-{
- if (expr_computes_nonzero (expr))
- return true;
-
- /* If we have an expression of the form &X->a, then the expression
- is nonnull if X is nonnull. */
- if (TREE_CODE (expr) == ADDR_EXPR)
- {
- tree base = get_base_address (TREE_OPERAND (expr, 0));
-
- if (base != NULL_TREE
- && TREE_CODE (base) == INDIRECT_REF
- && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
- {
- value_range *vr = get_value_range (TREE_OPERAND (base, 0));
- if (range_is_nonnull (vr))
- return true;
- }
- }
-
- return false;
+ set_value_range (vr, vr0.type, min, max, NULL);
}
@@ -819,51 +1228,53 @@ vrp_expr_computes_nonzero (tree expr)
the range of its operand and the expression code. */
static void
-extract_range_from_unary_expr (value_range *vr, tree expr)
+extract_range_from_unary_expr (value_range_t *vr, tree expr)
{
enum tree_code code = TREE_CODE (expr);
tree min, max, op0;
- value_range vr0;
int cmp;
+ value_range_t vr0 = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
+
+ /* Refuse to operate on certain unary expressions for which we
+ cannot easily determine a resulting range. */
+ if (code == FIX_TRUNC_EXPR
+ || code == FIX_CEIL_EXPR
+ || code == FIX_FLOOR_EXPR
+ || code == FIX_ROUND_EXPR
+ || code == FLOAT_EXPR
+ || code == BIT_NOT_EXPR
+ || code == NON_LVALUE_EXPR
+ || code == CONJ_EXPR)
+ {
+ set_value_range_to_varying (vr);
+ return;
+ }
/* Get value ranges for the operand. For constant operands, create
a new value range with the operand to simplify processing. */
op0 = TREE_OPERAND (expr, 0);
if (TREE_CODE (op0) == SSA_NAME)
vr0 = *(get_value_range (op0));
+ else if (is_gimple_min_invariant (op0))
+ set_value_range (&vr0, VR_RANGE, op0, op0, NULL);
else
- {
- if (is_gimple_min_invariant (op0))
- set_value_range (&vr0, VR_RANGE, op0, op0);
- else
- set_value_range_to_varying (&vr0);
- }
+ set_value_range_to_varying (&vr0);
/* If VR0 is UNDEFINED, so is the result. */
if (vr0.type == VR_UNDEFINED)
{
- set_value_range (vr, VR_UNDEFINED, NULL_TREE, NULL_TREE);
+ set_value_range_to_undefined (vr);
return;
}
- /* If VR0 is VARYING, so is the result. */
- if (vr0.type == VR_VARYING)
- {
- set_value_range_to_varying (vr);
- return;
- }
-
- /* TODO. Refuse to do any symbolic range operations for now. */
- if (symbolic_range_p (&vr0))
- {
- set_value_range_to_varying (vr);
- return;
- }
-
- /* If the operand is neither a pointer nor an integral type, set the
- range to VARYING. TODO, we may set the range to non-zero. */
- if (!INTEGRAL_TYPE_P (TREE_TYPE (op0))
- && !POINTER_TYPE_P (TREE_TYPE (op0)))
+ /* Refuse to operate on varying and symbolic ranges. Also, if the
+ operand is neither a pointer nor an integral type, set the
+ resulting range to VARYING. TODO, in some cases we may be able
+ to derive anti-ranges (like non-zero values). */
+ if (vr0.type == VR_VARYING
+ || (!INTEGRAL_TYPE_P (TREE_TYPE (op0))
+ && !POINTER_TYPE_P (TREE_TYPE (op0)))
+ || symbolic_range_p (&vr0))
{
set_value_range_to_varying (vr);
return;
@@ -899,8 +1310,52 @@ extract_range_from_unary_expr (value_range *vr, tree expr)
/* Apply the operation to each end of the range and see what we end
up with. */
- min = fold_unary_to_constant (code, TREE_TYPE (expr), vr0.min);
- max = fold_unary_to_constant (code, TREE_TYPE (expr), vr0.max);
+ if (code == NEGATE_EXPR
+ && !TYPE_UNSIGNED (TREE_TYPE (expr)))
+ {
+ /* Negating an anti-range doesn't really do anything to it. The
+ new range will also not take on the same range of values
+ excluded by the original anti-range. */
+ if (vr0.type == VR_ANTI_RANGE)
+ {
+ copy_value_range (vr, &vr0);
+ return;
+ }
+
+ /* NEGATE_EXPR flips the range around. */
+ min = (vr0.max == TYPE_MAX_VALUE (TREE_TYPE (expr)))
+ ? TYPE_MIN_VALUE (TREE_TYPE (expr))
+ : fold_unary_to_constant (code, TREE_TYPE (expr), vr0.max);
+
+ max = (vr0.min == TYPE_MIN_VALUE (TREE_TYPE (expr)))
+ ? TYPE_MAX_VALUE (TREE_TYPE (expr))
+ : fold_unary_to_constant (code, TREE_TYPE (expr), vr0.min);
+ }
+ else if (code == ABS_EXPR
+ && !TYPE_UNSIGNED (TREE_TYPE (expr)))
+ {
+ /* ABS_EXPR may flip the range around, if the original range
+ included negative values. */
+ min = (vr0.min == TYPE_MIN_VALUE (TREE_TYPE (expr)))
+ ? TYPE_MAX_VALUE (TREE_TYPE (expr))
+ : fold_unary_to_constant (code, TREE_TYPE (expr), vr0.min);
+
+ max = fold_unary_to_constant (code, TREE_TYPE (expr), vr0.max);
+
+ /* If the range was reversed, swap MIN and MAX. */
+ if (compare_values (min, max) == 1)
+ {
+ tree t = min;
+ min = max;
+ max = t;
+ }
+ }
+ else
+ {
+ /* Otherwise, operate on each end of the range. */
+ min = fold_unary_to_constant (code, TREE_TYPE (expr), vr0.min);
+ max = fold_unary_to_constant (code, TREE_TYPE (expr), vr0.max);
+ }
cmp = compare_values (min, max);
if (cmp == -2 || cmp == 1)
@@ -911,15 +1366,35 @@ extract_range_from_unary_expr (value_range *vr, tree expr)
set_value_range_to_varying (vr);
}
else
- set_value_range (vr, vr0.type, min, max);
+ set_value_range (vr, vr0.type, min, max, NULL);
+}
+
+
+/* Extract range information from a comparison expression EXPR based
+ on the range of its operand and the expression code. */
+
+static void
+extract_range_from_comparison (value_range_t *vr, tree expr)
+{
+ tree val = vrp_evaluate_conditional (expr, false);
+ if (val)
+ {
+ /* Since this expression was found on the RHS of an assignment,
+ its type may be different from _Bool. Convert VAL to EXPR's
+ type. */
+ val = fold_convert (TREE_TYPE (expr), val);
+ set_value_range (vr, VR_RANGE, val, val, vr->equiv);
+ }
+ else
+ set_value_range_to_varying (vr);
}
/* Try to compute a useful range out of expression EXPR and store it
- in *VR_P. */
+ in *VR. */
static void
-extract_range_from_expr (value_range *vr, tree expr)
+extract_range_from_expr (value_range_t *vr, tree expr)
{
enum tree_code code = TREE_CODE (expr);
@@ -927,14 +1402,21 @@ extract_range_from_expr (value_range *vr, tree expr)
extract_range_from_assert (vr, expr);
else if (code == SSA_NAME)
extract_range_from_ssa_name (vr, expr);
- else if (TREE_CODE_CLASS (code) == tcc_binary)
+ else if (TREE_CODE_CLASS (code) == tcc_binary
+ || code == TRUTH_ANDIF_EXPR
+ || code == TRUTH_ORIF_EXPR
+ || code == TRUTH_AND_EXPR
+ || code == TRUTH_OR_EXPR
+ || code == TRUTH_XOR_EXPR)
extract_range_from_binary_expr (vr, expr);
else if (TREE_CODE_CLASS (code) == tcc_unary)
extract_range_from_unary_expr (vr, expr);
+ else if (TREE_CODE_CLASS (code) == tcc_comparison)
+ extract_range_from_comparison (vr, expr);
else if (vrp_expr_computes_nonzero (expr))
set_value_range_to_nonnull (vr, TREE_TYPE (expr));
- else if (TREE_CODE (expr) == INTEGER_CST)
- set_value_range (vr, VR_RANGE, expr, expr);
+ else if (is_gimple_min_invariant (expr))
+ set_value_range (vr, VR_RANGE, expr, expr, NULL);
else
set_value_range_to_varying (vr);
}
@@ -945,7 +1427,7 @@ extract_range_from_expr (value_range *vr, tree expr)
for VAR. If so, update VR with the new limits. */
static void
-adjust_range_with_scev (value_range *vr, struct loop *l, tree var)
+adjust_range_with_scev (value_range_t *vr, struct loop *l, tree var)
{
tree init, step, chrec;
bool init_is_max;
@@ -975,6 +1457,10 @@ adjust_range_with_scev (value_range *vr, struct loop *l, tree var)
if (INTEGRAL_TYPE_P (TREE_TYPE (step)) && TYPE_UNSIGNED (TREE_TYPE (step)))
return;
+ /* Do not adjust ranges when using wrapping arithmetic. */
+ if (flag_wrapv)
+ return;
+
/* If STEP is negative, then INIT is the maximum value the range
will take. Otherwise, INIT is the minimum value. */
init_is_max = (tree_int_cst_sgn (step) < 0);
@@ -985,9 +1471,11 @@ adjust_range_with_scev (value_range *vr, struct loop *l, tree var)
/* For VARYING or UNDEFINED ranges, just about anything we get
from scalar evolutions should be better. */
if (init_is_max)
- set_value_range (vr, VR_RANGE, TYPE_MIN_VALUE (TREE_TYPE (init)), init);
+ set_value_range (vr, VR_RANGE, TYPE_MIN_VALUE (TREE_TYPE (init)),
+ init, vr->equiv);
else
- set_value_range (vr, VR_RANGE, init, TYPE_MAX_VALUE (TREE_TYPE (init)));
+ set_value_range (vr, VR_RANGE, init, TYPE_MAX_VALUE (TREE_TYPE (init)),
+ vr->equiv);
}
else if (vr->type == VR_RANGE)
{
@@ -1024,23 +1512,24 @@ adjust_range_with_scev (value_range *vr, struct loop *l, tree var)
}
}
- set_value_range (vr, VR_RANGE, min, max);
+ set_value_range (vr, VR_RANGE, min, max, vr->equiv);
}
}
/* Given two numeric value ranges VR0, VR1 and a comparison code COMP:
- - Return BOOLEAN_TRUE_NODE if VR0 COMP VR1 always returns true for all the
- values in the ranges.
+ - Return BOOLEAN_TRUE_NODE if VR0 COMP VR1 always returns true for
+ all the values in the ranges.
- Return BOOLEAN_FALSE_NODE if the comparison always returns false.
- - Return NULL_TREE if it is not always possible to determine the value of
- the comparison. */
+ - Return NULL_TREE if it is not always possible to determine the
+ value of the comparison. */
+
static tree
-compare_ranges (enum tree_code comp, value_range *vr0, value_range *vr1)
+compare_ranges (enum tree_code comp, value_range_t *vr0, value_range_t *vr1)
{
/* VARYING or UNDEFINED ranges cannot be compared. */
if (vr0->type == VR_VARYING
@@ -1069,7 +1558,7 @@ compare_ranges (enum tree_code comp, value_range *vr0, value_range *vr1)
if (vr0->type == VR_RANGE)
{
/* To simplify processing, make VR0 the anti-range. */
- value_range *tmp = vr0;
+ value_range_t *tmp = vr0;
vr0 = vr1;
vr1 = tmp;
}
@@ -1087,7 +1576,7 @@ compare_ranges (enum tree_code comp, value_range *vr0, value_range *vr1)
operands around and change the comparison code. */
if (comp == GT_EXPR || comp == GE_EXPR)
{
- value_range *tmp;
+ value_range_t *tmp;
comp = (comp == GT_EXPR) ? LT_EXPR : LE_EXPR;
tmp = vr0;
vr0 = vr1;
@@ -1162,13 +1651,13 @@ compare_ranges (enum tree_code comp, value_range *vr0, value_range *vr1)
/* Given a value range VR, a value VAL and a comparison code COMP, return
- BOOLEAN_TRUE_NODE if VR COMP VR1 always returns true for all the
+ BOOLEAN_TRUE_NODE if VR COMP VAL always returns true for all the
values in VR. Return BOOLEAN_FALSE_NODE if the comparison
always returns false. Return NULL_TREE if it is not always
possible to determine the value of the comparison. */
static tree
-compare_range_with_value (enum tree_code comp, value_range *vr, tree val)
+compare_range_with_value (enum tree_code comp, value_range_t *vr, tree val)
{
if (vr->type == VR_VARYING || vr->type == VR_UNDEFINED)
return NULL_TREE;
@@ -1271,8 +1760,18 @@ compare_range_with_value (enum tree_code comp, value_range *vr, tree val)
/* Debugging dumps. */
+void dump_value_range (FILE *, value_range_t *);
+void debug_value_range (value_range_t *);
+void dump_all_value_ranges (FILE *);
+void debug_all_value_ranges (void);
+void dump_vr_equiv (FILE *, bitmap);
+void debug_vr_equiv (bitmap);
+
+
+/* Dump value range VR to FILE. */
+
void
-dump_value_range (FILE *file, value_range *vr)
+dump_value_range (FILE *file, value_range_t *vr)
{
if (vr == NULL)
fprintf (file, "[]");
@@ -1280,11 +1779,43 @@ dump_value_range (FILE *file, value_range *vr)
fprintf (file, "UNDEFINED");
else if (vr->type == VR_RANGE || vr->type == VR_ANTI_RANGE)
{
+ tree type = TREE_TYPE (vr->min);
+
fprintf (file, "%s[", (vr->type == VR_ANTI_RANGE) ? "~" : "");
- print_generic_expr (file, vr->min, 0);
+
+ if (INTEGRAL_TYPE_P (type)
+ && !TYPE_UNSIGNED (type)
+ && vr->min == TYPE_MIN_VALUE (type))
+ fprintf (file, "-INF");
+ else
+ print_generic_expr (file, vr->min, 0);
+
fprintf (file, ", ");
- print_generic_expr (file, vr->max, 0);
+
+ if (INTEGRAL_TYPE_P (type)
+ && vr->max == TYPE_MAX_VALUE (type))
+ fprintf (file, "+INF");
+ else
+ print_generic_expr (file, vr->max, 0);
+
fprintf (file, "]");
+
+ if (vr->equiv)
+ {
+ bitmap_iterator bi;
+ unsigned i, c = 0;
+
+ fprintf (file, " EQUIVALENCES: { ");
+
+ EXECUTE_IF_SET_IN_BITMAP (vr->equiv, 0, i, bi)
+ {
+ print_generic_expr (file, ssa_name (i), 0);
+ fprintf (file, " ");
+ c++;
+ }
+
+ fprintf (file, "} (%u elements)", c);
+ }
}
else if (vr->type == VR_VARYING)
fprintf (file, "VARYING");
@@ -1296,7 +1827,7 @@ dump_value_range (FILE *file, value_range *vr)
/* Dump value range VR to stderr. */
void
-debug_value_range (value_range *vr)
+debug_value_range (value_range_t *vr)
{
dump_value_range (stderr, vr);
}
@@ -1311,12 +1842,11 @@ dump_all_value_ranges (FILE *file)
for (i = 0; i < num_ssa_names; i++)
{
- tree var = ssa_name (i);
- if (var && SSA_NAME_VALUE_RANGE (var))
+ if (vr_value[i])
{
- print_generic_expr (file, var, 0);
+ print_generic_expr (file, ssa_name (i), 0);
fprintf (file, ": ");
- dump_value_range (file, SSA_NAME_VALUE_RANGE (var));
+ dump_value_range (file, vr_value[i]);
fprintf (file, "\n");
}
}
@@ -1334,10 +1864,6 @@ debug_all_value_ranges (void)
}
-/*---------------------------------------------------------------------------
- Value Range Propagation
----------------------------------------------------------------------------*/
-
/* Given a COND_EXPR COND of the form 'V OP W', and an SSA name V,
create a new SSA name N and return the assertion assignment
'V = ASSERT_EXPR <V, V OP W>'. */
@@ -1352,17 +1878,8 @@ build_assert_expr_for (tree cond, tree v)
if (COMPARISON_CLASS_P (cond))
{
- /* Build N = ASSERT_EXPR <V, COND>. As a special case, if the
- conditional is an EQ_EXPR (V == Z), just build the assignment
- N = Z. */
- if (TREE_CODE (cond) == EQ_EXPR)
- {
- tree other = get_opposite_operand (cond, v);
- assertion = build (MODIFY_EXPR, TREE_TYPE (v), n, other);
- }
- else
- assertion = build (MODIFY_EXPR, TREE_TYPE (v), n,
- build (ASSERT_EXPR, TREE_TYPE (v), v, cond));
+ tree a = build (ASSERT_EXPR, TREE_TYPE (v), v, cond);
+ assertion = build (MODIFY_EXPR, TREE_TYPE (v), n, a);
}
else if (TREE_CODE (cond) == TRUTH_NOT_EXPR)
{
@@ -1403,16 +1920,26 @@ fp_predicate (tree expr)
}
-/* Return an expression predicate that represents the range of values
- that can be taken by operand OP after STMT executes. */
+/* If the range of values taken by OP can be inferred after STMT executes,
+ return the comparison code (COMP_CODE_P) and value (VAL_P) that
+ describes the inferred range. Return true if a range could be
+ inferred. */
-static tree
-infer_value_range (tree stmt, tree op)
+static bool
+infer_value_range (tree stmt, tree op, enum tree_code *comp_code_p, tree *val_p)
{
+ *val_p = NULL_TREE;
+ *comp_code_p = ERROR_MARK;
+
/* Do not attempt to infer anything in names that flow through
abnormal edges. */
if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op))
- return NULL_TREE;
+ return false;
+
+ /* Similarly, don't infer anything from statements that may throw
+ exceptions. */
+ if (tree_could_throw_p (stmt))
+ return false;
if (POINTER_TYPE_P (TREE_TYPE (op)))
{
@@ -1424,83 +1951,371 @@ infer_value_range (tree stmt, tree op)
{
/* We can only assume that a pointer dereference will yield
non-NULL if -fdelete-null-pointer-checks is enabled. */
- tree null = build_int_cst (TREE_TYPE (op), 0);
- tree t = build (NE_EXPR, boolean_type_node, op, null);
- return t;
+ *val_p = build_int_cst (TREE_TYPE (op), 0);
+ *comp_code_p = NE_EXPR;
+ return true;
}
}
- return NULL_TREE;
+ return false;
+}
+
+
+void dump_asserts_for (FILE *, tree);
+void debug_asserts_for (tree);
+void dump_all_asserts (FILE *);
+void debug_all_asserts (void);
+
+/* Dump all the registered assertions for NAME to FILE. */
+
+void
+dump_asserts_for (FILE *file, tree name)
+{
+ assert_locus_t loc;
+
+ fprintf (file, "Assertions to be inserted for ");
+ print_generic_expr (file, name, 0);
+ fprintf (file, "\n");
+
+ loc = asserts_for[SSA_NAME_VERSION (name)];
+ while (loc)
+ {
+ fprintf (file, "\t");
+ print_generic_expr (file, bsi_stmt (loc->si), 0);
+ fprintf (file, "\n\tBB #%d", loc->bb->index);
+ if (loc->e)
+ {
+ fprintf (file, "\n\tEDGE %d->%d", loc->e->src->index,
+ loc->e->dest->index);
+ dump_edge_info (file, loc->e, 0);
+ }
+ fprintf (file, "\n\tPREDICATE: ");
+ print_generic_expr (file, name, 0);
+ fprintf (file, " %s ", tree_code_name[(int)loc->comp_code]);
+ print_generic_expr (file, loc->val, 0);
+ fprintf (file, "\n\n");
+ loc = loc->next;
+ }
+
+ fprintf (file, "\n");
+}
+
+
+/* Dump all the registered assertions for NAME to stderr. */
+
+void
+debug_asserts_for (tree name)
+{
+ dump_asserts_for (stderr, name);
+}
+
+
+/* Dump all the registered assertions for all the names to FILE. */
+
+void
+dump_all_asserts (FILE *file)
+{
+ unsigned i;
+ bitmap_iterator bi;
+
+ fprintf (file, "\nASSERT_EXPRs to be inserted\n\n");
+ EXECUTE_IF_SET_IN_BITMAP (need_assert_for, 0, i, bi)
+ dump_asserts_for (file, ssa_name (i));
+ fprintf (file, "\n");
+}
+
+
+/* Dump all the registered assertions for all the names to stderr. */
+
+void
+debug_all_asserts (void)
+{
+ dump_all_asserts (stderr);
+}
+
+
+/* If NAME doesn't have an ASSERT_EXPR registered for asserting
+ 'NAME COMP_CODE VAL' at a location that dominates block BB or
+ E->DEST, then register this location as a possible insertion point
+ for ASSERT_EXPR <NAME, NAME COMP_CODE VAL>.
+
+ BB, E and SI provide the exact insertion point for the new
+ ASSERT_EXPR. If BB is NULL, then the ASSERT_EXPR is to be inserted
+ on edge E. Otherwise, if E is NULL, the ASSERT_EXPR is inserted on
+ BB. If SI points to a COND_EXPR or a SWITCH_EXPR statement, then E
+ must not be NULL. */
+
+static void
+register_new_assert_for (tree name,
+ enum tree_code comp_code,
+ tree val,
+ basic_block bb,
+ edge e,
+ block_stmt_iterator si)
+{
+ assert_locus_t n, loc, last_loc;
+ bool found;
+ basic_block dest_bb;
+
+#if defined ENABLE_CHECKING
+ gcc_assert (bb == NULL || e == NULL);
+
+ if (e == NULL)
+ gcc_assert (TREE_CODE (bsi_stmt (si)) != COND_EXPR
+ && TREE_CODE (bsi_stmt (si)) != SWITCH_EXPR);
+#endif
+
+ /* The new assertion A will be inserted at BB or E. We need to
+ determine if the new location is dominated by a previously
+ registered location for A. If we are doing an edge insertion,
+ assume that A will be inserted at E->DEST. Note that this is not
+ necessarily true.
+
+ If E is a critical edge, it will be split. But even if E is
+ split, the new block will dominate the same set of blocks that
+ E->DEST dominates.
+
+ The reverse, however, is not true, blocks dominated by E->DEST
+ will not be dominated by the new block created to split E. So,
+ if the insertion location is on a critical edge, we will not use
+ the new location to move another assertion previously registered
+ at a block dominated by E->DEST. */
+ dest_bb = (bb) ? bb : e->dest;
+
+ /* If NAME already has an ASSERT_EXPR registered for COMP_CODE and
+ VAL at a block dominating DEST_BB, then we don't need to insert a new
+ one. Similarly, if the same assertion already exists at a block
+ dominated by DEST_BB and the new location is not on a critical
+ edge, then update the existing location for the assertion (i.e.,
+ move the assertion up in the dominance tree).
+
+ Note, this is implemented as a simple linked list because there
+ should not be more than a handful of assertions registered per
+ name. If this becomes a performance problem, a table hashed by
+ COMP_CODE and VAL could be implemented. */
+ loc = asserts_for[SSA_NAME_VERSION (name)];
+ last_loc = loc;
+ found = false;
+ while (loc)
+ {
+ if (loc->comp_code == comp_code
+ && (loc->val == val
+ || operand_equal_p (loc->val, val, 0)))
+ {
+ /* If the assertion NAME COMP_CODE VAL has already been
+ registered at a basic block that dominates DEST_BB, then
+ we don't need to insert the same assertion again. Note
+ that we don't check strict dominance here to avoid
+ replicating the same assertion inside the same basic
+ block more than once (e.g., when a pointer is
+ dereferenced several times inside a block).
+
+ An exception to this rule are edge insertions. If the
+ new assertion is to be inserted on edge E, then it will
+ dominate all the other insertions that we may want to
+ insert in DEST_BB. So, if we are doing an edge
+ insertion, don't do this dominance check. */
+ if (e == NULL
+ && dominated_by_p (CDI_DOMINATORS, dest_bb, loc->bb))
+ return;
+
+ /* Otherwise, if E is not a critical edge and DEST_BB
+ dominates the existing location for the assertion, move
+ the assertion up in the dominance tree by updating its
+ location information. */
+ if ((e == NULL || !EDGE_CRITICAL_P (e))
+ && dominated_by_p (CDI_DOMINATORS, loc->bb, dest_bb))
+ {
+ loc->bb = dest_bb;
+ loc->e = e;
+ loc->si = si;
+ return;
+ }
+ }
+
+ /* Update the last node of the list and move to the next one. */
+ last_loc = loc;
+ loc = loc->next;
+ }
+
+ /* If we didn't find an assertion already registered for
+ NAME COMP_CODE VAL, add a new one at the end of the list of
+ assertions associated with NAME. */
+ n = xmalloc (sizeof (*n));
+ n->bb = dest_bb;
+ n->e = e;
+ n->si = si;
+ n->comp_code = comp_code;
+ n->val = val;
+ n->next = NULL;
+
+ if (last_loc)
+ last_loc->next = n;
+ else
+ asserts_for[SSA_NAME_VERSION (name)] = n;
+
+ bitmap_set_bit (need_assert_for, SSA_NAME_VERSION (name));
}
-/* Return true if OP is the result of an ASSERT_EXPR that tests the
- same condition as COND. */
+/* Try to register an edge assertion for SSA name NAME on edge E for
+ the conditional jump pointed by SI. Return true if an assertion
+ for NAME could be registered. */
static bool
-has_assert_expr (tree op, tree cond)
+register_edge_assert_for (tree name, edge e, block_stmt_iterator si)
{
- tree def_stmt = SSA_NAME_DEF_STMT (op);
- tree assert_expr, other_cond, other_op;
+ tree val, stmt;
+ enum tree_code comp_code;
+
+ stmt = bsi_stmt (si);
- /* If OP was not generated by an ASSERT_EXPR, return false. */
- if (TREE_CODE (def_stmt) != MODIFY_EXPR
- || TREE_CODE (TREE_OPERAND (def_stmt, 1)) != ASSERT_EXPR)
+ /* Do not attempt to infer anything in names that flow through
+ abnormal edges. */
+ if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name))
return false;
- assert_expr = TREE_OPERAND (def_stmt, 1);
- other_cond = ASSERT_EXPR_COND (assert_expr);
- other_op = ASSERT_EXPR_VAR (assert_expr);
+ /* If NAME was not found in the sub-graph reachable from E, then
+ there's nothing to do. */
+ if (!TEST_BIT (found_in_subgraph, SSA_NAME_VERSION (name)))
+ return false;
- if (TREE_CODE (cond) == TREE_CODE (other_cond))
+ /* We found a use of NAME in the sub-graph rooted at E->DEST.
+ Register an assertion for NAME according to the value that NAME
+ takes on edge E. */
+ if (TREE_CODE (stmt) == COND_EXPR)
{
- tree t1, t2;
+ /* If BB ends in a COND_EXPR then NAME then we should insert
+ the original predicate on EDGE_TRUE_VALUE and the
+ opposite predicate on EDGE_FALSE_VALUE. */
+ tree cond = COND_EXPR_COND (stmt);
+ bool is_else_edge = (e->flags & EDGE_FALSE_VALUE) != 0;
- /* If COND is not a comparison predicate, something is wrong. */
- gcc_assert (COMPARISON_CLASS_P (cond));
-
- /* Note that we only need to compare against one of the operands
- of OTHER_COND.
-
- Suppose that we are about to insert the assertion ASSERT_EXPR
- <x_4, x_4 != 0> and the defining statement for x_4 is x_4 =
- ASSERT_EXPR <x_3, x_3 != 0>.
-
- In this case, we don't really want to insert a new
- ASSERT_EXPR for x_4 because that would be redundant. We
- already know that x_4 is not 0. So, when comparing the
- conditionals 'x_3 != 0' and 'x_4 != 0', we don't want to
- compare x_3 and x_4, we just want to compare the predicate's
- code (!=) and the other operand (0). */
- if (TREE_OPERAND (cond, 0) == op)
- t1 = TREE_OPERAND (cond, 1);
+ /* Predicates may be a single SSA name or NAME OP VAL. */
+ if (cond == name)
+ {
+ /* If the predicate is a name, it must be NAME, in which
+ case we create the predicate NAME == true or
+ NAME == false accordingly. */
+ comp_code = EQ_EXPR;
+ val = (is_else_edge) ? boolean_false_node : boolean_true_node;
+ }
else
- t1 = TREE_OPERAND (cond, 0);
+ {
+ /* Otherwise, we have a comparison of the form NAME COMP VAL
+ or VAL COMP NAME. */
+ if (name == TREE_OPERAND (cond, 1))
+ {
+ /* If the predicate is of the form VAL COMP NAME, flip
+ COMP around because we need to register NAME as the
+ first operand in the predicate. */
+ comp_code = opposite_comparison (TREE_CODE (cond));
+ val = TREE_OPERAND (cond, 0);
+ }
+ else
+ {
+ /* The comparison is of the form NAME COMP VAL, so the
+ comparison code remains unchanged. */
+ comp_code = TREE_CODE (cond);
+ val = TREE_OPERAND (cond, 1);
+ }
- if (TREE_OPERAND (other_cond, 0) == other_op)
- t2 = TREE_OPERAND (other_cond, 1);
- else
- t2 = TREE_OPERAND (other_cond, 0);
+ /* If we are inserting the assertion on the ELSE edge, we
+ need to invert the sign comparison. */
+ if (is_else_edge)
+ comp_code = invert_tree_comparison (comp_code, 0);
+ }
+ }
+ else
+ {
+ /* FIXME. Handle SWITCH_EXPR. */
+ gcc_unreachable ();
+ }
+
+ register_new_assert_for (name, comp_code, val, NULL, e, si);
+ return true;
+}
+
+
+static bool find_assert_locations (basic_block bb);
+
+/* Determine whether the outgoing edges of BB should receive an
+ ASSERT_EXPR for each of the operands of BB's last statement. The
+ last statement of BB must be a COND_EXPR or a SWITCH_EXPR.
+
+ If any of the sub-graphs rooted at BB have an interesting use of
+ the predicate operands, an assert location node is added to the
+ list of assertions for the corresponding operands. */
+
+static bool
+find_conditional_asserts (basic_block bb)
+{
+ bool need_assert;
+ block_stmt_iterator last_si;
+ tree op, last;
+ edge_iterator ei;
+ edge e;
+ ssa_op_iter iter;
+
+ need_assert = false;
+ last_si = bsi_last (bb);
+ last = bsi_stmt (last_si);
- return (t1 == t2 || operand_equal_p (t1, t2, 0));
+ /* Look for uses of the operands in each of the sub-graphs
+ rooted at BB. We need to check each of the outgoing edges
+ separately, so that we know what kind of ASSERT_EXPR to
+ insert. */
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ {
+ if (e->dest == bb)
+ continue;
+
+ /* Remove the COND_EXPR operands from the FOUND_IN_SUBGRAPH bitmap.
+ Otherwise, when we finish traversing each of the sub-graphs, we
+ won't know whether the variables were found in the sub-graphs or
+ if they had been found in a block upstream from BB. */
+ FOR_EACH_SSA_TREE_OPERAND (op, last, iter, SSA_OP_USE)
+ RESET_BIT (found_in_subgraph, SSA_NAME_VERSION (op));
+
+ /* Traverse the strictly dominated sub-graph rooted at E->DEST
+ to determine if any of the operands in the conditional
+ predicate are used. */
+ if (e->dest != bb)
+ need_assert |= find_assert_locations (e->dest);
+
+ /* Register the necessary assertions for each operand in the
+ conditional predicate. */
+ FOR_EACH_SSA_TREE_OPERAND (op, last, iter, SSA_OP_USE)
+ need_assert |= register_edge_assert_for (op, e, last_si);
}
- return false;
+ /* Finally, indicate that we have found the operands in the
+ conditional. */
+ FOR_EACH_SSA_TREE_OPERAND (op, last, iter, SSA_OP_USE)
+ SET_BIT (found_in_subgraph, SSA_NAME_VERSION (op));
+
+ return need_assert;
}
-/* Traverse all the statements in block BB looking for used variables.
- Variables used in BB are added to bitmap FOUND. The algorithm
- works in three main parts:
+/* Traverse all the statements in block BB looking for statements that
+ may generate useful assertions for the SSA names in their operand.
+ If a statement produces a useful assertion A for name N_i, then the
+ list of assertions already generated for N_i is scanned to
+ determine if A is actually needed.
+
+ If N_i already had the assertion A at a location dominating the
+ current location, then nothing needs to be done. Otherwise, the
+ new location for A is recorded instead.
1- For every statement S in BB, all the variables used by S are
- added to bitmap FOUND.
+ added to bitmap FOUND_IN_SUBGRAPH.
2- If statement S uses an operand N in a way that exposes a known
value range for N, then if N was not already generated by an
- ASSERT_EXPR, create a new ASSERT_EXPR for N. For instance, if N
- is a pointer and the statement dereferences it, we can assume
- that N is not NULL.
+ ASSERT_EXPR, create a new assert location for N. For instance,
+ if N is a pointer and the statement dereferences it, we can
+ assume that N is not NULL.
3- COND_EXPRs are a special case of #2. We can derive range
information from the predicate but need to insert different
@@ -1508,112 +2323,116 @@ has_assert_expr (tree op, tree cond)
conditional block. If the last statement of BB is a conditional
expression of the form 'X op Y', then
- a) Remove X and Y from the set FOUND.
+ a) Remove X and Y from the set FOUND_IN_SUBGRAPH.
- b) If the conditional dominates its THEN_CLAUSE sub-graph,
- recurse into it. On return, if X and/or Y are marked in
- FOUND, then an ASSERT_EXPR is added for the corresponding
- variable.
+ b) If the conditional is the only entry point to the sub-graph
+ corresponding to the THEN_CLAUSE, recurse into it. On
+ return, if X and/or Y are marked in FOUND_IN_SUBGRAPH, then
+ an ASSERT_EXPR is added for the corresponding variable.
c) Repeat step (b) on the ELSE_CLAUSE.
- d) Mark X and Y in FOUND.
+ d) Mark X and Y in FOUND_IN_SUBGRAPH.
+
+ For instance,
+
+ if (a == 9)
+ b = a;
+ else
+ b = c + 1;
+
+ In this case, an assertion on the THEN clause is useful to
+ determine that 'a' is always 9 on that edge. However, an assertion
+ on the ELSE clause would be unnecessary.
4- If BB does not end in a conditional expression, then we recurse
into BB's dominator children.
- At the end of the recursive traversal, ASSERT_EXPRs will have been
- added to the edges of COND_EXPR blocks that have sub-graphs using
- one or both predicate operands. For instance,
-
- if (a == 9)
- b = a;
- else
- b = c + 1;
-
- In this case, an assertion on the THEN clause is useful to
- determine that 'a' is always 9 on that edge. However, an assertion
- on the ELSE clause would be unnecessary.
-
- On exit from this function, all the names created by the newly
- inserted ASSERT_EXPRs need to be added to the SSA web by rewriting
- the SSA names that they replace.
-
+ At the end of the recursive traversal, every SSA name will have a
+ list of locations where ASSERT_EXPRs should be added. When a new
+ location for name N is found, it is registered by calling
+ register_new_assert_for. That function keeps track of all the
+ registered assertions to prevent adding unnecessary assertions.
+ For instance, if a pointer P_4 is dereferenced more than once in a
+ dominator tree, only the location dominating all the dereference of
+ P_4 will receive an ASSERT_EXPR.
+
+ If this function returns true, then it means that there are names
+ for which we need to generate ASSERT_EXPRs. Those assertions are
+ inserted by process_assert_insertions.
+
TODO. Handle SWITCH_EXPR. */
static bool
-maybe_add_assert_expr (basic_block bb)
+find_assert_locations (basic_block bb)
{
block_stmt_iterator si;
- tree last;
- bool added;
+ tree last, phi;
+ bool need_assert;
+ basic_block son;
+
+ if (TEST_BIT (blocks_visited, bb->index))
+ return false;
+
+ SET_BIT (blocks_visited, bb->index);
- /* Step 1. Mark all the SSA names used in BB in bitmap FOUND. */
- added = false;
+ need_assert = false;
+
+ /* Traverse all PHI nodes in BB marking used operands. */
+ for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+ {
+ use_operand_p arg_p;
+ ssa_op_iter i;
+
+ FOR_EACH_PHI_ARG (arg_p, phi, i, SSA_OP_USE)
+ {
+ tree arg = USE_FROM_PTR (arg_p);
+ if (TREE_CODE (arg) == SSA_NAME)
+ {
+ gcc_assert (is_gimple_reg (PHI_RESULT (phi)));
+ SET_BIT (found_in_subgraph, SSA_NAME_VERSION (arg));
+ }
+ }
+ }
+
+ /* Traverse all the statements in BB marking used names and looking
+ for statements that may infer assertions for their used operands. */
last = NULL_TREE;
for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
{
tree stmt, op;
ssa_op_iter i;
-
+
stmt = bsi_stmt (si);
- /* Mark all the SSA names used by STMT in bitmap FOUND. If STMT
- is inside the sub-graph of a conditional block, when we
- return from this recursive walk, our parent will use the
- FOUND bitset to determine if one of the operands it was
- looking for was present in the sub-graph. */
+ /* See if we can derive an assertion for any of STMT's operands. */
FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_USE)
{
- tree cond;
+ tree value;
+ enum tree_code comp_code;
+
+ /* Mark OP in bitmap FOUND_IN_SUBGRAPH. If STMT is inside
+ the sub-graph of a conditional block, when we return from
+ this recursive walk, our parent will use the
+ FOUND_IN_SUBGRAPH bitset to determine if one of the
+ operands it was looking for was present in the sub-graph. */
+ SET_BIT (found_in_subgraph, SSA_NAME_VERSION (op));
/* If OP is used only once, namely in this STMT, don't
- bother inserting an ASSERT_EXPR for it. Such an
+ bother creating an ASSERT_EXPR for it. Such an
ASSERT_EXPR would do nothing but increase compile time.
Experiments show that with this simple check, we can save
more than 20% of ASSERT_EXPRs. */
if (has_single_use (op))
continue;
- SET_BIT (found, SSA_NAME_VERSION (op));
-
- cond = infer_value_range (stmt, op);
- if (!cond)
- continue;
-
- /* Step 2. If OP is used in such a way that we can infer a
- value range for it, create a new ASSERT_EXPR for OP
- (unless OP already has an ASSERT_EXPR). */
- gcc_assert (!is_ctrl_stmt (stmt));
-
- if (has_assert_expr (op, cond))
- continue;
-
- if (!stmt_ends_bb_p (stmt))
- {
- /* If STMT does not end the block, we can insert the new
- assertion right after it. */
- tree t = build_assert_expr_for (cond, op);
- bsi_insert_after (&si, t, BSI_NEW_STMT);
- added = true;
- }
- else
+ /* If OP is used in such a way that we can infer a value
+ range for it, and we don't find a previous assertion for
+ it, create a new assertion location node for OP. */
+ if (infer_value_range (stmt, op, &comp_code, &value))
{
- /* STMT must be the last statement in BB. We can only
- insert new assertions on the non-abnormal edge out of
- BB. Note that since STMT is not control flow, there
- may only be one non-abnormal edge out of BB. */
- edge_iterator ei;
- edge e;
-
- FOR_EACH_EDGE (e, ei, bb->succs)
- if (!(e->flags & EDGE_ABNORMAL))
- {
- tree t = build_assert_expr_for (cond, op);
- bsi_insert_on_edge (e, t);
- added = true;
- break;
- }
+ register_new_assert_for (op, comp_code, value, bb, NULL, si);
+ need_assert = true;
}
}
@@ -1621,103 +2440,112 @@ maybe_add_assert_expr (basic_block bb)
last = stmt;
}
- /* Step 3. If BB's last statement is a conditional expression
+ /* If BB's last statement is a conditional expression
involving integer operands, recurse into each of the sub-graphs
- rooted at BB to determine if we need to add ASSERT_EXPRs.
- Notice that we only care about the first operand of the
- conditional. Adding assertions for both operands may actually
- hinder VRP. FIXME, add example. */
+ rooted at BB to determine if we need to add ASSERT_EXPRs. */
if (last
&& TREE_CODE (last) == COND_EXPR
&& !fp_predicate (COND_EXPR_COND (last))
&& !ZERO_SSA_OPERANDS (last, SSA_OP_USE))
+ need_assert |= find_conditional_asserts (bb);
+
+ /* Recurse into the dominator children of BB. */
+ for (son = first_dom_son (CDI_DOMINATORS, bb);
+ son;
+ son = next_dom_son (CDI_DOMINATORS, son))
+ need_assert |= find_assert_locations (son);
+
+ return need_assert;
+}
+
+
+/* Create an ASSERT_EXPR for NAME and insert it in the location
+ indicated by LOC. Return true if we made any edge insertions. */
+
+static bool
+process_assert_insertions_for (tree name, assert_locus_t loc)
+{
+ /* Build the comparison expression NAME_i COMP_CODE VAL. */
+ tree stmt, cond, assert_expr;
+ edge_iterator ei;
+ edge e;
+
+ cond = build (loc->comp_code, boolean_type_node, name, loc->val);
+ assert_expr = build_assert_expr_for (cond, name);
+
+ if (loc->e)
{
- edge e;
- edge_iterator ei;
- tree op, cond;
- basic_block son;
- ssa_op_iter iter;
-
- cond = COND_EXPR_COND (last);
+ /* We have been asked to insert the assertion on an edge. This
+ is used only by COND_EXPR and SWITCH_EXPR assertions. */
+#if defined ENABLE_CHECKING
+ gcc_assert (TREE_CODE (bsi_stmt (loc->si)) == COND_EXPR
+ || TREE_CODE (bsi_stmt (loc->si)) == SWITCH_EXPR);
+#endif
- /* Get just the first use operand. */
- FOR_EACH_SSA_TREE_OPERAND (op, last, iter, SSA_OP_USE)
- break;
- gcc_assert (op != NULL);
-
- /* Do not attempt to infer anything in names that flow through
- abnormal edges. */
- if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op))
- return false;
-
- /* Remove the COND_EXPR operand from the FOUND bitmap.
- Otherwise, when we finish traversing each of the sub-graphs,
- we won't know whether the variables were found in the
- sub-graphs or if they had been found in a block upstream from
- BB. */
- RESET_BIT (found, SSA_NAME_VERSION (op));
-
- /* Look for uses of the operands in each of the sub-graphs
- rooted at BB. We need to check each of the outgoing edges
- separately, so that we know what kind of ASSERT_EXPR to
- insert. */
- FOR_EACH_EDGE (e, ei, bb->succs)
- {
- /* If BB strictly dominates the sub-graph at E->DEST,
- recurse into it. */
- if (e->dest != bb
- && dominated_by_p (CDI_DOMINATORS, e->dest, bb))
- added |= maybe_add_assert_expr (e->dest);
-
- /* Once we traversed the sub-graph, check if any block inside
- used either of the predicate's operands. If so, add the
- appropriate ASSERT_EXPR. */
- if (TEST_BIT (found, SSA_NAME_VERSION (op)))
- {
- /* We found a use of OP in the sub-graph rooted at
- E->DEST. Add an ASSERT_EXPR according to whether
- E goes to THEN_CLAUSE or ELSE_CLAUSE. */
- tree c, t;
-
- if (e->flags & EDGE_TRUE_VALUE)
- c = unshare_expr (cond);
- else if (e->flags & EDGE_FALSE_VALUE)
- c = invert_truthvalue (cond);
- else
- gcc_unreachable ();
-
- t = build_assert_expr_for (c, op);
- bsi_insert_on_edge (e, t);
- added = true;
- }
- }
+ bsi_insert_on_edge (loc->e, assert_expr);
+ return true;
+ }
- /* Finally, mark all the COND_EXPR operands as found. */
- SET_BIT (found, SSA_NAME_VERSION (op));
+ /* Otherwise, we can insert right after LOC->SI iff the
+ statement must not be the last statement in the block. */
+ stmt = bsi_stmt (loc->si);
+ if (!stmt_ends_bb_p (stmt))
+ {
+ bsi_insert_after (&loc->si, assert_expr, BSI_SAME_STMT);
+ return false;
+ }
+
+ /* If STMT must be the last statement in BB, we can only insert new
+ assertions on the non-abnormal edge out of BB. Note that since
+ STMT is not control flow, there may only be one non-abnormal edge
+ out of BB. */
+ FOR_EACH_EDGE (e, ei, loc->bb->succs)
+ if (!(e->flags & EDGE_ABNORMAL))
+ {
+ bsi_insert_on_edge (e, assert_expr);
+ return true;
+ }
+
+ gcc_unreachable ();
+}
+
+
+/* Process all the insertions registered for every name N_i registered
+ in NEED_ASSERT_FOR. The list of assertions to be inserted are
+ found in ASSERTS_FOR[i]. */
- /* Recurse into the dominator children of BB that are not BB's
- immediate successors. Note that we have already visited BB's
- other dominator children above. */
- for (son = first_dom_son (CDI_DOMINATORS, bb);
- son;
- son = next_dom_son (CDI_DOMINATORS, son))
+static void
+process_assert_insertions (void)
+{
+ unsigned i;
+ bitmap_iterator bi;
+ bool update_edges_p = false;
+ int num_asserts = 0;
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ dump_all_asserts (dump_file);
+
+ EXECUTE_IF_SET_IN_BITMAP (need_assert_for, 0, i, bi)
+ {
+ assert_locus_t loc = asserts_for[i];
+ gcc_assert (loc);
+
+ while (loc)
{
- if (find_edge (bb, son) == NULL)
- added |= maybe_add_assert_expr (son);
+ assert_locus_t next = loc->next;
+ update_edges_p |= process_assert_insertions_for (ssa_name (i), loc);
+ free (loc);
+ loc = next;
+ num_asserts++;
}
}
- else
- {
- /* Step 4. Recurse into the dominator children of BB. */
- basic_block son;
- for (son = first_dom_son (CDI_DOMINATORS, bb);
- son;
- son = next_dom_son (CDI_DOMINATORS, son))
- added |= maybe_add_assert_expr (son);
- }
+ if (update_edges_p)
+ bsi_commit_edge_inserts ();
- return added;
+ if (dump_file && (dump_flags & TDF_STATS))
+ fprintf (dump_file, "\nNumber of ASSERT_EXPR expressions inserted: %d\n\n",
+ num_asserts);
}
@@ -1760,19 +2588,26 @@ insert_range_assertions (void)
edge_iterator ei;
bool update_ssa_p;
- found = sbitmap_alloc (num_ssa_names);
- sbitmap_zero (found);
+ found_in_subgraph = sbitmap_alloc (num_ssa_names);
+ sbitmap_zero (found_in_subgraph);
+
+ blocks_visited = sbitmap_alloc (last_basic_block);
+ sbitmap_zero (blocks_visited);
+
+ need_assert_for = BITMAP_ALLOC (NULL);
+ asserts_for = xmalloc (num_ssa_names * sizeof (assert_locus_t));
+ memset (asserts_for, 0, num_ssa_names * sizeof (assert_locus_t));
calculate_dominance_info (CDI_DOMINATORS);
update_ssa_p = false;
FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs)
- if (maybe_add_assert_expr (e->dest))
+ if (find_assert_locations (e->dest))
update_ssa_p = true;
if (update_ssa_p)
{
- bsi_commit_edge_inserts ();
+ process_assert_insertions ();
update_ssa (TODO_update_ssa_no_phi);
}
@@ -1782,11 +2617,27 @@ insert_range_assertions (void)
dump_function_to_file (current_function_decl, dump_file, dump_flags);
}
- sbitmap_free (found);
+ sbitmap_free (found_in_subgraph);
+ free (asserts_for);
+ BITMAP_FREE (need_assert_for);
}
-/* Convert range assertion expressions into copies. FIXME, explain why. */
+/* Convert range assertion expressions into the implied copies.
+
+ FIXME, this will eventually lead to copy propagation removing the
+ names that had useful range information attached to them. For
+ instance, if we had the assertion N_i = ASSERT_EXPR <N_j, N_j > 3>,
+ then N_i will have the range [3, +INF].
+
+ However, by converting the assertion into the implied copy
+ operation N_i = N_j, we will then copy-propagate N_j into the uses
+ of N_i and lose the range information. We may want to hold on to
+ ASSERT_EXPRs a little while longer as the ranges could be used in
+ things like jump threading.
+
+ The problem with keeping ASSERT_EXPRs around is that passes after
+ VRP need to handle them appropriately. */
static void
remove_range_assertions (void)
@@ -1843,15 +2694,13 @@ stmt_interesting_for_vrp (tree stmt)
is worth running (i.e. if we found any statements that could
benefit from range information). */
-static bool
+static void
vrp_initialize (void)
{
basic_block bb;
- bool do_vrp;
- /* If we don't find any ASSERT_EXPRs in the code, there's no point
- running VRP. */
- do_vrp = false;
+ vr_value = xmalloc (num_ssa_names * sizeof (value_range_t *));
+ memset (vr_value, 0, num_ssa_names * sizeof (value_range_t *));
FOR_EACH_BB (bb)
{
@@ -1884,16 +2733,10 @@ vrp_initialize (void)
}
else
{
- if (TREE_CODE (stmt) == MODIFY_EXPR
- && TREE_CODE (TREE_OPERAND (stmt, 1)) == ASSERT_EXPR)
- do_vrp = true;
-
DONT_SIMULATE_AGAIN (stmt) = false;
}
}
}
-
- return do_vrp;
}
@@ -1914,10 +2757,9 @@ vrp_visit_assignment (tree stmt, tree *output_p)
&& (INTEGRAL_TYPE_P (TREE_TYPE (lhs))
|| POINTER_TYPE_P (TREE_TYPE (lhs))))
{
- value_range *vr, new_vr;
struct loop *l;
-
- vr = get_value_range (lhs);
+ value_range_t new_vr = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
+
extract_range_from_expr (&new_vr, rhs);
/* If STMT is inside a loop, we may be able to know something
@@ -1926,16 +2768,16 @@ vrp_visit_assignment (tree stmt, tree *output_p)
if (cfg_loops && (l = loop_containing_stmt (stmt)))
adjust_range_with_scev (&new_vr, l, lhs);
- if (update_value_range (vr, new_vr.type, new_vr.min, new_vr.max))
+ if (update_value_range (lhs, &new_vr))
{
*output_p = lhs;
if (dump_file && (dump_flags & TDF_DETAILS))
{
- fprintf (dump_file, "Found new range ");
- dump_value_range (dump_file, &new_vr);
- fprintf (dump_file, " for ");
+ fprintf (dump_file, "Found new range for ");
print_generic_expr (dump_file, lhs, 0);
+ fprintf (dump_file, ": ");
+ dump_value_range (dump_file, &new_vr);
fprintf (dump_file, "\n\n");
}
@@ -1948,7 +2790,7 @@ vrp_visit_assignment (tree stmt, tree *output_p)
return SSA_PROP_NOT_INTERESTING;
}
- /* Every other statements produces no useful ranges. */
+ /* Every other statement produces no useful ranges. */
FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_DEF)
set_value_range_to_varying (get_value_range (def));
@@ -1956,43 +2798,226 @@ vrp_visit_assignment (tree stmt, tree *output_p)
}
-/* Given a conditional predicate COND, try to determine if COND yields
- true or false based on the value ranges of its operands. */
+/* Compare all the value ranges for names equivalent to VAR with VAL
+ using comparison code COMP. Return the same value returned by
+ compare_range_with_value. */
static tree
-vrp_evaluate_conditional (tree cond)
+compare_name_with_value (enum tree_code comp, tree var, tree val)
+{
+ bitmap_iterator bi;
+ unsigned i;
+ bitmap e;
+ tree retval, t;
+
+ t = retval = NULL_TREE;
+
+ /* Get the set of equivalences for VAR. */
+ e = get_value_range (var)->equiv;
+
+ /* Add VAR to its own set of equivalences so that VAR's value range
+ is processed by this loop (otherwise, we would have to replicate
+ the body of the loop just to check VAR's value range). */
+ bitmap_set_bit (e, SSA_NAME_VERSION (var));
+
+ EXECUTE_IF_SET_IN_BITMAP (e, 0, i, bi)
+ {
+ value_range_t equiv_vr = *(vr_value[i]);
+
+ /* If name N_i does not have a valid range, use N_i as its own
+ range. This allows us to compare against names that may
+ have N_i in their ranges. */
+ if (equiv_vr.type == VR_VARYING || equiv_vr.type == VR_UNDEFINED)
+ {
+ equiv_vr.type = VR_RANGE;
+ equiv_vr.min = ssa_name (i);
+ equiv_vr.max = ssa_name (i);
+ }
+
+ t = compare_range_with_value (comp, &equiv_vr, val);
+ if (t)
+ {
+ /* All the ranges should compare the same against VAL. */
+ gcc_assert (retval == NULL || t == retval);
+ retval = t;
+ }
+ }
+
+ /* Remove VAR from its own equivalence set. */
+ bitmap_clear_bit (e, SSA_NAME_VERSION (var));
+
+ if (retval)
+ return retval;
+
+ /* We couldn't find a non-NULL value for the predicate. */
+ return NULL_TREE;
+}
+
+
+/* Given a comparison code COMP and names N1 and N2, compare all the
+ ranges equivalent to N1 against all the ranges equivalent to N2
+ to determine the value of N1 COMP N2. Return the same value
+ returned by compare_ranges. */
+
+static tree
+compare_names (enum tree_code comp, tree n1, tree n2)
+{
+ tree t, retval;
+ bitmap e1, e2;
+ bitmap_iterator bi1, bi2;
+ unsigned i1, i2;
+
+ /* Compare the ranges of every name equivalent to N1 against the
+ ranges of every name equivalent to N2. */
+ e1 = get_value_range (n1)->equiv;
+ e2 = get_value_range (n2)->equiv;
+
+ /* Add N1 and N2 to their own set of equivalences to avoid
+ duplicating the body of the loop just to check N1 and N2
+ ranges. */
+ bitmap_set_bit (e1, SSA_NAME_VERSION (n1));
+ bitmap_set_bit (e2, SSA_NAME_VERSION (n2));
+
+ /* If the equivalence sets have a common intersection, then the two
+ names can be compared without checking their ranges. */
+ if (bitmap_intersect_p (e1, e2))
+ {
+ bitmap_clear_bit (e1, SSA_NAME_VERSION (n1));
+ bitmap_clear_bit (e2, SSA_NAME_VERSION (n2));
+
+ return (comp == EQ_EXPR || comp == GE_EXPR || comp == LE_EXPR)
+ ? boolean_true_node
+ : boolean_false_node;
+ }
+
+ /* Otherwise, compare all the equivalent ranges. First, add N1 and
+ N2 to their own set of equivalences to avoid duplicating the body
+ of the loop just to check N1 and N2 ranges. */
+ EXECUTE_IF_SET_IN_BITMAP (e1, 0, i1, bi1)
+ {
+ value_range_t vr1 = *(vr_value[i1]);
+
+ /* If the range is VARYING or UNDEFINED, use the name itself. */
+ if (vr1.type == VR_VARYING || vr1.type == VR_UNDEFINED)
+ {
+ vr1.type = VR_RANGE;
+ vr1.min = ssa_name (i1);
+ vr1.max = ssa_name (i1);
+ }
+
+ t = retval = NULL_TREE;
+ EXECUTE_IF_SET_IN_BITMAP (e2, 0, i2, bi2)
+ {
+ value_range_t vr2 = *(vr_value[i2]);
+
+ if (vr2.type == VR_VARYING || vr2.type == VR_UNDEFINED)
+ {
+ vr2.type = VR_RANGE;
+ vr2.min = ssa_name (i2);
+ vr2.max = ssa_name (i2);
+ }
+
+ t = compare_ranges (comp, &vr1, &vr2);
+ if (t)
+ {
+ /* All the ranges in the equivalent sets should compare
+ the same. */
+ gcc_assert (retval == NULL || t == retval);
+ retval = t;
+ }
+ }
+
+ if (retval)
+ {
+ bitmap_clear_bit (e1, SSA_NAME_VERSION (n1));
+ bitmap_clear_bit (e2, SSA_NAME_VERSION (n2));
+ return retval;
+ }
+ }
+
+ /* None of the equivalent ranges are useful in computing this
+ comparison. */
+ bitmap_clear_bit (e1, SSA_NAME_VERSION (n1));
+ bitmap_clear_bit (e2, SSA_NAME_VERSION (n2));
+ return NULL_TREE;
+}
+
+
+/* Given a conditional predicate COND, try to determine if COND yields
+ true or false based on the value ranges of its operands. Return
+ BOOLEAN_TRUE_NODE if the conditional always evaluates to true,
+ BOOLEAN_FALSE_NODE if the conditional always evaluates to false, and,
+ NULL if the conditional cannot be evaluated at compile time.
+
+ If USE_EQUIV_P is true, the ranges of all the names equivalent with
+ the operands in COND are used when trying to compute its value.
+ This is only used during final substitution. During propagation,
+ we only check the range of each variable and not its equivalents. */
+
+tree
+vrp_evaluate_conditional (tree cond, bool use_equiv_p)
{
gcc_assert (TREE_CODE (cond) == SSA_NAME
|| TREE_CODE_CLASS (TREE_CODE (cond)) == tcc_comparison);
if (TREE_CODE (cond) == SSA_NAME)
{
- /* For SSA names, only return a truth value if the range is
- known and contains exactly one value. */
- value_range *vr = SSA_NAME_VALUE_RANGE (cond);
- if (vr && vr->type == VR_RANGE && vr->min == vr->max)
+ value_range_t *vr;
+ tree retval;
+
+ if (use_equiv_p)
+ retval = compare_name_with_value (NE_EXPR, cond, boolean_false_node);
+ else
+ {
+ value_range_t *vr = get_value_range (cond);
+ retval = compare_range_with_value (NE_EXPR, vr, boolean_false_node);
+ }
+
+ /* If COND has a known boolean range, return it. */
+ if (retval)
+ return retval;
+
+ /* Otherwise, if COND has a symbolic range of exactly one value,
+ return it. */
+ vr = get_value_range (cond);
+ if (vr->type == VR_RANGE && vr->min == vr->max)
return vr->min;
}
else
{
- /* For comparisons, evaluate each operand and compare their
- ranges. */
- tree op0, op1;
- value_range *vr0, *vr1;
-
- op0 = TREE_OPERAND (cond, 0);
- vr0 = (TREE_CODE (op0) == SSA_NAME) ? get_value_range (op0) : NULL;
+ tree op0 = TREE_OPERAND (cond, 0);
+ tree op1 = TREE_OPERAND (cond, 1);
- op1 = TREE_OPERAND (cond, 1);
- vr1 = (TREE_CODE (op1) == SSA_NAME) ? get_value_range (op1) : NULL;
+ /* We only deal with integral and pointer types. */
+ if (!INTEGRAL_TYPE_P (TREE_TYPE (op0))
+ && !POINTER_TYPE_P (TREE_TYPE (op0)))
+ return NULL_TREE;
- if (vr0 && vr1)
- return compare_ranges (TREE_CODE (cond), vr0, vr1);
- else if (vr0 && vr1 == NULL)
- return compare_range_with_value (TREE_CODE (cond), vr0, op1);
- else if (vr0 == NULL && vr1)
- return compare_range_with_value (opposite_comparison (TREE_CODE (cond)),
- vr1, op0);
+ if (use_equiv_p)
+ {
+ if (TREE_CODE (op0) == SSA_NAME && TREE_CODE (op1) == SSA_NAME)
+ return compare_names (TREE_CODE (cond), op0, op1);
+ else if (TREE_CODE (op0) == SSA_NAME)
+ return compare_name_with_value (TREE_CODE (cond), op0, op1);
+ else if (TREE_CODE (op1) == SSA_NAME)
+ return compare_name_with_value (
+ opposite_comparison (TREE_CODE (cond)), op1, op0);
+ }
+ else
+ {
+ value_range_t *vr0, *vr1;
+
+ vr0 = (TREE_CODE (op0) == SSA_NAME) ? get_value_range (op0) : NULL;
+ vr1 = (TREE_CODE (op1) == SSA_NAME) ? get_value_range (op1) : NULL;
+
+ if (vr0 && vr1)
+ return compare_ranges (TREE_CODE (cond), vr0, vr1);
+ else if (vr0 && vr1 == NULL)
+ return compare_range_with_value (TREE_CODE (cond), vr0, op1);
+ else if (vr0 == NULL && vr1)
+ return compare_range_with_value (
+ opposite_comparison (TREE_CODE (cond)), vr1, op0);
+ }
}
/* Anything else cannot be computed statically. */
@@ -2033,15 +3058,55 @@ vrp_visit_cond_stmt (tree stmt, edge *taken_edge_p)
fprintf (dump_file, "\t");
print_generic_expr (dump_file, use, 0);
fprintf (dump_file, ": ");
- dump_value_range (dump_file, SSA_NAME_VALUE_RANGE (use));
+ dump_value_range (dump_file, vr_value[SSA_NAME_VERSION (use)]);
}
fprintf (dump_file, "\n");
}
/* Compute the value of the predicate COND by checking the known
- ranges of each of its operands. */
- val = vrp_evaluate_conditional (cond);
+ ranges of each of its operands.
+
+ Note that we cannot evaluate all the equivalent ranges here
+ because those ranges may not yet be final and with the current
+ propagation strategy, we cannot determine when the value ranges
+ of the names in the equivalence set have changed.
+
+ For instance, given the following code fragment
+
+ i_5 = PHI <8, i_13>
+ ...
+ i_14 = ASSERT_EXPR <i_5, i_5 != 0>
+ if (i_14 == 1)
+ ...
+
+ Assume that on the first visit to i_14, i_5 has the temporary
+ range [8, 8] because the second argument to the PHI function is
+ not yet executable. We derive the range ~[0, 0] for i_14 and the
+ equivalence set { i_5 }. So, when we visit 'if (i_14 == 1)' for
+ the first time, since i_14 is equivalent to the range [8, 8], we
+ determine that the predicate is always false.
+
+ On the next round of propagation, i_13 is determined to be
+ VARYING, which causes i_5 to drop down to VARYING. So, another
+ visit to i_14 is scheduled. In this second visit, we compute the
+ exact same range and equivalence set for i_14, namely ~[0, 0] and
+ { i_5 }. But we did not have the previous range for i_5
+ registered, so vrp_visit_assignment thinks that the range for
+ i_14 has not changed. Therefore, the predicate 'if (i_14 == 1)'
+ is not visited again, which stops propagation from visiting
+ statements in the THEN clause of that if().
+
+ To properly fix this we would need to keep the previous range
+ value for the names in the equivalence set. This way we would've
+ discovered that from one visit to the other i_5 changed from
+ range [8, 8] to VR_VARYING.
+
+ However, fixing this apparent limitation may not be worth the
+ additional checking. Testing on several code bases (GCC, DLV,
+ MICO, TRAMP3D and SPEC2000) showed that doing this results in
+ 4 more predicates folded in SPEC. */
+ val = vrp_evaluate_conditional (cond, false);
if (val)
*taken_edge_p = find_taken_edge (bb_for_stmt (stmt), val);
@@ -2108,11 +3173,11 @@ vrp_visit_stmt (tree stmt, edge *taken_edge_p, tree *output_p)
union of VR0 and VR1. */
static void
-vrp_meet (value_range *vr0, value_range *vr1)
+vrp_meet (value_range_t *vr0, value_range_t *vr1)
{
if (vr0->type == VR_UNDEFINED)
{
- *vr0 = *vr1;
+ copy_value_range (vr0, vr1);
return;
}
@@ -2130,13 +3195,6 @@ vrp_meet (value_range *vr0, value_range *vr1)
if (vr1->type == VR_VARYING)
{
- *vr0 = *vr1;
- return;
- }
-
- /* If either is a symbolic range, drop to VARYING. */
- if (symbolic_range_p (vr0) || symbolic_range_p (vr1))
- {
set_value_range_to_varying (vr0);
return;
}
@@ -2147,28 +3205,46 @@ vrp_meet (value_range *vr0, value_range *vr1)
union of both ranges. */
if (value_ranges_intersect_p (vr0, vr1))
{
+ int cmp;
tree min, max;
- min = vr0->min;
- max = vr0->max;
-
/* The lower limit of the new range is the minimum of the
- two ranges. */
- if (compare_values (vr0->min, vr1->min) == 1)
+ two ranges. If they cannot be compared, the result is
+ VARYING. */
+ cmp = compare_values (vr0->min, vr1->min);
+ if (cmp == 0 || cmp == 1)
min = vr1->min;
+ else if (cmp == -1)
+ min = vr0->min;
+ else
+ {
+ set_value_range_to_varying (vr0);
+ return;
+ }
- /* The upper limit of the new range is the maximum of the
- two ranges. */
- if (compare_values (vr0->max, vr1->max) == -1)
+ /* Similarly, the upper limit of the new range is the
+ maximum of the two ranges. If they cannot be compared,
+ the result is VARYING. */
+ cmp = compare_values (vr0->max, vr1->max);
+ if (cmp == 0 || cmp == -1)
max = vr1->max;
+ else if (cmp == 1)
+ max = vr0->max;
+ else
+ {
+ set_value_range_to_varying (vr0);
+ return;
+ }
+
+ /* The resulting set of equivalences is the intersection of
+ the two sets. */
+ if (vr0->equiv && vr1->equiv && vr0->equiv != vr1->equiv)
+ bitmap_and_into (vr0->equiv, vr1->equiv);
- set_value_range (vr0, vr0->type, min, max);
+ set_value_range (vr0, vr0->type, min, max, vr0->equiv);
}
else
- {
- /* The two ranges don't intersect, set the result to VR_VARYING. */
- set_value_range_to_varying (vr0);
- }
+ goto no_meet;
}
else if (vr0->type == VR_ANTI_RANGE && vr1->type == VR_ANTI_RANGE)
{
@@ -2176,28 +3252,49 @@ vrp_meet (value_range *vr0, value_range *vr1)
if (compare_values (vr0->min, vr1->min) == 0
&& compare_values (vr0->max, vr1->max) == 0
&& compare_values (vr0->min, vr0->max) == 0)
- /* Nothing to do. */ ;
+ {
+ /* The resulting set of equivalences is the intersection of
+ the two sets. */
+ if (vr0->equiv && vr1->equiv && vr0->equiv != vr1->equiv)
+ bitmap_and_into (vr0->equiv, vr1->equiv);
+ }
else
- set_value_range_to_varying (vr0);
+ goto no_meet;
}
else if (vr0->type == VR_ANTI_RANGE || vr1->type == VR_ANTI_RANGE)
{
- /* A range [VAL1, VAL2] and an anti-range ~[VAL3, VAL4] meet
- only if the ranges have an empty intersection. The result of
- the meet operation is the anti-range. */
- if (!value_ranges_intersect_p (vr0, vr1))
+ /* A numeric range [VAL1, VAL2] and an anti-range ~[VAL3, VAL4]
+ meet only if the ranges have an empty intersection. The
+ result of the meet operation is the anti-range. */
+ if (!symbolic_range_p (vr0)
+ && !symbolic_range_p (vr1)
+ && !value_ranges_intersect_p (vr0, vr1))
{
if (vr1->type == VR_ANTI_RANGE)
- *vr0 = *vr1;
+ copy_value_range (vr0, vr1);
}
else
- set_value_range_to_varying (vr0);
+ goto no_meet;
}
else
gcc_unreachable ();
+
+ return;
+
+no_meet:
+ /* The two range VR0 and VR1 do not meet. Before giving up and
+ setting the result to VARYING, see if we can at least derive a
+ useful anti-range. */
+ if (!symbolic_range_p (vr0)
+ && !range_includes_zero_p (vr0)
+ && !symbolic_range_p (vr1)
+ && !range_includes_zero_p (vr1))
+ set_value_range_to_nonnull (vr0, TREE_TYPE (vr0->min));
+ else
+ set_value_range_to_varying (vr0);
}
-
+
/* Visit all arguments for PHI node PHI that flow through executable
edges. If a valid value range can be derived from all the incoming
value ranges, set a new range for the LHS of PHI. */
@@ -2207,8 +3304,10 @@ vrp_visit_phi_node (tree phi)
{
int i;
tree lhs = PHI_RESULT (phi);
- value_range *lhs_vr = get_value_range (lhs);
- value_range vr_result = *lhs_vr;
+ value_range_t *lhs_vr = get_value_range (lhs);
+ value_range_t vr_result = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
+
+ copy_value_range (&vr_result, lhs_vr);
if (dump_file && (dump_flags & TDF_DETAILS))
{
@@ -2231,7 +3330,7 @@ vrp_visit_phi_node (tree phi)
if (e->flags & EDGE_EXECUTABLE)
{
tree arg = PHI_ARG_DEF (phi, i);
- value_range vr_arg;
+ value_range_t vr_arg;
if (TREE_CODE (arg) == SSA_NAME)
vr_arg = *(get_value_range (arg));
@@ -2240,6 +3339,7 @@ vrp_visit_phi_node (tree phi)
vr_arg.type = VR_RANGE;
vr_arg.min = arg;
vr_arg.max = arg;
+ vr_arg.equiv = NULL;
}
if (dump_file && (dump_flags & TDF_DETAILS))
@@ -2259,10 +3359,7 @@ vrp_visit_phi_node (tree phi)
}
if (vr_result.type == VR_VARYING)
- {
- set_value_range_to_varying (lhs_vr);
- return SSA_PROP_VARYING;
- }
+ goto varying;
/* To prevent infinite iterations in the algorithm, derive ranges
when the new value is slightly bigger or smaller than the
@@ -2291,20 +3388,22 @@ vrp_visit_phi_node (tree phi)
VARYING. */
if (vr_result.min == TYPE_MIN_VALUE (TREE_TYPE (vr_result.min))
&& vr_result.max == TYPE_MAX_VALUE (TREE_TYPE (vr_result.max)))
- {
- set_value_range_to_varying (lhs_vr);
- return SSA_PROP_VARYING;
- }
+ goto varying;
}
}
/* If the new range is different than the previous value, keep
iterating. */
- if (update_value_range (lhs_vr, vr_result.type, vr_result.min, vr_result.max))
+ if (update_value_range (lhs, &vr_result))
return SSA_PROP_INTERESTING;
/* Nothing changed, don't add outgoing edges. */
return SSA_PROP_NOT_INTERESTING;
+
+ /* No match found. Set the LHS to VARYING. */
+varying:
+ set_value_range_to_varying (lhs_vr);
+ return SSA_PROP_VARYING;
}
@@ -2313,8 +3412,9 @@ vrp_visit_phi_node (tree phi)
static void
vrp_finalize (void)
{
- basic_block bb;
- int num_pred_folded = 0;
+ size_t i;
+ prop_value_t *single_val_range;
+ bool do_value_subst_p;
if (dump_file)
{
@@ -2323,33 +3423,42 @@ vrp_finalize (void)
fprintf (dump_file, "\n");
}
- FOR_EACH_BB (bb)
+ /* We may have ended with ranges that have exactly one value. Those
+ values can be substituted as any other copy/const propagated
+ value using substitute_and_fold. */
+ single_val_range = xmalloc (num_ssa_names * sizeof (*single_val_range));
+ memset (single_val_range, 0, num_ssa_names * sizeof (*single_val_range));
+
+ do_value_subst_p = false;
+ for (i = 0; i < num_ssa_names; i++)
+ if (vr_value[i]
+ && vr_value[i]->type == VR_RANGE
+ && vr_value[i]->min == vr_value[i]->max)
+ {
+ single_val_range[i].value = vr_value[i]->min;
+ do_value_subst_p = true;
+ }
+
+ if (!do_value_subst_p)
{
- tree last = last_stmt (bb);
- if (last && TREE_CODE (last) == COND_EXPR)
- {
- tree val = vrp_evaluate_conditional (COND_EXPR_COND (last));
- if (val)
- {
- if (dump_file)
- {
- fprintf (dump_file, "Folding predicate ");
- print_generic_expr (dump_file, COND_EXPR_COND (last), 0);
- fprintf (dump_file, " to ");
- print_generic_expr (dump_file, val, 0);
- fprintf (dump_file, "\n");
- }
-
- num_pred_folded++;
- COND_EXPR_COND (last) = val;
- update_stmt (last);
- }
- }
+ /* We found no single-valued ranges, don't waste time trying to
+ do single value substitution in substitute_and_fold. */
+ free (single_val_range);
+ single_val_range = NULL;
}
- if (dump_file && (dump_flags & TDF_STATS))
- fprintf (dump_file, "\nNumber of predicates folded: %d\n\n",
- num_pred_folded);
+ substitute_and_fold (single_val_range, true);
+
+ /* Free allocated memory. */
+ for (i = 0; i < num_ssa_names; i++)
+ if (vr_value[i])
+ {
+ BITMAP_FREE (vr_value[i]->equiv);
+ free (vr_value[i]);
+ }
+
+ free (single_val_range);
+ free (vr_value);
}
@@ -2362,6 +3471,34 @@ vrp_finalize (void)
This is essentially an SSA-CCP pass modified to deal with ranges
instead of constants.
+ While propagating ranges, we may find that two or more SSA name
+ have equivalent, though distinct ranges. For instance,
+
+ 1 x_9 = p_3->a;
+ 2 p_4 = ASSERT_EXPR <p_3, p_3 != 0>
+ 3 if (p_4 == q_2)
+ 4 p_5 = ASSERT_EXPR <p_4, p_4 == q_2>;
+ 5 endif
+ 6 if (q_2)
+
+ In the code above, pointer p_5 has range [q_2, q_2], but from the
+ code we can also determine that p_5 cannot be NULL and, if q_2 had
+ a non-varying range, p_5's range should also be compatible with it.
+
+ These equivalences are created by two expressions: ASSERT_EXPR and
+ copy operations. Since p_5 is an assertion on p_4, and p_4 was the
+ result of another assertion, then we can use the fact that p_5 and
+ p_4 are equivalent when evaluating p_5's range.
+
+ Together with value ranges, we also propagate these equivalences
+ between names so that we can take advantage of information from
+ multiple ranges when doing final replacement. Note that this
+ equivalency relation is transitive but not symmetric.
+
+ In the example above, p_5 is equivalent to p_4, q_2 and p_3, but we
+ cannot assert that q_2 is equivalent to p_5 because q_2 may be used
+ in contexts where that assertion does not hold (e.g., in line 6).
+
TODO, the main difference between this pass and Patterson's is that
we do not propagate edge probabilities. We only compute whether
edges can be taken or not. That is, instead of having a spectrum
@@ -2378,11 +3515,9 @@ execute_vrp (void)
if (cfg_loops)
scev_initialize (cfg_loops);
- if (vrp_initialize ())
- {
- ssa_propagate (vrp_visit_stmt, vrp_visit_phi_node);
- vrp_finalize ();
- }
+ vrp_initialize ();
+ ssa_propagate (vrp_visit_stmt, vrp_visit_phi_node);
+ vrp_finalize ();
if (cfg_loops)
{
diff --git a/gcc/tree.c b/gcc/tree.c
index 9b45e0a3a5a..0592704b272 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -131,19 +131,36 @@ static GTY (()) tree int_cst_node;
static GTY ((if_marked ("ggc_marked_p"), param_is (union tree_node)))
htab_t int_cst_hash_table;
+/* General tree->tree mapping structure for use in hash tables. */
+
+struct tree_map GTY(())
+{
+ hashval_t hash;
+ tree from;
+ tree to;
+};
+
+static GTY ((if_marked ("tree_map_marked_p"), param_is (struct tree_map)))
+ htab_t debug_expr_for_decl;
+
static void set_type_quals (tree, int);
static int type_hash_eq (const void *, const void *);
static hashval_t type_hash_hash (const void *);
+static int tree_map_eq (const void *, const void *);
+static hashval_t tree_map_hash (const void *);
static hashval_t int_cst_hash_hash (const void *);
static int int_cst_hash_eq (const void *, const void *);
static void print_type_hash_statistics (void);
+static void print_debug_expr_statistics (void);
static tree make_vector_type (tree, int, enum machine_mode);
static int type_hash_marked_p (const void *);
+static int tree_map_marked_p (const void *);
static unsigned int type_hash_list (tree, hashval_t);
static unsigned int attribute_hash_list (tree, hashval_t);
tree global_trees[TI_MAX];
tree integer_types[itk_none];
+
/* Init tree.c. */
@@ -153,9 +170,15 @@ init_ttree (void)
/* Initialize the hash table of types. */
type_hash_table = htab_create_ggc (TYPE_HASH_INITIAL_SIZE, type_hash_hash,
type_hash_eq, 0);
+
+ debug_expr_for_decl = htab_create_ggc (512, tree_map_hash,
+ tree_map_eq, 0);
+
int_cst_hash_table = htab_create_ggc (1024, int_cst_hash_hash,
int_cst_hash_eq, NULL);
+
int_cst_node = make_node (INTEGER_CST);
+
}
@@ -3430,6 +3453,76 @@ build_variant_type_copy (tree type)
return t;
}
+/* Return true if the from tree in both tree maps are equal. */
+
+static int
+tree_map_eq (const void *va, const void *vb)
+{
+ const struct tree_map *a = va, *b = vb;
+ return (a->from == b->from);
+}
+
+/* Hash a from tree in a tree_map. */
+
+static hashval_t
+tree_map_hash (const void *item)
+{
+ return (((const struct tree_map *) item)->hash);
+}
+
+/* Return true if this tree map structure is marked for garbage collection
+ purposes. We simply return true if the from tree is marked, so that this
+ structure goes away when the from tree goes away. */
+
+static int
+tree_map_marked_p (const void *p)
+{
+ tree from = ((struct tree_map *) p)->from;
+
+ return ggc_marked_p (from);
+}
+
+/* Print out the statistics for the DECL_DEBUG_EXPR hash table. */
+
+static void
+print_debug_expr_statistics (void)
+{
+ fprintf (stderr, "DECL_DEBUG_EXPR hash: size %ld, %ld elements, %f collisions\n",
+ (long) htab_size (debug_expr_for_decl),
+ (long) htab_elements (debug_expr_for_decl),
+ htab_collisions (debug_expr_for_decl));
+}
+
+/* Lookup a debug expression for FROM, and return it if we find one. */
+
+tree
+decl_debug_expr_lookup (tree from)
+{
+ struct tree_map *h, in;
+ in.from = from;
+
+ h = htab_find_with_hash (debug_expr_for_decl, &in, htab_hash_pointer (from));
+ if (h)
+ return h->to;
+ return NULL_TREE;
+}
+
+/* Insert a mapping FROM->TO in the debug expression hashtable. */
+
+void
+decl_debug_expr_insert (tree from, tree to)
+{
+ struct tree_map *h;
+ void **loc;
+
+ h = ggc_alloc (sizeof (struct tree_map));
+ h->hash = htab_hash_pointer (from);
+ h->from = from;
+ h->to = to;
+ loc = htab_find_slot_with_hash (debug_expr_for_decl, h, h->hash, INSERT);
+ *(struct tree_map **) loc = h;
+}
+
/* Hashing of types so that we don't make duplicates.
The entry point is `type_hash_canon'. */
@@ -5261,6 +5354,7 @@ dump_tree_statistics (void)
fprintf (stderr, "(No per-node statistics)\n");
#endif
print_type_hash_statistics ();
+ print_debug_expr_statistics ();
lang_hooks.print_statistics ();
}
@@ -5772,7 +5866,7 @@ build_common_builtin_nodes (void)
tmp = tree_cons (NULL_TREE, size_type_node, void_list_node);
tmp = tree_cons (NULL_TREE, const_ptr_type_node, tmp);
tmp = tree_cons (NULL_TREE, const_ptr_type_node, tmp);
- ftype = build_function_type (ptr_type_node, tmp);
+ ftype = build_function_type (integer_type_node, tmp);
local_define_builtin ("__builtin_memcmp", ftype, BUILT_IN_MEMCMP,
"memcmp", ECF_PURE | ECF_NOTHROW);
}
@@ -6600,7 +6694,7 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, struct pointer_set_t *pset)
case SSA_NAME:
case FIELD_DECL:
case RESULT_DECL:
- /* None of thse have subtrees other than those already walked
+ /* None of these have subtrees other than those already walked
above. */
break;
diff --git a/gcc/tree.h b/gcc/tree.h
index dcede1571c7..21a31a0ab26 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -1349,17 +1349,12 @@ struct tree_exp GTY(())
#define SSA_NAME_VALUE(N) \
SSA_NAME_CHECK (N)->ssa_name.value_handle
-/* Range information for SSA_NAMEs. */
-#define SSA_NAME_VALUE_RANGE(N) \
- SSA_NAME_CHECK (N)->ssa_name.value_range
-
/* Auxiliary pass-specific data. */
#define SSA_NAME_AUX(N) \
SSA_NAME_CHECK (N)->ssa_name.aux
#ifndef _TREE_FLOW_H
struct ptr_info_def;
-struct value_range_def;
#endif
@@ -1397,9 +1392,6 @@ struct tree_ssa_name GTY(())
as well. */
tree value_handle;
- /* Value range information. */
- struct value_range_def *value_range;
-
/* Auxiliary information stored with the ssa name. */
PTR GTY((skip)) aux;
@@ -2064,10 +2056,17 @@ struct tree_binfo GTY (())
writing debugging information about vfield and vbase decls for C++. */
#define DECL_FCONTEXT(NODE) (FIELD_DECL_CHECK (NODE)->decl.vindex)
+extern tree decl_debug_expr_lookup (tree);
+extern void decl_debug_expr_insert (tree, tree);
+
/* For VAR_DECL, this is set to either an expression that it was split
from (if DECL_DEBUG_EXPR_IS_FROM is true), otherwise a tree_list of
subexpressions that it was split into. */
-#define DECL_DEBUG_EXPR(NODE) (DECL_CHECK (NODE)->decl.vindex)
+#define DECL_DEBUG_EXPR(NODE) \
+ (decl_debug_expr_lookup (VAR_DECL_CHECK (NODE)))
+
+#define SET_DECL_DEBUG_EXPR(NODE, VAL) \
+ (decl_debug_expr_insert (VAR_DECL_CHECK (NODE), (VAL)))
#define DECL_DEBUG_EXPR_IS_FROM(NODE) \
(DECL_CHECK (NODE)->decl.debug_expr_is_from)
@@ -3552,6 +3551,7 @@ extern tree fold_convert (tree, tree);
extern tree fold_single_bit_test (enum tree_code, tree, tree, tree);
extern tree fold_ignored_result (tree);
extern tree fold_abs_const (tree, tree);
+extern tree fold_indirect_ref_1 (tree, tree);
extern tree force_fit_type (tree, int, bool, bool);
@@ -3613,6 +3613,7 @@ extern bool tree_swap_operands_p (tree, tree, bool);
extern enum tree_code swap_tree_comparison (enum tree_code);
extern bool ptr_difference_const (tree, tree, HOST_WIDE_INT *);
+extern enum tree_code invert_tree_comparison (enum tree_code, bool);
/* In builtins.c */
extern tree fold_builtin (tree, tree, bool);
@@ -4002,9 +4003,6 @@ extern int tree_node_sizes[];
restricted to creating gimple expressions. */
extern bool in_gimple_form;
-/* In tree-ssa-threadupdate.c. */
-extern bool thread_through_all_blocks (void);
-
/* In tree-gimple.c. */
extern tree get_base_address (tree t);
diff --git a/gcc/treelang/ChangeLog b/gcc/treelang/ChangeLog
index b1a80e940e0..b0d3f002fa2 100644
--- a/gcc/treelang/ChangeLog
+++ b/gcc/treelang/ChangeLog
@@ -1,3 +1,9 @@
+2005-05-31 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * treelang/lex.l, treelang/parse.y: Don't include errors.h and
+ include toplev.h.
+ * treelang/Make-lang.in: Updates dependencies.
+
2005-05-02 Andrew Pinski <pinskia@physics.uc.edu>
PR treelang/21345
diff --git a/gcc/treelang/Make-lang.in b/gcc/treelang/Make-lang.in
index 239d3f9bf49..bb170b554ad 100644
--- a/gcc/treelang/Make-lang.in
+++ b/gcc/treelang/Make-lang.in
@@ -116,11 +116,12 @@ treelang/spec.o: treelang/spec.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h diagnostic.h $(TREE_H) flags.h toplev.h langhooks.h $(TM_H)
treelang/parse.o: treelang/parse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
- $(TM_H) diagnostic.h treelang/treelang.h input.h treelang/treetree.h
+ $(TM_H) diagnostic.h treelang/treelang.h input.h treelang/treetree.h \
+ toplev.h
treelang/lex.o: treelang/lex.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) diagnostic.h $(TREE_H) treelang/treelang.h input.h \
- treelang/parse.h
+ treelang/parse.h toplev.h
# generated files the files from lex and yacc are put into the source
# directory in case someone wants to build but does not have
diff --git a/gcc/treelang/lex.l b/gcc/treelang/lex.l
index 188c480a550..9e4943046b8 100644
--- a/gcc/treelang/lex.l
+++ b/gcc/treelang/lex.l
@@ -37,13 +37,13 @@
#include "coretypes.h"
#include "tm.h"
#include "input.h"
-#include "errors.h"
#include "tree.h"
/* Token defs. */
#include "treelang.h"
#include "parse.h"
#include "treetree.h"
+#include "toplev.h"
extern int option_lexer_trace;
diff --git a/gcc/treelang/parse.y b/gcc/treelang/parse.y
index a18717cb9f5..fe1d9b16207 100644
--- a/gcc/treelang/parse.y
+++ b/gcc/treelang/parse.y
@@ -39,11 +39,11 @@ the GCC compiler. */
#include "system.h"
#include "coretypes.h"
#include "tm.h"
-#include "errors.h"
#include "timevar.h"
#include "treelang.h"
#include "treetree.h"
+#include "toplev.h"
#define YYDEBUG 1
#define YYPRINT(file, type, value) print_token (file, type, value)
diff --git a/gcc/unwind-compat.c b/gcc/unwind-compat.c
index 3e8c302f03a..4b5a2b3c0ef 100644
--- a/gcc/unwind-compat.c
+++ b/gcc/unwind-compat.c
@@ -1,5 +1,5 @@
/* Backward compatibility unwind routines.
- Copyright (C) 2004
+ Copyright (C) 2004, 2005
Free Software Foundation, Inc.
This file is part of GCC.
diff --git a/gcc/unwind-dw2-fde-compat.c b/gcc/unwind-dw2-fde-compat.c
index b5fd3ce37f6..55adc3660fe 100644
--- a/gcc/unwind-dw2-fde-compat.c
+++ b/gcc/unwind-dw2-fde-compat.c
@@ -1,5 +1,5 @@
/* Backward compatibility unwind routines.
- Copyright (C) 2004
+ Copyright (C) 2004, 2005
Free Software Foundation, Inc.
This file is part of GCC.
diff --git a/gcc/unwind-dw2-fde.c b/gcc/unwind-dw2-fde.c
index 15cdd57f69b..df9eafe1f43 100644
--- a/gcc/unwind-dw2-fde.c
+++ b/gcc/unwind-dw2-fde.c
@@ -1,5 +1,5 @@
/* Subroutines needed for unwinding stack frames for exception handling. */
-/* Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+/* Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
Free Software Foundation, Inc.
Contributed by Jason Merrill <jason@cygnus.com>.
diff --git a/gcc/value-prof.c b/gcc/value-prof.c
index b96cdcafbf6..e6b45a519e5 100644
--- a/gcc/value-prof.c
+++ b/gcc/value-prof.c
@@ -1221,12 +1221,6 @@ tree_divmod_fixed_value_transform (tree stmt)
if (simple_cst_equal (op2, value) != 1 || 2 * count < all)
return false;
- if (dump_file)
- {
- fprintf (dump_file, "Div/mod by constant transformation on insn ");
- print_generic_stmt (dump_file, stmt, TDF_SLIM);
- }
-
/* Compute probability of taking the optimal path. */
prob = (count * REG_BR_PROB_BASE + all / 2) / all;
@@ -1235,6 +1229,16 @@ tree_divmod_fixed_value_transform (tree stmt)
val >> (HOST_BITS_PER_WIDE_INT - 1) >> 1);
result = tree_divmod_fixed_value (stmt, op, op1, op2, tree_val, prob, count, all);
+ if (dump_file)
+ {
+ fprintf (dump_file, "Div/mod by constant ");
+ print_generic_expr (dump_file, value, TDF_SLIM);
+ fprintf (dump_file, "=");
+ print_generic_expr (dump_file, tree_val, TDF_SLIM);
+ fprintf (dump_file, " transformation on insn ");
+ print_generic_stmt (dump_file, stmt, TDF_SLIM);
+ }
+
TREE_OPERAND (modify, 1) = result;
return true;
@@ -1489,11 +1493,11 @@ tree_mod_subtract (tree stmt, tree operation, tree op1, tree op2,
e12->flags &= ~EDGE_FALLTHRU;
e12->flags |= EDGE_FALSE_VALUE;
e12->probability = REG_BR_PROB_BASE - prob1;
- e12->count = count1;
+ e12->count = all - count1;
e14 = make_edge (bb, bb4, EDGE_TRUE_VALUE);
e14->probability = prob1;
- e14->count = all - count1;
+ e14->count = count1;
if (ncounts) /* Assumed to be 0 or 1. */
{
@@ -1653,16 +1657,6 @@ tree_divmod_values_to_profile (tree stmt, histogram_values *values)
if (is_gimple_reg (divisor))
{
- /* Check for a special case where the divisor is power(s) of 2.
- This is more aggressive than the RTL version, under the
- assumption that later phases will reduce / or % by power of 2
- to something clever most of the time. Signed or unsigned. */
- hist = ggc_alloc (sizeof (*hist));
- hist->hvalue.tree.value = divisor;
- hist->hvalue.tree.stmt = stmt;
- hist->type = HIST_TYPE_POW2;
- VEC_quick_push (histogram_value, *values, hist);
-
/* Check for the case where the divisor is the same value most
of the time. */
hist = ggc_alloc (sizeof (*hist));
@@ -1677,6 +1671,13 @@ tree_divmod_values_to_profile (tree stmt, histogram_values *values)
if (TREE_CODE (rhs) == TRUNC_MOD_EXPR
&& TYPE_UNSIGNED (type))
{
+ /* Check for a special case where the divisor is power of 2. */
+ hist = ggc_alloc (sizeof (*hist));
+ hist->hvalue.tree.value = divisor;
+ hist->hvalue.tree.stmt = stmt;
+ hist->type = HIST_TYPE_POW2;
+ VEC_quick_push (histogram_value, *values, hist);
+
hist = ggc_alloc (sizeof (*hist));
hist->hvalue.tree.stmt = stmt;
hist->hvalue.tree.value
diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c
index a6a9c15d79e..626a8e04dd9 100644
--- a/gcc/var-tracking.c
+++ b/gcc/var-tracking.c
@@ -1441,8 +1441,7 @@ track_expr_p (tree expr)
don't need to track this expression if the ultimate declaration is
ignored. */
realdecl = expr;
- if (DECL_DEBUG_EXPR (realdecl)
- && DECL_DEBUG_EXPR_IS_FROM (realdecl))
+ if (DECL_DEBUG_EXPR_IS_FROM (realdecl) && DECL_DEBUG_EXPR (realdecl))
{
realdecl = DECL_DEBUG_EXPR (realdecl);
/* ??? We don't yet know how to emit DW_OP_piece for variable
diff --git a/gcc/varray.c b/gcc/varray.c
index e80827a5ce6..ee3d76d3910 100644
--- a/gcc/varray.c
+++ b/gcc/varray.c
@@ -31,7 +31,11 @@
#include "system.h"
#include "coretypes.h"
#include "tm.h"
-#include "errors.h"
+#ifdef GENERATOR_FILE
+# include "errors.h"
+#else
+# include "toplev.h"
+#endif
#include "varray.h"
#include "ggc.h"
#include "hashtab.h"
diff --git a/gcc/vec.c b/gcc/vec.c
index 67643b5abd2..225cfb1545c 100644
--- a/gcc/vec.c
+++ b/gcc/vec.c
@@ -23,9 +23,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "system.h"
#include "ggc.h"
#include "vec.h"
-#include "errors.h"
#include "coretypes.h"
#include "tree.h"
+#include "toplev.h"
struct vec_prefix
{
diff --git a/gcc/vec.h b/gcc/vec.h
index 13c4ed6b654..9b16976e268 100644
--- a/gcc/vec.h
+++ b/gcc/vec.h
@@ -29,17 +29,14 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
out-of-line generic functions. The vectors are designed to
interoperate with the GTY machinery.
- Because of the different behavior of objects and of pointers to
- objects, there are two flavors. One to deal with a vector of
- pointers to objects, and one to deal with a vector of objects
- themselves. Both of these pass pointers to objects around -- in
- the former case the pointers are stored into the vector and in the
- latter case the pointers are dereferenced and the objects copied
- into the vector. Therefore, when using a vector of pointers, the
- objects pointed to must be long lived, but when dealing with a
- vector of objects, the source objects need not be. The vector of
- pointers API is also appropriate for small register sized objects
- like integers.
+ Because of the different behavior of structure objects, scalar
+ objects and of pointers, there are three flavors, one for each of
+ these variants. Both the structure object and pointer variants
+ pass pointers to objects around -- in the former case the pointers
+ are stored into the vector and in the latter case the pointers are
+ dereferenced and the objects copied into the vector. The scalar
+ object variant is suitable for int-like objects, and the vector
+ elements are returned by value.
There are both 'index' and 'iterate' accessors. The iterator
returns a boolean iteration condition and updates the iteration
@@ -96,20 +93,24 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
the 'space' predicate will tell you whether there is spare capacity
in the vector. You will not normally need to use these two functions.
- Vector types are defined using a DEF_VEC_{O,P}(TYPEDEF) macro, to
+ Vector types are defined using a DEF_VEC_{O,P,I}(TYPEDEF) macro, to
get the non-memory allocation version, and then a
- DEF_VEC_ALLOC_{O,P}(TYPEDEF,ALLOC) macro to get memory managed
+ DEF_VEC_ALLOC_{O,P,I}(TYPEDEF,ALLOC) macro to get memory managed
vectors. Variables of vector type are declared using a
VEC(TYPEDEF,ALLOC) macro. The ALLOC argument specifies the
allocation strategy, and can be either 'gc' or 'heap' for garbage
collected and heap allocated respectively. It can be 'none' to get
a vector that must be explicitly allocated (for instance as a
- trailing array of another structure). The characters O and P
- indicate whether TYPEDEF is a pointer (P) or object (O) type. Be
- careful to pick the correct one, as you'll get an awkward and
- inefficient API if you get the wrong one. There is a check, which
- results in a compile-time warning, for the P versions, but there is
- no check for the O versions, as that is not possible in plain C.
+ trailing array of another structure). The characters O, P and I
+ indicate whether TYPEDEF is a pointer (P), object (O) or integral
+ (I) type. Be careful to pick the correct one, as you'll get an
+ awkward and inefficient API if you use the wrong one. There is a
+ check, which results in a compile-time warning, for the P and I
+ versions, but there is no check for the O versions, as that is not
+ possible in plain C. Due to the way GTY works, you must annotate
+ any structures you wish to insert or reference from a vector with a
+ GTY(()) tag. You need to do this even if you never declare the GC
+ allocated variants.
An example of their use would be,
@@ -147,6 +148,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#define VEC_length(T,V) (VEC_OP(T,base,length)(VEC_BASE(V)))
/* Get the final element of the vector.
+ T VEC_T_last(VEC(T) *v); // Integer
T VEC_T_last(VEC(T) *v); // Pointer
T *VEC_T_last(VEC(T) *v); // Object
@@ -155,6 +157,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#define VEC_last(T,V) (VEC_OP(T,base,last)(VEC_BASE(V) VEC_CHECK_INFO))
/* Index into vector
+ T VEC_T_index(VEC(T) *v, unsigned ix); // Integer
T VEC_T_index(VEC(T) *v, unsigned ix); // Pointer
T *VEC_T_index(VEC(T) *v, unsigned ix); // Object
@@ -163,6 +166,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#define VEC_index(T,V,I) (VEC_OP(T,base,index)(VEC_BASE(V),I VEC_CHECK_INFO))
/* Iterate over vector
+ int VEC_T_iterate(VEC(T) *v, unsigned ix, T &ptr); // Integer
int VEC_T_iterate(VEC(T) *v, unsigned ix, T &ptr); // Pointer
int VEC_T_iterate(VEC(T) *v, unsigned ix, T *&ptr); // Object
@@ -228,6 +232,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
(VEC_OP(T,A,reserve)(&(V),R VEC_CHECK_INFO MEM_STAT_INFO))
/* Push object with no reallocation
+ T *VEC_T_quick_push (VEC(T) *v, T obj); // Integer
T *VEC_T_quick_push (VEC(T) *v, T obj); // Pointer
T *VEC_T_quick_push (VEC(T) *v, T *obj); // Object
@@ -240,6 +245,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
(VEC_OP(T,base,quick_push)(VEC_BASE(V),O VEC_CHECK_INFO))
/* Push object with reallocation
+ T *VEC_T_A_safe_push (VEC(T,A) *&v, T obj); // Integer
T *VEC_T_A_safe_push (VEC(T,A) *&v, T obj); // Pointer
T *VEC_T_A_safe_push (VEC(T,A) *&v, T *obj); // Object
@@ -251,6 +257,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
(VEC_OP(T,A,safe_push)(&(V),O VEC_CHECK_INFO MEM_STAT_INFO))
/* Pop element off end
+ T VEC_T_pop (VEC(T) *v); // Integer
T VEC_T_pop (VEC(T) *v); // Pointer
void VEC_T_pop (VEC(T) *v); // Object
@@ -279,6 +286,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
(VEC_OP(T,A,safe_grow)(&(V),I VEC_CHECK_INFO))
/* Replace element
+ T VEC_T_replace (VEC(T) *v, unsigned ix, T val); // Integer
T VEC_T_replace (VEC(T) *v, unsigned ix, T val); // Pointer
T *VEC_T_replace (VEC(T) *v, unsigned ix, T *val); // Object
@@ -292,6 +300,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
(VEC_OP(T,base,replace)(VEC_BASE(V),I,O VEC_CHECK_INFO))
/* Insert object with no reallocation
+ T *VEC_T_quick_insert (VEC(T) *v, unsigned ix, T val); // Integer
T *VEC_T_quick_insert (VEC(T) *v, unsigned ix, T val); // Pointer
T *VEC_T_quick_insert (VEC(T) *v, unsigned ix, T *val); // Object
@@ -304,6 +313,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
(VEC_OP(T,base,quick_insert)(VEC_BASE(V),I,O VEC_CHECK_INFO))
/* Insert object with reallocation
+ T *VEC_T_A_safe_insert (VEC(T,A) *&v, unsigned ix, T val); // Integer
T *VEC_T_A_safe_insert (VEC(T,A) *&v, unsigned ix, T val); // Pointer
T *VEC_T_A_safe_insert (VEC(T,A) *&v, unsigned ix, T *val); // Object
@@ -316,6 +326,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
(VEC_OP(T,A,safe_insert)(&(V),I,O VEC_CHECK_INFO MEM_STAT_INFO))
/* Remove element retaining order
+ T VEC_T_ordered_remove (VEC(T) *v, unsigned ix); // Integer
T VEC_T_ordered_remove (VEC(T) *v, unsigned ix); // Pointer
void VEC_T_ordered_remove (VEC(T) *v, unsigned ix); // Object
@@ -327,6 +338,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
(VEC_OP(T,base,ordered_remove)(VEC_BASE(V),I VEC_CHECK_INFO))
/* Remove element destroying order
+ T VEC_T_unordered_remove (VEC(T) *v, unsigned ix); // Integer
T VEC_T_unordered_remove (VEC(T) *v, unsigned ix); // Pointer
void VEC_T_unordered_remove (VEC(T) *v, unsigned ix); // Object
@@ -347,6 +359,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
/* Find the first index in the vector not less than the object.
unsigned VEC_T_lower_bound (VEC(T) *v, const T val,
+ bool (*lessthan) (const T, const T)); // Integer
+ unsigned VEC_T_lower_bound (VEC(T) *v, const T val,
bool (*lessthan) (const T, const T)); // Pointer
unsigned VEC_T_lower_bound (VEC(T) *v, const T *val,
bool (*lessthan) (const T*, const T*)); // Object
@@ -397,6 +411,14 @@ extern void vec_assert_fail (const char *, const char * VEC_CHECK_DECL)
/* Base of vector type, not user visible. */
#define VEC_T(T,B) \
+typedef struct VEC(T,B) \
+{ \
+ unsigned num; \
+ unsigned alloc; \
+ T vec[1]; \
+} VEC(T,B)
+
+#define VEC_T_GTY(T,B) \
typedef struct VEC(T,B) GTY(()) \
{ \
unsigned num; \
@@ -405,7 +427,7 @@ typedef struct VEC(T,B) GTY(()) \
} VEC(T,B)
/* Derived vector type, user visible. */
-#define VEC_TA(T,B,A,GTY) \
+#define VEC_TA_GTY(T,B,A,GTY) \
typedef struct VEC(T,A) GTY \
{ \
VEC(T,B) base; \
@@ -414,20 +436,49 @@ typedef struct VEC(T,A) GTY \
/* Convert to base type. */
#define VEC_BASE(P) ((P) ? &(P)->base : 0)
+/* Vector of integer-like object. */
+#if IN_GENGTYPE
+{"DEF_VEC_I", VEC_STRINGIFY (VEC_T(#0,#1)) ";", "none"},
+{"DEF_VEC_ALLOC_I", VEC_STRINGIFY (VEC_TA (#0,#1,#2,#3)) ";", NULL},
+#else
+#define DEF_VEC_I(T) \
+static inline void VEC_OP (T,must_be,integral_type) (void) \
+{ \
+ (void)~(T)0; \
+} \
+ \
+VEC_T(T,base); \
+VEC_TA_GTY(T,base,none,); \
+DEF_VEC_FUNC_P(T) \
+struct vec_swallow_trailing_semi
+#define DEF_VEC_ALLOC_I(T,A) \
+VEC_TA_GTY(T,base,A,); \
+DEF_VEC_ALLOC_FUNC_P(T,A) \
+struct vec_swallow_trailing_semi
+#endif
+
/* Vector of pointer to object. */
#if IN_GENGTYPE
-{"DEF_VEC_P", VEC_STRINGIFY (VEC_T(#0,#1)) ";", "none"},
-{"DEF_VEC_ALLOC_P", VEC_STRINGIFY (VEC_TA (#0,#1,#2,#3)) ";", NULL},
+{"DEF_VEC_P", VEC_STRINGIFY (VEC_T_GTY(#0,#1)) ";", "none"},
+{"DEF_VEC_ALLOC_P", VEC_STRINGIFY (VEC_TA_GTY (#0,#1,#2,#3)) ";", NULL},
#else
-
#define DEF_VEC_P(T) \
-VEC_T(T,base); \
- \
-static inline void VEC_OP (T,must,be_a_pointer_or_integer) (void) \
+static inline void VEC_OP (T,must_be,pointer_type) (void) \
{ \
- (void)((T)0 == (void *)0); \
+ (void)((T)1 == (void *)1); \
} \
\
+VEC_T_GTY(T,base); \
+VEC_TA_GTY(T,base,none,); \
+DEF_VEC_FUNC_P(T) \
+struct vec_swallow_trailing_semi
+#define DEF_VEC_ALLOC_P(T,A) \
+VEC_TA_GTY(T,base,A,); \
+DEF_VEC_ALLOC_FUNC_P(T,A) \
+struct vec_swallow_trailing_semi
+#endif
+
+#define DEF_VEC_FUNC_P(T) \
static inline unsigned VEC_OP (T,base,length) (const VEC(T,base) *vec_) \
{ \
return vec_ ? vec_->num : 0; \
@@ -598,13 +649,9 @@ static inline unsigned VEC_OP (T,base,lower_bound) \
len_ = half_; \
} \
return first_; \
-} \
- \
-VEC_TA(T,base,none,)
-
-#define DEF_VEC_ALLOC_P(T,A) \
-VEC_TA(T,base,A,); \
- \
+}
+
+#define DEF_VEC_ALLOC_FUNC_P(T,A) \
static inline VEC(T,A) *VEC_OP (T,A,alloc) \
(int alloc_ MEM_STAT_DECL) \
{ \
@@ -659,20 +706,25 @@ static inline T *VEC_OP (T,A,safe_insert) \
\
return VEC_OP (T,base,quick_insert) (VEC_BASE(*vec_), ix_, obj_ \
VEC_CHECK_PASS); \
-} \
- \
-struct vec_swallow_trailing_semi
-#endif
+}
/* Vector of object. */
#if IN_GENGTYPE
-{"DEF_VEC_O", VEC_STRINGIFY (VEC_T(#0,#1)) ";", "none"},
-{"DEF_VEC_ALLOC_O", VEC_STRINGIFY (VEC_TA(#0,#1,#2,#3)) ";", NULL},
+{"DEF_VEC_O", VEC_STRINGIFY (VEC_T_GTY(#0,#1)) ";", "none"},
+{"DEF_VEC_ALLOC_O", VEC_STRINGIFY (VEC_TA_GTY(#0,#1,#2,#3)) ";", NULL},
#else
-
#define DEF_VEC_O(T) \
-VEC_T(T,base); \
- \
+VEC_T_GTY(T,base); \
+VEC_TA_GTY(T,base,none,); \
+DEF_VEC_FUNC_O(T) \
+struct vec_swallow_trailing_semi
+#define DEF_VEC_ALLOC_O(T,A) \
+VEC_TA_GTY(T,base,A,); \
+DEF_VEC_ALLOC_FUNC_O(T,A) \
+struct vec_swallow_trailing_semi
+#endif
+
+#define DEF_VEC_FUNC_O(T) \
static inline unsigned VEC_OP (T,base,length) (const VEC(T,base) *vec_) \
{ \
return vec_ ? vec_->num : 0; \
@@ -830,13 +882,9 @@ static inline unsigned VEC_OP (T,base,lower_bound) \
len_ = half_; \
} \
return first_; \
-} \
- \
-VEC_TA(T,base,none,)
+}
-#define DEF_VEC_ALLOC_O(T,A) \
-VEC_TA(T,base,A,); \
- \
+#define DEF_VEC_ALLOC_FUNC_O(T,A) \
static inline VEC(T,A) *VEC_OP (T,A,alloc) \
(int alloc_ MEM_STAT_DECL) \
{ \
@@ -899,9 +947,5 @@ static inline T *VEC_OP (T,A,safe_insert) \
\
return VEC_OP (T,base,quick_insert) (VEC_BASE(*vec_), ix_, obj_ \
VEC_CHECK_PASS); \
-} \
- \
-struct vec_swallow_trailing_semi
-#endif
-
+}
#endif /* GCC_VEC_H */
diff --git a/include/ChangeLog b/include/ChangeLog
index 5265c311b85..3122162f20a 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,9 +1,27 @@
+2005-06-01 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * libiberty.h (vsnprintf): Add format attribute.
+
+2005-05-29 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * ansidecl.h: Add ATTRIBUTE_FPTR_PRINTF.
+
+2005-05-28 Eli Zaretskii <eliz@gnu.org>
+
+ * libiberty.h: (snprintf) [!HAVE_DECL_SNPRINTF]: Declare if
+ needed.
+ (vsnprintf) [!HAVE_DECL_VSNPRINTF]: Declare if needed.
+
+2005-05-25 Richard Henderson <rth@redhat.com>
+
+ * demangle.h (DEMANGLE_COMPONENT_HIDDEN_ALIAS): New.
+
2005-05-24 Gabriel Dos Reis <gdr@integrable-solutions.net>
* libiberty.h (ACONCAT): Properly cast value of alloca().
* ansidecl.h (ATTRIBUTE_UNUSED_LABEL): Don't define if
- __cplusplus.
+ __cplusplus.
2005-05-12 Steve Ellcey <sje@cup.hp.com>
@@ -63,7 +81,7 @@
2005-03-28 Mark Mitchell <mark@codesourcery.com>
* libiberty.h (ffs): Declare, if necessary.
-
+
2005-03-27 Gabriel Dos Reis <gdr@integrable-solutions.net>
* xregex2.h (_RE_ARGS): Remove definition and uses.
@@ -173,9 +191,9 @@
* hashtab.h (struct htab): Add size_prime_index.
2004-04-13 Jeff Law <law@redhat.com>
-
+
* hashtab.h (htab_remove_elt_with_hash): Prototype new function.
-
+
2004-03-30 Zack Weinberg <zack@codesourcery.com>
* hashtab.h, splay-tree.h: Use new shorter form of GTY markers.
diff --git a/include/ansidecl.h b/include/ansidecl.h
index 380e7b35114..439431182dc 100644
--- a/include/ansidecl.h
+++ b/include/ansidecl.h
@@ -312,6 +312,22 @@ So instead we use the macro below and test it against specific values. */
#define ATTRIBUTE_PRINTF_5 ATTRIBUTE_PRINTF(5, 6)
#endif /* ATTRIBUTE_PRINTF */
+/* Use ATTRIBUTE_FPTR_PRINTF when the format attribute is to be set on
+ a function pointer. Format attributes were allowed on function
+ pointers as of gcc 3.1. */
+#ifndef ATTRIBUTE_FPTR_PRINTF
+# if (GCC_VERSION >= 3001)
+# define ATTRIBUTE_FPTR_PRINTF(m, n) ATTRIBUTE_PRINTF(m, n)
+# else
+# define ATTRIBUTE_FPTR_PRINTF(m, n)
+# endif /* GNUC >= 3.1 */
+# define ATTRIBUTE_FPTR_PRINTF_1 ATTRIBUTE_FPTR_PRINTF(1, 2)
+# define ATTRIBUTE_FPTR_PRINTF_2 ATTRIBUTE_FPTR_PRINTF(2, 3)
+# define ATTRIBUTE_FPTR_PRINTF_3 ATTRIBUTE_FPTR_PRINTF(3, 4)
+# define ATTRIBUTE_FPTR_PRINTF_4 ATTRIBUTE_FPTR_PRINTF(4, 5)
+# define ATTRIBUTE_FPTR_PRINTF_5 ATTRIBUTE_FPTR_PRINTF(5, 6)
+#endif /* ATTRIBUTE_FPTR_PRINTF */
+
/* Use ATTRIBUTE_NULL_PRINTF when the format specifier may be NULL. A
NULL format specifier was allowed as of gcc 3.3. */
#ifndef ATTRIBUTE_NULL_PRINTF
diff --git a/include/demangle.h b/include/demangle.h
index 944a951772d..304a4c4e472 100644
--- a/include/demangle.h
+++ b/include/demangle.h
@@ -239,6 +239,9 @@ enum demangle_component_type
/* A reference temporary. This has one subtree, the name for which
this is a temporary. */
DEMANGLE_COMPONENT_REFTEMP,
+ /* A hidden alias. This has one subtree, the encoding for which it
+ is providing alternative linkage. */
+ DEMANGLE_COMPONENT_HIDDEN_ALIAS,
/* A standard substitution. This holds the name of the
substitution. */
DEMANGLE_COMPONENT_SUB_STD,
diff --git a/include/libiberty.h b/include/libiberty.h
index 9af981cd74e..a9a75eaa8ec 100644
--- a/include/libiberty.h
+++ b/include/libiberty.h
@@ -527,8 +527,17 @@ extern int asprintf (char **, const char *, ...) ATTRIBUTE_PRINTF_2;
/* Like vsprintf but provides a pointer to malloc'd storage, which
must be freed by the caller. */
-extern int vasprintf (char **, const char *, va_list)
- ATTRIBUTE_PRINTF(2,0);
+extern int vasprintf (char **, const char *, va_list) ATTRIBUTE_PRINTF(2,0);
+#endif
+
+#if defined(HAVE_DECL_SNPRINTF) && !HAVE_DECL_SNPRINTF
+/* Like sprintf but prints at most N characters. */
+extern int snprintf (char *, size_t, const char *, ...) ATTRIBUTE_PRINTF_3;
+#endif
+
+#if defined(HAVE_DECL_VSNPRINTF) && !HAVE_DECL_VSNPRINTF
+/* Like vsprintf but prints at most N characters. */
+extern int vsnprintf (char *, size_t, const char *, va_list) ATTRIBUTE_PRINTF(3,0);
#endif
#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog
index c13a0679b3b..f4e8a5e83cc 100644
--- a/libcpp/ChangeLog
+++ b/libcpp/ChangeLog
@@ -1,3 +1,90 @@
+2005-05-28 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * configure.ac: Check declarations for asprintf and vasprintf.
+ * config.in: Regenerate.
+ * configure: Likewise.
+
+ * charset.c (conversion_loop): Use XRESIZEVEC.
+ (convert_no_conversion): Likewise.
+ (convert_using_iconv): Likewise.
+ (init_iconv_desc): Cast return value of alloca.
+ (cpp_host_to_exec_charset): Use XNEWVEC.
+ (emit_numeric_escape): Use XRESIZEVEC.
+ (cpp_interpret_string): Use XNEWVEC.
+ (cpp_interpret_string): Use XRESIZEVEC.
+ (_cpp_interpret_identifier): Cast return value of alloca.
+ (_cpp_convert_input): Use XNEWVEC and XRESIZEVEC.
+ * directives.c (glue_header_name): Use XNEWVEC and XRESIZEVEC.
+ (parse_include): Use XNEWVEC.
+ (insert_pragma_entry): Rename local variable "new" to
+ "new_entry".
+ (save_registered_pragmas): Cast return value of xmemdup.
+ (destringize_and_run): Same for alloca.
+ (parse_assertion): Likewise.
+ (do_assert): Cast allocated storage to proper type.
+ (cpp_define): Likewise.
+ (_cpp_define_builtin): Likewise.
+ (cpp_undef): Likewise.
+ (handle_assertion): Likewise.
+ (cpp_push_buffer): Rename local variable "new" to "new_buffer".
+ * expr.c (CPP_UPLUS): Cast value to type cpp_ttype.
+ (CPP_UMINUS): Likewise.
+ (struct cpp_operator): Rename from struct operator.
+ (_cpp_expand_op_stack): Use XRESIZEVEC.
+ * files.c (pch_open_file): Use XNEWVEC.
+ (pch_open_file): Use XRESIZEVEC.
+ (read_file_guts): Use XNEWVEC and XRESIZEVEC.
+ (dir_name_of_file): Use XNEWVEC.
+ (make_cpp_file): Use XCNEW.
+ (make_cpp_dir): Likewise.
+ (allocate_file_hash_entries): USE XNEWVEC.
+ (cpp_included): Cast return value of htab_find_with_hash.
+ (append_file_to_dir): Use XNEWVEC.
+ (read_filename_string): Likewise. Use XRESIZEVEC too.
+ (read_name_map): Cast return value of alloca. Use XRESIZEVEC.
+ (remap_filename): Use XNEWVEC.
+ (struct pchf_entry): Move definition out of struct pchf_data.
+ (_cpp_save_file_entries): Use XCNEWVAR.
+ (_cpp_read_file_entries): Use XNEWVAR.
+ * identifiers.c (alloc_node): Use XOBNEW.
+ * init.c (cpp_create_reader): Use XCNEW.
+ (cpp_init_builtins): Cast of b->value to enum builtin_type.
+ (read_original_directory): Cast return value of alloca.
+ * lex.c (add_line_note): Use XRESIZEVEC.
+ (warn_about_normalization): Use XNEWVEC.
+ (_cpp_lex_direct): Cast node->directive_index to (enum cpp_ttype).
+ (new_buff): Use XNEWVEC.
+ * line-map.c (linemap_add): Use XRESIZEVEC.
+ * macro.c (builtin_macro): Cast return value of alloca.
+ (paste_tokens): Likewise.
+ (expand_arg): Use XNEWVEC and XRESIZEVEC.
+ (_cpp_save_parameter): Use XRESIZEVEC.
+ (create_iso_definition): Cast allocated storage to proper type.
+ (_cpp_create_definition): Likewise.
+ (cpp_macro_definition): Use XRESIZEVEC.
+ * makedepend.c (add_clm): Use XNEW.
+ (add_dir): Likewise.
+ * mkdeps.c (munge): Use XNEWVEC.
+ (deps_init): Use XCNEW.
+ (deps_add_target): Use XRESIZEVEC.
+ (deps_add_default_target): Cast return value of alloca.
+ (deps_add_dep): Use XRESIZEVEC.
+ (deps_add_vpath): Likewise. Use XNEWVEC too.
+ (deps_restore): Likewise.
+ * pch.c (save_idents): Use XNEW and XNEWVEC.
+ (cpp_save_state): Use XNEW.
+ (count_defs): Cast return value of htab_find.
+ (write_defs): Likewise.
+ (cpp_write_pch_deps): Use XNEWVEC.
+ (collect_ht_nodes): Use XRESIZEVEC.
+ (cpp_valid_state): Use XNEWVEC.
+ (save_macros): Use XRESIZEVEC. Cast return value of xmemdup.
+ * symtab.c (ht_create): Use XCNEW.
+ (ht_lookup_with_hash): Cast return value of obstack_copy0.
+ (ht_expand): Use XCNEWVEC.
+ * system.h (HAVE_DESIGNATED_INITIALIZERS): False if __cplusplus.
+ (bool): Do not define if __cplusplus.
+
2005-05-12 Zack Weinberg <zack@codesourcery.com>
* directives.c (#sccs table entry): Mark IN_I, consistent with #ident.
diff --git a/libcpp/charset.c b/libcpp/charset.c
index ba53f6337cc..f382d7f57fc 100644
--- a/libcpp/charset.c
+++ b/libcpp/charset.c
@@ -486,7 +486,7 @@ conversion_loop (int (*const one_conversion)(iconv_t, const uchar **, size_t *,
outbytesleft += OUTBUF_BLOCK_SIZE;
to->asize += OUTBUF_BLOCK_SIZE;
- to->text = xrealloc (to->text, to->asize);
+ to->text = XRESIZEVEC (uchar, to->text, to->asize);
outbuf = to->text + to->asize - outbytesleft;
}
}
@@ -538,7 +538,7 @@ convert_no_conversion (iconv_t cd ATTRIBUTE_UNUSED,
if (to->len + flen > to->asize)
{
to->asize = to->len + flen;
- to->text = xrealloc (to->text, to->asize);
+ to->text = XRESIZEVEC (uchar, to->text, to->asize);
}
memcpy (to->text + to->len, from, flen);
to->len += flen;
@@ -578,7 +578,7 @@ convert_using_iconv (iconv_t cd, const uchar *from, size_t flen,
outbytesleft += OUTBUF_BLOCK_SIZE;
to->asize += OUTBUF_BLOCK_SIZE;
- to->text = xrealloc (to->text, to->asize);
+ to->text = XRESIZEVEC (uchar, to->text, to->asize);
outbuf = (char *)to->text + to->asize - outbytesleft;
}
}
@@ -628,7 +628,7 @@ init_iconv_desc (cpp_reader *pfile, const char *to, const char *from)
return ret;
}
- pair = alloca(strlen(to) + strlen(from) + 2);
+ pair = (char *) alloca(strlen(to) + strlen(from) + 2);
strcpy(pair, from);
strcat(pair, "/");
@@ -751,7 +751,7 @@ cpp_host_to_exec_charset (cpp_reader *pfile, cppchar_t c)
/* This should never need to reallocate, but just in case... */
tbuf.asize = 1;
- tbuf.text = xmalloc (tbuf.asize);
+ tbuf.text = XNEWVEC (uchar, tbuf.asize);
tbuf.len = 0;
if (!APPLY_CONVERSION (pfile->narrow_cset_desc, sbuf, 1, &tbuf))
@@ -1087,7 +1087,7 @@ emit_numeric_escape (cpp_reader *pfile, cppchar_t n,
if (tbuf->len + nbwc > tbuf->asize)
{
tbuf->asize += OUTBUF_BLOCK_SIZE;
- tbuf->text = xrealloc (tbuf->text, tbuf->asize);
+ tbuf->text = XRESIZEVEC (uchar, tbuf->text, tbuf->asize);
}
for (i = 0; i < nbwc; i++)
@@ -1105,7 +1105,7 @@ emit_numeric_escape (cpp_reader *pfile, cppchar_t n,
if (tbuf->len + 1 > tbuf->asize)
{
tbuf->asize += OUTBUF_BLOCK_SIZE;
- tbuf->text = xrealloc (tbuf->text, tbuf->asize);
+ tbuf->text = XRESIZEVEC (uchar, tbuf->text, tbuf->asize);
}
tbuf->text[tbuf->len++] = n;
}
@@ -1306,7 +1306,7 @@ cpp_interpret_string (cpp_reader *pfile, const cpp_string *from, size_t count,
= wide ? pfile->wide_cset_desc : pfile->narrow_cset_desc;
tbuf.asize = MAX (OUTBUF_BLOCK_SIZE, from->len);
- tbuf.text = xmalloc (tbuf.asize);
+ tbuf.text = XNEWVEC (uchar, tbuf.asize);
tbuf.len = 0;
for (i = 0; i < count; i++)
@@ -1337,7 +1337,7 @@ cpp_interpret_string (cpp_reader *pfile, const cpp_string *from, size_t count,
/* NUL-terminate the 'to' buffer and translate it to a cpp_string
structure. */
emit_numeric_escape (pfile, 0, &tbuf, wide);
- tbuf.text = xrealloc (tbuf.text, tbuf.len);
+ tbuf.text = XRESIZEVEC (uchar, tbuf.text, tbuf.len);
to->text = tbuf.text;
to->len = tbuf.len;
return true;
@@ -1526,7 +1526,7 @@ _cpp_interpret_identifier (cpp_reader *pfile, const uchar *id, size_t len)
{
/* It turns out that a UCN escape always turns into fewer characters
than the escape itself, so we can allocate a temporary in advance. */
- uchar * buf = alloca (len + 1);
+ uchar * buf = (uchar *) alloca (len + 1);
uchar * bufp = buf;
size_t idp;
@@ -1598,7 +1598,7 @@ _cpp_convert_input (cpp_reader *pfile, const char *input_charset,
else
{
to.asize = MAX (65536, len);
- to.text = xmalloc (to.asize);
+ to.text = XNEWVEC (uchar, to.asize);
to.len = 0;
if (!APPLY_CONVERSION (input_cset, input, len, &to))
@@ -1616,7 +1616,7 @@ _cpp_convert_input (cpp_reader *pfile, const char *input_charset,
/* Resize buffer if we allocated substantially too much, or if we
haven't enough space for the \n-terminator. */
if (to.len + 4096 < to.asize || to.len >= to.asize)
- to.text = xrealloc (to.text, to.len + 1);
+ to.text = XRESIZEVEC (uchar, to.text, to.len + 1);
/* If the file is using old-school Mac line endings (\r only),
terminate with another \r, not an \n, so that we do not mistake
diff --git a/libcpp/config.in b/libcpp/config.in
index a302492406b..2b05ba0c401 100644
--- a/libcpp/config.in
+++ b/libcpp/config.in
@@ -29,6 +29,10 @@
*/
#undef HAVE_DECL_ABORT
+/* Define to 1 if you have the declaration of `asprintf', and to 0 if you
+ don't. */
+#undef HAVE_DECL_ASPRINTF
+
/* Define to 1 if you have the declaration of `basename', and to 0 if you
don't. */
#undef HAVE_DECL_BASENAME
@@ -105,6 +109,10 @@
don't. */
#undef HAVE_DECL_PUTC_UNLOCKED
+/* Define to 1 if you have the declaration of `vasprintf', and to 0 if you
+ don't. */
+#undef HAVE_DECL_VASPRINTF
+
/* Define to 1 if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
diff --git a/libcpp/configure b/libcpp/configure
index 63647450dfc..d0c04d959a1 100755
--- a/libcpp/configure
+++ b/libcpp/configure
@@ -5077,6 +5077,76 @@ _ACEOF
fi
+echo "$as_me:$LINENO: checking whether asprintf is declared" >&5
+echo $ECHO_N "checking whether asprintf is declared... $ECHO_C" >&6
+if test "${ac_cv_have_decl_asprintf+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+#ifndef asprintf
+ char *p = (char *) asprintf;
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_have_decl_asprintf=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_have_decl_asprintf=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_have_decl_asprintf" >&5
+echo "${ECHO_T}$ac_cv_have_decl_asprintf" >&6
+if test $ac_cv_have_decl_asprintf = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_ASPRINTF 1
+_ACEOF
+
+
+else
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_ASPRINTF 0
+_ACEOF
+
+
+fi
echo "$as_me:$LINENO: checking whether basename is declared" >&5
echo $ECHO_N "checking whether basename is declared... $ECHO_C" >&6
if test "${ac_cv_have_decl_basename+set}" = set; then
@@ -6407,6 +6477,76 @@ _ACEOF
fi
+echo "$as_me:$LINENO: checking whether vasprintf is declared" >&5
+echo $ECHO_N "checking whether vasprintf is declared... $ECHO_C" >&6
+if test "${ac_cv_have_decl_vasprintf+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+#ifndef vasprintf
+ char *p = (char *) vasprintf;
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_have_decl_vasprintf=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_have_decl_vasprintf=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_have_decl_vasprintf" >&5
+echo "${ECHO_T}$ac_cv_have_decl_vasprintf" >&6
+if test $ac_cv_have_decl_vasprintf = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_VASPRINTF 1
+_ACEOF
+
+
+else
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_VASPRINTF 0
+_ACEOF
+
+
+fi
diff --git a/libcpp/configure.ac b/libcpp/configure.ac
index b56a7443619..fe52964aae9 100644
--- a/libcpp/configure.ac
+++ b/libcpp/configure.ac
@@ -50,7 +50,8 @@ define(libcpp_UNLOCKED_FUNCS, clearerr_unlocked feof_unlocked dnl
fread_unlocked fwrite_unlocked getchar_unlocked getc_unlocked dnl
putchar_unlocked putc_unlocked)
AC_CHECK_FUNCS(libcpp_UNLOCKED_FUNCS)
-AC_CHECK_DECLS(m4_split(m4_normalize(abort basename errno getopt libcpp_UNLOCKED_FUNCS)))
+AC_CHECK_DECLS(m4_split(m4_normalize(abort asprintf basename errno getopt \
+ libcpp_UNLOCKED_FUNCS vasprintf)))
# Checks for library functions.
AC_FUNC_ALLOCA
diff --git a/libcpp/directives.c b/libcpp/directives.c
index 672415b8d61..a768ea14408 100644
--- a/libcpp/directives.c
+++ b/libcpp/directives.c
@@ -588,7 +588,7 @@ glue_header_name (cpp_reader *pfile)
/* To avoid lexed tokens overwriting our glued name, we can only
allocate from the string pool once we've lexed everything. */
- buffer = xmalloc (capacity);
+ buffer = XNEWVEC (char, capacity);
for (;;)
{
token = get_token_no_padding (pfile);
@@ -605,7 +605,7 @@ glue_header_name (cpp_reader *pfile)
if (total_len + len > capacity)
{
capacity = (capacity + len) * 2;
- buffer = xrealloc (buffer, capacity);
+ buffer = XRESIZEVEC (char, buffer, capacity);
}
if (token->flags & PREV_WHITE)
@@ -633,7 +633,7 @@ parse_include (cpp_reader *pfile, int *pangle_brackets)
header = get_token_no_padding (pfile);
if (header->type == CPP_STRING || header->type == CPP_HEADER_NAME)
{
- fname = xmalloc (header->val.str.len - 1);
+ fname = XNEWVEC (char, header->val.str.len - 1);
memcpy (fname, header->val.str.text + 1, header->val.str.len - 2);
fname[header->val.str.len - 2] = '\0';
*pangle_brackets = header->type == CPP_HEADER_NAME;
@@ -985,27 +985,27 @@ insert_pragma_entry (cpp_reader *pfile, struct pragma_entry **chain,
const cpp_hashnode *pragma, pragma_cb handler,
bool allow_expansion, bool internal)
{
- struct pragma_entry *new;
+ struct pragma_entry *new_entry;
- new = (struct pragma_entry *)
+ new_entry = (struct pragma_entry *)
_cpp_aligned_alloc (pfile, sizeof (struct pragma_entry));
- new->pragma = pragma;
+ new_entry->pragma = pragma;
if (handler)
{
- new->is_nspace = 0;
- new->u.handler = handler;
+ new_entry->is_nspace = 0;
+ new_entry->u.handler = handler;
}
else
{
- new->is_nspace = 1;
- new->u.space = NULL;
+ new_entry->is_nspace = 1;
+ new_entry->u.space = NULL;
}
- new->allow_expansion = allow_expansion;
- new->is_internal = internal;
- new->next = *chain;
- *chain = new;
- return new;
+ new_entry->allow_expansion = allow_expansion;
+ new_entry->is_internal = internal;
+ new_entry->next = *chain;
+ *chain = new_entry;
+ return new_entry;
}
/* Register a pragma NAME in namespace SPACE. If SPACE is null, it
@@ -1110,9 +1110,9 @@ save_registered_pragmas (struct pragma_entry *pe, char **sd)
{
if (pe->is_nspace)
sd = save_registered_pragmas (pe->u.space, sd);
- *sd++ = xmemdup (HT_STR (&pe->pragma->ident),
- HT_LEN (&pe->pragma->ident),
- HT_LEN (&pe->pragma->ident) + 1);
+ *sd++ = (char *) xmemdup (HT_STR (&pe->pragma->ident),
+ HT_LEN (&pe->pragma->ident),
+ HT_LEN (&pe->pragma->ident) + 1);
}
return sd;
}
@@ -1383,7 +1383,7 @@ destringize_and_run (cpp_reader *pfile, const cpp_string *in)
const unsigned char *src, *limit;
char *dest, *result;
- dest = result = alloca (in->len - 1);
+ dest = result = (char *) alloca (in->len - 1);
src = in->text + 1 + (in->text[0] == 'L');
limit = in->text + in->len - 1;
while (src < limit)
@@ -1760,7 +1760,7 @@ parse_assertion (cpp_reader *pfile, struct answer **answerp, int type)
else if (parse_answer (pfile, answerp, type) == 0)
{
unsigned int len = NODE_LEN (predicate->val.node);
- unsigned char *sym = alloca (len + 1);
+ unsigned char *sym = (unsigned char *) alloca (len + 1);
/* Prefix '#' to get it out of macro namespace. */
sym[0] = '#';
@@ -1855,7 +1855,8 @@ do_assert (cpp_reader *pfile)
if (pfile->hash_table->alloc_subobject)
{
struct answer *temp_answer = new_answer;
- new_answer = pfile->hash_table->alloc_subobject (answer_size);
+ new_answer = (struct answer *) pfile->hash_table->alloc_subobject
+ (answer_size);
memcpy (new_answer, temp_answer, answer_size);
}
else
@@ -1917,7 +1918,7 @@ cpp_define (cpp_reader *pfile, const char *str)
tack " 1" on the end. */
count = strlen (str);
- buf = alloca (count + 3);
+ buf = (char *) alloca (count + 3);
memcpy (buf, str, count);
p = strchr (str, '=');
@@ -1938,7 +1939,7 @@ void
_cpp_define_builtin (cpp_reader *pfile, const char *str)
{
size_t len = strlen (str);
- char *buf = alloca (len + 1);
+ char *buf = (char *) alloca (len + 1);
memcpy (buf, str, len);
buf[len] = '\n';
run_directive (pfile, T_DEFINE, buf, len);
@@ -1949,7 +1950,7 @@ void
cpp_undef (cpp_reader *pfile, const char *macro)
{
size_t len = strlen (macro);
- char *buf = alloca (len + 1);
+ char *buf = (char *) alloca (len + 1);
memcpy (buf, macro, len);
buf[len] = '\n';
run_directive (pfile, T_UNDEF, buf, len);
@@ -1978,7 +1979,7 @@ handle_assertion (cpp_reader *pfile, const char *str, int type)
/* Copy the entire option so we can modify it. Change the first
"=" in the string to a '(', and tack a ')' on the end. */
- char *buf = alloca (count + 2);
+ char *buf = (char *) alloca (count + 2);
memcpy (buf, str, count);
if (p)
@@ -2036,20 +2037,20 @@ cpp_buffer *
cpp_push_buffer (cpp_reader *pfile, const uchar *buffer, size_t len,
int from_stage3)
{
- cpp_buffer *new = XOBNEW (&pfile->buffer_ob, cpp_buffer);
+ cpp_buffer *new_buffer = XOBNEW (&pfile->buffer_ob, cpp_buffer);
/* Clears, amongst other things, if_stack and mi_cmacro. */
- memset (new, 0, sizeof (cpp_buffer));
+ memset (new_buffer, 0, sizeof (cpp_buffer));
- new->next_line = new->buf = buffer;
- new->rlimit = buffer + len;
- new->from_stage3 = from_stage3;
- new->prev = pfile->buffer;
- new->need_line = true;
+ new_buffer->next_line = new_buffer->buf = buffer;
+ new_buffer->rlimit = buffer + len;
+ new_buffer->from_stage3 = from_stage3;
+ new_buffer->prev = pfile->buffer;
+ new_buffer->need_line = true;
- pfile->buffer = new;
+ pfile->buffer = new_buffer;
- return new;
+ return new_buffer;
}
/* Pops a single buffer, with a file change call-back if appropriate.
diff --git a/libcpp/expr.c b/libcpp/expr.c
index 47689189b2b..73356a966a0 100644
--- a/libcpp/expr.c
+++ b/libcpp/expr.c
@@ -65,8 +65,8 @@ static unsigned int interpret_int_suffix (const uchar *, size_t);
static void check_promotion (cpp_reader *, const struct op *);
/* Token type abuse to create unary plus and minus operators. */
-#define CPP_UPLUS (CPP_LAST_CPP_OP + 1)
-#define CPP_UMINUS (CPP_LAST_CPP_OP + 2)
+#define CPP_UPLUS ((enum cpp_ttype) (CPP_LAST_CPP_OP + 1))
+#define CPP_UMINUS ((enum cpp_ttype) (CPP_LAST_CPP_OP + 2))
/* With -O2, gcc appears to produce nice code, moving the error
message load and subsequent jump completely out of the main path. */
@@ -627,7 +627,7 @@ extra semantics need to be handled with operator-specific code. */
/* Operator to priority map. Must be in the same order as the first
N entries of enum cpp_ttype. */
-static const struct operator
+static const struct cpp_operator
{
uchar prio;
uchar flags;
@@ -975,7 +975,7 @@ _cpp_expand_op_stack (cpp_reader *pfile)
size_t old_size = (size_t) (pfile->op_limit - pfile->op_stack);
size_t new_size = old_size * 2 + 20;
- pfile->op_stack = xrealloc (pfile->op_stack, new_size * sizeof (struct op));
+ pfile->op_stack = XRESIZEVEC (struct op, pfile->op_stack, new_size);
pfile->op_limit = pfile->op_stack + new_size;
return pfile->op_stack + old_size;
diff --git a/libcpp/files.c b/libcpp/files.c
index c0ce6d45227..6cab34f8b83 100644
--- a/libcpp/files.c
+++ b/libcpp/files.c
@@ -255,7 +255,7 @@ pch_open_file (cpp_reader *pfile, _cpp_file *file, bool *invalid_pch)
flen = strlen (path);
len = flen + sizeof (extension);
- pchname = xmalloc (len);
+ pchname = XNEWVEC (char, len);
memcpy (pchname, path, flen);
memcpy (pchname + flen, extension, sizeof (extension));
@@ -279,7 +279,7 @@ pch_open_file (cpp_reader *pfile, _cpp_file *file, bool *invalid_pch)
if (dlen + plen > len)
{
len += dlen + 64;
- pchname = xrealloc (pchname, len);
+ pchname = XRESIZEVEC (char, pchname, len);
}
memcpy (pchname + plen, d->d_name, dlen);
valid = validate_pch (pfile, file, pchname);
@@ -549,7 +549,7 @@ read_file_guts (cpp_reader *pfile, _cpp_file *file)
the majority of C source files. */
size = 8 * 1024;
- buf = xmalloc (size + 1);
+ buf = XNEWVEC (uchar, size + 1);
total = 0;
while ((count = read (file->fd, buf + total, size - total)) > 0)
{
@@ -560,7 +560,7 @@ read_file_guts (cpp_reader *pfile, _cpp_file *file)
if (regular)
break;
size *= 2;
- buf = xrealloc (buf, size + 1);
+ buf = XRESIZEVEC (uchar, buf, size + 1);
}
}
@@ -815,7 +815,7 @@ dir_name_of_file (_cpp_file *file)
if (!file->dir_name)
{
size_t len = lbasename (file->path) - file->path;
- char *dir_name = xmalloc (len + 1);
+ char *dir_name = XNEWVEC (char, len + 1);
memcpy (dir_name, file->path, len);
dir_name[len] = '\0';
@@ -896,7 +896,7 @@ make_cpp_file (cpp_reader *pfile, cpp_dir *dir, const char *fname)
{
_cpp_file *file;
- file = xcalloc (1, sizeof (_cpp_file));
+ file = XCNEW (_cpp_file);
file->main_file = !pfile->buffer;
file->fd = -1;
file->dir = dir;
@@ -938,7 +938,7 @@ make_cpp_dir (cpp_reader *pfile, const char *dir_name, int sysp)
if (entry->start_dir == NULL)
return entry->u.dir;
- dir = xcalloc (1, sizeof (cpp_dir));
+ dir = XCNEW (cpp_dir);
dir->next = pfile->quote_include;
dir->name = (char *) dir_name;
dir->len = strlen (dir_name);
@@ -961,8 +961,8 @@ allocate_file_hash_entries (cpp_reader *pfile)
{
pfile->file_hash_entries_used = 0;
pfile->file_hash_entries_allocated = 127;
- pfile->file_hash_entries = xmalloc
- (pfile->file_hash_entries_allocated * sizeof (struct file_hash_entry));
+ pfile->file_hash_entries = XNEWVEC (struct file_hash_entry,
+ pfile->file_hash_entries_allocated);
}
/* Return a new file hash entry. */
@@ -983,8 +983,8 @@ cpp_included (cpp_reader *pfile, const char *fname)
{
struct file_hash_entry *entry;
- entry = htab_find_with_hash (pfile->file_hash, fname,
- htab_hash_string (fname));
+ entry = (struct file_hash_entry *)
+ htab_find_with_hash (pfile->file_hash, fname, htab_hash_string (fname));
while (entry && (entry->start_dir == NULL || entry->u.file->err_no))
entry = entry->next;
@@ -1204,7 +1204,7 @@ append_file_to_dir (const char *fname, cpp_dir *dir)
dlen = dir->len;
flen = strlen (fname);
- path = xmalloc (dlen + 1 + flen + 1);
+ path = XNEWVEC (char, dlen + 1 + flen + 1);
memcpy (path, dir->name, dlen);
if (dlen && path[dlen - 1] != '/')
path[dlen++] = '/';
@@ -1222,7 +1222,7 @@ read_filename_string (int ch, FILE *f)
int len;
len = 20;
- set = alloc = xmalloc (len + 1);
+ set = alloc = XNEWVEC (char, len + 1);
if (! is_space (ch))
{
*set++ = ch;
@@ -1231,7 +1231,7 @@ read_filename_string (int ch, FILE *f)
if (set - alloc == len)
{
len *= 2;
- alloc = xrealloc (alloc, len + 1);
+ alloc = XRESIZEVEC (char, alloc, len + 1);
set = alloc + len / 2;
}
*set++ = ch;
@@ -1252,14 +1252,14 @@ read_name_map (cpp_dir *dir)
size_t len, count = 0, room = 9;
len = dir->len;
- name = alloca (len + sizeof (FILE_NAME_MAP_FILE) + 1);
+ name = (char *) alloca (len + sizeof (FILE_NAME_MAP_FILE) + 1);
memcpy (name, dir->name, len);
if (len && name[len - 1] != '/')
name[len++] = '/';
strcpy (name + len, FILE_NAME_MAP_FILE);
f = fopen (name, "r");
- dir->name_map = xmalloc (room * sizeof (char *));
+ dir->name_map = XNEWVEC (const char *, room);
/* Silently return NULL if we cannot open. */
if (f)
@@ -1276,7 +1276,7 @@ read_name_map (cpp_dir *dir)
if (count + 2 > room)
{
room += 8;
- dir->name_map = xrealloc (dir->name_map, room * sizeof (char *));
+ dir->name_map = XRESIZEVEC (const char *, dir->name_map, room);
}
dir->name_map[count] = read_filename_string (ch, f);
@@ -1333,7 +1333,7 @@ remap_filename (cpp_reader *pfile, _cpp_file *file)
return NULL;
len = dir->len + (p - fname + 1);
- new_dir = xmalloc (len + 1);
+ new_dir = XNEWVEC (char, len + 1);
memcpy (new_dir, dir->name, dir->len);
memcpy (new_dir + dir->len, fname, p - fname + 1);
new_dir[len] = '\0';
@@ -1426,6 +1426,16 @@ cpp_get_prev (cpp_buffer *b)
that's OK. The code does rely on having entries with the same size
next to each other. */
+struct pchf_entry {
+ /* The size of this file. This is used to save running a MD5 checksum
+ if the sizes don't match. */
+ off_t size;
+ /* The MD5 checksum of this file. */
+ unsigned char sum[16];
+ /* Is this file to be included only once? */
+ bool once_only;
+};
+
struct pchf_data {
/* Number of pchf_entry structures. */
size_t count;
@@ -1435,15 +1445,7 @@ struct pchf_data {
the structure if we're processing a regular #include. */
bool have_once_only;
- struct pchf_entry {
- /* The size of this file. This is used to save running a MD5 checksum
- if the sizes don't match. */
- off_t size;
- /* The MD5 checksum of this file. */
- unsigned char sum[16];
- /* Is this file to be included only once? */
- bool once_only;
- } entries[1];
+ struct pchf_entry entries[1];
};
static struct pchf_data *pchf;
@@ -1471,7 +1473,7 @@ _cpp_save_file_entries (cpp_reader *pfile, FILE *fp)
result_size = (sizeof (struct pchf_data)
+ sizeof (struct pchf_entry) * (count - 1));
- result = xcalloc (result_size, 1);
+ result = XCNEWVAR (struct pchf_data, result_size);
result->count = 0;
result->have_once_only = false;
@@ -1534,7 +1536,7 @@ _cpp_read_file_entries (cpp_reader *pfile ATTRIBUTE_UNUSED, FILE *f)
!= 1)
return false;
- pchf = xmalloc (sizeof (struct pchf_data)
+ pchf = XNEWVAR (struct pchf_data, sizeof (struct pchf_data)
+ sizeof (struct pchf_entry) * (d.count - 1));
memcpy (pchf, &d, sizeof (struct pchf_data) - sizeof (struct pchf_entry));
if (fread (pchf->entries, sizeof (struct pchf_entry), d.count, f)
diff --git a/libcpp/identifiers.c b/libcpp/identifiers.c
index a6b35b4e57c..8ab3ce9c977 100644
--- a/libcpp/identifiers.c
+++ b/libcpp/identifiers.c
@@ -37,7 +37,7 @@ alloc_node (hash_table *table)
{
cpp_hashnode *node;
- node = obstack_alloc (&table->pfile->hash_ob, sizeof (cpp_hashnode));
+ node = XOBNEW (&table->pfile->hash_ob, cpp_hashnode);
memset (node, 0, sizeof (cpp_hashnode));
return node;
}
diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h
index 321de40727e..3ec4c466436 100644
--- a/libcpp/include/cpplib.h
+++ b/libcpp/include/cpplib.h
@@ -569,6 +569,19 @@ enum {
/* The common part of an identifier node shared amongst all 3 C front
ends. Also used to store CPP identifiers, which are a superset of
identifiers in the grammatical sense. */
+
+union _cpp_hashnode_value GTY(())
+{
+ /* If a macro. */
+ cpp_macro * GTY((tag ("NTV_MACRO"))) macro;
+ /* Answers to an assertion. */
+ struct answer * GTY ((tag ("NTV_ANSWER"))) answers;
+ /* Code for a builtin macro. */
+ enum builtin_type GTY ((tag ("NTV_BUILTIN"))) builtin;
+ /* Macro argument index. */
+ unsigned short GTY ((tag ("NTV_ARGUMENT"))) arg_index;
+};
+
struct cpp_hashnode GTY(())
{
struct ht_identifier ident;
@@ -580,17 +593,7 @@ struct cpp_hashnode GTY(())
ENUM_BITFIELD(node_type) type : 8; /* CPP node type. */
unsigned char flags; /* CPP flags. */
- union _cpp_hashnode_value
- {
- /* If a macro. */
- cpp_macro * GTY((tag ("NTV_MACRO"))) macro;
- /* Answers to an assertion. */
- struct answer * GTY ((tag ("NTV_ANSWER"))) answers;
- /* Code for a builtin macro. */
- enum builtin_type GTY ((tag ("NTV_BUILTIN"))) builtin;
- /* Macro argument index. */
- unsigned short GTY ((tag ("NTV_ARGUMENT"))) arg_index;
- } GTY ((desc ("CPP_HASHNODE_VALUE_IDX (%1)"))) value;
+ union _cpp_hashnode_value GTY ((desc ("CPP_HASHNODE_VALUE_IDX (%1)"))) value;
};
/* Call this first to get a handle to pass to other functions.
diff --git a/libcpp/init.c b/libcpp/init.c
index 7ad5a73856a..56acd7ac24c 100644
--- a/libcpp/init.c
+++ b/libcpp/init.c
@@ -137,7 +137,7 @@ cpp_create_reader (enum c_lang lang, hash_table *table,
/* Initialize this instance of the library if it hasn't been already. */
init_library ();
- pfile = xcalloc (1, sizeof (cpp_reader));
+ pfile = XCNEW (cpp_reader);
cpp_set_lang (pfile, lang);
CPP_OPTION (pfile, warn_multichar) = 1;
@@ -357,7 +357,7 @@ cpp_init_builtins (cpp_reader *pfile, int hosted)
cpp_hashnode *hp = cpp_lookup (pfile, b->name, b->len);
hp->type = NT_MACRO;
hp->flags |= NODE_BUILTIN | NODE_WARN;
- hp->value.builtin = b->value;
+ hp->value.builtin = (enum builtin_type) b->value;
}
if (CPP_OPTION (pfile, cplusplus))
@@ -545,7 +545,7 @@ read_original_directory (cpp_reader *pfile)
if (pfile->cb.dir_change)
{
- char *debugdir = alloca (token->val.str.len - 3);
+ char *debugdir = (char *) alloca (token->val.str.len - 3);
memcpy (debugdir, (const char *) token->val.str.text + 1,
token->val.str.len - 4);
diff --git a/libcpp/lex.c b/libcpp/lex.c
index 58e559fd9fd..b38047e0879 100644
--- a/libcpp/lex.c
+++ b/libcpp/lex.c
@@ -85,8 +85,8 @@ add_line_note (cpp_buffer *buffer, const uchar *pos, unsigned int type)
if (buffer->notes_used == buffer->notes_cap)
{
buffer->notes_cap = buffer->notes_cap * 2 + 200;
- buffer->notes = xrealloc (buffer->notes,
- buffer->notes_cap * sizeof (_cpp_line_note));
+ buffer->notes = XRESIZEVEC (_cpp_line_note, buffer->notes,
+ buffer->notes_cap);
}
buffer->notes[buffer->notes_used].pos = pos;
@@ -439,7 +439,7 @@ warn_about_normalization (cpp_reader *pfile,
{
/* Make sure that the token is printed using UCNs, even
if we'd otherwise happily print UTF-8. */
- unsigned char *buf = xmalloc (cpp_token_len (token));
+ unsigned char *buf = XNEWVEC (unsigned char, cpp_token_len (token));
size_t sz;
sz = cpp_spell_token (pfile, token, buf, false) - buf;
@@ -970,7 +970,7 @@ _cpp_lex_direct (cpp_reader *pfile)
if (result->val.node->flags & NODE_OPERATOR)
{
result->flags |= NAMED_OP;
- result->type = result->val.node->directive_index;
+ result->type = (enum cpp_ttype) result->val.node->directive_index;
}
break;
@@ -1541,7 +1541,7 @@ new_buff (size_t len)
len = MIN_BUFF_SIZE;
len = CPP_ALIGN (len);
- base = xmalloc (len + sizeof (_cpp_buff));
+ base = XNEWVEC (unsigned char, len + sizeof (_cpp_buff));
result = (_cpp_buff *) (base + len);
result->base = base;
result->cur = base;
diff --git a/libcpp/line-map.c b/libcpp/line-map.c
index 1ace4c9585d..59a80ac92f8 100644
--- a/libcpp/line-map.c
+++ b/libcpp/line-map.c
@@ -97,7 +97,7 @@ linemap_add (struct line_maps *set, enum lc_reason reason,
if (set->used == set->allocated)
{
set->allocated = 2 * set->allocated + 256;
- set->maps = xrealloc (set->maps, set->allocated * sizeof (struct line_map));
+ set->maps = XRESIZEVEC (struct line_map, set->maps, set->allocated);
}
map = &set->maps[set->used];
diff --git a/libcpp/macro.c b/libcpp/macro.c
index daa2bd34a0e..05a87702aa6 100644
--- a/libcpp/macro.c
+++ b/libcpp/macro.c
@@ -273,7 +273,7 @@ builtin_macro (cpp_reader *pfile, cpp_hashnode *node)
buf = _cpp_builtin_macro_text (pfile, node);
len = ustrlen (buf);
- nbuf = alloca (len + 1);
+ nbuf = (char *) alloca (len + 1);
memcpy (nbuf, buf, len);
nbuf[len]='\n';
@@ -421,7 +421,7 @@ paste_tokens (cpp_reader *pfile, const cpp_token **plhs, const cpp_token *rhs)
lhs = *plhs;
len = cpp_token_len (lhs) + cpp_token_len (rhs) + 1;
- buf = alloca (len);
+ buf = (unsigned char *) alloca (len);
end = cpp_spell_token (pfile, lhs, buf, false);
/* Avoid comment headers, since they are still processed in stage 3.
@@ -1001,7 +1001,7 @@ expand_arg (cpp_reader *pfile, macro_arg *arg)
/* Loop, reading in the arguments. */
capacity = 256;
- arg->expanded = xmalloc (capacity * sizeof (cpp_token *));
+ arg->expanded = XNEWVEC (const cpp_token *, capacity);
push_ptoken_context (pfile, NULL, NULL, arg->first, arg->count + 1);
for (;;)
@@ -1011,8 +1011,8 @@ expand_arg (cpp_reader *pfile, macro_arg *arg)
if (arg->expanded_count + 1 >= capacity)
{
capacity *= 2;
- arg->expanded = xrealloc (arg->expanded,
- capacity * sizeof (cpp_token *));
+ arg->expanded = XRESIZEVEC (const cpp_token *, arg->expanded,
+ capacity);
}
token = cpp_get_token (pfile);
@@ -1272,7 +1272,8 @@ _cpp_save_parameter (cpp_reader *pfile, cpp_macro *macro, cpp_hashnode *node)
len = macro->paramc * sizeof (union _cpp_hashnode_value);
if (len > pfile->macro_buffer_len)
{
- pfile->macro_buffer = xrealloc (pfile->macro_buffer, len);
+ pfile->macro_buffer = XRESIZEVEC (unsigned char, pfile->macro_buffer,
+ len);
pfile->macro_buffer_len = len;
}
((union _cpp_hashnode_value *) pfile->macro_buffer)[macro->paramc - 1]
@@ -1419,8 +1420,9 @@ create_iso_definition (cpp_reader *pfile, cpp_macro *macro)
/* Success. Commit or allocate the parameter array. */
if (pfile->hash_table->alloc_subobject)
{
- cpp_hashnode **params = pfile->hash_table->alloc_subobject
- (sizeof (cpp_hashnode *) * macro->paramc);
+ cpp_hashnode **params =
+ (cpp_hashnode **) pfile->hash_table->alloc_subobject
+ (sizeof (cpp_hashnode *) * macro->paramc);
memcpy (params, macro->params,
sizeof (cpp_hashnode *) * macro->paramc);
macro->params = params;
@@ -1532,8 +1534,9 @@ create_iso_definition (cpp_reader *pfile, cpp_macro *macro)
/* Commit or allocate the memory. */
if (pfile->hash_table->alloc_subobject)
{
- cpp_token *tokns = pfile->hash_table->alloc_subobject (sizeof (cpp_token)
- * macro->count);
+ cpp_token *tokns =
+ (cpp_token *) pfile->hash_table->alloc_subobject (sizeof (cpp_token)
+ * macro->count);
memcpy (tokns, macro->exp.tokens, sizeof (cpp_token) * macro->count);
macro->exp.tokens = tokns;
}
@@ -1552,7 +1555,8 @@ _cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node)
bool ok;
if (pfile->hash_table->alloc_subobject)
- macro = pfile->hash_table->alloc_subobject (sizeof (cpp_macro));
+ macro = (cpp_macro *) pfile->hash_table->alloc_subobject
+ (sizeof (cpp_macro));
else
macro = (cpp_macro *) _cpp_aligned_alloc (pfile, sizeof (cpp_macro));
macro->line = pfile->directive_line;
@@ -1722,7 +1726,8 @@ cpp_macro_definition (cpp_reader *pfile, const cpp_hashnode *node)
if (len > pfile->macro_buffer_len)
{
- pfile->macro_buffer = xrealloc (pfile->macro_buffer, len);
+ pfile->macro_buffer = XRESIZEVEC (unsigned char,
+ pfile->macro_buffer, len);
pfile->macro_buffer_len = len;
}
diff --git a/libcpp/makedepend.c b/libcpp/makedepend.c
index f28f9699828..7581c975515 100644
--- a/libcpp/makedepend.c
+++ b/libcpp/makedepend.c
@@ -47,7 +47,7 @@ static cpp_dir *cmd_line_searchpath;
static void
add_clm (const char *macro, bool is_undef)
{
- struct cmd_line_macro *clm = xmalloc (sizeof (struct cmd_line_macro));
+ struct cmd_line_macro *clm = XNEW (struct cmd_line_macro);
clm->next = cmd_line_macros;
clm->is_undef = is_undef;
clm->macro = macro;
@@ -57,7 +57,7 @@ add_clm (const char *macro, bool is_undef)
static void
add_dir (char *name, bool sysp)
{
- cpp_dir *dir = xmalloc (sizeof (cpp_dir));
+ cpp_dir *dir = XNEW (cpp_dir);
dir->next = cmd_line_searchpath;
dir->name = name;
dir->sysp = sysp;
diff --git a/libcpp/mkdeps.c b/libcpp/mkdeps.c
index 5ab88138001..9042316a1ea 100644
--- a/libcpp/mkdeps.c
+++ b/libcpp/mkdeps.c
@@ -83,7 +83,7 @@ munge (const char *filename)
}
/* Now we know how big to make the buffer. */
- buffer = xmalloc (len + 1);
+ buffer = XNEWVEC (char, len + 1);
for (p = filename, dst = buffer; *p; p++, dst++)
{
@@ -151,7 +151,7 @@ apply_vpath (struct deps *d, const char *t)
struct deps *
deps_init (void)
{
- return xcalloc (sizeof (struct deps), 1);
+ return XCNEW (struct deps);
}
void
@@ -192,8 +192,7 @@ deps_add_target (struct deps *d, const char *t, int quote)
if (d->ntargets == d->targets_size)
{
d->targets_size = d->targets_size * 2 + 4;
- d->targetv = xrealloc (d->targetv,
- d->targets_size * sizeof (const char *));
+ d->targetv = XRESIZEVEC (const char *, d->targetv, d->targets_size);
}
t = apply_vpath (d, t);
@@ -223,7 +222,8 @@ deps_add_default_target (struct deps *d, const char *tgt)
# define TARGET_OBJECT_SUFFIX ".o"
#endif
const char *start = lbasename (tgt);
- char *o = alloca (strlen (start) + strlen (TARGET_OBJECT_SUFFIX) + 1);
+ char *o = (char *) alloca (strlen (start)
+ + strlen (TARGET_OBJECT_SUFFIX) + 1);
char *suffix;
strcpy (o, start);
@@ -245,7 +245,7 @@ deps_add_dep (struct deps *d, const char *t)
if (d->ndeps == d->deps_size)
{
d->deps_size = d->deps_size * 2 + 8;
- d->depv = xrealloc (d->depv, d->deps_size * sizeof (const char *));
+ d->depv = XRESIZEVEC (const char *, d->depv, d->deps_size);
}
d->depv[d->ndeps++] = t;
}
@@ -261,7 +261,7 @@ deps_add_vpath (struct deps *d, const char *vpath)
{
for (p = elem; *p && *p != ':'; p++);
len = p - elem;
- copy = xmalloc (len + 1);
+ copy = XNEWVEC (char, len + 1);
memcpy (copy, elem, len);
copy[len] = '\0';
if (*p == ':')
@@ -270,9 +270,8 @@ deps_add_vpath (struct deps *d, const char *vpath)
if (d->nvpaths == d->vpaths_size)
{
d->vpaths_size = d->vpaths_size * 2 + 8;
- d->vpathv = xrealloc (d->vpathv,
- d->vpaths_size * sizeof (const char *));
- d->vpathlv = xrealloc (d->vpathlv, d->vpaths_size * sizeof (size_t));
+ d->vpathv = XRESIZEVEC (const char *, d->vpathv, d->vpaths_size);
+ d->vpathlv = XRESIZEVEC (size_t, d->vpathlv, d->vpaths_size);
}
d->vpathv[d->nvpaths] = copy;
d->vpathlv[d->nvpaths] = len;
@@ -382,7 +381,7 @@ deps_restore (struct deps *deps, FILE *fd, const char *self)
unsigned int i, count;
size_t num_to_read;
size_t buf_size = 512;
- char *buf = xmalloc (buf_size);
+ char *buf = XNEWVEC (char, buf_size);
/* Number of dependences. */
if (fread (&count, 1, sizeof (count), fd) != sizeof (count))
@@ -397,7 +396,7 @@ deps_restore (struct deps *deps, FILE *fd, const char *self)
if (buf_size < num_to_read + 1)
{
buf_size = num_to_read + 1 + 127;
- buf = xrealloc (buf, buf_size);
+ buf = XRESIZEVEC (char, buf, buf_size);
}
if (fread (buf, 1, num_to_read, fd) != num_to_read)
return -1;
diff --git a/libcpp/pch.c b/libcpp/pch.c
index 79900c30c36..28cafbc9199 100644
--- a/libcpp/pch.c
+++ b/libcpp/pch.c
@@ -137,11 +137,11 @@ save_idents (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn, void *ss_p)
struct cpp_string *sp;
unsigned char *text;
- sp = xmalloc (sizeof (struct cpp_string));
+ sp = XNEW (struct cpp_string);
*slot = sp;
sp->len = NODE_LEN (hn);
- sp->text = text = xmalloc (NODE_LEN (hn));
+ sp->text = text = XNEWVEC (unsigned char, NODE_LEN (hn));
memcpy (text, NODE_NAME (hn), NODE_LEN (hn));
}
}
@@ -193,7 +193,7 @@ int
cpp_save_state (cpp_reader *r, FILE *f)
{
/* Save the list of non-void identifiers for the dependency checking. */
- r->savedstate = xmalloc (sizeof (struct cpp_savedstate));
+ r->savedstate = XNEW (struct cpp_savedstate);
r->savedstate->definedhash = htab_create (100, cpp_string_hash,
cpp_string_eq, NULL);
cpp_forall_identifiers (r, save_idents, r->savedstate);
@@ -226,7 +226,7 @@ count_defs (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn, void *ss_p)
news.len = NODE_LEN (hn);
news.text = NODE_NAME (hn);
- slot = htab_find (ss->definedhash, &news);
+ slot = (void **) htab_find (ss->definedhash, &news);
if (slot == NULL)
{
ss->hashsize += NODE_LEN (hn) + 1;
@@ -265,7 +265,7 @@ write_defs (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn, void *ss_p)
news.len = NODE_LEN (hn);
news.text = NODE_NAME (hn);
- slot = htab_find (ss->definedhash, &news);
+ slot = (void **) htab_find (ss->definedhash, &news);
if (slot == NULL)
{
ss->defs[ss->n_defs] = hn;
@@ -310,13 +310,13 @@ cpp_write_pch_deps (cpp_reader *r, FILE *f)
ss->n_defs = 0;
cpp_forall_identifiers (r, count_defs, ss);
- ss->defs = xmalloc (ss->n_defs * sizeof (cpp_hashnode *));
+ ss->defs = XNEWVEC (cpp_hashnode *, ss->n_defs);
ss->n_defs = 0;
cpp_forall_identifiers (r, write_defs, ss);
/* Sort the list, copy it into a buffer, and write it out. */
qsort (ss->defs, ss->n_defs, sizeof (cpp_hashnode *), &comp_hashnodes);
- definedstrs = ss->definedstrs = xmalloc (ss->hashsize);
+ definedstrs = ss->definedstrs = XNEWVEC (unsigned char, ss->hashsize);
for (i = 0; i < ss->n_defs; ++i)
{
size_t len = NODE_LEN (ss->defs[i]);
@@ -390,7 +390,7 @@ collect_ht_nodes (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn,
if (nl->n_defs == nl->asize)
{
nl->asize *= 2;
- nl->defs = xrealloc (nl->defs, nl->asize * sizeof (cpp_hashnode *));
+ nl->defs = XRESIZEVEC (cpp_hashnode *, nl->defs, nl->asize);
}
nl->defs[nl->n_defs] = hn;
@@ -418,7 +418,7 @@ cpp_valid_state (cpp_reader *r, const char *name, int fd)
{
struct macrodef_struct m;
size_t namebufsz = 256;
- unsigned char *namebuf = xmalloc (namebufsz);
+ unsigned char *namebuf = XNEWVEC (unsigned char, namebufsz);
unsigned char *undeftab = NULL;
struct ht_node_list nl = { 0, 0, 0 };
unsigned char *first, *last;
@@ -450,7 +450,7 @@ cpp_valid_state (cpp_reader *r, const char *name, int fd)
{
free (namebuf);
namebufsz = m.definition_length + 256;
- namebuf = xmalloc (namebufsz);
+ namebuf = XNEWVEC (unsigned char, namebufsz);
}
if ((size_t)read (fd, namebuf, m.definition_length)
@@ -488,14 +488,14 @@ cpp_valid_state (cpp_reader *r, const char *name, int fd)
/* Read in the list of identifiers that must not be defined.
Check that they really aren't. */
- undeftab = xmalloc (m.definition_length);
+ undeftab = XNEWVEC (unsigned char, m.definition_length);
if ((size_t) read (fd, undeftab, m.definition_length) != m.definition_length)
goto error;
/* Collect identifiers from the current hash table. */
nl.n_defs = 0;
nl.asize = 10;
- nl.defs = xmalloc (nl.asize * sizeof (cpp_hashnode *));
+ nl.defs = XNEWVEC (cpp_hashnode *, nl.asize);
cpp_forall_identifiers (r, &collect_ht_nodes, &nl);
qsort (nl.defs, nl.n_defs, sizeof (cpp_hashnode *), &comp_hashnodes);
@@ -577,8 +577,7 @@ save_macros (cpp_reader *r, cpp_hashnode *h, void *data_p)
if (data->count == data->array_size)
{
data->array_size *= 2;
- data->defns = xrealloc (data->defns, (data->array_size
- * sizeof (uchar *)));
+ data->defns = XRESIZEVEC (uchar *, data->defns, (data->array_size));
}
switch (h->type)
@@ -592,7 +591,8 @@ save_macros (cpp_reader *r, cpp_hashnode *h, void *data_p)
const uchar * defn = cpp_macro_definition (r, h);
size_t defnlen = ustrlen (defn);
- data->defns[data->count] = xmemdup (defn, defnlen, defnlen + 2);
+ data->defns[data->count] = (uchar *) xmemdup (defn, defnlen,
+ defnlen + 2);
data->defns[data->count][defnlen] = '\n';
}
break;
@@ -611,10 +611,10 @@ save_macros (cpp_reader *r, cpp_hashnode *h, void *data_p)
void
cpp_prepare_state (cpp_reader *r, struct save_macro_data **data)
{
- struct save_macro_data *d = xmalloc (sizeof (struct save_macro_data));
+ struct save_macro_data *d = XNEW (struct save_macro_data);
d->array_size = 512;
- d->defns = xmalloc (d->array_size * sizeof (d->defns[0]));
+ d->defns = XNEWVEC (uchar *, d->array_size);
d->count = 0;
cpp_forall_identifiers (r, save_macros, d);
d->saved_pragmas = _cpp_save_pragma_names (r);
diff --git a/libcpp/symtab.c b/libcpp/symtab.c
index 471765ca697..85450101b80 100644
--- a/libcpp/symtab.c
+++ b/libcpp/symtab.c
@@ -56,7 +56,7 @@ ht_create (unsigned int order)
unsigned int nslots = 1 << order;
hash_table *table;
- table = xcalloc (1, sizeof (hash_table));
+ table = XCNEW (hash_table);
/* Strings need no alignment. */
_obstack_begin (&table->stack, 0, 0,
@@ -65,7 +65,7 @@ ht_create (unsigned int order)
obstack_alignment_mask (&table->stack) = 0;
- table->entries = xcalloc (nslots, sizeof (hashnode));
+ table->entries = XCNEWVEC (hashnode, nslots);
table->entries_owned = true;
table->nslots = nslots;
return table;
@@ -161,7 +161,8 @@ ht_lookup_with_hash (hash_table *table, const unsigned char *str,
HT_LEN (node) = (unsigned int) len;
node->hash_value = hash;
if (insert == HT_ALLOC)
- HT_STR (node) = obstack_copy0 (&table->stack, str, len);
+ HT_STR (node) = (const unsigned char *) obstack_copy0 (&table->stack,
+ str, len);
else
HT_STR (node) = str;
@@ -181,7 +182,7 @@ ht_expand (hash_table *table)
unsigned int size, sizemask;
size = table->nslots * 2;
- nentries = xcalloc (size, sizeof (hashnode));
+ nentries = XCNEWVEC (hashnode, size);
sizemask = size - 1;
p = table->entries;
diff --git a/libcpp/system.h b/libcpp/system.h
index 98ac118e351..b27995b400b 100644
--- a/libcpp/system.h
+++ b/libcpp/system.h
@@ -342,10 +342,14 @@ extern void abort (void);
#include "libiberty.h"
#include "safe-ctype.h"
-/* 1 if we have C99 designated initializers. */
+/* 1 if we have C99 designated initializers.
+
+ ??? C99 designated initializers are not supported by most C++
+ compilers, including G++. -- gdr, 2005-05-18 */
#if !defined(HAVE_DESIGNATED_INITIALIZERS)
#define HAVE_DESIGNATED_INITIALIZERS \
- ((GCC_VERSION >= 2007) || (__STDC_VERSION__ >= 199901L))
+ ((!defined(__cplusplus) && (GCC_VERSION >= 2007)) \
+ || (__STDC_VERSION__ >= 199901L))
#endif
/* Be conservative and only use enum bitfields with GCC.
@@ -379,7 +383,9 @@ extern void abort (void);
#undef TRUE
#undef FALSE
+#ifndef __cplusplus
#define bool unsigned char
+#endif
#define true 1
#define false 0
diff --git a/libcpp/traditional.c b/libcpp/traditional.c
index 85be48716a5..a20facb063e 100644
--- a/libcpp/traditional.c
+++ b/libcpp/traditional.c
@@ -107,7 +107,7 @@ check_output_buffer (cpp_reader *pfile, size_t n)
size_t size = pfile->out.cur - pfile->out.base;
size_t new_size = (size + n) * 3 / 2;
- pfile->out.base = xrealloc (pfile->out.base, new_size);
+ pfile->out.base = XRESIZEVEC (unsigned char, pfile->out.base, new_size);
pfile->out.limit = pfile->out.base + new_size;
pfile->out.cur = pfile->out.base + size;
}
@@ -1069,7 +1069,7 @@ bool
_cpp_expansions_different_trad (const cpp_macro *macro1,
const cpp_macro *macro2)
{
- uchar *p1 = xmalloc (macro1->count + macro2->count);
+ uchar *p1 = XNEWVEC (uchar, macro1->count + macro2->count);
uchar *p2 = p1 + macro1->count;
uchar quote1 = 0, quote2 = 0;
bool mismatch;
diff --git a/libffi/ChangeLog b/libffi/ChangeLog
index d1f580e3c7b..fb1e67b39f5 100644
--- a/libffi/ChangeLog
+++ b/libffi/ChangeLog
@@ -1,3 +1,9 @@
+2005-06-01 Alan Modra <amodra@bigpond.net.au>
+
+ * src/powerpc/ppc_closure.S (ffi_closure_SYSV): Don't use JUMPTARGET
+ to call ffi_closure_helper_SYSV. Append @local instead.
+ * src/powerpc/sysv.S (ffi_call_SYSV): Likewise for ffi_prep_args_SYSV.
+
2005-05-17 Kelley Cook <kcook@gcc.gnu.org>
* configure.ac: Use AC_C_BIGENDIAN instead of AC_C_BIGENDIAN_CROSS.
diff --git a/libffi/src/powerpc/ppc_closure.S b/libffi/src/powerpc/ppc_closure.S
index ba13fa467e4..c71a7ff3b3b 100644
--- a/libffi/src/powerpc/ppc_closure.S
+++ b/libffi/src/powerpc/ppc_closure.S
@@ -57,7 +57,7 @@ ENTRY(ffi_closure_SYSV)
addi %r7,%r1,152
# make the call
- bl JUMPTARGET(ffi_closure_helper_SYSV)
+ bl ffi_closure_helper_SYSV@local
# now r3 contains the return type
# so use it to look up in a table
diff --git a/libffi/src/powerpc/sysv.S b/libffi/src/powerpc/sysv.S
index 1689d292d80..6d8b60155bb 100644
--- a/libffi/src/powerpc/sysv.S
+++ b/libffi/src/powerpc/sysv.S
@@ -60,7 +60,7 @@ ENTRY(ffi_call_SYSV)
/* Call ffi_prep_args_SYSV. */
mr %r4,%r1
- bl JUMPTARGET(ffi_prep_args_SYSV)
+ bl ffi_prep_args_SYSV@local
/* Now do the call. */
/* Set up cr1 with bits 4-7 of the flags. */
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog
index 94b9b84329b..b912b31adcf 100644
--- a/libgfortran/ChangeLog
+++ b/libgfortran/ChangeLog
@@ -1,3 +1,37 @@
+2005-05-30 Francois-Xavier Coudert <coudert@clipper.ens.fr>
+
+ PR libfortran/20179
+ * io/unix.c (fd_close): Add test so that we don't close()
+ stdout and stderr.
+
+2005-05-29 Francois-Xavier Coudert <coudert@clipper.ens.fr>
+
+ PR libfortran/20006
+ * io/format.c (parse_format_list): Set repeat count of $ format
+ node to 1.
+ * io/transfer.c (read_sf): Add g.seen_dollar to the test
+ concerning advancing I/O.
+ (data_transfer_init): Likewise.
+ (finalize_transfer): Likewise.
+
+2005-05-27 Thomas Koenig <Thomas.Koenig@online.de>
+
+ * runtime/in_pack_generic.c: Adjust copyright years.
+ (in_pack_generic): Change dimension of auxiliary arrays from
+ GFC_MAX_DIMENSION - 1 to GFC_MAX_DIMENSION.
+ * runtime/in_unpack_generic.c: Adjust copyright years.
+ (in_unpack_generic): Change dimension of auxiliary arrays from
+ GFC_MAX_DIMENSION - 1 to GFC_MAX_DIMENSION.
+
+2005-05-26 Thomas Koenig <Thomas.Koenig@online.de>
+
+ PR libfortran/17283
+ * intrinsics/unpack_generic.c: Fix name of routine
+ on top. Update copyright years.
+ (unpack1): Remove const from return array descriptor.
+ rs: New variable, for calculating return sizes.
+ Populate return array descriptor if ret->data is NULL.
+
2005-05-22 Peter Wainwright <prw@ceiriog1.demon.co.uk>
PR libfortran/21376
diff --git a/libgfortran/intrinsics/unpack_generic.c b/libgfortran/intrinsics/unpack_generic.c
index 57eb30c6480..a5c098b0e81 100644
--- a/libgfortran/intrinsics/unpack_generic.c
+++ b/libgfortran/intrinsics/unpack_generic.c
@@ -1,5 +1,5 @@
-/* Generic implementation of the RESHAPE intrinsic
- Copyright 2002 Free Software Foundation, Inc.
+/* Generic implementation of the UNPACK intrinsic
+ Copyright 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
Contributed by Paul Brook <paul@nowt.org>
This file is part of the GNU Fortran 95 runtime library (libgfortran).
@@ -34,17 +34,18 @@ Boston, MA 02111-1307, USA. */
#include <string.h>
#include "libgfortran.h"
-extern void unpack1 (const gfc_array_char *, const gfc_array_char *,
+extern void unpack1 (gfc_array_char *, const gfc_array_char *,
const gfc_array_l4 *, const gfc_array_char *);
iexport_proto(unpack1);
void
-unpack1 (const gfc_array_char *ret, const gfc_array_char *vector,
+unpack1 (gfc_array_char *ret, const gfc_array_char *vector,
const gfc_array_l4 *mask, const gfc_array_char *field)
{
/* r.* indicates the return array. */
index_type rstride[GFC_MAX_DIMENSIONS];
index_type rstride0;
+ index_type rs;
char *rptr;
/* v.* indicates the vector array. */
index_type vstride0;
@@ -68,17 +69,41 @@ unpack1 (const gfc_array_char *ret, const gfc_array_char *vector,
size = GFC_DESCRIPTOR_SIZE (ret);
/* A field element size of 0 actually means this is a scalar. */
fsize = GFC_DESCRIPTOR_SIZE (field);
- dim = GFC_DESCRIPTOR_RANK (ret);
- for (n = 0; n < dim; n++)
+ if (ret->data == NULL)
{
- count[n] = 0;
- extent[n] = ret->dim[n].ubound + 1 - ret->dim[n].lbound;
- rstride[n] = ret->dim[n].stride * size;
- fstride[n] = field->dim[n].stride * fsize;
- mstride[n] = mask->dim[n].stride;
+ /* The front end has signalled that we need to populate the
+ return array descriptor. */
+ dim = GFC_DESCRIPTOR_RANK (mask);
+ rs = 1;
+ for (n = 0; n < dim; n++)
+ {
+ count[n] = 0;
+ ret->dim[n].stride = rs;
+ ret->dim[n].lbound = 0;
+ ret->dim[n].ubound = mask->dim[n].ubound - mask->dim[n].lbound;
+ extent[n] = ret->dim[n].ubound + 1;
+ rstride[n] = ret->dim[n].stride * size;
+ fstride[n] = field->dim[n].stride * fsize;
+ mstride[n] = mask->dim[n].stride;
+ rs *= extent[n];
+ }
+ ret->base = 0;
+ ret->data = internal_malloc_size (rs * size);
+ }
+ else
+ {
+ dim = GFC_DESCRIPTOR_RANK (ret);
+ for (n = 0; n < dim; n++)
+ {
+ count[n] = 0;
+ extent[n] = ret->dim[n].ubound + 1 - ret->dim[n].lbound;
+ rstride[n] = ret->dim[n].stride * size;
+ fstride[n] = field->dim[n].stride * fsize;
+ mstride[n] = mask->dim[n].stride;
+ }
+ if (rstride[0] == 0)
+ rstride[0] = size;
}
- if (rstride[0] == 0)
- rstride[0] = size;
if (fstride[0] == 0)
fstride[0] = fsize;
if (mstride[0] == 0)
diff --git a/libgfortran/io/format.c b/libgfortran/io/format.c
index 413a664542d..229a937b05b 100644
--- a/libgfortran/io/format.c
+++ b/libgfortran/io/format.c
@@ -579,6 +579,7 @@ parse_format_list (void)
case FMT_DOLLAR:
get_fnode (&head, &tail, FMT_DOLLAR);
+ tail->repeat = 1;
goto between_desc;
case FMT_T:
diff --git a/libgfortran/io/transfer.c b/libgfortran/io/transfer.c
index b51da52204e..46bec834a27 100644
--- a/libgfortran/io/transfer.c
+++ b/libgfortran/io/transfer.c
@@ -191,7 +191,7 @@ read_sf (int *length)
/* If we see an EOR during non-advancing I/O, we need to skip
the rest of the I/O statement. Set the corresponding flag. */
- if (advance_status == ADVANCE_NO)
+ if (advance_status == ADVANCE_NO || g.seen_dollar)
eor_condition = 1;
/* Without padding, terminate the I/O statement without assigning
@@ -1187,7 +1187,7 @@ data_transfer_init (int read_flag)
}
else
{
- if (advance_status == ADVANCE_YES)
+ if (advance_status == ADVANCE_YES && !g.seen_dollar)
current_unit->read_bad = 1;
}
@@ -1459,11 +1459,12 @@ finalize_transfer (void)
{
free_fnodes ();
- if (advance_status == ADVANCE_NO)
+ if (advance_status == ADVANCE_NO || g.seen_dollar)
{
/* Most systems buffer lines, so force the partial record
to be written out. */
flush (current_unit->s);
+ g.seen_dollar = 0;
return;
}
diff --git a/libgfortran/io/unix.c b/libgfortran/io/unix.c
index 462d48df19a..f82ffa73041 100644
--- a/libgfortran/io/unix.c
+++ b/libgfortran/io/unix.c
@@ -542,8 +542,11 @@ fd_close (unix_stream * s)
if (s->buffer != NULL && s->buffer != s->small_buffer)
free_mem (s->buffer);
- if (close (s->fd) < 0)
- return FAILURE;
+ if (s->fd != STDOUT_FILENO && s->fd != STDERR_FILENO)
+ {
+ if (close (s->fd) < 0)
+ return FAILURE;
+ }
free_mem (s);
diff --git a/libgfortran/runtime/in_pack_generic.c b/libgfortran/runtime/in_pack_generic.c
index e3e1c53c201..99fdb92436f 100644
--- a/libgfortran/runtime/in_pack_generic.c
+++ b/libgfortran/runtime/in_pack_generic.c
@@ -1,5 +1,5 @@
/* Generic helper function for repacking arrays.
- Copyright 2003 Free Software Foundation, Inc.
+ Copyright 2003, 2004, 2005 Free Software Foundation, Inc.
Contributed by Paul Brook <paul@nowt.org>
This file is part of the GNU Fortran 95 runtime library (libgfortran).
@@ -40,9 +40,9 @@ export_proto(internal_pack);
void *
internal_pack (gfc_array_char * source)
{
- index_type count[GFC_MAX_DIMENSIONS - 1];
- index_type extent[GFC_MAX_DIMENSIONS - 1];
- index_type stride[GFC_MAX_DIMENSIONS - 1];
+ index_type count[GFC_MAX_DIMENSIONS];
+ index_type extent[GFC_MAX_DIMENSIONS];
+ index_type stride[GFC_MAX_DIMENSIONS];
index_type stride0;
index_type dim;
index_type ssize;
diff --git a/libgfortran/runtime/in_unpack_generic.c b/libgfortran/runtime/in_unpack_generic.c
index b0882b4a356..42f3b5d67a2 100644
--- a/libgfortran/runtime/in_unpack_generic.c
+++ b/libgfortran/runtime/in_unpack_generic.c
@@ -1,5 +1,5 @@
/* Generic helper function for repacking arrays.
- Copyright 2003 Free Software Foundation, Inc.
+ Copyright 2003, 2004, 2005 Free Software Foundation, Inc.
Contributed by Paul Brook <paul@nowt.org>
This file is part of the GNU Fortran 95 runtime library (libgfortran).
@@ -40,9 +40,9 @@ export_proto(internal_unpack);
void
internal_unpack (gfc_array_char * d, const void * s)
{
- index_type count[GFC_MAX_DIMENSIONS - 1];
- index_type extent[GFC_MAX_DIMENSIONS - 1];
- index_type stride[GFC_MAX_DIMENSIONS - 1];
+ index_type count[GFC_MAX_DIMENSIONS];
+ index_type extent[GFC_MAX_DIMENSIONS];
+ index_type stride[GFC_MAX_DIMENSIONS];
index_type stride0;
index_type dim;
index_type dsize;
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog
index 8f034b5f272..9cf2b1dafe6 100644
--- a/libiberty/ChangeLog
+++ b/libiberty/ChangeLog
@@ -1,7 +1,19 @@
+2005-05-28 Eli Zaretskii <eliz@gnu.org>
+
+ * configure.ac: Add snprintf and vsnprintf to AC_CHEK_DECLS.
+ * config.in, configure: Regenerate.
+
+2005-05-25 Richard Henderson <rth@redhat.com>
+
+ * cp-demangle.c (d_dump): Handle DEMANGLE_COMPONENT_HIDDEN_ALIAS.
+ (d_make_comp, d_print_comp): Likewise.
+ (d_special_name): Generate one.
+ * testsuite/demangle-expected: Add a hidden alias test.
+
2005-05-24 Gabriel Dos Reis <gdr@integrable-solutions.net>
* configure.ac: Check declarations for calloc(), getenv(),
- malloc(), realloc() and sbrk().
+ malloc(), realloc() and sbrk().
* config.in: Regenerate.
* configure: Likewise.
@@ -13,7 +25,7 @@
(concat): Use XNEWVEC instead of xmalloc.
(reconcat): Likewise.
* cp-demangle.c (struct d_print_template): Rename member
- "template" to "template_decl". Adjust use throughout the file.
+ "template" to "template_decl". Adjust use throughout the file.
(d_print_resize): Properly cast return value of realloc().
(cplus_demangle_print): Same for malloc().
(d_demangle): Likewise.
@@ -43,7 +55,7 @@
* getpwd.c (getpwd): Use XNEWVEC.
(htab_create_alloc_ex): Use C90 prototype-style.
* lrealpath.c (lrealpath): Appropriately cast return value of
- malloc().
+ malloc().
* make-relative-prefix.c (save_string): Likewise.
* make-temp-file.c (try_dir): Rename from "try". Adjust use in
the file.
diff --git a/libiberty/config.in b/libiberty/config.in
index 0c2778b916f..804945d70b4 100644
--- a/libiberty/config.in
+++ b/libiberty/config.in
@@ -68,10 +68,18 @@
*/
#undef HAVE_DECL_SBRK
+/* Define to 1 if you have the declaration of `snprintf', and to 0 if you
+ don't. */
+#undef HAVE_DECL_SNPRINTF
+
/* Define to 1 if you have the declaration of `vasprintf', and to 0 if you
don't. */
#undef HAVE_DECL_VASPRINTF
+/* Define to 1 if you have the declaration of `vsnprintf', and to 0 if you
+ don't. */
+#undef HAVE_DECL_VSNPRINTF
+
/* Define to 1 if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
diff --git a/libiberty/configure b/libiberty/configure
index 931989dfc95..48407c9a8b2 100755
--- a/libiberty/configure
+++ b/libiberty/configure
@@ -5300,6 +5300,146 @@ _ACEOF
fi
+echo "$as_me:$LINENO: checking whether snprintf is declared" >&5
+echo $ECHO_N "checking whether snprintf is declared... $ECHO_C" >&6
+if test "${ac_cv_have_decl_snprintf+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+#ifndef snprintf
+ char *p = (char *) snprintf;
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_have_decl_snprintf=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_have_decl_snprintf=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_have_decl_snprintf" >&5
+echo "${ECHO_T}$ac_cv_have_decl_snprintf" >&6
+if test $ac_cv_have_decl_snprintf = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_SNPRINTF 1
+_ACEOF
+
+
+else
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_SNPRINTF 0
+_ACEOF
+
+
+fi
+echo "$as_me:$LINENO: checking whether vsnprintf is declared" >&5
+echo $ECHO_N "checking whether vsnprintf is declared... $ECHO_C" >&6
+if test "${ac_cv_have_decl_vsnprintf+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+#ifndef vsnprintf
+ char *p = (char *) vsnprintf;
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_have_decl_vsnprintf=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_have_decl_vsnprintf=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_have_decl_vsnprintf" >&5
+echo "${ECHO_T}$ac_cv_have_decl_vsnprintf" >&6
+if test $ac_cv_have_decl_vsnprintf = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_VSNPRINTF 1
+_ACEOF
+
+
+else
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_VSNPRINTF 0
+_ACEOF
+
+
+fi
@@ -7215,6 +7355,146 @@ _ACEOF
fi
+echo "$as_me:$LINENO: checking whether snprintf is declared" >&5
+echo $ECHO_N "checking whether snprintf is declared... $ECHO_C" >&6
+if test "${ac_cv_have_decl_snprintf+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+#ifndef snprintf
+ char *p = (char *) snprintf;
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_have_decl_snprintf=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_have_decl_snprintf=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_have_decl_snprintf" >&5
+echo "${ECHO_T}$ac_cv_have_decl_snprintf" >&6
+if test $ac_cv_have_decl_snprintf = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_SNPRINTF 1
+_ACEOF
+
+
+else
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_SNPRINTF 0
+_ACEOF
+
+
+fi
+echo "$as_me:$LINENO: checking whether vsnprintf is declared" >&5
+echo $ECHO_N "checking whether vsnprintf is declared... $ECHO_C" >&6
+if test "${ac_cv_have_decl_vsnprintf+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+#ifndef vsnprintf
+ char *p = (char *) vsnprintf;
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_have_decl_vsnprintf=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_have_decl_vsnprintf=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_have_decl_vsnprintf" >&5
+echo "${ECHO_T}$ac_cv_have_decl_vsnprintf" >&6
+if test $ac_cv_have_decl_vsnprintf = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_VSNPRINTF 1
+_ACEOF
+
+
+else
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_VSNPRINTF 0
+_ACEOF
+
+
+fi
echo "$as_me:$LINENO: checking whether calloc is declared" >&5
diff --git a/libiberty/configure.ac b/libiberty/configure.ac
index bd1e4583477..97abc327038 100644
--- a/libiberty/configure.ac
+++ b/libiberty/configure.ac
@@ -282,7 +282,7 @@ if test "x" = "y"; then
sysconf times sbrk gettimeofday ffs snprintf vsnprintf \
pstat_getstatic pstat_getdynamic sysmp getsysinfo table sysctl wait3 wait4 \
realpath canonicalize_file_name __fsetlocking)
- AC_CHECK_DECLS([basename, ffs, asprintf, vasprintf])
+ AC_CHECK_DECLS([basename, ffs, asprintf, vasprintf, snprintf, vsnprintf])
AC_DEFINE(HAVE_SYS_ERRLIST, 1, [Define if you have the sys_errlist variable.])
AC_DEFINE(HAVE_SYS_NERR, 1, [Define if you have the sys_nerr variable.])
AC_DEFINE(HAVE_SYS_SIGLIST, 1, [Define if you have the sys_siglist variable.])
@@ -518,7 +518,7 @@ if test -z "${setobjs}"; then
[AC_MSG_RESULT([no])])
AC_CHECK_FUNCS($checkfuncs)
- AC_CHECK_DECLS([basename, ffs, asprintf, vasprintf])
+ AC_CHECK_DECLS([basename, ffs, asprintf, vasprintf, snprintf, vsnprintf])
AC_CHECK_DECLS([calloc, getenv, malloc, realloc, sbrk])
libiberty_NEED_DECLARATION(canonicalize_file_name)
fi
diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c
index 856fbd42cc9..61744390725 100644
--- a/libiberty/cp-demangle.c
+++ b/libiberty/cp-demangle.c
@@ -520,6 +520,9 @@ d_dump (struct demangle_component *dc, int indent)
case DEMANGLE_COMPONENT_REFTEMP:
printf ("reference temporary\n");
break;
+ case DEMANGLE_COMPONENT_HIDDEN_ALIAS:
+ printf ("hidden alias\n");
+ break;
case DEMANGLE_COMPONENT_RESTRICT:
printf ("restrict\n");
break;
@@ -733,6 +736,7 @@ d_make_comp (struct d_info *di, enum demangle_component_type type,
case DEMANGLE_COMPONENT_JAVA_CLASS:
case DEMANGLE_COMPONENT_GUARD:
case DEMANGLE_COMPONENT_REFTEMP:
+ case DEMANGLE_COMPONENT_HIDDEN_ALIAS:
case DEMANGLE_COMPONENT_POINTER:
case DEMANGLE_COMPONENT_REFERENCE:
case DEMANGLE_COMPONENT_COMPLEX:
@@ -1439,6 +1443,7 @@ d_operator_name (struct d_info *di)
::= TF <type>
::= TJ <type>
::= GR <name>
+ ::= GA <encoding>
*/
static struct demangle_component *
@@ -1529,6 +1534,10 @@ d_special_name (struct d_info *di)
return d_make_comp (di, DEMANGLE_COMPONENT_REFTEMP, d_name (di),
NULL);
+ case 'A':
+ return d_make_comp (di, DEMANGLE_COMPONENT_HIDDEN_ALIAS,
+ d_encoding (di, 0), NULL);
+
default:
return NULL;
}
@@ -2931,6 +2940,11 @@ d_print_comp (struct d_print_info *dpi,
d_print_comp (dpi, d_left (dc));
return;
+ case DEMANGLE_COMPONENT_HIDDEN_ALIAS:
+ d_append_string_constant (dpi, "hidden alias for ");
+ d_print_comp (dpi, d_left (dc));
+ return;
+
case DEMANGLE_COMPONENT_SUB_STD:
d_append_buffer (dpi, dc->u.s_string.string, dc->u.s_string.len);
return;
diff --git a/libiberty/testsuite/demangle-expected b/libiberty/testsuite/demangle-expected
index d38ce33c830..f8e402d01bd 100644
--- a/libiberty/testsuite/demangle-expected
+++ b/libiberty/testsuite/demangle-expected
@@ -3771,3 +3771,7 @@ _Z1ZZ2Z::__CPR212____ct__Q3_3std141list__tm__128_Q2_3edm41THandle__tm__26_Q2_4em
_test_array__L_1__B23b___clean.6
_test_array__L_1__B23b___clean.6
_test_array__L_1__B23b___clean.6
+#
+--format=java
+_ZGAN4java4lang5Class7forNameEPNS0_6StringE
+hidden alias for java.lang.Class.forName(java.lang.String)
diff --git a/libjava/ChangeLog b/libjava/ChangeLog
index 717747ed972..a98920a7dd5 100644
--- a/libjava/ChangeLog
+++ b/libjava/ChangeLog
@@ -1,3 +1,114 @@
+2005-06-03 Andreas Tobler <a.tobler@schweiz.ch>
+
+ * jawt.c: Remove malloc.h, covered by stdlib.h.
+
+ * testsuite/libjava.jni/jni.exp
+ (gcj_jni_invocation_compile_c_to_binary): Add -bind_at_load to silence
+ the build process.
+
+2005-06-02 Keith Seitz <keiths@redhat.com>
+
+ * gnu/classpath/jdwp/transport/TransportException.java: New file.
+
+2005-06-02 Andreas Tobler <a.tobler@schweiz.ch>
+
+ * mauve-libgcj: Remove implemented classes from the fail section.
+ Add two new not implemented to it.
+
+2005-06-01 Bryce McKinlay <mckinlay@redhat.com>
+
+ * configure.ac (BACKTRACESPEC): Remove definition, but continue to
+ AC_SUBST definition from configure.host.
+ * configure.host: Don't use -fno-omit-frame-pointer. Set BACKTRACESPEC
+ to -fomit-frame-pointer on 32-bit x86 targets.
+
+2005-06-01 Tom Tromey <tromey@redhat.com>
+
+ * java/io/ObjectInputStream.java (currentLoader): Fixed typo.
+
+2005-06-01 Ziga Mahkovec <ziga.mahkovec@klika.si>
+
+ PR libgcj/20435:
+ * gnu/regexp/RESyntax.java (RE_POSSESSIVE_OPS): New field.
+ (static): Add possessive matching to JAVA_1_4 syntax.
+ * gnu/regexp/RETokenRepeated.java (possessive): New field.
+ (makePossessive, isPossessive): New methods.
+ (match): Don't back off during possessive matching.
+ * gnu/regexp/RE.java (initalize): Accept possessive quantifier.
+ * java/util/regex/Pattern.java (constructor): Switch syntax from PERL5
+ to JAVA_1_4.
+
+2005-06-01 Keith Seitz <keiths@redhat.com>
+
+ * gnu/classpath/jdwp/transport/JdwpPacket.java: New file.
+ * gnu/classpath/jdwp/transport/JdwpCommandPacket.java: New file.
+ * gnu/classpath/jdwp/transport/JdwpReplyPacket.java: New file.
+
+2005-06-01 Tom Tromey <tromey@redhat.com>
+
+ PR libgcj/21785:
+ * java/io/natObjectInputStream.cc (currentClassLoader): Removed.
+ (currentLoader): New method.
+ * java/io/ObjectInputStream.java (resolveProxyClass): Use
+ currentLoader.
+ (currentLoader): Now native.
+ (currentClassLoader): Removed.
+ * testsuite/libjava.lang/pr21785.java: New file.
+ * testsuite/libjava.lang/pr21785.out: New file.
+
+2005-06-01 Tom Tromey <tromey@redhat.com>
+
+ PR libgcj/21753:
+ * java/lang/natString.cc (substring): Changed sharing heuristic.
+
+2005-05-30 Bryce McKinlay <mckinlay@redhat.com>
+
+ PR libgcj/21821
+ * gnu/java/nio/channels/natFileChannelPosix.cc (open): Don't use
+ MAXPATHLEN. Format exception message using a StringBuffer instead.
+
+2005-05-29 Michael Koch <konqueror@gmx.de>
+
+ PR libgcj/20273:
+ * java/util/LinkedHashMap.java (access): Set 'root.pred'.
+
+2005-05-27 Ziga Mahkovec <ziga.mahkovec@klika.si>
+
+ * ChangeLog: Fix typo.
+
+2005-05-26 Ranjit Mathew <rmathew@hotmail.com>
+
+ Testsuite adjustments for PR java/19870.
+ * testsuite/libjava.lang/PR19870.java: New testcase.
+ * testsuite/libjava.lang/PR19870.out: Expected output for the
+ testcase.
+ * testsuite/libjava.jacks/jacks.xfail: Add
+ 8.5.2-accessible-static-member-usage-3 and 15.8.4-static-2
+
+
+2005-05-26 Bryce McKinlay <mckinlay@redhat.com>
+
+ * include/jvm.h (FLAG_BINARYCOMPAT_ABI, FLAG_BOOTSTRAP_LOADER): New.
+ (GCJ_BINARYCOMPAT_ADDITION, GCJ_BOOTSTRAP_LOADER_ADDITION): Removed.
+ (OLD_GCJ_40_BC_ABI_VERSION): Renamed. Old-style version ID for BC-ABI
+ classes.
+ (GCJ_CXX_ABI_VERSION): Renamed from GCJ_ABI_VERSION.
+ (GCJ_40_BC_ABI_VERSION): New. Calculate version IDs using new method.
+ (_Jv_CheckABIVersion): Check for both old and new style version IDs.
+ (_Jv_ClassForBootstrapLoader): Use FLAG_BOOTSTRAP_LOADER.
+
+2005-05-25 Richard Henderson <rth@redhat.com>
+
+ PR libgcj/21692
+ * sysdep/descriptor-n.h: New file.
+ * sysdep/descriptor-y.h: New file.
+ * sysdep/powerpc/descriptor.h: New file.
+ * configure.host: Set $descriptor_h appropriate for the host.
+ * configure.ac: Link it.
+ * configure: Regenerate.
+ * stacktrace.cc: Include sysdep/descriptor.h.
+ (_Jv_StackTrace::UpdateNCodeMap): Use UNWRAP_FUNCTION_DESCRIPTOR.
+
2005-05-25 Chris Burdess <dog@gnu.org>
* gnu/xml/dom/ls/SAXEventSink.java: Ignore XML entities in start/
@@ -158,7 +269,7 @@
2005-05-16 Ziga Mahkovec <ziga.mahkovec@klika.si>
PR libgcj/20504
- gnu/regexp/RE.java: Add support for quoting constructs.
+ * gnu/regexp/RE.java: Add support for quoting constructs.
2005-05-15 Tom Tromey <tromey@redhat.com>
diff --git a/libjava/configure b/libjava/configure
index 76b062af128..0e971e1a583 100755
--- a/libjava/configure
+++ b/libjava/configure
@@ -8511,6 +8511,8 @@ if test -d sysdep; then true; else mkdir sysdep; fi
ac_config_links="$ac_config_links sysdep/backtrace.h:$fallback_backtrace_h"
+ ac_config_links="$ac_config_links sysdep/descriptor.h:$descriptor_h"
+
HASH_SYNC_SPEC=
# Hash synchronization is only useful with posix threads right now.
@@ -16892,6 +16894,7 @@ do
"include/java-threads.h" ) CONFIG_LINKS="$CONFIG_LINKS include/java-threads.h:include/$THREADH" ;;
"sysdep/locks.h" ) CONFIG_LINKS="$CONFIG_LINKS sysdep/locks.h:sysdep/$sysdeps_dir/locks.h" ;;
"sysdep/backtrace.h" ) CONFIG_LINKS="$CONFIG_LINKS sysdep/backtrace.h:$fallback_backtrace_h" ;;
+ "sysdep/descriptor.h" ) CONFIG_LINKS="$CONFIG_LINKS sysdep/descriptor.h:$descriptor_h" ;;
"include/java-signal.h" ) CONFIG_LINKS="$CONFIG_LINKS include/java-signal.h:$SIGNAL_HANDLER" ;;
"include/java-signal-aux.h" ) CONFIG_LINKS="$CONFIG_LINKS include/java-signal-aux.h:$SIGNAL_HANDLER_AUX" ;;
"depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
diff --git a/libjava/configure.ac b/libjava/configure.ac
index 594df415c39..a7d9d20fb31 100644
--- a/libjava/configure.ac
+++ b/libjava/configure.ac
@@ -707,6 +707,7 @@ AM_CONDITIONAL(USING_NO_THREADS, test "$THREADS" = none)
if test -d sysdep; then true; else mkdir sysdep; fi
AC_CONFIG_LINKS(sysdep/locks.h:sysdep/$sysdeps_dir/locks.h)
AC_CONFIG_LINKS(sysdep/backtrace.h:$fallback_backtrace_h)
+AC_CONFIG_LINKS(sysdep/descriptor.h:$descriptor_h)
HASH_SYNC_SPEC=
# Hash synchronization is only useful with posix threads right now.
@@ -1147,6 +1148,7 @@ AC_SUBST(ZINCS)
AC_SUBST(DIVIDESPEC)
AC_SUBST(CHECKREFSPEC)
AC_SUBST(EXCEPTIONSPEC)
+AC_SUBST(BACKTRACESPEC)
AC_SUBST(IEEESPEC)
AM_CONDITIONAL(NATIVE, test "$NATIVE" = yes)
@@ -1344,15 +1346,6 @@ if test "$enable_sjlj_exceptions" = yes; then
SIGNAL_HANDLER_AUX=
fi
-# Define here any compiler flags that you need in order to make backtrace() work.
-BACKTRACESPEC=
-case "${host}" in
- x86_64*-*-linux*|i?86-*)
- BACKTRACESPEC=-fno-omit-frame-pointer
- ;;
-esac
-AC_SUBST(BACKTRACESPEC)
-
AC_SUBST(SYSDEP_SOURCES)
if test -z "$SIGNAL_HANDLER_AUX"; then
diff --git a/libjava/configure.host b/libjava/configure.host
index ff86d72305b..5f32bfbe5c4 100644
--- a/libjava/configure.host
+++ b/libjava/configure.host
@@ -32,6 +32,7 @@
# (i.e it is broken).
# fallback_backtrace_h Header to use for fallback backtrace implementation
# (only for targets that don't support DWARF2 unwind)
+# descriptor_h Header to use for looking past function descriptors
libgcj_flags=
libgcj_cflags=
@@ -68,6 +69,7 @@ echo "$target"
DIVIDESPEC=-fuse-divide-subroutine
EXCEPTIONSPEC=-fnon-call-exceptions
CHECKREFSPEC=
+BACKTRACESPEC=
# This case statement supports per-CPU defaults.
case "${host}" in
@@ -93,17 +95,18 @@ case "${host}" in
;;
i686-*|i586-*|i486-*|i386-*)
sysdeps_dir=i386
- libgcj_flags="${libgcj_flags} -ffloat-store -fno-omit-frame-pointer"
+ libgcj_flags="${libgcj_flags} -ffloat-store"
libgcj_interpreter=yes
libgcj_cxxflags=
libgcj_cflags=
DIVIDESPEC=-fno-use-divide-subroutine
+ BACKTRACESPEC=-fomit-frame-pointer
enable_hash_synchronization_default=yes
slow_pthread_self=yes
;;
x86_64-*)
sysdeps_dir=x86-64
- libgcj_flags="${libgcj_flags} -ffloat-store -fno-omit-frame-pointer"
+ libgcj_flags="${libgcj_flags} -ffloat-store"
libgcj_cxxflags=
libgcj_cflags=
DIVIDESPEC=-f%{m32:no-}use-divide-subroutine
@@ -265,9 +268,24 @@ esac
case "${host}" in
*-cygwin* | *-mingw*)
fallback_backtrace_h=sysdep/i386/backtrace.h
+ # We need a frame pointer on Windows, so override BACKTRACESPEC
+ BACKTRACESPEC=
;;
esac
+case "${host}" in
+ ia64-* | hppa*-*)
+ descriptor_h=sysdep/descriptor-y.h
+ ;;
+
+ rs6000-* | powerpc*-*)
+ descriptor_h=sysdep/powerpc/descriptor.h
+ ;;
+
+ *)
+ descriptor_h=sysdep/descriptor-n.h
+ ;;
+esac
libgcj_cflags="${libgcj_cflags} ${libgcj_flags}"
libgcj_cxxflags="${libgcj_cxxflags} ${libgcj_flags}"
diff --git a/libjava/gnu/java/nio/channels/natFileChannelPosix.cc b/libjava/gnu/java/nio/channels/natFileChannelPosix.cc
index 742201bde94..24b6396c66c 100644
--- a/libjava/gnu/java/nio/channels/natFileChannelPosix.cc
+++ b/libjava/gnu/java/nio/channels/natFileChannelPosix.cc
@@ -37,6 +37,7 @@ details. */
#include <java/lang/NullPointerException.h>
#include <java/lang/System.h>
#include <java/lang/String.h>
+#include <java/lang/StringBuffer.h>
#include <java/lang/Thread.h>
#include <java/nio/ByteBuffer.h>
#include <java/nio/MappedByteBufferImpl.h>
@@ -168,13 +169,13 @@ FileChannelImpl::open (jstring path, jint jflags)
}
if (fd == -1)
{
- char msg[MAXPATHLEN + 200];
// We choose the formatting here for JDK compatibility, believe
// it or not.
- sprintf (msg, "%.*s (%.*s)",
- MAXPATHLEN + 150, buf,
- 40, strerror (errno));
- throw new ::java::io::FileNotFoundException (JvNewStringLatin1 (msg));
+ ::java::lang::StringBuffer *msg = new ::java::lang::StringBuffer (path);
+ msg->append (JvNewStringUTF (" ("));
+ msg->append (JvNewStringUTF (strerror (errno)));
+ msg->append (JvNewStringUTF (")"));
+ throw new ::java::io::FileNotFoundException (msg->toString ());
}
_Jv_platform_close_on_exec (fd);
diff --git a/libjava/gnu/regexp/RE.java b/libjava/gnu/regexp/RE.java
index c8c8a3eb9ff..541e8cb950f 100644
--- a/libjava/gnu/regexp/RE.java
+++ b/libjava/gnu/regexp/RE.java
@@ -629,20 +629,29 @@ public class RE extends REToken {
currentToken = setRepeated(currentToken,0,Integer.MAX_VALUE,index);
}
- // ONE-OR-MORE REPEAT OPERATOR
+ // ONE-OR-MORE REPEAT OPERATOR / POSSESSIVE MATCHING OPERATOR
// + | \+ depending on RE_BK_PLUS_QM
// not available if RE_LIMITED_OPS is set
else if ((unit.ch == '+') && !syntax.get(RESyntax.RE_LIMITED_OPS) && (!syntax.get(RESyntax.RE_BK_PLUS_QM) ^ (unit.bk || quot))) {
if (currentToken == null)
throw new REException(getLocalizedMessage("repeat.no.token"),REException.REG_BADRPT,index);
- if (currentToken instanceof RETokenRepeated)
- throw new REException(getLocalizedMessage("repeat.chained"),REException.REG_BADRPT,index);
- if (currentToken instanceof RETokenWordBoundary || currentToken instanceof RETokenWordBoundary)
+
+ // Check for possessive matching on RETokenRepeated
+ if (currentToken instanceof RETokenRepeated) {
+ RETokenRepeated tokenRep = (RETokenRepeated)currentToken;
+ if (syntax.get(RESyntax.RE_POSSESSIVE_OPS) && !tokenRep.isPossessive() && !tokenRep.isStingy())
+ tokenRep.makePossessive();
+ else
+ throw new REException(getLocalizedMessage("repeat.chained"),REException.REG_BADRPT,index);
+
+ }
+ else if (currentToken instanceof RETokenWordBoundary || currentToken instanceof RETokenWordBoundary)
throw new REException(getLocalizedMessage("repeat.assertion"),REException.REG_BADRPT,index);
- if (currentToken.getMinimumLength() == 0)
+ else if (currentToken.getMinimumLength() == 0)
throw new REException(getLocalizedMessage("repeat.empty.token"),REException.REG_BADRPT,index);
- currentToken = setRepeated(currentToken,1,Integer.MAX_VALUE,index);
+ else
+ currentToken = setRepeated(currentToken,1,Integer.MAX_VALUE,index);
}
// ZERO-OR-ONE REPEAT OPERATOR / STINGY MATCHING OPERATOR
@@ -655,13 +664,14 @@ public class RE extends REToken {
// Check for stingy matching on RETokenRepeated
if (currentToken instanceof RETokenRepeated) {
- if (syntax.get(RESyntax.RE_STINGY_OPS) && !((RETokenRepeated)currentToken).isStingy())
- ((RETokenRepeated)currentToken).makeStingy();
- else
- throw new REException(getLocalizedMessage("repeat.chained"),REException.REG_BADRPT,index);
- }
- else if (currentToken instanceof RETokenWordBoundary || currentToken instanceof RETokenWordBoundary)
- throw new REException(getLocalizedMessage("repeat.assertion"),REException.REG_BADRPT,index);
+ RETokenRepeated tokenRep = (RETokenRepeated)currentToken;
+ if (syntax.get(RESyntax.RE_STINGY_OPS) && !tokenRep.isStingy() && !tokenRep.isPossessive())
+ tokenRep.makeStingy();
+ else
+ throw new REException(getLocalizedMessage("repeat.chained"),REException.REG_BADRPT,index);
+ }
+ else if (currentToken instanceof RETokenWordBoundary || currentToken instanceof RETokenWordBoundary)
+ throw new REException(getLocalizedMessage("repeat.assertion"),REException.REG_BADRPT,index);
else
currentToken = setRepeated(currentToken,0,1,index);
}
diff --git a/libjava/gnu/regexp/RESyntax.java b/libjava/gnu/regexp/RESyntax.java
index 649bd0df584..7cb3e1400b8 100644
--- a/libjava/gnu/regexp/RESyntax.java
+++ b/libjava/gnu/regexp/RESyntax.java
@@ -197,7 +197,12 @@ public final class RESyntax implements Serializable {
*/
public static final int RE_CHAR_CLASS_ESC_IN_LISTS = 24;
- private static final int BIT_TOTAL = 25;
+ /**
+ * Syntax bit. Possessive matching is allowed (++, *+, ?+, {x,y}+).
+ */
+ public static final int RE_POSSESSIVE_OPS = 25;
+
+ private static final int BIT_TOTAL = 26;
/**
* Predefined syntax.
@@ -425,6 +430,7 @@ public final class RESyntax implements Serializable {
RE_SYNTAX_JAVA_1_4 = new RESyntax(RE_SYNTAX_PERL5)
// XXX
+ .set(RE_POSSESSIVE_OPS) // *+,?+,++,{}+
.makeFinal();
}
diff --git a/libjava/gnu/regexp/RETokenRepeated.java b/libjava/gnu/regexp/RETokenRepeated.java
index 8c789271220..821e4c55c0f 100644
--- a/libjava/gnu/regexp/RETokenRepeated.java
+++ b/libjava/gnu/regexp/RETokenRepeated.java
@@ -44,6 +44,7 @@ final class RETokenRepeated extends REToken {
private REToken token;
private int min,max;
private boolean stingy;
+ private boolean possessive;
RETokenRepeated(int subIndex, REToken token, int min, int max) {
super(subIndex);
@@ -61,6 +62,16 @@ final class RETokenRepeated extends REToken {
boolean isStingy() {
return stingy;
}
+
+ /** Sets possessive matching mode to true. */
+ void makePossessive() {
+ possessive = true;
+ }
+
+ /** Queries if this token has possessive matching enabled. */
+ boolean isPossessive() {
+ return possessive;
+ }
/**
* The minimum length of a repeated token is the minimum length
@@ -172,6 +183,8 @@ final class RETokenRepeated extends REToken {
}
}
// else did not match rest of the tokens, try again on smaller sample
+ // or break out when performing possessive matching
+ if (possessive) break;
}
if (allResults != null) {
mymatch.assignFrom(allResults); // does this get all?
diff --git a/libjava/include/jvm.h b/libjava/include/jvm.h
index bceb291fb58..3a2eb9b923e 100644
--- a/libjava/include/jvm.h
+++ b/libjava/include/jvm.h
@@ -564,31 +564,50 @@ extern void (*_Jv_JVMPI_Notify_THREAD_END) (JVMPI_Event *event);
extern void _Jv_RegisterBootstrapPackages ();
+#define FLAG_BINARYCOMPAT_ABI (1<<31) /* Class is built with the BC-ABI. */
-// This is used to find ABI versions we recognize.
-#define GCJ_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 10)
-#define GCJ_BINARYCOMPAT_ADDITION 5
-#define GCJ_BOOTSTRAP_LOADER_ADDITION 1
+#define FLAG_BOOTSTRAP_LOADER (1<<30) /* Used when defining a class that
+ should be loaded by the bootstrap
+ loader. */
-// At present we know we are compatible with the BC ABI as used in GCC
-// 4.0.
-#define GCJ_40_BC_ABI_VERSION (4 * 10000 + 0 * 10 + GCJ_BINARYCOMPAT_ADDITION)
+// These are used to find ABI versions we recognize.
+#define GCJ_CXX_ABI_VERSION (__GNUC__ * 100000 + __GNUC_MINOR__ * 1000)
+
+// This is the old-style BC version ID used by GCJ 4.0.0.
+#define OLD_GCJ_40_BC_ABI_VERSION (4 * 10000 + 0 * 10 + 5)
+
+// New style version IDs used by GCJ 4.0.1 and later.
+#define GCJ_40_BC_ABI_VERSION (4 * 100000 + 0 * 1000)
inline bool
_Jv_CheckABIVersion (unsigned long value)
{
- // Recognize our defined C++ ABIs.
- return (value == GCJ_VERSION
- || value == (GCJ_VERSION + GCJ_BOOTSTRAP_LOADER_ADDITION)
- || value == GCJ_40_BC_ABI_VERSION
- || value == (GCJ_40_BC_ABI_VERSION + GCJ_BOOTSTRAP_LOADER_ADDITION));
+ // We are compatible with GCJ 4.0.0 BC-ABI classes. This release used a
+ // different format for the version ID string.
+ if (value == OLD_GCJ_40_BC_ABI_VERSION)
+ return true;
+
+ // The 20 low-end bits are used for the version number.
+ unsigned long version = value & 0xfffff;
+
+ if (value & FLAG_BINARYCOMPAT_ABI)
+ {
+ int abi_rev = version % 100;
+ int abi_ver = version - abi_rev;
+ if (abi_ver == GCJ_40_BC_ABI_VERSION && abi_rev <= 0)
+ return true;
+ }
+ else
+ // C++ ABI
+ return version == GCJ_CXX_ABI_VERSION;
+
+ return false;
}
inline bool
_Jv_ClassForBootstrapLoader (unsigned long value)
{
- return (value == (GCJ_VERSION + GCJ_BOOTSTRAP_LOADER_ADDITION)
- || value == (GCJ_40_BC_ABI_VERSION + GCJ_BOOTSTRAP_LOADER_ADDITION));
+ return (value & FLAG_BOOTSTRAP_LOADER);
}
// It makes the source cleaner if we simply always define this
diff --git a/libjava/java/io/ObjectInputStream.java b/libjava/java/io/ObjectInputStream.java
index 2cfe4c99419..3bcfd05f581 100644
--- a/libjava/java/io/ObjectInputStream.java
+++ b/libjava/java/io/ObjectInputStream.java
@@ -783,21 +783,11 @@ public class ObjectInputStream extends InputStream
}
/**
- * This method invokes the method currentClassLoader for the
- * current security manager (or build an empty one if it is not
- * present).
- *
- * @return The most recent non-system ClassLoader on the execution stack.
- * @see java.lang.SecurityManager#currentClassLoader()
+ * Returns the most recent user defined ClassLoader on the execution stack
+ * or null if none is found.
*/
- private ClassLoader currentLoader()
- {
- SecurityManager sm = System.getSecurityManager();
- if (sm == null)
- sm = new SecurityManager () {};
-
- return currentClassLoader(sm);
- }
+ // GCJ LOCAL: native method.
+ private native ClassLoader currentLoader();
/**
* Lookup a class stored in the local hashtable. If it is not
@@ -883,12 +873,7 @@ public class ObjectInputStream extends InputStream
protected Class resolveProxyClass(String[] intfs)
throws IOException, ClassNotFoundException
{
- SecurityManager sm = System.getSecurityManager();
-
- if (sm == null)
- sm = new SecurityManager() {};
-
- ClassLoader cl = currentClassLoader(sm);
+ ClassLoader cl = currentLoader();
Class[] clss = new Class[intfs.length];
if(cl == null)
@@ -1866,15 +1851,6 @@ public class ObjectInputStream extends InputStream
}
}
- /**
- * This native method is used to get access to the protected method
- * of the same name in SecurityManger.
- *
- * @param sm SecurityManager instance which should be called.
- * @return The current class loader in the calling stack.
- */
- private static native ClassLoader currentClassLoader (SecurityManager sm);
-
private void callReadMethod (Method readObject, Class klass, Object obj)
throws ClassNotFoundException, IOException
{
diff --git a/libjava/java/io/natObjectInputStream.cc b/libjava/java/io/natObjectInputStream.cc
index 0e0d5a719cc..2d1a55665d1 100644
--- a/libjava/java/io/natObjectInputStream.cc
+++ b/libjava/java/io/natObjectInputStream.cc
@@ -1,6 +1,6 @@
// natObjectInputStream.cc - Native part of ObjectInputStream class.
-/* Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation
+/* Copyright (C) 1998, 1999, 2000, 2001, 2005 Free Software Foundation
This ObjectInputStream is part of libgcj.
@@ -24,6 +24,7 @@ details. */
#include <java/lang/SecurityManager.h>
#include <java/lang/reflect/Constructor.h>
#include <java/lang/reflect/Method.h>
+#include <java-stack.h>
#ifdef DEBUG
#include <java/lang/System.h>
@@ -69,9 +70,11 @@ java::io::ObjectInputStream::allocateObject (jclass klass, jclass,
return obj;
}
-java::lang::ClassLoader*
-java::io::ObjectInputStream::currentClassLoader (::java::lang::SecurityManager *sm)
+java::lang::ClassLoader *
+java::io::ObjectInputStream::currentLoader ()
{
- return sm->currentClassLoader ();
+ jclass caller = _Jv_StackTrace::GetCallingClass (&ObjectInputStream::class$);
+ if (caller)
+ return caller->getClassLoaderInternal();
+ return NULL;
}
-
diff --git a/libjava/java/lang/natString.cc b/libjava/java/lang/natString.cc
index a14f5de9d6e..c8f3129a212 100644
--- a/libjava/java/lang/natString.cc
+++ b/libjava/java/lang/natString.cc
@@ -833,7 +833,10 @@ java::lang::String::substring (jint beginIndex, jint endIndex)
if (beginIndex == 0 && endIndex == count)
return this;
jint newCount = endIndex - beginIndex;
- if (newCount <= 8) // Optimization, mainly for GC.
+ // For very small strings, just allocate a new one. For other
+ // substrings, allocate a new one unless the substring is over half
+ // of the original string.
+ if (newCount <= 8 || newCount < (count >> 1))
return JvNewString(JvGetStringChars(this) + beginIndex, newCount);
jstring s = new String();
s->data = data;
diff --git a/libjava/java/util/LinkedHashMap.java b/libjava/java/util/LinkedHashMap.java
index f58cf3fe70e..d18d6f8e4a4 100644
--- a/libjava/java/util/LinkedHashMap.java
+++ b/libjava/java/util/LinkedHashMap.java
@@ -1,6 +1,6 @@
/* LinkedHashMap.java -- a class providing hashtable data structure,
mapping Object --> Object, with linked list traversal
- Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2002, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -186,6 +186,7 @@ public class LinkedHashMap extends HashMap
succ = null;
pred = root.pred;
pred.succ = this;
+ root.pred = this;
}
}
}
diff --git a/libjava/java/util/regex/Pattern.java b/libjava/java/util/regex/Pattern.java
index 06418a22a34..455171c5bbb 100644
--- a/libjava/java/util/regex/Pattern.java
+++ b/libjava/java/util/regex/Pattern.java
@@ -84,8 +84,7 @@ public final class Pattern implements Serializable
// if ((flags & UNICODE_CASE) != 0) gnuFlags =
// if ((flags & CANON_EQ) != 0) gnuFlags =
- // Eventually there will be such a thing as JDK 1_4 syntax
- RESyntax syntax = RESyntax.RE_SYNTAX_PERL5;
+ RESyntax syntax = RESyntax.RE_SYNTAX_JAVA_1_4;
if ((flags & UNIX_LINES) != 0)
{
// Use a syntax set with \n for linefeeds?
diff --git a/libjava/jawt.c b/libjava/jawt.c
index bb03c638e55..ad5284d4b13 100644
--- a/libjava/jawt.c
+++ b/libjava/jawt.c
@@ -40,7 +40,6 @@
#include <jawt.h>
#include <jawt_md.h>
#include "classpath_jawt.h"
-#include <malloc.h>
static jint (JNICALL _Jv_Lock) (JAWT_DrawingSurface* surface);
static void (JNICALL _Jv_Unlock) (JAWT_DrawingSurface* surface);
diff --git a/libjava/mauve-libgcj b/libjava/mauve-libgcj
index 04ef521ff89..ff3b1f5a867 100644
--- a/libjava/mauve-libgcj
+++ b/libjava/mauve-libgcj
@@ -20,9 +20,5 @@ JDBC2.0
!java.lang.ref.
# Tests for not yet implemented classes and/or methods.
-!javax.swing.plaf
-!javax.swing.text
-!javax.swing.table
-!javax.swing.SpinnerListModel
-!javax.swing.SwingUtilities
-!java.beans.XMLDecoder
+!java.awt.event.MouseEvent.modifiersEx
+!org.omg.
diff --git a/libjava/stacktrace.cc b/libjava/stacktrace.cc
index a849f6f9e71..e0276788835 100644
--- a/libjava/stacktrace.cc
+++ b/libjava/stacktrace.cc
@@ -29,6 +29,7 @@ details. */
#include <gnu/gcj/runtime/NameFinder.h>
#include <sysdep/backtrace.h>
+#include <sysdep/descriptor.h>
using namespace java::lang;
using namespace java::lang::reflect;
@@ -62,12 +63,12 @@ _Jv_StackTrace::UpdateNCodeMap ()
for (int i=0; i < klass->method_count; i++)
{
_Jv_Method *method = &klass->methods[i];
+ void *ncode = method->ncode;
// Add non-abstract methods to ncodeMap.
- if (method->ncode)
+ if (ncode)
{
- //printf("map->put 0x%x / %s.%s\n", method->ncode, klass->name->data,
- // method->name->data);
- ncodeMap->put ((java::lang::Object *) method->ncode, klass);
+ ncode = UNWRAP_FUNCTION_DESCRIPTOR (ncode);
+ ncodeMap->put ((java::lang::Object *)ncode, klass);
}
}
}
diff --git a/libjava/testsuite/libjava.jacks/jacks.xfail b/libjava/testsuite/libjava.jacks/jacks.xfail
index cd537878cb5..4524e957a33 100644
--- a/libjava/testsuite/libjava.jacks/jacks.xfail
+++ b/libjava/testsuite/libjava.jacks/jacks.xfail
@@ -306,6 +306,7 @@
15.8.2-type-12
15.8.2-type-13
15.8.2-type-14
+15.8.4-static-2
15.8.5-field-expression-6
15.8.5-method-expression-8
15.8.5-variable-5
@@ -633,6 +634,7 @@
8.5-inheritance-2
8.5-inheritance-3
8.5-inheritance-6
+8.5.2-accessible-static-member-usage-3
8.5.2-non-static-member-usage-2
8.5.2-non-static-member-usage-4
8.5.2-non-static-member-usage-5
diff --git a/libjava/testsuite/libjava.jni/jni.exp b/libjava/testsuite/libjava.jni/jni.exp
index 201daaca713..84614260b0b 100644
--- a/libjava/testsuite/libjava.jni/jni.exp
+++ b/libjava/testsuite/libjava.jni/jni.exp
@@ -196,7 +196,7 @@ proc gcj_jni_invocation_compile_c_to_binary {file {options {}}} {
# Set some darwin specific options
if { [istarget "*-*-darwin*"] } {
- lappend options "additional_flags=-multiply_defined suppress"
+ lappend options "additional_flags= -bind_at_load -multiply_defined suppress"
}
# Find the generated header.
lappend options "additional_flags=-I. -I.."
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 00bb7493f6d..77cc306df75 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,157 @@
+2005-06-03 Paolo Carlini <pcarlini@suse.de>
+
+ PR libstdc++/21770
+ * include/bits/stl_deque.h: Add concept-check. In class _Deque_base
+ rebind _Alloc to _Tp_alloc_type, change _Deque_impl to inherit from
+ the latter and add _M_get_Tp_allocator() which returns it. Use
+ everywhere _M_get_Tp_allocator() instead of get_allocator().
+ * include/bits/deque.tcc: Likewise, use _M_get_Tp_allocator().
+ * include/bits/stl_list.h: Add concept-check. In class _List_base
+ rebind _Alloc to _Tp_alloc_type and add _M_get_Tp_allocator(), which
+ returns the allocator (of type _Node_alloc_type) converted to
+ _Tp_alloc_type. Use everywhere _M_get_Tp_allocator() instead of
+ get_allocator().
+ * include/bits/list.tcc: Likewise, use _M_get_Tp_allocator().
+ * include/bits/stl_vector.h: Add concept-check. In class _Vector_base
+ rebind _Alloc to _Tp_alloc_type, change _Vector_impl to inherit from
+ the latter and add _M_get_Tp_allocator() which returns it. Use
+ everywhere _M_get_Tp_allocator() instead of get_allocator().
+ * include/bits/vector.tcc: Likewise, use _M_get_Tp_allocator().
+ * include/bits/stl_map.h: Add concept-check. Rebind _Alloc to
+ _Pair_alloc_type and use it for _Rb_tree.
+ * include/bits/stl_multimap.h: Likewise.
+ * include/bits/stl_multiset.h: Add concept-check. Rebind _Alloc to
+ _Key_alloc_type and use it for _Rb_tree.
+ * include/bits/stl_set.h: Likewise.
+ * include/bits/basic_string.h: Rebind _Alloc to _CharT_alloc_type and
+ use it for the allocator typedefs.
+ * testsuite/21_strings/basic_string/1.cc: New.
+ * testsuite/23_containers/deque/explicit_instantiation.cc: Move to...
+ * testsuite/23_containers/deque/explicit_instantiation/1.cc: ... here.
+ * testsuite/23_containers/deque/explicit_instantiation/3.cc: New.
+ * testsuite/23_containers/list/explicit_instantiation.cc: Move to...
+ * testsuite/23_containers/list/explicit_instantiation/1.cc: ... here.
+ * testsuite/23_containers/list/explicit_instantiation/3.cc: New.
+ * testsuite/23_containers/map/explicit_instantiation.cc: Move to...
+ * testsuite/23_containers/map/explicit_instantiation/1.cc: ... here.
+ * testsuite/23_containers/map/explicit_instantiation/3.cc: New.
+ * testsuite/23_containers/multimap/explicit_instantiation.cc: Move to...
+ * testsuite/23_containers/multimap/explicit_instantiation/1.cc: .. here.
+ * testsuite/23_containers/multimap/explicit_instantiation/3.cc: New.
+ * testsuite/23_containers/multiset/explicit_instantiation.cc: Move to...
+ * testsuite/23_containers/multiset/explicit_instantiation/1.cc: .. here.
+ * testsuite/23_containers/multiset/explicit_instantiation/3.cc: New.
+ * testsuite/23_containers/set/explicit_instantiation.cc: Move to...
+ * testsuite/23_containers/set/explicit_instantiation/1.cc: .. here.
+ * testsuite/23_containers/set/explicit_instantiation/3.cc: New.
+ * testsuite/23_containers/vector/explicit_instantiation.cc: Move to...
+ * testsuite/23_containers/vector/explicit_instantiation/1.cc: ... here.
+ * testsuite/23_containers/vector/explicit_instantiation/3.cc: New.
+
+2005-06-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/21280
+ * testsuite/27_io/ios_base/cons/assign_neg.cc: Adjust expected errors.
+ * testsuite/27_io/ios_base/cons/copy_neg.cc: Likewise.
+
+2005-05-31 Paolo Carlini <pcarlini@suse.de>
+
+ PR libstdc++/20534 (contd)
+ * include/debug/macros.h: Add _GLIBCXX_DEBUG_ABORT, using
+ __gnu_debug::__fancy_abort.
+ * src/debug.cc: Define the latter.
+ * include/debug/debug.h: Use _GLIBCXX_DEBUG_ABORT instead of
+ assert.
+ * config/linker-map.gnu (__gnu_debug::__fancy_abort): Add.
+
+2005-05-30 Paolo Carlini <pcarlini@suse.de>
+
+ * include/std/std_complex.h (log(const complex<_Tp>&)): When
+ _GLIBCXX_USE_C99_COMPLEX, forward to __builtin_clog/clogf/clogl.
+
+2005-05-28 Paolo Carlini <pcarlini@suse.de>
+
+ Revert:
+ 2005-05-18 Paolo Carlini <pcarlini@suse.de>
+ Nathan Myers <ncm@cantrip.org>
+
+ PR libstdc++/19495
+ * include/bits/basic_string.h (_Raw_bytes_alloc): Rebind to
+ size_type instead of char and rename to _Raw_alloc.
+ * include/bits/basic_string.tcc (_Rep::_M_destroy, _Rep::_S_create):
+ Use the above.
+ * src/bitmap_allocator.cc: Add instantiation for size_type.
+ * src/mt_allocator.cc: Likewise.
+ * src/pool_allocator.cc: Likewise.
+ * include/ext/array_allocator.h: Tweak slightly, avoid assuming
+ the existence of an _Array::begin() and size() members.
+ * testsuite/ext/array_allocator/2.cc: Tweak to use an allocator
+ of size_type, instead of char, thus avoiding problems with
+ rebinds, not treated correctly by array_allocator.
+
+2005-05-27 Paolo Carlini <pcarlini@suse.de>
+
+ * docs/html/abi.html: Mention 3.4.0 as the current baseline; add
+ a notice about the configure options.
+
+2005-05-27 Mark Mitchell <mark@codesourcery.com>
+
+ * docs/html/test.html: Mention PCH_CXXFLAGS.
+ * testsuite/lib/libstdc++.exp: Set PCH_CXXFLAGS by probing for an
+ available stcd++.h PCH.
+ * testsuite/libstdc++-dg/normal.exp: Use PCH_CXXFLAGS.
+
+2005-05-27 Theodore Papadopoulo <Theodore.Papadopoulo@sophia.inria.fr>
+
+ * src/misc-inst.cc: Remove unnecessary included files.
+
+2005-05-27 Benjamin Kosnik <bkoz@redhat.com>
+
+ PR libstdc++/21674
+ * include/bits/c++config: Remove extern template use when in debug
+ mode, disable for non-weak systems.
+
+2005-05-27 Benjamin Kosnik <bkoz@redhat.com>
+
+ PR libstdc++/20534
+ * include/debug/debug.h: Forwarding header, that pulls in details
+ only if in debug mode.
+ * include/debug/macros.h: ...transfer all the internal macros here.
+ * include/debug/functions.h: ...transfer all the functions here.
+ * include/debug/safe_iterator.h: Add functions.h, macros.h includes.
+ * include/debug/safe_sequence.h: Same.
+ * include/debug/vector: Tweak.
+ * include/Makefile.am (debug_headers): Add new includes.
+ * include/Makefile.in: Regenerate.
+ * testsuite/17_intro/no_assert_neg.cc: Add.
+
+ * include/ext/hash_set: Add debug mode include.
+ * include/ext/hash_map: Same.
+ * include/debug/hash_map: Fix included files to match actual files.
+ * include/debug/hash_set: Same.
+
+2005-05-26 Paolo Carlini <pcarlini@suse.de>
+
+ PR libstdc++/13943
+ * include/c_std/std_cstdlib.h: Do not open code llabs and lldiv,
+ available when _GLIBCXX_USE_C99 is defined.
+ * testsuite/26_numerics/cstdlib/13943.cc: New.
+
+ * acinclude.m4 ([GLIBCXX_ENABLE_C99]): For completeness, check
+ also strtoll and strtoull for ac_c99_stdlib.
+ * configure: Regenerate.
+
+2005-05-25 Benjamin Kosnik <bkoz@redhat.com>
+
+ * config/linker-map.gnu: Add linkage support for no extern templates.
+ (std::ios_base::_M_call_callbacks): Add.
+ (std::ios_base::_M_dispose_callbacks): Add.
+ (std::locale::facet::_S_get_c_name): Add.
+ (std::__copy_streambufs): Add.
+ * configure.ac (libtool_VERSION): To 6:5:0.
+ * configure: Regenerate.
+ * testsuite/testsuite_abi.cc (check_version): Add GLIBCXX_3.4.5.
+
2005-05-25 Paolo Carlini <pcarlini@suse.de>
* include/bits/basic_string.h (_Rep::_M_set_length_and_sharable):
diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index 757a0e8aed1..86a52e5904c 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -879,12 +879,14 @@ AC_DEFUN([GLIBCXX_ENABLE_C99], [
AC_MSG_CHECKING([for ISO C99 support in <stdlib.h>])
AC_CACHE_VAL(ac_c99_stdlib, [
AC_TRY_COMPILE([#include <stdlib.h>],
- [char* tmp;
- strtof("gnu", &tmp);
+ [char* tmp;
+ strtof("gnu", &tmp);
strtold("gnu", &tmp);
- llabs(10);
- lldiv(10,1);
- atoll("10");
+ strtoll("gnu", &tmp, 10);
+ strtoull("gnu", &tmp, 10);
+ llabs(10);
+ lldiv(10,1);
+ atoll("10");
_Exit(0);
lldiv_t mydivt;],[ac_c99_stdlib=yes], [ac_c99_stdlib=no])
])
diff --git a/libstdc++-v3/config/linker-map.gnu b/libstdc++-v3/config/linker-map.gnu
index a6f631a8d97..a9d20abe21e 100644
--- a/libstdc++-v3/config/linker-map.gnu
+++ b/libstdc++-v3/config/linker-map.gnu
@@ -1,6 +1,6 @@
## Linker script for GNU ld 2.13.91+ only.
##
-## Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+## Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
##
## This file is part of the libstdc++ version 3 distribution.
##
@@ -40,7 +40,7 @@ GLIBCXX_3.4 {
std::logic_error*;
std::locale::[A-Za-e]*;
std::locale::facet::[A-Za-z]*;
- std::locale::facet::_S_get_c_locale*;
+ std::locale::facet::_S_get_c_locale*;
std::locale::facet::_S_clone_c_locale*;
std::locale::facet::_S_create_c_locale*;
std::locale::facet::_S_destroy_c_locale*;
@@ -304,6 +304,16 @@ GLIBCXX_3.4.4 {
} GLIBCXX_3.4.3;
+GLIBCXX_3.4.5 {
+
+ _ZSt17__copy_streambufsI[cw]St11char_traitsI[cw]EEiPSt15basic_streambuf*;
+ _ZNSt8ios_base17_M_call_callbacksENS_5eventE;
+ _ZNSt8ios_base20_M_dispose_callbacksEv;
+ _ZNSt6locale5facet13_S_get_c_nameEv;
+ _ZN11__gnu_debug13__fancy_abortEPKciS1_S1_;
+
+} GLIBCXX_3.4.4;
+
# Symbols in the support library (libsupc++) have their own tag.
CXXABI_1.3 {
diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
index 053980648f8..9e0d61d4474 100755
--- a/libstdc++-v3/configure
+++ b/libstdc++-v3/configure
@@ -1376,7 +1376,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
### am handles this now? ORIGINAL_LD_FOR_MULTILIBS=$LD
# For libtool versioning info, format is CURRENT:REVISION:AGE
-libtool_VERSION=6:4:0
+libtool_VERSION=6:5:0
# Find the rest of the source tree framework.
@@ -7059,7 +7059,9 @@ main ()
char* tmp;
strtof("gnu", &tmp);
strtold("gnu", &tmp);
- llabs(10);
+ strtoll("gnu", &tmp, 10);
+ strtoull("gnu", &tmp, 10);
+ llabs(10);
lldiv(10,1);
atoll("10");
_Exit(0);
diff --git a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac
index f5a5c4c3d80..b0e72fc644e 100644
--- a/libstdc++-v3/configure.ac
+++ b/libstdc++-v3/configure.ac
@@ -12,7 +12,7 @@ AC_CONFIG_HEADER(config.h)
### am handles this now? ORIGINAL_LD_FOR_MULTILIBS=$LD
# For libtool versioning info, format is CURRENT:REVISION:AGE
-libtool_VERSION=6:4:0
+libtool_VERSION=6:5:0
AC_SUBST(libtool_VERSION)
# Find the rest of the source tree framework.
diff --git a/libstdc++-v3/docs/html/abi.html b/libstdc++-v3/docs/html/abi.html
index e48bb4b8bf7..1971b3aa63d 100644
--- a/libstdc++-v3/docs/html/abi.html
+++ b/libstdc++-v3/docs/html/abi.html
@@ -734,11 +734,18 @@ Use the 'make check-abi' rule in the libstdc++-v3 Makefile.
<p>
This is a proactive check the library ABI. Currently, exported symbol
names that are either weak or defined are checked against a last known
-good baseline. Currently, this baseline is keyed off of 3.2.0
+good baseline. Currently, this baseline is keyed off of 3.4.0
binaries, as this was the last time the .so number was incremented. In
addition, all exported names are demangled, and the exported objects
are checked to make sure they are the same size as the same object in
the baseline.
+
+Notice that each baseline is relative to a <strong>default</strong>
+configured library and compiler: in particular, if options such as
+--enable-clocale, or --with-cpu, in case of multilibs, are used at
+configure time, the check may fail, either because of substantive
+differences or because of limitations of the current checking
+machinery.
</p>
<p>
diff --git a/libstdc++-v3/docs/html/test.html b/libstdc++-v3/docs/html/test.html
index d15dc427180..41e0529e6c6 100644
--- a/libstdc++-v3/docs/html/test.html
+++ b/libstdc++-v3/docs/html/test.html
@@ -427,8 +427,8 @@ Example 4: Testing for compilation errors on line 41
Example 5: Testing with special command line settings, or without the
use of pre-compiled headers, in particular the stdc++.h.gch file. Any
-options here will override the DEFAULT_CXXFLAGS set up in the
-normal.exp file.
+options here will override the DEFAULT_CXXFLAGS and PCH_CXXFLAGS set
+up in the normal.exp file.
// { dg-options "-O0" { target *-*-* } }
</pre>
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index abd9abf4e70..797afb619c8 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -321,6 +321,7 @@ debug_headers = \
${debug_srcdir}/debug.h \
${debug_srcdir}/deque \
${debug_srcdir}/formatter.h \
+ ${debug_srcdir}/functions.h \
${debug_srcdir}/hash_map \
${debug_srcdir}/hash_map.h \
${debug_srcdir}/hash_multimap.h \
@@ -329,6 +330,7 @@ debug_headers = \
${debug_srcdir}/hash_set.h \
${debug_srcdir}/list \
${debug_srcdir}/map \
+ ${debug_srcdir}/macros.h \
${debug_srcdir}/map.h \
${debug_srcdir}/multimap.h \
${debug_srcdir}/multiset.h \
diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in
index 60bf72bf3c4..253c898a191 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -538,6 +538,7 @@ debug_headers = \
${debug_srcdir}/debug.h \
${debug_srcdir}/deque \
${debug_srcdir}/formatter.h \
+ ${debug_srcdir}/functions.h \
${debug_srcdir}/hash_map \
${debug_srcdir}/hash_map.h \
${debug_srcdir}/hash_multimap.h \
@@ -546,6 +547,7 @@ debug_headers = \
${debug_srcdir}/hash_set.h \
${debug_srcdir}/list \
${debug_srcdir}/map \
+ ${debug_srcdir}/macros.h \
${debug_srcdir}/map.h \
${debug_srcdir}/multimap.h \
${debug_srcdir}/multiset.h \
diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h
index 001a68f1008..07b66d6d615 100644
--- a/libstdc++-v3/include/bits/basic_string.h
+++ b/libstdc++-v3/include/bits/basic_string.h
@@ -109,17 +109,19 @@ namespace std
template<typename _CharT, typename _Traits, typename _Alloc>
class basic_string
{
+ typedef typename _Alloc::template rebind<_CharT>::other _CharT_alloc_type;
+
// Types:
public:
typedef _Traits traits_type;
typedef typename _Traits::char_type value_type;
typedef _Alloc allocator_type;
- typedef typename _Alloc::size_type size_type;
- typedef typename _Alloc::difference_type difference_type;
- typedef typename _Alloc::reference reference;
- typedef typename _Alloc::const_reference const_reference;
- typedef typename _Alloc::pointer pointer;
- typedef typename _Alloc::const_pointer const_pointer;
+ typedef typename _CharT_alloc_type::size_type size_type;
+ typedef typename _CharT_alloc_type::difference_type difference_type;
+ typedef typename _CharT_alloc_type::reference reference;
+ typedef typename _CharT_alloc_type::const_reference const_reference;
+ typedef typename _CharT_alloc_type::pointer pointer;
+ typedef typename _CharT_alloc_type::const_pointer const_pointer;
typedef __gnu_cxx::__normal_iterator<pointer, basic_string> iterator;
typedef __gnu_cxx::__normal_iterator<const_pointer, basic_string>
const_iterator;
@@ -151,7 +153,7 @@ namespace std
struct _Rep : _Rep_base
{
// Types:
- typedef typename _Alloc::template rebind<size_type>::other _Raw_alloc;
+ typedef typename _Alloc::template rebind<char>::other _Raw_bytes_alloc;
// (Public) Data members:
diff --git a/libstdc++-v3/include/bits/basic_string.tcc b/libstdc++-v3/include/bits/basic_string.tcc
index 672457f9be9..41db0dff438 100644
--- a/libstdc++-v3/include/bits/basic_string.tcc
+++ b/libstdc++-v3/include/bits/basic_string.tcc
@@ -425,10 +425,9 @@ namespace std
basic_string<_CharT, _Traits, _Alloc>::_Rep::
_M_destroy(const _Alloc& __a) throw ()
{
- const size_type __size = ((this->_M_capacity + 1) * sizeof(_CharT)
- + sizeof(_Rep_base) + sizeof(size_type) - 1);
- _Raw_alloc(__a).deallocate(reinterpret_cast<size_type*>(this), __size
- / sizeof(size_type));
+ const size_type __size = sizeof(_Rep_base) +
+ (this->_M_capacity + 1) * sizeof(_CharT);
+ _Raw_bytes_alloc(__a).deallocate(reinterpret_cast<char*>(this), __size);
}
template<typename _CharT, typename _Traits, typename _Alloc>
@@ -569,12 +568,9 @@ namespace std
__capacity = 2 * __old_capacity;
// NB: Need an array of char_type[__capacity], plus a terminating
- // null char_type() element, plus enough for the _Rep data structure,
- // plus sizeof(size_type) - 1 to upper round to a size multiple
- // of sizeof(size_type).
+ // null char_type() element, plus enough for the _Rep data structure.
// Whew. Seemingly so needy, yet so elemental.
- size_type __size = ((__capacity + 1) * sizeof(_CharT) + sizeof(_Rep)
- + sizeof(size_type) - 1);
+ size_type __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep);
const size_type __adj_size = __size + __malloc_header_size;
if (__adj_size > __pagesize && __capacity > __old_capacity)
@@ -584,14 +580,12 @@ namespace std
// Never allocate a string bigger than _S_max_size.
if (__capacity > _S_max_size)
__capacity = _S_max_size;
- __size = ((__capacity + 1) * sizeof(_CharT) + sizeof(_Rep)
- + sizeof(size_type) - 1);
+ __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep);
}
// NB: Might throw, but no worries about a leak, mate: _Rep()
// does not throw.
- void* __place = _Raw_alloc(__alloc).allocate(__size
- / sizeof(size_type));
+ void* __place = _Raw_bytes_alloc(__alloc).allocate(__size);
_Rep *__p = new (__place) _Rep;
__p->_M_capacity = __capacity;
return __p;
diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config
index 526ab8c7355..16c3194ba67 100644
--- a/libstdc++-v3/include/bits/c++config
+++ b/libstdc++-v3/include/bits/c++config
@@ -1,6 +1,6 @@
// Predefined symbols and macros -*- C++ -*-
-// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -34,27 +34,6 @@
// Pick up any OS-specific definitions.
#include <bits/os_defines.h>
-// Allow use of "export template." This is currently not a feature
-// that g++ supports.
-// #define _GLIBCXX_EXPORT_TEMPLATE 1
-
-// Allow use of the GNU syntax extension, "extern template." This
-// extension is fully documented in the g++ manual, but in a nutshell,
-// it inhibits all implicit instantiations and is used throughout the
-// library to avoid multiple weak definitions for required types that
-// are already explicitly instantiated in the library binary. This
-// substantially reduces the binary size of resulting executables.
-#ifndef _GLIBCXX_EXTERN_TEMPLATE
-# define _GLIBCXX_EXTERN_TEMPLATE 1
-#endif
-
-// Certain function definitions that are meant to be overridable from
-// user code are decorated with this macro. For some targets, this
-// macro causes these definitions to be weak.
-#ifndef _GLIBCXX_WEAK_DEFINITION
-# define _GLIBCXX_WEAK_DEFINITION
-#endif
-
// Debug mode support. Debug mode basic_string is not allowed to be
// associated with std, because of locale and exception link
// dependence.
@@ -66,7 +45,10 @@ namespace __gnu_debug
}
#ifdef _GLIBCXX_DEBUG
-# define _GLIBCXX_STD __gnu_norm
+# if __GXX_WEAK__
+# define _GLIBCXX_STD __gnu_norm
+# define _GLIBCXX_EXTERN_TEMPLATE 0
+
namespace __gnu_norm
{
using namespace std;
@@ -75,10 +57,33 @@ namespace std
{
using namespace __gnu_debug_def __attribute__ ((strong));
}
+# else
+# warning debug mode disabled due to lack of weak symbol support
+# endif
#else
# define _GLIBCXX_STD std
#endif
+// Allow use of "export template." This is currently not a feature
+// that g++ supports.
+// #define _GLIBCXX_EXPORT_TEMPLATE 1
+
+// Allow use of the GNU syntax extension, "extern template." This
+// extension is fully documented in the g++ manual, but in a nutshell,
+// it inhibits all implicit instantiations and is used throughout the
+// library to avoid multiple weak definitions for required types that
+// are already explicitly instantiated in the library binary. This
+// substantially reduces the binary size of resulting executables.
+#ifndef _GLIBCXX_EXTERN_TEMPLATE
+# define _GLIBCXX_EXTERN_TEMPLATE 1
+#endif
+
+// Certain function definitions that are meant to be overridable from
+// user code are decorated with this macro. For some targets, this
+// macro causes these definitions to be weak.
+#ifndef _GLIBCXX_WEAK_DEFINITION
+# define _GLIBCXX_WEAK_DEFINITION
+#endif
// The remainder of the prewritten config is automatic; all the
// user hooks are listed above.
diff --git a/libstdc++-v3/include/bits/deque.tcc b/libstdc++-v3/include/bits/deque.tcc
index c5440b22419..35ceb69b402 100644
--- a/libstdc++-v3/include/bits/deque.tcc
+++ b/libstdc++-v3/include/bits/deque.tcc
@@ -147,7 +147,7 @@ namespace _GLIBCXX_STD
std::copy_backward(this->_M_impl._M_start, __first, __last);
iterator __new_start = this->_M_impl._M_start + __n;
std::_Destroy(this->_M_impl._M_start, __new_start,
- this->get_allocator());
+ _M_get_Tp_allocator());
_M_destroy_nodes(this->_M_impl._M_start._M_node,
__new_start._M_node);
this->_M_impl._M_start = __new_start;
@@ -157,7 +157,7 @@ namespace _GLIBCXX_STD
std::copy(__last, this->_M_impl._M_finish, __first);
iterator __new_finish = this->_M_impl._M_finish - __n;
std::_Destroy(__new_finish, this->_M_impl._M_finish,
- this->get_allocator());
+ _M_get_Tp_allocator());
_M_destroy_nodes(__new_finish._M_node + 1,
this->_M_impl._M_finish._M_node + 1);
this->_M_impl._M_finish = __new_finish;
@@ -176,7 +176,7 @@ namespace _GLIBCXX_STD
++__node)
{
std::_Destroy(*__node, *__node + _S_buffer_size(),
- this->get_allocator());
+ _M_get_Tp_allocator());
_M_deallocate_node(*__node);
}
@@ -184,16 +184,16 @@ namespace _GLIBCXX_STD
{
std::_Destroy(this->_M_impl._M_start._M_cur,
this->_M_impl._M_start._M_last,
- this->get_allocator());
+ _M_get_Tp_allocator());
std::_Destroy(this->_M_impl._M_finish._M_first,
this->_M_impl._M_finish._M_cur,
- this->get_allocator());
+ _M_get_Tp_allocator());
_M_deallocate_node(this->_M_impl._M_finish._M_first);
}
else
std::_Destroy(this->_M_impl._M_start._M_cur,
this->_M_impl._M_finish._M_cur,
- this->get_allocator());
+ _M_get_Tp_allocator());
this->_M_impl._M_finish = this->_M_impl._M_start;
}
@@ -226,7 +226,7 @@ namespace _GLIBCXX_STD
{
std::__uninitialized_fill_a(__new_start, this->_M_impl._M_start,
__x,
- this->get_allocator());
+ _M_get_Tp_allocator());
this->_M_impl._M_start = __new_start;
}
catch(...)
@@ -243,7 +243,7 @@ namespace _GLIBCXX_STD
{
std::__uninitialized_fill_a(this->_M_impl._M_finish,
__new_finish, __x,
- this->get_allocator());
+ _M_get_Tp_allocator());
this->_M_impl._M_finish = __new_finish;
}
catch(...)
@@ -269,15 +269,15 @@ namespace _GLIBCXX_STD
__cur < this->_M_impl._M_finish._M_node;
++__cur)
std::__uninitialized_fill_a(*__cur, *__cur + _S_buffer_size(),
- __value, this->get_allocator());
+ __value, _M_get_Tp_allocator());
std::__uninitialized_fill_a(this->_M_impl._M_finish._M_first,
this->_M_impl._M_finish._M_cur,
- __value, this->get_allocator());
+ __value, _M_get_Tp_allocator());
}
catch(...)
{
std::_Destroy(this->_M_impl._M_start, iterator(*__cur, __cur),
- this->get_allocator());
+ _M_get_Tp_allocator());
__throw_exception_again;
}
}
@@ -322,18 +322,18 @@ namespace _GLIBCXX_STD
_ForwardIterator __mid = __first;
std::advance(__mid, _S_buffer_size());
std::__uninitialized_copy_a(__first, __mid, *__cur_node,
- this->get_allocator());
+ _M_get_Tp_allocator());
__first = __mid;
}
std::__uninitialized_copy_a(__first, __last,
this->_M_impl._M_finish._M_first,
- this->get_allocator());
+ _M_get_Tp_allocator());
}
catch(...)
{
std::_Destroy(this->_M_impl._M_start,
iterator(*__cur_node, __cur_node),
- this->get_allocator());
+ _M_get_Tp_allocator());
__throw_exception_again;
}
}
@@ -435,7 +435,7 @@ namespace _GLIBCXX_STD
try
{
std::__uninitialized_copy_a(__first, __last, __new_start,
- this->get_allocator());
+ _M_get_Tp_allocator());
this->_M_impl._M_start = __new_start;
}
catch(...)
@@ -452,7 +452,7 @@ namespace _GLIBCXX_STD
{
std::__uninitialized_copy_a(__first, __last,
this->_M_impl._M_finish,
- this->get_allocator());
+ _M_get_Tp_allocator());
this->_M_impl._M_finish = __new_finish;
}
catch(...)
@@ -520,7 +520,7 @@ namespace _GLIBCXX_STD
+ difference_type(__n));
std::__uninitialized_copy_a(this->_M_impl._M_start,
__start_n, __new_start,
- this->get_allocator());
+ _M_get_Tp_allocator());
this->_M_impl._M_start = __new_start;
std::copy(__start_n, __pos, __old_start);
fill(__pos - difference_type(__n), __pos, __x_copy);
@@ -531,7 +531,7 @@ namespace _GLIBCXX_STD
__pos, __new_start,
this->_M_impl._M_start,
__x_copy,
- this->get_allocator());
+ _M_get_Tp_allocator());
this->_M_impl._M_start = __new_start;
std::fill(__old_start, __pos, __x_copy);
}
@@ -559,7 +559,7 @@ namespace _GLIBCXX_STD
std::__uninitialized_copy_a(__finish_n,
this->_M_impl._M_finish,
this->_M_impl._M_finish,
- this->get_allocator());
+ _M_get_Tp_allocator());
this->_M_impl._M_finish = __new_finish;
std::copy_backward(__pos, __finish_n, __old_finish);
std::fill(__pos, __pos + difference_type(__n), __x_copy);
@@ -570,7 +570,7 @@ namespace _GLIBCXX_STD
__pos + difference_type(__n),
__x_copy, __pos,
this->_M_impl._M_finish,
- this->get_allocator());
+ _M_get_Tp_allocator());
this->_M_impl._M_finish = __new_finish;
std::fill(__pos, __old_finish, __x_copy);
}
@@ -607,7 +607,7 @@ namespace _GLIBCXX_STD
+ difference_type(__n));
std::__uninitialized_copy_a(this->_M_impl._M_start,
__start_n, __new_start,
- this->get_allocator());
+ _M_get_Tp_allocator());
this->_M_impl._M_start = __new_start;
std::copy(__start_n, __pos, __old_start);
std::copy(__first, __last, __pos - difference_type(__n));
@@ -619,7 +619,7 @@ namespace _GLIBCXX_STD
std::__uninitialized_copy_copy(this->_M_impl._M_start,
__pos, __first, __mid,
__new_start,
- this->get_allocator());
+ _M_get_Tp_allocator());
this->_M_impl._M_start = __new_start;
std::copy(__mid, __last, __old_start);
}
@@ -647,7 +647,7 @@ namespace _GLIBCXX_STD
std::__uninitialized_copy_a(__finish_n,
this->_M_impl._M_finish,
this->_M_impl._M_finish,
- this->get_allocator());
+ _M_get_Tp_allocator());
this->_M_impl._M_finish = __new_finish;
std::copy_backward(__pos, __finish_n, __old_finish);
std::copy(__first, __last, __pos);
@@ -659,7 +659,7 @@ namespace _GLIBCXX_STD
std::__uninitialized_copy_copy(__mid, __last, __pos,
this->_M_impl._M_finish,
this->_M_impl._M_finish,
- this->get_allocator());
+ _M_get_Tp_allocator());
this->_M_impl._M_finish = __new_finish;
std::copy(__first, __mid, __pos);
}
diff --git a/libstdc++-v3/include/bits/list.tcc b/libstdc++-v3/include/bits/list.tcc
index 59f9d1ad703..14ea0f0dbfa 100644
--- a/libstdc++-v3/include/bits/list.tcc
+++ b/libstdc++-v3/include/bits/list.tcc
@@ -74,7 +74,7 @@ namespace _GLIBCXX_STD
{
_Node* __tmp = __cur;
__cur = static_cast<_Node*>(__cur->_M_next);
- this->get_allocator().destroy(&__tmp->_M_data);
+ _M_get_Tp_allocator().destroy(&__tmp->_M_data);
_M_put_node(__tmp);
}
}
diff --git a/libstdc++-v3/include/bits/stl_deque.h b/libstdc++-v3/include/bits/stl_deque.h
index fdee3d5aedf..249c4f2e7ee 100644
--- a/libstdc++-v3/include/bits/stl_deque.h
+++ b/libstdc++-v3/include/bits/stl_deque.h
@@ -358,7 +358,7 @@ namespace _GLIBCXX_STD
allocator_type
get_allocator() const
- { return *static_cast<const _Alloc*>(&this->_M_impl); }
+ { return _M_get_Tp_allocator(); }
typedef _Deque_iterator<_Tp, _Tp&, _Tp*> iterator;
typedef _Deque_iterator<_Tp, const _Tp&, const _Tp*> const_iterator;
@@ -377,30 +377,43 @@ namespace _GLIBCXX_STD
//This struct encapsulates the implementation of the std::deque
//standard container and at the same time makes use of the EBO
//for empty allocators.
+ typedef typename _Alloc::template rebind<_Tp*>::other _Map_alloc_type;
+
+ typedef typename _Alloc::template rebind<_Tp>::other _Tp_alloc_type;
+
struct _Deque_impl
- : public _Alloc
+ : public _Tp_alloc_type
{
_Tp** _M_map;
size_t _M_map_size;
iterator _M_start;
iterator _M_finish;
- _Deque_impl(const _Alloc& __a)
- : _Alloc(__a), _M_map(0), _M_map_size(0), _M_start(), _M_finish()
+ _Deque_impl(const _Tp_alloc_type& __a)
+ : _Tp_alloc_type(__a), _M_map(0), _M_map_size(0),
+ _M_start(), _M_finish()
{ }
};
- typedef typename _Alloc::template rebind<_Tp*>::other _Map_alloc_type;
- _Map_alloc_type _M_get_map_allocator() const
- { return _Map_alloc_type(this->get_allocator()); }
+ _Tp_alloc_type
+ _M_get_Tp_allocator() const
+ { return *static_cast<const _Tp_alloc_type*>(&this->_M_impl); }
+
+ _Map_alloc_type
+ _M_get_map_allocator() const
+ { return _M_get_Tp_allocator(); }
_Tp*
_M_allocate_node()
- { return _M_impl._Alloc::allocate(__deque_buf_size(sizeof(_Tp))); }
+ {
+ return _M_impl._Tp_alloc_type::allocate(__deque_buf_size(sizeof(_Tp)));
+ }
void
_M_deallocate_node(_Tp* __p)
- { _M_impl._Alloc::deallocate(__p, __deque_buf_size(sizeof(_Tp))); }
+ {
+ _M_impl._Tp_alloc_type::deallocate(__p, __deque_buf_size(sizeof(_Tp)));
+ }
_Tp**
_M_allocate_map(size_t __n)
@@ -595,23 +608,26 @@ namespace _GLIBCXX_STD
class deque : protected _Deque_base<_Tp, _Alloc>
{
// concept requirements
+ typedef typename _Alloc::value_type _Alloc_value_type;
__glibcxx_class_requires(_Tp, _SGIAssignableConcept)
+ __glibcxx_class_requires2(_Tp, _Alloc_value_type, _SameTypeConcept)
typedef _Deque_base<_Tp, _Alloc> _Base;
+ typedef typename _Base::_Tp_alloc_type _Tp_alloc_type;
public:
- typedef _Tp value_type;
- typedef typename _Alloc::pointer pointer;
- typedef typename _Alloc::const_pointer const_pointer;
- typedef typename _Alloc::reference reference;
- typedef typename _Alloc::const_reference const_reference;
- typedef typename _Base::iterator iterator;
- typedef typename _Base::const_iterator const_iterator;
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
- typedef std::reverse_iterator<iterator> reverse_iterator;
+ typedef _Tp value_type;
+ typedef typename _Tp_alloc_type::pointer pointer;
+ typedef typename _Tp_alloc_type::const_pointer const_pointer;
+ typedef typename _Tp_alloc_type::reference reference;
+ typedef typename _Tp_alloc_type::const_reference const_reference;
+ typedef typename _Base::iterator iterator;
+ typedef typename _Base::const_iterator const_iterator;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
- typedef typename _Base::allocator_type allocator_type;
+ typedef _Alloc allocator_type;
protected:
typedef pointer* _Map_pointer;
@@ -627,6 +643,7 @@ namespace _GLIBCXX_STD
using _Base::_M_deallocate_node;
using _Base::_M_allocate_map;
using _Base::_M_deallocate_map;
+ using _Base::_M_get_Tp_allocator;
/** @if maint
* A total of four data members accumulated down the heirarchy.
@@ -680,7 +697,7 @@ namespace _GLIBCXX_STD
: _Base(__x.get_allocator(), __x.size())
{ std::__uninitialized_copy_a(__x.begin(), __x.end(),
this->_M_impl._M_start,
- this->get_allocator()); }
+ _M_get_Tp_allocator()); }
/**
* @brief Builds a %deque from a range.
@@ -713,7 +730,7 @@ namespace _GLIBCXX_STD
*/
~deque()
{ std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
- this->get_allocator()); }
+ _M_get_Tp_allocator()); }
/**
* @brief %Deque assignment operator.
diff --git a/libstdc++-v3/include/bits/stl_list.h b/libstdc++-v3/include/bits/stl_list.h
index ce167ef80e4..879048063d1 100644
--- a/libstdc++-v3/include/bits/stl_list.h
+++ b/libstdc++-v3/include/bits/stl_list.h
@@ -290,18 +290,19 @@ namespace _GLIBCXX_STD
//
// We put this to the test in the constructors and in
// get_allocator, where we use conversions between
- // allocator_type and _Node_Alloc_type. The conversion is
+ // allocator_type and _Node_alloc_type. The conversion is
// required by table 32 in [20.1.5].
typedef typename _Alloc::template rebind<_List_node<_Tp> >::other
+ _Node_alloc_type;
- _Node_Alloc_type;
+ typedef typename _Alloc::template rebind<_Tp>::other _Tp_alloc_type;
struct _List_impl
- : public _Node_Alloc_type
+ : public _Node_alloc_type
{
_List_node_base _M_node;
- _List_impl (const _Node_Alloc_type& __a)
- : _Node_Alloc_type(__a)
+ _List_impl(const _Node_alloc_type& __a)
+ : _Node_alloc_type(__a)
{ }
};
@@ -309,19 +310,22 @@ namespace _GLIBCXX_STD
_List_node<_Tp>*
_M_get_node()
- { return _M_impl._Node_Alloc_type::allocate(1); }
+ { return _M_impl._Node_alloc_type::allocate(1); }
void
_M_put_node(_List_node<_Tp>* __p)
- { _M_impl._Node_Alloc_type::deallocate(__p, 1); }
+ { _M_impl._Node_alloc_type::deallocate(__p, 1); }
public:
typedef _Alloc allocator_type;
+ _Tp_alloc_type
+ _M_get_Tp_allocator() const
+ { return *static_cast<const _Node_alloc_type*>(&this->_M_impl); }
+
allocator_type
get_allocator() const
- { return allocator_type(*static_cast<
- const _Node_Alloc_type*>(&this->_M_impl)); }
+ { return _M_get_Tp_allocator(); }
_List_base(const allocator_type& __a)
: _M_impl(__a)
@@ -391,28 +395,31 @@ namespace _GLIBCXX_STD
class list : protected _List_base<_Tp, _Alloc>
{
// concept requirements
+ typedef typename _Alloc::value_type _Alloc_value_type;
__glibcxx_class_requires(_Tp, _SGIAssignableConcept)
+ __glibcxx_class_requires2(_Tp, _Alloc_value_type, _SameTypeConcept)
- typedef _List_base<_Tp, _Alloc> _Base;
+ typedef _List_base<_Tp, _Alloc> _Base;
+ typedef typename _Base::_Tp_alloc_type _Tp_alloc_type;
public:
typedef _Tp value_type;
- typedef typename _Alloc::pointer pointer;
- typedef typename _Alloc::const_pointer const_pointer;
- typedef typename _Alloc::reference reference;
- typedef typename _Alloc::const_reference const_reference;
+ typedef typename _Tp_alloc_type::pointer pointer;
+ typedef typename _Tp_alloc_type::const_pointer const_pointer;
+ typedef typename _Tp_alloc_type::reference reference;
+ typedef typename _Tp_alloc_type::const_reference const_reference;
typedef _List_iterator<_Tp> iterator;
typedef _List_const_iterator<_Tp> const_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
- typedef typename _Base::allocator_type allocator_type;
+ typedef _Alloc allocator_type;
protected:
// Note that pointers-to-_Node's can be ctor-converted to
// iterator types.
- typedef _List_node<_Tp> _Node;
+ typedef _List_node<_Tp> _Node;
/** @if maint
* One data member plus two memory-handling functions. If the
@@ -423,6 +430,7 @@ namespace _GLIBCXX_STD
using _Base::_M_impl;
using _Base::_M_put_node;
using _Base::_M_get_node;
+ using _Base::_M_get_Tp_allocator;
/**
* @if maint
@@ -437,7 +445,7 @@ namespace _GLIBCXX_STD
_Node* __p = this->_M_get_node();
try
{
- this->get_allocator().construct(&__p->_M_data, __x);
+ _M_get_Tp_allocator().construct(&__p->_M_data, __x);
}
catch(...)
{
@@ -1158,7 +1166,7 @@ namespace _GLIBCXX_STD
{
__position._M_node->unhook();
_Node* __n = static_cast<_Node*>(__position._M_node);
- this->get_allocator().destroy(&__n->_M_data);
+ _M_get_Tp_allocator().destroy(&__n->_M_data);
_M_put_node(__n);
}
};
diff --git a/libstdc++-v3/include/bits/stl_map.h b/libstdc++-v3/include/bits/stl_map.h
index a0834a763bc..5f4be568a69 100644
--- a/libstdc++-v3/include/bits/stl_map.h
+++ b/libstdc++-v3/include/bits/stl_map.h
@@ -90,21 +90,26 @@ namespace _GLIBCXX_STD
typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
class map
{
- // concept requirements
- __glibcxx_class_requires(_Tp, _SGIAssignableConcept)
- __glibcxx_class_requires4(_Compare, bool, _Key, _Key,
- _BinaryFunctionConcept)
-
public:
typedef _Key key_type;
typedef _Tp mapped_type;
typedef std::pair<const _Key, _Tp> value_type;
typedef _Compare key_compare;
+ typedef _Alloc allocator_type;
+
+ private:
+ // concept requirements
+ typedef typename _Alloc::value_type _Alloc_value_type;
+ __glibcxx_class_requires(_Tp, _SGIAssignableConcept)
+ __glibcxx_class_requires4(_Compare, bool, _Key, _Key,
+ _BinaryFunctionConcept)
+ __glibcxx_class_requires2(value_type, _Alloc_value_type, _SameTypeConcept)
+ public:
class value_compare
: public std::binary_function<value_type, value_type, bool>
{
- friend class map<_Key,_Tp,_Compare,_Alloc>;
+ friend class map<_Key, _Tp, _Compare, _Alloc>;
protected:
_Compare comp;
@@ -118,19 +123,22 @@ namespace _GLIBCXX_STD
private:
/// @if maint This turns a red-black tree into a [multi]map. @endif
- typedef _Rb_tree<key_type, value_type,
- _Select1st<value_type>, key_compare, _Alloc> _Rep_type;
+ typedef typename _Alloc::template rebind<value_type>::other
+ _Pair_alloc_type;
+
+ typedef _Rb_tree<key_type, value_type, _Select1st<value_type>,
+ key_compare, _Pair_alloc_type> _Rep_type;
+
/// @if maint The actual tree structure. @endif
_Rep_type _M_t;
public:
// many of these are specified differently in ISO, but the following are
// "functionally equivalent"
- typedef typename _Alloc::pointer pointer;
- typedef typename _Alloc::const_pointer const_pointer;
- typedef typename _Alloc::reference reference;
- typedef typename _Alloc::const_reference const_reference;
- typedef typename _Rep_type::allocator_type allocator_type;
+ typedef typename _Pair_alloc_type::pointer pointer;
+ typedef typename _Pair_alloc_type::const_pointer const_pointer;
+ typedef typename _Pair_alloc_type::reference reference;
+ typedef typename _Pair_alloc_type::const_reference const_reference;
typedef typename _Rep_type::iterator iterator;
typedef typename _Rep_type::const_iterator const_iterator;
typedef typename _Rep_type::size_type size_type;
@@ -589,7 +597,7 @@ namespace _GLIBCXX_STD
*
* This function probably only makes sense for multimaps.
*/
- std::pair<iterator,iterator>
+ std::pair<iterator, iterator>
equal_range(const key_type& __x)
{ return _M_t.equal_range(__x); }
@@ -608,19 +616,19 @@ namespace _GLIBCXX_STD
*
* This function probably only makes sense for multimaps.
*/
- std::pair<const_iterator,const_iterator>
+ std::pair<const_iterator, const_iterator>
equal_range(const key_type& __x) const
{ return _M_t.equal_range(__x); }
template <typename _K1, typename _T1, typename _C1, typename _A1>
friend bool
- operator== (const map<_K1,_T1,_C1,_A1>&,
- const map<_K1,_T1,_C1,_A1>&);
+ operator== (const map<_K1, _T1, _C1, _A1>&,
+ const map<_K1, _T1, _C1, _A1>&);
template <typename _K1, typename _T1, typename _C1, typename _A1>
friend bool
- operator< (const map<_K1,_T1,_C1,_A1>&,
- const map<_K1,_T1,_C1,_A1>&);
+ operator< (const map<_K1, _T1, _C1, _A1>&,
+ const map<_K1, _T1, _C1, _A1>&);
};
/**
@@ -635,8 +643,8 @@ namespace _GLIBCXX_STD
*/
template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool
- operator==(const map<_Key,_Tp,_Compare,_Alloc>& __x,
- const map<_Key,_Tp,_Compare,_Alloc>& __y)
+ operator==(const map<_Key, _Tp, _Compare, _Alloc>& __x,
+ const map<_Key, _Tp, _Compare, _Alloc>& __y)
{ return __x._M_t == __y._M_t; }
/**
@@ -652,42 +660,43 @@ namespace _GLIBCXX_STD
*/
template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool
- operator<(const map<_Key,_Tp,_Compare,_Alloc>& __x,
- const map<_Key,_Tp,_Compare,_Alloc>& __y)
+ operator<(const map<_Key, _Tp, _Compare, _Alloc>& __x,
+ const map<_Key, _Tp, _Compare, _Alloc>& __y)
{ return __x._M_t < __y._M_t; }
/// Based on operator==
template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool
- operator!=(const map<_Key,_Tp,_Compare,_Alloc>& __x,
- const map<_Key,_Tp,_Compare,_Alloc>& __y)
+ operator!=(const map<_Key, _Tp, _Compare, _Alloc>& __x,
+ const map<_Key, _Tp, _Compare, _Alloc>& __y)
{ return !(__x == __y); }
/// Based on operator<
template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool
- operator>(const map<_Key,_Tp,_Compare,_Alloc>& __x,
- const map<_Key,_Tp,_Compare,_Alloc>& __y)
+ operator>(const map<_Key, _Tp, _Compare, _Alloc>& __x,
+ const map<_Key, _Tp, _Compare, _Alloc>& __y)
{ return __y < __x; }
/// Based on operator<
template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool
- operator<=(const map<_Key,_Tp,_Compare,_Alloc>& __x,
- const map<_Key,_Tp,_Compare,_Alloc>& __y)
+ operator<=(const map<_Key, _Tp, _Compare, _Alloc>& __x,
+ const map<_Key, _Tp, _Compare, _Alloc>& __y)
{ return !(__y < __x); }
/// Based on operator<
template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool
- operator>=(const map<_Key,_Tp,_Compare,_Alloc>& __x,
- const map<_Key,_Tp,_Compare,_Alloc>& __y)
+ operator>=(const map<_Key, _Tp, _Compare, _Alloc>& __x,
+ const map<_Key, _Tp, _Compare, _Alloc>& __y)
{ return !(__x < __y); }
/// See std::map::swap().
template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline void
- swap(map<_Key,_Tp,_Compare,_Alloc>& __x, map<_Key,_Tp,_Compare,_Alloc>& __y)
+ swap(map<_Key, _Tp, _Compare, _Alloc>& __x,
+ map<_Key, _Tp, _Compare, _Alloc>& __y)
{ __x.swap(__y); }
} // namespace std
diff --git a/libstdc++-v3/include/bits/stl_multimap.h b/libstdc++-v3/include/bits/stl_multimap.h
index 524b2366813..dca95563343 100644
--- a/libstdc++-v3/include/bits/stl_multimap.h
+++ b/libstdc++-v3/include/bits/stl_multimap.h
@@ -74,13 +74,13 @@ namespace _GLIBCXX_STD
template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool
- operator==(const multimap<_Key,_Tp,_Compare,_Alloc>& __x,
- const multimap<_Key,_Tp,_Compare,_Alloc>& __y);
+ operator==(const multimap<_Key, _Tp, _Compare, _Alloc>& __x,
+ const multimap<_Key, _Tp, _Compare, _Alloc>& __y);
template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool
- operator<(const multimap<_Key,_Tp,_Compare,_Alloc>& __x,
- const multimap<_Key,_Tp,_Compare,_Alloc>& __y);
+ operator<(const multimap<_Key, _Tp, _Compare, _Alloc>& __x,
+ const multimap<_Key, _Tp, _Compare, _Alloc>& __y);
/**
* @brief A standard container made up of (key,value) pairs, which can be
@@ -106,21 +106,26 @@ namespace _GLIBCXX_STD
template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
class multimap
{
- // concept requirements
- __glibcxx_class_requires(_Tp, _SGIAssignableConcept)
- __glibcxx_class_requires4(_Compare, bool, _Key, _Key,
- _BinaryFunctionConcept)
-
public:
typedef _Key key_type;
typedef _Tp mapped_type;
typedef std::pair<const _Key, _Tp> value_type;
typedef _Compare key_compare;
+ typedef _Alloc allocator_type;
+ private:
+ // concept requirements
+ typedef typename _Alloc::value_type _Alloc_value_type;
+ __glibcxx_class_requires(_Tp, _SGIAssignableConcept)
+ __glibcxx_class_requires4(_Compare, bool, _Key, _Key,
+ _BinaryFunctionConcept)
+ __glibcxx_class_requires2(value_type, _Alloc_value_type, _SameTypeConcept)
+
+ public:
class value_compare
: public std::binary_function<value_type, value_type, bool>
{
- friend class multimap<_Key,_Tp,_Compare,_Alloc>;
+ friend class multimap<_Key, _Tp, _Compare, _Alloc>;
protected:
_Compare comp;
@@ -134,19 +139,21 @@ namespace _GLIBCXX_STD
private:
/// @if maint This turns a red-black tree into a [multi]map. @endif
- typedef _Rb_tree<key_type, value_type,
- _Select1st<value_type>, key_compare, _Alloc> _Rep_type;
+ typedef typename _Alloc::template rebind<value_type>::other
+ _Pair_alloc_type;
+
+ typedef _Rb_tree<key_type, value_type, _Select1st<value_type>,
+ key_compare, _Pair_alloc_type> _Rep_type;
/// @if maint The actual tree structure. @endif
_Rep_type _M_t;
public:
// many of these are specified differently in ISO, but the following are
// "functionally equivalent"
- typedef typename _Alloc::pointer pointer;
- typedef typename _Alloc::const_pointer const_pointer;
- typedef typename _Alloc::reference reference;
- typedef typename _Alloc::const_reference const_reference;
- typedef typename _Rep_type::allocator_type allocator_type;
+ typedef typename _Pair_alloc_type::pointer pointer;
+ typedef typename _Pair_alloc_type::const_pointer const_pointer;
+ typedef typename _Pair_alloc_type::reference reference;
+ typedef typename _Pair_alloc_type::const_reference const_reference;
typedef typename _Rep_type::iterator iterator;
typedef typename _Rep_type::const_iterator const_iterator;
typedef typename _Rep_type::size_type size_type;
@@ -573,7 +580,7 @@ namespace _GLIBCXX_STD
* @endcode
* (but is faster than making the calls separately).
*/
- std::pair<iterator,iterator>
+ std::pair<iterator, iterator>
equal_range(const key_type& __x)
{ return _M_t.equal_range(__x); }
@@ -590,19 +597,19 @@ namespace _GLIBCXX_STD
* @endcode
* (but is faster than making the calls separately).
*/
- std::pair<const_iterator,const_iterator>
+ std::pair<const_iterator, const_iterator>
equal_range(const key_type& __x) const
{ return _M_t.equal_range(__x); }
template <typename _K1, typename _T1, typename _C1, typename _A1>
friend bool
- operator== (const multimap<_K1,_T1,_C1,_A1>&,
- const multimap<_K1,_T1,_C1,_A1>&);
+ operator== (const multimap<_K1, _T1, _C1, _A1>&,
+ const multimap<_K1, _T1, _C1, _A1>&);
template <typename _K1, typename _T1, typename _C1, typename _A1>
friend bool
- operator< (const multimap<_K1,_T1,_C1,_A1>&,
- const multimap<_K1,_T1,_C1,_A1>&);
+ operator< (const multimap<_K1, _T1, _C1, _A1>&,
+ const multimap<_K1, _T1, _C1, _A1>&);
};
/**
@@ -617,8 +624,8 @@ namespace _GLIBCXX_STD
*/
template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool
- operator==(const multimap<_Key,_Tp,_Compare,_Alloc>& __x,
- const multimap<_Key,_Tp,_Compare,_Alloc>& __y)
+ operator==(const multimap<_Key, _Tp, _Compare, _Alloc>& __x,
+ const multimap<_Key, _Tp, _Compare, _Alloc>& __y)
{ return __x._M_t == __y._M_t; }
/**
@@ -634,43 +641,43 @@ namespace _GLIBCXX_STD
*/
template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool
- operator<(const multimap<_Key,_Tp,_Compare,_Alloc>& __x,
- const multimap<_Key,_Tp,_Compare,_Alloc>& __y)
+ operator<(const multimap<_Key, _Tp, _Compare, _Alloc>& __x,
+ const multimap<_Key, _Tp, _Compare, _Alloc>& __y)
{ return __x._M_t < __y._M_t; }
/// Based on operator==
template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool
- operator!=(const multimap<_Key,_Tp,_Compare,_Alloc>& __x,
- const multimap<_Key,_Tp,_Compare,_Alloc>& __y)
+ operator!=(const multimap<_Key, _Tp, _Compare, _Alloc>& __x,
+ const multimap<_Key, _Tp, _Compare, _Alloc>& __y)
{ return !(__x == __y); }
/// Based on operator<
template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool
- operator>(const multimap<_Key,_Tp,_Compare,_Alloc>& __x,
- const multimap<_Key,_Tp,_Compare,_Alloc>& __y)
+ operator>(const multimap<_Key, _Tp, _Compare, _Alloc>& __x,
+ const multimap<_Key, _Tp, _Compare, _Alloc>& __y)
{ return __y < __x; }
/// Based on operator<
template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool
- operator<=(const multimap<_Key,_Tp,_Compare,_Alloc>& __x,
- const multimap<_Key,_Tp,_Compare,_Alloc>& __y)
+ operator<=(const multimap<_Key, _Tp, _Compare, _Alloc>& __x,
+ const multimap<_Key, _Tp, _Compare, _Alloc>& __y)
{ return !(__y < __x); }
/// Based on operator<
template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline bool
- operator>=(const multimap<_Key,_Tp,_Compare,_Alloc>& __x,
- const multimap<_Key,_Tp,_Compare,_Alloc>& __y)
+ operator>=(const multimap<_Key, _Tp, _Compare, _Alloc>& __x,
+ const multimap<_Key, _Tp, _Compare, _Alloc>& __y)
{ return !(__x < __y); }
/// See std::multimap::swap().
template <typename _Key, typename _Tp, typename _Compare, typename _Alloc>
inline void
- swap(multimap<_Key,_Tp,_Compare,_Alloc>& __x,
- multimap<_Key,_Tp,_Compare,_Alloc>& __y)
+ swap(multimap<_Key, _Tp, _Compare, _Alloc>& __x,
+ multimap<_Key, _Tp, _Compare, _Alloc>& __y)
{ __x.swap(__y); }
} // namespace std
diff --git a/libstdc++-v3/include/bits/stl_multiset.h b/libstdc++-v3/include/bits/stl_multiset.h
index 3f42ef4c38d..f401db76fd5 100644
--- a/libstdc++-v3/include/bits/stl_multiset.h
+++ b/libstdc++-v3/include/bits/stl_multiset.h
@@ -73,13 +73,13 @@ namespace _GLIBCXX_STD
template <class _Key, class _Compare, class _Alloc>
inline bool
- operator==(const multiset<_Key,_Compare,_Alloc>& __x,
- const multiset<_Key,_Compare,_Alloc>& __y);
+ operator==(const multiset<_Key, _Compare, _Alloc>& __x,
+ const multiset<_Key, _Compare, _Alloc>& __y);
template <class _Key, class _Compare, class _Alloc>
inline bool
- operator<(const multiset<_Key,_Compare,_Alloc>& __x,
- const multiset<_Key,_Compare,_Alloc>& __y);
+ operator<(const multiset<_Key, _Compare, _Alloc>& __x,
+ const multiset<_Key, _Compare, _Alloc>& __y);
/**
* @brief A standard container made up of elements, which can be retrieved
@@ -105,9 +105,11 @@ namespace _GLIBCXX_STD
class multiset
{
// concept requirements
+ typedef typename _Alloc::value_type _Alloc_value_type;
__glibcxx_class_requires(_Key, _SGIAssignableConcept)
__glibcxx_class_requires4(_Compare, bool, _Key, _Key,
_BinaryFunctionConcept)
+ __glibcxx_class_requires2(_Key, _Alloc_value_type, _SameTypeConcept)
public:
// typedefs:
@@ -115,35 +117,37 @@ namespace _GLIBCXX_STD
typedef _Key value_type;
typedef _Compare key_compare;
typedef _Compare value_compare;
+ typedef _Alloc allocator_type;
private:
/// @if maint This turns a red-black tree into a [multi]set. @endif
- typedef _Rb_tree<key_type, value_type,
- _Identity<value_type>, key_compare, _Alloc> _Rep_type;
+ typedef typename _Alloc::template rebind<_Key>::other _Key_alloc_type;
+
+ typedef _Rb_tree<key_type, value_type, _Identity<value_type>,
+ key_compare, _Key_alloc_type> _Rep_type;
/// @if maint The actual tree structure. @endif
_Rep_type _M_t;
public:
- typedef typename _Alloc::pointer pointer;
- typedef typename _Alloc::const_pointer const_pointer;
- typedef typename _Alloc::reference reference;
- typedef typename _Alloc::const_reference const_reference;
+ typedef typename _Key_alloc_type::pointer pointer;
+ typedef typename _Key_alloc_type::const_pointer const_pointer;
+ typedef typename _Key_alloc_type::reference reference;
+ typedef typename _Key_alloc_type::const_reference const_reference;
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 103. set::iterator is required to be modifiable,
// but this allows modification of keys.
- typedef typename _Rep_type::const_iterator iterator;
- typedef typename _Rep_type::const_iterator const_iterator;
- typedef typename _Rep_type::const_reverse_iterator reverse_iterator;
- typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator;
- typedef typename _Rep_type::size_type size_type;
- typedef typename _Rep_type::difference_type difference_type;
- typedef typename _Rep_type::allocator_type allocator_type;
-
- // allocation/deallocation
-
- /**
- * @brief Default constructor creates no elements.
- */
+ typedef typename _Rep_type::const_iterator iterator;
+ typedef typename _Rep_type::const_iterator const_iterator;
+ typedef typename _Rep_type::const_reverse_iterator reverse_iterator;
+ typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator;
+ typedef typename _Rep_type::size_type size_type;
+ typedef typename _Rep_type::difference_type difference_type;
+
+ // allocation/deallocation
+
+ /**
+ * @brief Default constructor creates no elements.
+ */
multiset()
: _M_t(_Compare(), allocator_type()) { }
@@ -286,7 +290,7 @@ namespace _GLIBCXX_STD
* std::swap(s1,s2) will feed to this function.
*/
void
- swap(multiset<_Key,_Compare,_Alloc>& __x)
+ swap(multiset<_Key, _Compare, _Alloc>& __x)
{ _M_t.swap(__x._M_t); }
// insert/erase
@@ -492,23 +496,23 @@ namespace _GLIBCXX_STD
*
* This function probably only makes sense for multisets.
*/
- std::pair<iterator,iterator>
+ std::pair<iterator, iterator>
equal_range(const key_type& __x)
{ return _M_t.equal_range(__x); }
- std::pair<const_iterator,const_iterator>
+ std::pair<const_iterator, const_iterator>
equal_range(const key_type& __x) const
{ return _M_t.equal_range(__x); }
template <class _K1, class _C1, class _A1>
friend bool
- operator== (const multiset<_K1,_C1,_A1>&,
- const multiset<_K1,_C1,_A1>&);
+ operator== (const multiset<_K1, _C1, _A1>&,
+ const multiset<_K1, _C1, _A1>&);
template <class _K1, class _C1, class _A1>
friend bool
- operator< (const multiset<_K1,_C1,_A1>&,
- const multiset<_K1,_C1,_A1>&);
+ operator< (const multiset<_K1, _C1, _A1>&,
+ const multiset<_K1, _C1, _A1>&);
};
/**
@@ -524,8 +528,8 @@ namespace _GLIBCXX_STD
*/
template <class _Key, class _Compare, class _Alloc>
inline bool
- operator==(const multiset<_Key,_Compare,_Alloc>& __x,
- const multiset<_Key,_Compare,_Alloc>& __y)
+ operator==(const multiset<_Key, _Compare, _Alloc>& __x,
+ const multiset<_Key, _Compare, _Alloc>& __y)
{ return __x._M_t == __y._M_t; }
/**
@@ -541,15 +545,15 @@ namespace _GLIBCXX_STD
*/
template <class _Key, class _Compare, class _Alloc>
inline bool
- operator<(const multiset<_Key,_Compare,_Alloc>& __x,
- const multiset<_Key,_Compare,_Alloc>& __y)
+ operator<(const multiset<_Key, _Compare, _Alloc>& __x,
+ const multiset<_Key, _Compare, _Alloc>& __y)
{ return __x._M_t < __y._M_t; }
/// Returns !(x == y).
template <class _Key, class _Compare, class _Alloc>
inline bool
- operator!=(const multiset<_Key,_Compare,_Alloc>& __x,
- const multiset<_Key,_Compare,_Alloc>& __y)
+ operator!=(const multiset<_Key, _Compare, _Alloc>& __x,
+ const multiset<_Key, _Compare, _Alloc>& __y)
{ return !(__x == __y); }
/// Returns y < x.
@@ -562,22 +566,22 @@ namespace _GLIBCXX_STD
/// Returns !(y < x)
template <class _Key, class _Compare, class _Alloc>
inline bool
- operator<=(const multiset<_Key,_Compare,_Alloc>& __x,
- const multiset<_Key,_Compare,_Alloc>& __y)
+ operator<=(const multiset<_Key, _Compare, _Alloc>& __x,
+ const multiset<_Key, _Compare, _Alloc>& __y)
{ return !(__y < __x); }
/// Returns !(x < y)
template <class _Key, class _Compare, class _Alloc>
inline bool
- operator>=(const multiset<_Key,_Compare,_Alloc>& __x,
- const multiset<_Key,_Compare,_Alloc>& __y)
+ operator>=(const multiset<_Key, _Compare, _Alloc>& __x,
+ const multiset<_Key, _Compare, _Alloc>& __y)
{ return !(__x < __y); }
/// See std::multiset::swap().
template <class _Key, class _Compare, class _Alloc>
inline void
- swap(multiset<_Key,_Compare,_Alloc>& __x,
- multiset<_Key,_Compare,_Alloc>& __y)
+ swap(multiset<_Key, _Compare, _Alloc>& __x,
+ multiset<_Key, _Compare, _Alloc>& __y)
{ __x.swap(__y); }
} // namespace std
diff --git a/libstdc++-v3/include/bits/stl_set.h b/libstdc++-v3/include/bits/stl_set.h
index 1a15d1172c8..c76e55475c6 100644
--- a/libstdc++-v3/include/bits/stl_set.h
+++ b/libstdc++-v3/include/bits/stl_set.h
@@ -72,13 +72,13 @@ namespace _GLIBCXX_STD
template<class _Key, class _Compare, class _Alloc>
inline bool
- operator==(const set<_Key,_Compare,_Alloc>& __x,
- const set<_Key,_Compare,_Alloc>& __y);
+ operator==(const set<_Key, _Compare, _Alloc>& __x,
+ const set<_Key, _Compare, _Alloc>& __y);
template<class _Key, class _Compare, class _Alloc>
inline bool
- operator<(const set<_Key,_Compare,_Alloc>& __x,
- const set<_Key,_Compare,_Alloc>& __y);
+ operator<(const set<_Key, _Compare, _Alloc>& __x,
+ const set<_Key, _Compare, _Alloc>& __y);
/**
* @brief A standard container made up of unique keys, which can be
@@ -107,9 +107,11 @@ namespace _GLIBCXX_STD
class set
{
// concept requirements
+ typedef typename _Alloc::value_type _Alloc_value_type;
__glibcxx_class_requires(_Key, _SGIAssignableConcept)
__glibcxx_class_requires4(_Compare, bool, _Key, _Key,
_BinaryFunctionConcept)
+ __glibcxx_class_requires2(_Key, _Alloc_value_type, _SameTypeConcept)
public:
// typedefs:
@@ -119,29 +121,32 @@ namespace _GLIBCXX_STD
typedef _Key value_type;
typedef _Compare key_compare;
typedef _Compare value_compare;
+ typedef _Alloc allocator_type;
//@}
private:
- typedef _Rb_tree<key_type, value_type,
- _Identity<value_type>, key_compare, _Alloc> _Rep_type;
+ typedef typename _Alloc::template rebind<_Key>::other _Key_alloc_type;
+
+ typedef _Rb_tree<key_type, value_type, _Identity<value_type>,
+ key_compare, _Key_alloc_type> _Rep_type;
_Rep_type _M_t; // red-black tree representing set
+
public:
//@{
/// Iterator-related typedefs.
- typedef typename _Alloc::pointer pointer;
- typedef typename _Alloc::const_pointer const_pointer;
- typedef typename _Alloc::reference reference;
- typedef typename _Alloc::const_reference const_reference;
+ typedef typename _Key_alloc_type::pointer pointer;
+ typedef typename _Key_alloc_type::const_pointer const_pointer;
+ typedef typename _Key_alloc_type::reference reference;
+ typedef typename _Key_alloc_type::const_reference const_reference;
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 103. set::iterator is required to be modifiable,
// but this allows modification of keys.
- typedef typename _Rep_type::const_iterator iterator;
- typedef typename _Rep_type::const_iterator const_iterator;
- typedef typename _Rep_type::const_reverse_iterator reverse_iterator;
- typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator;
- typedef typename _Rep_type::size_type size_type;
- typedef typename _Rep_type::difference_type difference_type;
- typedef typename _Rep_type::allocator_type allocator_type;
+ typedef typename _Rep_type::const_iterator iterator;
+ typedef typename _Rep_type::const_iterator const_iterator;
+ typedef typename _Rep_type::const_reverse_iterator reverse_iterator;
+ typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator;
+ typedef typename _Rep_type::size_type size_type;
+ typedef typename _Rep_type::difference_type difference_type;
//@}
// allocation/deallocation
@@ -155,8 +160,9 @@ namespace _GLIBCXX_STD
* @param comp Comparator to use.
* @param a Allocator to use.
*/
- explicit set(const _Compare& __comp,
- const allocator_type& __a = allocator_type())
+ explicit
+ set(const _Compare& __comp,
+ const allocator_type& __a = allocator_type())
: _M_t(__comp, __a) {}
/**
@@ -503,22 +509,22 @@ namespace _GLIBCXX_STD
*
* This function probably only makes sense for multisets.
*/
- std::pair<iterator,iterator>
+ std::pair<iterator, iterator>
equal_range(const key_type& __x)
{ return _M_t.equal_range(__x); }
- std::pair<const_iterator,const_iterator>
+ std::pair<const_iterator, const_iterator>
equal_range(const key_type& __x) const
{ return _M_t.equal_range(__x); }
//@}
template<class _K1, class _C1, class _A1>
friend bool
- operator== (const set<_K1,_C1,_A1>&, const set<_K1,_C1,_A1>&);
+ operator== (const set<_K1, _C1, _A1>&, const set<_K1, _C1, _A1>&);
template<class _K1, class _C1, class _A1>
friend bool
- operator< (const set<_K1,_C1,_A1>&, const set<_K1,_C1,_A1>&);
+ operator< (const set<_K1, _C1, _A1>&, const set<_K1, _C1, _A1>&);
};
@@ -534,8 +540,8 @@ namespace _GLIBCXX_STD
*/
template<class _Key, class _Compare, class _Alloc>
inline bool
- operator==(const set<_Key,_Compare,_Alloc>& __x,
- const set<_Key,_Compare,_Alloc>& __y)
+ operator==(const set<_Key, _Compare, _Alloc>& __x,
+ const set<_Key, _Compare, _Alloc>& __y)
{ return __x._M_t == __y._M_t; }
/**
@@ -551,42 +557,42 @@ namespace _GLIBCXX_STD
*/
template<class _Key, class _Compare, class _Alloc>
inline bool
- operator<(const set<_Key,_Compare,_Alloc>& __x,
- const set<_Key,_Compare,_Alloc>& __y)
+ operator<(const set<_Key, _Compare, _Alloc>& __x,
+ const set<_Key, _Compare, _Alloc>& __y)
{ return __x._M_t < __y._M_t; }
/// Returns !(x == y).
template<class _Key, class _Compare, class _Alloc>
inline bool
- operator!=(const set<_Key,_Compare,_Alloc>& __x,
- const set<_Key,_Compare,_Alloc>& __y)
+ operator!=(const set<_Key, _Compare, _Alloc>& __x,
+ const set<_Key, _Compare, _Alloc>& __y)
{ return !(__x == __y); }
/// Returns y < x.
template<class _Key, class _Compare, class _Alloc>
inline bool
- operator>(const set<_Key,_Compare,_Alloc>& __x,
- const set<_Key,_Compare,_Alloc>& __y)
+ operator>(const set<_Key, _Compare, _Alloc>& __x,
+ const set<_Key, _Compare, _Alloc>& __y)
{ return __y < __x; }
/// Returns !(y < x)
template<class _Key, class _Compare, class _Alloc>
inline bool
- operator<=(const set<_Key,_Compare,_Alloc>& __x,
- const set<_Key,_Compare,_Alloc>& __y)
+ operator<=(const set<_Key, _Compare, _Alloc>& __x,
+ const set<_Key, _Compare, _Alloc>& __y)
{ return !(__y < __x); }
/// Returns !(x < y)
template<class _Key, class _Compare, class _Alloc>
inline bool
- operator>=(const set<_Key,_Compare,_Alloc>& __x,
- const set<_Key,_Compare,_Alloc>& __y)
+ operator>=(const set<_Key, _Compare, _Alloc>& __x,
+ const set<_Key, _Compare, _Alloc>& __y)
{ return !(__x < __y); }
/// See std::set::swap().
template<class _Key, class _Compare, class _Alloc>
inline void
- swap(set<_Key,_Compare,_Alloc>& __x, set<_Key,_Compare,_Alloc>& __y)
+ swap(set<_Key, _Compare, _Alloc>& __x, set<_Key, _Compare, _Alloc>& __y)
{ __x.swap(__y); }
} // namespace std
diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h
index d532c2dc910..dccc9dd9623 100644
--- a/libstdc++-v3/include/bits/stl_vector.h
+++ b/libstdc++-v3/include/bits/stl_vector.h
@@ -75,23 +75,29 @@ namespace _GLIBCXX_STD
template<typename _Tp, typename _Alloc>
struct _Vector_base
{
+ typedef typename _Alloc::template rebind<_Tp>::other _Tp_alloc_type;
+
struct _Vector_impl
- : public _Alloc
+ : public _Tp_alloc_type
{
_Tp* _M_start;
_Tp* _M_finish;
_Tp* _M_end_of_storage;
- _Vector_impl(_Alloc const& __a)
- : _Alloc(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0)
+ _Vector_impl(_Tp_alloc_type const& __a)
+ : _Tp_alloc_type(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0)
{ }
};
public:
typedef _Alloc allocator_type;
+ _Tp_alloc_type
+ _M_get_Tp_allocator() const
+ { return *static_cast<const _Tp_alloc_type*>(&this->_M_impl); }
+
allocator_type
get_allocator() const
- { return *static_cast<const _Alloc*>(&this->_M_impl); }
+ { return _M_get_Tp_allocator(); }
_Vector_base(const allocator_type& __a)
: _M_impl(__a)
@@ -148,17 +154,20 @@ namespace _GLIBCXX_STD
class vector : protected _Vector_base<_Tp, _Alloc>
{
// Concept requirements.
+ typedef typename _Alloc::value_type _Alloc_value_type;
__glibcxx_class_requires(_Tp, _SGIAssignableConcept)
-
- typedef _Vector_base<_Tp, _Alloc> _Base;
- typedef vector<_Tp, _Alloc> vector_type;
+ __glibcxx_class_requires2(_Tp, _Alloc_value_type, _SameTypeConcept)
+
+ typedef _Vector_base<_Tp, _Alloc> _Base;
+ typedef vector<_Tp, _Alloc> vector_type;
+ typedef typename _Base::_Tp_alloc_type _Tp_alloc_type;
public:
typedef _Tp value_type;
- typedef typename _Alloc::pointer pointer;
- typedef typename _Alloc::const_pointer const_pointer;
- typedef typename _Alloc::reference reference;
- typedef typename _Alloc::const_reference const_reference;
+ typedef typename _Tp_alloc_type::pointer pointer;
+ typedef typename _Tp_alloc_type::const_pointer const_pointer;
+ typedef typename _Tp_alloc_type::reference reference;
+ typedef typename _Tp_alloc_type::const_reference const_reference;
typedef __gnu_cxx::__normal_iterator<pointer, vector_type> iterator;
typedef __gnu_cxx::__normal_iterator<const_pointer, vector_type>
const_iterator;
@@ -166,7 +175,7 @@ namespace _GLIBCXX_STD
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
- typedef typename _Base::allocator_type allocator_type;
+ typedef _Alloc allocator_type;
protected:
/** @if maint
@@ -177,6 +186,7 @@ namespace _GLIBCXX_STD
using _Base::_M_allocate;
using _Base::_M_deallocate;
using _Base::_M_impl;
+ using _Base::_M_get_Tp_allocator;
public:
// [23.2.4.1] construct/copy/destroy
@@ -201,7 +211,7 @@ namespace _GLIBCXX_STD
: _Base(__n, __a)
{
std::__uninitialized_fill_n_a(this->_M_impl._M_start, __n, __value,
- this->get_allocator());
+ _M_get_Tp_allocator());
this->_M_impl._M_finish = this->_M_impl._M_start + __n;
}
@@ -217,7 +227,7 @@ namespace _GLIBCXX_STD
: _Base(__n, allocator_type())
{
std::__uninitialized_fill_n_a(this->_M_impl._M_start, __n, value_type(),
- this->get_allocator());
+ _M_get_Tp_allocator());
this->_M_impl._M_finish = this->_M_impl._M_start + __n;
}
@@ -235,7 +245,7 @@ namespace _GLIBCXX_STD
{ this->_M_impl._M_finish =
std::__uninitialized_copy_a(__x.begin(), __x.end(),
this->_M_impl._M_start,
- this->get_allocator());
+ _M_get_Tp_allocator());
}
/**
@@ -271,7 +281,7 @@ namespace _GLIBCXX_STD
*/
~vector()
{ std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
- this->get_allocator());
+ _M_get_Tp_allocator());
}
/**
@@ -764,7 +774,7 @@ namespace _GLIBCXX_STD
try
{
std::__uninitialized_copy_a(__first, __last, __result,
- this->get_allocator());
+ _M_get_Tp_allocator());
return __result;
}
catch(...)
@@ -785,7 +795,7 @@ namespace _GLIBCXX_STD
this->_M_impl._M_start = _M_allocate(__n);
this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n;
std::__uninitialized_fill_n_a(this->_M_impl._M_start, __n, __value,
- this->get_allocator());
+ _M_get_Tp_allocator());
this->_M_impl._M_finish = this->_M_impl._M_end_of_storage;
}
@@ -822,7 +832,7 @@ namespace _GLIBCXX_STD
this->_M_impl._M_finish =
std::__uninitialized_copy_a(__first, __last,
this->_M_impl._M_start,
- this->get_allocator());
+ _M_get_Tp_allocator());
}
diff --git a/libstdc++-v3/include/bits/vector.tcc b/libstdc++-v3/include/bits/vector.tcc
index f9f5e5ac8a7..aa1634bbc5e 100644
--- a/libstdc++-v3/include/bits/vector.tcc
+++ b/libstdc++-v3/include/bits/vector.tcc
@@ -77,7 +77,7 @@ namespace _GLIBCXX_STD
this->_M_impl._M_start,
this->_M_impl._M_finish);
std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
- this->get_allocator());
+ _M_get_Tp_allocator());
_M_deallocate(this->_M_impl._M_start,
this->_M_impl._M_end_of_storage
- this->_M_impl._M_start);
@@ -122,7 +122,7 @@ namespace _GLIBCXX_STD
erase(iterator __first, iterator __last)
{
iterator __i(std::copy(__last, end(), __first));
- std::_Destroy(__i, end(), this->get_allocator());
+ std::_Destroy(__i, end(), _M_get_Tp_allocator());
this->_M_impl._M_finish = this->_M_impl._M_finish - (__last - __first);
return __first;
}
@@ -140,7 +140,7 @@ namespace _GLIBCXX_STD
pointer __tmp = _M_allocate_and_copy(__xlen, __x.begin(),
__x.end());
std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
- this->get_allocator());
+ _M_get_Tp_allocator());
_M_deallocate(this->_M_impl._M_start,
this->_M_impl._M_end_of_storage
- this->_M_impl._M_start);
@@ -150,7 +150,7 @@ namespace _GLIBCXX_STD
else if (size() >= __xlen)
{
iterator __i(std::copy(__x.begin(), __x.end(), begin()));
- std::_Destroy(__i, end(), this->get_allocator());
+ std::_Destroy(__i, end(), _M_get_Tp_allocator());
}
else
{
@@ -158,7 +158,7 @@ namespace _GLIBCXX_STD
this->_M_impl._M_start);
std::__uninitialized_copy_a(__x.begin() + size(),
__x.end(), this->_M_impl._M_finish,
- this->get_allocator());
+ _M_get_Tp_allocator());
}
this->_M_impl._M_finish = this->_M_impl._M_start + __xlen;
}
@@ -172,7 +172,7 @@ namespace _GLIBCXX_STD
{
if (__n > capacity())
{
- vector __tmp(__n, __val, get_allocator());
+ vector __tmp(__n, __val, _M_get_Tp_allocator());
__tmp.swap(*this);
}
else if (__n > size())
@@ -180,7 +180,7 @@ namespace _GLIBCXX_STD
std::fill(begin(), end(), __val);
std::__uninitialized_fill_n_a(this->_M_impl._M_finish,
__n - size(), __val,
- this->get_allocator());
+ _M_get_Tp_allocator());
this->_M_impl._M_finish += __n - size();
}
else
@@ -216,7 +216,7 @@ namespace _GLIBCXX_STD
{
pointer __tmp(_M_allocate_and_copy(__len, __first, __last));
std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
- this->get_allocator());
+ _M_get_Tp_allocator());
_M_deallocate(this->_M_impl._M_start,
this->_M_impl._M_end_of_storage
- this->_M_impl._M_start);
@@ -228,7 +228,7 @@ namespace _GLIBCXX_STD
{
iterator __new_finish(std::copy(__first, __last,
this->_M_impl._M_start));
- std::_Destroy(__new_finish, end(), this->get_allocator());
+ std::_Destroy(__new_finish, end(), _M_get_Tp_allocator());
this->_M_impl._M_finish = __new_finish.base();
}
else
@@ -239,7 +239,7 @@ namespace _GLIBCXX_STD
this->_M_impl._M_finish =
std::__uninitialized_copy_a(__mid, __last,
this->_M_impl._M_finish,
- this->get_allocator());
+ _M_get_Tp_allocator());
}
}
@@ -280,22 +280,22 @@ namespace _GLIBCXX_STD
std::__uninitialized_copy_a(iterator(this->_M_impl._M_start),
__position,
__new_start,
- this->get_allocator());
+ _M_get_Tp_allocator());
this->_M_impl.construct(__new_finish.base(), __x);
++__new_finish;
__new_finish =
std::__uninitialized_copy_a(__position,
iterator(this->_M_impl._M_finish),
__new_finish,
- this->get_allocator());
+ _M_get_Tp_allocator());
}
catch(...)
{
- std::_Destroy(__new_start, __new_finish, this->get_allocator());
+ std::_Destroy(__new_start, __new_finish, _M_get_Tp_allocator());
_M_deallocate(__new_start.base(),__len);
__throw_exception_again;
}
- std::_Destroy(begin(), end(), this->get_allocator());
+ std::_Destroy(begin(), end(), _M_get_Tp_allocator());
_M_deallocate(this->_M_impl._M_start,
this->_M_impl._M_end_of_storage
- this->_M_impl._M_start);
@@ -323,7 +323,7 @@ namespace _GLIBCXX_STD
std::__uninitialized_copy_a(this->_M_impl._M_finish - __n,
this->_M_impl._M_finish,
this->_M_impl._M_finish,
- this->get_allocator());
+ _M_get_Tp_allocator());
this->_M_impl._M_finish += __n;
std::copy_backward(__position, __old_finish - __n,
__old_finish);
@@ -334,11 +334,11 @@ namespace _GLIBCXX_STD
std::__uninitialized_fill_n_a(this->_M_impl._M_finish,
__n - __elems_after,
__x_copy,
- this->get_allocator());
+ _M_get_Tp_allocator());
this->_M_impl._M_finish += __n - __elems_after;
std::__uninitialized_copy_a(__position, __old_finish,
this->_M_impl._M_finish,
- this->get_allocator());
+ _M_get_Tp_allocator());
this->_M_impl._M_finish += __elems_after;
std::fill(__position, __old_finish, __x_copy);
}
@@ -361,23 +361,23 @@ namespace _GLIBCXX_STD
__new_finish =
std::__uninitialized_copy_a(begin(), __position,
__new_start,
- this->get_allocator());
+ _M_get_Tp_allocator());
std::__uninitialized_fill_n_a(__new_finish, __n, __x,
- this->get_allocator());
+ _M_get_Tp_allocator());
__new_finish += __n;
__new_finish =
std::__uninitialized_copy_a(__position, end(), __new_finish,
- this->get_allocator());
+ _M_get_Tp_allocator());
}
catch(...)
{
std::_Destroy(__new_start, __new_finish,
- this->get_allocator());
+ _M_get_Tp_allocator());
_M_deallocate(__new_start.base(), __len);
__throw_exception_again;
}
std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
- this->get_allocator());
+ _M_get_Tp_allocator());
_M_deallocate(this->_M_impl._M_start,
this->_M_impl._M_end_of_storage
- this->_M_impl._M_start);
@@ -421,7 +421,7 @@ namespace _GLIBCXX_STD
std::__uninitialized_copy_a(this->_M_impl._M_finish - __n,
this->_M_impl._M_finish,
this->_M_impl._M_finish,
- this->get_allocator());
+ _M_get_Tp_allocator());
this->_M_impl._M_finish += __n;
std::copy_backward(__position, __old_finish - __n,
__old_finish);
@@ -433,11 +433,11 @@ namespace _GLIBCXX_STD
std::advance(__mid, __elems_after);
std::__uninitialized_copy_a(__mid, __last,
this->_M_impl._M_finish,
- this->get_allocator());
+ _M_get_Tp_allocator());
this->_M_impl._M_finish += __n - __elems_after;
std::__uninitialized_copy_a(__position, __old_finish,
this->_M_impl._M_finish,
- this->get_allocator());
+ _M_get_Tp_allocator());
this->_M_impl._M_finish += __elems_after;
std::copy(__first, __mid, __position);
}
@@ -461,25 +461,25 @@ namespace _GLIBCXX_STD
std::__uninitialized_copy_a(iterator(this->_M_impl._M_start),
__position,
__new_start,
- this->get_allocator());
+ _M_get_Tp_allocator());
__new_finish =
std::__uninitialized_copy_a(__first, __last, __new_finish,
- this->get_allocator());
+ _M_get_Tp_allocator());
__new_finish =
std::__uninitialized_copy_a(__position,
iterator(this->_M_impl._M_finish),
__new_finish,
- this->get_allocator());
+ _M_get_Tp_allocator());
}
catch(...)
{
std::_Destroy(__new_start,__new_finish,
- this->get_allocator());
+ _M_get_Tp_allocator());
_M_deallocate(__new_start.base(), __len);
__throw_exception_again;
}
std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
- this->get_allocator());
+ _M_get_Tp_allocator());
_M_deallocate(this->_M_impl._M_start,
this->_M_impl._M_end_of_storage
- this->_M_impl._M_start);
diff --git a/libstdc++-v3/include/c_std/std_cstdlib.h b/libstdc++-v3/include/c_std/std_cstdlib.h
index 3fde655621a..cf91f27b2d3 100644
--- a/libstdc++-v3/include/c_std/std_cstdlib.h
+++ b/libstdc++-v3/include/c_std/std_cstdlib.h
@@ -1,6 +1,6 @@
// -*- C++ -*- forwarding header.
-// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
+// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -168,17 +168,14 @@ namespace __gnu_cxx
inline long long
abs(long long __x) { return __x >= 0 ? __x : -__x; }
- inline long long
- llabs(long long __x) { return __x >= 0 ? __x : -__x; }
-
#if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC
+ using ::llabs;
+
inline lldiv_t
div(long long __n, long long __d)
{ lldiv_t __q; __q.quot = __n / __d; __q.rem = __n % __d; return __q; }
- inline lldiv_t
- lldiv(long long __n, long long __d)
- { lldiv_t __q; __q.quot = __n / __d; __q.rem = __n % __d; return __q; }
+ using ::lldiv;
#endif
#if _GLIBCXX_USE_C99_LONG_LONG_CHECK || _GLIBCXX_USE_C99_LONG_LONG_DYNAMIC
@@ -204,8 +201,8 @@ namespace std
#endif
using __gnu_cxx::_Exit;
using __gnu_cxx::abs;
- using __gnu_cxx::llabs;
#if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC
+ using __gnu_cxx::llabs;
using __gnu_cxx::div;
using __gnu_cxx::lldiv;
#endif
diff --git a/libstdc++-v3/include/debug/debug.h b/libstdc++-v3/include/debug/debug.h
index f371a6a47ca..7cd08cdeca0 100644
--- a/libstdc++-v3/include/debug/debug.h
+++ b/libstdc++-v3/include/debug/debug.h
@@ -31,191 +31,6 @@
#ifndef _GLIBCXX_DEBUG_DEBUG_H
#define _GLIBCXX_DEBUG_DEBUG_H 1
-/**
- * Macros used by the implementation to verify certain
- * properties. These macros may only be used directly by the debug
- * wrappers. Note that these are macros (instead of the more obviously
- * "correct" choice of making them functions) because we need line and
- * file information at the call site, to minimize the distance between
- * the user error and where the error is reported.
- *
- */
-#define _GLIBCXX_DEBUG_VERIFY(_Condition,_ErrorMessage) \
- do { \
- if (! (_Condition)) \
- ::__gnu_debug::_Error_formatter::_M_at(__FILE__, __LINE__) \
- ._ErrorMessage._M_error(); \
- } while (false)
-
-// Verify that [_First, _Last) forms a valid iterator range.
-#define __glibcxx_check_valid_range(_First,_Last) \
-_GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__valid_range(_First, _Last), \
- _M_message(::__gnu_debug::__msg_valid_range) \
- ._M_iterator(_First, #_First) \
- ._M_iterator(_Last, #_Last))
-
-/** Verify that we can insert into *this with the iterator _Position.
- * Insertion into a container at a specific position requires that
- * the iterator be nonsingular (i.e., either dereferenceable or
- * past-the-end) and that it reference the sequence we are inserting
- * into. Note that this macro is only valid when the container is a
- * _Safe_sequence and the iterator is a _Safe_iterator.
-*/
-#define __glibcxx_check_insert(_Position) \
-_GLIBCXX_DEBUG_VERIFY(!_Position._M_singular(), \
- _M_message(::__gnu_debug::__msg_insert_singular) \
- ._M_sequence(*this, "this") \
- ._M_iterator(_Position, #_Position)); \
-_GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this), \
- _M_message(::__gnu_debug::__msg_insert_different) \
- ._M_sequence(*this, "this") \
- ._M_iterator(_Position, #_Position))
-
-/** Verify that we can insert the values in the iterator range
- * [_First, _Last) into *this with the iterator _Position. Insertion
- * into a container at a specific position requires that the iterator
- * be nonsingular (i.e., either dereferenceable or past-the-end),
- * that it reference the sequence we are inserting into, and that the
- * iterator range [_First, Last) is a valid (possibly empty)
- * range. Note that this macro is only valid when the container is a
- * _Safe_sequence and the iterator is a _Safe_iterator.
- *
- * @tbd We would like to be able to check for noninterference of
- * _Position and the range [_First, _Last), but that can't (in
- * general) be done.
-*/
-#define __glibcxx_check_insert_range(_Position,_First,_Last) \
-__glibcxx_check_valid_range(_First,_Last); \
-_GLIBCXX_DEBUG_VERIFY(!_Position._M_singular(), \
- _M_message(::__gnu_debug::__msg_insert_singular) \
- ._M_sequence(*this, "this") \
- ._M_iterator(_Position, #_Position)); \
-_GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this), \
- _M_message(::__gnu_debug::__msg_insert_different) \
- ._M_sequence(*this, "this") \
- ._M_iterator(_Position, #_Position))
-
-/** Verify that we can erase the element referenced by the iterator
- * _Position. We can erase the element if the _Position iterator is
- * dereferenceable and references this sequence.
-*/
-#define __glibcxx_check_erase(_Position) \
-_GLIBCXX_DEBUG_VERIFY(_Position._M_dereferenceable(), \
- _M_message(::__gnu_debug::__msg_erase_bad) \
- ._M_sequence(*this, "this") \
- ._M_iterator(_Position, #_Position)); \
-_GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this), \
- _M_message(::__gnu_debug::__msg_erase_different) \
- ._M_sequence(*this, "this") \
- ._M_iterator(_Position, #_Position))
-
-/** Verify that we can erase the elements in the iterator range
- * [_First, _Last). We can erase the elements if [_First, _Last) is a
- * valid iterator range within this sequence.
-*/
-#define __glibcxx_check_erase_range(_First,_Last) \
-__glibcxx_check_valid_range(_First,_Last); \
-_GLIBCXX_DEBUG_VERIFY(_First._M_attached_to(this), \
- _M_message(::__gnu_debug::__msg_erase_different) \
- ._M_sequence(*this, "this") \
- ._M_iterator(_First, #_First) \
- ._M_iterator(_Last, #_Last))
-
-// Verify that the subscript _N is less than the container's size.
-#define __glibcxx_check_subscript(_N) \
-_GLIBCXX_DEBUG_VERIFY(_N < this->size(), \
- _M_message(::__gnu_debug::__msg_subscript_oob) \
- ._M_sequence(*this, "this") \
- ._M_integer(_N, #_N) \
- ._M_integer(this->size(), "size"))
-
-// Verify that the container is nonempty
-#define __glibcxx_check_nonempty() \
-_GLIBCXX_DEBUG_VERIFY(! this->empty(), \
- _M_message(::__gnu_debug::__msg_empty) \
- ._M_sequence(*this, "this"))
-
-// Verify that the < operator for elements in the sequence is a
-// StrictWeakOrdering by checking that it is irreflexive.
-#define __glibcxx_check_strict_weak_ordering(_First,_Last) \
-_GLIBCXX_DEBUG_ASSERT(_First == _Last || !(*_First < *_First))
-
-// Verify that the predicate is StrictWeakOrdering by checking that it
-// is irreflexive.
-#define __glibcxx_check_strict_weak_ordering_pred(_First,_Last,_Pred) \
-_GLIBCXX_DEBUG_ASSERT(_First == _Last || !_Pred(*_First, *_First))
-
-
-// Verify that the iterator range [_First, _Last) is sorted
-#define __glibcxx_check_sorted(_First,_Last) \
-__glibcxx_check_valid_range(_First,_Last); \
-__glibcxx_check_strict_weak_ordering(_First,_Last); \
-_GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__check_sorted(_First, _Last), \
- _M_message(::__gnu_debug::__msg_unsorted) \
- ._M_iterator(_First, #_First) \
- ._M_iterator(_Last, #_Last))
-
-/** Verify that the iterator range [_First, _Last) is sorted by the
- predicate _Pred. */
-#define __glibcxx_check_sorted_pred(_First,_Last,_Pred) \
-__glibcxx_check_valid_range(_First,_Last); \
-__glibcxx_check_strict_weak_ordering_pred(_First,_Last,_Pred); \
-_GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__check_sorted(_First, _Last, _Pred), \
- _M_message(::__gnu_debug::__msg_unsorted_pred) \
- ._M_iterator(_First, #_First) \
- ._M_iterator(_Last, #_Last) \
- ._M_string(#_Pred))
-
-/** Verify that the iterator range [_First, _Last) is partitioned
- w.r.t. the value _Value. */
-#define __glibcxx_check_partitioned(_First,_Last,_Value) \
-__glibcxx_check_valid_range(_First,_Last); \
-_GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__check_partitioned(_First, _Last, \
- _Value), \
- _M_message(::__gnu_debug::__msg_unpartitioned) \
- ._M_iterator(_First, #_First) \
- ._M_iterator(_Last, #_Last) \
- ._M_string(#_Value))
-
-/** Verify that the iterator range [_First, _Last) is partitioned
- w.r.t. the value _Value and predicate _Pred. */
-#define __glibcxx_check_partitioned_pred(_First,_Last,_Value,_Pred) \
-__glibcxx_check_valid_range(_First,_Last); \
-_GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__check_partitioned(_First, _Last, \
- _Value, _Pred), \
- _M_message(::__gnu_debug::__msg_unpartitioned_pred) \
- ._M_iterator(_First, #_First) \
- ._M_iterator(_Last, #_Last) \
- ._M_string(#_Pred) \
- ._M_string(#_Value))
-
-// Verify that the iterator range [_First, _Last) is a heap
-#define __glibcxx_check_heap(_First,_Last) \
-__glibcxx_check_valid_range(_First,_Last); \
-_GLIBCXX_DEBUG_VERIFY(::std::__is_heap(_First, _Last), \
- _M_message(::__gnu_debug::__msg_not_heap) \
- ._M_iterator(_First, #_First) \
- ._M_iterator(_Last, #_Last))
-
-/** Verify that the iterator range [_First, _Last) is a heap
- w.r.t. the predicate _Pred. */
-#define __glibcxx_check_heap_pred(_First,_Last,_Pred) \
-__glibcxx_check_valid_range(_First,_Last); \
-_GLIBCXX_DEBUG_VERIFY(::std::__is_heap(_First, _Last, _Pred), \
- _M_message(::__gnu_debug::__msg_not_heap_pred) \
- ._M_iterator(_First, #_First) \
- ._M_iterator(_Last, #_Last) \
- ._M_string(#_Pred))
-
-#ifdef _GLIBCXX_DEBUG_PEDANTIC
-# define __glibcxx_check_string(_String) _GLIBCXX_DEBUG_ASSERT(_String != 0)
-# define __glibcxx_check_string_len(_String,_Len) \
- _GLIBCXX_DEBUG_ASSERT(_String != 0 || _Len == 0)
-#else
-# define __glibcxx_check_string(_String)
-# define __glibcxx_check_string_len(_String,_Len)
-#endif
-
/** Macros used by the implementation outside of debug wrappers to
* verify certain properties. The __glibcxx_requires_xxx macros are
* merely wrappers around the __glibcxx_check_xxx wrappers when we
@@ -223,11 +38,13 @@ _GLIBCXX_DEBUG_VERIFY(::std::__is_heap(_First, _Last, _Pred), \
* release mode so that there is no checking performed in, e.g., the
* standard library algorithms.
*/
+
#ifdef _GLIBCXX_DEBUG
-# define _GLIBCXX_DEBUG_ASSERT(_Condition) assert(_Condition)
+# include <debug/macros.h>
+# define _GLIBCXX_DEBUG_ASSERT(_Condition) _GLIBCXX_DEBUG_ABORT(_Condition)
# ifdef _GLIBCXX_DEBUG_PEDANTIC
-# define _GLIBCXX_DEBUG_PEDASSERT(_Condition) assert(_Condition)
+# define _GLIBCXX_DEBUG_PEDASSERT(_Condition) _GLIBCXX_DEBUG_ABORT(_Condition)
# else
# define _GLIBCXX_DEBUG_PEDASSERT(_Condition)
# endif
@@ -252,6 +69,9 @@ _GLIBCXX_DEBUG_VERIFY(::std::__is_heap(_First, _Last, _Pred), \
# define __glibcxx_requires_string_len(_String,_Len) \
__glibcxx_check_string_len(_String,_Len)
# define __glibcxx_requires_subscript(_N) __glibcxx_check_subscript(_N)
+
+# include <debug/functions.h>
+# include <debug/formatter.h>
#else
# define _GLIBCXX_DEBUG_ASSERT(_Condition)
# define _GLIBCXX_DEBUG_PEDASSERT(_Condition)
@@ -269,263 +89,4 @@ _GLIBCXX_DEBUG_VERIFY(::std::__is_heap(_First, _Last, _Pred), \
# define __glibcxx_requires_subscript(_N)
#endif
-#include <cassert> // TBD: temporary
-
-#include <stddef.h> // for ptrdiff_t
-#include <bits/stl_iterator_base_types.h> // for iterator_traits, categories
-#include <bits/cpp_type_traits.h> // for __is_integer
-
-namespace __gnu_debug
-{
- template<typename _Iterator, typename _Sequence>
- class _Safe_iterator;
-
- // An arbitrary iterator pointer is not singular.
- inline bool
- __check_singular_aux(const void*) { return false; }
-
- // We may have an iterator that derives from _Safe_iterator_base but isn't
- // a _Safe_iterator.
- template<typename _Iterator>
- inline bool
- __check_singular(_Iterator& __x)
- { return __gnu_debug::__check_singular_aux(&__x); }
-
- /** Non-NULL pointers are nonsingular. */
- template<typename _Tp>
- inline bool
- __check_singular(const _Tp* __ptr)
- { return __ptr == 0; }
-
- /** Safe iterators know if they are singular. */
- template<typename _Iterator, typename _Sequence>
- inline bool
- __check_singular(const _Safe_iterator<_Iterator, _Sequence>& __x)
- { return __x._M_singular(); }
-
- /** Assume that some arbitrary iterator is dereferenceable, because we
- can't prove that it isn't. */
- template<typename _Iterator>
- inline bool
- __check_dereferenceable(_Iterator&)
- { return true; }
-
- /** Non-NULL pointers are dereferenceable. */
- template<typename _Tp>
- inline bool
- __check_dereferenceable(const _Tp* __ptr)
- { return __ptr; }
-
- /** Safe iterators know if they are singular. */
- template<typename _Iterator, typename _Sequence>
- inline bool
- __check_dereferenceable(const _Safe_iterator<_Iterator, _Sequence>& __x)
- { return __x._M_dereferenceable(); }
-
- /** If the distance between two random access iterators is
- * nonnegative, assume the range is valid.
- */
- template<typename _RandomAccessIterator>
- inline bool
- __valid_range_aux2(const _RandomAccessIterator& __first,
- const _RandomAccessIterator& __last,
- std::random_access_iterator_tag)
- { return __last - __first >= 0; }
-
- /** Can't test for a valid range with input iterators, because
- * iteration may be destructive. So we just assume that the range
- * is valid.
- */
- template<typename _InputIterator>
- inline bool
- __valid_range_aux2(const _InputIterator&, const _InputIterator&,
- std::input_iterator_tag)
- { return true; }
-
- /** We say that integral types for a valid range, and defer to other
- * routines to realize what to do with integral types instead of
- * iterators.
- */
- template<typename _Integral>
- inline bool
- __valid_range_aux(const _Integral&, const _Integral&, __true_type)
- { return true; }
-
- /** We have iterators, so figure out what kind of iterators that are
- * to see if we can check the range ahead of time.
- */
- template<typename _InputIterator>
- inline bool
- __valid_range_aux(const _InputIterator& __first,
- const _InputIterator& __last, __false_type)
- {
- typedef typename std::iterator_traits<_InputIterator>::iterator_category
- _Category;
- return __gnu_debug::__valid_range_aux2(__first, __last, _Category());
- }
-
- /** Don't know what these iterators are, or if they are even
- * iterators (we may get an integral type for InputIterator), so
- * see if they are integral and pass them on to the next phase
- * otherwise.
- */
- template<typename _InputIterator>
- inline bool
- __valid_range(const _InputIterator& __first, const _InputIterator& __last)
- {
- typedef typename std::__is_integer<_InputIterator>::__type _Integral;
- return __gnu_debug::__valid_range_aux(__first, __last, _Integral());
- }
-
- /** Safe iterators know how to check if they form a valid range. */
- template<typename _Iterator, typename _Sequence>
- inline bool
- __valid_range(const _Safe_iterator<_Iterator, _Sequence>& __first,
- const _Safe_iterator<_Iterator, _Sequence>& __last)
- { return __first._M_valid_range(__last); }
-
- /* Checks that [first, last) is a valid range, and then returns
- * __first. This routine is useful when we can't use a separate
- * assertion statement because, e.g., we are in a constructor.
- */
- template<typename _InputIterator>
- inline _InputIterator
- __check_valid_range(const _InputIterator& __first,
- const _InputIterator& __last)
- {
- _GLIBCXX_DEBUG_ASSERT(__gnu_debug::__valid_range(__first, __last));
- return __first;
- }
-
- /** Checks that __s is non-NULL or __n == 0, and then returns __s. */
- template<typename _CharT, typename _Integer>
- inline const _CharT*
- __check_string(const _CharT* __s, const _Integer& __n)
- {
-#ifdef _GLIBCXX_DEBUG_PEDANTIC
- _GLIBCXX_DEBUG_ASSERT(__s != 0 || __n == 0);
-#endif
- return __s;
- }
-
- /** Checks that __s is non-NULL and then returns __s. */
- template<typename _CharT>
- inline const _CharT*
- __check_string(const _CharT* __s)
- {
-#ifdef _GLIBCXX_DEBUG_PEDANTIC
- _GLIBCXX_DEBUG_ASSERT(__s != 0);
-#endif
- return __s;
- }
-
- // Can't check if an input iterator sequence is sorted, because we
- // can't step through the sequence.
- template<typename _InputIterator>
- inline bool
- __check_sorted_aux(const _InputIterator&, const _InputIterator&,
- std::input_iterator_tag)
- { return true; }
-
- // Can verify if a forward iterator sequence is in fact sorted using
- // std::__is_sorted
- template<typename _ForwardIterator>
- inline bool
- __check_sorted_aux(_ForwardIterator __first, _ForwardIterator __last,
- std::forward_iterator_tag)
- {
- if (__first == __last)
- return true;
-
- _ForwardIterator __next = __first;
- for (++__next; __next != __last; __first = __next, ++__next) {
- if (*__next < *__first)
- return false;
- }
-
- return true;
- }
-
- // Can't check if an input iterator sequence is sorted, because we can't step
- // through the sequence.
- template<typename _InputIterator, typename _Predicate>
- inline bool
- __check_sorted_aux(const _InputIterator&, const _InputIterator&,
- _Predicate, std::input_iterator_tag)
- { return true; }
-
- // Can verify if a forward iterator sequence is in fact sorted using
- // std::__is_sorted
- template<typename _ForwardIterator, typename _Predicate>
- inline bool
- __check_sorted_aux(_ForwardIterator __first, _ForwardIterator __last,
- _Predicate __pred, std::forward_iterator_tag)
- {
- if (__first == __last)
- return true;
-
- _ForwardIterator __next = __first;
- for (++__next; __next != __last; __first = __next, ++__next) {
- if (__pred(*__next, *__first))
- return false;
- }
-
- return true;
- }
-
- // Determine if a sequence is sorted.
- template<typename _InputIterator>
- inline bool
- __check_sorted(const _InputIterator& __first, const _InputIterator& __last)
- {
- typedef typename std::iterator_traits<_InputIterator>::iterator_category
- _Category;
- return __gnu_debug::__check_sorted_aux(__first, __last, _Category());
- }
-
- template<typename _InputIterator, typename _Predicate>
- inline bool
- __check_sorted(const _InputIterator& __first, const _InputIterator& __last,
- _Predicate __pred)
- {
- typedef typename std::iterator_traits<_InputIterator>::iterator_category
- _Category;
- return __gnu_debug::__check_sorted_aux(__first, __last, __pred,
- _Category());
- }
-
- // _GLIBCXX_RESOLVE_LIB_DEFECTS
- // 270. Binary search requirements overly strict
- // Determine if a sequence is partitioned w.r.t. this element.
- template<typename _ForwardIterator, typename _Tp>
- inline bool
- __check_partitioned(_ForwardIterator __first, _ForwardIterator __last,
- const _Tp& __value)
- {
- while (__first != __last && *__first < __value)
- ++__first;
- while (__first != __last && !(*__first < __value))
- ++__first;
- return __first == __last;
- }
-
- // Determine if a sequence is partitioned w.r.t. this element.
- template<typename _ForwardIterator, typename _Tp, typename _Pred>
- inline bool
- __check_partitioned(_ForwardIterator __first, _ForwardIterator __last,
- const _Tp& __value, _Pred __pred)
- {
- while (__first != __last && __pred(*__first, __value))
- ++__first;
- while (__first != __last && !__pred(*__first, __value))
- ++__first;
- return __first == __last;
- }
-} // namespace __gnu_debug
-
-#ifdef _GLIBCXX_DEBUG
-// We need the error formatter
-# include <debug/formatter.h>
-#endif
-
#endif
diff --git a/libstdc++-v3/include/debug/hash_map b/libstdc++-v3/include/debug/hash_map
index 570a9af6b69..d4d149756cd 100644
--- a/libstdc++-v3/include/debug/hash_map
+++ b/libstdc++-v3/include/debug/hash_map
@@ -1,6 +1,6 @@
// Debugging hash_map/hash_multimap implementation -*- C++ -*-
-// Copyright (C) 2003
+// Copyright (C) 2003, 2005
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -31,8 +31,8 @@
#ifndef _GLIBCXX_DEBUG_HASH_MAP
#define _GLIBCXX_DEBUG_HASH_MAP 1
-#include <hash_map>
-#include <debug/dbg_hash_map.h>
-#include <debug/dbg_hash_multimap.h>
+#include <ext/hash_map>
+#include <debug/hash_map.h>
+#include <debug/hash_multimap.h>
#endif
diff --git a/libstdc++-v3/include/debug/hash_set b/libstdc++-v3/include/debug/hash_set
index 282cba27613..c600f07c160 100644
--- a/libstdc++-v3/include/debug/hash_set
+++ b/libstdc++-v3/include/debug/hash_set
@@ -1,6 +1,6 @@
// Debugging hash_set/hash_multiset implementation -*- C++ -*-
-// Copyright (C) 2003
+// Copyright (C) 2003, 2005
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -31,8 +31,8 @@
#ifndef _GLIBCXX_DEBUG_HASH_SET
#define _GLIBCXX_DEBUG_HASH_SET 1
-#include <hash_set>
-#include <debug/dbg_hash_set.h>
-#include <debug/dbg_hash_multiset.h>
+#include <ext/hash_set>
+#include <debug/hash_set.h>
+#include <debug/hash_multiset.h>
#endif
diff --git a/libstdc++-v3/include/debug/safe_iterator.h b/libstdc++-v3/include/debug/safe_iterator.h
index 1f5b0f65e45..8d96f397c85 100644
--- a/libstdc++-v3/include/debug/safe_iterator.h
+++ b/libstdc++-v3/include/debug/safe_iterator.h
@@ -31,10 +31,12 @@
#ifndef _GLIBCXX_DEBUG_SAFE_ITERATOR_H
#define _GLIBCXX_DEBUG_SAFE_ITERATOR_H 1
-#include <bits/stl_pair.h>
#include <debug/debug.h>
+#include <debug/macros.h>
+#include <debug/functions.h>
#include <debug/formatter.h>
#include <debug/safe_base.h>
+#include <bits/stl_pair.h>
#include <bits/cpp_type_traits.h>
namespace __gnu_debug
@@ -46,7 +48,8 @@ namespace __gnu_debug
* _Safe_iterators can be determined singular or non-singular via
* _Safe_iterator_base.
*/
- inline bool __check_singular_aux(const _Safe_iterator_base* __x)
+ inline bool
+ __check_singular_aux(const _Safe_iterator_base* __x)
{ return __x->_M_singular(); }
/** \brief Safe iterator wrapper.
diff --git a/libstdc++-v3/include/debug/safe_sequence.h b/libstdc++-v3/include/debug/safe_sequence.h
index f050530a997..a1577b4b4ee 100644
--- a/libstdc++-v3/include/debug/safe_sequence.h
+++ b/libstdc++-v3/include/debug/safe_sequence.h
@@ -1,6 +1,6 @@
// Safe sequence implementation -*- C++ -*-
-// Copyright (C) 2003, 2004
+// Copyright (C) 2003, 2004, 2005
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -32,6 +32,8 @@
#define _GLIBCXX_DEBUG_SAFE_SEQUENCE_H 1
#include <debug/debug.h>
+#include <debug/macros.h>
+#include <debug/functions.h>
#include <debug/safe_base.h>
namespace __gnu_debug
diff --git a/libstdc++-v3/include/debug/vector b/libstdc++-v3/include/debug/vector
index 0cc2997b975..45a423d2d89 100644
--- a/libstdc++-v3/include/debug/vector
+++ b/libstdc++-v3/include/debug/vector
@@ -1,6 +1,6 @@
// Debugging vector implementation -*- C++ -*-
-// Copyright (C) 2003, 2004
+// Copyright (C) 2003, 2004, 2005
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -32,9 +32,9 @@
#define _GLIBCXX_DEBUG_VECTOR 1
#include <vector>
+#include <utility>
#include <debug/safe_sequence.h>
#include <debug/safe_iterator.h>
-#include <utility>
namespace __gnu_debug_def
{
diff --git a/libstdc++-v3/include/ext/array_allocator.h b/libstdc++-v3/include/ext/array_allocator.h
index 27169193306..8689d9da26a 100644
--- a/libstdc++-v3/include/ext/array_allocator.h
+++ b/libstdc++-v3/include/ext/array_allocator.h
@@ -121,10 +121,9 @@ namespace __gnu_cxx
allocate(size_type __n, const void* = 0)
{
static size_type __array_used;
- if (_M_array == 0
- || __array_used + __n > sizeof(*_M_array) / sizeof(_Tp))
+ if (_M_array == 0 || __array_used + __n > _M_array->size())
std::__throw_bad_alloc();
- pointer __ret = reinterpret_cast<_Tp*>(_M_array) + __array_used;
+ pointer __ret = _M_array->begin() + __array_used;
__array_used += __n;
return __ret;
}
diff --git a/libstdc++-v3/include/ext/hash_map b/libstdc++-v3/include/ext/hash_map
index eff10e0272b..20eebeb29a2 100644
--- a/libstdc++-v3/include/ext/hash_map
+++ b/libstdc++-v3/include/ext/hash_map
@@ -1,6 +1,6 @@
// Hashing map implementation -*- C++ -*-
-// Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc.
+// Copyright (C) 2001, 2002, 2004, 2005 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -617,4 +617,9 @@ namespace std
{ return *this; }
};
} // namespace std
+
+#ifdef _GLIBCXX_DEBUG
+# include <debug/hash_map>
+#endif
+
#endif
diff --git a/libstdc++-v3/include/ext/hash_set b/libstdc++-v3/include/ext/hash_set
index f6e791a500f..120bfc5ae4b 100644
--- a/libstdc++-v3/include/ext/hash_set
+++ b/libstdc++-v3/include/ext/hash_set
@@ -1,6 +1,6 @@
// Hashing set implementation -*- C++ -*-
-// Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc.
+// Copyright (C) 2001, 2002, 2004, 2005 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -583,4 +583,9 @@ namespace std
operator++(int) { return *this; }
};
} // namespace std
+
+#ifdef _GLIBCXX_DEBUG
+# include <debug/hash_set>
+#endif
+
#endif
diff --git a/libstdc++-v3/include/std/std_complex.h b/libstdc++-v3/include/std/std_complex.h
index 6c1e0033730..80020756789 100644
--- a/libstdc++-v3/include/std/std_complex.h
+++ b/libstdc++-v3/include/std/std_complex.h
@@ -749,7 +749,7 @@ namespace std
__complex_log(const complex<_Tp>& __z)
{ return complex<_Tp>(log(std::abs(__z)), std::arg(__z)); }
- /*
+#if _GLIBCXX_USE_C99_COMPLEX
inline __complex__ float
__complex_log(__complex__ float __z) { return __builtin_clogf(__z); }
@@ -758,14 +758,16 @@ namespace std
inline __complex__ long double
__complex_log(const __complex__ long double& __z)
- { return __builtin_clogl(__z); } */
+ { return __builtin_clogl(__z); }
- // FIXME: Currently we don't use built-ins for log() because of some
- // obscure user name-space issues. So, we use the generic version
- // which is why we don't use __z.__rep() in the call below.
+ template<typename _Tp>
+ inline complex<_Tp>
+ log(const complex<_Tp>& __z) { return __complex_log(__z.__rep()); }
+#else
template<typename _Tp>
inline complex<_Tp>
log(const complex<_Tp>& __z) { return __complex_log(__z); }
+#endif
template<typename _Tp>
inline complex<_Tp>
diff --git a/libstdc++-v3/src/bitmap_allocator.cc b/libstdc++-v3/src/bitmap_allocator.cc
index 4e42cced450..c8d94af2157 100644
--- a/libstdc++-v3/src/bitmap_allocator.cc
+++ b/libstdc++-v3/src/bitmap_allocator.cc
@@ -41,10 +41,6 @@ namespace __gnu_cxx
<bitmap_allocator<wchar_t>::_Alloc_block*,
bitmap_allocator<wchar_t>::_Alloc_block*> >;
- template class __mini_vector<std::pair
- <bitmap_allocator<size_t>::_Alloc_block*,
- bitmap_allocator<size_t>::_Alloc_block*> >;
-
template class __mini_vector<size_t*>;
template size_t** __lower_bound
diff --git a/libstdc++-v3/src/debug.cc b/libstdc++-v3/src/debug.cc
index 3375adf1f47..621a1c96727 100644
--- a/libstdc++-v3/src/debug.cc
+++ b/libstdc++-v3/src/debug.cc
@@ -48,6 +48,15 @@ namespace __gnu_internal
namespace __gnu_debug
{
+ void
+ __fancy_abort(const char* __file, int __line, const char* __function,
+ const char* __condition)
+ {
+ printf("%s:%d: %s: Assertion '%s' failed.\n", __file, __line,
+ __function, __condition);
+ abort();
+ }
+
const char* _S_debug_messages[] =
{
"function requires a valid iterator range [%1.name;, %2.name;)",
diff --git a/libstdc++-v3/src/misc-inst.cc b/libstdc++-v3/src/misc-inst.cc
index b9bc29882f0..382de97952f 100644
--- a/libstdc++-v3/src/misc-inst.cc
+++ b/libstdc++-v3/src/misc-inst.cc
@@ -1,6 +1,6 @@
// Explicit instantiation file.
-// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
// Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
@@ -35,9 +35,6 @@
#include <string>
#include <istream>
#include <ostream>
-#include <algorithm>
-#include <vector>
-#include <bits/atomicity.h>
#include <ext/stdio_sync_filebuf.h>
namespace std
diff --git a/libstdc++-v3/src/mt_allocator.cc b/libstdc++-v3/src/mt_allocator.cc
index 9c94bc86044..bb6ab899caf 100644
--- a/libstdc++-v3/src/mt_allocator.cc
+++ b/libstdc++-v3/src/mt_allocator.cc
@@ -1,8 +1,8 @@
// Allocator details.
-// Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+// Copyright (C) 2004 Free Software Foundation, Inc.
//
-// This file is part of the GNU ISO C++ Library. This library is free
+// This file is part of the GNU ISO C++ Librarbooly. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
@@ -552,5 +552,4 @@ namespace __gnu_cxx
// Instantiations.
template class __mt_alloc<char>;
template class __mt_alloc<wchar_t>;
- template class __mt_alloc<size_t>;
} // namespace __gnu_cxx
diff --git a/libstdc++-v3/src/pool_allocator.cc b/libstdc++-v3/src/pool_allocator.cc
index 1ad4e9c9a45..731cfffa0ea 100644
--- a/libstdc++-v3/src/pool_allocator.cc
+++ b/libstdc++-v3/src/pool_allocator.cc
@@ -170,5 +170,4 @@ namespace __gnu_cxx
// Instantiations.
template class __pool_alloc<char>;
template class __pool_alloc<wchar_t>;
- template class __pool_alloc<size_t>;
} // namespace __gnu_cxx
diff --git a/libstdc++-v3/testsuite/23_containers/deque/explicit_instantiation.cc b/libstdc++-v3/testsuite/23_containers/deque/explicit_instantiation.cc
deleted file mode 100644
index e6e758d0c74..00000000000
--- a/libstdc++-v3/testsuite/23_containers/deque/explicit_instantiation.cc
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (C) 2004 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library. This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 2, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING. If not, write to the Free
-// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
-// USA.
-
-// As a special exception, you may use this file as part of a free software
-// library without restriction. Specifically, if other files instantiate
-// templates or use macros or inline functions from this file, or you compile
-// this file and link it with other files to produce an executable, this
-// file does not by itself cause the resulting executable to be covered by
-// the GNU General Public License. This exception does not however
-// invalidate any other reasons why the executable file might be covered by
-// the GNU General Public License.
-
-// This file tests explicit instantiation of library containers
-
-#include <deque>
-
-// { dg-do compile }
-
-template class std::deque<int>;
diff --git a/libstdc++-v3/testsuite/23_containers/list/explicit_instantiation.cc b/libstdc++-v3/testsuite/23_containers/list/explicit_instantiation.cc
deleted file mode 100644
index 2c9db8d3f86..00000000000
--- a/libstdc++-v3/testsuite/23_containers/list/explicit_instantiation.cc
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (C) 2004 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library. This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 2, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING. If not, write to the Free
-// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
-// USA.
-
-// As a special exception, you may use this file as part of a free software
-// library without restriction. Specifically, if other files instantiate
-// templates or use macros or inline functions from this file, or you compile
-// this file and link it with other files to produce an executable, this
-// file does not by itself cause the resulting executable to be covered by
-// the GNU General Public License. This exception does not however
-// invalidate any other reasons why the executable file might be covered by
-// the GNU General Public License.
-
-// This file tests explicit instantiation of library containers
-
-#include <list>
-
-// { dg-do compile }
-
-template class std::list<int>;
diff --git a/libstdc++-v3/testsuite/23_containers/map/explicit_instantiation.cc b/libstdc++-v3/testsuite/23_containers/map/explicit_instantiation.cc
deleted file mode 100644
index 4ceb2501569..00000000000
--- a/libstdc++-v3/testsuite/23_containers/map/explicit_instantiation.cc
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (C) 2004 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library. This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 2, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING. If not, write to the Free
-// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
-// USA.
-
-// As a special exception, you may use this file as part of a free software
-// library without restriction. Specifically, if other files instantiate
-// templates or use macros or inline functions from this file, or you compile
-// this file and link it with other files to produce an executable, this
-// file does not by itself cause the resulting executable to be covered by
-// the GNU General Public License. This exception does not however
-// invalidate any other reasons why the executable file might be covered by
-// the GNU General Public License.
-
-// This file tests explicit instantiation of library containers
-
-#include <map>
-
-// { dg-do compile }
-
-template class std::map<int, double>;
diff --git a/libstdc++-v3/testsuite/23_containers/multimap/explicit_instantiation.cc b/libstdc++-v3/testsuite/23_containers/multimap/explicit_instantiation.cc
deleted file mode 100644
index 4a740b250f6..00000000000
--- a/libstdc++-v3/testsuite/23_containers/multimap/explicit_instantiation.cc
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (C) 2004 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library. This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 2, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING. If not, write to the Free
-// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
-// USA.
-
-// As a special exception, you may use this file as part of a free software
-// library without restriction. Specifically, if other files instantiate
-// templates or use macros or inline functions from this file, or you compile
-// this file and link it with other files to produce an executable, this
-// file does not by itself cause the resulting executable to be covered by
-// the GNU General Public License. This exception does not however
-// invalidate any other reasons why the executable file might be covered by
-// the GNU General Public License.
-
-// This file tests explicit instantiation of library containers
-
-#include <map>
-
-// { dg-do compile }
-
-template class std::multimap<int, double>;
diff --git a/libstdc++-v3/testsuite/23_containers/multiset/explicit_instantiation.cc b/libstdc++-v3/testsuite/23_containers/multiset/explicit_instantiation.cc
deleted file mode 100644
index fb6b5f1db19..00000000000
--- a/libstdc++-v3/testsuite/23_containers/multiset/explicit_instantiation.cc
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (C) 2004 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library. This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 2, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING. If not, write to the Free
-// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
-// USA.
-
-// As a special exception, you may use this file as part of a free software
-// library without restriction. Specifically, if other files instantiate
-// templates or use macros or inline functions from this file, or you compile
-// this file and link it with other files to produce an executable, this
-// file does not by itself cause the resulting executable to be covered by
-// the GNU General Public License. This exception does not however
-// invalidate any other reasons why the executable file might be covered by
-// the GNU General Public License.
-
-// This file tests explicit instantiation of library containers
-
-#include <set>
-
-// { dg-do compile }
-
-template class std::multiset<int>;
diff --git a/libstdc++-v3/testsuite/23_containers/set/explicit_instantiation.cc b/libstdc++-v3/testsuite/23_containers/set/explicit_instantiation.cc
deleted file mode 100644
index 02e33be0456..00000000000
--- a/libstdc++-v3/testsuite/23_containers/set/explicit_instantiation.cc
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (C) 2004 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library. This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 2, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING. If not, write to the Free
-// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
-// USA.
-
-// As a special exception, you may use this file as part of a free software
-// library without restriction. Specifically, if other files instantiate
-// templates or use macros or inline functions from this file, or you compile
-// this file and link it with other files to produce an executable, this
-// file does not by itself cause the resulting executable to be covered by
-// the GNU General Public License. This exception does not however
-// invalidate any other reasons why the executable file might be covered by
-// the GNU General Public License.
-
-// This file tests explicit instantiation of library containers
-
-#include <set>
-
-// { dg-do compile }
-
-template class std::set<int>;
diff --git a/libstdc++-v3/testsuite/23_containers/vector/explicit_instantiation.cc b/libstdc++-v3/testsuite/23_containers/vector/explicit_instantiation.cc
deleted file mode 100644
index 0668bbd12ab..00000000000
--- a/libstdc++-v3/testsuite/23_containers/vector/explicit_instantiation.cc
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (C) 2004 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library. This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 2, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING. If not, write to the Free
-// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
-// USA.
-
-// As a special exception, you may use this file as part of a free software
-// library without restriction. Specifically, if other files instantiate
-// templates or use macros or inline functions from this file, or you compile
-// this file and link it with other files to produce an executable, this
-// file does not by itself cause the resulting executable to be covered by
-// the GNU General Public License. This exception does not however
-// invalidate any other reasons why the executable file might be covered by
-// the GNU General Public License.
-
-// This file tests explicit instantiation of library containers
-
-#include <vector>
-
-// { dg-do compile }
-
-template class std::vector<int>;
diff --git a/libstdc++-v3/testsuite/27_io/ios_base/cons/assign_neg.cc b/libstdc++-v3/testsuite/27_io/ios_base/cons/assign_neg.cc
index 50c8eb8b05f..ea6eb423cec 100644
--- a/libstdc++-v3/testsuite/27_io/ios_base/cons/assign_neg.cc
+++ b/libstdc++-v3/testsuite/27_io/ios_base/cons/assign_neg.cc
@@ -40,6 +40,7 @@ void test01()
test_base io2;
io1 = io2;
}
-// { dg-error "within this context" "" { target *-*-* } 41 }
+// { dg-error "synthesized" "" { target *-*-* } 41 }
+// { dg-error "within this context" "" { target *-*-* } 34 }
// { dg-error "is private" "" { target *-*-* } 782 }
// { dg-error "operator=" "" { target *-*-* } 0 }
diff --git a/libstdc++-v3/testsuite/27_io/ios_base/cons/copy_neg.cc b/libstdc++-v3/testsuite/27_io/ios_base/cons/copy_neg.cc
index 925087d5b27..2c047a5c3b5 100644
--- a/libstdc++-v3/testsuite/27_io/ios_base/cons/copy_neg.cc
+++ b/libstdc++-v3/testsuite/27_io/ios_base/cons/copy_neg.cc
@@ -40,6 +40,7 @@ void test02()
test_base io1;
test_base io2 = io1;
}
-// { dg-error "within this context" "" { target *-*-* } 41 }
+// { dg-error "within this context" "" { target *-*-* } 35 }
+// { dg-error "synthesized" "" { target *-*-* } 41 }
// { dg-error "is private" "" { target *-*-* } 779 }
// { dg-error "copy constructor" "" { target *-*-* } 0 }
diff --git a/libstdc++-v3/testsuite/ext/array_allocator/2.cc b/libstdc++-v3/testsuite/ext/array_allocator/2.cc
index 1e837258923..f580ea250b7 100644
--- a/libstdc++-v3/testsuite/ext/array_allocator/2.cc
+++ b/libstdc++-v3/testsuite/ext/array_allocator/2.cc
@@ -1,4 +1,7 @@
-// Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+// Expected execution error for PR19495.
+// { dg-do run { xfail powerpc*-*-linux* } }
+
+// Copyright (C) 2004 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -32,10 +35,7 @@
typedef char char_type;
typedef std::char_traits<char_type> traits_type;
-// NB: Array_allocator doesn't properly support rebinding, used by
-// basic_string. See libstdc++/21609 for details.
-typedef std::tr1::array<size_t, 16> array_type;
-typedef __gnu_cxx::array_allocator<size_t, array_type> allocator_type;
+typedef std::tr1::array<char_type, 32> array_type;
array_type extern_array;
@@ -44,8 +44,10 @@ void test01()
bool test __attribute__((unused)) = true;
using std::basic_string;
+ typedef __gnu_cxx::array_allocator<char_type, array_type> allocator_type;
typedef basic_string<char_type, traits_type, allocator_type> string_type;
+ size_t index = array_type::_S_index;
allocator_type a(&extern_array);
string_type s(a);
diff --git a/libstdc++-v3/testsuite/lib/libstdc++.exp b/libstdc++-v3/testsuite/lib/libstdc++.exp
index 2dbf8217938..bcae3777e75 100644
--- a/libstdc++-v3/testsuite/lib/libstdc++.exp
+++ b/libstdc++-v3/testsuite/lib/libstdc++.exp
@@ -103,14 +103,7 @@ proc libstdc++_init { testfile } {
# headers, or without assertions.
global DEFAULT_CXXFLAGS
if ![info exists DEFAULT_CXXFLAGS] then {
- # Set up includes for stdc++.h.gch, the precompiled header file.
- if { [file exists $flags_file] } {
- set cxxpchflags [exec sh $flags_file --cxxpchflags]
- } else {
- set cxxpchflags ""
- }
- set DEFAULT_CXXFLAGS " ${cxxpchflags}"
-
+ set DEFAULT_CXXFLAGS ""
# Host specific goo here.
if { [string match "powerpc-*-darwin*" $target_triplet] } {
append DEFAULT_CXXFLAGS " -multiply_defined suppress"
@@ -195,6 +188,28 @@ proc libstdc++_init { testfile } {
}
}
+ # If a PCH file is available, use it. We must delay performing
+ # this check until $cxx and such have been initialized because we
+ # perform a test compilation. (Ideally, gcc --print-file-name would
+ # list PCH files, but it does not.)
+ global PCH_CXXFLAGS
+ if ![info exists PCH_CXXFLAGS] then {
+ set src "config[pid].cc"
+ set f [open $src "w"]
+ puts $f "int main () {}"
+ close $f
+
+ set lines [v3_target_compile $src "config[pid].o" object \
+ "additional_flags=-include additional_flags=bits/stdc++.h"]
+ if {$lines == "" } {
+ set PCH_CXXFLAGS "-include bits/stdc++.h"
+ } else {
+ set PCH_CXXFLAGS ""
+ }
+ file delete $src
+ v3track PCH_CXXFLAGS 2
+ }
+
libstdc++_maybe_build_wrapper "${objdir}/testglue.o"
}
diff --git a/libstdc++-v3/testsuite/libstdc++-dg/normal.exp b/libstdc++-v3/testsuite/libstdc++-dg/normal.exp
index 746c7a8ec3f..9d2f1a63a9a 100644
--- a/libstdc++-v3/testsuite/libstdc++-dg/normal.exp
+++ b/libstdc++-v3/testsuite/libstdc++-dg/normal.exp
@@ -87,7 +87,8 @@ set tests [lsort $tests]
# Main loop.
global DEFAULT_CXXFLAGS
-dg-runtest $tests "" $DEFAULT_CXXFLAGS
+global PCH_CXXFLAGS
+dg-runtest $tests "" "$DEFAULT_CXXFLAGS $PCH_CXXFLAGS"
# All done.
dg-finish
diff --git a/libstdc++-v3/testsuite/testsuite_abi.cc b/libstdc++-v3/testsuite/testsuite_abi.cc
index 5f6e23ed83b..0aa594256fa 100644
--- a/libstdc++-v3/testsuite/testsuite_abi.cc
+++ b/libstdc++-v3/testsuite/testsuite_abi.cc
@@ -166,6 +166,7 @@ check_version(const symbol& test, bool added)
known_versions.push_back("GLIBCXX_3.4.2");
known_versions.push_back("GLIBCXX_3.4.3");
known_versions.push_back("GLIBCXX_3.4.4");
+ known_versions.push_back("GLIBCXX_3.4.5");
known_versions.push_back("CXXABI_1.2");
known_versions.push_back("CXXABI_1.2.1");
known_versions.push_back("CXXABI_1.3");